_fs = $fs; $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $fs->get_slug() . '_info', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); // Remove default plugin information action. remove_all_actions( 'install_plugins_pre_plugin-information' ); // Override action with custom plugins function for add-ons. add_action( 'install_plugins_pre_plugin-information', array( &$this, 'install_plugin_information' ) ); // Override request for plugin information for Add-ons. add_filter( 'fs_plugins_api', array( &$this, '_get_addon_info_filter' ), WP_FS__DEFAULT_PRIORITY, 3 ); } /** * Generate add-on plugin information. * * @author Vova Feldman (@svovaf) * @since 1.0.6 * * @param array $data * @param string $action * @param object|null $args * * @return array|null */ function _get_addon_info_filter( $data, $action = '', $args = null ) { $this->_logger->entrance(); $parent_plugin_id = fs_request_get( 'parent_plugin_id', $this->_fs->get_id() ); if ( $this->_fs->get_id() != $parent_plugin_id || ( 'plugin_information' !== $action ) || ! isset( $args->slug ) ) { return $data; } // Find add-on by slug. $selected_addon = $this->_fs->get_addon_by_slug( $args->slug, WP_FS__DEV_MODE ); if ( false === $selected_addon ) { return $data; } if ( ! isset( $selected_addon->info ) ) { // Setup some default info. $selected_addon->info = new stdClass(); $selected_addon->info->selling_point_0 = 'Selling Point 1'; $selected_addon->info->selling_point_1 = 'Selling Point 2'; $selected_addon->info->selling_point_2 = 'Selling Point 3'; $selected_addon->info->description = '
Tell your users all about your add-on
'; } fs_enqueue_local_style( 'fs_addons', '/admin/add-ons.css' ); $data = $args; $has_free_plan = false; $has_paid_plan = false; // Load add-on pricing. $has_pricing = false; $has_features = false; $plans = false; $result = $this->_fs->get_api_plugin_scope()->get( $this->_fs->add_show_pending( "/addons/{$selected_addon->id}/pricing.json?type=visible" ) ); if ( ! isset( $result->error ) ) { $plans = $result->plans; if ( is_array( $plans ) ) { for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) { $pricing = isset( $plans[ $i ]->pricing ) ? $plans[ $i ]->pricing : null; $features = isset( $plans[ $i ]->features ) ? $plans[ $i ]->features : null; $plans[ $i ] = new FS_Plugin_Plan( $plans[ $i ] ); $plan = $plans[ $i ]; if ( 'free' == $plans[ $i ]->name || ! is_array( $pricing ) || 0 == count( $pricing ) ) { $has_free_plan = true; } if ( is_array( $pricing ) && 0 < count( $pricing ) ) { $filtered_pricing = array(); foreach ( $pricing as $prices ) { $prices = new FS_Pricing( $prices ); if ( ! $prices->is_usd() ) { /** * Skip non-USD pricing. * * @author Leo Fajardo (@leorw) * @since 2.3.1 */ continue; } if ( ( $prices->has_monthly() && $prices->monthly_price > 1.0 ) || ( $prices->has_annual() && $prices->annual_price > 1.0 ) || ( $prices->has_lifetime() && $prices->lifetime_price > 1.0 ) ) { $filtered_pricing[] = $prices; } } if ( ! empty( $filtered_pricing ) ) { $has_paid_plan = true; $plan->pricing = $filtered_pricing; $has_pricing = true; } } if ( is_array( $features ) && 0 < count( $features ) ) { $plan->features = $features; $has_features = true; } } } } $latest = null; if ( ! $has_paid_plan && $selected_addon->is_wp_org_compliant ) { $repo_data = FS_Plugin_Updater::_fetch_plugin_info_from_repository( 'plugin_information', (object) array( 'slug' => $selected_addon->slug, 'is_ssl' => is_ssl(), 'fields' => array( 'banners' => true, 'reviews' => true, 'downloaded' => false, 'active_installs' => true ) ) ); if ( ! empty( $repo_data ) ) { $data = $repo_data; $data->wp_org_missing = false; } else { // Couldn't find plugin on .org. $selected_addon->is_wp_org_compliant = false; // Plugin is missing, not on Freemius nor WP.org. $data->wp_org_missing = true; } $data->fs_missing = ( ! $has_free_plan || $data->wp_org_missing ); } else { $data->has_purchased_license = false; $data->wp_org_missing = false; $fs_addon = null; $current_addon_version = false; if ( $this->_fs->is_addon_activated( $selected_addon->id ) ) { $fs_addon = $this->_fs->get_addon_instance( $selected_addon->id ); $current_addon_version = $fs_addon->get_plugin_version(); } else if ( $this->_fs->is_addon_installed( $selected_addon->id ) ) { $addon_plugin_data = get_plugin_data( ( WP_PLUGIN_DIR . '/' . $this->_fs->get_addon_basename( $selected_addon->id ) ), false, false ); if ( ! empty( $addon_plugin_data ) ) { $current_addon_version = $addon_plugin_data['Version']; } } // Fetch latest version from Freemius. $latest = $this->_fs->_fetch_latest_version( $selected_addon->id, true, WP_FS__TIME_24_HOURS_IN_SEC, $current_addon_version ); if ( $has_paid_plan ) { $blog_id = fs_request_get( 'fs_blog_id' ); $has_valid_blog_id = is_numeric( $blog_id ); if ( $has_valid_blog_id ) { switch_to_blog( $blog_id ); } $data->checkout_link = $this->_fs->checkout_url( WP_FS__PERIOD_ANNUALLY, false, array(), ( $has_valid_blog_id ? false : null ) ); if ( $has_valid_blog_id ) { restore_current_blog(); } } /** * Check if there's a purchased license in case the add-on can only be installed/downloaded as part of a purchased bundle. * * @author Leo Fajardo (@leorw) * @since 2.4.1 */ if ( is_object( $fs_addon ) ) { $data->has_purchased_license = $fs_addon->has_active_valid_license(); } else { $account_addons = $this->_fs->get_account_addons(); if ( ! empty( $account_addons ) && in_array( $selected_addon->id, $account_addons ) ) { $data->has_purchased_license = true; } } if ( $has_free_plan || $data->has_purchased_license ) { $data->download_link = $this->_fs->_get_latest_download_local_url( $selected_addon->id ); } $data->fs_missing = ( false === $latest && ( empty( $selected_addon->premium_releases_count ) || ! ( $selected_addon->premium_releases_count > 0 ) ) ); // Fetch as much as possible info from local files. $plugin_local_data = $this->_fs->get_plugin_data(); $data->author = $plugin_local_data['Author']; if ( ! empty( $selected_addon->info->banner_url ) ) { $data->banners = array( 'low' => $selected_addon->info->banner_url, ); } if ( ! empty( $selected_addon->info->screenshots ) ) { $view_vars = array( 'screenshots' => $selected_addon->info->screenshots, 'plugin' => $selected_addon, ); $data->sections['screenshots'] = fs_get_template( '/plugin-info/screenshots.php', $view_vars ); } if ( is_object( $latest ) ) { $data->version = $latest->version; $data->last_updated = $latest->created; $data->requires = $latest->requires_platform_version; $data->requires_php = $latest->requires_programming_language_version; $data->tested = $latest->tested_up_to_version; } else if ( ! empty( $current_addon_version ) ) { $data->version = $current_addon_version; } else { // Add dummy version. $data->version = '1.0.0'; // Add message to developer to deploy the plugin through Freemius. } } $data->name = $selected_addon->title; $view_vars = array( 'plugin' => $selected_addon ); if ( is_object( $latest ) && isset( $latest->readme ) && is_object( $latest->readme ) ) { $latest_version_readme_data = $latest->readme; if ( isset( $latest_version_readme_data->sections ) ) { $data->sections = (array) $latest_version_readme_data->sections; } else { $data->sections = array(); } } $data->sections['description'] = fs_get_template( '/plugin-info/description.php', $view_vars ); if ( $has_pricing ) { // Add plans to data. $data->plans = $plans; if ( $has_features ) { $view_vars = array( 'plans' => $plans, 'plugin' => $selected_addon, ); $data->sections['features'] = fs_get_template( '/plugin-info/features.php', $view_vars ); } } $data->has_free_plan = $has_free_plan; $data->has_paid_plan = $has_paid_plan; $data->is_paid = $has_paid_plan; $data->is_wp_org_compliant = $selected_addon->is_wp_org_compliant; $data->premium_slug = $selected_addon->premium_slug; $data->addon_id = $selected_addon->id; if ( ! isset( $data->has_purchased_license ) ) { $data->has_purchased_license = false; } return $data; } /** * @author Vova Feldman (@svovaf) * @since 1.1.7 * * @param FS_Plugin_Plan $plan * * @return string */ private function get_billing_cycle( FS_Plugin_Plan $plan ) { $billing_cycle = null; if ( 1 === count( $plan->pricing ) && 1 == $plan->pricing[0]->licenses ) { $pricing = $plan->pricing[0]; if ( isset( $pricing->annual_price ) ) { $billing_cycle = 'annual'; } else if ( isset( $pricing->monthly_price ) ) { $billing_cycle = 'monthly'; } else if ( isset( $pricing->lifetime_price ) ) { $billing_cycle = 'lifetime'; } } else { foreach ( $plan->pricing as $pricing ) { if ( isset( $pricing->annual_price ) ) { $billing_cycle = 'annual'; } else if ( isset( $pricing->monthly_price ) ) { $billing_cycle = 'monthly'; } else if ( isset( $pricing->lifetime_price ) ) { $billing_cycle = 'lifetime'; } if ( ! is_null( $billing_cycle ) ) { break; } } } return $billing_cycle; } /** * @author Vova Feldman (@svovaf) * @since 2.0.0 * * @param FS_Plugin_Plan $plan * @param FS_Pricing $pricing * * @return float|null|string */ private function get_price_tag( FS_Plugin_Plan $plan, FS_Pricing $pricing ) { $price_tag = ''; if ( isset( $pricing->annual_price ) ) { $price_tag = $pricing->annual_price . ( $plan->is_block_features ? ' / year' : '' ); } else if ( isset( $pricing->monthly_price ) ) { $price_tag = $pricing->monthly_price . ' / mo'; } else if ( isset( $pricing->lifetime_price ) ) { $price_tag = $pricing->lifetime_price; } return '$' . $price_tag; } /** * @author Leo Fajardo (@leorw) * @since 2.3.0 * * @param object $api * @param FS_Plugin_Plan $plan * * @return string */ private function get_actions_dropdown( $api, $plan = null ) { $this->actions = isset( $this->actions ) ? $this->actions : $this->get_plugin_actions( $api ); $actions = $this->actions; $checkout_cta = $this->get_checkout_cta( $api, $plan ); if ( ! empty( $checkout_cta ) ) { /** * If there's no license yet, make the checkout button the main CTA. Otherwise, make it the last item in * the actions dropdown. * * @author Leo Fajardo (@leorw) * @since 2.3.0 */ if ( ! $api->has_purchased_license ) { array_unshift( $actions, $checkout_cta ); } else { $actions[] = $checkout_cta; } } if ( empty( $actions ) ) { return ''; } $total_actions = count( $actions ); if ( 1 === $total_actions ) { return $actions[0]; } ob_start(); ?>' . fs_text_inline( 'Error', 'error', $api->slug ) . ': ' . fs_text_inline( 'This plugin requires a newer version of PHP.', 'newer-php-required-error', $api->slug ); if ( current_user_can( 'update_php' ) ) { $wp_get_update_php_url = function_exists( 'wp_get_update_php_url' ) ? wp_get_update_php_url() : 'https://wordpress.org/support/update-php/'; printf( /* translators: %s: URL to Update PHP page. */ ' ' . fs_text_inline( 'Click here to learn more about updating PHP.', 'php-update-learn-more-link', $api->slug ), esc_url( $wp_get_update_php_url ) ); if ( function_exists( 'wp_update_php_annotation' ) ) { wp_update_php_annotation( '
', '' ); } } else { echo '
'; } echo '' . '' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ': ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '
' . '' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ': ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '