diff --git a/hm-top-posts.php b/hm-top-posts.php index b09bac5..28eda42 100644 --- a/hm-top-posts.php +++ b/hm-top-posts.php @@ -82,15 +82,23 @@ private function __construct() { require_once HMTP_PLUGIN_PATH . 'hmtp.widget.php'; require_once HMTP_PLUGIN_PATH . 'hmtp.template-tags.php'; + $options = get_settings_handler()->get_option( 'hmtp_setting' ); + $this->token = get_settings_handler()->get_option( 'hmtp_ga_token' ); + if ( is_network_activated() ) { + $ga_redirect_url = network_admin_url( 'settings.php?page=hmtp_settings_page' ); + } else { + $ga_redirect_url = admin_url( 'options-general.php?page=hmtp_settings_page' ); + } + $this->settings = wp_parse_args( - get_option( 'hmtp_setting', array() ), + $options, array( 'ga_property_id' => null, 'ga_property_account_id' => null, 'ga_property_profile_id' => null, 'ga_client_id' => null, 'ga_client_secret' => null, - 'ga_redirect_url' => admin_url( 'options-general.php?page=hmtp_settings_page' ), + 'ga_redirect_url' => $ga_redirect_url, 'allow_opt_out' => false, 'allow_opt_out_blogs' => false, ) @@ -108,26 +116,28 @@ private function __construct() { $this->settings['ga_redirect_url'] = HMTP_GA_REDIRECT_URL; } - $this->token = get_option( 'hmtp_ga_token' ); - $this->ga_client = new \Google_Client(); - $this->ga_client->setApplicationName( "WP Top Posts by GA" ); + $this->ga_client->setApplicationName( 'WP Top Posts by GA' ); // Visit https://code.google.com/apis/console?api=analytics to generate your // client id, client secret, and to register your redirect uri. $this->ga_client->setClientId( $this->settings['ga_client_id'] ); $this->ga_client->setClientSecret( $this->settings['ga_client_secret'] ); $this->ga_client->setRedirectUri( $this->settings['ga_redirect_url'] ); - $this->ga_client->setScopes( 'https://www.googleapis.com/auth/analytics.readonly' ); + $this->ga_client->setScopes( 'https://www.googleapis.com/auth/analytics' ); if ( $this->token ) { - $this->ga_client->setAccessToken( $this->token ); - - // Refresh token if necessary - if ( $this->ga_client->isAccessTokenExpired() && $this->ga_client->getRefreshToken() ) { - $this->ga_client->refreshToken( $this->ga_client->getRefreshToken() ); - update_option( 'hmtp_ga_token', $this->ga_client->getAccessToken() ); + try { + $this->ga_client->setAccessToken( $this->token ); + // Refresh token if necessary + if ( $this->ga_client->isAccessTokenExpired() && $this->ga_client->getRefreshToken() ) { + $this->ga_client->refreshToken( $this->ga_client->getRefreshToken() ); + get_settings_handler()->update_option( 'hmtp_ga_token', $this->ga_client->getAccessToken() ); + } + } catch ( \Exception $e ) { + update_option( 'hmtp_top_posts_error_message', $e->getMessage() ); + return array(); } } @@ -181,12 +191,14 @@ public function init() { if ( isset( $_GET['page'] ) && 'hmtp_settings_page' === $_GET['page'] && isset( $_GET['code'] ) ) { $this->ga_client->authenticate( sanitize_text_field( $_GET['code'] ) ); - update_option( 'hmtp_ga_token', $this->ga_client->getAccessToken() ); - - wp_safe_redirect( admin_url( 'options-general.php?page=hmtp_settings_page' ) ); + get_settings_handler()->update_option( 'hmtp_ga_token', $this->ga_client->getAccessToken() ); + if ( is_network_activated() ) { + wp_safe_redirect( network_admin_url( 'settings.php?page=hmtp_settings_page' ) ); + } else { + wp_safe_redirect( admin_url( 'options-general.php?page=hmtp_settings_page' ) ); + } exit; } - } /** @@ -201,7 +213,6 @@ public function get_results( array $args = array() ) { } return $this->top_posts->get_results( $args ); } - } /** @@ -239,3 +250,48 @@ function top_blogs_fetch_results( array $args = array() ) { } return Plugin::get_instance()->top_blogs->fetch_results( $args ); } + +/** + * Gets test data. + * + * @param array $args + * @return array + */ +function test_request( array $args = array() ) { + if ( ! Plugin::get_instance()->top_posts ) { + return array(); + } + return Plugin::get_instance()->top_posts->test_request( $args ); + +} + +/** + * Detect network activated. + * + * @return bool + */ +function is_network_activated() { + // Makes sure the plugin is defined before trying to use it + if ( ! function_exists( 'is_plugin_active_for_network' ) ) { + require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); + } + return is_plugin_active_for_network( 'hm-top-posts/hm-top-posts.php' ); +} + +function get_settings_handler() { + + static $hmtp_settings_handler = null; + + if ( ! isset( $hmtp_settings_handler ) ) { + require_once HMTP_PLUGIN_PATH . '/hmtp.settings-handler.php'; + require_once HMTP_PLUGIN_PATH . '/hmtp.local-settings-handler.php'; + require_once HMTP_PLUGIN_PATH . '/hmtp.network-settings-handler.php'; + if ( is_network_activated() ) { + $hmtp_settings_handler = new NetworkSettingsHandler(); + } else { + $hmtp_settings_handler = new LocalSettingsHandler(); + } + } + + return $hmtp_settings_handler; +} diff --git a/hmtp.admin.php b/hmtp.admin.php index ac13c0c..8632e91 100644 --- a/hmtp.admin.php +++ b/hmtp.admin.php @@ -50,11 +50,25 @@ public function __construct( $settings = array(), \Google_Client $ga_client, \Go add_action( 'init', array( $this, 'init' ) ); add_action( 'admin_init', array( $this, 'admin_init' ) ); add_action( 'admin_menu', array( $this, 'add_options_pages' ) ); - + add_action( 'network_admin_menu', array( $this, 'add_network_options_pages' ) ); + add_action( 'network_admin_edit_forms_processing', array( $this, 'forms_processing' ) ); } function add_options_pages() { - add_options_page( 'HM Top Posts', 'Top Posts', 'manage_options', 'hmtp_settings_page', array( $this, 'settings_page' ) ); + if ( ! is_network_activated() ) { + add_options_page( 'HM Top Posts', 'Top Posts', 'manage_options', 'hmtp_settings_page', array( $this, 'settings_page' ) ); + } + } + + function add_network_options_pages() { + add_submenu_page( + 'settings.php', + __( 'HM Top Posts', 'ub' ), + 'Net Top Posts', + 'manage_network', + 'hmtp_settings_page', + array( $this, 'settings_page' ) + ); } /** @@ -73,7 +87,11 @@ function init() { delete_option( 'hmtp_setting' ); delete_option( 'hmtp_ga_token' ); - wp_safe_redirect( admin_url( 'options-general.php?page=hmtp_settings_page' ) ); + if ( is_network_activated() ) { + wp_safe_redirect( network_admin_url( 'settings.php?page=hmtp_settings_page' ) ); + } else { + wp_safe_redirect( admin_url( 'options-general.php?page=hmtp_settings_page' ) ); + } exit; } @@ -151,42 +169,41 @@ function admin_init() { * Output the plugin settings page */ public function settings_page() { - + if ( is_network_activated() ) { + $action = 'edit.php?action=forms_processing'; + } else { + $action = 'options.php'; + } ?> -

HM Top Posts

-
- + -
+ ga_client->getAccessToken() ) : ?> +
+ -

'; + ?> +
- // Demo. - $results = get_top_posts( array( 'post_type' => 'any' ) ); + 'post' ) ); ?> - ?> - -

+

+ + %s

', esc_html( $results['status_message'] ) ); ?> + + %s

', esc_html( $results['status_message'] ) ); ?> + - -
    - -
  1. %s (%d)', esc_url( get_permalink( $post['post_id'] ) ), esc_html( get_the_title( $post['post_id'] ) ), absint( $post['views'] ) ); ?>
  2. - -
- -

No posts found

-
ga_service->management_webproperties->listManagementWebproperties( "~all" ); + } catch ( \Exception $e ) { + update_option( 'hmtp_top_posts_error_message', $e->getMessage() ); + return array(); + } - $props = $this->ga_service->management_webproperties->listManagementWebproperties( "~all" ); $deauth_url = wp_nonce_url( add_query_arg( array() ), 'hmtp_deauth', 'hmtp_deauth' ); ?> @@ -335,19 +357,48 @@ public function settings_field_opt_out_display() { ?> * @return bool */ public function settings_sanitize( $input ) { - - $input['allow_opt_out'] = isset( $input['allow_opt_out'] ); + $input['allow_opt_out'] = isset( $input['allow_opt_out'] ) ? (boolean) $input['allow_opt_out'] : false; // Reset token if client ID / secret change if ( $input['ga_client_id'] !== $this->settings['ga_client_id'] ) { - delete_option( 'hmtp_ga_token' ); + get_settings_handler()->delete_option( 'hmtp_ga_token' ); } if ( $input['ga_client_secret'] !== $this->settings['ga_client_secret'] ) { - delete_option( 'hmtp_ga_token' ); + get_settings_handler()->delete_option( 'hmtp_ga_token' ); } - return $input; + // Reset token if client ID / secret change + if ( isset( $_POST['reset_token'] ) ) { + get_settings_handler()->delete_option( 'hmtp_ga_token' ); + exit; + } + return $input; } + public function forms_processing() { + // Reset token if client ID / secret change + if ( isset( $_POST['reset_token'] ) ) { + get_settings_handler()->delete_option( 'hmtp_ga_token' ); + wp_safe_redirect( network_admin_url( 'settings.php?page=hmtp_settings_page' ) ); + exit; + } + + $options = get_settings_handler()->get_option( 'hmtp_setting' ); + + $to_save = array(); + foreach ( $_POST['hmtp_setting'] as $key => $value ) { + if ( 'ga_access_token' === $key ) { continue; } + $to_save[ $key ] = $value ? $value : ''; // save raw code - doesn't require sanitization. + } + if ( ! array_key_exists( 'allow_opt_out', $to_save ) ) { + $to_save['allow_opt_out'] = false; + } + $options = wp_parse_args( $to_save, $options ); + get_settings_handler()->update_option( 'hmtp_setting', $options ); + wp_safe_redirect( network_admin_url( 'settings.php?page=hmtp_settings_page' ) ); + + exit; + + } } diff --git a/hmtp.local-settings-handler.php b/hmtp.local-settings-handler.php new file mode 100644 index 0000000..ac95824 --- /dev/null +++ b/hmtp.local-settings-handler.php @@ -0,0 +1,29 @@ +network_id = get_current_network_id(); + } + + public function get_option( $option_name ) { + return get_network_option( $this->network_id, $option_name ); + } + + public function update_option( $option_name, $option_value ) { + update_network_option( $this->network_id, $option_name, $option_value ); + } + + public function delete_option( $option_name ) { + delete_network_option( $this->network_id, $option_name ); + } +} \ No newline at end of file diff --git a/hmtp.settings-handler.php b/hmtp.settings-handler.php new file mode 100644 index 0000000..1eafe66 --- /dev/null +++ b/hmtp.settings-handler.php @@ -0,0 +1,21 @@ +ga_property_profile_id . json_encode( $args ) ); + $query_id = 'hmtp_' . hash( 'md5', $this->ga_property_profile_id . json_encode( $args ) . get_current_blog_id() ); // If TLC Transients exists, use that. if ( class_exists( '\\TLC_Transient' ) ) { @@ -120,6 +120,8 @@ function get_results( array $args = array() ) { */ public function fetch_results( $args ) { + + $max_results = apply_filters( 'hmtp_max_results', 1000 ); // Build up a list of top posts. @@ -128,6 +130,7 @@ public function fetch_results( $args ) { $start_index = 1; $opt_params = array( + 'filters' => 'ga:hostname=@' . parse_url( WP_SITEURL, PHP_URL_HOST ), 'dimensions' => 'ga:hostname,ga:pagePath', 'sort' => '-ga:pageviews', 'max-results' => $max_results, @@ -159,7 +162,7 @@ public function fetch_results( $args ) { foreach ( $results->getRows() as $result ) { - $url = str_replace( 'index.htm', '', apply_filters( 'hmtp_result_url', (string) $result[0] ) ); + $url = str_replace( 'index.htm', '', apply_filters( 'hmtp_result_url', (string) $result[1] ) ); // URls are relative so let's turn them into absolute URLS. $url = WP_SITEURL . $url; @@ -209,19 +212,14 @@ public function fetch_results( $args ) { // Build an array of $post_id => $pageviews $top_posts[ $post_id ] = array( 'post_id' => $post_id, - 'views' => $result[1], + 'views' => $result[2], 'blog_id' => false, ); - if ( is_multisite() ) { - $top_posts[ $post_id ]['blog_id'] = $this->get_blog_id_from_host( $result[0] ); - } - // break when we have enough posts. if ( isset( $top_posts ) && count( $top_posts ) >= $args['count'] ) { break; } - } $opt_params['start-index'] += $max_results; @@ -232,4 +230,71 @@ public function fetch_results( $args ) { } + /** + * Cached version of url_to_postid, which can be expensive. + * + * Taken from wpcom_vip_url_to_postid + * Examine a url and try to determine the post ID it represents. + * + * @param string $url Permalink to check. + * @return int Post ID, or 0 on failure. + */ + private function url_to_postid( $url ) { + + $cache_key = md5( $url ); + $post_id = wp_cache_get( $cache_key, 'url_to_postid' ); + + if ( false === $post_id ) { + $post_id = url_to_postid( $url ); // returns 0 on failure, so need to catch the false condition + wp_cache_add( $cache_key, $post_id, 'url_to_postid' ); + } + + return $post_id; + + } + + /** + * Gets test data from google analytics. + * + * @param array $args + * @return array + */ + public function test_request( $args ) { + $respond = array( + 'success' => false, + 'status_message' => '', + ); + + $args = wp_parse_args( $args, $this->args_defaults ); + + $opt_params = array( + 'dimensions' => 'ga:hostname,ga:pagePath', + 'sort' => '-ga:pageviews', + 'max-results' => 10, + 'start-index' => 1, + ); + + if ( ! empty( $this->args['filters'] ) ) { + $opt_params['filters'] = $this->args['filters']; + } + try { + $results = $this->analytics->data_ga->get( + 'ga:' . $this->ga_property_profile_id, + $args['start_date'], + $args['end_date'], + 'ga:pageviews', + $opt_params + ); + } catch ( \Exception $e ) { + $respond['status_message'] = $e->getMessage(); + } + if ( isset( $results ) && $results->getRows() > 0 ) { + $count = $results->getTotalResults(); + $respond['success'] = true; + $respond['status_message'] = "Connection succeeded, $count items founded."; + } + + + return $respond; + } }