/** * @author Vova Feldman (@svovaf) * @since 1.0.7 * * @param string $key * @param mixed $value * @param bool $flush */ function store($key, $value, $flush = true) { if ($this->_logger->is_on()) { $this->_logger->entrance($key . ' = ' . var_export($value, true)); } if (array_key_exists($key, $this->_data) && $value === $this->_data[$key]) { // No need to store data if the value wasn't changed. return; } $all_data = $this->get_all_data(); $this->_data[$key] = $value; $all_data[$this->_slug] = $this->_data; $options_manager = $this->get_option_manager(); $options_manager->set_option($this->_id, $all_data, $flush); }
/** * Modify plugin's page action links collection. * * @author Vova Feldman (@svovaf) * @since 1.0.0 * * @param array $links * @param $file * * @return array */ function _modify_plugin_action_links_hook($links, $file) { $this->_logger->entrance(); ksort($this->_action_links); foreach ($this->_action_links as $new_links) { foreach ($new_links as $link) { $links[$link['key']] = '<a href="' . $link['href'] . '"' . ($link['external'] ? ' target="_blank"' : '') . '>' . $link['label'] . '</a>'; } } return $links; }
/** * @return bool True if successful connectivity to the API. */ function test() { $this->_logger->entrance(); $test = $this->_api->Test(); if (false === $test && $this->_api->IsHttps()) { // Fallback to HTTP, since HTTPS fails. $this->_api->SetHttp(); self::$_options->set_option('api_force_http', true, true); $test = $this->_api->Test(); } return $test; }
/** * Test API connectivity. * * @since 1.0.9 If fails, try to fallback to HTTP. * * @param null|string $unique_anonymous_id * * @return bool True if successful connectivity to the API. */ function test($unique_anonymous_id = null) { $this->_logger->entrance(); $test = is_null($unique_anonymous_id) ? $this->_api->Test() : $this->_api->Test($this->_call('ping.json?uid=' . $unique_anonymous_id)); if (false === $test && $this->_api->IsHttps()) { // Fallback to HTTP, since HTTPS fails. $this->_api->SetHttp(); self::$_options->set_option('api_force_http', true, true); $test = $this->_api->Test(); } return $test; }
/** * Updates information on the "View version x.x details" page with custom data. * * @author Vova Feldman (@svovaf) * @since 1.0.4 * * @uses FS_Api * * @param object $data * @param string $action * @param mixed $args * * @return object */ function plugins_api_filter($data, $action = '', $args = null) { $this->_logger->entrance(); if ('plugin_information' !== $action || !isset($args->slug)) { return $data; } $addon = false; $is_addon = false; if ($this->_fs->get_slug() !== $args->slug) { $addon = $this->_fs->get_addon_by_slug($args->slug); if (!is_object($addon)) { return $data; } $is_addon = true; } $plugin_in_repo = false; if (!$is_addon) { // Try to fetch info from .org repository. $data = self::_fetch_plugin_info_from_repository($action, $args); $plugin_in_repo = false !== $data; } if (!$plugin_in_repo) { $data = $args; // Fetch as much as possible info from local files. $plugin_local_data = $this->_fs->get_plugin_data(); $data->name = $plugin_local_data['Name']; $data->author = $plugin_local_data['Author']; $data->sections = array('description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.'); // @todo Store extra plugin info on Freemius or parse readme.txt markup. /*$info = $this->_fs->get_api_site_scope()->call('/information.json'); if ( !isset($info->error) ) { $data = $info; }*/ } // Get plugin's newest update. $new_version = $this->_fs->_fetch_latest_version($is_addon ? $addon->id : false); if ($is_addon) { $data->name = $addon->title . ' ' . __fs('addon', $this->_fs->get_slug()); $data->slug = $addon->slug; $data->url = WP_FS__ADDRESS; $data->package = $new_version->url; } if (!$plugin_in_repo) { $data->last_updated = !is_null($new_version->updated) ? $new_version->updated : $new_version->created; $data->requires = $new_version->requires_platform_version; $data->tested = $new_version->tested_up_to_version; } $data->version = $new_version->version; $data->download_link = $new_version->url; return $data; }
/** * Dump options to database. * * @author Vova Feldman (@svovaf) * @since 1.0.3 */ function store() { $this->_logger->entrance(); $option_name = $this->_get_option_manager_name(); if ($this->_logger->is_on()) { $this->_logger->info($option_name . ' = ' . var_export($this->_options, true)); } // Update DB. update_option($option_name, $this->_options); if (!WP_FS__DEBUG_SDK) { wp_cache_set($option_name, $this->_options, WP_FS__SLUG); } }
public static function _uninstall_plugin() { self::_load_required_static(); self::$_static_logger->entrance(); if (!current_user_can('activate_plugins')) { return; } $plugin_file = substr(current_filter(), strlen('uninstall_')); self::$_static_logger->info('plugin = ' . $plugin_file); $fs = self::load_instance_by_file($plugin_file); if (is_object($fs)) { $fs->_uninstall_plugin_event(); } }
/** * * @author Vova Feldman (@svovaf) * @since 1.0.9 * * @return array[string]mixed */ function remove_menu_item() { $this->_logger->entrance(); // Find main menu item. $menu = $this->find_top_level_menu(); if (false === $menu) { return $menu; } // Remove it with its actions. remove_all_actions($menu['hook_name']); // Remove all submenu items. $this->remove_all_submenu_items(); return $menu; }
/** * Ping API for connectivity test, and return result object. * * @author Vova Feldman (@svovaf) * @since 1.0.9 * * @param null|string $unique_anonymous_id * @param array $params * * @return object */ function ping($unique_anonymous_id = null, $params = array()) { $this->_logger->entrance(); if (self::is_temporary_down()) { return $this->get_temporary_unavailable_error(); } $pong = is_null($unique_anonymous_id) ? Freemius_Api::Ping() : $this->_call('ping.json?' . http_build_query(array_merge(array('uid' => $unique_anonymous_id), $params))); if ($this->is_valid_ping($pong)) { return $pong; } if (self::should_try_with_http($pong)) { // Fallback to HTTP, since HTTPS fails. Freemius_Api::SetHttp(); self::$_options->set_option('api_force_http', true, true); $pong = is_null($unique_anonymous_id) ? Freemius_Api::Ping() : $this->_call('ping.json?' . http_build_query(array_merge(array('uid' => $unique_anonymous_id), $params))); if (!$this->is_valid_ping($pong)) { self::$_options->set_option('api_force_http', false, true); } } return $pong; }
/** * Modify plugin's page action links collection. * * @author Vova Feldman (@svovaf) * @since 1.0.0 * * @param array $links * @param $file * * @return array */ function _modify_plugin_action_links_hook($links, $file) { $this->_logger->entrance(); $passed_deactivate = false; $deactivate_link = ''; $before_deactivate = array(); $after_deactivate = array(); foreach ($links as $key => $link) { if ('deactivate' === $key) { $deactivate_link = $link; $passed_deactivate = true; continue; } if (!$passed_deactivate) { $before_deactivate[$key] = $link; } else { $after_deactivate[$key] = $link; } } ksort($this->_action_links); foreach ($this->_action_links as $new_links) { foreach ($new_links as $link) { $before_deactivate[$link['key']] = '<a href="' . $link['href'] . '"' . ($link['external'] ? ' target="_blank"' : '') . '>' . $link['label'] . '</a>'; } } if (!empty($deactivate_link)) { if (!$this->is_paying_or_trial() || $this->is_premium()) { /* * This HTML element is used to identify the correct plugin when attaching an event to its Deactivate link. * * If user is paying or in trial and have the free version installed, * assume that the deactivation is for the upgrade process, so this is not needed. */ $deactivate_link .= '<i class="fs-slug" data-slug="' . $this->_slug . '"></i>'; } // Append deactivation link. $before_deactivate['deactivate'] = $deactivate_link; } return array_merge($before_deactivate, $after_deactivate); }
/** * Modify plugin's page action links collection. * * @author Vova Feldman (@svovaf) * @since 1.0.0 * * @param array $links * @param $file * * @return array */ function _modify_plugin_action_links_hook($links, $file) { $this->_logger->entrance(); ksort($this->_action_links); foreach ($this->_action_links as $new_links) { foreach ($new_links as $link) { $links[$link['key']] = '<a href="' . $link['href'] . '"' . ($link['external'] ? ' target="_blank"' : '') . '>' . $link['label'] . '</a>'; } } /* * This HTML element is used to identify the correct plugin when attaching an event to its Deactivate link. * * If user is paying or in trial and have the free version installed, * assume that the deactivation is for the upgrade process, so this is not needed. */ if (!$this->is_paying_or_trial() || $this->is_premium()) { if (isset($links['deactivate'])) { $links['deactivate'] .= '<i class="fs-slug" data-slug="' . $this->_slug . '"></i>'; } } return $links; }
/** * Purge cached item. * * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key */ function purge($key) { $this->_logger->entrance('key = ' . $key); $this->_options->unset_option($key, true); }
/** * 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', false); 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); 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 = '<p>Tell your users all about your add-on</p>'; } fs_enqueue_local_style('fs_addons', '/admin/add-ons.css'); $data = $args; $is_free = true; // Load add-on pricing. $has_pricing = false; $has_features = false; $plans = false; $plans_result = $this->_fs->get_api_site_or_plugin_scope()->get("/addons/{$selected_addon->id}/plans.json"); if (!isset($plans_result->error)) { $plans = $plans_result->plans; if (is_array($plans)) { for ($i = 0, $len = count($plans); $i < $len; $i++) { $plans[$i] = new FS_Plugin_Plan($plans[$i]); $plan = $plans[$i]; $pricing_result = $this->_fs->get_api_site_or_plugin_scope()->get("/addons/{$selected_addon->id}/plans/{$plan->id}/pricing.json"); if (!isset($pricing_result->error)) { // Update plan's pricing. $plan->pricing = $pricing_result->pricing; if (is_array($plan->pricing) && !empty($plan->pricing)) { $is_free = false; foreach ($plan->pricing as &$pricing) { $pricing = new FS_Pricing($pricing); } } $has_pricing = true; } $features_result = $this->_fs->get_api_site_or_plugin_scope()->get("/addons/{$selected_addon->id}/plans/{$plan->id}/features.json"); if (!isset($features_result->error) && is_array($features_result->features) && 0 < count($features_result->features)) { // Update plan's pricing. $plan->features = $features_result->features; $has_features = true; } } } } // Fetch latest version from Freemius. $latest = $this->_fs->_fetch_latest_version($selected_addon->id); if (!$is_free) { // If paid add-on, then it's not on wordpress.org $is_wordpress_org = false; } else { // If no versions found, then assume it's a .org plugin. $is_wordpress_org = false === $latest; } if ($is_wordpress_org) { $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. $is_wordpress_org = false; // Plugin is missing, not on Freemius nor WP.org. $data->wp_org_missing = true; } } if (!$is_wordpress_org) { $data->checkout_link = $this->_fs->checkout_url(); $data->fs_missing = false === $latest; if ($is_free) { $data->download_link = $this->_fs->_get_latest_download_local_url($selected_addon->id); } } if (!$is_wordpress_org) { // Fetch as much as possible info from local files. $plugin_local_data = $this->_fs->get_plugin_data(); $data->name = $selected_addon->title; $data->author = $plugin_local_data['Author']; $view_vars = array('plugin' => $selected_addon); $data->sections = array('description' => fs_get_template('/plugin-info/description.php', $view_vars)); 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 = !is_null($latest->updated) ? $latest->updated : $latest->created; $data->requires = $latest->requires_platform_version; $data->tested = $latest->tested_up_to_version; } else { // Add dummy version. $data->version = '1.0.0'; // Add message to developer to deploy the plugin through Freemius. } } 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->is_paid = !$is_free; $data->external = !$is_wordpress_org; return $data; }