first commit
This commit is contained in:
7
wp-content/plugins/pixelyoursite/vendor/autoload.php
vendored
Normal file
7
wp-content/plugins/pixelyoursite/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitdaa5543e142760e462d1cb6eea8cb38e::getLoader();
|
||||
445
wp-content/plugins/pixelyoursite/vendor/composer/ClassLoader.php
vendored
Normal file
445
wp-content/plugins/pixelyoursite/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
private $classMapAuthoritative = false;
|
||||
private $missingClasses = array();
|
||||
private $apcuPrefix;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
21
wp-content/plugins/pixelyoursite/vendor/composer/LICENSE
vendored
Normal file
21
wp-content/plugins/pixelyoursite/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
1437
wp-content/plugins/pixelyoursite/vendor/composer/autoload_classmap.php
vendored
Normal file
1437
wp-content/plugins/pixelyoursite/vendor/composer/autoload_classmap.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
wp-content/plugins/pixelyoursite/vendor/composer/autoload_namespaces.php
vendored
Normal file
9
wp-content/plugins/pixelyoursite/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
10
wp-content/plugins/pixelyoursite/vendor/composer/autoload_psr4.php
vendored
Normal file
10
wp-content/plugins/pixelyoursite/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'URL\\' => array($vendorDir . '/glenscott/url-normalizer/src/URL'),
|
||||
);
|
||||
55
wp-content/plugins/pixelyoursite/vendor/composer/autoload_real.php
vendored
Normal file
55
wp-content/plugins/pixelyoursite/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitdaa5543e142760e462d1cb6eea8cb38e
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitdaa5543e142760e462d1cb6eea8cb38e', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitdaa5543e142760e462d1cb6eea8cb38e', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitdaa5543e142760e462d1cb6eea8cb38e::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
1463
wp-content/plugins/pixelyoursite/vendor/composer/autoload_static.php
vendored
Normal file
1463
wp-content/plugins/pixelyoursite/vendor/composer/autoload_static.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
94
wp-content/plugins/pixelyoursite/vendor/composer/installed.json
vendored
Normal file
94
wp-content/plugins/pixelyoursite/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
[
|
||||
{
|
||||
"name": "glenscott/url-normalizer",
|
||||
"version": "1.4.0",
|
||||
"version_normalized": "1.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/glenscott/url-normalizer.git",
|
||||
"reference": "b8e79d3360a1bd7182398c9956bd74d219ad1b3c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/glenscott/url-normalizer/zipball/b8e79d3360a1bd7182398c9956bd74d219ad1b3c",
|
||||
"reference": "b8e79d3360a1bd7182398c9956bd74d219ad1b3c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2015-06-11T16:06:02+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"URL\\": "src/URL"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Glen Scott",
|
||||
"email": "glen@glenscott.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Syntax based normalization of URL's"
|
||||
},
|
||||
{
|
||||
"name": "techcrunch/wp-async-task",
|
||||
"version": "dev-master",
|
||||
"version_normalized": "9999999-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/techcrunch/wp-async-task.git",
|
||||
"reference": "9bdbbf9df4ff5179711bb58b9a2451296f6753dc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/techcrunch/wp-async-task/zipball/9bdbbf9df4ff5179711bb58b9a2451296f6753dc",
|
||||
"reference": "9bdbbf9df4ff5179711bb58b9a2451296f6753dc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
"10up/wp_mock": "dev-master",
|
||||
"phpunit/phpunit": "*@stable"
|
||||
},
|
||||
"time": "2016-03-10T17:37:13+00:00",
|
||||
"type": "wordpress-plugin",
|
||||
"installation-source": "source",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"wp-async-task.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Alex Khadiwala",
|
||||
"role": "developer"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Vincent",
|
||||
"role": "developer"
|
||||
},
|
||||
{
|
||||
"name": "Eric Mann",
|
||||
"email": "eric.mann@10up.com",
|
||||
"role": "developer"
|
||||
},
|
||||
{
|
||||
"name": "John P. Bloch",
|
||||
"email": "john.bloch@10up.com",
|
||||
"role": "developer"
|
||||
}
|
||||
],
|
||||
"description": "Run asynchronous tasks for long-running operations in WordPress"
|
||||
}
|
||||
]
|
||||
7
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/LICENSE
vendored
Normal file
7
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/LICENSE
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2013 Glen Scott
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
51
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/README.md
vendored
Normal file
51
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/README.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
# Syntax based normalization of URI's
|
||||
|
||||
This normalizes URI's based on the specification RFC 3986
|
||||
https://tools.ietf.org/html/rfc3986
|
||||
|
||||
Example usage:
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
$url = 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d';
|
||||
$un = new URL\Normalizer( $url );
|
||||
echo $un->normalize();
|
||||
|
||||
// result: "example://a/b/c/%7Bfoo%7D"
|
||||
|
||||
The normalization process preserves semantics so, for example, the following URL's are all equivalent:
|
||||
|
||||
HTTP://www.Example.com/ and http://www.example.com/
|
||||
http://www.example.com/a%c2%b1b and http://www.example.com/a%C2%B1b
|
||||
http://www.example.com/%7Eusername/ and http://www.example.com/~username/
|
||||
http://www.example.com and http://www.example.com/
|
||||
http://www.example.com:80/bar.html and http://www.example.com/bar.html
|
||||
http://www.example.com/../a/b/../c/./d.html and http://www.example.com/a/c/d.html
|
||||
http://www.example.com/?array[key]=value and http://www.example.com/?array%5Bkey%5D=value
|
||||
|
||||
The following normalizations are performed:
|
||||
|
||||
1. Converting the scheme and host to lower case
|
||||
2. Capitalizing letters in escape sequences
|
||||
3. Decoding percent-encoded octets of unreserved characters
|
||||
4. Adding trailing /
|
||||
5. Removing the default port
|
||||
6. Removing dot-segments
|
||||
|
||||
For more information about these normalizations, please see the following Wikipedia article:
|
||||
|
||||
http://en.wikipedia.org/wiki/URL_normalization#Normalizations_that_Preserve_Semantics
|
||||
|
||||
For license information, please see LICENSE file.
|
||||
|
||||
## Options
|
||||
|
||||
Two options are available when normalizing URLs which are disabled by default:
|
||||
|
||||
1. Remove empty delimiters. Enabling this option would normalize http://www.example.com/? to http://www.example.com/ Currently, only the query string delimiter (?) is supported by this option.
|
||||
2. Sort query parameters. Enabling this option sorts the query parameters by key alphabetically. For example, http://www.example.com/?c=3&b=2&a=1 becomes http://www.example.com/?a=1&b=2&c=3
|
||||
|
||||
## TODO
|
||||
|
||||
Add further scheme-based normalization steps, as detailed in section 6.2.3 of the RFC.
|
||||
20
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/composer.json
vendored
Normal file
20
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/composer.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "glenscott/url-normalizer",
|
||||
"description": "Syntax based normalization of URL's",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Glen Scott",
|
||||
"email": "glen@glenscott.co.uk"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"URL\\" : "src/URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
389
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/src/URL/Normalizer.php
vendored
Normal file
389
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/src/URL/Normalizer.php
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace URL;
|
||||
|
||||
/**
|
||||
* Syntax based normalization of URI's
|
||||
*
|
||||
* This normalises URI's based on the specification RFC 3986
|
||||
* https://tools.ietf.org/html/rfc3986
|
||||
*
|
||||
* Example usage:
|
||||
* <code>
|
||||
* require_once 'Normalizer.php';
|
||||
*
|
||||
* $url = 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d';
|
||||
* $un = new URLNormalizer();
|
||||
* $un->setUrl( $url );
|
||||
* echo $un->normalize();
|
||||
*
|
||||
* // result: "example://a/b/c/%7Bfoo%7D"
|
||||
* </code>
|
||||
*
|
||||
* @author Glen Scott <glen@glenscott.co.uk>
|
||||
*/
|
||||
class Normalizer
|
||||
{
|
||||
private $url;
|
||||
private $scheme;
|
||||
private $host;
|
||||
private $port;
|
||||
private $user;
|
||||
private $pass;
|
||||
private $path;
|
||||
private $query;
|
||||
private $fragment;
|
||||
private $default_scheme_ports = array( 'http:' => 80, 'https:' => 443, );
|
||||
private $components = array( 'scheme', 'host', 'port', 'user', 'pass', 'path', 'query', 'fragment', );
|
||||
private $remove_empty_delimiters;
|
||||
private $sort_query_params;
|
||||
|
||||
/**
|
||||
* Does the original URL have a ? query delimiter
|
||||
*/
|
||||
private $query_delimiter;
|
||||
|
||||
public function __construct($url = null, $remove_empty_delimiters = false, $sort_query_params = false)
|
||||
{
|
||||
if ($url) {
|
||||
$this->setUrl($url);
|
||||
}
|
||||
|
||||
$this->remove_empty_delimiters = $remove_empty_delimiters;
|
||||
$this->sort_query_params = $sort_query_params;
|
||||
}
|
||||
|
||||
private function getQuery($query)
|
||||
{
|
||||
$qs = array();
|
||||
foreach ($query as $qk => $qv) {
|
||||
if (is_array($qv)) {
|
||||
$qs[rawurldecode($qk)] = $this->getQuery($qv);
|
||||
} else {
|
||||
$qs[rawurldecode($qk)] = rawurldecode($qv);
|
||||
}
|
||||
}
|
||||
return $qs;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
if (strpos($this->url, '?') !== false) {
|
||||
$this->query_delimiter = true;
|
||||
} else {
|
||||
$this->query_delimiter = false;
|
||||
}
|
||||
|
||||
// parse URL into respective parts
|
||||
$url_components = $this->mbParseUrl($this->url);
|
||||
|
||||
if (! $url_components) {
|
||||
// Reset URL
|
||||
$this->url = '';
|
||||
|
||||
// Flush properties
|
||||
foreach ($this->components as $key) {
|
||||
if (property_exists($this, $key)) {
|
||||
$this->$key = '';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Update properties
|
||||
foreach ($url_components as $key => $value) {
|
||||
if (property_exists($this, $key)) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush missing components
|
||||
$missing_components = array_diff(
|
||||
array_values($this->components),
|
||||
array_keys($url_components)
|
||||
);
|
||||
|
||||
foreach ($missing_components as $key) {
|
||||
if (property_exists($this, $key)) {
|
||||
$this->$key = '';
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function normalize()
|
||||
{
|
||||
|
||||
// URI Syntax Components
|
||||
// scheme authority path query fragment
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3
|
||||
|
||||
// Scheme
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.1
|
||||
|
||||
if ($this->scheme) {
|
||||
// Converting the scheme to lower case
|
||||
$this->scheme = strtolower($this->scheme) . ':';
|
||||
}
|
||||
|
||||
// Authority
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
|
||||
$authority = '';
|
||||
if ($this->host) {
|
||||
$authority .= '//';
|
||||
|
||||
// User Information
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.2.1
|
||||
|
||||
if ($this->user) {
|
||||
if ($this->pass) {
|
||||
$authority .= $this->user . ':' . $this->pass . '@';
|
||||
} else {
|
||||
$authority .= $this->user . '@';
|
||||
}
|
||||
}
|
||||
|
||||
// Host
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
|
||||
// Converting the host to lower case
|
||||
if (mb_detect_encoding($this->host) == 'UTF-8') {
|
||||
$authority .= mb_strtolower($this->host, 'UTF-8');
|
||||
} else {
|
||||
$authority .= strtolower($this->host);
|
||||
}
|
||||
|
||||
// Port
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.2.3
|
||||
|
||||
// Removing the default port
|
||||
if (isset($this->default_scheme_ports[$this->scheme] )
|
||||
&& $this->port == $this->default_scheme_ports[$this->scheme]) {
|
||||
$this->port = '';
|
||||
}
|
||||
|
||||
if ($this->port) {
|
||||
$authority .= ':' . $this->port;
|
||||
}
|
||||
}
|
||||
|
||||
// Path
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.3
|
||||
|
||||
if ($this->path) {
|
||||
$this->path = $this->removeAdditionalPathPrefixSlashes($this->path);
|
||||
$this->path = $this->removeDotSegments($this->path);
|
||||
$this->path = $this->urlDecodeUnreservedChars($this->path);
|
||||
$this->path = $this->urlDecodeReservedSubDelimChars($this->path);
|
||||
} elseif ($this->url) {
|
||||
// Add default path only when valid URL is present
|
||||
// Adding trailing /
|
||||
$this->path = '/';
|
||||
}
|
||||
|
||||
// Query
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.4
|
||||
|
||||
if ($this->query) {
|
||||
$query = $this->parseStr($this->query);
|
||||
|
||||
//encodes every parameter correctly
|
||||
$qs = $this->getQuery($query);
|
||||
|
||||
$this->query = '?';
|
||||
|
||||
if ($this->sort_query_params) {
|
||||
ksort($qs);
|
||||
}
|
||||
|
||||
foreach ($qs as $key => $val) {
|
||||
if (strlen($this->query) > 1) {
|
||||
$this->query .= '&';
|
||||
}
|
||||
|
||||
if (is_array($val)) {
|
||||
for ($i = 0; $i < count($val); $i++) {
|
||||
if ($i > 0) {
|
||||
$this->query .= '&';
|
||||
}
|
||||
$this->query .= rawurlencode($key) . '=' . rawurlencode($val[$i]);
|
||||
}
|
||||
} else {
|
||||
$this->query .= rawurlencode($key) . '=' . rawurlencode($val);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix http_build_query adding equals sign to empty keys
|
||||
$this->query = str_replace('=&', '&', rtrim($this->query, '='));
|
||||
} else {
|
||||
if ($this->query_delimiter && ! $this->remove_empty_delimiters) {
|
||||
$this->query = '?';
|
||||
}
|
||||
}
|
||||
|
||||
// Fragment
|
||||
// @link https://tools.ietf.org/html/rfc3986#section-3.5
|
||||
|
||||
if ($this->fragment) {
|
||||
$this->fragment = rawurldecode($this->fragment);
|
||||
$this->fragment = rawurlencode($this->fragment);
|
||||
$this->fragment = '#' . $this->fragment;
|
||||
}
|
||||
|
||||
$this->setUrl($this->scheme . $authority . $this->path . $this->query . $this->fragment);
|
||||
|
||||
return $this->getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Path segment normalization
|
||||
* https://tools.ietf.org/html/rfc3986#section-5.2.4
|
||||
*/
|
||||
public function removeDotSegments($path)
|
||||
{
|
||||
$new_path = '';
|
||||
|
||||
while (! empty($path)) {
|
||||
// A
|
||||
$pattern_a = '!^(\.\./|\./)!x';
|
||||
$pattern_b_1 = '!^(/\./)!x';
|
||||
$pattern_b_2 = '!^(/\.)$!x';
|
||||
$pattern_c = '!^(/\.\./|/\.\.)!x';
|
||||
$pattern_d = '!^(\.|\.\.)$!x';
|
||||
$pattern_e = '!(/*[^/]*)!x';
|
||||
|
||||
if (preg_match($pattern_a, $path)) {
|
||||
// remove prefix from $path
|
||||
$path = preg_replace($pattern_a, '', $path);
|
||||
} elseif (preg_match($pattern_b_1, $path, $matches) || preg_match($pattern_b_2, $path, $matches)) {
|
||||
$path = preg_replace("!^" . $matches[1] . "!", '/', $path);
|
||||
} elseif (preg_match($pattern_c, $path, $matches)) {
|
||||
$path = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $path);
|
||||
|
||||
// remove the last segment and its preceding "/" (if any) from output buffer
|
||||
$new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
|
||||
} elseif (preg_match($pattern_d, $path)) {
|
||||
$path = preg_replace($pattern_d, '', $path);
|
||||
} else {
|
||||
if (preg_match($pattern_e, $path, $matches)) {
|
||||
$first_path_segment = $matches[1];
|
||||
|
||||
$path = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $path, 1);
|
||||
|
||||
$new_path .= $first_path_segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $new_path;
|
||||
}
|
||||
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode unreserved characters
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-2.3
|
||||
*/
|
||||
public function urlDecodeUnreservedChars($string)
|
||||
{
|
||||
$string = rawurldecode($string);
|
||||
$string = rawurlencode($string);
|
||||
$string = str_replace(array( '%2F', '%3A', '%40' ), array( '/', ':', '@' ), $string);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode reserved sub-delims
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-2.2
|
||||
*/
|
||||
public function urlDecodeReservedSubDelimChars($string)
|
||||
{
|
||||
return str_replace(
|
||||
array( '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D' ),
|
||||
array( '!', '$', '&', "'", '(', ')', '*', '+', ',', ';', '=' ),
|
||||
$string
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement for PHP's parse_string which does not deal with spaces or dots in key names
|
||||
*
|
||||
* @param string $string URL query string
|
||||
* @return array key value pairs
|
||||
*/
|
||||
private function parseStr($string)
|
||||
{
|
||||
$params = array();
|
||||
|
||||
$pairs = explode('&', $string);
|
||||
|
||||
foreach ($pairs as $pair) {
|
||||
if (! $pair) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$var = explode('=', $pair, 2);
|
||||
$val = ( isset( $var[1] ) ? $var[1] : '' );
|
||||
|
||||
if (isset($params[$var[0]])) {
|
||||
if (is_array($params[$var[0]])) {
|
||||
$params[$var[0]][] = $val;
|
||||
} else {
|
||||
$params[$var[0]] = array($params[$var[0]], $val);
|
||||
}
|
||||
} else {
|
||||
$params[$var[0]] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
private function mbParseUrl($url)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
// Build arrays of values we need to decode before parsing
|
||||
$entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%24', '%2C', '%2F', '%3F', '%23', '%5B', '%5D');
|
||||
$replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "$", ",", "/", "?", "#", "[", "]");
|
||||
|
||||
// Create encoded URL with special URL characters decoded so it can be parsed
|
||||
// All other characters will be encoded
|
||||
$encodedURL = str_replace($entities, $replacements, urlencode($url));
|
||||
|
||||
// Parse the encoded URL
|
||||
$encodedParts = parse_url($encodedURL);
|
||||
|
||||
// Now, decode each value of the resulting array
|
||||
if ($encodedParts) {
|
||||
foreach ($encodedParts as $key => $value) {
|
||||
$result[$key] = urldecode(str_replace($replacements, $entities, $value));
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts ////foo to /foo within each path segment
|
||||
*/
|
||||
private function removeAdditionalPathPrefixSlashes($path)
|
||||
{
|
||||
return preg_replace('/(\/)+/', '/', $path);
|
||||
}
|
||||
}
|
||||
84
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/test-client.php
vendored
Normal file
84
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/test-client.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
echo '<pre>';
|
||||
|
||||
require_once 'src/URL/Normalizer.php';
|
||||
|
||||
$un = new URL\Normalizer();
|
||||
|
||||
test('eXAMPLE://a/./b/../b/%63/%7bfoo%7d', 'example://a/b/c/%7Bfoo%7D');
|
||||
test('http://www.example.com', 'http://www.example.com/');
|
||||
test('http://www.yahoo.com/%a1', 'http://www.yahoo.com/%A1');
|
||||
|
||||
test('HTTP://www.Example.com/', 'http://www.example.com/');
|
||||
test('http://www.example.com/a%c2%b1b', 'http://www.example.com/a%C2%B1b');
|
||||
test('http://www.example.com/%7Eusername/', 'http://www.example.com/~username/');
|
||||
test('http://www.example.com:80/bar.html', 'http://www.example.com/bar.html');
|
||||
|
||||
test('http://www.example.com/../a/b/../c/./d.html', 'http://www.example.com/a/c/d.html');
|
||||
test('../', '' );
|
||||
test('./', '' );
|
||||
test('/./', '/' );
|
||||
test('/.', '/' );
|
||||
test('/a/b/c/./../../g', '/a/g' );
|
||||
test('mid/content=5/../6', 'mid/6' );
|
||||
test('/foo/bar/.', '/foo/bar/' );
|
||||
test('/foo/bar/./', '/foo/bar/' );
|
||||
test('/foo/bar/..', '/foo/' );
|
||||
test('/foo/bar/../', '/foo/' );
|
||||
test('/foo/bar/../baz', '/foo/baz' );
|
||||
test('/foo/bar/../..', '/');
|
||||
test('/foo/bar/../../' , '/');
|
||||
test('/foo/bar/../../baz' , '/baz');
|
||||
//test('/foo/bar/../../../baz' , '/../baz');
|
||||
test('a/./b/../b/', 'a/b/' );
|
||||
test('.', '' );
|
||||
test('..', '' );
|
||||
|
||||
test('%63', 'c');
|
||||
test('%63/%7b', 'c/%7B');
|
||||
|
||||
test('http://example.com', 'http://example.com/');
|
||||
test('http://example.com/', 'http://example.com/');
|
||||
test('http://example.com:/', 'http://example.com/');
|
||||
test('http://example.com:80/', 'http://example.com/');
|
||||
|
||||
test('https://example.com', 'https://example.com/');
|
||||
test('https://example.com/', 'https://example.com/');
|
||||
test('https://example.com:/', 'https://example.com/');
|
||||
test('https://example.com:443/', 'https://example.com/');
|
||||
|
||||
test('http://fancysite.nl/links/doit.pl?id=2029', 'http://fancysite.nl/links/doit.pl?id=2029');
|
||||
test('http://example.com/index.html#fragment', 'http://example.com/index.html#fragment');
|
||||
test('http://example.com:81/index.html', 'http://example.com:81/index.html');
|
||||
test('HtTp://User:Pass@www.ExAmPle.com:80/Blah', 'http://User:Pass@www.example.com/Blah');
|
||||
test('/test:2/', '');
|
||||
test('mailto:mail@example.com', 'mailto:mail@example.com');
|
||||
test('http://user@example.com/', 'http://user@example.com/');
|
||||
test('http://example.com/path/?query#fragment', 'http://example.com/path/?query#fragment');
|
||||
test('http://example.com/path/?q1&q2&q3&q4', 'http://example.com/path/?q1&q2&q3&q4');
|
||||
test('http://example.com:400/', 'http://example.com:400/');
|
||||
test('http://example.com/', 'http://example.com/');
|
||||
|
||||
test('http://example.com/path/?query=space value', 'http://example.com/path/?query=space%20value');
|
||||
|
||||
test('http://www.example.com/?array[key]=value', 'http://www.example.com/?array%5Bkey%5D=value');
|
||||
|
||||
/**
|
||||
* Test URL Normalization
|
||||
*
|
||||
* @param string $input URL to normalize
|
||||
* @param string $expected Anticipated result of normalization
|
||||
* @return void
|
||||
* @author emojka
|
||||
**/
|
||||
function test($input, $expected) {
|
||||
global $un;
|
||||
$un->setUrl($input);
|
||||
$result = $un->normalize();
|
||||
if ($result === $expected) {
|
||||
printf("✔ %s → %s\n", $input, $result);
|
||||
} else {
|
||||
printf("%s ✘ %s → %s\n", $expected, $input, $result);
|
||||
}
|
||||
}
|
||||
320
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/tests/URL/NormalizerTest.php
vendored
Normal file
320
wp-content/plugins/pixelyoursite/vendor/glenscott/url-normalizer/tests/URL/NormalizerTest.php
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
|
||||
require_once dirname( __FILE__ ) . '/../../src/URL/Normalizer.php';
|
||||
|
||||
use URL\Normalizer;
|
||||
|
||||
class NormalizerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $fixture;
|
||||
private $test_url = 'http://www.yahoo.com/';
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->fixture = new Normalizer();
|
||||
}
|
||||
|
||||
public function testClassCanBeInstantiated() {
|
||||
$this->assertTrue( is_object( $this->fixture ) );
|
||||
}
|
||||
|
||||
public function testObjectIsOfCorrectType() {
|
||||
$this->assertTrue( get_class( $this->fixture ) == 'URL\Normalizer' );
|
||||
}
|
||||
|
||||
public function testObjectHasGetUrlMethod() {
|
||||
$this->assertTrue( method_exists( $this->fixture, 'getUrl' ) );
|
||||
}
|
||||
|
||||
public function testSetUrlFromConstructor() {
|
||||
$this->fixture = new Normalizer( 'http://www.example.com/' );
|
||||
$this->assertTrue( $this->fixture->getUrl() == 'http://www.example.com/' );
|
||||
}
|
||||
|
||||
public function testSetUrl() {
|
||||
$this->fixture->setUrl( $this->test_url );
|
||||
$this->assertTrue( $this->fixture->getUrl() == $this->test_url );
|
||||
}
|
||||
|
||||
public function testObjectHasGetSchemeMethod() {
|
||||
$this->assertTrue( method_exists( $this->fixture, 'getScheme' ) );
|
||||
}
|
||||
|
||||
public function testSchemeExtractedFromUrl() {
|
||||
$this->fixture->setUrl( $this->test_url );
|
||||
$this->assertTrue( $this->fixture->getScheme() == 'http' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provider
|
||||
*/
|
||||
public function testUrlsAreNormalised( $url, $normalised_url ) {
|
||||
$this->fixture->setUrl( $url );
|
||||
|
||||
$this->assertEquals( $normalised_url, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provider
|
||||
*/
|
||||
public function testUrlsAreNormalisedAgain( $url, $normalised_url ) {
|
||||
$this->fixture->setUrl( $url );
|
||||
|
||||
// normalize once
|
||||
$this->fixture->normalize();
|
||||
|
||||
// then normalize again
|
||||
$this->assertEquals( $normalised_url, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function provider() {
|
||||
// tests from http://en.wikipedia.org/wiki/URL_normalization#Normalizations_that_Preserve_Semantics
|
||||
return array(
|
||||
array( 'HTTP://www.Example.com/', 'http://www.example.com/' ),
|
||||
array( 'http://www.example.com/a%c2%b1b', 'http://www.example.com/a%C2%B1b' ),
|
||||
array( 'http://www.example.com/%7Eusername/', 'http://www.example.com/~username/' ),
|
||||
array( 'http://www.example.com', 'http://www.example.com/' ),
|
||||
array( 'http://www.example.com:80/bar.html', 'http://www.example.com/bar.html' ),
|
||||
array( 'http://www.example.com/../a/b/../c/./d.html', 'http://www.example.com/a/c/d.html' ),
|
||||
array( 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d', 'example://a/b/c/%7Bfoo%7D' ),
|
||||
);
|
||||
}
|
||||
|
||||
public function testCaseIsNormalization() {
|
||||
$this->fixture->setUrl( 'http://www.yahoo.com/%a1' );
|
||||
$this->assertEquals( 'http://www.yahoo.com/%A1', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dotSegmentProvider
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc3986#section-5.2.4
|
||||
*/
|
||||
public function testRemoveDotSegments( $path, $normalised_path ) {
|
||||
$this->assertEquals( $normalised_path, $this->fixture->removeDotSegments( $path ) );
|
||||
}
|
||||
|
||||
public function dotSegmentProvider() {
|
||||
return array(
|
||||
array( '../', '' ),
|
||||
array( './', '' ),
|
||||
array( '/./', '/' ),
|
||||
array( '/.', '/' ),
|
||||
array( '/a/b/c/./../../g', '/a/g' ),
|
||||
array( 'mid/content=5/../6', 'mid/6' ),
|
||||
array( '/foo/bar/.', '/foo/bar/' ),
|
||||
array( '/foo/bar/./', '/foo/bar/' ),
|
||||
array( '/foo/bar/..', '/foo/' ),
|
||||
array( '/foo/bar/../', '/foo/' ),
|
||||
array( '/foo/bar/../baz', '/foo/baz' ),
|
||||
array('/foo/bar/../..', '/'),
|
||||
array('/foo/bar/../../' , '/'),
|
||||
array('/foo/bar/../../baz' , '/baz'),
|
||||
//array('/foo/bar/../../../baz' , '/../baz'),
|
||||
array( 'a/./b/../b/', 'a/b/' ),
|
||||
array( '.', '' ),
|
||||
array( '..', '' ),
|
||||
);
|
||||
}
|
||||
|
||||
public function testDecodingUnreservedUrlChars() {
|
||||
$this->assertEquals( 'c', $this->fixture->urlDecodeUnreservedChars( '%63' ) );
|
||||
$this->assertEquals( 'c/%7B', $this->fixture->urlDecodeUnreservedChars( '%63/%7b' ) );
|
||||
$this->assertEquals( 'eXAMPLE://a/./b/../b/c/%7Bfoo%7D', $this->fixture->urlDecodeUnreservedChars( 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider schemeData
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc3986#section-6.2.3
|
||||
*/
|
||||
public function testSchemeBasedNormalization( $url ) {
|
||||
$expected_uri = 'http://example.com/';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( $expected_uri, $this->fixture->normalize() );
|
||||
|
||||
}
|
||||
|
||||
public function schemeData() {
|
||||
return array( array( 'http://example.com' ),
|
||||
array( 'http://example.com/' ),
|
||||
array( 'http://example.com:/' ),
|
||||
array( 'http://example.com:80/' ), );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider schemeDataSSL
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc3986#section-6.2.3
|
||||
*/
|
||||
public function testSchemeBasedNormalizationSSL( $url ) {
|
||||
$expected_uri = 'https://example.com/';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( $expected_uri, $this->fixture->normalize() );
|
||||
|
||||
}
|
||||
|
||||
public function schemeDataSSL() {
|
||||
return array( array( 'https://example.com' ),
|
||||
array( 'https://example.com/' ),
|
||||
array( 'https://example.com:/' ),
|
||||
array( 'https://example.com:443/' ), );
|
||||
}
|
||||
|
||||
public function testQueryParametersArePreserved() {
|
||||
$url = 'http://fancysite.nl/links/doit.pl?id=2029';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( $url, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testFragmentIdentifiersArePreserved() {
|
||||
$url = 'http://example.com/index.html#fragment';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( $url, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testPortNumbersArePreserved() {
|
||||
$url = 'http://example.com:81/index.html';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( $url, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testCaseSensitiveElementsArePreserved() {
|
||||
$url = 'HtTp://User:Pass@www.ExAmPle.com:80/Blah';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( 'http://User:Pass@www.example.com/Blah', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testSetUrlReturnsFalseWithUnparseableUrl() {
|
||||
$this->assertFalse( $this->fixture->setUrl( '/test:2/' ) );
|
||||
}
|
||||
|
||||
public function testTrailingSlashIsAdded() {
|
||||
$url = 'http://example.com';
|
||||
|
||||
$this->fixture->setUrl( $url );
|
||||
$this->assertEquals( 'http://example.com/', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testDoubleSlashNotAddedToSchemeIfNoHost() {
|
||||
$uri = 'mailto:mail@example.com';
|
||||
|
||||
$this->fixture->setUrl( $uri );
|
||||
$this->assertEquals( 'mailto:mail@example.com', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testColonNotAddedToUsernameWhenNoPassword() {
|
||||
$uri = 'http://user@example.com/';
|
||||
|
||||
$this->fixture->setUrl( $uri );
|
||||
$this->assertEquals( 'http://user@example.com/', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testPortAndFragmentDoNotPersistBetweenCalls() {
|
||||
$this->fixture->setUrl( 'http://example.com/path/?query#fragment' );
|
||||
$this->fixture->normalize();
|
||||
|
||||
$uri = 'http://example.com:400/';
|
||||
$this->fixture->setUrl( $uri );
|
||||
$this->assertEquals( $uri, $this->fixture->normalize() );
|
||||
|
||||
$uri = 'http://example.com/';
|
||||
$this->fixture->setUrl( $uri );
|
||||
$this->assertEquals( $uri, $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testEbayImageUrl() {
|
||||
$this->fixture->setUrl( 'http://i.ebayimg.com/t/O05520-Adidas-OM-Olympique-Marseille-Jacket-Hooded-UK-S-/00/s/NDAwWDQwMA==/$(KGrHqF,!lMF!iFJh4nmBQflyg7GSw~~60_12.JPG' );
|
||||
$this->assertEquals( 'http://i.ebayimg.com/t/O05520-Adidas-OM-Olympique-Marseille-Jacket-Hooded-UK-S-/00/s/NDAwWDQwMA==/$(KGrHqF,!lMF!iFJh4nmBQflyg7GSw~~60_12.JPG',
|
||||
$this->fixture->normalize() );
|
||||
|
||||
}
|
||||
|
||||
public function testReservedCharactersInPathSegmentAreNotEncoded() {
|
||||
$this->fixture->setUrl( "http://www.example.com/!$&'()*+,;=/" );
|
||||
$this->assertEquals( "http://www.example.com/!$&'()*+,;=/", $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testQueryWithArray() {
|
||||
$this->fixture->setUrl('http://www.example.com/?array[key]=value');
|
||||
$this->assertEquals('http://www.example.com/?array%5Bkey%5D=value', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testSpacesInQueryStringAreCorrectlyEncoded() {
|
||||
$this->fixture->setUrl( 'http://www.example.com/?a space' );
|
||||
$this->assertEquals( 'http://www.example.com/?a%20space', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testQueryValuesThatContainEqualsSignsArePreserved() {
|
||||
$this->fixture->setUrl( 'http://www.example.com/?key=v1=v2' );
|
||||
$this->assertEquals( 'http://www.example.com/?key=v1%3Dv2', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testUtf8HostNames() {
|
||||
$this->fixture->setUrl('http://www.Яндекс.РФ');
|
||||
$this->assertEquals( 'http://www.яндекс.рф/', $this->fixture->normalize() );
|
||||
|
||||
$this->fixture->setUrl('http://dev.ŽiŪrKėNaS.lt');
|
||||
$this->assertEquals( 'http://dev.žiūrkėnas.lt/', $this->fixture->normalize() );
|
||||
|
||||
}
|
||||
|
||||
public function testTrimMultipleSlashes() {
|
||||
$this->fixture->setUrl('http://www.яндекс.рф/////');
|
||||
$this->assertEquals( 'http://www.яндекс.рф/', $this->fixture->normalize() );
|
||||
|
||||
$this->fixture->setUrl('http://www.яндекс.рф/////index.php');
|
||||
$this->assertEquals( 'http://www.яндекс.рф/index.php', $this->fixture->normalize() );
|
||||
|
||||
$this->fixture->setUrl('http://www.яндекс.рф///index////subdir////');
|
||||
$this->assertEquals( 'http://www.яндекс.рф/index/subdir/', $this->fixture->normalize() );
|
||||
|
||||
$this->fixture->setUrl('http://www.яндекс.рф/index/../../subdir');
|
||||
$this->assertEquals( 'http://www.яндекс.рф/subdir', $this->fixture->normalize() );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider unnamedKeys
|
||||
*/
|
||||
public function testUnnamedKeysInQueryStringArePreserved($url, $expected) {
|
||||
$this->fixture->setUrl($url);
|
||||
$this->assertEquals($expected, $this->fixture->normalize());
|
||||
}
|
||||
|
||||
public function unnamedKeys() {
|
||||
return array(
|
||||
array('http://www.example.com/?foo[]=bar&foo[]=baz', 'http://www.example.com/?foo%5B%5D=bar&foo%5B%5D=baz'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testDelimitersArePreservedIfAssociatedComponentIsEmpty()
|
||||
{
|
||||
$this->fixture->setUrl('http://www.example.com/?');
|
||||
$this->assertEquals( 'http://www.example.com/?', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testEmptyDelimitersAreRemovedOption()
|
||||
{
|
||||
$this->fixture = new Normalizer('http://www.example.com/?', true);
|
||||
$this->assertEquals( 'http://www.example.com/', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testEmptyParametersAreNotPreserved()
|
||||
{
|
||||
$this->fixture->setUrl('http://www.example.com/?a&');
|
||||
$this->assertEquals( 'http://www.example.com/?a', $this->fixture->normalize() );
|
||||
}
|
||||
|
||||
public function testAlphabeticalSortingOfQueryParameters()
|
||||
{
|
||||
$this->fixture = new Normalizer('http://www.example.com/?c=3&b=2&a=1', false, true);
|
||||
$this->assertEquals( 'http://www.example.com/?a=1&b=2&c=3', $this->fixture->normalize() );
|
||||
}
|
||||
}
|
||||
21
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/LICENSE.md
vendored
Normal file
21
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 TechCrunch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
124
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/README.md
vendored
Normal file
124
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/README.md
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
# TechCrunch WP Asynchronous Tasks
|
||||
|
||||
TechCrunch WP Asynchronous Tasks plugin for TechCrunch.com
|
||||
|
||||
## Quick Start
|
||||
|
||||
WP Async Task can be installed as a plugin or bundled in other plugins or a theme. The class definition is wrapped in a `class_exists` check, so it will never run the risk of being accidentally defined twice. Just make sure that the plugin file is being included somehow.
|
||||
|
||||
Next, you need to extend the class with your own implementation. Implementations of the class act on an arbitrary action (e.g., `'save_post'`, etc). There are three parts that **must** be present in any class extending `WP_Async_Task`:
|
||||
|
||||
1. A protected `$action` property
|
||||
2. A protected `prepare_data()` method
|
||||
3. A protected `run_action()` method
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
class JPB_Async_Task extends WP_Async_Task {
|
||||
|
||||
protected $action = 'save_post';
|
||||
|
||||
/**
|
||||
* Prepare data for the asynchronous request
|
||||
*
|
||||
* @throws Exception If for any reason the request should not happen
|
||||
*
|
||||
* @param array $data An array of data sent to the hook
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepare_data( $data ) {}
|
||||
|
||||
/**
|
||||
* Run the async task action
|
||||
*/
|
||||
protected function run_action() {}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### `$action`
|
||||
|
||||
The protected `$action` property should be set to the action to which you wish to attach the asynchronous task. For example, if you want to spin off an asynchronous task whenever a post gets saved, you would set this to `save_post`.
|
||||
|
||||
#### `prepare_data( $data )`
|
||||
|
||||
Use this method to prepare the action's data for use in the asynchronous process. Data will be given to `prepare_data()` as an indexed array, just as it would if you used `func_get_args()` to get a function's arguments. This method needs to return an array containing the data in a more useful format. Since these values will be sent in a `POST` request, it's advisable to stick to scalar values for the most part. For example, on `'save_post'`, the action provides `$post_id` and the `$post` object, so we might do this:
|
||||
|
||||
```php
|
||||
protected function prepare_data($data){
|
||||
$post_id = $data[0];
|
||||
return array( 'post_id' => $post_id );
|
||||
}
|
||||
```
|
||||
|
||||
If for any reason the asynchronous task needs to be canceled, you will need to throw an exception:
|
||||
|
||||
```php
|
||||
protected function prepare_data($data){
|
||||
$post_id = $data[0];
|
||||
$post = $data[1];
|
||||
if( 'post' !== $post->post_type ) {
|
||||
throw new Exception( 'We only want async tasks for posts' );
|
||||
}
|
||||
return array( 'post_id' => $post_id );
|
||||
}
|
||||
```
|
||||
|
||||
The library will handle catching the exception and will prevent the request from running if it catches an Exception.
|
||||
|
||||
#### `run_action()`
|
||||
|
||||
This method is responsible for running whatever action should trigger the functions that need to run inside the asynchronous request. The convention is to use `"wp_async_$this->action"`, but that is up to the implementation.
|
||||
|
||||
```php
|
||||
protected function run_action() {
|
||||
$post_id = $_POST['post_id'];
|
||||
$post = get_post( $post_id );
|
||||
if ( $post ) {
|
||||
// Assuming $this->action is 'save_post'
|
||||
do_action( "wp_async_$this->action", $post->ID, $post );
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure that you instantiate your asynchronous task once. Do this no earlier than the `'plugins_loaded'` action.
|
||||
|
||||
Finally, update the action of any tasks that you wish to move to the asynchronous task.
|
||||
|
||||
For example, you might change this:
|
||||
|
||||
```php
|
||||
add_action( 'save_post', 'really_slow_process', 10, 2 );
|
||||
```
|
||||
|
||||
to this:
|
||||
|
||||
```php
|
||||
add_action( 'wp_async_save_post', 'really_slow_process', 10, 2 );
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute, please fork the github repository and submit a pull request.
|
||||
|
||||
When submitting pull requests, please make sure your changes do not cause any unit tests to fail. To run the unit test suite, make sure you've [installed composer](https://getcomposer.org/doc/00-intro.md) and install the test tools by running
|
||||
|
||||
```sh
|
||||
composer install
|
||||
```
|
||||
|
||||
After you've installed the dev tools, run the unit tests by running
|
||||
|
||||
```sh
|
||||
vendor/bin/phpunit
|
||||
```
|
||||
|
||||
## Copyright
|
||||
|
||||
© TechCrunch 2014
|
||||
|
||||
## License
|
||||
|
||||
This library is licensed under the [MIT](http://opensource.org/licenses/MIT) license. See LICENSE.md for more details.
|
||||
6
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/bootstrap.php.dist
vendored
Normal file
6
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/bootstrap.php.dist
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
WP_Mock::setUsePatchwork( false );
|
||||
WP_Mock::bootstrap();
|
||||
37
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/composer.json
vendored
Normal file
37
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/composer.json
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name" : "techcrunch/wp-async-task",
|
||||
"description" : "Run asynchronous tasks for long-running operations in WordPress",
|
||||
"minimum-stability": "dev",
|
||||
"license" : "MIT",
|
||||
"type" : "wordpress-plugin",
|
||||
"authors" : [
|
||||
{
|
||||
"name": "Alex Khadiwala",
|
||||
"role": "developer"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Vincent",
|
||||
"role": "developer"
|
||||
},
|
||||
{
|
||||
"name" : "Eric Mann",
|
||||
"email": "eric.mann@10up.com",
|
||||
"role" : "developer"
|
||||
},
|
||||
{
|
||||
"name" : "John P. Bloch",
|
||||
"email": "john.bloch@10up.com",
|
||||
"role" : "developer"
|
||||
}
|
||||
],
|
||||
"require-dev" : {
|
||||
"10up/wp_mock" : "dev-master",
|
||||
"phpunit/phpunit": "*@stable"
|
||||
},
|
||||
"autoload" : {
|
||||
"classmap": ["wp-async-task.php"]
|
||||
},
|
||||
"autoload-dev" : {
|
||||
"classmap": ["tests/phpunit/mocks/"]
|
||||
}
|
||||
}
|
||||
14
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/phpunit.xml.dist
vendored
Normal file
14
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<phpunit
|
||||
bootstrap="./bootstrap.php.dist"
|
||||
colors="true">
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<directory suffix="Test.php">./tests/phpunit/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<file>./wp-async-task.php</file>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
438
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/tests/phpunit/WP-Async-TaskTest.php
vendored
Normal file
438
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/tests/phpunit/WP-Async-TaskTest.php
vendored
Normal file
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
use WP_Mock\Tools\TestCase;
|
||||
|
||||
class WP_Async_Task_Tests extends TestCase {
|
||||
|
||||
/**
|
||||
* Set up some test mocks
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$_COOKIE = array();
|
||||
$_POST = array();
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
parent::tearDown();
|
||||
$_COOKIE = array();
|
||||
$_POST = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the correct actions are registered based on the auth level
|
||||
*/
|
||||
public function test_auth_level_both() {
|
||||
$async = new Async( false );
|
||||
|
||||
WP_Mock::expectActionAdded( 'async', array( $async, 'launch' ), 10, 20 );
|
||||
WP_Mock::expectActionAdded( 'admin_post_wp_async_async', array( $async, 'handle_postback' ) );
|
||||
WP_Mock::expectActionAdded( 'admin_post_nopriv_wp_async_async', array( $async, 'handle_postback' ) );
|
||||
|
||||
$async->__construct( WP_Async_Task::BOTH );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the correct actions are registered based on the auth level
|
||||
*/
|
||||
public function test_auth_level_logged_in_only() {
|
||||
$async = new Async( false );
|
||||
|
||||
WP_Mock::expectActionAdded( 'async', array( $async, 'launch' ), 10, 20 );
|
||||
WP_Mock::expectActionAdded( 'admin_post_wp_async_async', array( $async, 'handle_postback' ) );
|
||||
|
||||
$async->__construct( WP_Async_Task::LOGGED_IN );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the correct actions are registered based on the auth level
|
||||
*/
|
||||
public function test_auth_level_logged_out_only() {
|
||||
$async = new Async( false );
|
||||
|
||||
WP_Mock::expectActionAdded( 'async', array( $async, 'launch' ), 10, 20 );
|
||||
WP_Mock::expectActionAdded( 'admin_post_nopriv_wp_async_async', array( $async, 'handle_postback' ) );
|
||||
|
||||
$async->__construct( WP_Async_Task::LOGGED_OUT );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the constructor throws an Exception if action is undefined
|
||||
*
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function test_empty_action() {
|
||||
new EmptyAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that throwing an Exception in prepare_data stops a postback from firing
|
||||
*/
|
||||
public function test_exception_stops_launch_sequence() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'prepare_data', 'create_async_nonce' ) );
|
||||
$arg1 = rand( 0, 9 );
|
||||
$arg2 = rand( 10, 99 );
|
||||
$async->shouldReceive( 'prepare_data' )
|
||||
->once()
|
||||
->with( array( $arg1, $arg2 ) )
|
||||
->andThrow( 'Exception' );
|
||||
$async->shouldReceive( 'create_async_nonce' )->never();
|
||||
/** @var Async $async */
|
||||
$async->launch( $arg1, $arg2 );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that launch sets the correct action and _nonce values in the body
|
||||
*/
|
||||
public function test_launch() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'prepare_data', 'create_async_nonce' ) );
|
||||
$arg = 'arg' . rand( 0, 9 );
|
||||
$async->shouldReceive( 'prepare_data' )
|
||||
->once()
|
||||
->with( array( $arg ) )
|
||||
->andReturn( array( 'foo' => $arg ) );
|
||||
$nonce = substr( md5( 'async' . rand( 0, 9 ) ), - 12, 10 );
|
||||
$async->shouldReceive( 'create_async_nonce' )
|
||||
->once()
|
||||
->with()
|
||||
->andReturn( $nonce );
|
||||
$body_data = new ReflectionProperty( 'Async', '_body_data' );
|
||||
$body_data->setAccessible( true );
|
||||
|
||||
WP_Mock::wpFunction( 'has_action', array(
|
||||
'times' => 1,
|
||||
'args' => array( 'shutdown', array( $async, 'launch_on_shutdown' ) ),
|
||||
'return' => false,
|
||||
) );
|
||||
|
||||
WP_Mock::expectActionAdded( 'shutdown', array( $async, 'launch_on_shutdown' ) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->launch( $arg );
|
||||
|
||||
$data = $body_data->getValue( $async );
|
||||
|
||||
$this->assertArrayHasKey( 'action', $data );
|
||||
$this->assertEquals( 'wp_async_async', $data['action'] );
|
||||
$this->assertArrayHasKey( '_nonce', $data );
|
||||
$this->assertEquals( $nonce, $data['_nonce'] );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_launch_on_shutdown() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'prepare_data', 'create_async_nonce' ) );
|
||||
$async->shouldReceive( 'prepare_data' )->andReturn( array() );
|
||||
$async->shouldReceive( 'create_async_nonce' )->andReturn( 'asdf' );
|
||||
|
||||
WP_Mock::wpFunction( 'maybe_serialize', array(
|
||||
'return' => function ( $thing ) {
|
||||
return is_scalar( $thing ) ? $thing : serialize( $thing );
|
||||
}
|
||||
) );
|
||||
|
||||
$_COOKIE = array(
|
||||
'_some_cookie' => 'Value',
|
||||
'foo' => 'bar',
|
||||
'random' => rand( 0, 999999 ),
|
||||
'array' => array( 'not', 'scalar' ),
|
||||
);
|
||||
$cookie_header = '';
|
||||
array_walk( $_COOKIE, function ( $value, $key ) use ( &$cookie_header ) {
|
||||
if ( ! empty( $cookie_header ) ) {
|
||||
$cookie_header .= '; ';
|
||||
}
|
||||
if ( ! is_scalar( $value ) ) {
|
||||
$value = serialize( $value );
|
||||
}
|
||||
$cookie_header .= "$key=" . urlencode( $value );
|
||||
} );
|
||||
|
||||
$verify_ssl = (bool) rand( 0, 1 );
|
||||
WP_Mock::onFilter( 'https_local_ssl_verify' )->with( true )->reply( $verify_ssl );
|
||||
|
||||
WP_Mock::wpFunction( 'admin_url', array(
|
||||
'times' => 1,
|
||||
'args' => array( 'admin-post.php' ),
|
||||
'return' => $url = 'https://tctechcrunch2011.wordpress.com/wp-admin/admin-post.php'
|
||||
) );
|
||||
|
||||
WP_Mock::wpFunction( 'wp_remote_post', array(
|
||||
'times' => 1,
|
||||
'args' => array(
|
||||
$url,
|
||||
array(
|
||||
'timeout' => 0.01,
|
||||
'blocking' => false,
|
||||
'sslverify' => $verify_ssl,
|
||||
'body' => array(
|
||||
'action' => 'wp_async_async',
|
||||
'_nonce' => 'asdf',
|
||||
),
|
||||
'headers' => array(
|
||||
'cookie' => $cookie_header,
|
||||
),
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->launch(); // to set up body data, etc.
|
||||
$async->launch_on_shutdown();
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_launch_on_shutdown_empty_body() {
|
||||
WP_Mock::wpFunction( 'wp_remote_post', array( 'times' => 0, ) );
|
||||
/** @var Async $async */
|
||||
$async = $this->getMockAsync();
|
||||
$async->launch_on_shutdown();
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_handle_postback_nonce_not_set() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'verify_async_nonce', 'run_action' ) );
|
||||
$async->shouldReceive( 'verify_async_nonce' )->never();
|
||||
$async->shouldReceive( 'run_action' )->never();
|
||||
WP_Mock::expectFilterAdded( 'wp_die_handler', function () {
|
||||
die();
|
||||
} );
|
||||
WP_Mock::wpFunction( 'wp_die', array( 'times' => 1 ) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->handle_postback();
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_handle_postback_invalid_nonce() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'verify_async_nonce', 'run_action' ) );
|
||||
$nonce = 'asdfasdf';
|
||||
$_POST['_nonce'] = $nonce;
|
||||
$async->shouldReceive( 'verify_async_nonce' )
|
||||
->once()
|
||||
->with( $nonce )
|
||||
->andReturn( false );
|
||||
$async->shouldReceive( 'run_action' )->never();
|
||||
WP_Mock::expectFilterAdded( 'wp_die_handler', function () {
|
||||
die();
|
||||
} );
|
||||
WP_Mock::wpFunction( 'wp_die', array( 'times' => 1 ) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->handle_postback();
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_handle_postback_anon() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'verify_async_nonce', 'run_action' ) );
|
||||
$nonce = 'asdfasdf';
|
||||
$_POST['_nonce'] = $nonce;
|
||||
$async->shouldReceive( 'verify_async_nonce' )
|
||||
->once()
|
||||
->with( $nonce )
|
||||
->andReturn( true );
|
||||
WP_Mock::wpFunction( 'is_user_logged_in', array( 'times' => 1, 'return' => false, ) );
|
||||
|
||||
$async->shouldReceive( 'run_action' )
|
||||
->once()
|
||||
->with();
|
||||
WP_Mock::expectFilterAdded( 'wp_die_handler', function () {
|
||||
die();
|
||||
} );
|
||||
WP_Mock::wpFunction( 'wp_die', array( 'times' => 1 ) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->handle_postback();
|
||||
|
||||
$action = new ReflectionProperty( 'Async', 'action' );
|
||||
$action->setAccessible( true );
|
||||
$this->assertEquals( 'nopriv_async', $action->getValue( $async ) );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_handle_postback() {
|
||||
$async = $this->getMockAsync( 'Async', array( 'verify_async_nonce', 'run_action' ) );
|
||||
$nonce = 'asdfasdf';
|
||||
$_POST['_nonce'] = $nonce;
|
||||
$async->shouldReceive( 'verify_async_nonce' )
|
||||
->once()
|
||||
->with( $nonce )
|
||||
->andReturn( true );
|
||||
WP_Mock::wpFunction( 'is_user_logged_in', array( 'times' => 1, 'return' => true, ) );
|
||||
$async->shouldReceive( 'run_action' )
|
||||
->once()
|
||||
->with();
|
||||
WP_Mock::expectFilterAdded( 'wp_die_handler', function () {
|
||||
die();
|
||||
} );
|
||||
WP_Mock::wpFunction( 'wp_die', array( 'times' => 1 ) );
|
||||
|
||||
/** @var Async $async */
|
||||
$async->handle_postback();
|
||||
|
||||
$action = new ReflectionProperty( 'Async', 'action' );
|
||||
$action->setAccessible( true );
|
||||
$this->assertEquals( 'async', $action->getValue( $async ) );
|
||||
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_create_async_nonce() {
|
||||
$async = $this->getMockAsync();
|
||||
$nonce_tick = rand( 10, 99 );
|
||||
WP_Mock::wpFunction( 'wp_nonce_tick', array(
|
||||
'times' => 1,
|
||||
'args' => array(),
|
||||
'return' => $nonce_tick,
|
||||
) );
|
||||
$create_nonce = new ReflectionMethod( 'Async', 'create_async_nonce' );
|
||||
$create_nonce->setAccessible( true );
|
||||
|
||||
$expected_hash = md5( $nonce_tick . 'wp_async_async' . get_class( $async ) );
|
||||
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 1,
|
||||
'args' => array( $nonce_tick . 'wp_async_async' . get_class( $async ), 'nonce' ),
|
||||
'return' => $expected_hash,
|
||||
) );
|
||||
|
||||
$this->assertEquals( substr( $expected_hash, - 12, 10 ), $create_nonce->invoke( $async ) );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_verify_async_nonce_invalid() {
|
||||
$async = $this->getMockAsync();
|
||||
$nonce_tick = rand( 10, 99 );
|
||||
WP_Mock::wpFunction( 'wp_nonce_tick', array(
|
||||
'times' => 1,
|
||||
'args' => array(),
|
||||
'return' => $nonce_tick,
|
||||
) );
|
||||
$verify_nonce = new ReflectionMethod( 'Async', 'verify_async_nonce' );
|
||||
$verify_nonce->setAccessible( true );
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 2,
|
||||
'return' => md5( rand( 100, 999 ) ),
|
||||
) );
|
||||
|
||||
$this->assertFalse( $verify_nonce->invoke( $async, md5( $nonce_tick ) ) );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_verify_async_nonce_recent() {
|
||||
$async = $this->getMockAsync();
|
||||
$nonce_tick = rand( 10, 99 );
|
||||
WP_Mock::wpFunction( 'wp_nonce_tick', array(
|
||||
'times' => 1,
|
||||
'args' => array(),
|
||||
'return' => $nonce_tick,
|
||||
) );
|
||||
$verify_nonce = new ReflectionMethod( 'Async', 'verify_async_nonce' );
|
||||
$verify_nonce->setAccessible( true );
|
||||
$hash = md5( $nonce_tick . 'wp_async_async' . get_class( $async ) );
|
||||
$nonce = substr( $hash, - 12, 10 );
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 1,
|
||||
'args' => array( $nonce_tick . 'wp_async_async' . get_class( $async ), 'nonce' ),
|
||||
'return' => function ( $thing ) {
|
||||
return md5( $thing );
|
||||
}
|
||||
) );
|
||||
|
||||
$this->assertSame( 1, $verify_nonce->invoke( $async, $nonce ) );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_verify_async_nonce_old_but_valid() {
|
||||
$async = $this->getMockAsync();
|
||||
$nonce_tick = rand( 10, 99 );
|
||||
$real_tick = $nonce_tick - 1;
|
||||
WP_Mock::wpFunction( 'wp_nonce_tick', array(
|
||||
'times' => 1,
|
||||
'args' => array(),
|
||||
'return' => $nonce_tick,
|
||||
) );
|
||||
$verify_nonce = new ReflectionMethod( 'Async', 'verify_async_nonce' );
|
||||
$verify_nonce->setAccessible( true );
|
||||
$hash = md5( $real_tick . 'wp_async_async' . get_class( $async ) );
|
||||
$nonce = substr( $hash, - 12, 10 );
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 1,
|
||||
'args' => array( $nonce_tick . 'wp_async_async' . get_class( $async ), 'nonce' ),
|
||||
'return' => function ( $thing ) {
|
||||
return md5( $thing );
|
||||
}
|
||||
) );
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 1,
|
||||
'args' => array( $real_tick . 'wp_async_async' . get_class( $async ), 'nonce' ),
|
||||
'return' => function ( $thing ) {
|
||||
return md5( $thing );
|
||||
}
|
||||
) );
|
||||
|
||||
$this->assertSame( 2, $verify_nonce->invoke( $async, $nonce ) );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
public function test_verify_async_nonce_nopriv() {
|
||||
$async = $this->getMockAsync();
|
||||
$nonce_tick = rand( 10, 99 );
|
||||
WP_Mock::wpFunction( 'wp_nonce_tick', array(
|
||||
'times' => 1,
|
||||
'args' => array(),
|
||||
'return' => $nonce_tick,
|
||||
) );
|
||||
$action = new ReflectionProperty( 'Async', 'action' );
|
||||
$action->setAccessible( true );
|
||||
$action->setValue( $async, 'nopriv_async' );
|
||||
$verify_nonce = new ReflectionMethod( 'Async', 'verify_async_nonce' );
|
||||
$verify_nonce->setAccessible( true );
|
||||
$hash = md5( $nonce_tick . 'wp_async_async' . get_class( $async ) );
|
||||
$nonce = substr( $hash, - 12, 10 );
|
||||
WP_Mock::wpFunction( 'wp_hash', array(
|
||||
'times' => 1,
|
||||
'args' => array( $nonce_tick . 'wp_async_async' . get_class( $async ), 'nonce' ),
|
||||
'return' => function ( $thing ) {
|
||||
return md5( $thing );
|
||||
}
|
||||
) );
|
||||
|
||||
$this->assertSame( 1, $verify_nonce->invoke( $async, $nonce ) );
|
||||
$this->assertConditionsMet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mock object for the async task class
|
||||
*
|
||||
* @param string $class The name of the class to mock
|
||||
* @param array $methods Which methods to mock
|
||||
* @param mixed $auth The auth level to simulate
|
||||
*
|
||||
* @return \Mockery\Mock
|
||||
*/
|
||||
private function getMockAsync( $class = 'Async', array $methods = array(), $auth = false ) {
|
||||
$stub = '';
|
||||
if ( ! empty( $methods ) ) {
|
||||
$stub = '[' . implode( ',', $methods ) . ']';
|
||||
}
|
||||
$mockClass = "$class$stub";
|
||||
/** @var \Mockery\Mock $mock */
|
||||
$mock = Mockery::mock( $mockClass, array( $auth ) );
|
||||
$mock->makePartial();
|
||||
$mock->shouldAllowMockingProtectedMethods();
|
||||
return $mock;
|
||||
}
|
||||
|
||||
}
|
||||
11
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/tests/phpunit/mocks/Async.php
vendored
Normal file
11
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/tests/phpunit/mocks/Async.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class Async extends BaseAsync {
|
||||
|
||||
public function __construct( $init = parent::BOTH ) {
|
||||
if ( $init ) {
|
||||
parent::__construct( $init );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class BaseAsync extends WP_Async_Task {
|
||||
|
||||
protected $action = 'async';
|
||||
|
||||
protected function prepare_data( $data ) {
|
||||
}
|
||||
|
||||
protected function run_action() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
class EmptyAsync extends BaseAsync {
|
||||
|
||||
protected $action = null;
|
||||
|
||||
}
|
||||
266
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/wp-async-task.php
vendored
Normal file
266
wp-content/plugins/pixelyoursite/vendor/techcrunch/wp-async-task/wp-async-task.php
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WP Asynchronous Tasks
|
||||
* Version: 1.0
|
||||
* Description: Creates an abstract class to execute asynchronous tasks
|
||||
* Author: 10up, Eric Mann, Luke Gedeon, John P. Bloch
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Task' ) ) {
|
||||
abstract class WP_Async_Task {
|
||||
|
||||
/**
|
||||
* Constant identifier for a task that should be available to logged-in users
|
||||
*
|
||||
* See constructor documentation for more details.
|
||||
*/
|
||||
const LOGGED_IN = 1;
|
||||
|
||||
/**
|
||||
* Constant identifier for a task that should be available to logged-out users
|
||||
*
|
||||
* See constructor documentation for more details.
|
||||
*/
|
||||
const LOGGED_OUT = 2;
|
||||
|
||||
/**
|
||||
* Constant identifier for a task that should be available to all users regardless of auth status
|
||||
*
|
||||
* See constructor documentation for more details.
|
||||
*/
|
||||
const BOTH = 3;
|
||||
|
||||
/**
|
||||
* This is the argument count for the main action set in the constructor. It
|
||||
* is set to an arbitrarily high value of twenty, but can be overridden if
|
||||
* necessary
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $argument_count = 20;
|
||||
|
||||
/**
|
||||
* Priority to fire intermediate action.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $priority = 10;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $action;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_body_data;
|
||||
|
||||
/**
|
||||
* Constructor to wire up the necessary actions
|
||||
*
|
||||
* Which hooks the asynchronous postback happens on can be set by the
|
||||
* $auth_level parameter. There are essentially three options: logged in users
|
||||
* only, logged out users only, or both. Set this when you instantiate an
|
||||
* object by using one of the three class constants to do so:
|
||||
* - LOGGED_IN
|
||||
* - LOGGED_OUT
|
||||
* - BOTH
|
||||
* $auth_level defaults to BOTH
|
||||
*
|
||||
* @throws Exception If the class' $action value hasn't been set
|
||||
*
|
||||
* @param int $auth_level The authentication level to use (see above)
|
||||
*/
|
||||
public function __construct( $auth_level = self::BOTH ) {
|
||||
if ( empty( $this->action ) ) {
|
||||
throw new Exception( 'Action not defined for class ' . __CLASS__ );
|
||||
}
|
||||
add_action( $this->action, array( $this, 'launch' ), (int) $this->priority, (int) $this->argument_count );
|
||||
if ( $auth_level & self::LOGGED_IN ) {
|
||||
add_action( "admin_post_wp_async_$this->action", array( $this, 'handle_postback' ) );
|
||||
}
|
||||
if ( $auth_level & self::LOGGED_OUT ) {
|
||||
add_action( "admin_post_nopriv_wp_async_$this->action", array( $this, 'handle_postback' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the shutdown action for launching the real postback if we don't
|
||||
* get an exception thrown by prepare_data().
|
||||
*
|
||||
* @uses func_get_args() To grab any arguments passed by the action
|
||||
*/
|
||||
public function launch() {
|
||||
$data = func_get_args();
|
||||
try {
|
||||
$data = $this->prepare_data( $data );
|
||||
} catch ( Exception $e ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data['action'] = "wp_async_$this->action";
|
||||
$data['_nonce'] = $this->create_async_nonce();
|
||||
|
||||
$this->_body_data = $data;
|
||||
|
||||
if ( ! has_action( 'shutdown', array( $this, 'launch_on_shutdown' ) ) ) {
|
||||
add_action( 'shutdown', array( $this, 'launch_on_shutdown' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the request on the WordPress shutdown hook
|
||||
*
|
||||
* On VIP we got into data races due to the postback sometimes completing
|
||||
* faster than the data could propogate to the database server cluster.
|
||||
* This made WordPress get empty data sets from the database without
|
||||
* failing. On their advice, we're moving the actual firing of the async
|
||||
* postback to the shutdown hook. Supposedly that will ensure that the
|
||||
* data at least has time to get into the object cache.
|
||||
*
|
||||
* @uses $_COOKIE To send a cookie header for async postback
|
||||
* @uses apply_filters()
|
||||
* @uses admin_url()
|
||||
* @uses wp_remote_post()
|
||||
*/
|
||||
public function launch_on_shutdown() {
|
||||
if ( ! empty( $this->_body_data ) ) {
|
||||
$cookies = array();
|
||||
foreach ( $_COOKIE as $name => $value ) {
|
||||
$cookies[] = "$name=" . urlencode( is_array( $value ) ? serialize( $value ) : $value );
|
||||
}
|
||||
|
||||
$request_args = array(
|
||||
'timeout' => 0.01,
|
||||
'blocking' => false,
|
||||
'sslverify' => apply_filters( 'https_local_ssl_verify', true ),
|
||||
'body' => $this->_body_data,
|
||||
'headers' => array(
|
||||
'cookie' => implode( '; ', $cookies ),
|
||||
),
|
||||
);
|
||||
|
||||
$url = admin_url( 'admin-post.php' );
|
||||
|
||||
wp_remote_post( $url, $request_args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the postback is valid, then fire any scheduled events.
|
||||
*
|
||||
* @uses $_POST['_nonce']
|
||||
* @uses is_user_logged_in()
|
||||
* @uses add_filter()
|
||||
* @uses wp_die()
|
||||
*/
|
||||
public function handle_postback() {
|
||||
if ( isset( $_POST['_nonce'] ) && $this->verify_async_nonce( $_POST['_nonce'] ) ) {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$this->action = "nopriv_$this->action";
|
||||
}
|
||||
$this->run_action();
|
||||
}
|
||||
|
||||
add_filter( 'wp_die_handler', function() { die(); } );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random, one time use token.
|
||||
*
|
||||
* Based entirely on wp_create_nonce() but does not tie the nonce to the
|
||||
* current logged-in user.
|
||||
*
|
||||
* @uses wp_nonce_tick()
|
||||
* @uses wp_hash()
|
||||
*
|
||||
* @return string The one-time use token
|
||||
*/
|
||||
protected function create_async_nonce() {
|
||||
$action = $this->get_nonce_action();
|
||||
$i = wp_nonce_tick();
|
||||
|
||||
return substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the correct nonce was used within the time limit.
|
||||
*
|
||||
* @uses wp_nonce_tick()
|
||||
* @uses wp_hash()
|
||||
*
|
||||
* @param string $nonce Nonce to be verified
|
||||
*
|
||||
* @return bool Whether the nonce check passed or failed
|
||||
*/
|
||||
protected function verify_async_nonce( $nonce ) {
|
||||
$action = $this->get_nonce_action();
|
||||
$i = wp_nonce_tick();
|
||||
|
||||
// Nonce generated 0-12 hours ago
|
||||
if ( substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Nonce generated 12-24 hours ago
|
||||
if ( substr( wp_hash( ( $i - 1 ) . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Invalid nonce
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a nonce action based on the $action property of the class
|
||||
*
|
||||
* @return string The nonce action for the current instance
|
||||
*/
|
||||
protected function get_nonce_action() {
|
||||
$action = $this->action;
|
||||
if ( substr( $action, 0, 7 ) === 'nopriv_' ) {
|
||||
$action = substr( $action, 7 );
|
||||
}
|
||||
$action = "wp_async_$action";
|
||||
return $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare any data to be passed to the asynchronous postback
|
||||
*
|
||||
* The array this function receives will be a numerically keyed array from
|
||||
* func_get_args(). It is expected that you will return an associative array
|
||||
* so that the $_POST values used in the asynchronous call will make sense.
|
||||
*
|
||||
* The array you send back may or may not have anything to do with the data
|
||||
* passed into this method. It all depends on the implementation details and
|
||||
* what data is needed in the asynchronous postback.
|
||||
*
|
||||
* Do not set values for 'action' or '_nonce', as those will get overwritten
|
||||
* later in launch().
|
||||
*
|
||||
* @throws Exception If the postback should not occur for any reason
|
||||
*
|
||||
* @param array $data The raw data received by the launch method
|
||||
*
|
||||
* @return array The prepared data
|
||||
*/
|
||||
abstract protected function prepare_data( $data );
|
||||
|
||||
/**
|
||||
* Run the do_action function for the asynchronous postback.
|
||||
*
|
||||
* This method needs to fetch and sanitize any and all data from the $_POST
|
||||
* superglobal and provide them to the do_action call.
|
||||
*
|
||||
* The action should be constructed as "wp_async_task_$this->action"
|
||||
*/
|
||||
abstract protected function run_action();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user