From 3828fe8705db0e8482c40f975c047fe912b980bd Mon Sep 17 00:00:00 2001 From: Chuck Scott Date: Fri, 7 Oct 2016 10:16:13 -0400 Subject: [PATCH] Testing update server communications --- defines.php | 6 + index.php | 13 +- .../css/opentools-updatecheck.css | 23 ++ .../js/opentools-updatecheck.js | 76 ++++++ .../opentools-update-checker.php | 250 ++++++++++++++++++ .../plugin-update-checker.php | 173 ++++++------ 6 files changed, 452 insertions(+), 89 deletions(-) create mode 100644 lib/opentools-update-checker/css/opentools-updatecheck.css create mode 100644 lib/opentools-update-checker/js/opentools-updatecheck.js create mode 100644 lib/opentools-update-checker/opentools-update-checker.php diff --git a/defines.php b/defines.php index 8647c5e..29d59bf 100644 --- a/defines.php +++ b/defines.php @@ -31,6 +31,12 @@ $pageUri = explode('?', $_SERVER['REQUEST_URI']); // Bust this up // Enable to display smarty template debug. define('GLM_SERVERSTATS_PLUGIN_DEBUG_SMARTY', false); +/* + * Create a copy of the plugin slug that can be used as a variable prefix used to keep + * global instances from clashing with instances in other plugins. + */ +$vprefix = str_replace('-', '_', GLM_SERVERSTATS_PLUGIN_SLUG); +define('GLM_SERVERSTATS_PREFIX', $vprefix.'_'); // URLs define('GLM_SERVERSTATS_SITE_BASE_URL', home_url('/') ); diff --git a/index.php b/index.php index fd90db8..6231550 100644 --- a/index.php +++ b/index.php @@ -161,13 +161,20 @@ function serverStatsController($model) /* * Plugin Update Support - uses Gaslight Media update server */ -require GLM_SERVERSTATS_PLUGIN_LIB_PATH.'/plugin-update-checker/plugin-update-checker.php'; -$MyUpdateChecker = PucFactory::buildUpdateChecker( - 'http://gaslightmedia.gaslightmedia.com/update_server/?action=get_metadata&slug='.GLM_SERVERSTATS_PLUGIN_SLUG, +require GLM_SERVERSTATS_PLUGIN_LIB_PATH.'/opentools-update-checker/opentools-update-checker.php'; +${GLM_SERVERSTATS_PREFIX."updateChecker"} = new OpenToolsPluginUpdateChecker( +// 'http://gaslightmedia.gaslightmedia.com/GlmUpdateServer/?action=get_metadata&slug='.GLM_SERVERSTATS_PLUGIN_SLUG, + 'http://192.168.44.51/update_server/?action=get_metadata&slug='.GLM_SERVERSTATS_PLUGIN_SLUG, __FILE__, GLM_SERVERSTATS_PLUGIN_SLUG ); +${GLM_SERVERSTATS_PREFIX."updateChecker"}->declareCredentials(array( + 'license_key' => __('License Key:') +)); + + + /* * * Activate and Deactivate hooks diff --git a/lib/opentools-update-checker/css/opentools-updatecheck.css b/lib/opentools-update-checker/css/opentools-updatecheck.css new file mode 100644 index 0000000..e0ed451 --- /dev/null +++ b/lib/opentools-update-checker/css/opentools-updatecheck.css @@ -0,0 +1,23 @@ + +tr.otup_update_credentials .update-credentials { + margin: 0 10px 8px 31px; + padding: 6px 12px 8px 40px; + background-color: #f7f7f7; + background-color: rgba(0,0,0,.03); +} + +.widefat tr.otup_update_credentials th input, .widefat tr.otup_update_credentials thead td input { + /* margin: 0 0 0 8px; */ + padding: inherit; + vertical-align: inherit; +} + +tr.otup_update_credentials div.message-fail { + background-color: #FFBFBF; + padding: 3px; +} + +tr.otup_update_credentials div.message-success { + background-color: #BFFFBF; + padding: 3px; +} diff --git a/lib/opentools-update-checker/js/opentools-updatecheck.js b/lib/opentools-update-checker/js/opentools-updatecheck.js new file mode 100644 index 0000000..662a5cf --- /dev/null +++ b/lib/opentools-update-checker/js/opentools-updatecheck.js @@ -0,0 +1,76 @@ +/** + * OpenTools Update Check Admin JS + */ +var showUpdateCredentialsRow = function (btn) { + if (showUpdateCredentialsRow.credentialsRowDisplayed) { + return; + } + showUpdateCredentialsRow.credentialsRowDisplayed = true; + var ajaxurl = jQuery(btn).data('ajaxurl'); + var slug = jQuery(btn).data("slug"); + var nonce = jQuery(btn).data("nonce"); + var ajaxargs = { + type: "POST", + url: ajaxurl, + data: { + action: 'getUpdateCredentialsRow', + slug: slug, + _ajax_nonce: nonce + }, + success: function ( json ) { + jQuery(btn).closest('tr').after(json['row']); + }, + error: function() { }, + complete: function() { }, + }; + jQuery.ajax(ajaxargs); + return false; +}; + +var submitUpdateCredentials = function(btn) { + var ajaxurl = jQuery(btn).data('ajaxurl'); + var slug = jQuery(btn).data("slug"); + var nonce = jQuery(btn).data("nonce"); + // the credentialvars data field contains a json-encoded array of variables! + var credentialvars = jQuery(btn).data("credentialvars"); + + var tr = jQuery(btn).closest('tr'); + var data = { + action: 'submitUpdateCredentials', + slug: slug, + _ajax_nonce: nonce, + }; + + var index; + for (index = 0; index < credentialvars.length; index++) { + var credname = credentialvars[index]; + data[credname] = jQuery(tr).find("input[name='otup_update_credentials["+slug+"]["+credname+"]']").val(); + } + + var ajaxargs = { + type: "POST", + url: ajaxurl, + data: data, + success: function ( json ) { + if (json['success']) { + jQuery(tr).find('div.update-credentials-message').html(json['message']); + jQuery(tr).find('div.update-credentials').removeClass('message-fail').addClass('message-success') + jQuery(tr).find('div.update-credentials-form').fadeOut( 500, function() { jQuery(this).remove(); }); + jQuery(tr).closest('table').find('a.otup_credentials_link_'+slug).removeClass('dashicons-no').addClass('dashicons-yes'); + jQuery(tr).delay(5000).fadeOut(1000, function() { jQuery(this).remove(); }); + + } else { + jQuery(tr).find('div.update-credentials-message').html(json['message']); + jQuery(tr).find('div.update-credentials').addClass('message-fail').removeClass('message-success'); + jQuery(tr).closest('table').find('a.otup_credentials_link_'+slug).removeClass('dashicons-yes').addClass('dashicons-no'); + } + }, + error: function() { + jQuery(tr).find('div.update-credentials-message').html("Unable to validate the update credentials. Please make sure the server is available."); + jQuery(tr).find('div.update-credentials').addClass('message-fail').removeClass('message-success'); + }, + complete: function() { }, + }; + jQuery.ajax(ajaxargs); + return false; +} \ No newline at end of file diff --git a/lib/opentools-update-checker/opentools-update-checker.php b/lib/opentools-update-checker/opentools-update-checker.php new file mode 100644 index 0000000..a4f4ad5 --- /dev/null +++ b/lib/opentools-update-checker/opentools-update-checker.php @@ -0,0 +1,250 @@ +installOTHooks(); + } + public function declareCredentials($credential_def) { + $this->credvars = $credential_def; + // Append the update credentials to the update server link + $this->addQueryArgFilter(array($this, 'appendQueryArgsCredentials')); + + } + + protected function installOTHooks() + { + $this->ajaxurl = is_network_admin()?network_admin_url( 'admin-ajax.php' ): admin_url( 'admin-ajax.php' ); + + add_action('admin_print_scripts-plugins.php', array($this, 'addCredentialCheckScripts')); + add_action('admin_print_styles-plugins.php', array($this, 'addCredentialCheckStyles')); + +// add_filter('plugin_row_meta', array($this, 'displayUpdateCredentialsLink'), 9, 2); + add_filter('plugin_action_links_'.$this->pluginFile, array($this, 'displayUpdateCredentialsLink'), 9, 2); + + add_action( 'wp_ajax_getUpdateCredentialsRow', array( &$this, 'getUpdateCredentialsRow') ); + add_action( 'wp_ajax_submitUpdateCredentials', array( &$this, 'submitUpdateCredentials') ); + } + + protected function getCredentials($slug) + { + $credentials = array('validated' => FALSE); + foreach ($this->credvars as $credkey => $credname) { + $credentials[$credkey] = get_option('otup_credentials_'.$slug.'_'.$credkey); + } + $credentials['validated'] = get_option('otup_credentials_validated_'.$slug); + return $credentials; + } + + protected function setCredentials($slug, $credentials, $validated = false) + { + foreach ($credentials as $credkey => $credvalue) { + update_option('otup_credentials_'.$slug.'_'.$credkey, $credvalue, false); + } + update_option('otup_credentials_validated_'.$slug, $validated, false); + } + + + public function addCredentialCheckScripts() { + wp_register_script( 'opentools-updatecheck', plugins_url('js/opentools-updatecheck.js', __FILE__), array('jquery')); + wp_enqueue_script( 'opentools-updatecheck'); + } + + public function addCredentialCheckStyles() { + wp_register_style( 'opentools-updatecheck', plugins_url('css/opentools-updatecheck.css', __FILE__)); + wp_enqueue_style( 'opentools-updatecheck'); + } + + /** Append the ordernumber and order password to the update server URL + */ + public function appendQueryArgsCredentials($queryArgs) { + $credentials = $this->getCredentials($this->slug); + foreach ($credentials as $credkey => $credvalue) { + $queryArgs[$credkey] = $credvalue; + } + return $queryArgs; + } + + /** + * Add a "Update Credentials" link to the plugin row in the "Plugins" page. By default, + * the new link will appear after the "Visit plugin site" link. + * + * You can change the link text by using the "otup_enter_update_credentials-$slug" filter. + * Returning an empty string from the filter will disable the link. + * + * @param array $pluginMeta Array of meta links. + * @param string $pluginFile + * @return array + */ + public function displayUpdateCredentialsLink($links, $pluginFile) { + $isRelevant = ($pluginFile == $this->pluginFile) + || (!empty($this->muPluginFile) && $pluginFile == $this->muPluginFile); + $isRelevant = $isRelevant && !empty($this->credvars); + + if ( $isRelevant && current_user_can('update_plugins') ) { + $credentials = $this->getCredentials($this->slug); + $textcolor = $credentials['validated']?'':''; + $linkText = apply_filters('otup_enter_update_credentials-' . $this->slug, $textcolor.__('Update License Key', 'oton-updates').''); + if ( !empty($linkText) ) { + $iconyesno = $credentials['validated']?'yes':'no'; + $link = sprintf('%s', esc_attr($this->slug), esc_attr(wp_create_nonce( 'otup_enter_update_credentials' )), esc_attr($this->ajaxurl), $linkText); + array_unshift($links, $link); + } + } + return $links; + } + + + /** + * If the user has clicked on the "Update Credentials" link, display the input boxes after the plugin row. + * + * @param string $file + * @param array $plugin_data + * @return false|void + */ + public function getUpdateCredentialsRow() { + $json = array('row' => '', 'message'=>'Unsuccessful'); + + $showCredentials = isset($_REQUEST['slug']) + && $_REQUEST['slug'] == $this->slug + && current_user_can('update_plugins') + && check_ajax_referer('otup_enter_update_credentials'); + $showCredentials = $showCredentials && !empty($this->credvars); + + if ( $showCredentials && (is_network_admin() || !is_multisite() )) { + $slug = $this->slug; + if ( is_network_admin() ) { + $active_class = is_plugin_active_for_network( $this->pluginFile ) ? 'active': ''; + } else { + $active_class = is_plugin_active( $this->pluginFile ) ? 'active' : ''; + } + + $current_credentials = $this->getCredentials($slug); + + $tr = ''; + $tr .= ''; + $tr .= '
'; + $tr .= '
'; + $tr .= '
'; + $tr .= '
'; + + foreach ($this->credvars as $credkey => $credname) { + $tr .= $credname . "    "; + } + + $tr .= sprintf('', + esc_attr($this->slug), + esc_attr(wp_create_nonce( 'otup_enter_update_credentials_'.$slug )), + esc_attr($this->ajaxurl), + esc_attr(json_encode(array_keys($this->credvars))) + ); + + $tr .= '
'; + $tr .= '
'; + $json['row'] = $tr; + $json['message'] = ''; + } else { + $json['message'] = __("No permissions to modify update credentials", "opentools-updatecheck"); + } + wp_send_json($json); + } + + + /** + * Check the submitted update credentials for correctness and save them + * + * @return void + */ + public function submitUpdateCredentials() { + $json = array('message' => '', 'success' => FALSE); + $slug = isset($_REQUEST['slug'])?($_REQUEST['slug']):"INVALIDSLUG"; + + $submitCredentials = $slug == $this->slug + && current_user_can('update_plugins') + && check_ajax_referer('otup_enter_update_credentials_'.$slug); + $submitCredentials = $submitCredentials && !empty($this->credvars); + + if ( $submitCredentials ) { + $credentials = array(); + foreach ($this->credvars as $credkey=>$credname) { + if (isset($_REQUEST[$credkey])) { + $credentials[$credkey] = $_REQUEST[$credkey]; + } + } + + $message = ""; + $validated = $this->checkUpdateCredentials($credentials, $message); + $this->setCredentials($this->slug, $credentials, $validated); + + $json['success'] = $validated; + + if ($validated) { + if ( is_network_admin() ) { + $active_class = is_plugin_active_for_network( $this->pluginFile ) ? 'active': ''; + } else { + $active_class = is_plugin_active( $this->pluginFile ) ? 'active' : ''; + } + + $json['message'] .= __("License Key accepted. Automatic updates for this plugin are enabled.", "opentools-updatecheck"); + } else { + $json['message'] = $message; + } + } else { + $json['message'] = __("No permissions to modify update credentials", "opentools-updatecheck"); + } + wp_send_json($json); + } + + public function checkUpdateCredentials($credentials, &$message) + { + $this->setCredentials($this->slug, $credentials); + $success = FALSE; + $updateinfo = $this->requestInfo(array()); + + if ($updateinfo && isset($updateinfo->download_url)) { + $downloadurl = $updateinfo->download_url; + $downloadurl = apply_filters('puc_check_download_query_args-'.$this->slug, $downloadurl); + + $headers = get_headers($downloadurl); + list($version, $status_code, $msg) = explode(' ',$headers[0], 3); + + // Check the HTTP Status code + $message = $msg; + $success = ($status_code==200); + } else { + $message = __('Unable to verify your License Key. Please check your License Key and try again.'); + } + return $success; + } + + public function addAccessCheckQueryArgFilter($callback){ + add_filter('puc_check_download_query_args-'.$this->slug, $callback); + } + +}; + +endif; + + + +// ***************************************************************** diff --git a/lib/plugin-update-checker/plugin-update-checker.php b/lib/plugin-update-checker/plugin-update-checker.php index a894844..0193de2 100644 --- a/lib/plugin-update-checker/plugin-update-checker.php +++ b/lib/plugin-update-checker/plugin-update-checker.php @@ -2,7 +2,7 @@ /** * Plugin Update Checker Library 3.1 * http://w-shadow.com/ - * + * * Copyright 2016 Janis Elsts * Released under the MIT license. See license.txt for details. */ @@ -10,8 +10,8 @@ if ( !class_exists('PluginUpdateChecker_3_1', false) ): /** - * A custom plugin update checker. - * + * A custom plugin update checker. + * * @author Janis Elsts * @copyright 2016 * @version 3.0 @@ -60,7 +60,7 @@ class PluginUpdateChecker_3_1 { if ( empty($this->slug) ){ $this->slug = basename($this->pluginFile, '.php'); } - + if ( empty($this->optionName) ){ $this->optionName = 'external_updates-' . $this->slug; } @@ -89,17 +89,17 @@ class PluginUpdateChecker_3_1 { protected function createScheduler($checkPeriod) { return new PucScheduler_3_1($this, $checkPeriod); } - + /** - * Install the hooks required to run periodic update checks and inject update info - * into WP data structures. - * + * Install the hooks required to run periodic update checks and inject update info + * into WP data structures. + * * @return void */ protected function installHooks(){ //Override requests for plugin information add_filter('plugins_api', array($this, 'injectInfo'), 20, 3); - + //Insert our update info into the update array maintained by WP. add_filter('site_transient_update_plugins', array($this,'injectUpdate')); //WP 3.0+ add_filter('transient_update_plugins', array($this,'injectUpdate')); //WP 2.8+ @@ -133,7 +133,7 @@ class PluginUpdateChecker_3_1 { $this->metadataHost = @parse_url($this->metadataUrl, PHP_URL_HOST); add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2); } - + /** * Explicitly allow HTTP requests to the metadata URL. * @@ -161,9 +161,9 @@ class PluginUpdateChecker_3_1 { /** * Retrieve plugin info from the configured API endpoint. - * + * * @uses wp_remote_get() - * + * * @param array $queryArgs Additional query arguments to append to the request. Optional. * @return PluginInfo_3_1 */ @@ -172,7 +172,7 @@ class PluginUpdateChecker_3_1 { $installedVersion = $this->getInstalledVersion(); $queryArgs['installed_version'] = ($installedVersion !== null) ? $installedVersion : ''; $queryArgs = apply_filters('puc_request_info_query_args-'.$this->slug, $queryArgs); - + //Various options for the wp_remote_get() call. Plugins can filter these, too. $options = array( 'timeout' => 10, //seconds @@ -181,13 +181,13 @@ class PluginUpdateChecker_3_1 { ), ); $options = apply_filters('puc_request_info_options-'.$this->slug, $options); - + //The plugin info should be at 'http://your-api.com/url/here/$slug/info.json' - $url = $this->metadataUrl; + $url = $this->metadataUrl; if ( !empty($queryArgs) ){ $url = add_query_arg($queryArgs, $url); } - + $result = wp_remote_get( $url, $options @@ -221,6 +221,7 @@ class PluginUpdateChecker_3_1 { * @return true|WP_Error */ private function validateApiResponse($result) { + if ( is_wp_error($result) ) { /** @var WP_Error $result */ return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message()); } @@ -251,7 +252,7 @@ class PluginUpdateChecker_3_1 { * @return PluginUpdate_3_1 An instance of PluginUpdate, or NULL when no updates are available. */ public function requestUpdate(){ - //For the sake of simplicity, this function just calls requestInfo() + //For the sake of simplicity, this function just calls requestInfo() //and transforms the result accordingly. $pluginInfo = $this->requestInfo(array('checking_for_updates' => '1')); if ( $pluginInfo == null ){ @@ -299,10 +300,10 @@ class PluginUpdateChecker_3_1 { return $applicableTranslations; } - + /** * Get the currently installed version of the plugin. - * + * * @return string Version number. */ public function getInstalledVersion(){ @@ -376,20 +377,20 @@ class PluginUpdateChecker_3_1 { $state->checkedVersion = ''; $state->update = null; } - + $state->lastCheck = time(); $state->checkedVersion = $installedVersion; - $this->setUpdateState($state); //Save before checking in case something goes wrong - + $this->setUpdateState($state); //Save before checking in case something goes wrong + $state->update = $this->requestUpdate(); $this->setUpdateState($state); return $this->getUpdate(); } - + /** * Load the update checker state from the DB. - * + * * @return stdClass|null */ public function getUpdateState() { @@ -403,11 +404,11 @@ class PluginUpdateChecker_3_1 { } return $state; } - - + + /** * Persist the update checker state to the DB. - * + * * @param StdClass $state * @return void */ @@ -428,13 +429,13 @@ class PluginUpdateChecker_3_1 { public function resetUpdateState() { delete_site_option($this->optionName); } - + /** - * Intercept plugins_api() calls that request information about our plugin and - * use the configured API endpoint to satisfy them. - * + * Intercept plugins_api() calls that request information about our plugin and + * use the configured API endpoint to satisfy them. + * * @see plugins_api() - * + * * @param mixed $result * @param string $action * @param array|object $args @@ -447,19 +448,19 @@ class PluginUpdateChecker_3_1 { if ( !$relevant ) { return $result; } - + $pluginInfo = $this->requestInfo(); $pluginInfo = apply_filters('puc_pre_inject_info-' . $this->slug, $pluginInfo); if ( $pluginInfo ) { return $pluginInfo->toWpFormat(); } - + return $result; } - + /** * Insert the latest update (if any) into the update list maintained by WP. - * + * * @param StdClass $updates Update list. * @return StdClass Modified update list. */ @@ -859,48 +860,48 @@ class PluginUpdateChecker_3_1 { } /** - * Register a callback for filtering query arguments. - * + * Register a callback for filtering query arguments. + * * The callback function should take one argument - an associative array of query arguments. * It should return a modified array of query arguments. - * + * * @uses add_filter() This method is a convenience wrapper for add_filter(). - * + * * @param callable $callback * @return void */ public function addQueryArgFilter($callback){ add_filter('puc_request_info_query_args-'.$this->slug, $callback); } - + /** * Register a callback for filtering arguments passed to wp_remote_get(). - * + * * The callback function should take one argument - an associative array of arguments - * and return a modified array or arguments. See the WP documentation on wp_remote_get() - * for details on what arguments are available and how they work. - * + * for details on what arguments are available and how they work. + * * @uses add_filter() This method is a convenience wrapper for add_filter(). - * + * * @param callable $callback * @return void */ public function addHttpRequestArgFilter($callback){ add_filter('puc_request_info_options-'.$this->slug, $callback); } - + /** * Register a callback for filtering the plugin info retrieved from the external API. - * - * The callback function should take two arguments. If the plugin info was retrieved - * successfully, the first argument passed will be an instance of PluginInfo. Otherwise, - * it will be NULL. The second argument will be the corresponding return value of + * + * The callback function should take two arguments. If the plugin info was retrieved + * successfully, the first argument passed will be an instance of PluginInfo. Otherwise, + * it will be NULL. The second argument will be the corresponding return value of * wp_remote_get (see WP docs for details). - * + * * The callback function should return a new or modified instance of PluginInfo or NULL. - * + * * @uses add_filter() This method is a convenience wrapper for add_filter(). - * + * * @param callable $callback * @return void */ @@ -955,7 +956,7 @@ if ( !class_exists('PluginInfo_3_1', false) ): /** * A container class for holding and transforming various plugin metadata. - * + * * @author Janis Elsts * @copyright 2016 * @version 3.0 @@ -963,7 +964,7 @@ if ( !class_exists('PluginInfo_3_1', false) ): */ class PluginInfo_3_1 { //Most fields map directly to the contents of the plugin's info.json file. - //See the relevant docs for a description of their meaning. + //See the relevant docs for a description of their meaning. public $name; public $slug; public $version; @@ -975,25 +976,25 @@ class PluginInfo_3_1 { public $author; public $author_homepage; - + public $requires; public $tested; public $upgrade_notice; - + public $rating; public $num_ratings; public $downloaded; public $active_installs; public $last_updated; - + public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything. public $filename; //Plugin filename relative to the plugins directory. - + /** - * Create a new instance of PluginInfo from JSON-encoded plugin info + * Create a new instance of PluginInfo from JSON-encoded plugin info * returned by an external update API. - * + * * @param string $json Valid JSON string representing plugin info. * @return PluginInfo_3_1|null New instance of PluginInfo, or NULL on error. */ @@ -1002,18 +1003,18 @@ class PluginInfo_3_1 { $apiResponse = json_decode($json); if ( empty($apiResponse) || !is_object($apiResponse) ){ trigger_error( - "Failed to parse plugin metadata. Try validating your .json file with http://jsonlint.com/", + "Failed to parse plugin metadata. Try validating your .json file with http://jsonlint.com/\n".print_r($apiResponse,1), E_USER_NOTICE ); return null; } - + $valid = self::validateMetadata($apiResponse); if ( is_wp_error($valid) ){ trigger_error($valid->get_error_message(), E_USER_NOTICE); return null; } - + $info = new self(); foreach(get_object_vars($apiResponse) as $key => $value){ $info->$key = $value; @@ -1021,8 +1022,8 @@ class PluginInfo_3_1 { //json_decode decodes assoc. arrays as objects. We want it as an array. $info->sections = (array)$info->sections; - - return $info; + + return $info; } /** @@ -1045,17 +1046,17 @@ class PluginInfo_3_1 { return true; } - + /** * Transform plugin info into the format used by the native WordPress.org API - * + * * @return object */ public function toWpFormat(){ $info = new stdClass; - + //The custom update API is built so that many fields have the same name and format - //as those returned by the native WordPress.org API. These can be assigned directly. + //as those returned by the native WordPress.org API. These can be assigned directly. $sameFormat = array( 'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice', 'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated', @@ -1090,14 +1091,14 @@ class PluginInfo_3_1 { return $this->author; } } - + endif; if ( !class_exists('PluginUpdate_3_1', false) ): /** * A simple container class for holding information about an available update. - * + * * @author Janis Elsts * @copyright 2016 * @version 3.0 @@ -1119,10 +1120,10 @@ class PluginUpdate_3_1 { 'download_url', 'upgrade_notice', 'filename', 'translations' ); - + /** * Create a new instance of PluginUpdate from its JSON-encoded representation. - * + * * @param string $json * @return PluginUpdate_3_1|null */ @@ -1141,18 +1142,18 @@ class PluginUpdate_3_1 { /** * Create a new instance of PluginUpdate based on an instance of PluginInfo. * Basically, this just copies a subset of fields from one object to another. - * + * * @param PluginInfo_3_1 $info * @return PluginUpdate_3_1 */ public static function fromPluginInfo($info){ return self::fromObject($info); } - + /** - * Create a new instance of PluginUpdate by copying the necessary fields from + * Create a new instance of PluginUpdate by copying the necessary fields from * another object. - * + * * @param StdClass|PluginInfo_3_1|PluginUpdate_3_1 $object The source object. * @return PluginUpdate_3_1 The new copy. */ @@ -1169,13 +1170,13 @@ class PluginUpdate_3_1 { } return $update; } - + /** - * Create an instance of StdClass that can later be converted back to + * Create an instance of StdClass that can later be converted back to * a PluginUpdate. Useful for serialization and caching, as it avoids * the "incomplete object" problem if the cached value is loaded before * this class. - * + * * @return StdClass */ public function toStdClass() { @@ -1191,11 +1192,11 @@ class PluginUpdate_3_1 { } return $object; } - - + + /** * Transform the update into the format used by WordPress native plugin API. - * + * * @return object */ public function toWpFormat(){ @@ -1212,11 +1213,11 @@ class PluginUpdate_3_1 { if ( !empty($this->upgrade_notice) ){ $update->upgrade_notice = $this->upgrade_notice; } - + return $update; } } - + endif; if ( !class_exists('PucScheduler_3_1', false) ): -- 2.17.1