'Recommended_Widget parsely-recommended-widget-hidden', 'description' => __( 'Display a list of post recommendations, personalized for a visitor or the current post.', 'wp-parsely' ), ) ); } /** * Get the URL for the Recommendation API (GET /related). * * @see https://www.parse.ly/help/api/recommendations#get-related * * @internal While this is a public method now, this should be moved to a new class. * * @since 2.5.0 * * @param string $api_key Publisher Site ID (API key). * @param int $published_within Publication filter start date; see https://www.parse.ly/help/api/time for * formatting details. No restriction by default. * @param string $sort What to sort the results by. There are currently 2 valid options: `score`, which * will sort articles by overall relevance and `pub_date` which will sort results by * their publication date. The default is `score`. * @param string $boost Available for sort=score only. Sub-sort value to re-rank relevant posts that * received high e.g. views; default is undefined. * @param int $return_limit Number of records to retrieve; defaults to "10". * @return string API URL. */ private function get_api_url( string $api_key, int $published_within, string $sort, string $boost, int $return_limit ): string { $related_api_endpoint = 'https://api.parsely.com/v2/related'; $query_args = array( 'apikey' => $api_key, 'sort' => $sort, 'limit' => $return_limit, ); if ( 'score' === $sort && 'no-boost' !== $boost ) { $query_args['boost'] = $boost; } if ( 0 !== $published_within ) { $query_args['pub_date_start'] = $published_within . 'd'; } return add_query_arg( $query_args, $related_api_endpoint ); } /** * This is the widget function * * @param array $args Widget Arguments. * @param array $instance Values saved to the db. * @return void */ public function widget( $args, $instance ): void { if ( ! $this->api_key_and_secret_are_populated() ) { return; } $removed_title_esc = remove_filter( 'widget_title', 'esc_html' ); /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $instance['title'] ); if ( $removed_title_esc ) { add_filter( 'widget_title', 'esc_html' ); } wp_enqueue_style( 'wp-parsely-style' ); $title_html = $args['before_widget'] . $args['before_title'] . $title . $args['after_title']; echo wp_kses_post( $title_html ); // Set up the variables. $options = get_option( 'parsely' ); $api_url = $this->get_api_url( $options['apikey'], $instance['published_within'], $instance['sort'], $instance['boost'], (int) $instance['return_limit'] ); $recommended_widget_script_asset = require plugin_dir_path( PARSELY_FILE ) . 'build/admin-page.asset.php'; ?> migrate_old_fields( $instance ); if ( ! $this->api_key_and_secret_are_populated() ) { $settings_page_url = add_query_arg( 'page', 'parsely', get_admin_url() . 'options-general.php' ); $message = sprintf( /* translators: %s: Plugin settings page URL */ __( 'The Parse.ly Site ID and Parse.ly API Secret fields need to be populated on the Parse.ly settings page for this widget to work.', 'wp-parsely' ), esc_url( $settings_page_url ) ); echo '

', wp_kses_post( $message ), '

'; return; } // editable fields: title. $title = ! empty( $instance['title'] ) ? $instance['title'] : ''; $return_limit = ! empty( $instance['return_limit'] ) ? (int) $instance['return_limit'] : 5; $display_direction = ! empty( $instance['display_direction'] ) ? $instance['display_direction'] : 'vertical'; $published_within = ! empty( $instance['published_within'] ) ? $instance['published_within'] : 0; $sort = ! empty( $instance['sort'] ) ? $instance['sort'] : 'score'; $boost = ! empty( $instance['boost'] ) ? $instance['boost'] : 'views'; $personalize_results = ! empty( $instance['personalize_results'] ) ? $instance['personalize_results'] : false; $img_src = ! empty( $instance['img_src'] ) ? $instance['img_src'] : 'parsely_thumb'; $display_author = ! empty( $instance['display_author'] ) ? $instance['display_author'] : false; $instance['return_limit'] = $return_limit; $instance['display_direction'] = $display_direction; $instance['published_within'] = $published_within; $instance['sort'] = $sort; $instance['boost'] = $boost; $instance['personalize_results'] = $personalize_results; $instance['img_src'] = $img_src; $instance['display_author'] = $display_author; $boost_params = $this->get_boost_params(); ?>


value="horizontal" />
value="vertical" />




/>
/>

__( 'No boost', 'wp-parsely' ), 'views' => __( 'Page views', 'wp-parsely' ), 'mobile_views' => __( 'Page views on mobile devices', 'wp-parsely' ), 'tablet_views' => __( 'Page views on tablet devices', 'wp-parsely' ), 'desktop_views' => __( 'Page views on desktop devices', 'wp-parsely' ), 'visitors' => __( 'Unique page visitors, total', 'wp-parsely' ), 'visitors_new' => __( 'New visitors', 'wp-parsely' ), 'visitors_returning' => __( 'Returning visitors', 'wp-parsely' ), 'engaged_minutes' => __( 'Total engagement time in minutes', 'wp-parsely' ), 'avg_engaged' => __( 'Engaged minutes spent by total visitors', 'wp-parsely' ), 'avg_engaged_new' => __( 'Average engaged minutes spent by new visitors', 'wp-parsely' ), 'avg_engaged_returning' => __( 'Average engaged minutes spent by returning visitors', 'wp-parsely' ), 'social_interactions' => __( 'Total for Facebook, Twitter, LinkedIn, and Pinterest', 'wp-parsely' ), 'fb_interactions' => __( 'Count of Facebook shares, likes, and comments', 'wp-parsely' ), 'tw_interactions' => __( 'Count of Twitter tweets and retweets', 'wp-parsely' ), 'li_interactions' => __( 'Count of LinkedIn social interactions', 'wp-parsely' ), 'pi_interactions' => __( 'Count of Pinterest pins', 'wp-parsely' ), 'social_referrals' => __( 'Page views where the referrer was any social network', 'wp-parsely' ), 'fb_referrals' => __( 'Page views where the referrer was facebook.com', 'wp-parsely' ), 'tw_referrals' => __( 'Page views where the referrer was twitter.com', 'wp-parsely' ), 'li_referrals' => __( 'Page views where the referrer was linkedin.com', 'wp-parsely' ), 'pi_referrals' => __( 'Page views where the referrer was pinterest.com', 'wp-parsely' ), ); } /** * Check if both the API key and API secret settings are populated with non-empty values. * * @since 2.5.0 * * @return bool True if apikey and api_secret settings are not empty strings. False otherwise. */ private function api_key_and_secret_are_populated(): bool { $options = get_option( 'parsely' ); // No options are saved, so API key is not available. if ( ! is_array( $options ) ) { return false; } // Parse.ly Site ID settings field is not populated. if ( ! array_key_exists( 'apikey', $options ) || '' === $options['apikey'] ) { return false; } // Parse.ly API Secret settings field is not populated. if ( ! array_key_exists( 'api_secret', $options ) || '' === $options['api_secret'] ) { return false; } return true; } }