Skip to content

Commit

Permalink
Merge branch 'release/2.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Hemberger committed Oct 12, 2017
2 parents dc89104 + 021510a commit ce8b346
Show file tree
Hide file tree
Showing 57 changed files with 8,901 additions and 57 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#### 2.1.0
* Added: Included updater script.

#### 2.0.1
* Update plugin header to point to new repo in bizbudding GitHub organization

Expand All @@ -12,4 +15,4 @@
* Fix click in popup causing it to close

#### 1.0.0
* Let's get this party started
* Let's get this party started
271 changes: 271 additions & 0 deletions includes/vendor/plugin-update-checker/Puc/v4/Factory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
<?php
if ( !class_exists('Puc_v4_Factory', false) ):

/**
* A factory that builds update checker instances.
*
* When multiple versions of the same class have been loaded (e.g. PluginUpdateChecker 4.0
* and 4.1), this factory will always use the latest available minor version. Register class
* versions by calling {@link PucFactory::addVersion()}.
*
* At the moment it can only build instances of the UpdateChecker class. Other classes are
* intended mainly for internal use and refer directly to specific implementations.
*/
class Puc_v4_Factory {
protected static $classVersions = array();
protected static $sorted = false;

protected static $myMajorVersion = '';
protected static $latestCompatibleVersion = '';

/**
* Create a new instance of the update checker.
*
* This method automatically detects if you're using it for a plugin or a theme and chooses
* the appropriate implementation for your update source (JSON file, GitHub, BitBucket, etc).
*
* @see Puc_v4p2_UpdateChecker::__construct
*
* @param string $metadataUrl The URL of the metadata file, a GitHub repository, or another supported update source.
* @param string $fullPath Full path to the main plugin file or to the theme directory.
* @param string $slug Custom slug. Defaults to the name of the main plugin file or the theme directory.
* @param int $checkPeriod How often to check for updates (in hours).
* @param string $optionName Where to store book-keeping info about update checks.
* @param string $muPluginFile The plugin filename relative to the mu-plugins directory.
* @return Puc_v4p2_Plugin_UpdateChecker|Puc_v4p2_Theme_UpdateChecker|Puc_v4p2_Vcs_BaseChecker
*/
public static function buildUpdateChecker($metadataUrl, $fullPath, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
$fullPath = wp_normalize_path($fullPath);
$id = null;

//Plugin or theme?
$themeDirectory = self::getThemeDirectoryName($fullPath);
if ( self::isPluginFile($fullPath) ) {
$type = 'Plugin';
$id = $fullPath;
} else if ( $themeDirectory !== null ) {
$type = 'Theme';
$id = $themeDirectory;
} else {
throw new RuntimeException(sprintf(
'The update checker cannot determine if "%s" is a plugin or a theme. ' .
'This is a bug. Please contact the PUC developer.',
htmlentities($fullPath)
));
}

//Which hosting service does the URL point to?
$service = self::getVcsService($metadataUrl);

$apiClass = null;
if ( empty($service) ) {
//The default is to get update information from a remote JSON file.
$checkerClass = $type . '_UpdateChecker';
} else {
//You can also use a VCS repository like GitHub.
$checkerClass = 'Vcs_' . $type . 'UpdateChecker';
$apiClass = $service . 'Api';
}

$checkerClass = self::getCompatibleClassVersion($checkerClass);
if ( $checkerClass === null ) {
trigger_error(
sprintf(
'PUC %s does not support updates for %ss %s',
htmlentities(self::$latestCompatibleVersion),
strtolower($type),
$service ? ('hosted on ' . htmlentities($service)) : 'using JSON metadata'
),
E_USER_ERROR
);
return null;
}

if ( !isset($apiClass) ) {
//Plain old update checker.
return new $checkerClass($metadataUrl, $id, $slug, $checkPeriod, $optionName, $muPluginFile);
} else {
//VCS checker + an API client.
$apiClass = self::getCompatibleClassVersion($apiClass);
if ( $apiClass === null ) {
trigger_error(sprintf(
'PUC %s does not support %s',
htmlentities(self::$latestCompatibleVersion),
htmlentities($service)
), E_USER_ERROR);
return null;
}

return new $checkerClass(
new $apiClass($metadataUrl),
$id,
$slug,
$checkPeriod,
$optionName,
$muPluginFile
);
}
}

/**
* Check if the path points to a plugin file.
*
* @param string $absolutePath Normalized path.
* @return bool
*/
protected static function isPluginFile($absolutePath) {
//Is the file inside the "plugins" or "mu-plugins" directory?
$pluginDir = wp_normalize_path(WP_PLUGIN_DIR);
$muPluginDir = wp_normalize_path(WPMU_PLUGIN_DIR);
if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
return true;
}

//Is it a file at all? Caution: is_file() can fail if the parent dir. doesn't have the +x permission set.
if ( !is_file($absolutePath) ) {
return false;
}

//Does it have a valid plugin header?
//This is a last-ditch check for plugins symlinked from outside the WP root.
if ( function_exists('get_file_data') ) {
$headers = get_file_data($absolutePath, array('Name' => 'Plugin Name'), 'plugin');
return !empty($headers['Name']);
}

return false;
}

/**
* Get the name of the theme's directory from a full path to a file inside that directory.
* E.g. "/abc/public_html/wp-content/themes/foo/whatever.php" => "foo".
*
* Note that subdirectories are currently not supported. For example,
* "/xyz/wp-content/themes/my-theme/includes/whatever.php" => NULL.
*
* @param string $absolutePath Normalized path.
* @return string|null Directory name, or NULL if the path doesn't point to a theme.
*/
protected static function getThemeDirectoryName($absolutePath) {
if ( is_file($absolutePath) ) {
$absolutePath = dirname($absolutePath);
}

if ( file_exists($absolutePath . '/style.css') ) {
return basename($absolutePath);
}
return null;
}

/**
* Get the name of the hosting service that the URL points to.
*
* @param string $metadataUrl
* @return string|null
*/
private static function getVcsService($metadataUrl) {
$service = null;

//Which hosting service does the URL point to?
$host = @parse_url($metadataUrl, PHP_URL_HOST);
$path = @parse_url($metadataUrl, PHP_URL_PATH);
//Check if the path looks like "/user-name/repository".
$usernameRepoRegex = '@^/?([^/]+?)/([^/#?&]+?)/?$@';
if ( preg_match($usernameRepoRegex, $path) ) {
$knownServices = array(
'github.com' => 'GitHub',
'bitbucket.org' => 'BitBucket',
'gitlab.com' => 'GitLab',
);
if ( isset($knownServices[$host]) ) {
$service = $knownServices[$host];
}
}

return $service;
}

/**
* Get the latest version of the specified class that has the same major version number
* as this factory class.
*
* @param string $class Partial class name.
* @return string|null Full class name.
*/
protected static function getCompatibleClassVersion($class) {
if ( isset(self::$classVersions[$class][self::$latestCompatibleVersion]) ) {
return self::$classVersions[$class][self::$latestCompatibleVersion];
}
return null;
}

/**
* Get the specific class name for the latest available version of a class.
*
* @param string $class
* @return null|string
*/
public static function getLatestClassVersion($class) {
if ( !self::$sorted ) {
self::sortVersions();
}

if ( isset(self::$classVersions[$class]) ) {
return reset(self::$classVersions[$class]);
} else {
return null;
}
}

/**
* Sort available class versions in descending order (i.e. newest first).
*/
protected static function sortVersions() {
foreach ( self::$classVersions as $class => $versions ) {
uksort($versions, array(__CLASS__, 'compareVersions'));
self::$classVersions[$class] = $versions;
}
self::$sorted = true;
}

protected static function compareVersions($a, $b) {
return -version_compare($a, $b);
}

/**
* Register a version of a class.
*
* @access private This method is only for internal use by the library.
*
* @param string $generalClass Class name without version numbers, e.g. 'PluginUpdateChecker'.
* @param string $versionedClass Actual class name, e.g. 'PluginUpdateChecker_1_2'.
* @param string $version Version number, e.g. '1.2'.
*/
public static function addVersion($generalClass, $versionedClass, $version) {
if ( empty(self::$myMajorVersion) ) {
$nameParts = explode('_', __CLASS__, 3);
self::$myMajorVersion = substr(ltrim($nameParts[1], 'v'), 0, 1);
}

//Store the greatest version number that matches our major version.
$components = explode('.', $version);
if ( $components[0] === self::$myMajorVersion ) {

if (
empty(self::$latestCompatibleVersion)
|| version_compare($version, self::$latestCompatibleVersion, '>')
) {
self::$latestCompatibleVersion = $version;
}

}

if ( !isset(self::$classVersions[$generalClass]) ) {
self::$classVersions[$generalClass] = array();
}
self::$classVersions[$generalClass][$version] = $versionedClass;
self::$sorted = false;
}
}

endif;
49 changes: 49 additions & 0 deletions includes/vendor/plugin-update-checker/Puc/v4p2/Autoloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

if ( !class_exists('Puc_v4p2_Autoloader', false) ):

class Puc_v4p2_Autoloader {
private $prefix = '';
private $rootDir = '';
private $libraryDir = '';

private $staticMap;

public function __construct() {
$this->rootDir = dirname(__FILE__) . '/';
$nameParts = explode('_', __CLASS__, 3);
$this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';

$this->libraryDir = realpath($this->rootDir . '../..') . '/';
$this->staticMap = array(
'PucReadmeParser' => 'vendor/readme-parser.php',
'Parsedown' => 'vendor/ParsedownLegacy.php',
);
if ( version_compare(PHP_VERSION, '5.3.0', '>=') ) {
$this->staticMap['Parsedown'] = 'vendor/Parsedown.php';
}

spl_autoload_register(array($this, 'autoload'));
}

public function autoload($className) {
if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
/** @noinspection PhpIncludeInspection */
include ($this->libraryDir . $this->staticMap[$className]);
return;
}

if (strpos($className, $this->prefix) === 0) {
$path = substr($className, strlen($this->prefix));
$path = str_replace('_', '/', $path);
$path = $this->rootDir . $path . '.php';

if (file_exists($path)) {
/** @noinspection PhpIncludeInspection */
include $path;
}
}
}
}

endif;
Loading

0 comments on commit ce8b346

Please sign in to comment.