$data The current data for update_plugins. * * @return stdClass Extended data for update_plugins. */ public function check_for_updates( $data ) { global $wp_version; if ( empty( $data ) ) { return $data; } // We have to figure out if we're safe to upgrade the add-ons, based on what the latest Yoast Free requirements for the WP version is. $yoast_free_data = $this->extract_yoast_data( $data ); foreach ( $this->get_installed_addons() as $plugin_file => $installed_plugin ) { $subscription_slug = $this->get_slug_by_plugin_file( $plugin_file ); $subscription = $this->get_subscription( $subscription_slug ); if ( ! $subscription ) { continue; } $plugin_data = $this->convert_subscription_to_plugin( $subscription, $yoast_free_data, false, $plugin_file ); // Let's assume for now that it will get added in the 'no_update' key that we'll return to the WP API. $is_no_update = true; // If the add-on's version is the latest, we have to do no further checks. if ( version_compare( $installed_plugin['Version'], $plugin_data->new_version, '<' ) ) { // If we haven't retrieved the Yoast Free requirements for the WP version yet, do nothing. The next run will probably get us that information. if ( $plugin_data->requires === null ) { continue; } if ( version_compare( $plugin_data->requires, $wp_version, '<=' ) ) { // The add-on has an available update *and* the Yoast Free requirements for the WP version are also met, so go ahead and show the upgrade info to the user. $is_no_update = false; $data->response[ $plugin_file ] = $plugin_data; if ( $this->has_subscription_expired( $subscription ) ) { unset( $data->response[ $plugin_file ]->package, $data->response[ $plugin_file ]->download_link ); } } } if ( $is_no_update ) { // Still convert subscription when no updates is available. $data->no_update[ $plugin_file ] = $plugin_data; if ( $this->has_subscription_expired( $subscription ) ) { unset( $data->no_update[ $plugin_file ]->package, $data->no_update[ $plugin_file ]->download_link ); } } } return $data; } /** * Extracts Yoast SEO Free's data from the wp.org API response. * * @param object $data The wp.org API response. * * @return object Yoast Free's data from wp.org. */ protected function extract_yoast_data( $data ) { if ( isset( $data->response[ WPSEO_BASENAME ] ) ) { return $data->response[ WPSEO_BASENAME ]; } if ( isset( $data->no_update[ WPSEO_BASENAME ] ) ) { return $data->no_update[ WPSEO_BASENAME ]; } return (object) []; } /** * If the plugin is lacking an active subscription, throw a warning. * * @param array $plugin_data The data for the plugin in this row. * * @return void */ public function expired_subscription_warning( $plugin_data ) { $subscription = $this->get_subscription( $plugin_data['slug'] ); if ( $subscription && $this->has_subscription_expired( $subscription ) ) { $addon_link = ( isset( $this->addon_details[ $plugin_data['slug'] ] ) ) ? $this->addon_details[ $plugin_data['slug'] ]['short_link_renewal'] : $this->addon_details[ self::PREMIUM_SLUG ]['short_link_renewal']; $sale_copy = ''; if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { $sale_copy = sprintf( /* translators: %1$s and %2$s are a opening and closing tag. */ esc_html__( '%1$s30%% OFF - Black Friday %2$s', 'wordpress-seo' ), '', '' ); } echo '

'; echo ' ' . sprintf( /* translators: %1$s is the plugin name, %2$s and %3$s are a link. */ esc_html__( 'Your %1$s plugin cannot be updated as your subscription has expired. %2$sRenew your product subscription%3$s to restore updates and full feature access.', 'wordpress-seo' ), esc_html( $plugin_data['name'] ), '', '' ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is escaped above. . $sale_copy . ''; } } /** * Checks if there are any installed addons. * * @return bool True when there are installed Yoast addons. */ public function has_installed_addons() { $installed_addons = $this->get_installed_addons(); return ! empty( $installed_addons ); } /** * Checks if the plugin is installed and activated in WordPress. * * @param string $slug The class' slug. * * @return bool True when installed and activated. */ public function is_installed( $slug ) { $slug_to_class_map = [ static::PREMIUM_SLUG => 'WPSEO_Premium', static::NEWS_SLUG => 'WPSEO_News', static::WOOCOMMERCE_SLUG => 'Yoast_WooCommerce_SEO', static::VIDEO_SLUG => 'WPSEO_Video_Sitemap', static::LOCAL_SLUG => 'WPSEO_Local_Core', ]; if ( ! isset( $slug_to_class_map[ $slug ] ) ) { return false; } return class_exists( $slug_to_class_map[ $slug ] ); } /** * Validates the addons and show a notice for the ones that are invalid. * * @return void */ public function validate_addons() { $notification_center = Yoast_Notification_Center::get(); if ( $notification_center === null ) { return; } foreach ( $this->addon_details as $slug => $addon_info ) { $notification = $this->create_notification( $addon_info['name'], $addon_info['short_link_activation'] ); // Add a notification when the installed plugin isn't activated in My Yoast. if ( $this->is_installed( $slug ) && ! $this->has_valid_subscription( $slug ) ) { $notification_center->add_notification( $notification ); continue; } $notification_center->remove_notification( $notification ); } } /** * Checks if the user has any active addons. * * @return bool Whether there are active addons. */ public function has_active_addons() { $active_addons = $this->get_active_addons(); return ! empty( $active_addons ); } /** * Removes the site information transients. * * @codeCoverageIgnore * * @return void */ public function remove_site_information_transients() { delete_transient( self::SITE_INFORMATION_TRANSIENT ); delete_transient( self::SITE_INFORMATION_TRANSIENT_QUICK ); } /** * Creates an instance of Yoast_Notification. * * @param string $product_name The product to create the notification for. * @param string $short_link The short link for the addon notification. * * @return Yoast_Notification The created notification. */ protected function create_notification( $product_name, $short_link ) { $notification_options = [ 'type' => Yoast_Notification::ERROR, 'id' => 'wpseo-dismiss-' . sanitize_title_with_dashes( $product_name, null, 'save' ), 'capabilities' => 'wpseo_manage_options', ]; return new Yoast_Notification( sprintf( /* translators: %1$s expands to a strong tag, %2$s expands to the product name, %3$s expands to a closing strong tag, %4$s expands to an a tag. %5$s expands to MyYoast, %6$s expands to a closing a tag, %7$s expands to the product name */ __( '%1$s %2$s isn\'t working as expected %3$s and you are not receiving updates or support! Make sure to %4$s activate your product subscription in %5$s%6$s to unlock all the features of %7$s.', 'wordpress-seo' ), '', $product_name, '', '', 'MyYoast', '', $product_name ), $notification_options ); } /** * Checks whether a plugin expiry date has been passed. * * @param stdClass $subscription Plugin subscription. * * @return bool Has the plugin expired. */ protected function has_subscription_expired( $subscription ) { return ( strtotime( $subscription->expiry_date ) - time() ) < 0; } /** * Converts a subscription to plugin based format. * * @param stdClass $subscription The subscription to convert. * @param stdClass|null $yoast_free_data The Yoast Free's data. * @param bool $plugin_info Whether we're in the plugin information modal. * @param string $plugin_file The plugin filename. * * @return stdClass The converted subscription. */ protected function convert_subscription_to_plugin( $subscription, $yoast_free_data = null, $plugin_info = false, $plugin_file = '' ) { $changelog = ''; if ( isset( $subscription->product->changelog ) ) { // We need to replace h2's and h3's with h4's because the styling expects that. $changelog = str_replace( 'product->changelog ) ); $changelog = str_replace( ' ( $plugin_info ) ? YOAST_SEO_WP_REQUIRED : null, ]; return (object) [ 'new_version' => ( $subscription->product->version ?? '' ), 'name' => $subscription->product->name, 'slug' => $subscription->product->slug, 'plugin' => $plugin_file, 'url' => $subscription->product->store_url, 'last_update' => $subscription->product->last_updated, 'homepage' => $subscription->product->store_url, 'download_link' => $subscription->product->download, 'package' => $subscription->product->download, 'sections' => [ 'changelog' => $changelog, 'support' => $this->get_support_section(), ], 'icons' => [ '2x' => $this->get_icon( $subscription->product->slug ), ], 'update_supported' => true, 'banners' => $this->get_banners( $subscription->product->slug ), // If we have extracted Yoast Free's data before, use that. If not, resort to the defaults. 'tested' => YOAST_SEO_WP_TESTED, 'requires' => ( $yoast_free_data->requires ?? $defaults['requires'] ), 'requires_php' => YOAST_SEO_PHP_REQUIRED, ]; } /** * Returns the plugin's icon URL. * * @param string $slug The plugin slug. * * @return string The icon URL for this plugin. */ protected function get_icon( $slug ) { switch ( $slug ) { case self::LOCAL_SLUG: return 'https://yoa.st/local-seo-icon'; case self::NEWS_SLUG: return 'https://yoa.st/news-seo-icon'; case self::PREMIUM_SLUG: return 'https://yoa.st/yoast-seo-icon'; case self::VIDEO_SLUG: return 'https://yoa.st/video-seo-icon'; case self::WOOCOMMERCE_SLUG: return 'https://yoa.st/woo-seo-icon'; } } /** * Return an array of plugin banner URLs. * * @param string $slug The plugin slug. * * @return string[] */ protected function get_banners( $slug ) { switch ( $slug ) { case self::LOCAL_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-local', 'low' => 'https://yoa.st/yoast-seo-banner-low-local', ]; case self::NEWS_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-news', 'low' => 'https://yoa.st/yoast-seo-banner-low-news', ]; case self::PREMIUM_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-premium', 'low' => 'https://yoa.st/yoast-seo-banner-low-premium', ]; case self::VIDEO_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-video', 'low' => 'https://yoa.st/yoast-seo-banner-low-video', ]; case self::WOOCOMMERCE_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-woo', 'low' => 'https://yoa.st/yoast-seo-banner-low-woo', ]; } } /** * Checks if the given plugin_file belongs to a Yoast addon. * * @param string $plugin_file Path to the plugin. * * @return bool Tr $data The current data for update_plugins. * * @return stdClass Extended data for update_plugins. */ public function check_for_updates( $data ) { global $wp_version; if ( empty( $data ) ) { return $data; } // We have to figure out if we're safe to upgrade the add-ons, based on what the latest Yoast Free requirements for the WP version is. $yoast_free_data = $this->extract_yoast_data( $data ); foreach ( $this->get_installed_addons() as $plugin_file => $installed_plugin ) { $subscription_slug = $this->get_slug_by_plugin_file( $plugin_file ); $subscription = $this->get_subscription( $subscription_slug ); if ( ! $subscription ) { continue; } $plugin_data = $this->convert_subscription_to_plugin( $subscription, $yoast_free_data, false, $plugin_file ); // Let's assume for now that it will get added in the 'no_update' key that we'll return to the WP API. $is_no_update = true; // If the add-on's version is the latest, we have to do no further checks. if ( version_compare( $installed_plugin['Version'], $plugin_data->new_version, '<' ) ) { // If we haven't retrieved the Yoast Free requirements for the WP version yet, do nothing. The next run will probably get us that information. if ( $plugin_data->requires === null ) { continue; } if ( version_compare( $plugin_data->requires, $wp_version, '<=' ) ) { // The add-on has an available update *and* the Yoast Free requirements for the WP version are also met, so go ahead and show the upgrade info to the user. $is_no_update = false; $data->response[ $plugin_file ] = $plugin_data; if ( $this->has_subscription_expired( $subscription ) ) { unset( $data->response[ $plugin_file ]->package, $data->response[ $plugin_file ]->download_link ); } } } if ( $is_no_update ) { // Still convert subscription when no updates is available. $data->no_update[ $plugin_file ] = $plugin_data; if ( $this->has_subscription_expired( $subscription ) ) { unset( $data->no_update[ $plugin_file ]->package, $data->no_update[ $plugin_file ]->download_link ); } } } return $data; } /** * Extracts Yoast SEO Free's data from the wp.org API response. * * @param object $data The wp.org API response. * * @return object Yoast Free's data from wp.org. */ protected function extract_yoast_data( $data ) { if ( isset( $data->response[ WPSEO_BASENAME ] ) ) { return $data->response[ WPSEO_BASENAME ]; } if ( isset( $data->no_update[ WPSEO_BASENAME ] ) ) { return $data->no_update[ WPSEO_BASENAME ]; } return (object) []; } /** * If the plugin is lacking an active subscription, throw a warning. * * @param array $plugin_data The data for the plugin in this row. * * @return void */ public function expired_subscription_warning( $plugin_data ) { $subscription = $this->get_subscription( $plugin_data['slug'] ); if ( $subscription && $this->has_subscription_expired( $subscription ) ) { $addon_link = ( isset( $this->addon_details[ $plugin_data['slug'] ] ) ) ? $this->addon_details[ $plugin_data['slug'] ]['short_link_renewal'] : $this->addon_details[ self::PREMIUM_SLUG ]['short_link_renewal']; $sale_copy = ''; if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { $sale_copy = sprintf( /* translators: %1$s and %2$s are a opening and closing tag. */ esc_html__( '%1$s30%% OFF - Black Friday %2$s', 'wordpress-seo' ), '', '' ); } echo '

'; echo ' ' . sprintf( /* translators: %1$s is the plugin name, %2$s and %3$s are a link. */ esc_html__( 'Your %1$s plugin cannot be updated as your subscription has expired. %2$sRenew your product subscription%3$s to restore updates and full feature access.', 'wordpress-seo' ), esc_html( $plugin_data['name'] ), '', '' ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is escaped above. . $sale_copy . ''; } } /** * Checks if there are any installed addons. * * @return bool True when there are installed Yoast addons. */ public function has_installed_addons() { $installed_addons = $this->get_installed_addons(); return ! empty( $installed_addons ); } /** * Checks if the plugin is installed and activated in WordPress. * * @param string $slug The class' slug. * * @return bool True when installed and activated. */ public function is_installed( $slug ) { $slug_to_class_map = [ static::PREMIUM_SLUG => 'WPSEO_Premium', static::NEWS_SLUG => 'WPSEO_News', static::WOOCOMMERCE_SLUG => 'Yoast_WooCommerce_SEO', static::VIDEO_SLUG => 'WPSEO_Video_Sitemap', static::LOCAL_SLUG => 'WPSEO_Local_Core', ]; if ( ! isset( $slug_to_class_map[ $slug ] ) ) { return false; } return class_exists( $slug_to_class_map[ $slug ] ); } /** * Validates the addons and show a notice for the ones that are invalid. * * @return void */ public function validate_addons() { $notification_center = Yoast_Notification_Center::get(); if ( $notification_center === null ) { return; } foreach ( $this->addon_details as $slug => $addon_info ) { $notification = $this->create_notification( $addon_info['name'], $addon_info['short_link_activation'] ); // Add a notification when the installed plugin isn't activated in My Yoast. if ( $this->is_installed( $slug ) && ! $this->has_valid_subscription( $slug ) ) { $notification_center->add_notification( $notification ); continue; } $notification_center->remove_notification( $notification ); } } /** * Checks if the user has any active addons. * * @return bool Whether there are active addons. */ public function has_active_addons() { $active_addons = $this->get_active_addons(); return ! empty( $active_addons ); } /** * Removes the site information transients. * * @codeCoverageIgnore * * @return void */ public function remove_site_information_transients() { delete_transient( self::SITE_INFORMATION_TRANSIENT ); delete_transient( self::SITE_INFORMATION_TRANSIENT_QUICK ); } /** * Creates an instance of Yoast_Notification. * * @param string $product_name The product to create the notification for. * @param string $short_link The short link for the addon notification. * * @return Yoast_Notification The created notification. */ protected function create_notification( $product_name, $short_link ) { $notification_options = [ 'type' => Yoast_Notification::ERROR, 'id' => 'wpseo-dismiss-' . sanitize_title_with_dashes( $product_name, null, 'save' ), 'capabilities' => 'wpseo_manage_options', ]; return new Yoast_Notification( sprintf( /* translators: %1$s expands to a strong tag, %2$s expands to the product name, %3$s expands to a closing strong tag, %4$s expands to an a tag. %5$s expands to MyYoast, %6$s expands to a closing a tag, %7$s expands to the product name */ __( '%1$s %2$s isn\'t working as expected %3$s and you are not receiving updates or support! Make sure to %4$s activate your product subscription in %5$s%6$s to unlock all the features of %7$s.', 'wordpress-seo' ), '', $product_name, '', '', 'MyYoast', '', $product_name ), $notification_options ); } /** * Checks whether a plugin expiry date has been passed. * * @param stdClass $subscription Plugin subscription. * * @return bool Has the plugin expired. */ protected function has_subscription_expired( $subscription ) { return ( strtotime( $subscription->expiry_date ) - time() ) < 0; } /** * Converts a subscription to plugin based format. * * @param stdClass $subscription The subscription to convert. * @param stdClass|null $yoast_free_data The Yoast Free's data. * @param bool $plugin_info Whether we're in the plugin information modal. * @param string $plugin_file The plugin filename. * * @return stdClass The converted subscription. */ protected function convert_subscription_to_plugin( $subscription, $yoast_free_data = null, $plugin_info = false, $plugin_file = '' ) { $changelog = ''; if ( isset( $subscription->product->changelog ) ) { // We need to replace h2's and h3's with h4's because the styling expects that. $changelog = str_replace( 'product->changelog ) ); $changelog = str_replace( ' ( $plugin_info ) ? YOAST_SEO_WP_REQUIRED : null, ]; return (object) [ 'new_version' => ( $subscription->product->version ?? '' ), 'name' => $subscription->product->name, 'slug' => $subscription->product->slug, 'plugin' => $plugin_file, 'url' => $subscription->product->store_url, 'last_update' => $subscription->product->last_updated, 'homepage' => $subscription->product->store_url, 'download_link' => $subscription->product->download, 'package' => $subscription->product->download, 'sections' => [ 'changelog' => $changelog, 'support' => $this->get_support_section(), ], 'icons' => [ '2x' => $this->get_icon( $subscription->product->slug ), ], 'update_supported' => true, 'banners' => $this->get_banners( $subscription->product->slug ), // If we have extracted Yoast Free's data before, use that. If not, resort to the defaults. 'tested' => YOAST_SEO_WP_TESTED, 'requires' => ( $yoast_free_data->requires ?? $defaults['requires'] ), 'requires_php' => YOAST_SEO_PHP_REQUIRED, ]; } /** * Returns the plugin's icon URL. * * @param string $slug The plugin slug. * * @return string The icon URL for this plugin. */ protected function get_icon( $slug ) { switch ( $slug ) { case self::LOCAL_SLUG: return 'https://yoa.st/local-seo-icon'; case self::NEWS_SLUG: return 'https://yoa.st/news-seo-icon'; case self::PREMIUM_SLUG: return 'https://yoa.st/yoast-seo-icon'; case self::VIDEO_SLUG: return 'https://yoa.st/video-seo-icon'; case self::WOOCOMMERCE_SLUG: return 'https://yoa.st/woo-seo-icon'; } } /** * Return an array of plugin banner URLs. * * @param string $slug The plugin slug. * * @return string[] */ protected function get_banners( $slug ) { switch ( $slug ) { case self::LOCAL_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-local', 'low' => 'https://yoa.st/yoast-seo-banner-low-local', ]; case self::NEWS_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-news', 'low' => 'https://yoa.st/yoast-seo-banner-low-news', ]; case self::PREMIUM_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-premium', 'low' => 'https://yoa.st/yoast-seo-banner-low-premium', ]; case self::VIDEO_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-video', 'low' => 'https://yoa.st/yoast-seo-banner-low-video', ]; case self::WOOCOMMERCE_SLUG: return [ 'high' => 'https://yoa.st/yoast-seo-banner-woo', 'low' => 'https://yoa.st/yoast-seo-banner-low-woo', ]; } } /** * Checks if the given plugin_file belongs to a Yoast addon. * * @param string $plugin_file Path to the plugin. * * @return bool Tr بهترین موسسه آموزشی کشور - موسسه آموزشی و فرهنگی کیسان

موسسه بین المللی کیسان ، پرافتخارترین موسسه آموزشی کشور

آموزش تئوری و عملی

( حضوری و آنلاین )

موسسه آموزشی کیسان، بهترین آموزشگاه کنکور کشور با ۸ سال تجربه
پادکست ویدیویی رادیو کیسان
گفتگو با مجله روزهای زندگی
کتاب نوآموزی تا نوآوری

بیش از 7 هزار دانش آموز

برند برتر آموزشی سال ۹۶ تا کنون

تدریس حضوری خصوصی و گروهی

فرم نمایندگی کیسان

جدیدترین دوره های آموزشی کیسان

رایگان!
رایگان!
بدون امتیاز 0 رای
رایگان!
رایگان!
بدون امتیاز 0 رای
رایگان!
رایگان!
دپارتمان کودک و نوجوان کیسان
تست گاردنر

فرصت باقی مانده به لایو رابطه تحصیل با شغل

ثبت نام زود هنگام!

نظرات مشتریان

پیج اینستاگرام کیسان
مشاوره رایگان