✨feature: Add update from repo
This commit is contained in:
@@ -46,6 +46,9 @@ The plugin is designed to work out of the box with minimal configuration. Howeve
|
||||
- ~~pagination~~
|
||||
|
||||
## Changelog
|
||||
### 1.5.0 - 2025-02-13
|
||||
- Added repo update feature
|
||||
|
||||
### 1.4.0 - 2025-02-13
|
||||
- Added admin configuration page
|
||||
|
||||
|
||||
410
includes/updater.php
Normal file
410
includes/updater.php
Normal file
@@ -0,0 +1,410 @@
|
||||
<?php
|
||||
// Prevent loading this file directly and/or if the class is already defined
|
||||
if (!defined('ABSPATH') || class_exists('WPGitHubUpdater') || class_exists('WP_GitHub_Updater')) { return; }
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @version 1.6
|
||||
* @author Joachim Kudish <info@jkudish.com>
|
||||
* @link http://jkudish.com
|
||||
* @package WP_GitHub_Updater
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @copyright Copyright (c) 2011-2013, Joachim Kudish
|
||||
*
|
||||
* GNU General Public License, Free Software Foundation
|
||||
* <http://creativecommons.org/licenses/GPL/2.0/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
class WpGitHubUpdater {
|
||||
/**
|
||||
* GitHub Updater version
|
||||
*/
|
||||
const VERSION = 1.6;
|
||||
|
||||
/**
|
||||
* @var $config the config for the updater
|
||||
* @access public
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* @var $missingConfig any config that is missing from the initialization of this instance
|
||||
* @access public
|
||||
*/
|
||||
public $missingConfig;
|
||||
|
||||
/**
|
||||
* @var $githubData temporiraly store the data fetched from GitHub, allows us to only load the data once per class instance
|
||||
* @access private
|
||||
*/
|
||||
private $githubData;
|
||||
|
||||
|
||||
/**
|
||||
* Class Constructor
|
||||
*
|
||||
* @since 1.0
|
||||
* @param array $config the configuration required for the updater to work
|
||||
* @see hasMinimumConfig()
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($config = array()) {
|
||||
|
||||
$defaults = array(
|
||||
'slug' => plugin_basename(__FILE__),
|
||||
'proper_folder_name' => dirname(plugin_basename(__FILE__)),
|
||||
'sslverify' => true,
|
||||
'access_token' => '',
|
||||
);
|
||||
|
||||
$this->config = wp_parse_args($config, $defaults);
|
||||
|
||||
// if the minimum config isn't set, issue a warning and bail
|
||||
if (!$this->hasMinimumConfig()) {
|
||||
$message = 'The GitHub Updater was initialized without the minimum required configuration, please check the config in your plugin. The following params are missing: ';
|
||||
$message .= implode(',', $this->missingConfig);
|
||||
_doing_it_wrong(__CLASS__, $message , self::VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setDefaults();
|
||||
|
||||
add_filter('pre_set_site_transient_update_plugins', array($this, 'apiCheck'));
|
||||
|
||||
// Hook into the plugin details screen
|
||||
add_filter('plugins_api', array($this, 'getPluginInfo'), 10, 3);
|
||||
add_filter('upgraderPostInstall', array($this, 'upgraderPostInstall'), 10, 3);
|
||||
|
||||
// set timeout
|
||||
add_filter('httpRequestTimeout', array($this, 'httpRequestTimeout'));
|
||||
|
||||
// set sslverify for zip download
|
||||
add_filter('http_request_args', array($this, 'httpRequestSslverify'), 10, 2);
|
||||
}
|
||||
|
||||
public function hasMinimumConfig() {
|
||||
|
||||
$this->missingConfig = array();
|
||||
|
||||
$required_config_params = array(
|
||||
'api_url',
|
||||
'raw_url',
|
||||
'github_url',
|
||||
'zip_url',
|
||||
'requires',
|
||||
'tested',
|
||||
'readme',
|
||||
);
|
||||
|
||||
foreach ($required_config_params as $required_param) {
|
||||
if (empty($this->config[$required_param])) { $this->missingConfig[] = $required_param; }
|
||||
}
|
||||
|
||||
return empty($this->missingConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check wether or not the transients need to be overruled and API needs to be called for every single page load
|
||||
*
|
||||
* @return bool overrule or not
|
||||
*/
|
||||
public function overruleTransients() {
|
||||
return defined('WP_GITHUB_FORCE_UPDATE') && WP_GITHUB_FORCE_UPDATE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set defaults
|
||||
*
|
||||
* @since 1.2
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaults() {
|
||||
if (!empty($this->config['access_token'])) {
|
||||
|
||||
// See Downloading a zipball (private repo) https://help.github.com/articles/downloading-files-from-the-command-line
|
||||
extract(parse_url($this->config['zip_url'])); // $scheme, $host, $path
|
||||
|
||||
$zip_url = $scheme . '://api.github.com/repos' . $path;
|
||||
$zip_url = add_query_arg(array('access_token' => $this->config['access_token']), $zip_url);
|
||||
|
||||
$this->config['zip_url'] = $zip_url;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($this->config['new_version'])) { $this->config['new_version'] = $this->getNewVersion(); }
|
||||
|
||||
if (!isset($this->config['last_updated'])) { $this->config['last_updated'] = $this->getDate(); }
|
||||
|
||||
if (!isset($this->config['description'])) { $this->config['description'] = $this->getDescription(); }
|
||||
|
||||
$plugin_data = $this->getPluginData();
|
||||
if (!isset($this->config['plugin_name'])) { $this->config['plugin_name'] = $plugin_data['Name']; }
|
||||
|
||||
if (!isset($this->config['version'])) { $this->config['version'] = $plugin_data['Version']; }
|
||||
|
||||
if (!isset($this->config['author'])) { $this->config['author'] = $plugin_data['Author']; }
|
||||
|
||||
if (!isset($this->config['homepage'])) { $this->config['homepage'] = $plugin_data['PluginURI']; }
|
||||
|
||||
if (!isset($this->config['readme'])) { $this->config['readme'] = 'README.md'; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback fn for the httpRequestTimeout filter
|
||||
*
|
||||
* @since 1.0
|
||||
* @return int timeout value
|
||||
*/
|
||||
public function httpRequestTimeout() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback fn for the http_request_args filter
|
||||
*
|
||||
* @param unknown $args
|
||||
* @param unknown $url
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function httpRequestSslverify($args, $url) {
|
||||
if ($this->config[ 'zip_url' ] == $url) { $args[ 'sslverify' ] = $this->config[ 'sslverify' ]; }
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get New Version from GitHub
|
||||
*
|
||||
* @since 1.0
|
||||
* @return int $version the version number
|
||||
*/
|
||||
public function getNewVersion() {
|
||||
$version = get_site_transient(md5($this->config['slug']).'_new_version');
|
||||
|
||||
if ($this->overruleTransients() || (!isset($version) || !$version || '' == $version)) {
|
||||
$version = $this->fetchVersionFromGitHub();
|
||||
if (false === $version) {
|
||||
$version = $this->fetchVersionFromReadme();
|
||||
}
|
||||
if (false !== $version) {
|
||||
set_site_transient(md5($this->config['slug']).'_new_version', $version, 60*60*6);
|
||||
}
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
private function fetchVersionFromGitHub() {
|
||||
$raw_response = $this->remoteGet(trailingslashit($this->config['raw_url']) . basename($this->config['slug']));
|
||||
if (is_wp_error($raw_response)) { return false; }
|
||||
|
||||
if (is_array($raw_response) && !empty($raw_response['body'])) {
|
||||
preg_match('/.*Version\:\s*(.*)$/mi', $raw_response['body'], $matches);
|
||||
}
|
||||
|
||||
return empty($matches[1]) ? false : $matches[1];
|
||||
}
|
||||
|
||||
private function fetchVersionFromReadme() {
|
||||
$raw_response = $this->remoteGet(trailingslashit($this->config['raw_url']) . $this->config['readme']);
|
||||
if (is_wp_error($raw_response)) { return false; }
|
||||
|
||||
preg_match('#^\s*`*~Current Version\:\s*([^~]*)~#im', $raw_response['body'], $__version);
|
||||
|
||||
return isset($__version[1]) ? $__version[1] : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interact with GitHub
|
||||
*
|
||||
* @param string $query
|
||||
*
|
||||
* @since 1.6
|
||||
* @return mixed
|
||||
*/
|
||||
public function remoteGet($query) {
|
||||
if (!empty($this->config['access_token'])) { $query = add_query_arg(array('access_token' => $this->config['access_token']), $query); }
|
||||
|
||||
return wp_remote_get($query, array(
|
||||
'sslverify' => $this->config['sslverify']
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get GitHub Data from the specified repository
|
||||
*
|
||||
* @since 1.0
|
||||
* @return array $githubData the data
|
||||
*/
|
||||
public function getGithubData() {
|
||||
if (isset($this->githubData) && !empty($this->githubData)) {
|
||||
$githubData = $this->githubData;
|
||||
} else {
|
||||
$githubData = get_site_transient(md5($this->config['slug']).'_githubData');
|
||||
|
||||
if ($this->overruleTransients() || (!isset($githubData) || !$githubData || '' == $githubData)) {
|
||||
$githubData = $this->remoteGet($this->config['api_url']);
|
||||
|
||||
if (is_wp_error($githubData)) { return false; }
|
||||
|
||||
$githubData = json_decode($githubData['body']);
|
||||
|
||||
// refresh every 6 hours
|
||||
set_site_transient(md5($this->config['slug']).'_githubData', $githubData, 60*60*6);
|
||||
}
|
||||
|
||||
// Store the data in this class instance for future calls
|
||||
$this->githubData = $githubData;
|
||||
}
|
||||
|
||||
return $githubData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get update date
|
||||
*
|
||||
* @since 1.0
|
||||
* @return string $date the date
|
||||
*/
|
||||
public function getDate() {
|
||||
$_date = $this->getGithubData();
|
||||
return (!empty($_date->updated_at)) ? date('Y-m-d', strtotime($_date->updated_at)) : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get plugin description
|
||||
*
|
||||
* @since 1.0
|
||||
* @return string $description the description
|
||||
*/
|
||||
public function getDescription() {
|
||||
$_description = $this->getGithubData();
|
||||
return (!empty($_description->description)) ? $_description->description : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Plugin data
|
||||
*
|
||||
* @since 1.0
|
||||
* @return object $data the data
|
||||
*/
|
||||
public function getPluginData() {
|
||||
include_once ABSPATH.'/wp-admin/includes/plugin.php';
|
||||
return get_plugin_data(WP_PLUGIN_DIR.'/'.$this->config['slug']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook into the plugin update check and connect to GitHub
|
||||
*
|
||||
* @since 1.0
|
||||
* @param object $transient the plugin data transient
|
||||
* @return object $transient updated plugin data transient
|
||||
*/
|
||||
public function apiCheck($transient) {
|
||||
|
||||
// Check if the transient contains the 'checked' information
|
||||
// If not, just return its value without hacking it
|
||||
if (empty($transient->checked)) { return $transient; }
|
||||
|
||||
// check the version and decide if it's new
|
||||
$update = version_compare($this->config['new_version'], $this->config['version']);
|
||||
|
||||
if (1 === $update) {
|
||||
$response = new stdClass;
|
||||
$response->new_version = $this->config['new_version'];
|
||||
$response->slug = $this->config['proper_folder_name'];
|
||||
$response->url = add_query_arg(array('access_token' => $this->config['access_token']), $this->config['github_url']);
|
||||
$response->package = $this->config['zip_url'];
|
||||
|
||||
// If response is false, don't alter the transient
|
||||
if (false !== $response) { $transient->response[ $this->config['slug'] ] = $response; }
|
||||
}
|
||||
|
||||
return $transient;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Plugin info
|
||||
*
|
||||
* @since 1.0
|
||||
* @param bool $false always false
|
||||
* @param string $action the API function being performed
|
||||
* @param object $args plugin arguments
|
||||
* @return object $response the plugin info
|
||||
*/
|
||||
public function getPluginInfo($false, $action, $response) {
|
||||
|
||||
// Check if this call API is for the right plugin
|
||||
if (!isset($response->slug) || $response->slug != $this->config['slug']) { return false; }
|
||||
|
||||
$response->slug = $this->config['slug'];
|
||||
$response->plugin_name = $this->config['plugin_name'];
|
||||
$response->version = $this->config['new_version'];
|
||||
$response->author = $this->config['author'];
|
||||
$response->homepage = $this->config['homepage'];
|
||||
$response->requires = $this->config['requires'];
|
||||
$response->tested = $this->config['tested'];
|
||||
$response->downloaded = 0;
|
||||
$response->last_updated = $this->config['last_updated'];
|
||||
$response->sections = array('description' => $this->config['description']);
|
||||
$response->download_link = $this->config['zip_url'];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upgrader/Updater
|
||||
* Move & activate the plugin, echo the update message
|
||||
*
|
||||
* @since 1.0
|
||||
* @param boolean $true always true
|
||||
* @param mixed $hook_extra not used
|
||||
* @param array $result the result of the move
|
||||
* @return array $result the result of the move
|
||||
*/
|
||||
public function upgraderPostInstall($true, $hook_extra, $result) {
|
||||
|
||||
global $wp_filesystem;
|
||||
|
||||
// Move & Activate
|
||||
$proper_destination = WP_PLUGIN_DIR.'/'.$this->config['proper_folder_name'];
|
||||
$wp_filesystem->move($result['destination'], $proper_destination);
|
||||
$result['destination'] = $proper_destination;
|
||||
$activate = activate_plugin(WP_PLUGIN_DIR.'/'.$this->config['slug']);
|
||||
|
||||
// Output the update message
|
||||
$fail = __('The plugin has been updated, but could not be reactivated. Please reactivate it manually.', 'github_plugin_updater');
|
||||
$success = __('Plugin reactivated successfully.', 'github_plugin_updater');
|
||||
echo is_wp_error($activate) ? $fail : $success;
|
||||
return $result;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,37 @@
|
||||
/**
|
||||
* Plugin Name: Content Filter
|
||||
* Description: Adds filtering for the content typed by various taxonomies.
|
||||
* Version: 1.4.0
|
||||
* Version: 1.5.0
|
||||
* Author: Keith Solomon
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) { exit; } // Prevent direct access
|
||||
|
||||
require_once plugin_dir_path(__FILE__) . 'includes/updater.php';
|
||||
require_once plugin_dir_path(__FILE__) . 'includes/template-loader.php';
|
||||
|
||||
function cfInit() {
|
||||
if (is_admin()) { // note the use of is_admin() to double check that this is happening in the admin
|
||||
$config = array(
|
||||
'slug' => plugin_basename(__FILE__), // this is the slug of your plugin
|
||||
'proper_folder_name' => 'plugin-name', // this is the name of the folder your plugin lives in
|
||||
'api_url' => 'https://api.github.com/repos/username/repository-name', // the GitHub API url of your GitHub repo
|
||||
'raw_url' => 'https://raw.github.com/username/repository-name/master', // the GitHub raw url of your GitHub repo
|
||||
'github_url' => 'https://github.com/username/repository-name', // the GitHub url of your GitHub repo
|
||||
'zip_url' => 'https://github.com/username/repository-name/zipball/master', // the zip url of the GitHub repo
|
||||
'sslverify' => true, // whether WP should check the validity of the SSL cert when getting an update, see https://github.com/jkudish/WordPress-GitHub-Plugin-Updater/issues/2 and https://github.com/jkudish/WordPress-GitHub-Plugin-Updater/issues/4 for details
|
||||
'requires' => '3.0', // which version of WordPress does your plugin require?
|
||||
'tested' => '3.3', // which version of WordPress is your plugin tested up to?
|
||||
'readme' => 'README.md', // which file to use as the readme for the version number
|
||||
'access_token' => '', // Access private repositories by authorizing under Plugins > GitHub Updates when this example plugin is installed
|
||||
);
|
||||
|
||||
new WpGitHubUpdater($config);
|
||||
}
|
||||
}
|
||||
|
||||
add_action('init', 'cfInit');
|
||||
|
||||
class ContentFilterPlugin {
|
||||
/** Registers the necessary actions and filters for the Content Filter plugin.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user