商业WordPress主题更新

问题描述

我正在构建商业WP主题并查看更新功能

我发现了这篇文章:为主题制作更新通知功能,这些功能将我带到了本教程:https://w-shadow.com/blog/2011/06/02/automatic-updates-for-commercial-themes/

这似乎可行,但是我有几个问题:

  1. 我的主题screenshot.png图片没有进入更新页面
  2. 它并没有涉及当前的主题版本:

    enter image description here

  1. 它已成功更新,没有错误,但是它没有删除主题并激活更新的主题,而是保留了旧主题并使其处于活动状态,并将更新后的主题添加为具有奇怪主题名称的单独的非活动主题- ' fern-aUvtaR '

这是我的.json更新文件

    {
      "version" : "2.1.0","details_url" : "https://...","download_url" : "https://.../fern.zip"
    }

**This is my themechecker function in the themes functions.PHP file:**
require get_template_directory() . '/theme-updates/theme-update-checker.PHP';

$example_update_checker = new ThemeUpdateChecker(
    'Fern','https://.../wp-themes/fern/fern-updates.json'
);

以及本教程中的theme-update-checker.PHP

<?PHP
/**
 * Theme Update Checker Library 1.2
 * http://w-shadow.com/
 * 
 * copyright 2012 Janis Elsts
 * Licensed under the GNU GPL license.
 * http://www.gnu.org/licenses/gpl.html
 */

if ( !class_exists('ThemeUpdateChecker') ):
    
/**
 * A custom theme update checker. 
 * 
 * @author Janis Elsts
 * @copyright 2012
 * @version 1.2
 * @access public
 */
class ThemeUpdateChecker {
    public $theme = '';              //The theme associated with this update checker instance.
    public $MetadataUrl = '';        //The URL of the theme's Metadata file.
    public $enableAutomaticChecking = true; //Enable/disable automatic update checks.
    
    protected $optionName = '';      //Where to store update info.
    protected $automaticCheckDone = false;
    protected static $filterPrefix = 'tuc_request_update_';
                                     
    /**
     * Class constructor.
     *
     * @param string $theme Theme slug,e.g. "twentyten".
     * @param string $MetadataUrl The URL of the theme Metadata file.
     * @param boolean $enableAutomaticChecking Enable/disable automatic update checking. If set to FALSE,you'll need to explicitly call checkForUpdates() to,err,check for updates.
     */
    public function __construct($theme,$MetadataUrl,$enableAutomaticChecking = true){
        $this->MetadataUrl = $MetadataUrl;
        $this->enableAutomaticChecking = $enableAutomaticChecking;
        $this->theme = $theme;
        $this->optionName = 'external_theme_updates-'.$this->theme;
        
        $this->installHooks();      
    }
    
    /**
     * Install the hooks required to run periodic update checks and inject update info 
     * into WP data structures.
     * 
     * @return void
     */
    public function installHooks(){
        //Check for updates when wordpress does. We can detect when that happens by tracking
        //updates to the "update_themes" transient,which only happen in wp_update_themes().
        if ( $this->enableAutomaticChecking ){
            add_filter('pre_set_site_transient_update_themes',array($this,'onTransientUpdate'));
        }
        
        //Insert our update info into the update list maintained by WP.
        add_filter('site_transient_update_themes','injectUpdate')); 
        
        //Delete our update info when WP deletes its own.
        //This usually happens when a theme is installed,removed or upgraded.
        add_action('delete_site_transient_update_themes','deleteStoredData'));
    }
    
    /**
     * Retrieve update info from the configured Metadata URL.
     * 
     * Returns either an instance of ThemeUpdate,or NULL if there is 
     * no newer version available or if there's an error.
     * 
     * @uses wp_remote_get()
     * 
     * @param array $queryArgs Additional query arguments to append to the request. Optional.
     * @return ThemeUpdate 
     */
    public function requestUpdate($queryArgs = array()){
        //Query args to append to the URL. Themes can add their own by using a filter callback (see addQueryArgFilter()).
        $queryArgs['installed_version'] = $this->getInstalledVersion(); 
        $queryArgs = apply_filters(self::$filterPrefix.'query_args-'.$this->theme,$queryArgs);
        
        //VarIoUs options for the wp_remote_get() call. Themes can filter these,too.
        $options = array(
            'timeout' => 10,//seconds
        );
        $options = apply_filters(self::$filterPrefix.'options-'.$this->theme,$options);
        
        $url = $this->MetadataUrl; 
        if ( !empty($queryArgs) ){
            $url = add_query_arg($queryArgs,$url);
        }
        
        //Send the request.
        $result = wp_remote_get($url,$options);
        
        //Try to parse the response
        $themeUpdate = null;
        $code = wp_remote_retrieve_response_code($result);
        $body = wp_remote_retrieve_body($result);
        if ( ($code == 200) && !empty($body) ){
            $themeUpdate = ThemeUpdate::fromJson($body);
            //The update should be newer than the currently installed version.
            if ( ($themeUpdate != null) && version_compare($themeUpdate->version,$this->getInstalledVersion(),'<=') ){
                $themeUpdate = null;
            }
        }
        
        $themeUpdate = apply_filters(self::$filterPrefix.'result-'.$this->theme,$themeUpdate,$result);
        return $themeUpdate;
    }
    
    /**
     * Get the currently installed version of our theme.
     * 
     * @return string Version number.
     */
    public function getInstalledVersion(){
        if ( function_exists('wp_get_theme') ) {
            $theme = wp_get_theme($this->theme);
            return $theme->get('Version');
        }

        /** @noinspection PHPDeprecationinspection get_themes() used for compatibility with WP 3.3 and below. */
        foreach(get_themes() as $theme){
            if ( $theme['Stylesheet'] === $this->theme ){
                return $theme['Version'];
            }
        }
        return '';
    }
    
    /**
     * Check for theme updates. 
     * 
     * @return void
     */
    public function checkForUpdates(){
        $state = get_option($this->optionName);
        if ( empty($state) ){
            $state = new StdClass;
            $state->lastCheck = 0;
            $state->checkedVersion = '';
            $state->update = null;
        }
        
        $state->lastCheck = time();
        $state->checkedVersion = $this->getInstalledVersion();
        update_option($this->optionName,$state); //Save before checking in case something goes wrong 
        
        $state->update = $this->requestUpdate();
        update_option($this->optionName,$state);
    }
    
    /**
     * Run the automatic update check,but no more than once per page load.
     * This is a callback for WP hooks. Do not call it directly.  
     * 
     * @param mixed $value
     * @return mixed
     */
    public function onTransientUpdate($value){
        if ( !$this->automaticCheckDone ){
            $this->checkForUpdates();
            $this->automaticCheckDone = true;
        }
        return $value;
    }
    
    /**
     * Insert the latest update (if any) into the update list maintained by WP.
     * 
     * @param StdClass $updates Update list.
     * @return array Modified update list.
     */
    public function injectUpdate($updates){
        $state = get_option($this->optionName);
        
        //Is there an update to insert?
        if ( !empty($state) && isset($state->update) && !empty($state->update) ){
            $updates->response[$this->theme] = $state->update->toWpformat();
        }
        
        return $updates;
    }
    
    /**
     * Delete any stored book-keeping data.
     * 
     * @return void
     */
    public function deleteStoredData(){
        delete_option($this->optionName);
    } 
    
    /**
     * 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.
     * 
     * @param callable $callback
     * @return void
     */
    public function addQueryArgFilter($callback){
        add_filter(self::$filterPrefix.'query_args-'.$this->theme,$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. 
     * 
     * @param callable $callback
     * @return void
     */
    public function addHttpRequestArgFilter($callback){
        add_filter(self::$filterPrefix.'options-'.$this->theme,$callback);
    }
    
    /**
     * Register a callback for filtering the theme info retrieved from the external API.
     * 
     * The callback function should take two arguments. If a theme update was retrieved 
     * successfully,the first argument passed will be an instance of  ThemeUpdate. 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 ThemeUpdate or NULL.
     * 
     * @param callable $callback
     * @return void
     */
    public function addResultFilter($callback){
        add_filter(self::$filterPrefix.'result-'.$this->theme,$callback,10,2);
    }
}
    
endif;

if ( !class_exists('ThemeUpdate') ):

/**
 * A simple container class for holding @R_188_4045@ion about an available update.
 * 
 * @author Janis Elsts
 * @copyright 2012
 * @version 1.0
 * @access public
 */
class ThemeUpdate {
    public $version;      //Version number.
    public $details_url;  //The URL where the user can learn more about this version. 
    public $download_url; //The download URL for this version of the theme. Optional.
    
    /**
     * Create a new instance of ThemeUpdate from its JSON-encoded representation.
     * 
     * @param string $json Valid JSON string representing a theme @R_188_4045@ion object. 
     * @return ThemeUpdate New instance of ThemeUpdate,or NULL on error.
     */
    public static function fromJson($json){
        $apiResponse = json_decode($json);
        if ( empty($apiResponse) || !is_object($apiResponse) ){
            return null;
        }
        
        //Very,very basic validation.
        $valid = isset($apiResponse->version) && !empty($apiResponse->version) && isset($apiResponse->details_url) && !empty($apiResponse->details_url);
        if ( !$valid ){
            return null;
        }
        
        $update = new self();
        foreach(get_object_vars($apiResponse) as $key => $value){
            $update->$key = $value;
        }
        
        return $update;
    }
    
    /**
     * Transform the update into the format expected by the wordpress core.
     * 
     * @return array
     */
    public function toWpformat(){
        $update = array(
            'new_version' => $this->version,'url' => $this->details_url,);
        
        if ( !empty($this->download_url) ){
            $update['package'] = $this->download_url;
        }
        
        return $update;
    }
}
    
endif;

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)