给自己的主题添加在线更新功能

shmily 1.3K 百度已收录 0

利用第三方类为主题提供在线更新安装服务,免去了下载主题包的麻烦。[doge]

给自己的主题添加在线更新功能

盗图必究,图片内容仅供参考

前言

使用过WordPress的都知道WordPress默认主题都有在线更新的功能,但是我们一般使用的主题却木有,在对欲思主题的二次开发的时候,小编就用到了一个自动更新的功能,在这里和大家说说吧

程序简介

theme-update-check是国外的牛人开发的一个终于WordPress主题更新的PHP类,类似于我们熟悉的裁图工具timthumb.php,我们可以很方便的将他集成到我们的主题里面,实现主题的自动更新服务。

文件说明

首先在文末下载文件包,解压出来是三个文件,updates.php和info.json。
首先打开info.json,你会发现是类似下面的代码

    {
    	"version" : "2.0",
    	"details_url" : "http://git.oschina.net/yunluo/yusi",
    	"download_url" : "http://git.oschina.net/yunluo/yusi/repository/archive?ref=master"
    }

当然,这个是自己主题的文件,应该都能看懂吧。
主要就三个参数
第一个是版本号
第二个是主题发布页
第三个是主题下载直链,就是输入这个链接,浏览器自动下载主题的那种。

再看一下updates.php文件,其他你不需要看,你只需要把主题名字(别名)和info.json文件的路径填写进去就好了,其他就不用管了。
然后在主题的functions.php写入下面代码

    //主题自动更新服务
    require 'updates.php';
    $example_update_checker = new ThemeUpdateChecker(
        'yusi',
        'info.json文件路径'//此路径可以开发者自己定义,保证info.json文件能够公开访问以及不能被除开发者之外的人修改即可
    );

文件部署

首先将updates.php文件放在主题根目录,然后将info.json放在主题开发者自己的网站根目录里面,当然,其实并不一定是根目录,放在哪里,然后updates.php文件里面的路径就是这个,info.json文件必须保证能够公开访问,然后over了!

推送更新

程序是将主题的开发者留下的meta文件和主题样式style..css里面的版本号进行比对,如果主题开发者的info.json文件里面的版本号比使用者的主题文件style.css里面的版本号大,那么就会在WordPress后台的更新工具进行更新提醒,和正常的WordPress更新,插件更新完全一样,如果你选择更新,就自动从主题直链在线安装主题。

注意事项

在使用中,小编发现了一些小问题,在这里也顺便说一下。
最重要的是保证一致性。保证自动更新里面的主题名字和你使用的主题名字一样,比如我目前使用的主题名字叫yusi,对,这里说的是主题文件夹名字,而不是其他中文名字,需要保持一致的地方有info.json,functions.php中的初始化函数代码,updates.php文件这四个地方,另外下载链接所下载的主题包文件名字也必须是一样的。
另外有很多朋友和博猪一样喜欢使用github,gitcafe,oschina,coding等等使用GIT版本控制系统的代码托管网站,如果采用这里提供的直链下载的话,你的项目名字也必须和主题名字一样,比如我之前的项目名字叫yusi-theme,结果自动更新之后主题文件夹多了一个名字叫yusi-theme的主题文件夹。好吧,明白怎么回事了吧!

后语

使用这种自动更新功能可以给主题使用者更新鲜的体验以及免去了多次下载的麻烦,自动检查更新的功能最好弄一个开关,让用户选择是否启用,因为主题更新会全部覆盖主题文件,如果使用者在主题里面自己添加了什么代码,最后都可能被覆盖掉,所以,主题开发者尽量给主题多留一些框框,尽量让使用者在主题设置里面设置,而不是直接在主题里面。

源代码

    <?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') ):
     
    class ThemeUpdateChecker {
    	public $theme = 'Git-master';              //待检查更新的主题名
    	public $metadataUrl = 'https://coding.net/u/googlo/p/File/git/raw/master/info.json';  //元数据文件的路径
    	public $enableAutomaticChecking = true; //是否启用自动更新
    	protected $optionName = '';      //更新时候的文字信息
    	protected $automaticCheckDone = false;
    	protected static $filterPrefix = 'tuc_request_update_';
     
    	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();
    	}
     
    	public function installHooks(){
     
    		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', array($this,'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', array($this, 'deleteStoredData'));
    	}
     
    	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' => 20, //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;
    	}
     
    	public function getInstalledVersion(){
    		if ( function_exists('wp_get_theme') ) {
    			$theme = wp_get_theme($this->theme);
    			return $theme->get('Version');
    		}
     
    		foreach(get_themes() as $theme){
    			if ( $theme['Stylesheet'] === $this->theme ){
    				return $theme['Version'];
    			}
    		}
    		return '';
    	}
     
    	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);
    	}
     
    	public function onTransientUpdate($value){
    		if ( !$this->automaticCheckDone ){
    			$this->checkForUpdates();
    			$this->automaticCheckDone = true;
    		}
    		return $value;
    	}
     
    	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;
    	}
     
    	public function deleteStoredData(){
    		delete_option($this->optionName);
    	}
     
    	public function addQueryArgFilter($callback){
    		add_filter(self::$filterPrefix.'query_args-'.$this->theme, $callback);
    	}
     
    	public function addHttpRequestArgFilter($callback){
    		add_filter(self::$filterPrefix.'options-'.$this->theme, $callback);
    	}
     
    	public function addResultFilter($callback){
    		add_filter(self::$filterPrefix.'result-'.$this->theme, $callback, 10, 2);
    	}
    }
     
    endif;
     
    if ( !class_exists('ThemeUpdate') ):
     
    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.
     
    	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;
    	}
     
    	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;
     

下载地址: 本地下载

发表评论 取消回复
表情 代码

分享