mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-08 19:33:55 +00:00
remove php vendor
This commit is contained in:
parent
5cbe5d60aa
commit
78e1fb231e
@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload.php @generated by Composer
|
|
||||||
|
|
||||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
|
||||||
|
|
||||||
return ComposerAutoloaderInit8ce10e27fcb2a98a8a9f86a0cb326360::getLoader();
|
|
@ -1 +0,0 @@
|
|||||||
../satooshi/php-coveralls/composer/bin/coveralls
|
|
@ -1 +0,0 @@
|
|||||||
../squizlabs/php_codesniffer/scripts/phpcbf
|
|
@ -1 +0,0 @@
|
|||||||
../squizlabs/php_codesniffer/scripts/phpcs
|
|
@ -1 +0,0 @@
|
|||||||
../phpunit/phpunit/phpunit
|
|
@ -1,413 +0,0 @@
|
|||||||
<?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 class loader
|
|
||||||
*
|
|
||||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
|
|
||||||
*
|
|
||||||
* $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>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
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-0 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
|
||||||
if ('\\' == $class[0]) {
|
|
||||||
$class = substr($class, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// class map lookup
|
|
||||||
if (isset($this->classMap[$class])) {
|
|
||||||
return $this->classMap[$class];
|
|
||||||
}
|
|
||||||
if ($this->classMapAuthoritative) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = $this->findFileWithExtension($class, '.php');
|
|
||||||
|
|
||||||
// Search for Hack files if we are running on HHVM
|
|
||||||
if ($file === null && defined('HHVM_VERSION')) {
|
|
||||||
$file = $this->findFileWithExtension($class, '.hh');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($file === null) {
|
|
||||||
// Remember that this class does not exist.
|
|
||||||
return $this->classMap[$class] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function findFileWithExtension($class, $ext)
|
|
||||||
{
|
|
||||||
// PSR-4 lookup
|
|
||||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
|
||||||
|
|
||||||
$first = $class[0];
|
|
||||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
|
||||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
|
||||||
if (0 === strpos($class, $prefix)) {
|
|
||||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
|
||||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scope isolated include.
|
|
||||||
*
|
|
||||||
* Prevents access to $this/self from included files.
|
|
||||||
*/
|
|
||||||
function includeFile($file)
|
|
||||||
{
|
|
||||||
include $file;
|
|
||||||
}
|
|
@ -1,667 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_classmap.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(dirname(__FILE__));
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php',
|
|
||||||
'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php',
|
|
||||||
'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php',
|
|
||||||
'Generic_Sniffs_Classes_DuplicateClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_EmptyStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_ForLoopShouldBeWhileLoopSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_ForLoopWithTestFunctionCallSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_UnconditionalIfStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_UnnecessaryFinalModifierSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_UnusedFunctionParameterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php',
|
|
||||||
'Generic_Sniffs_CodeAnalysis_UselessOverridingMethodSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php',
|
|
||||||
'Generic_Sniffs_Commenting_DocCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php',
|
|
||||||
'Generic_Sniffs_Commenting_FixmeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php',
|
|
||||||
'Generic_Sniffs_Commenting_TodoSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php',
|
|
||||||
'Generic_Sniffs_ControlStructures_InlineControlStructureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php',
|
|
||||||
'Generic_Sniffs_Debug_CSSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php',
|
|
||||||
'Generic_Sniffs_Debug_ClosureLinterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php',
|
|
||||||
'Generic_Sniffs_Debug_JSHintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php',
|
|
||||||
'Generic_Sniffs_Files_ByteOrderMarkSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php',
|
|
||||||
'Generic_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php',
|
|
||||||
'Generic_Sniffs_Files_EndFileNoNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNoNewlineSniff.php',
|
|
||||||
'Generic_Sniffs_Files_InlineHTMLSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/InlineHTMLSniff.php',
|
|
||||||
'Generic_Sniffs_Files_LineEndingsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineEndingsSniff.php',
|
|
||||||
'Generic_Sniffs_Files_LineLengthSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineLengthSniff.php',
|
|
||||||
'Generic_Sniffs_Files_LowercasedFilenameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LowercasedFilenameSniff.php',
|
|
||||||
'Generic_Sniffs_Files_OneClassPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneClassPerFileSniff.php',
|
|
||||||
'Generic_Sniffs_Files_OneInterfacePerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneInterfacePerFileSniff.php',
|
|
||||||
'Generic_Sniffs_Files_OneTraitPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneTraitPerFileSniff.php',
|
|
||||||
'Generic_Sniffs_Formatting_DisallowMultipleStatementsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/DisallowMultipleStatementsSniff.php',
|
|
||||||
'Generic_Sniffs_Formatting_MultipleStatementAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php',
|
|
||||||
'Generic_Sniffs_Formatting_NoSpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/NoSpaceAfterCastSniff.php',
|
|
||||||
'Generic_Sniffs_Formatting_SpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterCastSniff.php',
|
|
||||||
'Generic_Sniffs_Functions_CallTimePassByReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/CallTimePassByReferenceSniff.php',
|
|
||||||
'Generic_Sniffs_Functions_FunctionCallArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php',
|
|
||||||
'Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php',
|
|
||||||
'Generic_Sniffs_Functions_OpeningFunctionBraceKernighanRitchieSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
|
|
||||||
'Generic_Sniffs_Metrics_CyclomaticComplexitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php',
|
|
||||||
'Generic_Sniffs_Metrics_NestingLevelSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/NestingLevelSniff.php',
|
|
||||||
'Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php',
|
|
||||||
'Generic_Sniffs_NamingConventions_ConstructorNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/ConstructorNameSniff.php',
|
|
||||||
'Generic_Sniffs_NamingConventions_UpperCaseConstantNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_CharacterBeforePHPOpeningTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/CharacterBeforePHPOpeningTagSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_ClosingPHPTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ClosingPHPTagSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_DeprecatedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_DisallowShortOpenTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_LowerCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseConstantSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_LowerCaseKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseKeywordSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_NoSilencedErrorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/NoSilencedErrorsSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_SAPIUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SAPIUsageSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_SyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php',
|
|
||||||
'Generic_Sniffs_PHP_UpperCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/UpperCaseConstantSniff.php',
|
|
||||||
'Generic_Sniffs_Strings_UnnecessaryStringConcatSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Strings/UnnecessaryStringConcatSniff.php',
|
|
||||||
'Generic_Sniffs_VersionControl_SubversionPropertiesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/VersionControl/SubversionPropertiesSniff.php',
|
|
||||||
'Generic_Sniffs_WhiteSpace_DisallowSpaceIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowSpaceIndentSniff.php',
|
|
||||||
'Generic_Sniffs_WhiteSpace_DisallowTabIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
|
|
||||||
'Generic_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
|
||||||
'MySource_Sniffs_CSS_BrowserSpecificStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/CSS/BrowserSpecificStylesSniff.php',
|
|
||||||
'MySource_Sniffs_Channels_DisallowSelfActionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/DisallowSelfActionsSniff.php',
|
|
||||||
'MySource_Sniffs_Channels_IncludeOwnSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeOwnSystemSniff.php',
|
|
||||||
'MySource_Sniffs_Channels_IncludeSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeSystemSniff.php',
|
|
||||||
'MySource_Sniffs_Channels_UnusedSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/UnusedSystemSniff.php',
|
|
||||||
'MySource_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Commenting/FunctionCommentSniff.php',
|
|
||||||
'MySource_Sniffs_Debug_DebugCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/DebugCodeSniff.php',
|
|
||||||
'MySource_Sniffs_Debug_FirebugConsoleSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/FirebugConsoleSniff.php',
|
|
||||||
'MySource_Sniffs_Objects_AssignThisSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/AssignThisSniff.php',
|
|
||||||
'MySource_Sniffs_Objects_CreateWidgetTypeCallbackSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/CreateWidgetTypeCallbackSniff.php',
|
|
||||||
'MySource_Sniffs_Objects_DisallowNewWidgetSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/DisallowNewWidgetSniff.php',
|
|
||||||
'MySource_Sniffs_PHP_AjaxNullComparisonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/AjaxNullComparisonSniff.php',
|
|
||||||
'MySource_Sniffs_PHP_EvalObjectFactorySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/EvalObjectFactorySniff.php',
|
|
||||||
'MySource_Sniffs_PHP_GetRequestDataSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/GetRequestDataSniff.php',
|
|
||||||
'MySource_Sniffs_PHP_ReturnFunctionValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/ReturnFunctionValueSniff.php',
|
|
||||||
'MySource_Sniffs_Strings_JoinStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Strings/JoinStringsSniff.php',
|
|
||||||
'PEAR_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Classes/ClassDeclarationSniff.php',
|
|
||||||
'PEAR_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/ClassCommentSniff.php',
|
|
||||||
'PEAR_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FileCommentSniff.php',
|
|
||||||
'PEAR_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php',
|
|
||||||
'PEAR_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/InlineCommentSniff.php',
|
|
||||||
'PEAR_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
|
||||||
'PEAR_Sniffs_ControlStructures_MultiLineConditionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/MultiLineConditionSniff.php',
|
|
||||||
'PEAR_Sniffs_Files_IncludingFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Files/IncludingFileSniff.php',
|
|
||||||
'PEAR_Sniffs_Formatting_MultiLineAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Formatting/MultiLineAssignmentSniff.php',
|
|
||||||
'PEAR_Sniffs_Functions_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php',
|
|
||||||
'PEAR_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php',
|
|
||||||
'PEAR_Sniffs_Functions_ValidDefaultValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
|
|
||||||
'PEAR_Sniffs_NamingConventions_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidClassNameSniff.php',
|
|
||||||
'PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
|
||||||
'PEAR_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
|
||||||
'PEAR_Sniffs_WhiteSpace_ObjectOperatorIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php',
|
|
||||||
'PEAR_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
|
||||||
'PEAR_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
|
||||||
'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php',
|
|
||||||
'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php',
|
|
||||||
'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php',
|
|
||||||
'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php',
|
|
||||||
'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php',
|
|
||||||
'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php',
|
|
||||||
'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php',
|
|
||||||
'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php',
|
|
||||||
'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
|
|
||||||
'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php',
|
|
||||||
'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
|
|
||||||
'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php',
|
|
||||||
'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php',
|
|
||||||
'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
|
|
||||||
'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
|
|
||||||
'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
|
|
||||||
'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
|
|
||||||
'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php',
|
|
||||||
'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php',
|
|
||||||
'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php',
|
|
||||||
'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php',
|
|
||||||
'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
|
|
||||||
'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
|
|
||||||
'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
|
|
||||||
'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php',
|
|
||||||
'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
|
|
||||||
'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
|
|
||||||
'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
|
|
||||||
'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php',
|
|
||||||
'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php',
|
|
||||||
'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
|
|
||||||
'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php',
|
|
||||||
'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php',
|
|
||||||
'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php',
|
|
||||||
'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
|
|
||||||
'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
|
|
||||||
'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
|
|
||||||
'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
|
|
||||||
'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
|
|
||||||
'PHPUnit_Framework_InvalidCoversTargetError' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php',
|
|
||||||
'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
|
|
||||||
'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php',
|
|
||||||
'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php',
|
|
||||||
'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php',
|
|
||||||
'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php',
|
|
||||||
'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php',
|
|
||||||
'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php',
|
|
||||||
'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php',
|
|
||||||
'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php',
|
|
||||||
'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
|
|
||||||
'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
|
|
||||||
'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php',
|
|
||||||
'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
|
|
||||||
'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
|
|
||||||
'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
|
|
||||||
'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php',
|
|
||||||
'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php',
|
|
||||||
'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php',
|
|
||||||
'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php',
|
|
||||||
'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php',
|
|
||||||
'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php',
|
|
||||||
'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php',
|
|
||||||
'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php',
|
|
||||||
'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
|
|
||||||
'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php',
|
|
||||||
'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
|
|
||||||
'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php',
|
|
||||||
'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
|
|
||||||
'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php',
|
|
||||||
'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php',
|
|
||||||
'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php',
|
|
||||||
'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php',
|
|
||||||
'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
|
|
||||||
'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
|
|
||||||
'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php',
|
|
||||||
'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php',
|
|
||||||
'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
|
|
||||||
'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php',
|
|
||||||
'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php',
|
|
||||||
'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php',
|
|
||||||
'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php',
|
|
||||||
'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php',
|
|
||||||
'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php',
|
|
||||||
'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php',
|
|
||||||
'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php',
|
|
||||||
'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php',
|
|
||||||
'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
|
|
||||||
'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php',
|
|
||||||
'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php',
|
|
||||||
'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php',
|
|
||||||
'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php',
|
|
||||||
'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php',
|
|
||||||
'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php',
|
|
||||||
'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php',
|
|
||||||
'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php',
|
|
||||||
'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php',
|
|
||||||
'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php',
|
|
||||||
'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
|
|
||||||
'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
|
|
||||||
'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php',
|
|
||||||
'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php',
|
|
||||||
'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php',
|
|
||||||
'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php',
|
|
||||||
'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php',
|
|
||||||
'PHP_CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php',
|
|
||||||
'PHP_CodeCoverage_Driver' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver.php',
|
|
||||||
'PHP_CodeCoverage_Driver_HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php',
|
|
||||||
'PHP_CodeCoverage_Driver_Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php',
|
|
||||||
'PHP_CodeCoverage_Exception' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception.php',
|
|
||||||
'PHP_CodeCoverage_Exception_UnintentionallyCoveredCode' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php',
|
|
||||||
'PHP_CodeCoverage_Filter' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Filter.php',
|
|
||||||
'PHP_CodeCoverage_Report_Clover' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php',
|
|
||||||
'PHP_CodeCoverage_Report_Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php',
|
|
||||||
'PHP_CodeCoverage_Report_Factory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php',
|
|
||||||
'PHP_CodeCoverage_Report_HTML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php',
|
|
||||||
'PHP_CodeCoverage_Report_HTML_Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php',
|
|
||||||
'PHP_CodeCoverage_Report_HTML_Renderer_Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php',
|
|
||||||
'PHP_CodeCoverage_Report_HTML_Renderer_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php',
|
|
||||||
'PHP_CodeCoverage_Report_HTML_Renderer_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php',
|
|
||||||
'PHP_CodeCoverage_Report_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php',
|
|
||||||
'PHP_CodeCoverage_Report_Node_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php',
|
|
||||||
'PHP_CodeCoverage_Report_Node_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php',
|
|
||||||
'PHP_CodeCoverage_Report_Node_Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php',
|
|
||||||
'PHP_CodeCoverage_Report_PHP' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php',
|
|
||||||
'PHP_CodeCoverage_Report_Text' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_File_Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_File_Method' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_File_Report' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_File_Unit' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_Project' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_Tests' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php',
|
|
||||||
'PHP_CodeCoverage_Report_XML_Totals' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php',
|
|
||||||
'PHP_CodeCoverage_Util' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util.php',
|
|
||||||
'PHP_CodeCoverage_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util/InvalidArgumentHelper.php',
|
|
||||||
'PHP_CodeSniffer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer.php',
|
|
||||||
'PHP_CodeSniffer_CLI' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/CLI.php',
|
|
||||||
'PHP_CodeSniffer_DocGenerators_Generator' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php',
|
|
||||||
'PHP_CodeSniffer_DocGenerators_HTML' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php',
|
|
||||||
'PHP_CodeSniffer_DocGenerators_Markdown' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php',
|
|
||||||
'PHP_CodeSniffer_DocGenerators_Text' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php',
|
|
||||||
'PHP_CodeSniffer_Exception' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Exception.php',
|
|
||||||
'PHP_CodeSniffer_File' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/File.php',
|
|
||||||
'PHP_CodeSniffer_Fixer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Fixer.php',
|
|
||||||
'PHP_CodeSniffer_Report' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Report.php',
|
|
||||||
'PHP_CodeSniffer_Reporting' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reporting.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Cbf' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Checkstyle' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Csv' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Diff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Emacs' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Full' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Gitblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Hgblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Info' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Json' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Junit' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Notifysend' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Source' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Summary' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Svnblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php',
|
|
||||||
'PHP_CodeSniffer_Reports_VersionControl' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php',
|
|
||||||
'PHP_CodeSniffer_Reports_Xml' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php',
|
|
||||||
'PHP_CodeSniffer_Sniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Sniff.php',
|
|
||||||
'PHP_CodeSniffer_Standards_AbstractPatternSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php',
|
|
||||||
'PHP_CodeSniffer_Standards_AbstractScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php',
|
|
||||||
'PHP_CodeSniffer_Standards_AbstractVariableSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php',
|
|
||||||
'PHP_CodeSniffer_Standards_IncorrectPatternException' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/IncorrectPatternException.php',
|
|
||||||
'PHP_CodeSniffer_Tokenizers_CSS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/CSS.php',
|
|
||||||
'PHP_CodeSniffer_Tokenizers_Comment' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/Comment.php',
|
|
||||||
'PHP_CodeSniffer_Tokenizers_JS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/JS.php',
|
|
||||||
'PHP_CodeSniffer_Tokenizers_PHP' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/PHP.php',
|
|
||||||
'PHP_CodeSniffer_Tokens' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokens.php',
|
|
||||||
'PHP_Timer' => $vendorDir . '/phpunit/php-timer/PHP/Timer.php',
|
|
||||||
'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php',
|
|
||||||
'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
|
|
||||||
'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
|
||||||
'PSR1_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Classes/ClassDeclarationSniff.php',
|
|
||||||
'PSR1_Sniffs_Files_SideEffectsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Files/SideEffectsSniff.php',
|
|
||||||
'PSR1_Sniffs_Methods_CamelCapsMethodNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Methods/CamelCapsMethodNameSniff.php',
|
|
||||||
'PSR2_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/ClassDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_Classes_PropertyDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_ControlStructures_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ControlStructureSpacingSniff.php',
|
|
||||||
'PSR2_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/ClosingTagSniff.php',
|
|
||||||
'PSR2_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/EndFileNewlineSniff.php',
|
|
||||||
'PSR2_Sniffs_Methods_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionCallSignatureSniff.php',
|
|
||||||
'PSR2_Sniffs_Methods_MethodDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/MethodDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_Namespaces_NamespaceDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/NamespaceDeclarationSniff.php',
|
|
||||||
'PSR2_Sniffs_Namespaces_UseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/UseDeclarationSniff.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php',
|
|
||||||
'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php',
|
|
||||||
'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php',
|
|
||||||
'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php',
|
|
||||||
'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php',
|
|
||||||
'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php',
|
|
||||||
'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php',
|
|
||||||
'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php',
|
|
||||||
'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php',
|
|
||||||
'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php',
|
|
||||||
'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php',
|
|
||||||
'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php',
|
|
||||||
'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php',
|
|
||||||
'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php',
|
|
||||||
'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php',
|
|
||||||
'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php',
|
|
||||||
'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php',
|
|
||||||
'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php',
|
|
||||||
'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php',
|
|
||||||
'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php',
|
|
||||||
'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php',
|
|
||||||
'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php',
|
|
||||||
'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php',
|
|
||||||
'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php',
|
|
||||||
'Squiz_Sniffs_Arrays_ArrayBracketSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayBracketSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_Arrays_ArrayDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ClassDefinitionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionClosingBraceSpaceSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ClassDefinitionNameSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionNameSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionOpeningBraceSpaceSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ColonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColonSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ColourDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColourDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_DisallowMultipleStyleDefinitionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DisallowMultipleStyleDefinitionsSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateClassDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_DuplicateStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateStyleDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_EmptyClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyClassDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_EmptyStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyStyleDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ForbiddenStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ForbiddenStylesSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_IndentationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/IndentationSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_LowercaseStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/LowercaseStyleDefinitionSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_MissingColonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/MissingColonSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_NamedColoursSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/NamedColoursSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_OpacitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/OpacitySniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/SemicolonSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_CSS_ShorthandSizeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ShorthandSizeSniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_ClassFileNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassFileNameSniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_DuplicatePropertySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/DuplicatePropertySniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_LowercaseClassKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/LowercaseClassKeywordsSniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_SelfMemberReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php',
|
|
||||||
'Squiz_Sniffs_Classes_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ValidClassNameSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_BlockCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/BlockCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClassCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_ClosingDeclarationCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClosingDeclarationCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_DocCommentAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_EmptyCatchCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/EmptyCatchCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FileCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentThrowTagSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/InlineCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_LongConditionClosingCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/LongConditionClosingCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_PostStatementCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/PostStatementCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_Commenting_VariableCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/VariableCommentSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_ForLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForLoopDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_InlineIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/InlineIfDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_LowercaseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/LowercaseDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_Debug_JSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php',
|
|
||||||
'Squiz_Sniffs_Debug_JavaScriptLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php',
|
|
||||||
'Squiz_Sniffs_Files_FileExtensionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Files/FileExtensionSniff.php',
|
|
||||||
'Squiz_Sniffs_Formatting_OperatorBracketSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_FunctionDeclarationArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_FunctionDuplicateArgumentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDuplicateArgumentSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_GlobalFunctionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/GlobalFunctionSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_LowercaseFunctionKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/LowercaseFunctionKeywordsSniff.php',
|
|
||||||
'Squiz_Sniffs_Functions_MultiLineFunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php',
|
|
||||||
'Squiz_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
|
||||||
'Squiz_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
|
||||||
'Squiz_Sniffs_Objects_DisallowObjectStringIndexSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/DisallowObjectStringIndexSniff.php',
|
|
||||||
'Squiz_Sniffs_Objects_ObjectInstantiationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectInstantiationSniff.php',
|
|
||||||
'Squiz_Sniffs_Objects_ObjectMemberCommaSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectMemberCommaSniff.php',
|
|
||||||
'Squiz_Sniffs_Operators_ComparisonOperatorUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php',
|
|
||||||
'Squiz_Sniffs_Operators_IncrementDecrementUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/IncrementDecrementUsageSniff.php',
|
|
||||||
'Squiz_Sniffs_Operators_ValidLogicalOperatorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ValidLogicalOperatorsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_CommentedOutCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/CommentedOutCodeSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowBooleanStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowBooleanStatementSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowComparisonAssignmentSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowInlineIfSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowInlineIfSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowMultipleAssignmentsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowObEndFlushSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowObEndFlushSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DisallowSizeFunctionsInLoopsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowSizeFunctionsInLoopsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_DiscouragedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DiscouragedFunctionsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_EmbeddedPhpSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EmbeddedPhpSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_EvalSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EvalSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_GlobalKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/GlobalKeywordSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_HeredocSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/HeredocSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_InnerFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/LowercasePHPFunctionsSniff.php',
|
|
||||||
'Squiz_Sniffs_PHP_NonExecutableCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
|
|
||||||
'Squiz_Sniffs_Scope_MemberVarScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MemberVarScopeSniff.php',
|
|
||||||
'Squiz_Sniffs_Scope_MethodScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MethodScopeSniff.php',
|
|
||||||
'Squiz_Sniffs_Scope_StaticThisUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/StaticThisUsageSniff.php',
|
|
||||||
'Squiz_Sniffs_Strings_ConcatenationSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/ConcatenationSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_Strings_DoubleQuoteUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/DoubleQuoteUsageSniff.php',
|
|
||||||
'Squiz_Sniffs_Strings_EchoedStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/EchoedStringsSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_CastSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/CastSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_FunctionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionClosingBraceSpaceSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_FunctionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionOpeningBraceSpaceSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_FunctionSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_LanguageConstructSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LanguageConstructSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_LogicalOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LogicalOperatorSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_MemberVarSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/MemberVarSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_ObjectOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ObjectOperatorSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_PropertyLabelSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/PropertyLabelSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_ScopeKeywordSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SemicolonSpacingSniff.php',
|
|
||||||
'Squiz_Sniffs_WhiteSpace_SuperfluousWhitespaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php',
|
|
||||||
'Text_Template' => $vendorDir . '/phpunit/php-text-template/Text/Template.php',
|
|
||||||
'Zend_Sniffs_Debug_CodeAnalyzerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php',
|
|
||||||
'Zend_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Files/ClosingTagSniff.php',
|
|
||||||
'Zend_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
|
||||||
);
|
|
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_namespaces.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(dirname(__FILE__));
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'phpDocumentor' => array($vendorDir . '/phpdocumentor/reflection-docblock/src'),
|
|
||||||
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
|
|
||||||
'Symfony\\Component\\Stopwatch\\' => array($vendorDir . '/symfony/stopwatch'),
|
|
||||||
'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
|
|
||||||
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
|
|
||||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
|
||||||
'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
|
|
||||||
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
|
|
||||||
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
|
|
||||||
'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
|
|
||||||
'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
|
|
||||||
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src'),
|
|
||||||
'Contrib\\Component' => array($vendorDir . '/satooshi/php-coveralls/src'),
|
|
||||||
'Contrib\\Bundle' => array($vendorDir . '/satooshi/php-coveralls/src'),
|
|
||||||
);
|
|
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_psr4.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(dirname(__FILE__));
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'SwaggerPetstore\\' => array($baseDir . '/lib'),
|
|
||||||
);
|
|
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_real.php @generated by Composer
|
|
||||||
|
|
||||||
class ComposerAutoloaderInit8ce10e27fcb2a98a8a9f86a0cb326360
|
|
||||||
{
|
|
||||||
private static $loader;
|
|
||||||
|
|
||||||
public static function loadClassLoader($class)
|
|
||||||
{
|
|
||||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
|
||||||
require __DIR__ . '/ClassLoader.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getLoader()
|
|
||||||
{
|
|
||||||
if (null !== self::$loader) {
|
|
||||||
return self::$loader;
|
|
||||||
}
|
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInit8ce10e27fcb2a98a8a9f86a0cb326360', 'loadClassLoader'), true, true);
|
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInit8ce10e27fcb2a98a8a9f86a0cb326360', 'loadClassLoader'));
|
|
||||||
|
|
||||||
$includePaths = require __DIR__ . '/include_paths.php';
|
|
||||||
array_push($includePaths, get_include_path());
|
|
||||||
set_include_path(join(PATH_SEPARATOR, $includePaths));
|
|
||||||
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function composerRequire8ce10e27fcb2a98a8a9f86a0cb326360($file)
|
|
||||||
{
|
|
||||||
require $file;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// include_paths.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(dirname(__FILE__));
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
$vendorDir . '/phpunit/php-text-template',
|
|
||||||
$vendorDir . '/phpunit/php-timer',
|
|
||||||
);
|
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
|||||||
phpunit.xml
|
|
||||||
composer.lock
|
|
||||||
build
|
|
||||||
vendor
|
|
||||||
coverage.clover
|
|
@ -1,46 +0,0 @@
|
|||||||
before_commands:
|
|
||||||
- "composer install --prefer-source"
|
|
||||||
|
|
||||||
tools:
|
|
||||||
external_code_coverage:
|
|
||||||
timeout: 600
|
|
||||||
php_code_coverage:
|
|
||||||
enabled: true
|
|
||||||
test_command: ./vendor/bin/phpunit
|
|
||||||
php_code_sniffer:
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
standard: PSR2
|
|
||||||
filter:
|
|
||||||
paths: ["src/*", "tests/*"]
|
|
||||||
php_cpd:
|
|
||||||
enabled: true
|
|
||||||
excluded_dirs: ["build/*", "tests", "vendor"]
|
|
||||||
php_cs_fixer:
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
level: all
|
|
||||||
filter:
|
|
||||||
paths: ["src/*", "tests/*"]
|
|
||||||
php_loc:
|
|
||||||
enabled: true
|
|
||||||
excluded_dirs: ["build", "tests", "vendor"]
|
|
||||||
php_mess_detector:
|
|
||||||
enabled: true
|
|
||||||
config:
|
|
||||||
ruleset: phpmd.xml.dist
|
|
||||||
design_rules: { eval_expression: false }
|
|
||||||
filter:
|
|
||||||
paths: ["src/*"]
|
|
||||||
php_pdepend:
|
|
||||||
enabled: true
|
|
||||||
excluded_dirs: ["build", "tests", "vendor"]
|
|
||||||
php_analyzer:
|
|
||||||
enabled: true
|
|
||||||
filter:
|
|
||||||
paths: ["src/*", "tests/*"]
|
|
||||||
php_hhvm:
|
|
||||||
enabled: true
|
|
||||||
filter:
|
|
||||||
paths: ["src/*", "tests/*"]
|
|
||||||
sensiolabs_security_checker: true
|
|
@ -1,13 +0,0 @@
|
|||||||
set -x
|
|
||||||
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] || [ "$TRAVIS_PHP_VERSION" = 'hhvm-nightly' ] ; then
|
|
||||||
curl -sS https://getcomposer.org/installer > composer-installer.php
|
|
||||||
hhvm composer-installer.php
|
|
||||||
hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 composer.phar update --prefer-source
|
|
||||||
elif [ "$TRAVIS_PHP_VERSION" = '5.3.3' ] ; then
|
|
||||||
composer self-update
|
|
||||||
composer update --prefer-source --no-dev
|
|
||||||
composer dump-autoload
|
|
||||||
else
|
|
||||||
composer self-update
|
|
||||||
composer update --prefer-source
|
|
||||||
fi
|
|
@ -1,26 +0,0 @@
|
|||||||
language: php
|
|
||||||
|
|
||||||
php:
|
|
||||||
- 5.3.3
|
|
||||||
- 5.3
|
|
||||||
- 5.4
|
|
||||||
- 5.5
|
|
||||||
- 5.6
|
|
||||||
- hhvm
|
|
||||||
- hhvm-nightly
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- ./.travis.install.sh
|
|
||||||
|
|
||||||
script:
|
|
||||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3.3' ]; then phpunit; fi"
|
|
||||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then ./vendor/bin/phpunit; fi"
|
|
||||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/; fi"
|
|
||||||
- sh -c "if [[ '$TRAVIS_PHP_VERSION' != '5.3.3' && '$TRAVIS_PHP_VERSION' != '5.4.29' && '$TRAVIS_PHP_VERSION' != '5.5.13' ]]; then php -n ./vendor/bin/athletic -p ./tests/DoctrineTest/InstantiatorPerformance/ -f GroupedFormatter; fi"
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.3.3' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- php: hhvm-nightly
|
|
@ -1,35 +0,0 @@
|
|||||||
# Contributing
|
|
||||||
|
|
||||||
* Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
|
|
||||||
* The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
|
|
||||||
* Any contribution must provide tests for additional introduced conditions
|
|
||||||
* Any un-confirmed issue needs a failing test case before being accepted
|
|
||||||
* Pull requests must be sent from a new hotfix/feature branch, not from `master`.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
To install the project and run the tests, you need to clone it first:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ git clone git://github.com/doctrine/instantiator.git
|
|
||||||
```
|
|
||||||
|
|
||||||
You will then need to run a composer installation:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ cd Instantiator
|
|
||||||
$ curl -s https://getcomposer.org/installer | php
|
|
||||||
$ php composer.phar update
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
The PHPUnit version to be used is the one installed as a dev- dependency via composer:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ ./vendor/bin/phpunit
|
|
||||||
```
|
|
||||||
|
|
||||||
Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
|
|
||||||
won't be merged.
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2014 Doctrine Project
|
|
||||||
|
|
||||||
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.
|
|
@ -1,40 +0,0 @@
|
|||||||
# Instantiator
|
|
||||||
|
|
||||||
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator)
|
|
||||||
[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
|
|
||||||
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
|
|
||||||
[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator)
|
|
||||||
[![HHVM Status](http://hhvm.h4cc.de/badge/doctrine/instantiator.png)](http://hhvm.h4cc.de/package/doctrine/instantiator)
|
|
||||||
|
|
||||||
[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator)
|
|
||||||
[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
The suggested installation method is via [composer](https://getcomposer.org/):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
php composer.phar require "doctrine/instantiator:~1.0.3"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
The instantiator is able to create new instances of any class without using the constructor or any API of the class
|
|
||||||
itself:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$instantiator = new \Doctrine\Instantiator\Instantiator();
|
|
||||||
|
|
||||||
$instance = $instantiator->instantiate('My\\ClassName\\Here');
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
|
|
||||||
This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
|
|
||||||
has been donated to the doctrine organization, and which is now deprecated in favour of this package.
|
|
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "doctrine/instantiator",
|
|
||||||
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
|
|
||||||
"type": "library",
|
|
||||||
"license": "MIT",
|
|
||||||
"homepage": "https://github.com/doctrine/instantiator",
|
|
||||||
"keywords": [
|
|
||||||
"instantiate",
|
|
||||||
"constructor"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Marco Pivetta",
|
|
||||||
"email": "ocramius@gmail.com",
|
|
||||||
"homepage": "http://ocramius.github.com/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3,<8.0-DEV"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-phar": "*",
|
|
||||||
"ext-pdo": "*",
|
|
||||||
"phpunit/phpunit": "~4.0",
|
|
||||||
"squizlabs/php_codesniffer": "2.0.*@ALPHA",
|
|
||||||
"athletic/athletic": "~0.1.8"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Doctrine\\Instantiator\\": "src"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-0": {
|
|
||||||
"DoctrineTest\\InstantiatorPerformance\\": "tests",
|
|
||||||
"DoctrineTest\\InstantiatorTest\\": "tests",
|
|
||||||
"DoctrineTest\\InstantiatorTestAsset\\": "tests"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.0.x-dev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<ruleset
|
|
||||||
name="Instantiator rules"
|
|
||||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
|
||||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
|
|
||||||
>
|
|
||||||
<rule ref="rulesets/cleancode.xml">
|
|
||||||
<!-- static access is used for caching purposes -->
|
|
||||||
<exclude name="StaticAccess"/>
|
|
||||||
</rule>
|
|
||||||
<rule ref="rulesets/codesize.xml"/>
|
|
||||||
<rule ref="rulesets/controversial.xml"/>
|
|
||||||
<rule ref="rulesets/design.xml"/>
|
|
||||||
<rule ref="rulesets/naming.xml"/>
|
|
||||||
<rule ref="rulesets/unusedcode.xml"/>
|
|
||||||
<rule
|
|
||||||
name="NPathComplexity"
|
|
||||||
message="The {0} {1}() has an NPath complexity of {2}. The configured NPath complexity threshold is {3}."
|
|
||||||
class="PHP_PMD_Rule_Design_NpathComplexity"
|
|
||||||
>
|
|
||||||
<properties>
|
|
||||||
<property name="minimum" description="The npath reporting threshold" value="10"/>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
</ruleset>
|
|
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<phpunit
|
|
||||||
bootstrap="./vendor/autoload.php"
|
|
||||||
colors="true"
|
|
||||||
convertErrorsToExceptions="true"
|
|
||||||
convertNoticesToExceptions="true"
|
|
||||||
convertWarningsToExceptions="true"
|
|
||||||
verbose="true"
|
|
||||||
stopOnFailure="false"
|
|
||||||
processIsolation="false"
|
|
||||||
backupGlobals="false"
|
|
||||||
syntaxCheck="true"
|
|
||||||
>
|
|
||||||
<testsuite name="Doctrine\Instantiator tests">
|
|
||||||
<directory>./tests/DoctrineTest/InstantiatorTest</directory>
|
|
||||||
</testsuite>
|
|
||||||
<filter>
|
|
||||||
<whitelist addUncoveredFilesFromWhitelist="true">
|
|
||||||
<directory suffix=".php">./src</directory>
|
|
||||||
</whitelist>
|
|
||||||
</filter>
|
|
||||||
<logging>
|
|
||||||
<log type="coverage-clover" target="./coverage.clover"/>
|
|
||||||
</logging>
|
|
||||||
</phpunit>
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Instantiator\Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base exception marker interface for the instantiator component
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
interface ExceptionInterface
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Instantiator\Exception;
|
|
||||||
|
|
||||||
use InvalidArgumentException as BaseInvalidArgumentException;
|
|
||||||
use ReflectionClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception for invalid arguments provided to the instantiator
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromNonExistingClass($className)
|
|
||||||
{
|
|
||||||
if (interface_exists($className)) {
|
|
||||||
return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
|
|
||||||
return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new self(sprintf('The provided class "%s" does not exist', $className));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromAbstractClass(ReflectionClass $reflectionClass)
|
|
||||||
{
|
|
||||||
return new self(sprintf(
|
|
||||||
'The provided class "%s" is abstract, and can not be instantiated',
|
|
||||||
$reflectionClass->getName()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Instantiator\Exception;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use ReflectionClass;
|
|
||||||
use UnexpectedValueException as BaseUnexpectedValueException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception for given parameters causing invalid/unexpected state on instantiation
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
* @param Exception $exception
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception)
|
|
||||||
{
|
|
||||||
return new self(
|
|
||||||
sprintf(
|
|
||||||
'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
|
|
||||||
$reflectionClass->getName()
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
$exception
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
* @param string $errorString
|
|
||||||
* @param int $errorCode
|
|
||||||
* @param string $errorFile
|
|
||||||
* @param int $errorLine
|
|
||||||
*
|
|
||||||
* @return UnexpectedValueException
|
|
||||||
*/
|
|
||||||
public static function fromUncleanUnSerialization(
|
|
||||||
ReflectionClass $reflectionClass,
|
|
||||||
$errorString,
|
|
||||||
$errorCode,
|
|
||||||
$errorFile,
|
|
||||||
$errorLine
|
|
||||||
) {
|
|
||||||
return new self(
|
|
||||||
sprintf(
|
|
||||||
'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
|
|
||||||
. 'in file "%s" at line "%d"',
|
|
||||||
$reflectionClass->getName(),
|
|
||||||
$errorFile,
|
|
||||||
$errorLine
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
new Exception($errorString, $errorCode)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,254 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Instantiator;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Doctrine\Instantiator\Exception\InvalidArgumentException;
|
|
||||||
use Doctrine\Instantiator\Exception\UnexpectedValueException;
|
|
||||||
use Exception;
|
|
||||||
use ReflectionClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
final class Instantiator implements InstantiatorInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Markers used internally by PHP to define whether {@see \unserialize} should invoke
|
|
||||||
* the method {@see \Serializable::unserialize()} when dealing with classes implementing
|
|
||||||
* the {@see \Serializable} interface.
|
|
||||||
*/
|
|
||||||
const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
|
|
||||||
const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Closure[] of {@see \Closure} instances used to instantiate specific classes
|
|
||||||
*/
|
|
||||||
private static $cachedInstantiators = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var object[] of objects that can directly be cloned
|
|
||||||
*/
|
|
||||||
private static $cachedCloneables = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function instantiate($className)
|
|
||||||
{
|
|
||||||
if (isset(self::$cachedCloneables[$className])) {
|
|
||||||
return clone self::$cachedCloneables[$className];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset(self::$cachedInstantiators[$className])) {
|
|
||||||
$factory = self::$cachedInstantiators[$className];
|
|
||||||
|
|
||||||
return $factory();
|
|
||||||
}
|
|
||||||
|
|
||||||
$factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
|
|
||||||
$instance = $factory();
|
|
||||||
$reflection = new ReflectionClass($instance);
|
|
||||||
|
|
||||||
if ($this->isSafeToClone($reflection)) {
|
|
||||||
self::$cachedCloneables[$className] = clone $instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
* @private
|
|
||||||
*
|
|
||||||
* Builds a {@see \Closure} capable of instantiating the given $className without
|
|
||||||
* invoking its constructor.
|
|
||||||
* This method is only exposed as public because of PHP 5.3 compatibility. Do not
|
|
||||||
* use this method in your own code
|
|
||||||
*
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @return Closure
|
|
||||||
*/
|
|
||||||
public function buildFactory($className)
|
|
||||||
{
|
|
||||||
$reflectionClass = $this->getReflectionClass($className);
|
|
||||||
|
|
||||||
if ($this->isInstantiableViaReflection($reflectionClass)) {
|
|
||||||
return function () use ($reflectionClass) {
|
|
||||||
return $reflectionClass->newInstanceWithoutConstructor();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
$serializedString = sprintf(
|
|
||||||
'%s:%d:"%s":0:{}',
|
|
||||||
$this->getSerializationFormat($reflectionClass),
|
|
||||||
strlen($className),
|
|
||||||
$className
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
|
|
||||||
|
|
||||||
return function () use ($serializedString) {
|
|
||||||
return unserialize($serializedString);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @return ReflectionClass
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
private function getReflectionClass($className)
|
|
||||||
{
|
|
||||||
if (! class_exists($className)) {
|
|
||||||
throw InvalidArgumentException::fromNonExistingClass($className);
|
|
||||||
}
|
|
||||||
|
|
||||||
$reflection = new ReflectionClass($className);
|
|
||||||
|
|
||||||
if ($reflection->isAbstract()) {
|
|
||||||
throw InvalidArgumentException::fromAbstractClass($reflection);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $reflection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
* @param string $serializedString
|
|
||||||
*
|
|
||||||
* @throws UnexpectedValueException
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
|
|
||||||
{
|
|
||||||
set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
|
|
||||||
$error = UnexpectedValueException::fromUncleanUnSerialization(
|
|
||||||
$reflectionClass,
|
|
||||||
$message,
|
|
||||||
$code,
|
|
||||||
$file,
|
|
||||||
$line
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
unserialize($serializedString);
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
restore_error_handler();
|
|
||||||
|
|
||||||
throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
restore_error_handler();
|
|
||||||
|
|
||||||
if ($error) {
|
|
||||||
throw $error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
|
|
||||||
{
|
|
||||||
if (\PHP_VERSION_ID >= 50600) {
|
|
||||||
return ! ($reflectionClass->isInternal() && $reflectionClass->isFinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies whether the given class is to be considered internal
|
|
||||||
*
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function hasInternalAncestors(ReflectionClass $reflectionClass)
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
if ($reflectionClass->isInternal()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} while ($reflectionClass = $reflectionClass->getParentClass());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies if the given PHP version implements the `Serializable` interface serialization
|
|
||||||
* with an incompatible serialization format. If that's the case, use serialization marker
|
|
||||||
* "C" instead of "O".
|
|
||||||
*
|
|
||||||
* @link http://news.php.net/php.internals/74654
|
|
||||||
*
|
|
||||||
* @param ReflectionClass $reflectionClass
|
|
||||||
*
|
|
||||||
* @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
|
|
||||||
* or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
|
|
||||||
*/
|
|
||||||
private function getSerializationFormat(ReflectionClass $reflectionClass)
|
|
||||||
{
|
|
||||||
if ($this->isPhpVersionWithBrokenSerializationFormat()
|
|
||||||
&& $reflectionClass->implementsInterface('Serializable')
|
|
||||||
) {
|
|
||||||
return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the current PHP runtime uses an incompatible serialization format
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isPhpVersionWithBrokenSerializationFormat()
|
|
||||||
{
|
|
||||||
return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a class is cloneable
|
|
||||||
*
|
|
||||||
* @param ReflectionClass $reflection
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isSafeToClone(ReflectionClass $reflection)
|
|
||||||
{
|
|
||||||
if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cloneable if it implements `__clone`, as we want to avoid calling it
|
|
||||||
return ! $reflection->hasMethod('__clone');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Doctrine\Instantiator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiator provides utility methods to build objects without invoking their constructors
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
interface InstantiatorInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @return object
|
|
||||||
*
|
|
||||||
* @throws \Doctrine\Instantiator\Exception\ExceptionInterface
|
|
||||||
*/
|
|
||||||
public function instantiate($className);
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorPerformance;
|
|
||||||
|
|
||||||
use Athletic\AthleticEvent;
|
|
||||||
use Doctrine\Instantiator\Instantiator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performance tests for {@see \Doctrine\Instantiator\Instantiator}
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class InstantiatorPerformanceEvent extends AthleticEvent
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \Doctrine\Instantiator\Instantiator
|
|
||||||
*/
|
|
||||||
private $instantiator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
$this->instantiator = new Instantiator();
|
|
||||||
|
|
||||||
$this->instantiator->instantiate(__CLASS__);
|
|
||||||
$this->instantiator->instantiate('ArrayObject');
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset');
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset');
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @iterations 20000
|
|
||||||
* @baseline
|
|
||||||
* @group instantiation
|
|
||||||
*/
|
|
||||||
public function testInstantiateSelf()
|
|
||||||
{
|
|
||||||
$this->instantiator->instantiate(__CLASS__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @iterations 20000
|
|
||||||
* @group instantiation
|
|
||||||
*/
|
|
||||||
public function testInstantiateInternalClass()
|
|
||||||
{
|
|
||||||
$this->instantiator->instantiate('ArrayObject');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @iterations 20000
|
|
||||||
* @group instantiation
|
|
||||||
*/
|
|
||||||
public function testInstantiateSimpleSerializableAssetClass()
|
|
||||||
{
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @iterations 20000
|
|
||||||
* @group instantiation
|
|
||||||
*/
|
|
||||||
public function testInstantiateSerializableArrayObjectAsset()
|
|
||||||
{
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @iterations 20000
|
|
||||||
* @group instantiation
|
|
||||||
*/
|
|
||||||
public function testInstantiateUnCloneableAsset()
|
|
||||||
{
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTest\Exception;
|
|
||||||
|
|
||||||
use Doctrine\Instantiator\Exception\InvalidArgumentException;
|
|
||||||
use PHPUnit_Framework_TestCase;
|
|
||||||
use ReflectionClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@see \Doctrine\Instantiator\Exception\InvalidArgumentException}
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*
|
|
||||||
* @covers \Doctrine\Instantiator\Exception\InvalidArgumentException
|
|
||||||
*/
|
|
||||||
class InvalidArgumentExceptionTest extends PHPUnit_Framework_TestCase
|
|
||||||
{
|
|
||||||
public function testFromNonExistingTypeWithNonExistingClass()
|
|
||||||
{
|
|
||||||
$className = __CLASS__ . uniqid();
|
|
||||||
$exception = InvalidArgumentException::fromNonExistingClass($className);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\InvalidArgumentException', $exception);
|
|
||||||
$this->assertSame('The provided class "' . $className . '" does not exist', $exception->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromNonExistingTypeWithTrait()
|
|
||||||
{
|
|
||||||
if (PHP_VERSION_ID < 50400) {
|
|
||||||
$this->markTestSkipped('Need at least PHP 5.4.0, as this test requires traits support to run');
|
|
||||||
}
|
|
||||||
|
|
||||||
$exception = InvalidArgumentException::fromNonExistingClass(
|
|
||||||
'DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset'
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertSame(
|
|
||||||
'The provided type "DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset" is a trait, '
|
|
||||||
. 'and can not be instantiated',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromNonExistingTypeWithInterface()
|
|
||||||
{
|
|
||||||
$exception = InvalidArgumentException::fromNonExistingClass('Doctrine\\Instantiator\\InstantiatorInterface');
|
|
||||||
|
|
||||||
$this->assertSame(
|
|
||||||
'The provided type "Doctrine\\Instantiator\\InstantiatorInterface" is an interface, '
|
|
||||||
. 'and can not be instantiated',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromAbstractClass()
|
|
||||||
{
|
|
||||||
$reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset');
|
|
||||||
$exception = InvalidArgumentException::fromAbstractClass($reflection);
|
|
||||||
|
|
||||||
$this->assertSame(
|
|
||||||
'The provided class "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" is abstract, '
|
|
||||||
. 'and can not be instantiated',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTest\Exception;
|
|
||||||
|
|
||||||
use Doctrine\Instantiator\Exception\UnexpectedValueException;
|
|
||||||
use Exception;
|
|
||||||
use PHPUnit_Framework_TestCase;
|
|
||||||
use ReflectionClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@see \Doctrine\Instantiator\Exception\UnexpectedValueException}
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*
|
|
||||||
* @covers \Doctrine\Instantiator\Exception\UnexpectedValueException
|
|
||||||
*/
|
|
||||||
class UnexpectedValueExceptionTest extends PHPUnit_Framework_TestCase
|
|
||||||
{
|
|
||||||
public function testFromSerializationTriggeredException()
|
|
||||||
{
|
|
||||||
$reflectionClass = new ReflectionClass($this);
|
|
||||||
$previous = new Exception();
|
|
||||||
$exception = UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $previous);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception);
|
|
||||||
$this->assertSame($previous, $exception->getPrevious());
|
|
||||||
$this->assertSame(
|
|
||||||
'An exception was raised while trying to instantiate an instance of "'
|
|
||||||
. __CLASS__ . '" via un-serialization',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFromUncleanUnSerialization()
|
|
||||||
{
|
|
||||||
$reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset');
|
|
||||||
$exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception);
|
|
||||||
$this->assertSame(
|
|
||||||
'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" '
|
|
||||||
. 'via un-serialization, since an error was triggered in file "bar" at line "456"',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
|
|
||||||
$previous = $exception->getPrevious();
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Exception', $previous);
|
|
||||||
$this->assertSame('foo', $previous->getMessage());
|
|
||||||
$this->assertSame(123, $previous->getCode());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,216 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTest;
|
|
||||||
|
|
||||||
use Doctrine\Instantiator\Exception\UnexpectedValueException;
|
|
||||||
use Doctrine\Instantiator\Instantiator;
|
|
||||||
use PHPUnit_Framework_TestCase;
|
|
||||||
use ReflectionClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@see \Doctrine\Instantiator\Instantiator}
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*
|
|
||||||
* @covers \Doctrine\Instantiator\Instantiator
|
|
||||||
*/
|
|
||||||
class InstantiatorTest extends PHPUnit_Framework_TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var Instantiator
|
|
||||||
*/
|
|
||||||
private $instantiator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
protected function setUp()
|
|
||||||
{
|
|
||||||
$this->instantiator = new Instantiator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @dataProvider getInstantiableClasses
|
|
||||||
*/
|
|
||||||
public function testCanInstantiate($className)
|
|
||||||
{
|
|
||||||
$this->assertInstanceOf($className, $this->instantiator->instantiate($className));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $className
|
|
||||||
*
|
|
||||||
* @dataProvider getInstantiableClasses
|
|
||||||
*/
|
|
||||||
public function testInstantiatesSeparateInstances($className)
|
|
||||||
{
|
|
||||||
$instance1 = $this->instantiator->instantiate($className);
|
|
||||||
$instance2 = $this->instantiator->instantiate($className);
|
|
||||||
|
|
||||||
$this->assertEquals($instance1, $instance2);
|
|
||||||
$this->assertNotSame($instance1, $instance2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testExceptionOnUnSerializationException()
|
|
||||||
{
|
|
||||||
if (defined('HHVM_VERSION')) {
|
|
||||||
$this->markTestSkipped(
|
|
||||||
'As of facebook/hhvm#3432, HHVM has no PDORow, and therefore '
|
|
||||||
. ' no internal final classes that cannot be instantiated'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$className = 'DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset';
|
|
||||||
|
|
||||||
if (\PHP_VERSION_ID >= 50600) {
|
|
||||||
$className = 'PDORow';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
|
|
||||||
$className = 'DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setExpectedException('Doctrine\\Instantiator\\Exception\\UnexpectedValueException');
|
|
||||||
|
|
||||||
$this->instantiator->instantiate($className);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNoticeOnUnSerializationException()
|
|
||||||
{
|
|
||||||
if (\PHP_VERSION_ID >= 50600) {
|
|
||||||
$this->markTestSkipped(
|
|
||||||
'PHP 5.6 supports `ReflectionClass#newInstanceWithoutConstructor()` for some internal classes'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
|
|
||||||
|
|
||||||
$this->fail('No exception was raised');
|
|
||||||
} catch (UnexpectedValueException $exception) {
|
|
||||||
$wakeUpNoticesReflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
|
|
||||||
$previous = $exception->getPrevious();
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Exception', $previous);
|
|
||||||
|
|
||||||
// in PHP 5.4.29 and PHP 5.5.13, this case is not a notice, but an exception being thrown
|
|
||||||
if (! (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513)) {
|
|
||||||
$this->assertSame(
|
|
||||||
'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\WakeUpNoticesAsset" '
|
|
||||||
. 'via un-serialization, since an error was triggered in file "'
|
|
||||||
. $wakeUpNoticesReflection->getFileName() . '" at line "36"',
|
|
||||||
$exception->getMessage()
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertSame('Something went bananas while un-serializing this instance', $previous->getMessage());
|
|
||||||
$this->assertSame(\E_USER_NOTICE, $previous->getCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $invalidClassName
|
|
||||||
*
|
|
||||||
* @dataProvider getInvalidClassNames
|
|
||||||
*/
|
|
||||||
public function testInstantiationFromNonExistingClass($invalidClassName)
|
|
||||||
{
|
|
||||||
$this->setExpectedException('Doctrine\\Instantiator\\Exception\\InvalidArgumentException');
|
|
||||||
|
|
||||||
$this->instantiator->instantiate($invalidClassName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testInstancesAreNotCloned()
|
|
||||||
{
|
|
||||||
$className = 'TemporaryClass' . uniqid();
|
|
||||||
|
|
||||||
eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}');
|
|
||||||
|
|
||||||
$instance = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
|
|
||||||
|
|
||||||
$instance->foo = 'bar';
|
|
||||||
|
|
||||||
$instance2 = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
|
|
||||||
|
|
||||||
$this->assertObjectNotHasAttribute('foo', $instance2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a list of instantiable classes (existing)
|
|
||||||
*
|
|
||||||
* @return string[][]
|
|
||||||
*/
|
|
||||||
public function getInstantiableClasses()
|
|
||||||
{
|
|
||||||
$classes = array(
|
|
||||||
array('stdClass'),
|
|
||||||
array(__CLASS__),
|
|
||||||
array('Doctrine\\Instantiator\\Instantiator'),
|
|
||||||
array('PharException'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\PharExceptionAsset'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\XMLReaderAsset'),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
|
|
||||||
return $classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
$classes = array_merge(
|
|
||||||
$classes,
|
|
||||||
array(
|
|
||||||
array('PharException'),
|
|
||||||
array('ArrayObject'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\ArrayObjectAsset'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (\PHP_VERSION_ID >= 50600) {
|
|
||||||
$classes[] = array('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
|
|
||||||
$classes[] = array('DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a list of instantiable classes (existing)
|
|
||||||
*
|
|
||||||
* @return string[][]
|
|
||||||
*/
|
|
||||||
public function getInvalidClassNames()
|
|
||||||
{
|
|
||||||
$classNames = array(
|
|
||||||
array(__CLASS__ . uniqid()),
|
|
||||||
array('Doctrine\\Instantiator\\InstantiatorInterface'),
|
|
||||||
array('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (\PHP_VERSION_ID >= 50400) {
|
|
||||||
$classNames[] = array('DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $classNames;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple asset for an abstract class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
abstract class AbstractClassAsset
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use ArrayObject;
|
|
||||||
use BadMethodCallException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test asset that extends an internal PHP class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class ArrayObjectAsset extends ArrayObject
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
|
||||||
use Phar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test asset that extends an internal PHP class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class PharAsset extends Phar
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
|
||||||
use PharException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test asset that extends an internal PHP class
|
|
||||||
* This class should be serializable without problems
|
|
||||||
* and without getting the "Erroneous data format for unserializing"
|
|
||||||
* error
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class PharExceptionAsset extends PharException
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use ArrayObject;
|
|
||||||
use BadMethodCallException;
|
|
||||||
use Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializable test asset that also extends an internal class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class SerializableArrayObjectAsset extends ArrayObject implements Serializable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function serialize()
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* Should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function unserialize($serialized)
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
|
||||||
use Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base serializable test asset
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class SimpleSerializableAsset implements Serializable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function serialize()
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* Should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function unserialize($serialized)
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple trait with no attached logic
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
trait SimpleTraitAsset
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base un-cloneable asset
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class UnCloneableAsset
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Magic `__clone` - should not be invoked
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __clone()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use ArrayObject;
|
|
||||||
use BadMethodCallException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple asset for an abstract class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class UnserializeExceptionArrayObjectAsset extends ArrayObject
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public function __wakeup()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use ArrayObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple asset for an abstract class
|
|
||||||
*
|
|
||||||
* @author Marco Pivetta <ocramius@gmail.com>
|
|
||||||
*/
|
|
||||||
class WakeUpNoticesAsset extends ArrayObject
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Wakeup method called after un-serialization
|
|
||||||
*/
|
|
||||||
public function __wakeup()
|
|
||||||
{
|
|
||||||
trigger_error('Something went bananas while un-serializing this instance');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This software consists of voluntary contributions made by many individuals
|
|
||||||
* and is licensed under the MIT license. For more information, see
|
|
||||||
* <http://www.doctrine-project.org>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DoctrineTest\InstantiatorTestAsset;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
|
||||||
use XMLReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test asset that extends an internal PHP class
|
|
||||||
*
|
|
||||||
* @author Dave Marshall <dave@atst.io>
|
|
||||||
*/
|
|
||||||
class XMLReaderAsset extends XMLReader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor - should not be called
|
|
||||||
*
|
|
||||||
* @throws BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('Not supposed to be called!');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
# Ingore common cruft
|
|
||||||
.DS_STORE
|
|
||||||
coverage
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# Ignore binary files
|
|
||||||
guzzle.phar
|
|
||||||
guzzle-min.phar
|
|
||||||
|
|
||||||
# Ignore potentially sensitive phpunit file
|
|
||||||
phpunit.xml
|
|
||||||
|
|
||||||
# Ignore composer generated files
|
|
||||||
composer.phar
|
|
||||||
composer.lock
|
|
||||||
composer-test.lock
|
|
||||||
vendor/
|
|
||||||
|
|
||||||
# Ignore build files
|
|
||||||
build/
|
|
||||||
phing/build.properties
|
|
||||||
|
|
||||||
# Ignore subsplit working directory
|
|
||||||
.subsplit
|
|
||||||
|
|
||||||
docs/_build
|
|
||||||
docs/*.pyc
|
|
@ -1,17 +0,0 @@
|
|||||||
language: php
|
|
||||||
|
|
||||||
php:
|
|
||||||
- 5.3
|
|
||||||
- 5.4
|
|
||||||
- 5.5
|
|
||||||
- 5.6
|
|
||||||
- hhvm
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- curl --version
|
|
||||||
- pecl install uri_template-beta || echo "pecl uri_template not available"
|
|
||||||
- composer self-update
|
|
||||||
- composer install --no-interaction --prefer-source --dev
|
|
||||||
- ~/.nvm/nvm.sh install v0.6.14
|
|
||||||
|
|
||||||
script: composer test
|
|
@ -1,751 +0,0 @@
|
|||||||
# CHANGELOG
|
|
||||||
|
|
||||||
## 3.9.3 - 2015-03-18
|
|
||||||
|
|
||||||
* Ensuring Content-Length is not stripped from a request when it is `0`.
|
|
||||||
* Added more information to stream wrapper exceptions.
|
|
||||||
* Message parser will no longer throw warnings for malformed messages.
|
|
||||||
* Giving a valid cache TTL when max-age is 0.
|
|
||||||
|
|
||||||
## 3.9.2 - 2014-09-10
|
|
||||||
|
|
||||||
* Retrying "Connection died, retrying a fresh connect" curl errors.
|
|
||||||
* Automatically extracting the cacert from the phar in client constructor.
|
|
||||||
* Added EntityBody support for OPTIONS requests.
|
|
||||||
|
|
||||||
## 3.9.1 - 2014-05-07
|
|
||||||
|
|
||||||
* Added a fix to ReadLimitEntityBody to ensure it doesn't infinitely loop.
|
|
||||||
* Added a fix to the stream checksum function so that when the first read
|
|
||||||
returns a falsey value, it still continues to consume the stream until EOF.
|
|
||||||
|
|
||||||
## 3.9.0 - 2014-04-23
|
|
||||||
|
|
||||||
* `null`, `false`, and `"_guzzle_blank_"` all now serialize as an empty value
|
|
||||||
with no trailing "=". See dc1d824277.
|
|
||||||
* No longer performing an MD5 check on the cacert each time the phar is used,
|
|
||||||
but rather copying the cacert to the temp directory.
|
|
||||||
* `"0"` can now be added as a URL path
|
|
||||||
* Deleting cookies that are set to empty
|
|
||||||
* If-Modified-Since is no longer unnecessarily added to the CachePlugin
|
|
||||||
* Cookie path matching now follows RFC 6265 s5.1.4
|
|
||||||
* Updated service descriptions are now added to a service client's composite
|
|
||||||
factory.
|
|
||||||
* MockPlugin now throws an exception if the queue is empty.
|
|
||||||
* Properly parsing URLs that start with "http" but are not absolute
|
|
||||||
* Added the ability to configure the curl_multi_select timeout setting
|
|
||||||
* OAuth parameters are now sorted using lexicographical byte value ordering
|
|
||||||
* Fixing invalid usage of an out of range PHP feature in the ErrorResponsePlugin
|
|
||||||
|
|
||||||
## 3.8.1 -2014-01-28
|
|
||||||
|
|
||||||
* Bug: Always using GET requests when redirecting from a 303 response
|
|
||||||
* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
|
|
||||||
`Guzzle\Http\ClientInterface::setSslVerification()`
|
|
||||||
* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
|
|
||||||
* Bug: The body of a request can now be set to `"0"`
|
|
||||||
* Sending PHP stream requests no longer forces `HTTP/1.0`
|
|
||||||
* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
|
|
||||||
each sub-exception
|
|
||||||
* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
|
|
||||||
clobbering everything).
|
|
||||||
* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
|
|
||||||
* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
|
|
||||||
For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
|
|
||||||
* Now properly escaping the regular expression delimiter when matching Cookie domains.
|
|
||||||
* Network access is now disabled when loading XML documents
|
|
||||||
|
|
||||||
## 3.8.0 - 2013-12-05
|
|
||||||
|
|
||||||
* Added the ability to define a POST name for a file
|
|
||||||
* JSON response parsing now properly walks additionalProperties
|
|
||||||
* cURL error code 18 is now retried automatically in the BackoffPlugin
|
|
||||||
* Fixed a cURL error when URLs contain fragments
|
|
||||||
* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
|
|
||||||
CurlExceptions
|
|
||||||
* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
|
|
||||||
* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
|
|
||||||
* Fixed a bug that was encountered when parsing empty header parameters
|
|
||||||
* UriTemplate now has a `setRegex()` method to match the docs
|
|
||||||
* The `debug` request parameter now checks if it is truthy rather than if it exists
|
|
||||||
* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
|
|
||||||
* Added the ability to combine URLs using strict RFC 3986 compliance
|
|
||||||
* Command objects can now return the validation errors encountered by the command
|
|
||||||
* Various fixes to cache revalidation (#437 and 29797e5)
|
|
||||||
* Various fixes to the AsyncPlugin
|
|
||||||
* Cleaned up build scripts
|
|
||||||
|
|
||||||
## 3.7.4 - 2013-10-02
|
|
||||||
|
|
||||||
* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
|
|
||||||
* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
|
|
||||||
(see https://github.com/aws/aws-sdk-php/issues/147)
|
|
||||||
* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
|
|
||||||
* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
|
|
||||||
* Updated the bundled cacert.pem (#419)
|
|
||||||
* OauthPlugin now supports adding authentication to headers or query string (#425)
|
|
||||||
|
|
||||||
## 3.7.3 - 2013-09-08
|
|
||||||
|
|
||||||
* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
|
|
||||||
`CommandTransferException`.
|
|
||||||
* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
|
|
||||||
* Schemas are only injected into response models when explicitly configured.
|
|
||||||
* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
|
|
||||||
an EntityBody.
|
|
||||||
* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
|
|
||||||
* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
|
|
||||||
* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
|
|
||||||
* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
|
|
||||||
* Bug fix: Visiting XML attributes first before visting XML children when serializing requests
|
|
||||||
* Bug fix: Properly parsing headers that contain commas contained in quotes
|
|
||||||
* Bug fix: mimetype guessing based on a filename is now case-insensitive
|
|
||||||
|
|
||||||
## 3.7.2 - 2013-08-02
|
|
||||||
|
|
||||||
* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
|
|
||||||
See https://github.com/guzzle/guzzle/issues/371
|
|
||||||
* Bug fix: Cookie domains are now matched correctly according to RFC 6265
|
|
||||||
See https://github.com/guzzle/guzzle/issues/377
|
|
||||||
* Bug fix: GET parameters are now used when calculating an OAuth signature
|
|
||||||
* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
|
|
||||||
* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
|
|
||||||
* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
|
|
||||||
See https://github.com/guzzle/guzzle/issues/379
|
|
||||||
* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
|
|
||||||
https://github.com/guzzle/guzzle/pull/380
|
|
||||||
* cURL multi cleanup and optimizations
|
|
||||||
|
|
||||||
## 3.7.1 - 2013-07-05
|
|
||||||
|
|
||||||
* Bug fix: Setting default options on a client now works
|
|
||||||
* Bug fix: Setting options on HEAD requests now works. See #352
|
|
||||||
* Bug fix: Moving stream factory before send event to before building the stream. See #353
|
|
||||||
* Bug fix: Cookies no longer match on IP addresses per RFC 6265
|
|
||||||
* Bug fix: Correctly parsing header parameters that are in `<>` and quotes
|
|
||||||
* Added `cert` and `ssl_key` as request options
|
|
||||||
* `Host` header can now diverge from the host part of a URL if the header is set manually
|
|
||||||
* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
|
|
||||||
* OAuth parameters are only added via the plugin if they aren't already set
|
|
||||||
* Exceptions are now thrown when a URL cannot be parsed
|
|
||||||
* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
|
|
||||||
* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
|
|
||||||
|
|
||||||
## 3.7.0 - 2013-06-10
|
|
||||||
|
|
||||||
* See UPGRADING.md for more information on how to upgrade.
|
|
||||||
* Requests now support the ability to specify an array of $options when creating a request to more easily modify a
|
|
||||||
request. You can pass a 'request.options' configuration setting to a client to apply default request options to
|
|
||||||
every request created by a client (e.g. default query string variables, headers, curl options, etc).
|
|
||||||
* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
|
|
||||||
See `Guzzle\Http\StaticClient::mount`.
|
|
||||||
* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
|
|
||||||
created by a command (e.g. custom headers, query string variables, timeout settings, etc).
|
|
||||||
* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
|
|
||||||
headers of a response
|
|
||||||
* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
|
|
||||||
(e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
|
|
||||||
* ServiceBuilders now support storing and retrieving arbitrary data
|
|
||||||
* CachePlugin can now purge all resources for a given URI
|
|
||||||
* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
|
|
||||||
* CachePlugin now uses the Vary header to determine if a resource is a cache hit
|
|
||||||
* `Guzzle\Http\Message\Response` now implements `\Serializable`
|
|
||||||
* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
|
|
||||||
* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
|
|
||||||
* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
|
|
||||||
* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
|
|
||||||
* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
|
|
||||||
* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
|
|
||||||
Symfony users can still use the old version of Monolog.
|
|
||||||
* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
|
|
||||||
Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
|
|
||||||
* Several performance improvements to `Guzzle\Common\Collection`
|
|
||||||
* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
|
|
||||||
createRequest, head, delete, put, patch, post, options, prepareRequest
|
|
||||||
* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
|
|
||||||
* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
|
|
||||||
* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
|
|
||||||
`Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
|
|
||||||
resource, string, or EntityBody into the $options parameter to specify the download location of the response.
|
|
||||||
* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
|
|
||||||
default `array()`
|
|
||||||
* Added `Guzzle\Stream\StreamInterface::isRepeatable`
|
|
||||||
* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
|
|
||||||
$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
|
|
||||||
$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
|
|
||||||
* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
|
|
||||||
* Removed `Guzzle\Http\ClientInterface::expandTemplate()`
|
|
||||||
* Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
|
|
||||||
* Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
|
|
||||||
* Removed `Guzzle\Http\Message\RequestInterface::canCache`
|
|
||||||
* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
|
|
||||||
* Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
|
|
||||||
* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
|
|
||||||
* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
|
|
||||||
`Guzzle\Common\Version::$emitWarnings` to true.
|
|
||||||
* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
|
|
||||||
`$request->getResponseBody()->isRepeatable()` instead.
|
|
||||||
* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
|
|
||||||
`Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
||||||
* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
|
|
||||||
`Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
||||||
* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
||||||
* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
||||||
* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
|
|
||||||
* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
|
|
||||||
These will work through Guzzle 4.0
|
|
||||||
* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
|
|
||||||
* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
|
|
||||||
* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
|
|
||||||
* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
|
|
||||||
* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
|
|
||||||
* Marked `Guzzle\Common\Collection::inject()` as deprecated.
|
|
||||||
* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
|
|
||||||
* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
|
|
||||||
CacheStorageInterface. These two objects and interface will be removed in a future version.
|
|
||||||
* Always setting X-cache headers on cached responses
|
|
||||||
* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
|
|
||||||
* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
|
|
||||||
$request, Response $response);`
|
|
||||||
* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
|
|
||||||
* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
|
|
||||||
* Added `CacheStorageInterface::purge($url)`
|
|
||||||
* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
|
|
||||||
$plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
|
|
||||||
CanCacheStrategyInterface $canCache = null)`
|
|
||||||
* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
|
|
||||||
|
|
||||||
## 3.6.0 - 2013-05-29
|
|
||||||
|
|
||||||
* ServiceDescription now implements ToArrayInterface
|
|
||||||
* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
|
|
||||||
* Guzzle can now correctly parse incomplete URLs
|
|
||||||
* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
|
|
||||||
* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
|
|
||||||
* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
|
|
||||||
* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
|
|
||||||
HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
|
|
||||||
CacheControl header implementation.
|
|
||||||
* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
|
|
||||||
* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
|
|
||||||
* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
|
|
||||||
Guzzle\Http\Curl\RequestMediator
|
|
||||||
* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
|
|
||||||
* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
|
|
||||||
* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
|
|
||||||
* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
|
||||||
* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
|
||||||
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
|
||||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
|
||||||
directly via interfaces
|
|
||||||
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
|
||||||
but are a no-op until removed.
|
|
||||||
* Most classes that used to require a ``Guzzle\Service\Command\CommandInterface` typehint now request a
|
|
||||||
`Guzzle\Service\Command\ArrayCommandInterface`.
|
|
||||||
* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
|
|
||||||
on a request while the request is still being transferred
|
|
||||||
* The ability to case-insensitively search for header values
|
|
||||||
* Guzzle\Http\Message\Header::hasExactHeader
|
|
||||||
* Guzzle\Http\Message\Header::raw. Use getAll()
|
|
||||||
* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
|
|
||||||
instead.
|
|
||||||
* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
|
|
||||||
* Added the ability to cast Model objects to a string to view debug information.
|
|
||||||
|
|
||||||
## 3.5.0 - 2013-05-13
|
|
||||||
|
|
||||||
* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
|
|
||||||
* Bug: Better cleanup of one-time events accross the board (when an event is meant to fire once, it will now remove
|
|
||||||
itself from the EventDispatcher)
|
|
||||||
* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
|
|
||||||
* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
|
|
||||||
* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
|
|
||||||
non-existent key
|
|
||||||
* Bug: All __call() method arguments are now required (helps with mocking frameworks)
|
|
||||||
* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
|
|
||||||
to help with refcount based garbage collection of resources created by sending a request
|
|
||||||
* Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
|
|
||||||
* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it'sdeprecated). Use the
|
|
||||||
HistoryPlugin for a history.
|
|
||||||
* Added a `responseBody` alias for the `response_body` location
|
|
||||||
* Refactored internals to no longer rely on Response::getRequest()
|
|
||||||
* HistoryPlugin can now be cast to a string
|
|
||||||
* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
|
|
||||||
and responses that are sent over the wire
|
|
||||||
* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
|
|
||||||
|
|
||||||
## 3.4.3 - 2013-04-30
|
|
||||||
|
|
||||||
* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
|
|
||||||
* Added a check to re-extract the temp cacert bundle from the phar before sending each request
|
|
||||||
|
|
||||||
## 3.4.2 - 2013-04-29
|
|
||||||
|
|
||||||
* Bug fix: Stream objects now work correctly with "a" and "a+" modes
|
|
||||||
* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
|
|
||||||
* Bug fix: AsyncPlugin no longer forces HEAD requests
|
|
||||||
* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
|
|
||||||
* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
|
|
||||||
* Setting a response on a request will write to the custom request body from the response body if one is specified
|
|
||||||
* LogPlugin now writes to php://output when STDERR is undefined
|
|
||||||
* Added the ability to set multiple POST files for the same key in a single call
|
|
||||||
* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
|
|
||||||
* Added the ability to queue CurlExceptions to the MockPlugin
|
|
||||||
* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
|
|
||||||
* Configuration loading now allows remote files
|
|
||||||
|
|
||||||
## 3.4.1 - 2013-04-16
|
|
||||||
|
|
||||||
* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
|
|
||||||
handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
|
|
||||||
* Exceptions are now properly grouped when sending requests in parallel
|
|
||||||
* Redirects are now properly aggregated when a multi transaction fails
|
|
||||||
* Redirects now set the response on the original object even in the event of a failure
|
|
||||||
* Bug fix: Model names are now properly set even when using $refs
|
|
||||||
* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
|
|
||||||
* Added support for oauth_callback in OAuth signatures
|
|
||||||
* Added support for oauth_verifier in OAuth signatures
|
|
||||||
* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
|
|
||||||
|
|
||||||
## 3.4.0 - 2013-04-11
|
|
||||||
|
|
||||||
* Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
|
|
||||||
* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
|
|
||||||
* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
|
|
||||||
* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
|
|
||||||
* Bug fix: Added `number` type to service descriptions.
|
|
||||||
* Bug fix: empty parameters are removed from an OAuth signature
|
|
||||||
* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
|
|
||||||
* Bug fix: Fixed "array to string" error when validating a union of types in a service description
|
|
||||||
* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
|
|
||||||
* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
|
|
||||||
* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
|
|
||||||
* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
|
|
||||||
* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
|
|
||||||
the Content-Type can be determined based on the entity body or the path of the request.
|
|
||||||
* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
|
|
||||||
* Added support for a PSR-3 LogAdapter.
|
|
||||||
* Added a `command.after_prepare` event
|
|
||||||
* Added `oauth_callback` parameter to the OauthPlugin
|
|
||||||
* Added the ability to create a custom stream class when using a stream factory
|
|
||||||
* Added a CachingEntityBody decorator
|
|
||||||
* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
|
|
||||||
* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
|
|
||||||
* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
|
|
||||||
* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
|
|
||||||
means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
|
|
||||||
POST fields or files (the latter is only used when emulating a form POST in the browser).
|
|
||||||
* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
|
|
||||||
|
|
||||||
## 3.3.1 - 2013-03-10
|
|
||||||
|
|
||||||
* Added the ability to create PHP streaming responses from HTTP requests
|
|
||||||
* Bug fix: Running any filters when parsing response headers with service descriptions
|
|
||||||
* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
|
|
||||||
* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
|
|
||||||
response location visitors.
|
|
||||||
* Bug fix: Removed the possibility of creating configuration files with circular dependencies
|
|
||||||
* RequestFactory::create() now uses the key of a POST file when setting the POST file name
|
|
||||||
* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
|
|
||||||
|
|
||||||
## 3.3.0 - 2013-03-03
|
|
||||||
|
|
||||||
* A large number of performance optimizations have been made
|
|
||||||
* Bug fix: Added 'wb' as a valid write mode for streams
|
|
||||||
* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
|
|
||||||
* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
|
|
||||||
* BC: Removed `Guzzle\Http\Utils` class
|
|
||||||
* BC: Setting a service description on a client will no longer modify the client's command factories.
|
|
||||||
* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
|
|
||||||
the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
|
|
||||||
* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
|
|
||||||
lowercase
|
|
||||||
* Operation parameter objects are now lazy loaded internally
|
|
||||||
* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
|
|
||||||
* Added support for instantiating responseType=class responseClass classes. Classes must implement
|
|
||||||
`Guzzle\Service\Command\ResponseClassInterface`
|
|
||||||
* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
|
|
||||||
additional properties also support locations and can be used to parse JSON responses where the outermost part of the
|
|
||||||
JSON is an array
|
|
||||||
* Added support for nested renaming of JSON models (rename sentAs to name)
|
|
||||||
* CachePlugin
|
|
||||||
* Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
|
|
||||||
* Debug headers can now added to cached response in the CachePlugin
|
|
||||||
|
|
||||||
## 3.2.0 - 2013-02-14
|
|
||||||
|
|
||||||
* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
|
|
||||||
* URLs with no path no longer contain a "/" by default
|
|
||||||
* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
|
|
||||||
* BadResponseException no longer includes the full request and response message
|
|
||||||
* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
|
|
||||||
* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
|
|
||||||
* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
|
|
||||||
* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
|
|
||||||
* xmlEncoding can now be customized for the XML declaration of a XML service description operation
|
|
||||||
* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
|
|
||||||
aggregation and no longer uses callbacks
|
|
||||||
* The URL encoding implementation of Guzzle\Http\QueryString can now be customized
|
|
||||||
* Bug fix: Filters were not always invoked for array service description parameters
|
|
||||||
* Bug fix: Redirects now use a target response body rather than a temporary response body
|
|
||||||
* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
|
|
||||||
* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
|
|
||||||
|
|
||||||
## 3.1.2 - 2013-01-27
|
|
||||||
|
|
||||||
* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
|
|
||||||
response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
|
|
||||||
* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
|
|
||||||
* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
|
|
||||||
* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
|
|
||||||
* Setting default headers on a client after setting the user-agent will not erase the user-agent setting
|
|
||||||
|
|
||||||
## 3.1.1 - 2013-01-20
|
|
||||||
|
|
||||||
* Adding wildcard support to Guzzle\Common\Collection::getPath()
|
|
||||||
* Adding alias support to ServiceBuilder configs
|
|
||||||
* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
|
|
||||||
|
|
||||||
## 3.1.0 - 2013-01-12
|
|
||||||
|
|
||||||
* BC: CurlException now extends from RequestException rather than BadResponseException
|
|
||||||
* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
|
|
||||||
* Added getData to ServiceDescriptionInterface
|
|
||||||
* Added context array to RequestInterface::setState()
|
|
||||||
* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
|
|
||||||
* Bug: Adding required content-type when JSON request visitor adds JSON to a command
|
|
||||||
* Bug: Fixing the serialization of a service description with custom data
|
|
||||||
* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
|
|
||||||
an array of successful and failed responses
|
|
||||||
* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
|
|
||||||
* Added Guzzle\Http\IoEmittingEntityBody
|
|
||||||
* Moved command filtration from validators to location visitors
|
|
||||||
* Added `extends` attributes to service description parameters
|
|
||||||
* Added getModels to ServiceDescriptionInterface
|
|
||||||
|
|
||||||
## 3.0.7 - 2012-12-19
|
|
||||||
|
|
||||||
* Fixing phar detection when forcing a cacert to system if null or true
|
|
||||||
* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
|
|
||||||
* Cleaning up `Guzzle\Common\Collection::inject` method
|
|
||||||
* Adding a response_body location to service descriptions
|
|
||||||
|
|
||||||
## 3.0.6 - 2012-12-09
|
|
||||||
|
|
||||||
* CurlMulti performance improvements
|
|
||||||
* Adding setErrorResponses() to Operation
|
|
||||||
* composer.json tweaks
|
|
||||||
|
|
||||||
## 3.0.5 - 2012-11-18
|
|
||||||
|
|
||||||
* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
|
|
||||||
* Bug: Response body can now be a string containing "0"
|
|
||||||
* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
|
|
||||||
* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
|
|
||||||
* Added support for XML attributes in service description responses
|
|
||||||
* DefaultRequestSerializer now supports array URI parameter values for URI template expansion
|
|
||||||
* Added better mimetype guessing to requests and post files
|
|
||||||
|
|
||||||
## 3.0.4 - 2012-11-11
|
|
||||||
|
|
||||||
* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
|
|
||||||
* Bug: Cookies can now be added that have a name, domain, or value set to "0"
|
|
||||||
* Bug: Using the system cacert bundle when using the Phar
|
|
||||||
* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
|
|
||||||
* Enhanced cookie jar de-duplication
|
|
||||||
* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
|
|
||||||
* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
|
|
||||||
* Added the ability to create any sort of hash for a stream rather than just an MD5 hash
|
|
||||||
|
|
||||||
## 3.0.3 - 2012-11-04
|
|
||||||
|
|
||||||
* Implementing redirects in PHP rather than cURL
|
|
||||||
* Added PECL URI template extension and using as default parser if available
|
|
||||||
* Bug: Fixed Content-Length parsing of Response factory
|
|
||||||
* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
|
|
||||||
* Adding ToArrayInterface throughout library
|
|
||||||
* Fixing OauthPlugin to create unique nonce values per request
|
|
||||||
|
|
||||||
## 3.0.2 - 2012-10-25
|
|
||||||
|
|
||||||
* Magic methods are enabled by default on clients
|
|
||||||
* Magic methods return the result of a command
|
|
||||||
* Service clients no longer require a base_url option in the factory
|
|
||||||
* Bug: Fixed an issue with URI templates where null template variables were being expanded
|
|
||||||
|
|
||||||
## 3.0.1 - 2012-10-22
|
|
||||||
|
|
||||||
* Models can now be used like regular collection objects by calling filter, map, etc
|
|
||||||
* Models no longer require a Parameter structure or initial data in the constructor
|
|
||||||
* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
|
|
||||||
|
|
||||||
## 3.0.0 - 2012-10-15
|
|
||||||
|
|
||||||
* Rewrote service description format to be based on Swagger
|
|
||||||
* Now based on JSON schema
|
|
||||||
* Added nested input structures and nested response models
|
|
||||||
* Support for JSON and XML input and output models
|
|
||||||
* Renamed `commands` to `operations`
|
|
||||||
* Removed dot class notation
|
|
||||||
* Removed custom types
|
|
||||||
* Broke the project into smaller top-level namespaces to be more component friendly
|
|
||||||
* Removed support for XML configs and descriptions. Use arrays or JSON files.
|
|
||||||
* Removed the Validation component and Inspector
|
|
||||||
* Moved all cookie code to Guzzle\Plugin\Cookie
|
|
||||||
* Magic methods on a Guzzle\Service\Client now return the command un-executed.
|
|
||||||
* Calling getResult() or getResponse() on a command will lazily execute the command if needed.
|
|
||||||
* Now shipping with cURL's CA certs and using it by default
|
|
||||||
* Added previousResponse() method to response objects
|
|
||||||
* No longer sending Accept and Accept-Encoding headers on every request
|
|
||||||
* Only sending an Expect header by default when a payload is greater than 1MB
|
|
||||||
* Added/moved client options:
|
|
||||||
* curl.blacklist to curl.option.blacklist
|
|
||||||
* Added ssl.certificate_authority
|
|
||||||
* Added a Guzzle\Iterator component
|
|
||||||
* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
|
|
||||||
* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
|
|
||||||
* Added a more robust caching plugin
|
|
||||||
* Added setBody to response objects
|
|
||||||
* Updating LogPlugin to use a more flexible MessageFormatter
|
|
||||||
* Added a completely revamped build process
|
|
||||||
* Cleaning up Collection class and removing default values from the get method
|
|
||||||
* Fixed ZF2 cache adapters
|
|
||||||
|
|
||||||
## 2.8.8 - 2012-10-15
|
|
||||||
|
|
||||||
* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
|
|
||||||
|
|
||||||
## 2.8.7 - 2012-09-30
|
|
||||||
|
|
||||||
* Bug: Fixed config file aliases for JSON includes
|
|
||||||
* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
|
|
||||||
* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
|
|
||||||
* Bug: Hardening request and response parsing to account for missing parts
|
|
||||||
* Bug: Fixed PEAR packaging
|
|
||||||
* Bug: Fixed Request::getInfo
|
|
||||||
* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
|
|
||||||
* Adding the ability for the namespace Iterator factory to look in multiple directories
|
|
||||||
* Added more getters/setters/removers from service descriptions
|
|
||||||
* Added the ability to remove POST fields from OAuth signatures
|
|
||||||
* OAuth plugin now supports 2-legged OAuth
|
|
||||||
|
|
||||||
## 2.8.6 - 2012-09-05
|
|
||||||
|
|
||||||
* Added the ability to modify and build service descriptions
|
|
||||||
* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
|
|
||||||
* Added a `json` parameter location
|
|
||||||
* Now allowing dot notation for classes in the CacheAdapterFactory
|
|
||||||
* Using the union of two arrays rather than an array_merge when extending service builder services and service params
|
|
||||||
* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
|
|
||||||
in service builder config files.
|
|
||||||
* Services defined in two different config files that include one another will by default replace the previously
|
|
||||||
defined service, but you can now create services that extend themselves and merge their settings over the previous
|
|
||||||
* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
|
|
||||||
'_default' with a default JSON configuration file.
|
|
||||||
|
|
||||||
## 2.8.5 - 2012-08-29
|
|
||||||
|
|
||||||
* Bug: Suppressed empty arrays from URI templates
|
|
||||||
* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
|
|
||||||
* Added support for HTTP responses that do not contain a reason phrase in the start-line
|
|
||||||
* AbstractCommand commands are now invokable
|
|
||||||
* Added a way to get the data used when signing an Oauth request before a request is sent
|
|
||||||
|
|
||||||
## 2.8.4 - 2012-08-15
|
|
||||||
|
|
||||||
* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
|
|
||||||
* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
|
|
||||||
* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
|
|
||||||
* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
|
|
||||||
* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
|
|
||||||
* Added additional response status codes
|
|
||||||
* Removed SSL information from the default User-Agent header
|
|
||||||
* DELETE requests can now send an entity body
|
|
||||||
* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
|
|
||||||
* Added the ability of the MockPlugin to consume mocked request bodies
|
|
||||||
* LogPlugin now exposes request and response objects in the extras array
|
|
||||||
|
|
||||||
## 2.8.3 - 2012-07-30
|
|
||||||
|
|
||||||
* Bug: Fixed a case where empty POST requests were sent as GET requests
|
|
||||||
* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
|
|
||||||
* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
|
|
||||||
* Added multiple inheritance to service description commands
|
|
||||||
* Added an ApiCommandInterface and added ``getParamNames()`` and ``hasParam()``
|
|
||||||
* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
|
|
||||||
* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
|
|
||||||
|
|
||||||
## 2.8.2 - 2012-07-24
|
|
||||||
|
|
||||||
* Bug: Query string values set to 0 are no longer dropped from the query string
|
|
||||||
* Bug: A Collection object is no longer created each time a call is made to ``Guzzle\Service\Command\AbstractCommand::getRequestHeaders()``
|
|
||||||
* Bug: ``+`` is now treated as an encoded space when parsing query strings
|
|
||||||
* QueryString and Collection performance improvements
|
|
||||||
* Allowing dot notation for class paths in filters attribute of a service descriptions
|
|
||||||
|
|
||||||
## 2.8.1 - 2012-07-16
|
|
||||||
|
|
||||||
* Loosening Event Dispatcher dependency
|
|
||||||
* POST redirects can now be customized using CURLOPT_POSTREDIR
|
|
||||||
|
|
||||||
## 2.8.0 - 2012-07-15
|
|
||||||
|
|
||||||
* BC: Guzzle\Http\Query
|
|
||||||
* Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
|
|
||||||
* Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
|
|
||||||
* Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
|
|
||||||
* Changed the aggregation functions of QueryString to be static methods
|
|
||||||
* Can now use fromString() with querystrings that have a leading ?
|
|
||||||
* cURL configuration values can be specified in service descriptions using ``curl.`` prefixed parameters
|
|
||||||
* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
|
|
||||||
* Cookies are no longer URL decoded by default
|
|
||||||
* Bug: URI template variables set to null are no longer expanded
|
|
||||||
|
|
||||||
## 2.7.2 - 2012-07-02
|
|
||||||
|
|
||||||
* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
|
|
||||||
* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
|
|
||||||
* CachePlugin now allows for a custom request parameter function to check if a request can be cached
|
|
||||||
* Bug fix: CachePlugin now only caches GET and HEAD requests by default
|
|
||||||
* Bug fix: Using header glue when transferring headers over the wire
|
|
||||||
* Allowing deeply nested arrays for composite variables in URI templates
|
|
||||||
* Batch divisors can now return iterators or arrays
|
|
||||||
|
|
||||||
## 2.7.1 - 2012-06-26
|
|
||||||
|
|
||||||
* Minor patch to update version number in UA string
|
|
||||||
* Updating build process
|
|
||||||
|
|
||||||
## 2.7.0 - 2012-06-25
|
|
||||||
|
|
||||||
* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
|
|
||||||
* BC: Removed magic setX methods from commands
|
|
||||||
* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
|
|
||||||
* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
|
|
||||||
* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
|
|
||||||
* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
|
|
||||||
* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
|
|
||||||
* Added the ability to set POST fields and files in a service description
|
|
||||||
* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
|
|
||||||
* Adding a command.before_prepare event to clients
|
|
||||||
* Added BatchClosureTransfer and BatchClosureDivisor
|
|
||||||
* BatchTransferException now includes references to the batch divisor and transfer strategies
|
|
||||||
* Fixed some tests so that they pass more reliably
|
|
||||||
* Added Guzzle\Common\Log\ArrayLogAdapter
|
|
||||||
|
|
||||||
## 2.6.6 - 2012-06-10
|
|
||||||
|
|
||||||
* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
|
|
||||||
* BC: Removing Guzzle\Service\Command\CommandSet
|
|
||||||
* Adding generic batching system (replaces the batch queue plugin and command set)
|
|
||||||
* Updating ZF cache and log adapters and now using ZF's composer repository
|
|
||||||
* Bug: Setting the name of each ApiParam when creating through an ApiCommand
|
|
||||||
* Adding result_type, result_doc, deprecated, and doc_url to service descriptions
|
|
||||||
* Bug: Changed the default cookie header casing back to 'Cookie'
|
|
||||||
|
|
||||||
## 2.6.5 - 2012-06-03
|
|
||||||
|
|
||||||
* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
|
|
||||||
* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
|
|
||||||
* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
|
|
||||||
* BC: Renaming methods in the CookieJarInterface
|
|
||||||
* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
|
|
||||||
* Making the default glue for HTTP headers ';' instead of ','
|
|
||||||
* Adding a removeValue to Guzzle\Http\Message\Header
|
|
||||||
* Adding getCookies() to request interface.
|
|
||||||
* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
|
|
||||||
|
|
||||||
## 2.6.4 - 2012-05-30
|
|
||||||
|
|
||||||
* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
|
|
||||||
* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
|
|
||||||
* Bug: Fixing magic method command calls on clients
|
|
||||||
* Bug: Email constraint only validates strings
|
|
||||||
* Bug: Aggregate POST fields when POST files are present in curl handle
|
|
||||||
* Bug: Fixing default User-Agent header
|
|
||||||
* Bug: Only appending or prepending parameters in commands if they are specified
|
|
||||||
* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
|
|
||||||
* Allowing the use of dot notation for class namespaces when using instance_of constraint
|
|
||||||
* Added any_match validation constraint
|
|
||||||
* Added an AsyncPlugin
|
|
||||||
* Passing request object to the calculateWait method of the ExponentialBackoffPlugin
|
|
||||||
* Allowing the result of a command object to be changed
|
|
||||||
* Parsing location and type sub values when instantiating a service description rather than over and over at runtime
|
|
||||||
|
|
||||||
## 2.6.3 - 2012-05-23
|
|
||||||
|
|
||||||
* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
|
|
||||||
* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
|
|
||||||
* You can now use an array of data when creating PUT request bodies in the request factory.
|
|
||||||
* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
|
|
||||||
* [Http] Adding support for Content-Type in multipart POST uploads per upload
|
|
||||||
* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
|
|
||||||
* Adding more POST data operations for easier manipulation of POST data.
|
|
||||||
* You can now set empty POST fields.
|
|
||||||
* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
|
|
||||||
* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
|
|
||||||
* CS updates
|
|
||||||
|
|
||||||
## 2.6.2 - 2012-05-19
|
|
||||||
|
|
||||||
* [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method.
|
|
||||||
|
|
||||||
## 2.6.1 - 2012-05-19
|
|
||||||
|
|
||||||
* [BC] Removing 'path' support in service descriptions. Use 'uri'.
|
|
||||||
* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
|
|
||||||
* [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it.
|
|
||||||
* [BC] Removing Guzzle\Common\XmlElement.
|
|
||||||
* All commands, both dynamic and concrete, have ApiCommand objects.
|
|
||||||
* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
|
|
||||||
* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
|
|
||||||
* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
|
|
||||||
|
|
||||||
## 2.6.0 - 2012-05-15
|
|
||||||
|
|
||||||
* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
|
|
||||||
* [BC] Executing a Command returns the result of the command rather than the command
|
|
||||||
* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
|
|
||||||
* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
|
|
||||||
* [BC] Moving ResourceIterator* to Guzzle\Service\Resource
|
|
||||||
* [BC] Completely refactored ResourceIterators to iterate over a cloned command object
|
|
||||||
* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
|
|
||||||
* [BC] Guzzle\Guzzle is now deprecated
|
|
||||||
* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
|
|
||||||
* Adding Guzzle\Version class to give version information about Guzzle
|
|
||||||
* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
|
|
||||||
* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
|
|
||||||
* ServiceDescription and ServiceBuilder are now cacheable using similar configs
|
|
||||||
* Changing the format of XML and JSON service builder configs. Backwards compatible.
|
|
||||||
* Cleaned up Cookie parsing
|
|
||||||
* Trimming the default Guzzle User-Agent header
|
|
||||||
* Adding a setOnComplete() method to Commands that is called when a command completes
|
|
||||||
* Keeping track of requests that were mocked in the MockPlugin
|
|
||||||
* Fixed a caching bug in the CacheAdapterFactory
|
|
||||||
* Inspector objects can be injected into a Command object
|
|
||||||
* Refactoring a lot of code and tests to be case insensitive when dealing with headers
|
|
||||||
* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
|
|
||||||
* Adding the ability to set global option overrides to service builder configs
|
|
||||||
* Adding the ability to include other service builder config files from within XML and JSON files
|
|
||||||
* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
|
|
||||||
|
|
||||||
## 2.5.0 - 2012-05-08
|
|
||||||
|
|
||||||
* Major performance improvements
|
|
||||||
* [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated.
|
|
||||||
* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
|
|
||||||
* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}"
|
|
||||||
* Added the ability to passed parameters to all requests created by a client
|
|
||||||
* Added callback functionality to the ExponentialBackoffPlugin
|
|
||||||
* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
|
|
||||||
* Rewinding request stream bodies when retrying requests
|
|
||||||
* Exception is thrown when JSON response body cannot be decoded
|
|
||||||
* Added configurable magic method calls to clients and commands. This is off by default.
|
|
||||||
* Fixed a defect that added a hash to every parsed URL part
|
|
||||||
* Fixed duplicate none generation for OauthPlugin.
|
|
||||||
* Emitting an event each time a client is generated by a ServiceBuilder
|
|
||||||
* Using an ApiParams object instead of a Collection for parameters of an ApiCommand
|
|
||||||
* cache.* request parameters should be renamed to params.cache.*
|
|
||||||
* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc). See CurlHandle.
|
|
||||||
* Added the ability to disable type validation of service descriptions
|
|
||||||
* ServiceDescriptions and ServiceBuilders are now Serializable
|
|
@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2011 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
|
|
||||||
|
|
||||||
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.
|
|
@ -1,57 +0,0 @@
|
|||||||
Guzzle, PHP HTTP client and webservice framework
|
|
||||||
================================================
|
|
||||||
|
|
||||||
# This is an old version of Guzzle
|
|
||||||
|
|
||||||
This repository is for Guzzle 3.x. Guzzle 5.x, the new version of Guzzle, has
|
|
||||||
been released and is available at
|
|
||||||
[https://github.com/guzzle/guzzle](https://github.com/guzzle/guzzle). The
|
|
||||||
documentation for Guzzle version 5+ can be found at
|
|
||||||
[http://guzzlephp.org](http://guzzlephp.org).
|
|
||||||
|
|
||||||
Guzzle 3 is only maintained for bug and security fixes. Guzzle 3 will be EOL
|
|
||||||
at some point in late 2015.
|
|
||||||
|
|
||||||
### About Guzzle 3
|
|
||||||
|
|
||||||
[![Composer Downloads](https://poser.pugx.org/guzzle/guzzle/d/total.png)](https://packagist.org/packages/guzzle/guzzle)
|
|
||||||
[![Build Status](https://secure.travis-ci.org/guzzle/guzzle3.png?branch=master)](http://travis-ci.org/guzzle/guzzle3)
|
|
||||||
|
|
||||||
- Extremely powerful API provides all the power of cURL with a simple interface.
|
|
||||||
- Truly take advantage of HTTP/1.1 with persistent connections, connection pooling, and parallel requests.
|
|
||||||
- Service description DSL allows you build awesome web service clients faster.
|
|
||||||
- Symfony2 event-based plugin system allows you to completely modify the behavior of a request.
|
|
||||||
|
|
||||||
Get answers with: [Documentation](http://guzzle3.readthedocs.org/en/latest/), [Forums](https://groups.google.com/forum/?hl=en#!forum/guzzle), IRC ([#guzzlephp](irc://irc.freenode.net/#guzzlephp) @ irc.freenode.net)
|
|
||||||
|
|
||||||
### Installing via Composer
|
|
||||||
|
|
||||||
The recommended way to install Guzzle is through [Composer](http://getcomposer.org).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install Composer
|
|
||||||
curl -sS https://getcomposer.org/installer | php
|
|
||||||
|
|
||||||
# Add Guzzle as a dependency
|
|
||||||
php composer.phar require guzzle/guzzle:~3.9
|
|
||||||
```
|
|
||||||
|
|
||||||
After installing, you need to require Composer's autoloader:
|
|
||||||
|
|
||||||
```php
|
|
||||||
require 'vendor/autoload.php';
|
|
||||||
```
|
|
||||||
## Known Issues
|
|
||||||
|
|
||||||
1. Problem following a specific redirect: https://github.com/guzzle/guzzle/issues/385.
|
|
||||||
This has been fixed in Guzzle 4/5.
|
|
||||||
2. Root XML attributes not serialized in a service description: https://github.com/guzzle/guzzle3/issues/5.
|
|
||||||
This has been fixed in Guzzle 4/5.
|
|
||||||
3. Accept-Encoding not preserved when following redirect: https://github.com/guzzle/guzzle3/issues/9
|
|
||||||
Fixed in Guzzle 4/5.
|
|
||||||
4. String "Array" Transmitted w/ PostFiles and Duplicate Aggregator: https://github.com/guzzle/guzzle3/issues/10
|
|
||||||
Fixed in Guzzle 4/5.
|
|
||||||
5. Recursive model references with array items: https://github.com/guzzle/guzzle3/issues/13
|
|
||||||
Fixed in Guzzle 4/5
|
|
||||||
6. String "Array" Transmitted w/ PostFiles and Duplicate Aggregator: https://github.com/guzzle/guzzle3/issues/10
|
|
||||||
Fixed in Guzzle 4/5.
|
|
@ -1,537 +0,0 @@
|
|||||||
Guzzle Upgrade Guide
|
|
||||||
====================
|
|
||||||
|
|
||||||
3.6 to 3.7
|
|
||||||
----------
|
|
||||||
|
|
||||||
### Deprecations
|
|
||||||
|
|
||||||
- You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
|
|
||||||
|
|
||||||
```php
|
|
||||||
\Guzzle\Common\Version::$emitWarnings = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
The following APIs and options have been marked as deprecated:
|
|
||||||
|
|
||||||
- Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
|
|
||||||
- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
||||||
- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
||||||
- Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
||||||
- Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
||||||
- Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
|
|
||||||
- Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
|
|
||||||
- Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
|
|
||||||
- Marked `Guzzle\Common\Collection::inject()` as deprecated.
|
|
||||||
- Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
|
|
||||||
`$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
|
|
||||||
`$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
|
|
||||||
|
|
||||||
3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
|
|
||||||
request methods. When paired with a client's configuration settings, these options allow you to specify default settings
|
|
||||||
for various aspects of a request. Because these options make other previous configuration options redundant, several
|
|
||||||
configuration options and methods of a client and AbstractCommand have been deprecated.
|
|
||||||
|
|
||||||
- Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
|
|
||||||
- Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
|
|
||||||
- Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
|
|
||||||
- Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
|
|
||||||
|
|
||||||
$command = $client->getCommand('foo', array(
|
|
||||||
'command.headers' => array('Test' => '123'),
|
|
||||||
'command.response_body' => '/path/to/file'
|
|
||||||
));
|
|
||||||
|
|
||||||
// Should be changed to:
|
|
||||||
|
|
||||||
$command = $client->getCommand('foo', array(
|
|
||||||
'command.request_options' => array(
|
|
||||||
'headers' => array('Test' => '123'),
|
|
||||||
'save_as' => '/path/to/file'
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
### Interface changes
|
|
||||||
|
|
||||||
Additions and changes (you will need to update any implementations or subclasses you may have created):
|
|
||||||
|
|
||||||
- Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
|
|
||||||
createRequest, head, delete, put, patch, post, options, prepareRequest
|
|
||||||
- Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
|
|
||||||
- Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
|
|
||||||
- Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
|
|
||||||
`Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
|
|
||||||
resource, string, or EntityBody into the $options parameter to specify the download location of the response.
|
|
||||||
- Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
|
|
||||||
default `array()`
|
|
||||||
- Added `Guzzle\Stream\StreamInterface::isRepeatable`
|
|
||||||
- Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
|
|
||||||
|
|
||||||
The following methods were removed from interfaces. All of these methods are still available in the concrete classes
|
|
||||||
that implement them, but you should update your code to use alternative methods:
|
|
||||||
|
|
||||||
- Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
|
|
||||||
`$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
|
|
||||||
`$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
|
|
||||||
`$client->setDefaultOption('headers/{header_name}', 'value')`. or
|
|
||||||
`$client->setDefaultOption('headers', array('header_name' => 'value'))`.
|
|
||||||
- Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
|
|
||||||
- Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
|
|
||||||
- Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
|
|
||||||
- Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
|
|
||||||
- Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
|
|
||||||
- Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
|
|
||||||
- Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
|
|
||||||
|
|
||||||
### Cache plugin breaking changes
|
|
||||||
|
|
||||||
- CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
|
|
||||||
CacheStorageInterface. These two objects and interface will be removed in a future version.
|
|
||||||
- Always setting X-cache headers on cached responses
|
|
||||||
- Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
|
|
||||||
- `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
|
|
||||||
$request, Response $response);`
|
|
||||||
- `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
|
|
||||||
- `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
|
|
||||||
- Added `CacheStorageInterface::purge($url)`
|
|
||||||
- `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
|
|
||||||
$plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
|
|
||||||
CanCacheStrategyInterface $canCache = null)`
|
|
||||||
- Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
|
|
||||||
|
|
||||||
3.5 to 3.6
|
|
||||||
----------
|
|
||||||
|
|
||||||
* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
|
|
||||||
* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
|
|
||||||
* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
|
|
||||||
For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
|
|
||||||
Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
|
|
||||||
* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
|
|
||||||
HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
|
|
||||||
CacheControl header implementation.
|
|
||||||
* Moved getLinks() from Response to just be used on a Link header object.
|
|
||||||
|
|
||||||
If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
|
|
||||||
HeaderInterface (e.g. toArray(), getAll(), etc).
|
|
||||||
|
|
||||||
### Interface changes
|
|
||||||
|
|
||||||
* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
|
|
||||||
* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
|
|
||||||
* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
|
|
||||||
Guzzle\Http\Curl\RequestMediator
|
|
||||||
* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
|
|
||||||
* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
|
|
||||||
* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
|
|
||||||
|
|
||||||
### Removed deprecated functions
|
|
||||||
|
|
||||||
* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
|
||||||
* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
|
||||||
|
|
||||||
### Deprecations
|
|
||||||
|
|
||||||
* The ability to case-insensitively search for header values
|
|
||||||
* Guzzle\Http\Message\Header::hasExactHeader
|
|
||||||
* Guzzle\Http\Message\Header::raw. Use getAll()
|
|
||||||
* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
|
|
||||||
instead.
|
|
||||||
|
|
||||||
### Other changes
|
|
||||||
|
|
||||||
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
|
||||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
|
||||||
directly via interfaces
|
|
||||||
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
|
||||||
but are a no-op until removed.
|
|
||||||
* Most classes that used to require a ``Guzzle\Service\Command\CommandInterface` typehint now request a
|
|
||||||
`Guzzle\Service\Command\ArrayCommandInterface`.
|
|
||||||
* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
|
|
||||||
on a request while the request is still being transferred
|
|
||||||
* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
|
|
||||||
|
|
||||||
3.3 to 3.4
|
|
||||||
----------
|
|
||||||
|
|
||||||
Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
|
|
||||||
|
|
||||||
3.2 to 3.3
|
|
||||||
----------
|
|
||||||
|
|
||||||
### Response::getEtag() quote stripping removed
|
|
||||||
|
|
||||||
`Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
|
|
||||||
|
|
||||||
### Removed `Guzzle\Http\Utils`
|
|
||||||
|
|
||||||
The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
|
|
||||||
|
|
||||||
### Stream wrapper and type
|
|
||||||
|
|
||||||
`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to lowercase.
|
|
||||||
|
|
||||||
### curl.emit_io became emit_io
|
|
||||||
|
|
||||||
Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
|
|
||||||
'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
|
|
||||||
|
|
||||||
3.1 to 3.2
|
|
||||||
----------
|
|
||||||
|
|
||||||
### CurlMulti is no longer reused globally
|
|
||||||
|
|
||||||
Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
|
|
||||||
to a single client can pollute requests dispatched from other clients.
|
|
||||||
|
|
||||||
If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
|
|
||||||
ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
|
|
||||||
created.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$multi = new Guzzle\Http\Curl\CurlMulti();
|
|
||||||
$builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
|
|
||||||
$builder->addListener('service_builder.create_client', function ($event) use ($multi) {
|
|
||||||
$event['client']->setCurlMulti($multi);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### No default path
|
|
||||||
|
|
||||||
URLs no longer have a default path value of '/' if no path was specified.
|
|
||||||
|
|
||||||
Before:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$request = $client->get('http://www.foo.com');
|
|
||||||
echo $request->getUrl();
|
|
||||||
// >> http://www.foo.com/
|
|
||||||
```
|
|
||||||
|
|
||||||
After:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$request = $client->get('http://www.foo.com');
|
|
||||||
echo $request->getUrl();
|
|
||||||
// >> http://www.foo.com
|
|
||||||
```
|
|
||||||
|
|
||||||
### Less verbose BadResponseException
|
|
||||||
|
|
||||||
The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
|
|
||||||
response information. You can, however, get access to the request and response object by calling `getRequest()` or
|
|
||||||
`getResponse()` on the exception object.
|
|
||||||
|
|
||||||
### Query parameter aggregation
|
|
||||||
|
|
||||||
Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
|
|
||||||
setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
|
|
||||||
responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
|
|
||||||
|
|
||||||
2.8 to 3.x
|
|
||||||
----------
|
|
||||||
|
|
||||||
### Guzzle\Service\Inspector
|
|
||||||
|
|
||||||
Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
|
|
||||||
|
|
||||||
**Before**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Service\Inspector;
|
|
||||||
|
|
||||||
class YourClient extends \Guzzle\Service\Client
|
|
||||||
{
|
|
||||||
public static function factory($config = array())
|
|
||||||
{
|
|
||||||
$default = array();
|
|
||||||
$required = array('base_url', 'username', 'api_key');
|
|
||||||
$config = Inspector::fromConfig($config, $default, $required);
|
|
||||||
|
|
||||||
$client = new self(
|
|
||||||
$config->get('base_url'),
|
|
||||||
$config->get('username'),
|
|
||||||
$config->get('api_key')
|
|
||||||
);
|
|
||||||
$client->setConfig($config);
|
|
||||||
|
|
||||||
$client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
|
||||||
|
|
||||||
return $client;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Common\Collection;
|
|
||||||
|
|
||||||
class YourClient extends \Guzzle\Service\Client
|
|
||||||
{
|
|
||||||
public static function factory($config = array())
|
|
||||||
{
|
|
||||||
$default = array();
|
|
||||||
$required = array('base_url', 'username', 'api_key');
|
|
||||||
$config = Collection::fromConfig($config, $default, $required);
|
|
||||||
|
|
||||||
$client = new self(
|
|
||||||
$config->get('base_url'),
|
|
||||||
$config->get('username'),
|
|
||||||
$config->get('api_key')
|
|
||||||
);
|
|
||||||
$client->setConfig($config);
|
|
||||||
|
|
||||||
$client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
|
||||||
|
|
||||||
return $client;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Convert XML Service Descriptions to JSON
|
|
||||||
|
|
||||||
**Before**
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<client>
|
|
||||||
<commands>
|
|
||||||
<!-- Groups -->
|
|
||||||
<command name="list_groups" method="GET" uri="groups.json">
|
|
||||||
<doc>Get a list of groups</doc>
|
|
||||||
</command>
|
|
||||||
<command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
|
|
||||||
<doc>Uses a search query to get a list of groups</doc>
|
|
||||||
<param name="query" type="string" required="true" />
|
|
||||||
</command>
|
|
||||||
<command name="create_group" method="POST" uri="groups.json">
|
|
||||||
<doc>Create a group</doc>
|
|
||||||
<param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
|
||||||
<param name="Content-Type" location="header" static="application/json"/>
|
|
||||||
</command>
|
|
||||||
<command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
|
|
||||||
<doc>Delete a group by ID</doc>
|
|
||||||
<param name="id" type="integer" required="true"/>
|
|
||||||
</command>
|
|
||||||
<command name="get_group" method="GET" uri="groups/{{id}}.json">
|
|
||||||
<param name="id" type="integer" required="true"/>
|
|
||||||
</command>
|
|
||||||
<command name="update_group" method="PUT" uri="groups/{{id}}.json">
|
|
||||||
<doc>Update a group</doc>
|
|
||||||
<param name="id" type="integer" required="true"/>
|
|
||||||
<param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
|
||||||
<param name="Content-Type" location="header" static="application/json"/>
|
|
||||||
</command>
|
|
||||||
</commands>
|
|
||||||
</client>
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Zendesk REST API v2",
|
|
||||||
"apiVersion": "2012-12-31",
|
|
||||||
"description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
|
|
||||||
"operations": {
|
|
||||||
"list_groups": {
|
|
||||||
"httpMethod":"GET",
|
|
||||||
"uri": "groups.json",
|
|
||||||
"summary": "Get a list of groups"
|
|
||||||
},
|
|
||||||
"search_groups":{
|
|
||||||
"httpMethod":"GET",
|
|
||||||
"uri": "search.json?query=\"{query} type:group\"",
|
|
||||||
"summary": "Uses a search query to get a list of groups",
|
|
||||||
"parameters":{
|
|
||||||
"query":{
|
|
||||||
"location": "uri",
|
|
||||||
"description":"Zendesk Search Query",
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"create_group": {
|
|
||||||
"httpMethod":"POST",
|
|
||||||
"uri": "groups.json",
|
|
||||||
"summary": "Create a group",
|
|
||||||
"parameters":{
|
|
||||||
"data": {
|
|
||||||
"type": "array",
|
|
||||||
"location": "body",
|
|
||||||
"description":"Group JSON",
|
|
||||||
"filters": "json_encode",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"Content-Type":{
|
|
||||||
"type": "string",
|
|
||||||
"location":"header",
|
|
||||||
"static": "application/json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delete_group": {
|
|
||||||
"httpMethod":"DELETE",
|
|
||||||
"uri": "groups/{id}.json",
|
|
||||||
"summary": "Delete a group",
|
|
||||||
"parameters":{
|
|
||||||
"id":{
|
|
||||||
"location": "uri",
|
|
||||||
"description":"Group to delete by ID",
|
|
||||||
"type": "integer",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"get_group": {
|
|
||||||
"httpMethod":"GET",
|
|
||||||
"uri": "groups/{id}.json",
|
|
||||||
"summary": "Get a ticket",
|
|
||||||
"parameters":{
|
|
||||||
"id":{
|
|
||||||
"location": "uri",
|
|
||||||
"description":"Group to get by ID",
|
|
||||||
"type": "integer",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"update_group": {
|
|
||||||
"httpMethod":"PUT",
|
|
||||||
"uri": "groups/{id}.json",
|
|
||||||
"summary": "Update a group",
|
|
||||||
"parameters":{
|
|
||||||
"id": {
|
|
||||||
"location": "uri",
|
|
||||||
"description":"Group to update by ID",
|
|
||||||
"type": "integer",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"type": "array",
|
|
||||||
"location": "body",
|
|
||||||
"description":"Group JSON",
|
|
||||||
"filters": "json_encode",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"Content-Type":{
|
|
||||||
"type": "string",
|
|
||||||
"location":"header",
|
|
||||||
"static": "application/json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Guzzle\Service\Description\ServiceDescription
|
|
||||||
|
|
||||||
Commands are now called Operations
|
|
||||||
|
|
||||||
**Before**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Service\Description\ServiceDescription;
|
|
||||||
|
|
||||||
$sd = new ServiceDescription();
|
|
||||||
$sd->getCommands(); // @returns ApiCommandInterface[]
|
|
||||||
$sd->hasCommand($name);
|
|
||||||
$sd->getCommand($name); // @returns ApiCommandInterface|null
|
|
||||||
$sd->addCommand($command); // @param ApiCommandInterface $command
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Service\Description\ServiceDescription;
|
|
||||||
|
|
||||||
$sd = new ServiceDescription();
|
|
||||||
$sd->getOperations(); // @returns OperationInterface[]
|
|
||||||
$sd->hasOperation($name);
|
|
||||||
$sd->getOperation($name); // @returns OperationInterface|null
|
|
||||||
$sd->addOperation($operation); // @param OperationInterface $operation
|
|
||||||
```
|
|
||||||
|
|
||||||
### Guzzle\Common\Inflection\Inflector
|
|
||||||
|
|
||||||
Namespace is now `Guzzle\Inflection\Inflector`
|
|
||||||
|
|
||||||
### Guzzle\Http\Plugin
|
|
||||||
|
|
||||||
Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
|
|
||||||
|
|
||||||
### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
|
|
||||||
|
|
||||||
Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
|
|
||||||
|
|
||||||
**Before**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Common\Log\ClosureLogAdapter;
|
|
||||||
use Guzzle\Http\Plugin\LogPlugin;
|
|
||||||
|
|
||||||
/** @var \Guzzle\Http\Client */
|
|
||||||
$client;
|
|
||||||
|
|
||||||
// $verbosity is an integer indicating desired message verbosity level
|
|
||||||
$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Log\ClosureLogAdapter;
|
|
||||||
use Guzzle\Log\MessageFormatter;
|
|
||||||
use Guzzle\Plugin\Log\LogPlugin;
|
|
||||||
|
|
||||||
/** @var \Guzzle\Http\Client */
|
|
||||||
$client;
|
|
||||||
|
|
||||||
// $format is a string indicating desired message format -- @see MessageFormatter
|
|
||||||
$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Guzzle\Http\Plugin\CurlAuthPlugin
|
|
||||||
|
|
||||||
Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
|
|
||||||
|
|
||||||
### Guzzle\Http\Plugin\ExponentialBackoffPlugin
|
|
||||||
|
|
||||||
Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
|
|
||||||
|
|
||||||
**Before**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
|
|
||||||
|
|
||||||
$backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
|
|
||||||
ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
|
|
||||||
));
|
|
||||||
|
|
||||||
$client->addSubscriber($backoffPlugin);
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Guzzle\Plugin\Backoff\BackoffPlugin;
|
|
||||||
use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
|
|
||||||
|
|
||||||
// Use convenient factory method instead -- see implementation for ideas of what
|
|
||||||
// you can do with chaining backoff strategies
|
|
||||||
$backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
|
|
||||||
HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
|
|
||||||
));
|
|
||||||
$client->addSubscriber($backoffPlugin);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Known Issues
|
|
||||||
|
|
||||||
#### [BUG] Accept-Encoding header behavior changed unintentionally.
|
|
||||||
|
|
||||||
(See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
|
|
||||||
|
|
||||||
In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
|
|
||||||
properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
|
|
||||||
See issue #217 for a workaround, or use a version containing the fix.
|
|
@ -1,45 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="guzzle" default="test">
|
|
||||||
<!-- set local values, like git location -->
|
|
||||||
<property file="phing/build.properties.dist" override="true" />
|
|
||||||
<property file="phing/build.properties" override="true" />
|
|
||||||
|
|
||||||
<property name="dir.output" value="${project.basedir}/build/artifacts" />
|
|
||||||
<property name="dir.imports" value="${project.basedir}/phing/imports" />
|
|
||||||
<property name="dir.bin" value="${project.basedir}/bin" />
|
|
||||||
<property name="repo.dir" value="${project.basedir}" />
|
|
||||||
|
|
||||||
<import file="${dir.imports}/dependencies.xml"/>
|
|
||||||
<import file="${dir.imports}/deploy.xml"/>
|
|
||||||
|
|
||||||
<target name="composer-lint" description="lint-check composer.json only">
|
|
||||||
<composerlint dir="${project.basedir}/src" file="{$project.basedir}/composer.json" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="test" description="Run unit tests">
|
|
||||||
<exec passthru="true" command="vendor/bin/phpunit" checkReturn="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="build-init" description="Initialize local phing properties">
|
|
||||||
<copy file="phing/build.properties.dist" tofile="phing/build.properties" overwrite="false" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean">
|
|
||||||
<delete dir="${dir.output}"/>
|
|
||||||
<delete dir="${project.basedir}/build/pearwork"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="prepare" depends="clean,build-init">
|
|
||||||
<mkdir dir="${dir.output}"/>
|
|
||||||
<mkdir dir="${dir.output}/logs" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="coverage" depends="prepare">
|
|
||||||
<exec passthru="true" command="vendor/bin/phpunit --coverage-html=${dir.output}/coverage" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="view-coverage">
|
|
||||||
<exec passthru="true" command="open ${dir.output}/coverage/index.html" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,82 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "guzzle/guzzle",
|
|
||||||
"type": "library",
|
|
||||||
"description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
|
|
||||||
"keywords": ["framework", "http", "rest", "web service", "curl", "client", "HTTP client"],
|
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"license": "MIT",
|
|
||||||
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Guzzle Community",
|
|
||||||
"homepage": "https://github.com/guzzle/guzzle/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
"replace": {
|
|
||||||
"guzzle/batch": "self.version",
|
|
||||||
"guzzle/cache": "self.version",
|
|
||||||
"guzzle/common": "self.version",
|
|
||||||
"guzzle/http": "self.version",
|
|
||||||
"guzzle/inflection": "self.version",
|
|
||||||
"guzzle/iterator": "self.version",
|
|
||||||
"guzzle/log": "self.version",
|
|
||||||
"guzzle/parser": "self.version",
|
|
||||||
"guzzle/plugin": "self.version",
|
|
||||||
"guzzle/plugin-async": "self.version",
|
|
||||||
"guzzle/plugin-backoff": "self.version",
|
|
||||||
"guzzle/plugin-cache": "self.version",
|
|
||||||
"guzzle/plugin-cookie": "self.version",
|
|
||||||
"guzzle/plugin-curlauth": "self.version",
|
|
||||||
"guzzle/plugin-error-response": "self.version",
|
|
||||||
"guzzle/plugin-history": "self.version",
|
|
||||||
"guzzle/plugin-log": "self.version",
|
|
||||||
"guzzle/plugin-md5": "self.version",
|
|
||||||
"guzzle/plugin-mock": "self.version",
|
|
||||||
"guzzle/plugin-oauth": "self.version",
|
|
||||||
"guzzle/service": "self.version",
|
|
||||||
"guzzle/stream": "self.version"
|
|
||||||
},
|
|
||||||
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3",
|
|
||||||
"ext-curl": "*",
|
|
||||||
"symfony/event-dispatcher": "~2.1"
|
|
||||||
},
|
|
||||||
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Guzzle": "src/",
|
|
||||||
"Guzzle\\Tests": "tests/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"suggest": {
|
|
||||||
"guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
|
|
||||||
},
|
|
||||||
|
|
||||||
"scripts": {
|
|
||||||
"test": "phpunit"
|
|
||||||
},
|
|
||||||
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/cache": "~1.3",
|
|
||||||
"symfony/class-loader": "~2.1",
|
|
||||||
"monolog/monolog": "~1.0",
|
|
||||||
"psr/log": "~1.0",
|
|
||||||
"zendframework/zend-cache": "2.*,<2.3",
|
|
||||||
"zendframework/zend-log": "2.*,<2.3",
|
|
||||||
"phpunit/phpunit": "3.7.*"
|
|
||||||
},
|
|
||||||
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.9-dev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,153 +0,0 @@
|
|||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = _build
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
|
|
||||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make standalone HTML files"
|
|
||||||
@echo " dirhtml to make HTML files named index.html in directories"
|
|
||||||
@echo " singlehtml to make a single large HTML file"
|
|
||||||
@echo " pickle to make pickle files"
|
|
||||||
@echo " json to make JSON files"
|
|
||||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
@echo " qthelp to make HTML files and a qthelp project"
|
|
||||||
@echo " devhelp to make HTML files and a Devhelp project"
|
|
||||||
@echo " epub to make an epub"
|
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " text to make text files"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " texinfo to make Texinfo files"
|
|
||||||
@echo " info to make Texinfo files and run them through makeinfo"
|
|
||||||
@echo " gettext to make PO message catalogs"
|
|
||||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
@echo " linkcheck to check all external links for integrity"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
|
||||||
|
|
||||||
dirhtml:
|
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
|
||||||
|
|
||||||
singlehtml:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
pickle:
|
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the pickle files."
|
|
||||||
|
|
||||||
json:
|
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the JSON files."
|
|
||||||
|
|
||||||
htmlhelp:
|
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
|
||||||
|
|
||||||
qthelp:
|
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
|
||||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
|
||||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Guzzle.qhcp"
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Guzzle.qhc"
|
|
||||||
|
|
||||||
devhelp:
|
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished."
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Guzzle"
|
|
||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Guzzle"
|
|
||||||
@echo "# devhelp"
|
|
||||||
|
|
||||||
epub:
|
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
|
||||||
|
|
||||||
latex:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
|
||||||
|
|
||||||
latexpdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
text:
|
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
|
||||||
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
||||||
|
|
||||||
texinfo:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
|
||||||
"(use \`make info' here to do that automatically)."
|
|
||||||
|
|
||||||
info:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
|
||||||
make -C $(BUILDDIR)/texinfo info
|
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
|
||||||
|
|
||||||
gettext:
|
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
|
||||||
|
|
||||||
changes:
|
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
|
||||||
@echo
|
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
|
||||||
|
|
||||||
linkcheck:
|
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
|
||||||
@echo
|
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
|
||||||
|
|
||||||
doctest:
|
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
@ -1,176 +0,0 @@
|
|||||||
{
|
|
||||||
"additionalProperties": true,
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Name of the web service"
|
|
||||||
},
|
|
||||||
"apiVersion": {
|
|
||||||
"type": ["string", "number"],
|
|
||||||
"description": "Version identifier that the service description is compatible with"
|
|
||||||
},
|
|
||||||
"baseUrl": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Base URL of the web service. Any relative URI specified in an operation will be merged with the baseUrl using the process defined in RFC 2396"
|
|
||||||
},
|
|
||||||
"basePath": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Alias of baseUrl"
|
|
||||||
},
|
|
||||||
"_description": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Short summary of the web service. This is actually called 'description' but this JSON schema wont validate using just description."
|
|
||||||
},
|
|
||||||
"operations": {
|
|
||||||
"description": "Operations of the web service",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"extends": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Extend from another operation by name. The parent operation must be defined before the child."
|
|
||||||
},
|
|
||||||
"httpMethod": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "HTTP method used with the operation (e.g. GET, POST, PUT, DELETE, PATCH, etc)"
|
|
||||||
},
|
|
||||||
"uri": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "URI of the operation. The uri attribute can contain URI templates. The variables of the URI template are parameters of the operation with a location value of uri"
|
|
||||||
},
|
|
||||||
"summary": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Short summary of what the operation does"
|
|
||||||
},
|
|
||||||
"class": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Custom class to instantiate instead of the default Guzzle\\Service\\Command\\OperationCommand"
|
|
||||||
},
|
|
||||||
"responseClass": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "This is what is returned from the method. Can be a primitive, class name, or model name."
|
|
||||||
},
|
|
||||||
"responseNotes": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "A description of the response returned by the operation"
|
|
||||||
},
|
|
||||||
"responseType": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The type of response that the operation creates. If not specified, this value will be automatically inferred based on whether or not there is a model matching the name, if a matching class name is found, or set to 'primitive' by default.",
|
|
||||||
"enum": [ "primitive", "class", "model", "documentation" ]
|
|
||||||
},
|
|
||||||
"deprecated": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Whether or not the operation is deprecated"
|
|
||||||
},
|
|
||||||
"errorResponses": {
|
|
||||||
"description": "Errors that could occur while executing the operation",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"code": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "HTTP response status code of the error"
|
|
||||||
},
|
|
||||||
"reason": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Response reason phrase or description of the error"
|
|
||||||
},
|
|
||||||
"class": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "A custom exception class that would be thrown if the error is encountered"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": "true"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"$ref": "parameters",
|
|
||||||
"description": "Parameters of the operation. Parameters are used to define how input data is serialized into a HTTP request."
|
|
||||||
},
|
|
||||||
"additionalParameters": {
|
|
||||||
"$ref": "parameters",
|
|
||||||
"description": "Validation and serialization rules for any parameter supplied to the operation that was not explicitly defined."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"description": "Schema models that can be referenced throughout the service description. Models can be used to define how an HTTP response is parsed into a Guzzle\\Service\\Resource\\Model object.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"$ref": "parameters",
|
|
||||||
"description": "Parameters of the model. When a model is referenced in a responseClass attribute of an operation, parameters define how a HTTP response message is parsed into a Guzzle\\Service\\Resource\\Model."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"includes": {
|
|
||||||
"description": "Service description files to include and extend from (can be a .json, .js, or .php file)",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"pattern": ".+\\.(js|json|php)$"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"definitions": {
|
|
||||||
"parameters": {
|
|
||||||
"extends": "http://json-schema.org/schema",
|
|
||||||
"id": "parameters",
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Unique name of the parameter"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": ["string", "array"],
|
|
||||||
"description": "Type of variable (string, number, integer, boolean, object, array, numeric, null, any). Types are using for validation and determining the structure of a parameter. You can use a union type by providing an array of simple types. If one of the union types matches the provided value, then the value is valid."
|
|
||||||
},
|
|
||||||
"instanceOf": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "When the type is an object, you can specify the class that the object must implement"
|
|
||||||
},
|
|
||||||
"required": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Whether or not the parameter is required"
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"description": "Default value to use if no value is supplied"
|
|
||||||
},
|
|
||||||
"static": {
|
|
||||||
"type": "bool",
|
|
||||||
"description": "Set to true to specify that the parameter value cannot be changed from the default setting"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Documentation of the parameter"
|
|
||||||
},
|
|
||||||
"location": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The location of a request used to apply a parameter. Custom locations can be registered with a command, but the defaults are uri, query, statusCode, reasonPhrase, header, body, json, xml, postField, postFile, responseBody"
|
|
||||||
},
|
|
||||||
"sentAs": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Specifies how the data being modeled is sent over the wire. For example, you may wish to include certain headers in a response model that have a normalized casing of FooBar, but the actual header is x-foo-bar. In this case, sentAs would be set to x-foo-bar."
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Array of static method names to to run a parameter value through. Each value in the array must be a string containing the full class path to a static method or an array of complex filter information. You can specify static methods of classes using the full namespace class name followed by ‘::’ (e.g. FooBar::baz()). Some filters require arguments in order to properly filter a value. For complex filters, use a hash containing a ‘method’ key pointing to a static method, and an ‘args’ key containing an array of positional arguments to pass to the method. Arguments can contain keywords that are replaced when filtering a value: '@value‘ is replaced with the value being validated, '@api‘ is replaced with the Parameter object.",
|
|
||||||
"items": {
|
|
||||||
"type": ["string", {
|
|
||||||
"object": {
|
|
||||||
"properties": {
|
|
||||||
"method": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "PHP function to call",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"args": {
|
|
||||||
"type": "array"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 803 B |
@ -1,122 +0,0 @@
|
|||||||
/* Hero unit on homepage */
|
|
||||||
|
|
||||||
.hero-unit h1 {
|
|
||||||
font-size: 49px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-unit {
|
|
||||||
padding: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-unit p {
|
|
||||||
font-size: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.masthead img {
|
|
||||||
float: left;
|
|
||||||
margin-right: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-unit ul li {
|
|
||||||
margin-left: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-unit .buttons {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jumbotron {
|
|
||||||
position: relative;
|
|
||||||
padding: 40px 0;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 1px 3px rgba(0,0,0,.4), 0 0 30px rgba(0,0,0,.075);
|
|
||||||
background: #00312F;
|
|
||||||
background: -moz-linear-gradient(45deg, #002F31 0%, #335A6D 100%);
|
|
||||||
background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#00312D), color-stop(100%,#33566D));
|
|
||||||
background: -webkit-linear-gradient(45deg, #020031 0%,#334F6D 100%);
|
|
||||||
background: -o-linear-gradient(45deg, #002D31 0%,#334D6D 100%);
|
|
||||||
background: -ms-linear-gradient(45deg, #002F31 0%,#33516D 100%);
|
|
||||||
background: linear-gradient(45deg, #020031 0%,#33516D 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#020031', endColorstr='#6d3353',GradientType=1 );
|
|
||||||
-webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, .2), inset 0 -3px 7px rgba(0, 0, 0, .2);
|
|
||||||
-moz-box-shadow: inset 0 3px 7px rgba(0,0,0,.2), inset 0 -3px 7px rgba(0,0,0,.2);
|
|
||||||
box-shadow: inset 0 3px 7px rgba(0, 0, 0, .2), inset 0 -3px 7px rgba(0, 0, 0, .2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.jumbotron h1 {
|
|
||||||
font-size: 80px;
|
|
||||||
font-weight: bold;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jumbotron p {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 300;
|
|
||||||
line-height: 1.25;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.masthead {
|
|
||||||
padding: 40px 0 30px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
color: #fff;
|
|
||||||
margin-top: -19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.masthead h1 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.masthead p {
|
|
||||||
font-size: 40px;
|
|
||||||
font-weight: 200;
|
|
||||||
line-height: 1.25;
|
|
||||||
margin: 12px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.masthead .btn {
|
|
||||||
padding: 19px 24px;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 200;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Social bar on homepage */
|
|
||||||
|
|
||||||
.social {
|
|
||||||
padding: 2px 0;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
margin: 0 0 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social ul {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-buttons {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-buttons li {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 5px 8px;
|
|
||||||
line-height: 1;
|
|
||||||
*display: inline;
|
|
||||||
*zoom: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-announcement {
|
|
||||||
padding: 10px;
|
|
||||||
background-color: rgb(238, 243, 255);
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
margin: 24px 0;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 242 KiB |
@ -1,41 +0,0 @@
|
|||||||
.com {
|
|
||||||
color: #93A1A1;
|
|
||||||
}
|
|
||||||
.lit {
|
|
||||||
color: #195F91;
|
|
||||||
}
|
|
||||||
.pun, .opn, .clo {
|
|
||||||
color: #93A1A1;
|
|
||||||
}
|
|
||||||
.fun {
|
|
||||||
color: #DC322F;
|
|
||||||
}
|
|
||||||
.str, .atv {
|
|
||||||
color: #DD1144;
|
|
||||||
}
|
|
||||||
.kwd, .linenums .tag {
|
|
||||||
color: #1E347B;
|
|
||||||
}
|
|
||||||
.typ, .atn, .dec, .var {
|
|
||||||
color: teal;
|
|
||||||
}
|
|
||||||
.pln {
|
|
||||||
color: #48484C;
|
|
||||||
}
|
|
||||||
.prettyprint {
|
|
||||||
background-color: #F7F7F9;
|
|
||||||
border: 1px solid #E1E1E8;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
.prettyprint.linenums {
|
|
||||||
box-shadow: 40px 0 0 #FBFBFC inset, 41px 0 0 #ECECF0 inset;
|
|
||||||
}
|
|
||||||
ol.linenums {
|
|
||||||
margin: 0 0 0 33px;
|
|
||||||
}
|
|
||||||
ol.linenums li {
|
|
||||||
color: #BEBEC5;
|
|
||||||
line-height: 18px;
|
|
||||||
padding-left: 12px;
|
|
||||||
text-shadow: 0 1px 0 #FFFFFF;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
|
|
||||||
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
|
|
||||||
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
|
|
||||||
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
|
|
||||||
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
|
|
||||||
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
|
|
||||||
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
|
|
||||||
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
|
|
||||||
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
|
|
||||||
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
|
|
||||||
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
|
|
||||||
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
|
|
||||||
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
|
|
||||||
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
|
|
||||||
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
|
|
||||||
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
|
|
||||||
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
|
|
||||||
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
|
|
||||||
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
|
|
||||||
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
|
|
||||||
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
|
|
||||||
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
|
|
||||||
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
|
|
||||||
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
|
|
||||||
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
|
|
||||||
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
|
|
||||||
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
|
|
||||||
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
|
|
@ -1,106 +0,0 @@
|
|||||||
<script type="text/javascript" src="{{ pathto('_static/prettify.js', 1) }}"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/prettify.css', 1) }}" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ pathto('_static/homepage.css', 1) }}" />
|
|
||||||
|
|
||||||
<div class="jumbotron masthead">
|
|
||||||
<div class="container">
|
|
||||||
<img src="{{ pathto('_static/logo.png', 1) }}" alt="guzzle" width="199" height="260" />
|
|
||||||
<h1>Guzzle</h1>
|
|
||||||
<p>Guzzle is a PHP HTTP client<br />& framework for building RESTful web service clients.</p>
|
|
||||||
<p>
|
|
||||||
<a class="btn btn-primary btn-lg" href="https://github.com/guzzle/guzzle">View Guzzle on GitHub</a>
|
|
||||||
<a class="btn btn-default btn-lg" href="{{ pathto('docs') }}">Read the docs</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="social">
|
|
||||||
<ul class="social-buttons">
|
|
||||||
<li>
|
|
||||||
<iframe src="http://ghbtns.com/github-btn.html?user=guzzle&repo=guzzle&type=watch&count=true"
|
|
||||||
allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://twitter.com/share" class="twitter-share-button" data-url="http://guzzlephp.org" data-text="Guzzle, PHP HTTP client & framework for building RESTful web service clients" data-via="mtdowling">Tweet</a>
|
|
||||||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="http://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://twitter.com/mtdowling" class="twitter-follow-button" data-show-count="false">Follow @mtdowling</a>
|
|
||||||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="http://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<h1>Introducing Guzzle</h1>
|
|
||||||
|
|
||||||
<p>Guzzle takes the pain out of sending HTTP requests and the redundancy out of creating web service clients. It's
|
|
||||||
a framework that includes the tools needed to create a robust web service client, including:
|
|
||||||
Service descriptions for defining the inputs and outputs of an API, resource iterators for traversing
|
|
||||||
paginated resources, batching for sending a large number of requests as efficiently as possible.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>All the power of cURL with a simple interface.</li>
|
|
||||||
<li>Persistent connections and parallel requests.</li>
|
|
||||||
<li>Streams request and response bodies</li>
|
|
||||||
<li><a href="{{ pathto('webservice-client/guzzle-service-descriptions') }}">Service descriptions</a> for quickly building clients.</li>
|
|
||||||
<li>Powered by the Symfony2 EventDispatcher.</li>
|
|
||||||
<li>Use all of the code or only <a href="https://packagist.org/packages/guzzle/">specific components</a>.</li>
|
|
||||||
<li><a href="{{ pathto('plugins/plugins-overview') }}">Plugins</a> for caching, logging, OAuth, mocks, and more</li>
|
|
||||||
<li>Includes a custom node.js webserver to <a href="{{ pathto('testing/unit-testing') }}">test your clients</a>.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="center-announcement">
|
|
||||||
Guzzle is now part of Drupal 8 core and powers the official <a href="https://github.com/aws/aws-sdk-php">AWS SDK for PHP</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>GitHub Example</h2>
|
|
||||||
|
|
||||||
<pre class="prettyprint"><?php
|
|
||||||
require_once 'vendor/autoload.php';
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
// Create a client and provide a base URL
|
|
||||||
$client = new Client('https://api.github.com');
|
|
||||||
// Create a request with basic Auth
|
|
||||||
$request = $client->get('/user')->setAuth('user', 'pass');
|
|
||||||
// Send the request and get the response
|
|
||||||
$response = $request->send();
|
|
||||||
echo $response->getBody();
|
|
||||||
// >>> {"type":"User", ...
|
|
||||||
echo $response->getHeader('Content-Length');
|
|
||||||
// >>> 792
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Twitter Example</h2>
|
|
||||||
<pre class="prettyprint"><?php
|
|
||||||
// Create a client to work with the Twitter API
|
|
||||||
$client = new Client('https://api.twitter.com/{version}', array(
|
|
||||||
'version' => '1.1'
|
|
||||||
));
|
|
||||||
|
|
||||||
// Sign all requests with the OauthPlugin
|
|
||||||
$client->addSubscriber(new Guzzle\Plugin\Oauth\OauthPlugin(array(
|
|
||||||
'consumer_key' => '***',
|
|
||||||
'consumer_secret' => '***',
|
|
||||||
'token' => '***',
|
|
||||||
'token_secret' => '***'
|
|
||||||
)));
|
|
||||||
|
|
||||||
echo $client->get('statuses/user_timeline.json')->send()->getBody();
|
|
||||||
// >>> {"public_gists":6,"type":"User" ...
|
|
||||||
|
|
||||||
// Create a tweet using POST
|
|
||||||
$request = $client->post('statuses/update.json', null, array(
|
|
||||||
'status' => 'Tweeted with Guzzle, http://guzzlephp.org'
|
|
||||||
));
|
|
||||||
|
|
||||||
// Send the request and parse the JSON response into an array
|
|
||||||
$data = $request->send()->json();
|
|
||||||
echo $data['text'];
|
|
||||||
// >>> Tweeted with Guzzle, http://t.co/kngJMfRk
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">prettyPrint();</script>
|
|
@ -1,5 +0,0 @@
|
|||||||
<li><a href="{{ pathto('docs') }}">Docs</a></li>
|
|
||||||
<li><a href="http://guzzlephp.org/api/index.html">API</a></li>
|
|
||||||
<li><a href="https://github.com/guzzle/guzzle">GitHub</a></li>
|
|
||||||
<li><a href="https://groups.google.com/forum/?hl=en#!forum/guzzle">Forum</a></li>
|
|
||||||
<li><a href="irc:irc.freenode.com/#guzzlephp">IRC</a></li>
|
|
@ -1,183 +0,0 @@
|
|||||||
========
|
|
||||||
Batching
|
|
||||||
========
|
|
||||||
|
|
||||||
Guzzle provides a fairly generic and very customizable batching framework that allows developers to efficiently
|
|
||||||
transfer requests in parallel.
|
|
||||||
|
|
||||||
Sending requests and commands in parallel
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
You can send HTTP requests in parallel by passing an array of ``Guzzle\Http\Message\RequestInterface`` objects to
|
|
||||||
``Guzzle\Http\Client::send()``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$responses = $client->send(array(
|
|
||||||
$client->get('http://www.example.com/foo'),
|
|
||||||
$client->get('http://www.example.com/baz')
|
|
||||||
$client->get('http://www.example.com/bar')
|
|
||||||
));
|
|
||||||
|
|
||||||
You can send commands in parallel by passing an array of ``Guzzle\Service\Command\CommandInterface`` objects
|
|
||||||
``Guzzle\Service\Client::execute()``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$commands = $client->execute(array(
|
|
||||||
$client->getCommand('foo'),
|
|
||||||
$client->getCommand('baz'),
|
|
||||||
$client->getCommand('bar')
|
|
||||||
));
|
|
||||||
|
|
||||||
These approaches work well for most use-cases. When you need more control over the requests that are sent in
|
|
||||||
parallel or you need to send a large number of requests, you need to use the functionality provided in the
|
|
||||||
``Guzzle\Batch`` namespace.
|
|
||||||
|
|
||||||
Batching overview
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The batch object, ``Guzzle\Batch\Batch``, is a queue. You add requests to the queue until you are ready to transfer
|
|
||||||
all of the requests. In order to efficiently transfer the items in the queue, the batch object delegates the
|
|
||||||
responsibility of dividing the queue into manageable parts to a divisor (``Guzzle\Batch\BatchDivisorInterface``).
|
|
||||||
The batch object then iterates over each array of items created by the divisor and sends them to the batch object's
|
|
||||||
``Guzzle\Batch\BatchTransferInterface``.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\Batch;
|
|
||||||
use Guzzle\Http\BatchRequestTransfer;
|
|
||||||
|
|
||||||
// BatchRequestTransfer acts as both the divisor and transfer strategy
|
|
||||||
$transferStrategy = new BatchRequestTransfer(10);
|
|
||||||
$divisorStrategy = $transferStrategy;
|
|
||||||
|
|
||||||
$batch = new Batch($transferStrategy, $divisorStrategy);
|
|
||||||
|
|
||||||
// Add some requests to the batch queue
|
|
||||||
$batch->add($request1)
|
|
||||||
->add($request2)
|
|
||||||
->add($request3);
|
|
||||||
|
|
||||||
// Flush the queue and retrieve the flushed items
|
|
||||||
$arrayOfTransferredRequests = $batch->flush();
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
You might find that your transfer strategy will need to act as both the divisor and transfer strategy.
|
|
||||||
|
|
||||||
Using the BatchBuilder
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
The ``Guzzle\Batch\BatchBuilder`` makes it easier to create batch objects. The batch builder also provides an easier
|
|
||||||
way to add additional behaviors to your batch object.
|
|
||||||
|
|
||||||
Transferring requests
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``Guzzle\Http\BatchRequestTransfer`` class efficiently transfers HTTP requests in parallel by grouping batches of
|
|
||||||
requests by the curl_multi handle that is used to transfer the requests.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\BatchBuilder;
|
|
||||||
|
|
||||||
$batch = BatchBuilder::factory()
|
|
||||||
->transferRequests(10)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
Transferring commands
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``Guzzle\Service\Command\BatchCommandTransfer`` class efficiently transfers service commands by grouping commands
|
|
||||||
by the client that is used to transfer them. You can add commands to a batch object that are transferred by different
|
|
||||||
clients, and the batch will handle the rest.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\BatchBuilder;
|
|
||||||
|
|
||||||
$batch = BatchBuilder::factory()
|
|
||||||
->transferCommands(10)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
$batch->add($client->getCommand('foo'))
|
|
||||||
->add($client->getCommand('baz'))
|
|
||||||
->add($client->getCommand('bar'));
|
|
||||||
|
|
||||||
$commands = $batch->flush();
|
|
||||||
|
|
||||||
Batch behaviors
|
|
||||||
---------------
|
|
||||||
|
|
||||||
You can add various behaviors to your batch that allow for more customizable transfers.
|
|
||||||
|
|
||||||
Automatically flushing a queue
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Use the ``Guzzle\Batch\FlushingBatch`` decorator when you want to pump a large number of items into a batch queue and
|
|
||||||
have the queue automatically flush when the size of the queue reaches a certain threshold.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\BatchBuilder;
|
|
||||||
|
|
||||||
$batch = BatchBuilder::factory()
|
|
||||||
->transferRequests(10)
|
|
||||||
->autoFlushAt(10)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
Batch builder method: ``autoFlushAt($threshold)``
|
|
||||||
|
|
||||||
Notifying on flush
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Use the ``Guzzle\Batch\NotifyingBatch`` decorator if you want a function to be notified each time the batch queue is
|
|
||||||
flushed. This is useful when paired with the flushing batch decorator. Pass a callable to the ``notify()`` method of
|
|
||||||
a batch builder to use this decorator with the builder.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\BatchBuilder;
|
|
||||||
|
|
||||||
$batch = BatchBuilder::factory()
|
|
||||||
->transferRequests(10)
|
|
||||||
->autoFlushAt(10)
|
|
||||||
->notify(function (array $transferredItems) {
|
|
||||||
echo 'Transferred ' . count($transferredItems) . "items\n";
|
|
||||||
})
|
|
||||||
->build();
|
|
||||||
|
|
||||||
Batch builder method:: ``notify(callable $callback)``
|
|
||||||
|
|
||||||
Keeping a history
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Use the ``Guzzle\Batch\HistoryBatch`` decorator if you want to maintain a history of all the items transferred with
|
|
||||||
the batch queue.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Batch\BatchBuilder;
|
|
||||||
|
|
||||||
$batch = BatchBuilder::factory()
|
|
||||||
->transferRequests(10)
|
|
||||||
->keepHistory()
|
|
||||||
->build();
|
|
||||||
|
|
||||||
After transferring items, you can use the ``getHistory()`` of a batch to retrieve an array of transferred items. Be
|
|
||||||
sure to periodically clear the history using ``clearHistory()``.
|
|
||||||
|
|
||||||
Batch builder method: ``keepHistory()``
|
|
||||||
|
|
||||||
Exception buffering
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Use the ``Guzzle\Batch\ExceptionBufferingBatch`` decorator to buffer exceptions during a transfer so that you can
|
|
||||||
transfer as many items as possible then deal with the errored batches after the transfer completes. After transfer,
|
|
||||||
use the ``getExceptions()`` method of a batch to retrieve an array of
|
|
||||||
``Guzzle\Batch\Exception\BatchTransferException`` objects. You can use these exceptions to attempt to retry the
|
|
||||||
failed batches. Be sure to clear the buffered exceptions when you are done with them by using the
|
|
||||||
``clearExceptions()`` method.
|
|
||||||
|
|
||||||
Batch builder method: ``bufferExceptions()``
|
|
@ -1,94 +0,0 @@
|
|||||||
import sys, os
|
|
||||||
from sphinx.highlighting import lexers
|
|
||||||
from pygments.lexers.web import PhpLexer
|
|
||||||
|
|
||||||
lexers['php'] = PhpLexer(startinline=True, linenos=1)
|
|
||||||
lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1)
|
|
||||||
primary_domain = 'php'
|
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
|
||||||
|
|
||||||
extensions = []
|
|
||||||
templates_path = ['_templates']
|
|
||||||
source_suffix = '.rst'
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
project = u'Guzzle'
|
|
||||||
copyright = u'2012, Michael Dowling'
|
|
||||||
version = '3.0.0'
|
|
||||||
release = '3.0.0'
|
|
||||||
|
|
||||||
exclude_patterns = ['_build']
|
|
||||||
|
|
||||||
# -- Options for HTML output ---------------------------------------------------
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
|
||||||
# "<project> v<release> documentation".
|
|
||||||
html_title = "Guzzle documentation"
|
|
||||||
html_short_title = "Guzzle"
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
html_sidebars = {
|
|
||||||
'**': ['localtoc.html', 'leftbar.html', 'searchbox.html']
|
|
||||||
}
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'Guzzledoc'
|
|
||||||
|
|
||||||
# -- Guzzle Sphinx theme setup ------------------------------------------------
|
|
||||||
|
|
||||||
sys.path.insert(0, '/Users/dowling/projects/guzzle_sphinx_theme')
|
|
||||||
|
|
||||||
import guzzle_sphinx_theme
|
|
||||||
html_translator_class = 'guzzle_sphinx_theme.HTMLTranslator'
|
|
||||||
html_theme_path = guzzle_sphinx_theme.html_theme_path()
|
|
||||||
html_theme = 'guzzle_sphinx_theme'
|
|
||||||
|
|
||||||
# Guzzle theme options (see theme.conf for more information)
|
|
||||||
html_theme_options = {
|
|
||||||
"index_template": "index.html",
|
|
||||||
"project_nav_name": "Guzzle",
|
|
||||||
"github_user": "guzzle",
|
|
||||||
"github_repo": "guzzle",
|
|
||||||
"disqus_comments_shortname": "guzzle",
|
|
||||||
"google_analytics_account": "UA-22752917-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# -- Options for LaTeX output --------------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
|
||||||
latex_documents = [
|
|
||||||
('index', 'Guzzle.tex', u'Guzzle Documentation',
|
|
||||||
u'Michael Dowling', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# -- Options for manual page output --------------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
('index', 'guzzle', u'Guzzle Documentation',
|
|
||||||
[u'Michael Dowling'], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
# -- Options for Texinfo output ------------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
('index', 'Guzzle', u'Guzzle Documentation',
|
|
||||||
u'Michael Dowling', 'Guzzle', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
@ -1,73 +0,0 @@
|
|||||||
.. title:: Guzzle | PHP HTTP client and framework for consuming RESTful web services
|
|
||||||
|
|
||||||
====================
|
|
||||||
Guzzle Documentation
|
|
||||||
====================
|
|
||||||
|
|
||||||
Getting started
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
getting-started/overview
|
|
||||||
getting-started/installation
|
|
||||||
getting-started/faq
|
|
||||||
|
|
||||||
The HTTP client
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
http-client/client
|
|
||||||
http-client/request
|
|
||||||
http-client/response
|
|
||||||
http-client/entity-bodies
|
|
||||||
http-client/http-redirects
|
|
||||||
http-client/uri-templates
|
|
||||||
|
|
||||||
Plugins
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
plugins/plugins-overview
|
|
||||||
plugins/creating-plugins
|
|
||||||
plugins/async-plugin
|
|
||||||
plugins/backoff-plugin
|
|
||||||
plugins/cache-plugin
|
|
||||||
plugins/cookie-plugin
|
|
||||||
plugins/curl-auth-plugin
|
|
||||||
plugins/history-plugin
|
|
||||||
plugins/log-plugin
|
|
||||||
plugins/md5-validator-plugin
|
|
||||||
plugins/mock-plugin
|
|
||||||
plugins/oauth-plugin
|
|
||||||
|
|
||||||
The web service client
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
webservice-client/webservice-client
|
|
||||||
webservice-client/using-the-service-builder
|
|
||||||
webservice-client/guzzle-service-descriptions
|
|
||||||
batching/batching
|
|
||||||
iterators/resource-iterators
|
|
||||||
iterators/guzzle-iterators
|
|
||||||
|
|
||||||
Testing
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
testing/unit-testing
|
|
||||||
|
|
||||||
API Docs
|
|
||||||
--------
|
|
||||||
|
|
||||||
`Read the API docs <http://guzzlephp.org/api/index.html>`_
|
|
@ -1,29 +0,0 @@
|
|||||||
===
|
|
||||||
FAQ
|
|
||||||
===
|
|
||||||
|
|
||||||
What should I do if I get this error: Fatal error: Maximum function nesting level of '100' reached, aborting!
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
You could run into this error if you have the XDebug extension installed and you execute a lot of requests in
|
|
||||||
callbacks. This error message comes specifically from the XDebug extension. PHP itself does not have a function
|
|
||||||
nesting limit. Change this setting in your php.ini to increase the limit::
|
|
||||||
|
|
||||||
xdebug.max_nesting_level = 1000
|
|
||||||
|
|
||||||
[`source <http://stackoverflow.com/a/4293870/151504>`_]
|
|
||||||
|
|
||||||
How can I speed up my client?
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
There are several things you can do to speed up your client:
|
|
||||||
|
|
||||||
1. Utilize a C based HTTP message parser (e.g. ``Guzzle\Parser\Message\PeclHttpMessageParser``)
|
|
||||||
2. Disable operation validation by setting the ``command.disable_validation`` option to true on a command
|
|
||||||
|
|
||||||
Why am I getting a 417 error response?
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
This can occur for a number of reasons, but if you are sending PUT, POST, or PATCH requests with an
|
|
||||||
``Expect: 100-Continue`` header, a server that does not support this header will return a 417 response. You can work
|
|
||||||
around this by calling ``$request->removeHeader('Expect');`` after setting the entity body of a request.
|
|
@ -1,154 +0,0 @@
|
|||||||
============
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
|
|
||||||
#. PHP 5.3.3+ compiled with the cURL extension
|
|
||||||
#. A recent version of cURL 7.16.2+ compiled with OpenSSL and zlib
|
|
||||||
|
|
||||||
Installing Guzzle
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Composer
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The recommended way to install Guzzle is with `Composer <http://getcomposer.org>`_. Composer is a dependency
|
|
||||||
management tool for PHP that allows you to declare the dependencies your project needs and installs them into your
|
|
||||||
project.
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
# Install Composer
|
|
||||||
curl -sS https://getcomposer.org/installer | php
|
|
||||||
|
|
||||||
# Add Guzzle as a dependency
|
|
||||||
php composer.phar require guzzle/guzzle:~3.9
|
|
||||||
|
|
||||||
After installing, you need to require Composer's autoloader:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
require 'vendor/autoload.php';
|
|
||||||
|
|
||||||
You can find out more on how to install Composer, configure autoloading, and other best-practices for defining
|
|
||||||
dependencies at `getcomposer.org <http://getcomposer.org>`_.
|
|
||||||
|
|
||||||
Using only specific parts of Guzzle
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
While you can always just rely on ``guzzle/guzzle``, Guzzle provides several smaller parts of Guzzle as individual
|
|
||||||
packages available through Composer.
|
|
||||||
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| Package name | Description |
|
|
||||||
+===============================================================================================+==========================================+
|
|
||||||
| `guzzle/common <https://packagist.org/packages/guzzle/common>`_ | Provides ``Guzzle\Common`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/http <https://packagist.org/packages/guzzle/http>`_ | Provides ``Guzzle\Http`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/parser <https://packagist.org/packages/guzzle/parser>`_ | Provides ``Guzzle\Parser`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/batch <https://packagist.org/packages/guzzle/batch>`_ | Provides ``Guzzle\Batch`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/cache <https://packagist.org/packages/guzzle/cache>`_ | Provides ``Guzzle\Cache`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/inflection <https://packagist.org/packages/guzzle/inflection>`_ | Provides ``Guzzle\Inflection`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/iterator <https://packagist.org/packages/guzzle/iterator>`_ | Provides ``Guzzle\Iterator`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/log <https://packagist.org/packages/guzzle/log>`_ | Provides ``Guzzle\Log`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin <https://packagist.org/packages/guzzle/plugin>`_ | Provides ``Guzzle\Plugin`` (all plugins) |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-async <https://packagist.org/packages/guzzle/plugin-async>`_ | Provides ``Guzzle\Plugin\Async`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-backoff <https://packagist.org/packages/guzzle/plugin-backoff>`_ | Provides ``Guzzle\Plugin\BackoffPlugin`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-cache <https://packagist.org/packages/guzzle/plugin-cache>`_ | Provides ``Guzzle\Plugin\Cache`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-cookie <https://packagist.org/packages/guzzle/plugin-cookie>`_ | Provides ``Guzzle\Plugin\Cookie`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-error-response <https://packagist.org/packages/guzzle/plugin-error-response>`_ | Provides ``Guzzle\Plugin\ErrorResponse`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-history <https://packagist.org/packages/guzzle/plugin-history>`_ | Provides ``Guzzle\Plugin\History`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-log <https://packagist.org/packages/guzzle/plugin-log>`_ | Provides ``Guzzle\Plugin\Log`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-md5 <https://packagist.org/packages/guzzle/plugin-md5>`_ | Provides ``Guzzle\Plugin\Md5`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-mock <https://packagist.org/packages/guzzle/plugin-mock>`_ | Provides ``Guzzle\Plugin\Mock`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/plugin-oauth <https://packagist.org/packages/guzzle/plugin-oauth>`_ | Provides ``Guzzle\Plugin\Oauth`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/service <https://packagist.org/packages/guzzle/service>`_ | Provides ``Guzzle\Service`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
| `guzzle/stream <https://packagist.org/packages/guzzle/stream>`_ | Provides ``Guzzle\Stream`` |
|
|
||||||
+-----------------------------------------------------------------------------------------------+------------------------------------------+
|
|
||||||
|
|
||||||
Bleeding edge
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
During your development, you can keep up with the latest changes on the master branch by setting the version
|
|
||||||
requirement for Guzzle to ``dev-master``.
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
{
|
|
||||||
"require": {
|
|
||||||
"guzzle/guzzle": "dev-master"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PEAR
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
Guzzle can be installed through PEAR:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pear channel-discover guzzlephp.org/pear
|
|
||||||
pear install guzzle/guzzle
|
|
||||||
|
|
||||||
You can install a specific version of Guzzle by providing a version number suffix:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pear install guzzle/guzzle-3.9.0
|
|
||||||
|
|
||||||
Contributing to Guzzle
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
In order to contribute, you'll need to checkout the source from GitHub and install Guzzle's dependencies using
|
|
||||||
Composer:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
git clone https://github.com/guzzle/guzzle.git
|
|
||||||
cd guzzle && curl -s http://getcomposer.org/installer | php && ./composer.phar install --dev
|
|
||||||
|
|
||||||
Guzzle is unit tested with PHPUnit. You will need to create your own phpunit.xml file in order to run the unit tests
|
|
||||||
(or just copy phpunit.xml.dist to phpunit.xml). Run the tests using the vendored PHPUnit binary:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
vendor/bin/phpunit
|
|
||||||
|
|
||||||
You'll need to install node.js v0.5.0 or newer in order to test the cURL implementation.
|
|
||||||
|
|
||||||
Framework integrations
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Using Guzzle with Symfony
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Bundles are available on GitHub:
|
|
||||||
|
|
||||||
- `DdeboerGuzzleBundle <https://github.com/ddeboer/GuzzleBundle>`_ for Guzzle 2
|
|
||||||
- `MisdGuzzleBundle <https://github.com/misd-service-development/guzzle-bundle>`_ for Guzzle 3
|
|
||||||
|
|
||||||
Using Guzzle with Silex
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A `Guzzle Silex service provider <https://github.com/guzzle/guzzle-silex-extension>`_ is available on GitHub.
|
|
@ -1,85 +0,0 @@
|
|||||||
=================
|
|
||||||
Welcome to Guzzle
|
|
||||||
=================
|
|
||||||
|
|
||||||
What is Guzzle?
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Guzzle is a PHP HTTP client and framework for building web service clients. Guzzle takes the pain out of sending HTTP
|
|
||||||
requests and the redundancy out of creating web service clients.
|
|
||||||
|
|
||||||
Features at a glance
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
- All the power of cURL with a simple interface.
|
|
||||||
- Persistent connections and parallel requests.
|
|
||||||
- Streams request and response bodies
|
|
||||||
- Service descriptions for quickly building clients.
|
|
||||||
- Powered by the Symfony2 EventDispatcher.
|
|
||||||
- Use all of the code or only specific components.
|
|
||||||
- Plugins for caching, logging, OAuth, mocks, and more
|
|
||||||
- Includes a custom node.js webserver to test your clients.
|
|
||||||
- Service descriptions for defining the inputs and outputs of an API
|
|
||||||
- Resource iterators for traversing paginated resources
|
|
||||||
- Batching for sending a large number of requests as efficiently as possible
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Really simple using a static facade
|
|
||||||
Guzzle\Http\StaticClient::mount();
|
|
||||||
$response = Guzzle::get('http://guzzlephp.org');
|
|
||||||
|
|
||||||
// More control using a client class
|
|
||||||
$client = new \Guzzle\Http\Client('http://guzzlephp.org');
|
|
||||||
$request = $client->get('/');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Licensed using the `MIT license <http://opensource.org/licenses/MIT>`_.
|
|
||||||
|
|
||||||
Copyright (c) 2013 Michael Dowling <https://github.com/mtdowling>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Contributing
|
|
||||||
------------
|
|
||||||
|
|
||||||
Guidelines
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
This is still a work in progress, but there are only a few rules:
|
|
||||||
|
|
||||||
1. Guzzle follows PSR-0, PSR-1, and PSR-2
|
|
||||||
2. All pull requests must include unit tests to ensure the change works as expected and to prevent future regressions
|
|
||||||
|
|
||||||
Reporting a security vulnerability
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
We want to ensure that Guzzle is a secure HTTP client library for everyone. If you've discovered a security
|
|
||||||
vulnerability in Guzzle, we appreciate your help in disclosing it to us in a
|
|
||||||
`responsible manner <http://en.wikipedia.org/wiki/Responsible_disclosure>`_.
|
|
||||||
|
|
||||||
Publicly disclosing a vulnerability can put the entire community at risk. If you've discovered a security concern,
|
|
||||||
please email us at security@guzzlephp.org. We'll work with you to make sure that we understand the scope of the issue,
|
|
||||||
and that we fully address your concern. We consider correspondence sent to security@guzzlephp.org our highest priority,
|
|
||||||
and work to address any issues that arise as quickly as possible.
|
|
||||||
|
|
||||||
After a security vulnerability has been corrected, a security hotfix release will be deployed as soon as possible.
|
|
@ -1,569 +0,0 @@
|
|||||||
======================
|
|
||||||
The Guzzle HTTP client
|
|
||||||
======================
|
|
||||||
|
|
||||||
Guzzle gives PHP developers complete control over HTTP requests while utilizing HTTP/1.1 best practices. Guzzle's HTTP
|
|
||||||
functionality is a robust framework built on top of the `PHP libcurl bindings <http://www.php.net/curl>`_.
|
|
||||||
|
|
||||||
The three main parts of the Guzzle HTTP client are:
|
|
||||||
|
|
||||||
+--------------+-------------------------------------------------------------------------------------------------------+
|
|
||||||
| Clients | ``Guzzle\Http\Client`` (creates and sends requests, associates a response with a request) |
|
|
||||||
+--------------+-------------------------------------------------------------------------------------------------------+
|
|
||||||
| Requests | ``Guzzle\Http\Message\Request`` (requests with no body), |
|
|
||||||
| | ``Guzzle\Http\Message\EntityEnclosingRequest`` (requests with a body) |
|
|
||||||
+--------------+-------------------------------------------------------------------------------------------------------+
|
|
||||||
| Responses | ``Guzzle\Http\Message\Response`` |
|
|
||||||
+--------------+-------------------------------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
Creating a Client
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Clients create requests, send requests, and set responses on a request object. When instantiating a client object,
|
|
||||||
you can pass an optional "base URL" and optional array of configuration options. A base URL is a
|
|
||||||
:doc:`URI template <uri-templates>` that contains the URL of a remote server. When creating requests with a relative
|
|
||||||
URL, the base URL of a client will be merged into the request's URL.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
// Create a client and provide a base URL
|
|
||||||
$client = new Client('https://api.github.com');
|
|
||||||
|
|
||||||
$request = $client->get('/user');
|
|
||||||
$request->setAuth('user', 'pass');
|
|
||||||
echo $request->getUrl();
|
|
||||||
// >>> https://api.github.com/user
|
|
||||||
|
|
||||||
// You must send a request in order for the transfer to occur
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
echo $response->getBody();
|
|
||||||
// >>> {"type":"User", ...
|
|
||||||
|
|
||||||
echo $response->getHeader('Content-Length');
|
|
||||||
// >>> 792
|
|
||||||
|
|
||||||
$data = $response->json();
|
|
||||||
echo $data['type'];
|
|
||||||
// >>> User
|
|
||||||
|
|
||||||
Base URLs
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
Notice that the URL provided to the client's ``get()`` method is relative. Relative URLs will always merge into the
|
|
||||||
base URL of the client. There are a few rules that control how the URLs are merged.
|
|
||||||
|
|
||||||
.. tip::
|
|
||||||
|
|
||||||
Guzzle follows `RFC 3986 <http://tools.ietf.org/html/rfc3986#section-5.2>`_ when merging base URLs and
|
|
||||||
relative URLs.
|
|
||||||
|
|
||||||
In the above example, we passed ``/user`` to the ``get()`` method of the client. This is a relative URL, so it will
|
|
||||||
merge into the base URL of the client-- resulting in the derived URL of ``https://api.github.com/users``.
|
|
||||||
|
|
||||||
``/user`` is a relative URL but uses an absolute path because it contains the leading slash. Absolute paths will
|
|
||||||
overwrite any existing path of the base URL. If an absolute path is provided (e.g. ``/path/to/something``), then the
|
|
||||||
path specified in the base URL of the client will be replaced with the absolute path, and the query string provided
|
|
||||||
by the relative URL will replace the query string of the base URL.
|
|
||||||
|
|
||||||
Omitting the leading slash and using relative paths will add to the path of the base URL of the client. So using a
|
|
||||||
client base URL of ``https://api.twitter.com/v1.1`` and creating a GET request with ``statuses/user_timeline.json``
|
|
||||||
will result in a URL of ``https://api.twitter.com/v1.1/statuses/user_timeline.json``. If a relative path and a query
|
|
||||||
string are provided, then the relative path will be appended to the base URL path, and the query string provided will
|
|
||||||
be merged into the query string of the base URL.
|
|
||||||
|
|
||||||
If an absolute URL is provided (e.g. ``http://httpbin.org/ip``), then the request will completely use the absolute URL
|
|
||||||
as-is without merging in any of the URL parts specified in the base URL.
|
|
||||||
|
|
||||||
Configuration options
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The second argument of the client's constructor is an array of configuration data. This can include URI template data
|
|
||||||
or special options that alter the client's behavior:
|
|
||||||
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
| ``request.options`` | Associative array of :ref:`Request options <request-options>` to apply to every |
|
|
||||||
| | request created by the client. |
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
| ``redirect.disable`` | Disable HTTP redirects for every request created by the client. |
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
| ``curl.options`` | Associative array of cURL options to apply to every request created by the client. |
|
|
||||||
| | if either the key or value of an entry in the array is a string, Guzzle will |
|
|
||||||
| | attempt to find a matching defined cURL constant automatically (e.g. |
|
|
||||||
| | "CURLOPT_PROXY" will be converted to the constant ``CURLOPT_PROXY``). |
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
| ``ssl.certificate_authority`` | Set to true to use the Guzzle bundled SSL certificate bundle (this is used by |
|
|
||||||
| | default, 'system' to use the bundle on your system, a string pointing to a file to |
|
|
||||||
| | use a specific certificate file, a string pointing to a directory to use multiple |
|
|
||||||
| | certificates, or ``false`` to disable SSL validation (not recommended). |
|
|
||||||
| | |
|
|
||||||
| | When using Guzzle inside of a phar file, the bundled SSL certificate will be |
|
|
||||||
| | extracted to your system's temp folder, and each time a client is created an MD5 |
|
|
||||||
| | check will be performed to ensure the integrity of the certificate. |
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
| ``command.params`` | When using a ``Guzzle\Service\Client`` object, this is an associative array of |
|
|
||||||
| | default options to set on each command created by the client. |
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
Here's an example showing how to set various configuration options, including default headers to send with each request,
|
|
||||||
default query string parameters to add to each request, a default auth scheme for each request, and a proxy to use for
|
|
||||||
each request. Values can be injected into the client's base URL using variables from the configuration array.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
$client = new Client('https://api.twitter.com/{version}', array(
|
|
||||||
'version' => 'v1.1',
|
|
||||||
'request.options' => array(
|
|
||||||
'headers' => array('Foo' => 'Bar'),
|
|
||||||
'query' => array('testing' => '123'),
|
|
||||||
'auth' => array('username', 'password', 'Basic|Digest|NTLM|Any'),
|
|
||||||
'proxy' => 'tcp://localhost:80'
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
Setting a custom User-Agent
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The default Guzzle User-Agent header is ``Guzzle/<Guzzle_Version> curl/<curl_version> PHP/<PHP_VERSION>``. You can
|
|
||||||
customize the User-Agent header of a client by calling the ``setUserAgent()`` method of a Client object.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Completely override the default User-Agent
|
|
||||||
$client->setUserAgent('Test/123');
|
|
||||||
|
|
||||||
// Prepend a string to the default User-Agent
|
|
||||||
$client->setUserAgent('Test/123', true);
|
|
||||||
|
|
||||||
Creating requests with a client
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
A Client object exposes several methods used to create Request objects:
|
|
||||||
|
|
||||||
* Create a custom HTTP request: ``$client->createRequest($method, $uri, array $headers, $body, $options)``
|
|
||||||
* Create a GET request: ``$client->get($uri, array $headers, $options)``
|
|
||||||
* Create a HEAD request: ``$client->head($uri, array $headers, $options)``
|
|
||||||
* Create a DELETE request: ``$client->delete($uri, array $headers, $body, $options)``
|
|
||||||
* Create a POST request: ``$client->post($uri, array $headers, $postBody, $options)``
|
|
||||||
* Create a PUT request: ``$client->put($uri, array $headers, $body, $options)``
|
|
||||||
* Create a PATCH request: ``$client->patch($uri, array $headers, $body, $options)``
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
$client = new Client('http://baseurl.com/api/v1');
|
|
||||||
|
|
||||||
// Create a GET request using Relative to base URL
|
|
||||||
// URL of the request: http://baseurl.com/api/v1/path?query=123&value=abc)
|
|
||||||
$request = $client->get('path?query=123&value=abc');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Create HEAD request using a relative URL with an absolute path
|
|
||||||
// URL of the request: http://baseurl.com/path?query=123&value=abc
|
|
||||||
$request = $client->head('/path?query=123&value=abc');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Create a DELETE request using an absolute URL
|
|
||||||
$request = $client->delete('http://www.example.com/path?query=123&value=abc');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Create a PUT request using the contents of a PHP stream as the body
|
|
||||||
// Specify custom HTTP headers
|
|
||||||
$request = $client->put('http://www.example.com/upload', array(
|
|
||||||
'X-Header' => 'My Header'
|
|
||||||
), fopen('http://www.test.com/', 'r'));
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Create a POST request and add the POST files manually
|
|
||||||
$request = $client->post('http://localhost:8983/solr/update')
|
|
||||||
->addPostFiles(array('file' => '/path/to/documents.xml'));
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Check if a resource supports the DELETE method
|
|
||||||
$supportsDelete = $client->options('/path')->send()->isMethodAllowed('DELETE');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
Client objects create Request objects using a request factory (``Guzzle\Http\Message\RequestFactoryInterface``).
|
|
||||||
You can inject a custom request factory into the Client using ``$client->setRequestFactory()``, but you can typically
|
|
||||||
rely on a Client's default request factory.
|
|
||||||
|
|
||||||
Static clients
|
|
||||||
--------------
|
|
||||||
|
|
||||||
You can use Guzzle's static client facade to more easily send simple HTTP requests.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Mount the client so that you can access it at \Guzzle
|
|
||||||
Guzzle\Http\StaticClient::mount();
|
|
||||||
$response = Guzzle::get('http://guzzlephp.org');
|
|
||||||
|
|
||||||
Each request method of the static client (e.g. ``get()``, ``post()`, ``put()``, etc) accepts an associative array of request
|
|
||||||
options to apply to the request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$response = Guzzle::post('http://test.com', array(
|
|
||||||
'headers' => array('X-Foo' => 'Bar'),
|
|
||||||
'body' => array('Test' => '123'),
|
|
||||||
'timeout' => 10
|
|
||||||
));
|
|
||||||
|
|
||||||
.. _request-options:
|
|
||||||
|
|
||||||
Request options
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Request options can be specified when creating a request or in the ``request.options`` parameter of a client. These
|
|
||||||
options can control various aspects of a request including: headers to send, query string data, where the response
|
|
||||||
should be downloaded, proxies, auth, etc.
|
|
||||||
|
|
||||||
headers
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
Associative array of headers to apply to the request. When specified in the ``$options`` argument of a client creational
|
|
||||||
method (e.g. ``get()``, ``post()``, etc), the headers in the ``$options`` array will overwrite headers specified in the
|
|
||||||
``$headers`` array.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, array(), array(
|
|
||||||
'headers' => array('X-Foo' => 'Bar')
|
|
||||||
));
|
|
||||||
|
|
||||||
Headers can be specified on a client to add default headers to every request sent by a client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client();
|
|
||||||
|
|
||||||
// Set a single header using path syntax
|
|
||||||
$client->setDefaultOption('headers/X-Foo', 'Bar');
|
|
||||||
|
|
||||||
// Set all headers
|
|
||||||
$client->setDefaultOption('headers', array('X-Foo' => 'Bar'));
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
In addition to setting request options when creating requests or using the ``setDefaultOption()`` method, any
|
|
||||||
default client request option can be set using a client's config object:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client->getConfig()->setPath('request.options/headers/X-Foo', 'Bar');
|
|
||||||
|
|
||||||
query
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
Associative array of query string parameters to the request. When specified in the ``$options`` argument of a client
|
|
||||||
creational method, the query string parameters in the ``$options`` array will overwrite query string parameters
|
|
||||||
specified in the `$url`.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, array(), array(
|
|
||||||
'query' => array('abc' => '123')
|
|
||||||
));
|
|
||||||
|
|
||||||
Query string parameters can be specified on a client to add default query string parameters to every request sent by a
|
|
||||||
client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client();
|
|
||||||
|
|
||||||
// Set a single query string parameter using path syntax
|
|
||||||
$client->setDefaultOption('query/abc', '123');
|
|
||||||
|
|
||||||
// Set an array of default query string parameters
|
|
||||||
$client->setDefaultOption('query', array('abc' => '123'));
|
|
||||||
|
|
||||||
body
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
Sets the body of a request. The value supplied to the body option can be a ``Guzzle\Http\EntityBodyInterface``, string,
|
|
||||||
fopen resource, or array when sending POST requests. When a ``body`` request option is supplied, the option value will
|
|
||||||
overwrite the ``$body`` argument of a client creational method.
|
|
||||||
|
|
||||||
auth
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
Specifies and array of HTTP authorization parameters parameters to use with the request. The array must contain the
|
|
||||||
username in index [0], the password in index [1], and can optionally contain the authentication type in index [2].
|
|
||||||
The available authentication types are: "Basic" (default), "Digest", "NTLM", or "Any".
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, array(), array(
|
|
||||||
'auth' => array('username', 'password', 'Digest')
|
|
||||||
));
|
|
||||||
|
|
||||||
// You can add auth headers to every request of a client
|
|
||||||
$client->setDefaultOption('auth', array('username', 'password', 'Digest'));
|
|
||||||
|
|
||||||
cookies
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
Specifies an associative array of cookies to add to the request.
|
|
||||||
|
|
||||||
allow_redirects
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Specifies whether or not the request should follow redirects. Requests will follow redirects by default. Set
|
|
||||||
``allow_redirects`` to ``false`` to disable redirects.
|
|
||||||
|
|
||||||
save_to
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
The ``save_to`` option specifies where the body of a response is downloaded. You can pass the path to a file, an fopen
|
|
||||||
resource, or a ``Guzzle\Http\EntityBodyInterface`` object.
|
|
||||||
|
|
||||||
See :ref:`Changing where a response is downloaded <request-set-response-body>` for more information on setting the
|
|
||||||
`save_to` option.
|
|
||||||
|
|
||||||
events
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
The `events` option makes it easy to attach listeners to the various events emitted by a request object. The `events`
|
|
||||||
options must be an associative array mapping an event name to a Closure or array the contains a Closure and the
|
|
||||||
priority of the event.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, array(), array(
|
|
||||||
'events' => array(
|
|
||||||
'request.before_send' => function (\Guzzle\Common\Event $e) {
|
|
||||||
echo 'About to send ' . $e['request'];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Using the static client:
|
|
||||||
Guzzle::get($url, array(
|
|
||||||
'events' => array(
|
|
||||||
'request.before_send' => function (\Guzzle\Common\Event $e) {
|
|
||||||
echo 'About to send ' . $e['request'];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
plugins
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
The `plugins` options makes it easy to attach an array of plugins to a request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Using the static client:
|
|
||||||
Guzzle::get($url, array(
|
|
||||||
'plugins' => array(
|
|
||||||
new Guzzle\Plugin\Cache\CachePlugin(),
|
|
||||||
new Guzzle\Plugin\Cookie\CookiePlugin()
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
exceptions
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
The `exceptions` option can be used to disable throwing exceptions for unsuccessful HTTP response codes
|
|
||||||
(e.g. 404, 500, etc). Set `exceptions` to false to not throw exceptions.
|
|
||||||
|
|
||||||
params
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
The `params` options can be used to specify an associative array of data parameters to add to a request. Note that
|
|
||||||
these are not query string parameters.
|
|
||||||
|
|
||||||
timeout / connect_timeout
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can specify the maximum number of seconds to allow for an entire transfer to take place before timing out using
|
|
||||||
the `timeout` request option. You can specify the maximum number of seconds to wait while trying to connect using the
|
|
||||||
`connect_timeout` request option. Set either of these options to 0 to wait indefinitely.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('http://www.example.com', array(), array(
|
|
||||||
'timeout' => 20,
|
|
||||||
'connect_timeout' => 1.5
|
|
||||||
));
|
|
||||||
|
|
||||||
verify
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
Set to true to enable SSL certificate validation (the default), false to disable SSL certificate validation, or supply
|
|
||||||
the path to a CA bundle to enable verification using a custom certificate.
|
|
||||||
|
|
||||||
cert
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
The `cert` option lets you specify a PEM formatted SSL client certificate to use with servers that require one. If the
|
|
||||||
certificate requires a password, provide an array with the password as the second item.
|
|
||||||
|
|
||||||
This would typically be used in conjunction with the `ssl_key` option.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('https://www.example.com', array(), array(
|
|
||||||
'cert' => '/etc/pki/client_certificate.pem'
|
|
||||||
)
|
|
||||||
|
|
||||||
$request = $client->get('https://www.example.com', array(), array(
|
|
||||||
'cert' => array('/etc/pki/client_certificate.pem', 's3cr3tp455w0rd')
|
|
||||||
)
|
|
||||||
|
|
||||||
ssl_key
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
The `ssl_key` option lets you specify a file containing your PEM formatted private key, optionally protected by a password.
|
|
||||||
Note: your password is sensitive, keep the PHP script containing it safe.
|
|
||||||
|
|
||||||
This would typically be used in conjunction with the `cert` option.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('https://www.example.com', array(), array(
|
|
||||||
'ssl_key' => '/etc/pki/private_key.pem'
|
|
||||||
)
|
|
||||||
|
|
||||||
$request = $client->get('https://www.example.com', array(), array(
|
|
||||||
'ssl_key' => array('/etc/pki/private_key.pem', 's3cr3tp455w0rd')
|
|
||||||
)
|
|
||||||
|
|
||||||
proxy
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
The `proxy` option is used to specify an HTTP proxy (e.g. `http://username:password@192.168.16.1:10`).
|
|
||||||
|
|
||||||
debug
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
The `debug` option is used to show verbose cURL output for a transfer.
|
|
||||||
|
|
||||||
stream
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
When using a static client, you can set the `stream` option to true to return a `Guzzle\Stream\Stream` object that can
|
|
||||||
be used to pull data from a stream as needed (rather than have cURL download the entire contents of a response to a
|
|
||||||
stream all at once).
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$stream = Guzzle::get('http://guzzlephp.org', array('stream' => true));
|
|
||||||
while (!$stream->feof()) {
|
|
||||||
echo $stream->readLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
Sending requests
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Requests can be sent by calling the ``send()`` method of a Request object, but you can also send requests using the
|
|
||||||
``send()`` method of a Client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('http://www.amazon.com');
|
|
||||||
$response = $client->send($request);
|
|
||||||
|
|
||||||
Sending requests in parallel
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The Client's ``send()`` method accept a single ``Guzzle\Http\Message\RequestInterface`` object or an array of
|
|
||||||
RequestInterface objects. When an array is specified, the requests will be sent in parallel.
|
|
||||||
|
|
||||||
Sending many HTTP requests serially (one at a time) can cause an unnecessary delay in a script's execution. Each
|
|
||||||
request must complete before a subsequent request can be sent. By sending requests in parallel, a pool of HTTP
|
|
||||||
requests can complete at the speed of the slowest request in the pool, significantly reducing the amount of time
|
|
||||||
needed to execute multiple HTTP requests. Guzzle provides a wrapper for the curl_multi functions in PHP.
|
|
||||||
|
|
||||||
Here's an example of sending three requests in parallel using a client object:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Exception\MultiTransferException;
|
|
||||||
|
|
||||||
try {
|
|
||||||
$responses = $client->send(array(
|
|
||||||
$client->get('http://www.google.com/'),
|
|
||||||
$client->head('http://www.google.com/'),
|
|
||||||
$client->get('https://www.github.com/')
|
|
||||||
));
|
|
||||||
} catch (MultiTransferException $e) {
|
|
||||||
|
|
||||||
echo "The following exceptions were encountered:\n";
|
|
||||||
foreach ($e as $exception) {
|
|
||||||
echo $exception->getMessage() . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "The following requests failed:\n";
|
|
||||||
foreach ($e->getFailedRequests() as $request) {
|
|
||||||
echo $request . "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "The following requests succeeded:\n";
|
|
||||||
foreach ($e->getSuccessfulRequests() as $request) {
|
|
||||||
echo $request . "\n\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
If the requests succeed, an array of ``Guzzle\Http\Message\Response`` objects are returned. A single request failure
|
|
||||||
will not cause the entire pool of requests to fail. Any exceptions thrown while transferring a pool of requests will
|
|
||||||
be aggregated into a ``Guzzle\Common\Exception\MultiTransferException`` exception.
|
|
||||||
|
|
||||||
Plugins and events
|
|
||||||
------------------
|
|
||||||
|
|
||||||
Guzzle provides easy to use request plugins that add behavior to requests based on signal slot event notifications
|
|
||||||
powered by the
|
|
||||||
`Symfony2 Event Dispatcher component <http://symfony.com/doc/2.0/components/event_dispatcher/introduction.html>`_. Any
|
|
||||||
event listener or subscriber attached to a Client object will automatically be attached to each request created by the
|
|
||||||
client.
|
|
||||||
|
|
||||||
Using the same cookie session for each request
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Attach a ``Guzzle\Plugin\Cookie\CookiePlugin`` to a client which will in turn add support for cookies to every request
|
|
||||||
created by a client, and each request will use the same cookie session:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Plugin\Cookie\CookiePlugin;
|
|
||||||
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
|
|
||||||
|
|
||||||
// Create a new cookie plugin
|
|
||||||
$cookiePlugin = new CookiePlugin(new ArrayCookieJar());
|
|
||||||
|
|
||||||
// Add the cookie plugin to the client
|
|
||||||
$client->addSubscriber($cookiePlugin);
|
|
||||||
|
|
||||||
.. _client-events:
|
|
||||||
|
|
||||||
Events emitted from a client
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A ``Guzzle\Http\Client`` object emits the following events:
|
|
||||||
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| Event name | Description | Event data |
|
|
||||||
+==============================+============================================+==========================================+
|
|
||||||
| client.create_request | Called when a client creates a request | * client: The client |
|
|
||||||
| | | * request: The created request |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
$client = new Client();
|
|
||||||
|
|
||||||
// Add a listener that will echo out requests as they are created
|
|
||||||
$client->getEventDispatcher()->addListener('client.create_request', function (Event $e) {
|
|
||||||
echo 'Client object: ' . spl_object_hash($e['client']) . "\n";
|
|
||||||
echo "Request object: {$e['request']}\n";
|
|
||||||
});
|
|
@ -1,151 +0,0 @@
|
|||||||
===========================
|
|
||||||
Request and response bodies
|
|
||||||
===========================
|
|
||||||
|
|
||||||
`Entity body <http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html>`_ is the term used for the body of an HTTP
|
|
||||||
message. The entity body of requests and responses is inherently a
|
|
||||||
`PHP stream <http://php.net/manual/en/book.stream.php>`_ in Guzzle. The body of the request can be either a string or
|
|
||||||
a PHP stream which are converted into a ``Guzzle\Http\EntityBody`` object using its factory method. When using a
|
|
||||||
string, the entity body is stored in a `temp PHP stream <http://www.php.net/manual/en/wrappers.php.php>`_. The use of
|
|
||||||
temp PHP streams helps to protect your application from running out of memory when sending or receiving large entity
|
|
||||||
bodies in your messages. When more than 2MB of data is stored in a temp stream, it automatically stores the data on
|
|
||||||
disk rather than in memory.
|
|
||||||
|
|
||||||
EntityBody objects provide a great deal of functionality: compression, decompression, calculate the Content-MD5,
|
|
||||||
calculate the Content-Length (when the resource is repeatable), guessing the Content-Type, and more. Guzzle doesn't
|
|
||||||
need to load an entire entity body into a string when sending or retrieving data; entity bodies are streamed when
|
|
||||||
being uploaded and downloaded.
|
|
||||||
|
|
||||||
Here's an example of gzip compressing a text file then sending the file to a URL:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\EntityBody;
|
|
||||||
|
|
||||||
$body = EntityBody::factory(fopen('/path/to/file.txt', 'r+'));
|
|
||||||
echo $body->read(1024);
|
|
||||||
$body->seek(0, SEEK_END);
|
|
||||||
$body->write('foo');
|
|
||||||
echo $body->ftell();
|
|
||||||
$body->rewind();
|
|
||||||
|
|
||||||
// Send a request using the body
|
|
||||||
$response = $client->put('http://localhost:8080/uploads', null, $body)->send();
|
|
||||||
|
|
||||||
The body of the request can be specified in the ``Client::put()`` or ``Client::post()`` method, or, you can specify
|
|
||||||
the body of the request by calling the ``setBody()`` method of any
|
|
||||||
``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object.
|
|
||||||
|
|
||||||
Compression
|
|
||||||
-----------
|
|
||||||
|
|
||||||
You can compress the contents of an EntityBody object using the ``compress()`` method. The compress method accepts a
|
|
||||||
filter that must match to one of the supported
|
|
||||||
`PHP stream filters <http://www.php.net/manual/en/filters.compression.php>`_ on your system (e.g. `zlib.deflate`,
|
|
||||||
``bzip2.compress``, etc). Compressing an entity body will stream the entire entity body through a stream compression
|
|
||||||
filter into a temporary PHP stream. You can uncompress an entity body using the ``uncompress()`` method and passing
|
|
||||||
the PHP stream filter to use when decompressing the stream (e.g. ``zlib.inflate``).
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\EntityBody;
|
|
||||||
|
|
||||||
$body = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
|
|
||||||
echo $body->getSize();
|
|
||||||
// >>> 1048576
|
|
||||||
|
|
||||||
// Compress using the default zlib.deflate filter
|
|
||||||
$body->compress();
|
|
||||||
echo $body->getSize();
|
|
||||||
// >>> 314572
|
|
||||||
|
|
||||||
// Decompress the stream
|
|
||||||
$body->uncompress();
|
|
||||||
echo $body->getSize();
|
|
||||||
// >>> 1048576
|
|
||||||
|
|
||||||
Decorators
|
|
||||||
----------
|
|
||||||
|
|
||||||
Guzzle provides several EntityBody decorators that can be used to add functionality to an EntityBody at runtime.
|
|
||||||
|
|
||||||
IoEmittingEntityBody
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This decorator will emit events when data is read from a stream or written to a stream. Add an event subscriber to the
|
|
||||||
entity body's ``body.read`` or ``body.write`` methods to receive notifications when data data is transferred.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
use Guzzle\Http\EntityBody;
|
|
||||||
use Guzzle\Http\IoEmittingEntityBody;
|
|
||||||
|
|
||||||
$original = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
|
|
||||||
$body = new IoEmittingEntityBody($original);
|
|
||||||
|
|
||||||
// Listen for read events
|
|
||||||
$body->getEventDispatcher()->addListener('body.read', function (Event $e) {
|
|
||||||
// Grab data from the event
|
|
||||||
$entityBody = $e['body'];
|
|
||||||
// Amount of data retrieved from the body
|
|
||||||
$lengthOfData = $e['length'];
|
|
||||||
// The actual data that was read
|
|
||||||
$data = $e['read'];
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for write events
|
|
||||||
$body->getEventDispatcher()->addListener('body.write', function (Event $e) {
|
|
||||||
// Grab data from the event
|
|
||||||
$entityBody = $e['body'];
|
|
||||||
// The data that was written
|
|
||||||
$data = $e['write'];
|
|
||||||
// The actual amount of data that was written
|
|
||||||
$data = $e['read'];
|
|
||||||
});
|
|
||||||
|
|
||||||
ReadLimitEntityBody
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ReadLimitEntityBody decorator can be used to transfer a subset or slice of an existing EntityBody object. This can
|
|
||||||
be useful for breaking a large file into smaller pieces to be sent in chunks (e.g. Amazon S3's multipart upload API).
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\EntityBody;
|
|
||||||
use Guzzle\Http\ReadLimitEntityBody;
|
|
||||||
|
|
||||||
$original = EntityBody::factory(fopen('/tmp/test.txt', 'r+'));
|
|
||||||
echo $original->getSize();
|
|
||||||
// >>> 1048576
|
|
||||||
|
|
||||||
// Limit the size of the body to 1024 bytes and start reading from byte 2048
|
|
||||||
$body = new ReadLimitEntityBody($original, 1024, 2048);
|
|
||||||
echo $body->getSize();
|
|
||||||
// >>> 1024
|
|
||||||
echo $body->ftell();
|
|
||||||
// >>> 0
|
|
||||||
|
|
||||||
CachingEntityBody
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The CachingEntityBody decorator is used to allow seeking over previously read bytes on non-seekable read streams. This
|
|
||||||
can be useful when transferring a non-seekable entity body fails due to needing to rewind the stream (for example,
|
|
||||||
resulting from a redirect). Data that is read from the remote stream will be buffered in a PHP temp stream so that
|
|
||||||
previously read bytes are cached first in memory, then on disk.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\EntityBody;
|
|
||||||
use Guzzle\Http\CachingEntityBody;
|
|
||||||
|
|
||||||
$original = EntityBody::factory(fopen('http://www.google.com', 'r'));
|
|
||||||
$body = new CachingEntityBody($original);
|
|
||||||
|
|
||||||
$body->read(1024);
|
|
||||||
echo $body->ftell();
|
|
||||||
// >>> 1024
|
|
||||||
|
|
||||||
$body->seek(0);
|
|
||||||
echo $body->ftell();
|
|
||||||
// >>> 0
|
|
@ -1,99 +0,0 @@
|
|||||||
==============
|
|
||||||
HTTP redirects
|
|
||||||
==============
|
|
||||||
|
|
||||||
By default, Guzzle will automatically follow redirects using the non-RFC compliant implementation used by most web
|
|
||||||
browsers. This means that redirects for POST requests are followed by a GET request. You can force RFC compliance by
|
|
||||||
enabling the strict mode on a request's parameter object:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Set per request
|
|
||||||
$request = $client->post();
|
|
||||||
$request->getParams()->set('redirect.strict', true);
|
|
||||||
|
|
||||||
// You can set globally on a client so all requests use strict redirects
|
|
||||||
$client->getConfig()->set('request.params', array(
|
|
||||||
'redirect.strict' => true
|
|
||||||
));
|
|
||||||
|
|
||||||
By default, Guzzle will redirect up to 5 times before throwing a ``Guzzle\Http\Exception\TooManyRedirectsException``.
|
|
||||||
You can raise or lower this value using the ``redirect.max`` parameter of a request object:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request->getParams()->set('redirect.max', 2);
|
|
||||||
|
|
||||||
Redirect history
|
|
||||||
----------------
|
|
||||||
|
|
||||||
You can get the number of redirects of a request using the resulting response object's ``getRedirectCount()`` method.
|
|
||||||
Similar to cURL's ``effective_url`` property, Guzzle provides the effective URL, or the last redirect URL that returned
|
|
||||||
the request, in a response's ``getEffectiveUrl()`` method.
|
|
||||||
|
|
||||||
When testing or debugging, it is often useful to see a history of redirects for a particular request. This can be
|
|
||||||
achieved using the HistoryPlugin.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('/');
|
|
||||||
$history = new Guzzle\Plugin\History\HistoryPlugin();
|
|
||||||
$request->addSubscriber($history);
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Get the last redirect URL or the URL of the request that received
|
|
||||||
// this response
|
|
||||||
echo $response->getEffectiveUrl();
|
|
||||||
|
|
||||||
// Get the number of redirects
|
|
||||||
echo $response->getRedirectCount();
|
|
||||||
|
|
||||||
// Iterate over each sent request and response
|
|
||||||
foreach ($history->getAll() as $transaction) {
|
|
||||||
// Request object
|
|
||||||
echo $transaction['request']->getUrl() . "\n";
|
|
||||||
// Response object
|
|
||||||
echo $transaction['response']->getEffectiveUrl() . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or, simply cast the HistoryPlugin to a string to view each request and response
|
|
||||||
echo $history;
|
|
||||||
|
|
||||||
Disabling redirects
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
You can disable redirects on a client by passing a configuration option in the client's constructor:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Client(null, array('redirect.disable' => true));
|
|
||||||
|
|
||||||
You can also disable redirects per request:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, array(), array('allow_redirects' => false));
|
|
||||||
|
|
||||||
Redirects and non-repeatable streams
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
If you are redirected when sending data from a non-repeatable stream and some of the data has been read off of the
|
|
||||||
stream, then you will get a ``Guzzle\Http\Exception\CouldNotRewindStreamException``. You can get around this error by
|
|
||||||
adding a custom rewind method to the entity body object being sent in the request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post(
|
|
||||||
'http://httpbin.com/redirect/2',
|
|
||||||
null,
|
|
||||||
fopen('http://httpbin.com/get', 'r')
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add a custom function that can be used to rewind the stream
|
|
||||||
// (reopen in this example)
|
|
||||||
$request->getBody()->setRewindFunction(function ($body) {
|
|
||||||
$body->setStream(fopen('http://httpbin.com/get', 'r'));
|
|
||||||
return true;
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = $client->send();
|
|
@ -1,667 +0,0 @@
|
|||||||
=====================
|
|
||||||
Using Request objects
|
|
||||||
=====================
|
|
||||||
|
|
||||||
HTTP request messages
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Request objects are all about building an HTTP message. Each part of an HTTP request message can be set individually
|
|
||||||
using methods on the request object or set in bulk using the ``setUrl()`` method. Here's the format of an HTTP request
|
|
||||||
with each part of the request referencing the method used to change it::
|
|
||||||
|
|
||||||
PUT(a) /path(b)?query=123(c) HTTP/1.1(d)
|
|
||||||
X-Header(e): header
|
|
||||||
Content-Length(e): 4
|
|
||||||
|
|
||||||
data(f)
|
|
||||||
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| a. **Method** | The request method can only be set when instantiating a request |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| b. **Path** | ``$request->setPath('/path');`` |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| c. **Query** | ``$request->getQuery()->set('query', '123');`` |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| d. **Protocol version** | ``$request->setProtocolVersion('1.1');`` |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| e. **Header** | ``$request->setHeader('X-Header', 'header');`` |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| f. **Entity Body** | ``$request->setBody('data'); // Only available with PUT, POST, PATCH, DELETE`` |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
Creating requests with a client
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Client objects are responsible for creating HTTP request objects.
|
|
||||||
|
|
||||||
GET requests
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
`GET requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3>`_ are the most common form of HTTP
|
|
||||||
requests. When you visit a website in your browser, the HTML of the website is downloaded using a GET request. GET
|
|
||||||
requests are idempotent requests that are typically used to download content (an entity) identified by a request URL.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
|
|
||||||
$client = new Client();
|
|
||||||
|
|
||||||
// Create a request that has a query string and an X-Foo header
|
|
||||||
$request = $client->get('http://www.amazon.com?a=1', array('X-Foo' => 'Bar'));
|
|
||||||
|
|
||||||
// Send the request and get the response
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
You can change where the body of a response is downloaded on any request using the
|
|
||||||
``$request->setResponseBody(string|EntityBodyInterface|resource)`` method of a request. You can also set the ``save_to``
|
|
||||||
option of a request:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Send the response body to a file
|
|
||||||
$request = $client->get('http://test.com', array(), array('save_to' => '/path/to/file'));
|
|
||||||
|
|
||||||
// Send the response body to an fopen resource
|
|
||||||
$request = $client->get('http://test.com', array(), array('save_to' => fopen('/path/to/file', 'w')));
|
|
||||||
|
|
||||||
HEAD requests
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
`HEAD requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4>`_ work exactly like GET requests except
|
|
||||||
that they do not actually download the response body (entity) of the response message. HEAD requests are useful for
|
|
||||||
retrieving meta information about an entity identified by a Request-URI.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client();
|
|
||||||
$request = $client->head('http://www.amazon.com');
|
|
||||||
$response = $request->send();
|
|
||||||
echo $response->getContentLength();
|
|
||||||
// >>> Will output the Content-Length header value
|
|
||||||
|
|
||||||
DELETE requests
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A `DELETE method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7>`_ requests that the origin server
|
|
||||||
delete the resource identified by the Request-URI.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client();
|
|
||||||
$request = $client->delete('http://example.com');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
POST requests
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
While `POST requests <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5>`_ can be used for a number of
|
|
||||||
reasons, POST requests are often used when submitting HTML form data to a website. POST requests can include an entity
|
|
||||||
body in the HTTP request.
|
|
||||||
|
|
||||||
POST requests in Guzzle are sent with an ``application/x-www-form-urlencoded`` Content-Type header if POST fields are
|
|
||||||
present but no files are being sent in the POST. If files are specified in the POST request, then the Content-Type
|
|
||||||
header will become ``multipart/form-data``.
|
|
||||||
|
|
||||||
The ``post()`` method of a client object accepts four arguments: the URL, optional headers, post fields, and an array of
|
|
||||||
request options. To send files in the POST request, prepend the ``@`` symbol to the array value (just like you would if
|
|
||||||
you were using the PHP ``curl_setopt`` function).
|
|
||||||
|
|
||||||
Here's how to create a multipart/form-data POST request containing files and fields:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post('http://httpbin.org/post', array(), array(
|
|
||||||
'custom_field' => 'my custom value',
|
|
||||||
'file_field' => '@/path/to/file.xml'
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Remember to **always** sanitize user input when sending POST requests:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Prevent users from accessing sensitive files by sanitizing input
|
|
||||||
$_POST = array('firstname' => '@/etc/passwd');
|
|
||||||
$request = $client->post('http://www.example.com', array(), array (
|
|
||||||
'firstname' => str_replace('@', '', $_POST['firstname'])
|
|
||||||
));
|
|
||||||
|
|
||||||
You can alternatively build up the contents of a POST request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post('http://httpbin.org/post')
|
|
||||||
->setPostField('custom_field', 'my custom value')
|
|
||||||
->addPostFile('file', '/path/to/file.xml');
|
|
||||||
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
Raw POST data
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
POST requests can also contain raw POST data that is not related to HTML forms.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post('http://httpbin.org/post', array(), 'this is the body');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
You can set the body of POST request using the ``setBody()`` method of the
|
|
||||||
``Guzzle\Http\Message\EntityEnclosingRequest`` object. This method accepts a string, a resource returned from
|
|
||||||
``fopen``, or a ``Guzzle\Http\EntityBodyInterface`` object.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post('http://httpbin.org/post');
|
|
||||||
// Set the body of the POST to stream the contents of /path/to/large_body.txt
|
|
||||||
$request->setBody(fopen('/path/to/large_body.txt', 'r'));
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
PUT requests
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The `PUT method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6>`_ requests that the enclosed entity be
|
|
||||||
stored under the supplied Request-URI. PUT requests are similar to POST requests in that they both can send an entity
|
|
||||||
body in the request message.
|
|
||||||
|
|
||||||
The body of a PUT request (any any ``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object) is always stored as
|
|
||||||
a ``Guzzle\Http\Message\EntityBodyInterface`` object. This allows a great deal of flexibility when sending data to a
|
|
||||||
remote server. For example, you can stream the contents of a stream returned by fopen, stream the contents of a
|
|
||||||
callback function, or simply send a string of data.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->put('http://httpbin.org/put', array(), 'this is the body');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
Just like with POST, PATH, and DELETE requests, you can set the body of a PUT request using the ``setBody()`` method.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->put('http://httpbin.org/put');
|
|
||||||
$request->setBody(fopen('/path/to/large_body.txt', 'r'));
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
PATCH requests
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
`PATCH requests <http://tools.ietf.org/html/rfc5789>`_ are used to modify a resource.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->patch('http://httpbin.org', array(), 'this is the body');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
OPTIONS requests
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The `OPTIONS method <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2>`_ represents a request for
|
|
||||||
information about the communication options available on the request/response chain identified by the Request-URI.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->options('http://httpbin.org');
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
// Check if the PUT method is supported by this resource
|
|
||||||
var_export($response->isMethodAllows('PUT'));
|
|
||||||
|
|
||||||
Custom requests
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can create custom HTTP requests that use non-standard HTTP methods using the ``createRequest()`` method of a
|
|
||||||
client object.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->createRequest('COPY', 'http://example.com/foo', array(
|
|
||||||
'Destination' => 'http://example.com/bar',
|
|
||||||
'Overwrite' => 'T'
|
|
||||||
));
|
|
||||||
$response = $request->send();
|
|
||||||
|
|
||||||
Query string parameters
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Query string parameters of a request are owned by a request's ``Guzzle\Http\Query`` object that is accessible by
|
|
||||||
calling ``$request->getQuery()``. The Query class extends from ``Guzzle\Common\Collection`` and allows you to set one
|
|
||||||
or more query string parameters as key value pairs. You can set a parameter on a Query object using the
|
|
||||||
``set($key, $value)`` method or access the query string object like an associative array. Any previously specified
|
|
||||||
value for a key will be overwritten when using ``set()``. Use ``add($key, $value)`` to add a value to query string
|
|
||||||
object, and in the event of a collision with an existing value at a specific key, the value will be converted to an
|
|
||||||
array that contains all of the previously set values.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = new Guzzle\Http\Message\Request('GET', 'http://www.example.com?foo=bar&abc=123');
|
|
||||||
|
|
||||||
$query = $request->getQuery();
|
|
||||||
echo "{$query}\n";
|
|
||||||
// >>> foo=bar&abc=123
|
|
||||||
|
|
||||||
$query->remove('abc');
|
|
||||||
echo "{$query}\n";
|
|
||||||
// >>> foo=bar
|
|
||||||
|
|
||||||
$query->set('foo', 'baz');
|
|
||||||
echo "{$query}\n";
|
|
||||||
// >>> foo=baz
|
|
||||||
|
|
||||||
$query->add('foo', 'bar');
|
|
||||||
echo "{$query}\n";
|
|
||||||
// >>> foo%5B0%5D=baz&foo%5B1%5D=bar
|
|
||||||
|
|
||||||
Whoah! What happened there? When ``foo=bar`` was added to the existing ``foo=baz`` query string parameter, the
|
|
||||||
aggregator associated with the Query object was used to help convert multi-value query string parameters into a string.
|
|
||||||
Let's disable URL-encoding to better see what's happening.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$query->useUrlEncoding(false);
|
|
||||||
echo "{$query}\n";
|
|
||||||
// >>> foo[0]=baz&foo[1]=bar
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
URL encoding can be disabled by passing false, enabled by passing true, set to use RFC 1738 by passing
|
|
||||||
``Query::FORM_URLENCODED`` (internally uses PHP's ``urlencode`` function), or set to RFC 3986 by passing
|
|
||||||
``Query::RFC_3986`` (this is the default and internally uses PHP's ``rawurlencode`` function).
|
|
||||||
|
|
||||||
As you can see, the multiple values were converted into query string parameters following the default PHP convention of
|
|
||||||
adding numerically indexed square bracket suffixes to each key (``foo[0]=baz&foo[1]=bar``). The strategy used to convert
|
|
||||||
multi-value parameters into a string can be customized using the ``setAggregator()`` method of the Query class. Guzzle
|
|
||||||
ships with the following query string aggregators by default:
|
|
||||||
|
|
||||||
1. ``Guzzle\Http\QueryAggregator\PhpAggregator``: Aggregates using PHP style brackets (e.g. ``foo[0]=baz&foo[1]=bar``)
|
|
||||||
2. ``Guzzle\Http\QueryAggregator\DuplicateAggregator``: Performs no aggregation and allows for key value pairs to be
|
|
||||||
repeated in a URL (e.g. ``foo=baz&foo=bar``)
|
|
||||||
3. ``Guzzle\Http\QueryAggregator\CommaAggregator``: Aggregates using commas (e.g. ``foo=baz,bar``)
|
|
||||||
|
|
||||||
.. _http-message-headers:
|
|
||||||
|
|
||||||
HTTP Message Headers
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
HTTP message headers are case insensitive, multiple occurrences of any header can be present in an HTTP message
|
|
||||||
(whether it's valid or not), and some servers require specific casing of particular headers. Because of this, request
|
|
||||||
and response headers are stored in ``Guzzle\Http\Message\Header`` objects. The Header object can be cast as a string,
|
|
||||||
counted, or iterated to retrieve each value from the header. Casting a Header object to a string will return all of
|
|
||||||
the header values concatenated together using a glue string (typically ", ").
|
|
||||||
|
|
||||||
A request (and response) object have several methods that allow you to retrieve and modify headers.
|
|
||||||
|
|
||||||
* ``getHeaders()``: Get all of the headers of a message as a ``Guzzle\Http\Message\Header\HeaderCollection`` object.
|
|
||||||
* ``getHeader($header)``: Get a specific header from a message. If the header exists, you'll get a
|
|
||||||
``Guzzle\Http\Message\Header`` object. If the header does not exist, this methods returns ``null``.
|
|
||||||
* ``hasHeader($header)``: Returns true or false based on if the message has a particular header.
|
|
||||||
* ``setHeader($header, $value)``: Set a header value and overwrite any previously set value for this header.
|
|
||||||
* ``addHeader($header, $value)``: Add a header with a particular name. If a previous value was already set by the same,
|
|
||||||
then the header will contain multiple values.
|
|
||||||
* ``removeHeader($header)``: Remove a header by name from the message.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = new Request('GET', 'http://httpbin.com/cookies');
|
|
||||||
// addHeader will set and append to any existing header values
|
|
||||||
$request->addHeader('Foo', 'bar');
|
|
||||||
$request->addHeader('foo', 'baz');
|
|
||||||
// setHeader overwrites any existing values
|
|
||||||
$request->setHeader('Test', '123');
|
|
||||||
|
|
||||||
// Request headers can be cast as a string
|
|
||||||
echo $request->getHeader('Foo');
|
|
||||||
// >>> bar, baz
|
|
||||||
echo $request->getHeader('Test');
|
|
||||||
// >>> 123
|
|
||||||
|
|
||||||
// You can count the number of headers of a particular case insensitive name
|
|
||||||
echo count($request->getHeader('foO'));
|
|
||||||
// >>> 2
|
|
||||||
|
|
||||||
// You can iterate over Header objects
|
|
||||||
foreach ($request->getHeader('foo') as $header) {
|
|
||||||
echo $header . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// You can get all of the request headers as a Guzzle\Http\Message\Header\HeaderCollection object
|
|
||||||
$headers = $request->getHeaders();
|
|
||||||
|
|
||||||
// Missing headers return NULL
|
|
||||||
var_export($request->getHeader('Missing'));
|
|
||||||
// >>> null
|
|
||||||
|
|
||||||
// You can see all of the different variations of a header by calling raw() on the Header
|
|
||||||
var_export($request->getHeader('foo')->raw());
|
|
||||||
|
|
||||||
Setting the body of a request
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
Requests that can send a body (e.g. PUT, POST, DELETE, PATCH) are instances of
|
|
||||||
``Guzzle\Http\Message\EntityEnclosingRequestInterface``. Entity enclosing requests contain several methods that allow
|
|
||||||
you to specify the body to send with a request.
|
|
||||||
|
|
||||||
Use the ``setBody()`` method of a request to set the body that will be sent with a request. This method accepts a
|
|
||||||
string, a resource returned by ``fopen()``, an array, or an instance of ``Guzzle\Http\EntityBodyInterface``. The body
|
|
||||||
will then be streamed from the underlying ``EntityBodyInterface`` object owned by the request. When setting the body
|
|
||||||
of the request, you can optionally specify a Content-Type header and whether or not to force the request to use
|
|
||||||
chunked Transfer-Encoding.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->put('/user.json');
|
|
||||||
$request->setBody('{"foo":"baz"}', 'application/json');
|
|
||||||
|
|
||||||
Content-Type header
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Guzzle will automatically add a Content-Type header to a request if the Content-Type can be guessed based on the file
|
|
||||||
extension of the payload being sent or the file extension present in the path of a request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->put('/user.json', array(), '{"foo":"bar"}');
|
|
||||||
// The Content-Type was guessed based on the path of the request
|
|
||||||
echo $request->getHeader('Content-Type');
|
|
||||||
// >>> application/json
|
|
||||||
|
|
||||||
$request = $client->put('/user.json');
|
|
||||||
$request->setBody(fopen('/tmp/user_data.json', 'r'));
|
|
||||||
// The Content-Type was guessed based on the path of the entity body
|
|
||||||
echo $request->getHeader('Content-Type');
|
|
||||||
// >>> application/json
|
|
||||||
|
|
||||||
Transfer-Encoding: chunked header
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
When sending HTTP requests that contain a payload, you must let the remote server know how to determine when the entire
|
|
||||||
message has been sent. This usually is done by supplying a ``Content-Length`` header that tells the origin server the
|
|
||||||
size of the body that is to be sent. In some cases, the size of the payload being sent in a request cannot be known
|
|
||||||
before initiating the transfer. In these cases (when using HTTP/1.1), you can use the ``Transfer-Encoding: chunked``
|
|
||||||
header.
|
|
||||||
|
|
||||||
If the Content-Length cannot be determined (i.e. using a PHP ``http://`` stream), then Guzzle will automatically add
|
|
||||||
the ``Transfer-Encoding: chunked`` header to the request.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->put('/user.json');
|
|
||||||
$request->setBody(fopen('http://httpbin.org/get', 'r'));
|
|
||||||
|
|
||||||
// The Content-Length could not be determined
|
|
||||||
echo $request->getHeader('Transfer-Encoding');
|
|
||||||
// >>> chunked
|
|
||||||
|
|
||||||
See :doc:`/http-client/entity-bodies` for more information on entity bodies.
|
|
||||||
|
|
||||||
Expect: 100-Continue header
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``Expect: 100-Continue`` header is used to help a client prevent sending a large payload to a server that will
|
|
||||||
reject the request. This allows clients to fail fast rather than waste bandwidth sending an erroneous payload. Guzzle
|
|
||||||
will automatically add the ``Expect: 100-Continue`` header to a request when the size of the payload exceeds 1MB or if
|
|
||||||
the body of the request is not seekable (this helps to prevent errors when a non-seekable body request is redirected).
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If you find that your larger requests are taking too long to complete, you should first check if the
|
|
||||||
``Expect: 100-Continue`` header is being sent with the request. Some servers do not respond well to this header,
|
|
||||||
which causes cURL to sleep for `1 second <http://curl.haxx.se/mail/lib-2010-01/0182.html>`_.
|
|
||||||
|
|
||||||
POST fields and files
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Any entity enclosing request can send POST style fields and files. This includes POST, PUT, PATCH, and DELETE requests.
|
|
||||||
Any request that has set POST fields or files will use cURL's POST message functionality.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->post('/post');
|
|
||||||
// Set an overwrite any previously specified value
|
|
||||||
$request->setPostField('foo', 'bar');
|
|
||||||
// Append a value to any existing values
|
|
||||||
$request->getPostFields()->add('foo', 'baz');
|
|
||||||
// Remove a POST field by name
|
|
||||||
$request->removePostField('fizz');
|
|
||||||
|
|
||||||
// Add a file to upload (forces multipart/form-data)
|
|
||||||
$request->addPostFile('my_file', '/path/to/file', 'plain/text');
|
|
||||||
// Remove a POST file by POST key name
|
|
||||||
$request->removePostFile('my_other_file');
|
|
||||||
|
|
||||||
.. tip::
|
|
||||||
|
|
||||||
Adding a large number of POST fields to a POST request is faster if you use the ``addPostFields()`` method so that
|
|
||||||
you can add and process multiple fields with a single call. Adding multiple POST files is also faster using
|
|
||||||
``addPostFiles()``.
|
|
||||||
|
|
||||||
Working with cookies
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Cookies can be modified and retrieved from a request using the following methods:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request->addCookie($name, $value);
|
|
||||||
$request->removeCookie($name);
|
|
||||||
$value = $request->getCookie($name);
|
|
||||||
$valueArray = $request->getCookies();
|
|
||||||
|
|
||||||
Use the :doc:`cookie plugin </plugins/cookie-plugin>` if you need to reuse cookies between requests.
|
|
||||||
|
|
||||||
.. _request-set-response-body:
|
|
||||||
|
|
||||||
Changing where a response is downloaded
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
When a request is sent, the body of the response will be stored in a PHP temp stream by default. You can change the
|
|
||||||
location in which the response will be downloaded using ``$request->setResponseBody($body)`` or the ``save_to`` request
|
|
||||||
option. This can be useful for downloading the contents of a URL to a specific file.
|
|
||||||
|
|
||||||
Here's an example of using request options:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $this->client->get('http://example.com/large.mov', array(), array(
|
|
||||||
'save_to' => '/tmp/large_file.mov'
|
|
||||||
));
|
|
||||||
$request->send();
|
|
||||||
var_export(file_exists('/tmp/large_file.mov'));
|
|
||||||
// >>> true
|
|
||||||
|
|
||||||
Here's an example of using ``setResponseBody()``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$body = fopen('/tmp/large_file.mov', 'w');
|
|
||||||
$request = $this->client->get('http://example.com/large.mov');
|
|
||||||
$request->setResponseBody($body);
|
|
||||||
|
|
||||||
// You can more easily specify the name of a file to save the contents
|
|
||||||
// of the response to by passing a string to ``setResponseBody()``.
|
|
||||||
|
|
||||||
$request = $this->client->get('http://example.com/large.mov');
|
|
||||||
$request->setResponseBody('/tmp/large_file.mov');
|
|
||||||
|
|
||||||
Custom cURL options
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Most of the functionality implemented in the libcurl bindings has been simplified and abstracted by Guzzle. Developers
|
|
||||||
who need access to `cURL specific functionality <http://www.php.net/curl_setopt>`_ can still add cURL handle
|
|
||||||
specific behavior to Guzzle HTTP requests by modifying the cURL options collection of a request:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request->getCurlOptions()->set(CURLOPT_LOW_SPEED_LIMIT, 200);
|
|
||||||
|
|
||||||
Other special options that can be set in the ``curl.options`` array include:
|
|
||||||
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| debug | Adds verbose cURL output to a temp stream owned by the cURL handle object |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
| progress | Instructs cURL to emit events when IO events occur. This allows you to be |
|
|
||||||
| | notified when bytes are transferred over the wire by subscribing to a request's |
|
|
||||||
| | ``curl.callback.read``, ``curl.callback.write``, and ``curl.callback.progress`` |
|
|
||||||
| | events. |
|
|
||||||
+-------------------------+---------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
Request options
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Requests options can be specified when creating a request or in the ``request.options`` parameter of a client. These
|
|
||||||
options can control various aspects of a request including: headers to send, query string data, where the response
|
|
||||||
should be downloaded, proxies, auth, etc.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get($url, $headers, array('proxy' => 'http://proxy.com'));
|
|
||||||
|
|
||||||
See :ref:`Request options <request-options>` for more information.
|
|
||||||
|
|
||||||
Working with errors
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
HTTP errors
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
Requests that receive a 4xx or 5xx response will throw a ``Guzzle\Http\Exception\BadResponseException``. More
|
|
||||||
specifically, 4xx errors throw a ``Guzzle\Http\Exception\ClientErrorResponseException``, and 5xx errors throw a
|
|
||||||
``Guzzle\Http\Exception\ServerErrorResponseException``. You can catch the specific exceptions or just catch the
|
|
||||||
BadResponseException to deal with either type of error. Here's an example of catching a generic BadResponseException:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
try {
|
|
||||||
$response = $client->get('/not_found.xml')->send();
|
|
||||||
} catch (Guzzle\Http\Exception\BadResponseException $e) {
|
|
||||||
echo 'Uh oh! ' . $e->getMessage();
|
|
||||||
echo 'HTTP request URL: ' . $e->getRequest()->getUrl() . "\n";
|
|
||||||
echo 'HTTP request: ' . $e->getRequest() . "\n";
|
|
||||||
echo 'HTTP response status: ' . $e->getResponse()->getStatusCode() . "\n";
|
|
||||||
echo 'HTTP response: ' . $e->getResponse() . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
Throwing an exception when a 4xx or 5xx response is encountered is the default behavior of Guzzle requests. This
|
|
||||||
behavior can be overridden by adding an event listener with a higher priority than -255 that stops event propagation.
|
|
||||||
You can subscribe to ``request.error`` to receive notifications any time an unsuccessful response is received.
|
|
||||||
|
|
||||||
You can change the response that will be associated with the request by calling ``setResponse()`` on the
|
|
||||||
``$event['request']`` object passed into your listener, or by changing the ``$event['response']`` value of the
|
|
||||||
``Guzzle\Common\Event`` object that is passed to your listener. Transparently changing the response associated with a
|
|
||||||
request by modifying the event allows you to retry failed requests without complicating the code that uses the client.
|
|
||||||
This might be useful for sending requests to a web service that has expiring auth tokens. When a response shows that
|
|
||||||
your token has expired, you can get a new token, retry the request with the new token, and return the successful
|
|
||||||
response to the user.
|
|
||||||
|
|
||||||
Here's an example of retrying a request using updated authorization credentials when a 401 response is received,
|
|
||||||
overriding the response of the original request with the new response, and still allowing the default exception
|
|
||||||
behavior to be called when other non-200 response status codes are encountered:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Add custom error handling to any request created by this client
|
|
||||||
$client->getEventDispatcher()->addListener('request.error', function(Event $event) {
|
|
||||||
|
|
||||||
if ($event['response']->getStatusCode() == 401) {
|
|
||||||
|
|
||||||
$newRequest = $event['request']->clone();
|
|
||||||
$newRequest->setHeader('X-Auth-Header', MyApplication::getNewAuthToken());
|
|
||||||
$newResponse = $newRequest->send();
|
|
||||||
|
|
||||||
// Set the response object of the request without firing more events
|
|
||||||
$event['response'] = $newResponse;
|
|
||||||
|
|
||||||
// You can also change the response and fire the normal chain of
|
|
||||||
// events by calling $event['request']->setResponse($newResponse);
|
|
||||||
|
|
||||||
// Stop other events from firing when you override 401 responses
|
|
||||||
$event->stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
cURL errors
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
Connection problems and cURL specific errors can also occur when transferring requests using Guzzle. When Guzzle
|
|
||||||
encounters cURL specific errors while transferring a single request, a ``Guzzle\Http\Exception\CurlException`` is
|
|
||||||
thrown with an informative error message and access to the cURL error message.
|
|
||||||
|
|
||||||
A ``Guzzle\Http\Exception\MultiTransferException`` exception is thrown when a cURL specific error occurs while
|
|
||||||
transferring multiple requests in parallel. You can then iterate over all of the exceptions encountered during the
|
|
||||||
transfer.
|
|
||||||
|
|
||||||
Plugins and events
|
|
||||||
------------------
|
|
||||||
|
|
||||||
Guzzle request objects expose various events that allow you to hook in custom logic. A request object owns a
|
|
||||||
``Symfony\Component\EventDispatcher\EventDispatcher`` object that can be accessed by calling
|
|
||||||
``$request->getEventDispatcher()``. You can use the event dispatcher to add listeners (a simple callback function) or
|
|
||||||
event subscribers (classes that listen to specific events of a dispatcher). You can add event subscribers to a request
|
|
||||||
directly by just calling ``$request->addSubscriber($mySubscriber);``.
|
|
||||||
|
|
||||||
.. _request-events:
|
|
||||||
|
|
||||||
Events emitted from a request
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A ``Guzzle\Http\Message\Request`` and ``Guzzle\Http\Message\EntityEnclosingRequest`` object emit the following events:
|
|
||||||
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| Event name | Description | Event data |
|
|
||||||
+==============================+============================================+==========================================+
|
|
||||||
| request.before_send | About to send request | * request: Request to be sent |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.sent | Sent the request | * request: Request that was sent |
|
|
||||||
| | | * response: Received response |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.complete | Completed a full HTTP transaction | * request: Request that was sent |
|
|
||||||
| | | * response: Received response |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.success | Completed a successful request | * request: Request that was sent |
|
|
||||||
| | | * response: Received response |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.error | Completed an unsuccessful request | * request: Request that was sent |
|
|
||||||
| | | * response: Received response |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.exception | An unsuccessful response was | * request: Request |
|
|
||||||
| | received. | * response: Received response |
|
|
||||||
| | | * exception: BadResponseException |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| request.receive.status_line | Received the start of a response | * line: Full response start line |
|
|
||||||
| | | * status_code: Status code |
|
|
||||||
| | | * reason_phrase: Reason phrase |
|
|
||||||
| | | * previous_response: (e.g. redirect) |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| curl.callback.progress | cURL progress event (only dispatched when | * handle: CurlHandle |
|
|
||||||
| | ``emit_io`` is set on a request's curl | * download_size: Total download size |
|
|
||||||
| | options) | * downloaded: Bytes downloaded |
|
|
||||||
| | | * upload_size: Total upload bytes |
|
|
||||||
| | | * uploaded: Bytes uploaded |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| curl.callback.write | cURL event called when data is written to | * request: Request |
|
|
||||||
| | an outgoing stream | * write: Data being written |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| curl.callback.read | cURL event called when data is written to | * request: Request |
|
|
||||||
| | an incoming stream | * read: Data being read |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
|
|
||||||
Creating a request event listener
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Here's an example that listens to the ``request.complete`` event of a request and prints the request and response.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
|
|
||||||
$request = $client->get('http://www.google.com');
|
|
||||||
|
|
||||||
// Echo out the response that was received
|
|
||||||
$request->getEventDispatcher()->addListener('request.complete', function (Event $e) {
|
|
||||||
echo $e['request'] . "\n\n";
|
|
||||||
echo $e['response'];
|
|
||||||
});
|
|
@ -1,141 +0,0 @@
|
|||||||
======================
|
|
||||||
Using Response objects
|
|
||||||
======================
|
|
||||||
|
|
||||||
Sending a request will return a ``Guzzle\Http\Message\Response`` object. You can view the raw HTTP response message by
|
|
||||||
casting the Response object to a string. Casting the response to a string will return the entity body of the response
|
|
||||||
as a string too, so this might be an expensive operation if the entity body is stored in a file or network stream. If
|
|
||||||
you only want to see the response headers, you can call ``getRawHeaders()``.
|
|
||||||
|
|
||||||
Response status line
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
The different parts of a response's `status line <http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1>`_
|
|
||||||
(the first line of the response HTTP message) are easily retrievable.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$response = $client->get('http://www.amazon.com')->send();
|
|
||||||
|
|
||||||
echo $response->getStatusCode(); // >>> 200
|
|
||||||
echo $response->getReasonPhrase(); // >>> OK
|
|
||||||
echo $response->getProtocol(); // >>> HTTP
|
|
||||||
echo $response->getProtocolVersion(); // >>> 1.1
|
|
||||||
|
|
||||||
You can determine the type of the response using several helper methods:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$response->isSuccessful(); // true
|
|
||||||
$response->isInformational();
|
|
||||||
$response->isRedirect();
|
|
||||||
$response->isClientError();
|
|
||||||
$response->isServerError();
|
|
||||||
|
|
||||||
Response headers
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The Response object contains helper methods for retrieving common response headers. These helper methods normalize the
|
|
||||||
variations of HTTP response headers.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$response->getCacheControl();
|
|
||||||
$response->getContentType();
|
|
||||||
$response->getContentLength();
|
|
||||||
$response->getContentEncoding();
|
|
||||||
$response->getContentMd5();
|
|
||||||
$response->getEtag();
|
|
||||||
// etc... There are methods for every known response header
|
|
||||||
|
|
||||||
You can interact with the Response headers using the same exact methods used to interact with Request headers. See
|
|
||||||
:ref:`http-message-headers` for more information.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $response->getHeader('Content-Type');
|
|
||||||
echo $response->getHeader('Content-Length');
|
|
||||||
echo $response->getHeaders()['Content-Type']; // PHP 5.4
|
|
||||||
|
|
||||||
Response body
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The entity body object of a response can be retrieved by calling ``$response->getBody()``. The response EntityBody can
|
|
||||||
be cast to a string, or you can pass ``true`` to this method to retrieve the body as a string.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get('http://www.amazon.com');
|
|
||||||
$response = $request->send();
|
|
||||||
echo $response->getBody();
|
|
||||||
|
|
||||||
See :doc:`/http-client/entity-bodies` for more information on entity bodies.
|
|
||||||
|
|
||||||
JSON Responses
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can easily parse and use a JSON response as an array using the ``json()`` method of a response. This method will
|
|
||||||
always return an array if the response is valid JSON or if the response body is empty. You will get an exception if you
|
|
||||||
call this method and the response is not valid JSON.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$data = $response->json();
|
|
||||||
echo gettype($data);
|
|
||||||
// >>> array
|
|
||||||
|
|
||||||
XML Responses
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can easily parse and use a XML response as SimpleXMLElement object using the ``xml()`` method of a response. This
|
|
||||||
method will always return a SimpleXMLElement object if the response is valid XML or if the response body is empty. You
|
|
||||||
will get an exception if you call this method and the response is not valid XML.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$xml = $response->xml();
|
|
||||||
echo $xml->foo;
|
|
||||||
// >>> Bar!
|
|
||||||
|
|
||||||
Streaming responses
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Some web services provide streaming APIs that allow a client to keep a HTTP request open for an extended period of
|
|
||||||
time while polling and reading. Guzzle provides a simple way to convert HTTP request messages into
|
|
||||||
``Guzzle\Stream\Stream`` objects so that you can send the initial headers of a request, read the response headers, and
|
|
||||||
pull in the response body manually as needed.
|
|
||||||
|
|
||||||
Here's an example using the Twitter Streaming API to track the keyword "bieber":
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Stream\PhpStreamRequestFactory;
|
|
||||||
|
|
||||||
$client = new Client('https://stream.twitter.com/1');
|
|
||||||
|
|
||||||
$request = $client->post('statuses/filter.json', null, array(
|
|
||||||
'track' => 'bieber'
|
|
||||||
));
|
|
||||||
|
|
||||||
$request->setAuth('myusername', 'mypassword');
|
|
||||||
|
|
||||||
$factory = new PhpStreamRequestFactory();
|
|
||||||
$stream = $factory->fromRequest($request);
|
|
||||||
|
|
||||||
// Read until the stream is closed
|
|
||||||
while (!$stream->feof()) {
|
|
||||||
// Read a line from the stream
|
|
||||||
$line = $stream->readLine();
|
|
||||||
// JSON decode the line of data
|
|
||||||
$data = json_decode($line, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
You can use the ``stream`` request option when using a static client to more easily create a streaming response.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$stream = Guzzle::get('http://guzzlephp.org', array('stream' => true));
|
|
||||||
while (!$stream->feof()) {
|
|
||||||
echo $stream->readLine();
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
=============
|
|
||||||
URI templates
|
|
||||||
=============
|
|
||||||
|
|
||||||
The ``$uri`` passed to one of the client's request creational methods or the base URL of a client can utilize URI
|
|
||||||
templates. Guzzle supports the entire `URI templates RFC <http://tools.ietf.org/html/rfc6570>`_. URI templates add a
|
|
||||||
special syntax to URIs that replace template place holders with user defined variables.
|
|
||||||
|
|
||||||
Every request created by a Guzzle HTTP client passes through a URI template so that URI template expressions are
|
|
||||||
automatically expanded:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client('https://example.com/', array('a' => 'hi'));
|
|
||||||
$request = $client->get('/{a}');
|
|
||||||
|
|
||||||
Because of URI template expansion, the URL of the above request will become ``https://example.com/hi``. Notice that
|
|
||||||
the template was expanded using configuration variables of the client. You can pass in custom URI template variables
|
|
||||||
by passing the URI of your request as an array where the first index of the array is the URI template and the second
|
|
||||||
index of the array are template variables that are merged into the client's configuration variables.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get(array('/test{?a,b}', array('b' => 'there')));
|
|
||||||
|
|
||||||
The URL for this request will become ``https://test.com?a=hi&b=there``. URI templates aren't limited to just simple
|
|
||||||
variable replacements; URI templates can provide an enormous amount of flexibility when creating request URIs.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $client->get(array('http://example.com{+path}{/segments*}{?query,data*}', array(
|
|
||||||
'path' => '/foo/bar',
|
|
||||||
'segments' => array('one', 'two'),
|
|
||||||
'query' => 'test',
|
|
||||||
'data' => array(
|
|
||||||
'more' => 'value'
|
|
||||||
)
|
|
||||||
)));
|
|
||||||
|
|
||||||
The resulting URL would become ``http://example.com/foo/bar/one/two?query=test&more=value``.
|
|
||||||
|
|
||||||
By default, URI template expressions are enclosed in an opening and closing brace (e.g. ``{var}``). If you are working
|
|
||||||
with a web service that actually uses braces (e.g. Solr), then you can specify a custom regular expression to use to
|
|
||||||
match URI template expressions.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client->getUriTemplate()->setRegex('/\<\$(.+)\>/');
|
|
||||||
$client->get('/<$a>');
|
|
||||||
|
|
||||||
You can learn about all of the different features of URI templates by reading the
|
|
||||||
`URI templates RFC <http://tools.ietf.org/html/rfc6570>`_.
|
|
@ -1,5 +0,0 @@
|
|||||||
.. title:: Guzzle | PHP HTTP client and framework for consuming RESTful web services
|
|
||||||
.. toctree::
|
|
||||||
:hidden:
|
|
||||||
|
|
||||||
docs.rst
|
|
@ -1,97 +0,0 @@
|
|||||||
================
|
|
||||||
Guzzle iterators
|
|
||||||
================
|
|
||||||
|
|
||||||
Guzzle provides several SPL iterators that can be used with other SPL iterators, including Guzzle resource iterators.
|
|
||||||
Guzzle's ``guzzle/iterator`` component can also be used independently of the rest of Guzzle through Packagist and
|
|
||||||
Composer: https://packagist.org/packages/guzzle/iterator
|
|
||||||
|
|
||||||
ChunkedIterator
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Pulls out multiple values from an inner iterator and yields and array of values for each outer iteration -- essentially
|
|
||||||
pulling out chunks of values from the inner iterator.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Iterator\ChunkedIterator;
|
|
||||||
|
|
||||||
$inner = new ArrayIterator(range(0, 8));
|
|
||||||
$chunkedIterator = new ChunkedIterator($inner, 2);
|
|
||||||
|
|
||||||
foreach ($chunkedIterator as $chunk) {
|
|
||||||
echo implode(', ', $chunk) . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// >>> 0, 1
|
|
||||||
// >>> 2, 3
|
|
||||||
// >>> 4, 5
|
|
||||||
// >>> 6, 7
|
|
||||||
// >>> 8
|
|
||||||
|
|
||||||
FilterIterator
|
|
||||||
--------------
|
|
||||||
|
|
||||||
This iterator is used to filter values out of the inner iterator. This iterator can be used when PHP 5.4's
|
|
||||||
CallbackFilterIterator is not available.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Iterator\FilterIterator;
|
|
||||||
|
|
||||||
$inner = new ArrayIterator(range(1, 10));
|
|
||||||
$filterIterator = new FilterIterator($inner, function ($value) {
|
|
||||||
return $value % 2;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach ($filterIterator as $value) {
|
|
||||||
echo $value . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// >>> 2
|
|
||||||
// >>> 4
|
|
||||||
// >>> 6
|
|
||||||
// >>> 8
|
|
||||||
// >>> 10
|
|
||||||
|
|
||||||
MapIterator
|
|
||||||
-----------
|
|
||||||
|
|
||||||
This iterator modifies the values of the inner iterator before yielding.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Iterator\MapIterator;
|
|
||||||
|
|
||||||
$inner = new ArrayIterator(range(0, 3));
|
|
||||||
|
|
||||||
$mapIterator = new MapIterator($inner, function ($value) {
|
|
||||||
return $value * 10;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach ($mapIterator as $value) {
|
|
||||||
echo $value . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// >>> 0
|
|
||||||
// >>> 10
|
|
||||||
// >>> 20
|
|
||||||
// >>> 30
|
|
||||||
|
|
||||||
MethodProxyIterator
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
This decorator is useful when you need to expose a specific method from an inner iterator that might be wrapper
|
|
||||||
by one or more iterator decorators. This decorator proxies missing method calls to each inner iterator until one
|
|
||||||
of the inner iterators can fulfill the call.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Iterator\MethodProxyIterator;
|
|
||||||
|
|
||||||
$inner = new \ArrayIterator();
|
|
||||||
$proxy = new MethodProxyIterator($inner);
|
|
||||||
|
|
||||||
// Proxy method calls to the ArrayIterator
|
|
||||||
$proxy->append('a');
|
|
||||||
$proxy->append('b');
|
|
@ -1,149 +0,0 @@
|
|||||||
==================
|
|
||||||
Resource iterators
|
|
||||||
==================
|
|
||||||
|
|
||||||
Web services often implement pagination in their responses which requires the end-user to issue a series of consecutive
|
|
||||||
requests in order to fetch all of the data they asked for. Users of your web service client should not be responsible
|
|
||||||
for implementing the logic involved in iterating through pages of results. Guzzle provides a simple resource iterator
|
|
||||||
foundation to make it easier on web service client developers to offer a useful abstraction layer.
|
|
||||||
|
|
||||||
Getting an iterator from a client
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
ResourceIteratorInterface Guzzle\Service\Client::getIterator($command [, array $commandOptions, array $iteratorOptions ])
|
|
||||||
|
|
||||||
The ``getIterator`` method of a ``Guzzle\Service\ClientInterface`` object provides a convenient interface for
|
|
||||||
instantiating a resource iterator for a specific command. This method implicitly uses a
|
|
||||||
``Guzzle\Service\Resource\ResourceIteratorFactoryInterface`` object to create resource iterators. Pass an
|
|
||||||
instantiated command object or the name of a command in the first argument. When passing the name of a command, the
|
|
||||||
command factory of the client will create the command by name using the ``$commandOptions`` array. The third argument
|
|
||||||
may be used to pass an array of options to the constructor of the instantiated ``ResourceIteratorInterface`` object.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$iterator = $client->getIterator('get_users');
|
|
||||||
|
|
||||||
foreach ($iterator as $user) {
|
|
||||||
echo $user['name'] . ' age ' . $user['age'] . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
The above code sample might execute a single request or a thousand requests. As a consumer of a web service, I don't
|
|
||||||
care. I just want to iterate over all of the users.
|
|
||||||
|
|
||||||
Iterator options
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The two universal options that iterators should support are ``limit`` and ``page_size``. Using the ``limit`` option
|
|
||||||
tells the resource iterator to attempt to limit the total number of iterated resources to a specific amount. Keep in
|
|
||||||
mind that this is not always possible due to limitations that may be inherent to a web service. The ``page_size``
|
|
||||||
option is used to tell a resource iterator how many resources to request per page of results. Much like the ``limit``
|
|
||||||
option, you can not rely on getting back exactly the number of resources your specify in the ``page_size`` option.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The ``limit`` and ``page_size`` options can also be specified on an iterator using the ``setLimit($limit)`` and
|
|
||||||
``setPageSize($pageSize)`` methods.
|
|
||||||
|
|
||||||
Resolving iterator class names
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The default resource iterator factory of a client object expects that your iterators are stored under the ``Model``
|
|
||||||
folder of your client and that an iterator is names after the CamelCase name of a command followed by the word
|
|
||||||
"Iterator". For example, if you wanted to create an iterator for the ``get_users`` command, then your iterator class
|
|
||||||
would be ``Model\GetUsersIterator`` and would be stored in ``Model/GetUsersIterator.php``.
|
|
||||||
|
|
||||||
Creating an iterator
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
While not required, resource iterators in Guzzle typically iterate using a ``Guzzle\Service\Command\CommandInterface``
|
|
||||||
object. ``Guzzle\Service\Resource\ResourceIterator``, the default iterator implementation that you should extend,
|
|
||||||
accepts a command object and array of iterator options in its constructor. The command object passed to the resource
|
|
||||||
iterator is expected to be ready to execute and not previously executed. The resource iterator keeps a reference of
|
|
||||||
this command and clones the original command each time a subsequent request needs to be made to fetch more data.
|
|
||||||
|
|
||||||
Implement the sendRequest method
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The most important thing (and usually the only thing) you need to do when creating a resource iterator is to implement
|
|
||||||
the ``sendRequest()`` method of the resource iterator. The ``sendRequest()`` method is called when you begin
|
|
||||||
iterating or if there are no resources left to iterate and it you expect to retrieve more resources by making a
|
|
||||||
subsequent request. The ``$this->command`` property of the resource iterator is updated with a cloned copy of the
|
|
||||||
original command object passed into the constructor of the iterator. Use this command object to issue your subsequent
|
|
||||||
requests.
|
|
||||||
|
|
||||||
The ``sendRequest()`` method must return an array of the resources you retrieved from making the subsequent call.
|
|
||||||
Returning an empty array will stop the iteration. If you suspect that your web service client will occasionally return
|
|
||||||
an empty result set but still requires further iteration, then you must implement a sort of loop in your
|
|
||||||
``sendRequest()`` method that will continue to issue subsequent requests until your reach the end of the paginated
|
|
||||||
result set or until additional resources are retrieved from the web service.
|
|
||||||
|
|
||||||
Update the nextToken property
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Beyond fetching more results, the ``sendRequest()`` method is responsible for updating the ``$this->nextToken``
|
|
||||||
property of the iterator. Setting this property to anything other than null tells the iterator that issuing a
|
|
||||||
subsequent request using the nextToken value will probably return more results. You must continually update this
|
|
||||||
value in your ``sendRequest()`` method as each response is received from the web service.
|
|
||||||
|
|
||||||
Example iterator
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Let's say you want to implement a resource iterator for the ``get_users`` command of your web service. The
|
|
||||||
``get_users`` command receives a response that contains a list of users, and if there are more pages of results to
|
|
||||||
retrieve, returns a value called ``next_user``. This return value is known as the **next token** and should be used to
|
|
||||||
issue subsequent requests.
|
|
||||||
|
|
||||||
Assume the response to a ``get_users`` command returns JSON data that looks like this:
|
|
||||||
|
|
||||||
.. code-block:: javascript
|
|
||||||
|
|
||||||
{
|
|
||||||
"users": [
|
|
||||||
{ "name": "Craig Johnson", "age": 10 },
|
|
||||||
{ "name": "Tom Barker", "age": 20 },
|
|
||||||
{ "name": "Bob Mitchell", "age": 74 }
|
|
||||||
],
|
|
||||||
"next_user": "Michael Dowling"
|
|
||||||
}
|
|
||||||
|
|
||||||
Assume that because there is a ``next_user`` value, there will be more users if a subsequent request is issued. If the
|
|
||||||
``next_user`` value is missing or null, then we know there are no more results to fetch. Let's implement a resource
|
|
||||||
iterator for this command.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace MyService\Model;
|
|
||||||
|
|
||||||
use Guzzle\Service\Resource\ResourceIterator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over a get_users command
|
|
||||||
*/
|
|
||||||
class GetUsersIterator extends ResourceIterator
|
|
||||||
{
|
|
||||||
protected function sendRequest()
|
|
||||||
{
|
|
||||||
// If a next token is set, then add it to the command
|
|
||||||
if ($this->nextToken) {
|
|
||||||
$this->command->set('next_user', $this->nextToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the command and parse the result
|
|
||||||
$result = $this->command->execute();
|
|
||||||
|
|
||||||
// Parse the next token
|
|
||||||
$this->nextToken = isset($result['next_user']) ? $result['next_user'] : false;
|
|
||||||
|
|
||||||
return $result['users'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
As you can see, it's pretty simple to implement an iterator. There are a few things that you should notice from this
|
|
||||||
example:
|
|
||||||
|
|
||||||
1. You do not need to create a new command in the ``sendRequest()`` method. A new command object is cloned from the
|
|
||||||
original command passed into the constructor of the iterator before the ``sendRequest()`` method is called.
|
|
||||||
Remember that the resource iterator expects a command that has not been executed.
|
|
||||||
2. When the ``sendRequest()`` method is first called, you will not have a ``$this->nextToken`` value, so always check
|
|
||||||
before setting it on a command. Notice that the next token is being updated each time a request is sent.
|
|
||||||
3. After fetching more resources from the service, always return an array of resources.
|
|
@ -1,18 +0,0 @@
|
|||||||
============
|
|
||||||
Async plugin
|
|
||||||
============
|
|
||||||
|
|
||||||
The AsyncPlugin allows you to send requests that do not wait on a response. This is handled through cURL by utilizing
|
|
||||||
the progress event. When a request has sent all of its data to the remote server, Guzzle adds a 1ms timeout on the
|
|
||||||
request and instructs cURL to not download the body of the response. The async plugin then catches the exception and
|
|
||||||
adds a mock response to the request, along with an X-Guzzle-Async header to let you know that the response was not
|
|
||||||
fully downloaded.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Async\AsyncPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://www.example.com');
|
|
||||||
$client->addSubscriber(new AsyncPlugin());
|
|
||||||
$response = $client->get()->send();
|
|
@ -1,22 +0,0 @@
|
|||||||
====================
|
|
||||||
Backoff retry plugin
|
|
||||||
====================
|
|
||||||
|
|
||||||
The ``Guzzle\Plugin\Backoff\BackoffPlugin`` automatically retries failed HTTP requests using custom backoff strategies:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Backoff\BackoffPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
// Use a static factory method to get a backoff plugin using the exponential backoff strategy
|
|
||||||
$backoffPlugin = BackoffPlugin::getExponentialBackoff();
|
|
||||||
|
|
||||||
// Add the backoff plugin to the client object
|
|
||||||
$client->addSubscriber($backoffPlugin);
|
|
||||||
|
|
||||||
The BackoffPlugin's constructor accepts a ``Guzzle\Plugin\Backoff\BackoffStrategyInterface`` object that is used to
|
|
||||||
determine when a retry should be issued and how long to delay between retries. The above code example shows how to
|
|
||||||
attach a BackoffPlugin to a client that is pre-configured to retry failed 500 and 503 responses using truncated
|
|
||||||
exponential backoff (emulating the behavior of Guzzle 2's ExponentialBackoffPlugin).
|
|
@ -1,169 +0,0 @@
|
|||||||
=================
|
|
||||||
HTTP Cache plugin
|
|
||||||
=================
|
|
||||||
|
|
||||||
Guzzle can leverage HTTP's caching specifications using the ``Guzzle\Plugin\Cache\CachePlugin``. The CachePlugin
|
|
||||||
provides a private transparent proxy cache that caches HTTP responses. The caching logic, based on
|
|
||||||
`RFC 2616 <http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html>`_, uses HTTP headers to control caching behavior,
|
|
||||||
cache lifetime, and supports Vary, ETag, and Last-Modified based revalidation:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Doctrine\Common\Cache\FilesystemCache;
|
|
||||||
use Guzzle\Cache\DoctrineCacheAdapter;
|
|
||||||
use Guzzle\Plugin\Cache\CachePlugin;
|
|
||||||
use Guzzle\Plugin\Cache\DefaultCacheStorage;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
$cachePlugin = new CachePlugin(array(
|
|
||||||
'storage' => new DefaultCacheStorage(
|
|
||||||
new DoctrineCacheAdapter(
|
|
||||||
new FilesystemCache('/path/to/cache/files')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add the cache plugin to the client object
|
|
||||||
$client->addSubscriber($cachePlugin);
|
|
||||||
$client->get('http://www.wikipedia.org/')->send();
|
|
||||||
|
|
||||||
// The next request will revalidate against the origin server to see if it
|
|
||||||
// has been modified. If a 304 response is received the response will be
|
|
||||||
// served from cache
|
|
||||||
$client->get('http://www.wikipedia.org/')->send();
|
|
||||||
|
|
||||||
The cache plugin intercepts GET and HEAD requests before they are actually transferred to the origin server. The cache
|
|
||||||
plugin then generates a hash key based on the request method and URL, and checks to see if a response exists in the cache. If
|
|
||||||
a response exists in the cache, the cache adapter then checks to make sure that the caching rules associated with the response
|
|
||||||
satisfy the request, and ensures that response still fresh. If the response is acceptable for the request any required
|
|
||||||
revalidation, then the cached response is served instead of contacting the origin server.
|
|
||||||
|
|
||||||
Vary
|
|
||||||
----
|
|
||||||
|
|
||||||
Cache keys are derived from a request method and a request URL. Multiple responses can map to the same cache key and
|
|
||||||
stored in Guzzle's underlying cache storage object. You should use the ``Vary`` HTTP header to tell the cache storage
|
|
||||||
object that the cache response must have been cached for a request that matches the headers specified in the Vary header
|
|
||||||
of the request. This allows you to have specific cache entries for the same request URL but variations in a request's
|
|
||||||
headers determine which cache entry is served. Please see the http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
Cache options
|
|
||||||
-------------
|
|
||||||
|
|
||||||
There are several options you can add to requests or clients to modify the behavior of the cache plugin.
|
|
||||||
|
|
||||||
Override cache TTL
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can override the number of seconds a cacheable response is stored in the cache by setting the
|
|
||||||
``cache.override_ttl`` parameter on the params object of a request:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// If the response to the request is cacheable, then the response will be cached for 100 seconds
|
|
||||||
$request->getParams()->set('cache.override_ttl', 100);
|
|
||||||
|
|
||||||
If a response doesn't specify any freshness policy, it will be kept in cache for 3600 seconds by default.
|
|
||||||
|
|
||||||
Custom caching decision
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If the service you are interacting with does not return caching headers or returns responses that are normally
|
|
||||||
something that would not be cached, you can set a custom ``can_cache`` object on the constructor of the CachePlugin
|
|
||||||
and provide a ``Guzzle\Plugin\Cache\CanCacheInterface`` object. You can use the
|
|
||||||
``Guzzle\Plugin\Cache\CallbackCanCacheStrategy`` to easily make a caching decision based on an HTTP request and
|
|
||||||
response.
|
|
||||||
|
|
||||||
Revalidation options
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can change the revalidation behavior of a request using the ``cache.revalidate`` parameter. Setting this
|
|
||||||
parameter to ``never`` will ensure that a revalidation request is never sent, and the response is always served from
|
|
||||||
the origin server. Setting this parameter to ``skip`` will never revalidate and uses the response stored in the cache.
|
|
||||||
|
|
||||||
Normalizing requests for caching
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Use the ``cache.key_filter`` parameter if you wish to strip certain query string parameters from your
|
|
||||||
request before creating a unique hash for the request. This parameter can be useful if your requests have query
|
|
||||||
string values that cause each request URL to be unique (thus preventing a cache hit). The ``cache.key_filter``
|
|
||||||
format is simply a comma separated list of query string values to remove from the URL when creating a cache key.
|
|
||||||
For example, here we are saying that the ``a`` and ``q`` query string variables should be ignored when generating a
|
|
||||||
cache key for the request:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request->getParams()->set('cache.key_filter', 'a, q');
|
|
||||||
|
|
||||||
Other options
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
There are many other options available to the CachePlugin that can meet almost any caching requirement, including
|
|
||||||
custom revalidation implementations, custom cache key generators, custom caching decision strategies, and custom
|
|
||||||
cache storage objects. Take a look the constructor of ``Guzzle\Plugin\Cache\CachePlugin`` for more information.
|
|
||||||
|
|
||||||
Setting Client-wide cache settings
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can specify cache settings for every request created by a client by adding cache settings to the configuration
|
|
||||||
options of a client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Http\Client('http://www.test.com', array(
|
|
||||||
'request.params' => array(
|
|
||||||
'cache.override_ttl' => 3600,
|
|
||||||
'params.cache.revalidate' => 'never'
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
echo $client->get('/')->getParams()->get('cache.override_ttl');
|
|
||||||
// >>> 3600
|
|
||||||
|
|
||||||
echo $client->get('/')->getParams()->get('cache.revalidate');
|
|
||||||
// >>> never
|
|
||||||
|
|
||||||
Cache revalidation
|
|
||||||
------------------
|
|
||||||
|
|
||||||
If the cache plugin determines that a response to a GET request needs revalidation, a conditional GET is transferred
|
|
||||||
to the origin server. If the origin server returns a 304 response, then a response containing the merged headers of
|
|
||||||
the cached response with the new response and the entity body of the cached response is returned. Custom revalidation
|
|
||||||
strategies can be injected into a CachePlugin if needed.
|
|
||||||
|
|
||||||
Cache adapters
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Guzzle doesn't try to reinvent the wheel when it comes to caching or logging. Plenty of other frameworks have
|
|
||||||
excellent solutions in place that you are probably already using in your applications. Guzzle uses adapters for
|
|
||||||
caching and logging. The cache plugin requires a cache adapter so that is can store responses in a cache. Guzzle
|
|
||||||
currently supports cache adapters for `Doctrine 2.0 <http://www.doctrine-project.org/>`_ and the
|
|
||||||
`Zend Framework <http://framework.zend.com>`_.
|
|
||||||
|
|
||||||
Doctrine cache adapter
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Common\Cache\ArrayCache;
|
|
||||||
use Guzzle\Cache\DoctrineCacheAdapter;
|
|
||||||
use Guzzle\Plugin\Cache\CachePlugin;
|
|
||||||
|
|
||||||
$backend = new ArrayCache();
|
|
||||||
$adapter = new DoctrineCacheAdapter($backend);
|
|
||||||
$cache = new CachePlugin($adapter);
|
|
||||||
|
|
||||||
Zend Framework cache adapter
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Cache\ZendCacheAdapter;
|
|
||||||
use Zend\Cache\Backend\TestBackend;
|
|
||||||
|
|
||||||
$backend = new TestBackend();
|
|
||||||
$adapter = new ZendCacheAdapter($backend);
|
|
||||||
$cache = new CachePlugin($adapter);
|
|
@ -1,33 +0,0 @@
|
|||||||
=============
|
|
||||||
Cookie plugin
|
|
||||||
=============
|
|
||||||
|
|
||||||
Some web services require a Cookie in order to maintain a session. The ``Guzzle\Plugin\Cookie\CookiePlugin`` will add
|
|
||||||
cookies to requests and parse cookies from responses using a CookieJar object:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Cookie\CookiePlugin;
|
|
||||||
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
|
|
||||||
|
|
||||||
$cookiePlugin = new CookiePlugin(new ArrayCookieJar());
|
|
||||||
|
|
||||||
// Add the cookie plugin to a client
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
$client->addSubscriber($cookiePlugin);
|
|
||||||
|
|
||||||
// Send the request with no cookies and parse the returned cookies
|
|
||||||
$client->get('http://www.yahoo.com/')->send();
|
|
||||||
|
|
||||||
// Send the request again, noticing that cookies are being sent
|
|
||||||
$request = $client->get('http://www.yahoo.com/');
|
|
||||||
$request->send();
|
|
||||||
|
|
||||||
echo $request;
|
|
||||||
|
|
||||||
You can disable cookies per-request by setting the ``cookies.disable`` value to true on a request's params object.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request->getParams()->set('cookies.disable', true);
|
|
@ -1,93 +0,0 @@
|
|||||||
================
|
|
||||||
Creating plugins
|
|
||||||
================
|
|
||||||
|
|
||||||
.. highlight:: php
|
|
||||||
|
|
||||||
Guzzle is extremely extensible because of the behavioral modifications that can be added to requests, clients, and
|
|
||||||
commands using an event system. Before and after the majority of actions are taken in the library, an event is emitted
|
|
||||||
with the name of the event and context surrounding the event. Observers can subscribe to a subject and modify the
|
|
||||||
subject based on the events received. Guzzle's event system utilizes the Symfony2 EventDispatcher and is the backbone
|
|
||||||
of its plugin architecture.
|
|
||||||
|
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
|
|
||||||
Plugins must implement the ``Symfony\Component\EventDispatcher\EventSubscriberInterface`` interface. The
|
|
||||||
``EventSubscriberInterface`` requires that your class implements a static method, ``getSubscribedEvents()``, that
|
|
||||||
returns an associative array mapping events to methods on the object. See the
|
|
||||||
`Symfony2 documentation <http://symfony.com/doc/2.0/book/internals.html#the-event-dispatcher>`_ for more information.
|
|
||||||
|
|
||||||
Plugins can be attached to any subject, or object in Guzzle that implements that
|
|
||||||
``Guzzle\Common\HasDispatcherInterface``.
|
|
||||||
|
|
||||||
Subscribing to a subject
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can subscribe an instantiated observer to an event by calling ``addSubscriber`` on a subject.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$testPlugin = new TestPlugin();
|
|
||||||
$client->addSubscriber($testPlugin);
|
|
||||||
|
|
||||||
You can also subscribe to only specific events using a closure::
|
|
||||||
|
|
||||||
$client->getEventDispatcher()->addListener('request.create', function(Event $event) {
|
|
||||||
echo $event->getName();
|
|
||||||
echo $event['request'];
|
|
||||||
});
|
|
||||||
|
|
||||||
``Guzzle\Common\Event`` objects are passed to notified functions. The Event object has a ``getName()`` method which
|
|
||||||
return the name of the emitted event and may contain contextual information that can be accessed like an array.
|
|
||||||
|
|
||||||
Knowing what events to listen to
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Any class that implements the ``Guzzle\Common\HasDispatcherInterface`` must implement a static method,
|
|
||||||
``getAllEvents()``, that returns an array of the events that are emitted from the object. You can browse the source
|
|
||||||
to see each event, or you can call the static method directly in your code to get a list of available events.
|
|
||||||
|
|
||||||
Event hooks
|
|
||||||
-----------
|
|
||||||
|
|
||||||
* :ref:`client-events`
|
|
||||||
* :ref:`service-client-events`
|
|
||||||
* :ref:`request-events`
|
|
||||||
* ``Guzzle\Http\Curl\CurlMulti``:
|
|
||||||
* :ref:`service-builder-events`
|
|
||||||
|
|
||||||
Examples of the event system
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Simple Echo plugin
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This simple plugin prints a string containing the request that is about to be sent by listening to the
|
|
||||||
``request.before_send`` event::
|
|
||||||
|
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
||||||
|
|
||||||
class EchoPlugin implements EventSubscriberInterface
|
|
||||||
{
|
|
||||||
public static function getSubscribedEvents()
|
|
||||||
{
|
|
||||||
return array('request.before_send' => 'onBeforeSend');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onBeforeSend(Guzzle\Common\Event $event)
|
|
||||||
{
|
|
||||||
echo 'About to send a request: ' . $event['request'] . "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$client = new Guzzle\Service\Client('http://www.test.com/');
|
|
||||||
|
|
||||||
// Create the plugin and add it as an event subscriber
|
|
||||||
$plugin = new EchoPlugin();
|
|
||||||
$client->addSubscriber($plugin);
|
|
||||||
|
|
||||||
// Send a request and notice that the request is printed to the screen
|
|
||||||
$client->get('/')->send();
|
|
||||||
|
|
||||||
Running the above code will print a string containing the HTTP request that is about to be sent.
|
|
@ -1,32 +0,0 @@
|
|||||||
==========================
|
|
||||||
cURL authentication plugin
|
|
||||||
==========================
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
The CurlAuthPlugin is deprecated. You should use the `auth` parameter of a client to add authorization headers to
|
|
||||||
every request created by a client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client->setDefaultOption('auth', array('username', 'password', 'Basic|Digest|NTLM|Any'));
|
|
||||||
|
|
||||||
If your web service client requires basic authorization, then you can use the CurlAuthPlugin to easily add an
|
|
||||||
Authorization header to each request sent by the client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\CurlAuth\CurlAuthPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
// Add the auth plugin to the client object
|
|
||||||
$authPlugin = new CurlAuthPlugin('username', 'password');
|
|
||||||
$client->addSubscriber($authPlugin);
|
|
||||||
|
|
||||||
$response = $client->get('projects/1/people')->send();
|
|
||||||
$xml = new SimpleXMLElement($response->getBody(true));
|
|
||||||
foreach ($xml->person as $person) {
|
|
||||||
echo $person->email . "\n";
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
==============
|
|
||||||
History plugin
|
|
||||||
==============
|
|
||||||
|
|
||||||
The history plugin tracks all of the requests and responses sent through a request or client. This plugin can be
|
|
||||||
useful for crawling or unit testing. By default, the history plugin stores up to 10 requests and responses.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\History\HistoryPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
// Add the history plugin to the client object
|
|
||||||
$history = new HistoryPlugin();
|
|
||||||
$history->setLimit(5);
|
|
||||||
$client->addSubscriber($history);
|
|
||||||
|
|
||||||
$client->get('http://www.yahoo.com/')->send();
|
|
||||||
|
|
||||||
echo $history->getLastRequest();
|
|
||||||
echo $history->getLastResponse();
|
|
||||||
echo count($history);
|
|
@ -1,69 +0,0 @@
|
|||||||
==========
|
|
||||||
Log plugin
|
|
||||||
==========
|
|
||||||
|
|
||||||
Use the ``Guzzle\Plugin\Log\LogPlugin`` to view all data sent over the wire, including entity bodies and redirects.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Log\Zf1LogAdapter;
|
|
||||||
use Guzzle\Plugin\Log\LogPlugin;
|
|
||||||
use Guzzle\Log\MessageFormatter;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
$adapter = new Zf1LogAdapter(
|
|
||||||
new \Zend_Log(new \Zend_Log_Writer_Stream('php://output'))
|
|
||||||
);
|
|
||||||
$logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT);
|
|
||||||
|
|
||||||
// Attach the plugin to the client, which will in turn be attached to all
|
|
||||||
// requests generated by the client
|
|
||||||
$client->addSubscriber($logPlugin);
|
|
||||||
|
|
||||||
$response = $client->get('http://google.com')->send();
|
|
||||||
|
|
||||||
The code sample above wraps a ``Zend_Log`` object using a ``Guzzle\Log\Zf1LogAdapter``. After attaching the plugin to
|
|
||||||
the client, all data sent over the wire will be logged to stdout.
|
|
||||||
|
|
||||||
The first argument of the LogPlugin's constructor accepts a ``Guzzle\Log\LogAdapterInterface`` object. This object is
|
|
||||||
an adapter that allows you to use the logging capabilities of your favorite log implementation. The second argument of
|
|
||||||
the constructor accepts a ``Guzzle\Log\MessageFormatter`` or a log messaged format string. The format string uses
|
|
||||||
variable substitution and allows you to define the log data that is important to your application. The different
|
|
||||||
variables that can be injected are as follows:
|
|
||||||
|
|
||||||
================== ====================================================================================
|
|
||||||
Variable Substitution
|
|
||||||
================== ====================================================================================
|
|
||||||
{request} Full HTTP request message
|
|
||||||
{response} Full HTTP response message
|
|
||||||
{ts} Timestamp
|
|
||||||
{host} Host of the request
|
|
||||||
{method} Method of the request
|
|
||||||
{url} URL of the request
|
|
||||||
{host} Host of the request
|
|
||||||
{protocol} Request protocol
|
|
||||||
{version} Protocol version
|
|
||||||
{resource} Resource of the request (path + query + fragment)
|
|
||||||
{port} Port of the request
|
|
||||||
{hostname} Hostname of the machine that sent the request
|
|
||||||
{code} Status code of the response (if available)
|
|
||||||
{phrase} Reason phrase of the response (if available)
|
|
||||||
{curl_error} Curl error message (if available)
|
|
||||||
{curl_code} Curl error code (if available)
|
|
||||||
{curl_stderr} Curl standard error (if available)
|
|
||||||
{connect_time} Time in seconds it took to establish the connection (if available)
|
|
||||||
{total_time} Total transaction time in seconds for last transfer (if available)
|
|
||||||
{req_header_*} Replace `*` with the lowercased name of a request header to add to the message
|
|
||||||
{res_header_*} Replace `*` with the lowercased name of a response header to add to the message
|
|
||||||
{req_body} Request body
|
|
||||||
{res_body} Response body
|
|
||||||
================== ====================================================================================
|
|
||||||
|
|
||||||
The LogPlugin has a helper method that can be used when debugging that will output the full HTTP request and
|
|
||||||
response of a transaction:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client->addSubscriber(LogPlugin::getDebugPlugin());
|
|
@ -1,29 +0,0 @@
|
|||||||
====================
|
|
||||||
MD5 validator plugin
|
|
||||||
====================
|
|
||||||
|
|
||||||
Entity bodies can sometimes be modified over the wire due to a faulty TCP transport or misbehaving proxy. If an HTTP
|
|
||||||
response contains a Content-MD5 header, then a MD5 hash of the entity body of a response can be compared against the
|
|
||||||
Content-MD5 header of the response to determine if the response was delivered intact. The
|
|
||||||
``Guzzle\Plugin\Md5\Md5ValidatorPlugin`` will throw an ``UnexpectedValueException`` if the calculated MD5 hash does
|
|
||||||
not match the Content-MD5 header value:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Md5\Md5ValidatorPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
$md5Plugin = new Md5ValidatorPlugin();
|
|
||||||
|
|
||||||
// Add the md5 plugin to the client object
|
|
||||||
$client->addSubscriber($md5Plugin);
|
|
||||||
|
|
||||||
$request = $client->get('http://www.yahoo.com/');
|
|
||||||
$request->send();
|
|
||||||
|
|
||||||
Calculating the MD5 hash of a large entity body or an entity body that was transferred using a Content-Encoding is an
|
|
||||||
expensive operation. When working in high performance applications, you might consider skipping the MD5 hash
|
|
||||||
validation for entity bodies bigger than a certain size or Content-Encoded entity bodies
|
|
||||||
(see ``Guzzle\Plugin\Md5\Md5ValidatorPlugin`` for more information).
|
|
@ -1,27 +0,0 @@
|
|||||||
===========
|
|
||||||
Mock plugin
|
|
||||||
===========
|
|
||||||
|
|
||||||
The mock plugin is useful for testing Guzzle clients. The mock plugin allows you to queue an array of responses that
|
|
||||||
will satisfy requests sent from a client by consuming the request queue in FIFO order.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Mock\MockPlugin;
|
|
||||||
use Guzzle\Http\Message\Response;
|
|
||||||
|
|
||||||
$client = new Client('http://www.test.com/');
|
|
||||||
|
|
||||||
$mock = new MockPlugin();
|
|
||||||
$mock->addResponse(new Response(200))
|
|
||||||
->addResponse(new Response(404));
|
|
||||||
|
|
||||||
// Add the mock plugin to the client object
|
|
||||||
$client->addSubscriber($mock);
|
|
||||||
|
|
||||||
// The following request will receive a 200 response from the plugin
|
|
||||||
$client->get('http://www.example.com/')->send();
|
|
||||||
|
|
||||||
// The following request will receive a 404 response from the plugin
|
|
||||||
$client->get('http://www.test.com/')->send();
|
|
@ -1,30 +0,0 @@
|
|||||||
============
|
|
||||||
OAuth plugin
|
|
||||||
============
|
|
||||||
|
|
||||||
Guzzle ships with an OAuth 1.0 plugin that can sign requests using a consumer key, consumer secret, OAuth token,
|
|
||||||
and OAuth secret. Here's an example showing how to send an authenticated request to the Twitter REST API:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Http\Client;
|
|
||||||
use Guzzle\Plugin\Oauth\OauthPlugin;
|
|
||||||
|
|
||||||
$client = new Client('http://api.twitter.com/1');
|
|
||||||
$oauth = new OauthPlugin(array(
|
|
||||||
'consumer_key' => 'my_key',
|
|
||||||
'consumer_secret' => 'my_secret',
|
|
||||||
'token' => 'my_token',
|
|
||||||
'token_secret' => 'my_token_secret'
|
|
||||||
));
|
|
||||||
$client->addSubscriber($oauth);
|
|
||||||
|
|
||||||
$response = $client->get('statuses/public_timeline.json')->send();
|
|
||||||
|
|
||||||
If you need to use a custom signing method, you can pass a ``signature_method`` configuration option in the
|
|
||||||
constructor of the OAuth plugin. The ``signature_method`` option must be a callable variable that accepts a string to
|
|
||||||
sign and signing key and returns a signed string.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
You can omit the ``token`` and ``token_secret`` options to use two-legged OAuth.
|
|
@ -1,9 +0,0 @@
|
|||||||
* :doc:`/plugins/async-plugin`
|
|
||||||
* :doc:`/plugins/backoff-plugin`
|
|
||||||
* :doc:`/plugins/cache-plugin`
|
|
||||||
* :doc:`/plugins/cookie-plugin`
|
|
||||||
* :doc:`/plugins/history-plugin`
|
|
||||||
* :doc:`/plugins/log-plugin`
|
|
||||||
* :doc:`/plugins/md5-validator-plugin`
|
|
||||||
* :doc:`/plugins/mock-plugin`
|
|
||||||
* :doc:`/plugins/oauth-plugin`
|
|
@ -1,59 +0,0 @@
|
|||||||
======================
|
|
||||||
Plugin system overview
|
|
||||||
======================
|
|
||||||
|
|
||||||
The workflow of sending a request and parsing a response is driven by Guzzle's event system, which is powered by the
|
|
||||||
`Symfony2 Event Dispatcher component <http://symfony.com/doc/current/components/event_dispatcher/introduction.html>`_.
|
|
||||||
|
|
||||||
Any object in Guzzle that emits events will implement the ``Guzzle\Common\HasEventDispatcher`` interface. You can add
|
|
||||||
event subscribers directly to these objects using the ``addSubscriber()`` method, or you can grab the
|
|
||||||
``Symfony\Component\EventDispatcher\EventDispatcher`` object owned by the object using ``getEventDispatcher()`` and
|
|
||||||
add a listener or event subscriber.
|
|
||||||
|
|
||||||
Adding event subscribers to clients
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
Any event subscriber or event listener attached to the EventDispatcher of a ``Guzzle\Http\Client`` or
|
|
||||||
``Guzzle\Service\Client`` object will automatically be attached to all request objects created by the client. This
|
|
||||||
allows you to attach, for example, a HistoryPlugin to a client object, and from that point on, every request sent
|
|
||||||
through that client will utilize the HistoryPlugin.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Plugin\History\HistoryPlugin;
|
|
||||||
use Guzzle\Service\Client;
|
|
||||||
|
|
||||||
$client = new Client();
|
|
||||||
|
|
||||||
// Create a history plugin and attach it to the client
|
|
||||||
$history = new HistoryPlugin();
|
|
||||||
$client->addSubscriber($history);
|
|
||||||
|
|
||||||
// Create and send a request. This request will also utilize the HistoryPlugin
|
|
||||||
$client->get('http://httpbin.org')->send();
|
|
||||||
|
|
||||||
// Echo out the last sent request by the client
|
|
||||||
echo $history->getLastRequest();
|
|
||||||
|
|
||||||
.. tip::
|
|
||||||
|
|
||||||
:doc:`Create event subscribers <creating-plugins>`, or *plugins*, to implement reusable logic that can be
|
|
||||||
shared across clients. Event subscribers are also easier to test than anonymous functions.
|
|
||||||
|
|
||||||
Pre-Built plugins
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Guzzle provides easy to use request plugins that add behavior to requests based on signal slot event notifications
|
|
||||||
powered by the Symfony2 Event Dispatcher component.
|
|
||||||
|
|
||||||
* :doc:`async-plugin`
|
|
||||||
* :doc:`backoff-plugin`
|
|
||||||
* :doc:`cache-plugin`
|
|
||||||
* :doc:`cookie-plugin`
|
|
||||||
* :doc:`curl-auth-plugin`
|
|
||||||
* :doc:`history-plugin`
|
|
||||||
* :doc:`log-plugin`
|
|
||||||
* :doc:`md5-validator-plugin`
|
|
||||||
* :doc:`mock-plugin`
|
|
||||||
* :doc:`oauth-plugin`
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
Sphinx>=1.2b1
|
|
||||||
guzzle_sphinx_theme>=0.5.0
|
|
@ -1,201 +0,0 @@
|
|||||||
===========================
|
|
||||||
Unit Testing Guzzle clients
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Guzzle provides several tools that will enable you to easily unit test your web service clients.
|
|
||||||
|
|
||||||
* PHPUnit integration
|
|
||||||
* Mock responses
|
|
||||||
* node.js web server for integration testing
|
|
||||||
|
|
||||||
PHPUnit integration
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Guzzle is unit tested using `PHPUnit <http://www.phpunit.de/>`_. Your web service client's unit tests should extend
|
|
||||||
``Guzzle\Tests\GuzzleTestCase`` so that you can take advantage of some of the built in helpers.
|
|
||||||
|
|
||||||
In order to unit test your client, a developer would need to copy phpunit.xml.dist to phpunit.xml and make any needed
|
|
||||||
modifications. As a best practice and security measure for you and your contributors, it is recommended to add an
|
|
||||||
ignore statement to your SCM so that phpunit.xml is ignored.
|
|
||||||
|
|
||||||
Bootstrapping
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Your web service client should have a tests/ folder that contains a bootstrap.php file. The bootstrap.php file
|
|
||||||
responsible for autoloading and configuring a ``Guzzle\Service\Builder\ServiceBuilder`` that is used throughout your
|
|
||||||
unit tests for loading a configured client. You can add custom parameters to your phpunit.xml file that expects users
|
|
||||||
to provide the path to their configuration data.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
Guzzle\Tests\GuzzleTestCase::setServiceBuilder(Aws\Common\Aws::factory($_SERVER['CONFIG']));
|
|
||||||
|
|
||||||
Guzzle\Tests\GuzzleTestCase::setServiceBuilder(Guzzle\Service\Builder\ServiceBuilder::factory(array(
|
|
||||||
'test.unfuddle' => array(
|
|
||||||
'class' => 'Guzzle.Unfuddle.UnfuddleClient',
|
|
||||||
'params' => array(
|
|
||||||
'username' => 'test_user',
|
|
||||||
'password' => '****',
|
|
||||||
'subdomain' => 'test'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)));
|
|
||||||
|
|
||||||
The above code registers a service builder that can be used throughout your unit tests. You would then be able to
|
|
||||||
retrieve an instantiated and configured Unfuddle client by calling ``$this->getServiceBuilder()->get('test.unfuddle)``.
|
|
||||||
The above code assumes that ``$_SERVER['CONFIG']`` contains the path to a file that stores service description
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
Unit testing remote APIs
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
Mock responses
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
One of the benefits of unit testing is the ability to quickly determine if there are errors in your code. If your
|
|
||||||
unit tests run slowly, then they become tedious and will likely be run less frequently. Guzzle's philosophy on unit
|
|
||||||
testing web service clients is that no network access should be required to run the unit tests. This means that
|
|
||||||
responses are served from mock responses or local servers. By adhering to this principle, tests will run much faster
|
|
||||||
and will not require an external resource to be available. The problem with this approach is that your mock responses
|
|
||||||
must first be gathered and then subsequently updated each time the remote API changes.
|
|
||||||
|
|
||||||
Integration testing over the internet
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can perform integration testing with a web service over the internet by making calls directly to the service. If
|
|
||||||
the web service you are requesting uses a complex signing algorithm or some other specific implementation, then you
|
|
||||||
may want to include at least one actual network test that can be run specifically through the command line using
|
|
||||||
`PHPUnit group annotations <http://www.phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group>`_.
|
|
||||||
|
|
||||||
@group internet annotation
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
When creating tests that require an internet connection, it is recommended that you add ``@group internet`` annotations
|
|
||||||
to your unit tests to specify which tests require network connectivity.
|
|
||||||
|
|
||||||
You can then `run PHPUnit tests <http://www.phpunit.de/manual/current/en/textui.html>`_ that exclude the @internet
|
|
||||||
group by running ``phpunit --exclude-group internet``.
|
|
||||||
|
|
||||||
API credentials
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
If API credentials are required to run your integration tests, you must add ``<php>`` parameters to your
|
|
||||||
phpunit.xml.dist file and extract these parameters in your bootstrap.php file.
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<phpunit bootstrap="./tests/bootstrap.php" colors="true">
|
|
||||||
<php>
|
|
||||||
<!-- Specify the path to a service configuration file -->
|
|
||||||
<server name="CONFIG" value="test_services.json" />
|
|
||||||
<!-- Or, specify each require parameter individually -->
|
|
||||||
<server name="API_USER" value="change_me" />
|
|
||||||
<server name="API_PASSWORD" value="****" />
|
|
||||||
</php>
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="guzzle-service">
|
|
||||||
<directory suffix="Test.php">./Tests</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
</phpunit>
|
|
||||||
|
|
||||||
You can then extract the ``server`` variables in your bootstrap.php file by grabbing them from the ``$_SERVER``
|
|
||||||
superglobal: ``$apiUser = $_SERVER['API_USER'];``
|
|
||||||
|
|
||||||
Further reading
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
A good discussion on the topic of testing remote APIs can be found in Sebastian Bergmann's
|
|
||||||
`Real-World Solutions for Developing High-Quality PHP Frameworks and Applications <http://www.amazon.com/dp/0470872497>`_.
|
|
||||||
|
|
||||||
Queueing Mock responses
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Mock responses can be used to test if requests are being generated correctly and responses and handled correctly by
|
|
||||||
your client. Mock responses can be queued up for a client using the ``$this->setMockResponse($client, $path)`` method
|
|
||||||
of your test class. Pass the client you are adding mock responses to and a single path or array of paths to mock
|
|
||||||
response files relative to the ``/tests/mock/ folder``. This will queue one or more mock responses for your client by
|
|
||||||
creating a simple observer on the client. Mock response files must contain a full HTTP response message:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Date: Wed, 25 Nov 2009 12:00:00 GMT
|
|
||||||
Connection: close
|
|
||||||
Server: AmazonS3
|
|
||||||
Content-Type: application/xml
|
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
|
|
||||||
|
|
||||||
After queuing mock responses for a client, you can get an array of the requests that were sent by the client that
|
|
||||||
were issued a mock response by calling ``$this->getMockedRequests()``.
|
|
||||||
|
|
||||||
You can also use the ``Guzzle\Plugin\Mock\MockPlugin`` object directly with your clients.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$plugin = new Guzzle\Plugin\Mock\MockPlugin();
|
|
||||||
$plugin->addResponse(new Guzzle\Http\Message\Response(200));
|
|
||||||
$client = new Guzzle\Http\Client();
|
|
||||||
$client->addSubscriber($plugin);
|
|
||||||
|
|
||||||
// The following request will get the mock response from the plugin in FIFO order
|
|
||||||
$request = $client->get('http://www.test.com/');
|
|
||||||
$request->send();
|
|
||||||
|
|
||||||
// The MockPlugin maintains a list of requests that were mocked
|
|
||||||
$this->assertContainsOnly($request, $plugin->getReceivedRequests());
|
|
||||||
|
|
||||||
node.js web server for integration testing
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
Using mock responses is usually enough when testing a web service client. If your client needs to add custom cURL
|
|
||||||
options to requests, then you should use the node.js test web server to ensure that your HTTP request message is
|
|
||||||
being created correctly.
|
|
||||||
|
|
||||||
Guzzle is based around PHP's libcurl bindings. cURL sometimes modifies an HTTP request message based on
|
|
||||||
``CURLOPT_*`` options. Headers that are added to your request by cURL will not be accounted for if you inject mock
|
|
||||||
responses into your tests. Additionally, some request entity bodies cannot be loaded by the client before transmitting
|
|
||||||
it to the sever (for example, when using a client as a sort of proxy and streaming content from a remote server). You
|
|
||||||
might also need to inspect the entity body of a ``multipart/form-data`` POST request.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
You can skip all of the tests that require the node.js test web server by excluding the ``server`` group:
|
|
||||||
``phpunit --exclude-group server``
|
|
||||||
|
|
||||||
Using the test server
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The node.js test server receives requests and returns queued responses. The test server exposes a simple API that is
|
|
||||||
used to enqueue responses and inspect the requests that it has received.
|
|
||||||
|
|
||||||
Retrieve the server object by calling ``$this->getServer()``. If the node.js server is not running, it will be
|
|
||||||
started as a forked process and an object that interfaces with the server will be returned. (note: stopping the
|
|
||||||
server is handled internally by Guzzle.)
|
|
||||||
|
|
||||||
You can queue an HTTP response or an array of responses by calling ``$this->getServer()->enqueue()``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
|
|
||||||
|
|
||||||
The above code queues a single 200 response with an empty body. Responses are queued using a FIFO order; this
|
|
||||||
response will be returned by the server when it receives the first request and then removed from the queue. If a
|
|
||||||
request is received by a server with no queued responses, an exception will be thrown in your unit test.
|
|
||||||
|
|
||||||
You can inspect the requests that the server has retrieved by calling ``$this->getServer()->getReceivedRequests()``.
|
|
||||||
This method accepts an optional ``$hydrate`` parameter that specifies if you are retrieving an array of string HTTP
|
|
||||||
requests or an array of ``Guzzle\Http\RequestInterface`` subclassed objects. "Hydrating" the requests will allow
|
|
||||||
greater flexibility in your unit tests so that you can easily assert the state of the various parts of a request.
|
|
||||||
|
|
||||||
You will need to modify the base_url of your web service client in order to use it against the test server.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = $this->getServiceBuilder()->get('my_client');
|
|
||||||
$client->setBaseUrl($this->getServer()->getUrl());
|
|
||||||
|
|
||||||
After running the above code, all calls made from the ``$client`` object will be sent to the test web server.
|
|
@ -1,619 +0,0 @@
|
|||||||
===========================
|
|
||||||
Guzzle service descriptions
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Guzzle allows you to serialize HTTP requests and parse HTTP responses using a DSL called a service descriptions.
|
|
||||||
Service descriptions define web service APIs by documenting each operation, the operation's parameters, validation
|
|
||||||
options for each parameter, an operation's response, how the response is parsed, and any errors that can be raised for
|
|
||||||
an operation. Writing a service description for a web service allows you to more quickly consume a web service than
|
|
||||||
writing concrete commands for each web service operation.
|
|
||||||
|
|
||||||
Guzzle service descriptions can be representing using a PHP array or JSON document. Guzzle's service descriptions are
|
|
||||||
heavily inspired by `Swagger <http://swagger.wordnik.com/>`_.
|
|
||||||
|
|
||||||
Service description schema
|
|
||||||
==========================
|
|
||||||
|
|
||||||
A Guzzle Service description must match the following JSON schema document. This document can also serve as a guide when
|
|
||||||
implementing a Guzzle service description.
|
|
||||||
|
|
||||||
Download the schema here: :download:`Guzzle JSON schema document </_downloads/guzzle-schema-1.0.json>`
|
|
||||||
|
|
||||||
.. class:: overflow-height-500px
|
|
||||||
|
|
||||||
.. literalinclude:: ../_downloads/guzzle-schema-1.0.json
|
|
||||||
:language: json
|
|
||||||
|
|
||||||
Top-level attributes
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Service descriptions are comprised of the following top-level attributes:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "string",
|
|
||||||
"apiVersion": "string|number",
|
|
||||||
"baseUrl": "string",
|
|
||||||
"description": "string",
|
|
||||||
"operations": {},
|
|
||||||
"models": {},
|
|
||||||
"includes": ["string.php", "string.json"]
|
|
||||||
}
|
|
||||||
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| Property Name | Value | Description |
|
|
||||||
+=========================================+=========================+=======================================================================================================================+
|
|
||||||
| name | string | Name of the web service |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| apiVersion | string|number | Version identifier that the service description is compatible with |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| baseUrl or basePath | string | Base URL of the web service. Any relative URI specified in an operation will be merged with the baseUrl using the |
|
|
||||||
| | | process defined in RFC 2396. Some clients require custom logic to determine the baseUrl. In those cases, it is best |
|
|
||||||
| | | to not include a baseUrl in the service description, but rather allow the factory method of the client to configure |
|
|
||||||
| | | the client’s baseUrl. |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| description | string | Short summary of the web service |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| operations | object containing | Operations of the service. The key is the name of the operation and value is the attributes of the operation. |
|
|
||||||
| | :ref:`operation-schema` | |
|
|
||||||
| | | |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| models | object containing | Schema models that can be referenced throughout the service description. Models can be used to define how an HTTP |
|
|
||||||
| | :ref:`model-schema` | response is parsed into a ``Guzzle\Service\Resource\Model`` object when an operation uses a ``model`` ``responseType``|
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| includes | array of .js, | Service description files to include and extend from (can be a .json, .js, or .php file) |
|
|
||||||
| | .json, or .php | |
|
|
||||||
| | files. | |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| (any additional properties) | mixed | Any additional properties specified as top-level attributes are allowed and will be treated as arbitrary data |
|
|
||||||
+-----------------------------------------+-------------------------+-----------------------------------------------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
.. _operation-schema:
|
|
||||||
|
|
||||||
Operations
|
|
||||||
----------
|
|
||||||
|
|
||||||
Operations are the actions that can be taken on a service. Each operation is given a unique name and has a distinct
|
|
||||||
endpoint and HTTP method. If an API has a ``DELETE /users/:id`` operation, a satisfactory operation name might be
|
|
||||||
``DeleteUser`` with a parameter of ``id`` that is inserted into the URI.
|
|
||||||
|
|
||||||
.. class:: overflow-height-250px
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"operations": {
|
|
||||||
"operationName": {
|
|
||||||
"extends": "string",
|
|
||||||
"httpMethod": "GET|POST|PUT|DELETE|PATCH|string",
|
|
||||||
"uri": "string",
|
|
||||||
"summary": "string",
|
|
||||||
"class": "string",
|
|
||||||
"responseClass": "string",
|
|
||||||
"responseNotes": "string",
|
|
||||||
"type": "string",
|
|
||||||
"description": "string",
|
|
||||||
"responseType": "primitive|class|(model by name)|documentation|(string)",
|
|
||||||
"deprecated": false,
|
|
||||||
"errorResponses": [
|
|
||||||
{
|
|
||||||
"code": 500,
|
|
||||||
"reason": "Unexpected Error",
|
|
||||||
"class": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"data": {
|
|
||||||
"foo": "bar",
|
|
||||||
"baz": "bam"
|
|
||||||
},
|
|
||||||
"parameters": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. csv-table::
|
|
||||||
:header: "Property Name", "Value", "Description"
|
|
||||||
:widths: 20, 15, 65
|
|
||||||
|
|
||||||
"extends", "string", "Extend from another operation by name. The parent operation must be defined before the child."
|
|
||||||
"httpMethod", "string", "HTTP method used with the operation (e.g. GET, POST, PUT, DELETE, PATCH, etc)"
|
|
||||||
"uri", "string", "URI of the operation. The uri attribute can contain URI templates. The variables of the URI template are parameters of the operation with a location value of uri"
|
|
||||||
"summary", "string", "Short summary of what the operation does"
|
|
||||||
"class", "string", "Custom class to instantiate instead of the default Guzzle\\Service\\Command\\OperationCommand. Using this attribute allows you to define an operation using a service description, but allows more customized logic to be implemented in user-land code."
|
|
||||||
"responseClass", "string", "Defined what is returned from the method. Can be a primitive, class name, or model name. You can specify the name of a class to return a more customized result from the operation (for example, a domain model object). When using the name of a PHP class, the class must implement ``Guzzle\Service\Command\ResponseClassInterface``."
|
|
||||||
"responseNotes", "string", "A description of the response returned by the operation"
|
|
||||||
"responseType", "string", "The type of response that the operation creates: one of primitive, class, model, or documentation. If not specified, this value will be automatically inferred based on whether or not there is a model matching the name, if a matching class name is found, or set to 'primitive' by default."
|
|
||||||
"deprecated", "boolean", "Whether or not the operation is deprecated"
|
|
||||||
"errorResponses", "array", "Errors that could occur while executing the operation. Each item of the array is an object that can contain a 'code' (HTTP response status code of the error), 'reason' (reason phrase or description of the error), and 'class' (an exception class that will be raised when this error is encountered)"
|
|
||||||
"data", "object", "Any arbitrary data to associate with the operation"
|
|
||||||
"parameters", "object containing :ref:`parameter-schema` objects", "Parameters of the operation. Parameters are used to define how input data is serialized into a HTTP request."
|
|
||||||
"additionalParameters", "A single :ref:`parameter-schema` object", "Validation and serialization rules for any parameter supplied to the operation that was not explicitly defined."
|
|
||||||
|
|
||||||
additionalParameters
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
When a webservice offers a large number of parameters that all are set in the same location (for example the query
|
|
||||||
string or a JSON document), defining each parameter individually can require a lot of time and repetition. Furthermore,
|
|
||||||
some web services allow for completely arbitrary parameters to be supplied for an operation. The
|
|
||||||
``additionalParameters`` attribute can be used to solve both of these issues.
|
|
||||||
|
|
||||||
As an example, we can define a Twitter API operation quite easily using ``additionalParameters``. The
|
|
||||||
GetMentions operation accepts a large number of query string parameters. Defining each of these parameters
|
|
||||||
is ideal because it provide much more introspection for the client and opens the possibility to use the description with
|
|
||||||
other tools (e.g. a documentation generator). However, you can very quickly provide a "catch-all" serialization rule
|
|
||||||
that will place any custom parameters supplied to an operation the generated request's query string parameters.
|
|
||||||
|
|
||||||
.. class:: overflow-height-250px
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Twitter",
|
|
||||||
"apiVersion": "1.1",
|
|
||||||
"baseUrl": "https://api.twitter.com/1.1",
|
|
||||||
"operations": {
|
|
||||||
"GetMentions": {
|
|
||||||
"httpMethod": "GET",
|
|
||||||
"uri": "statuses/mentions_timeline.json",
|
|
||||||
"responseClass": "GetMentionsOutput",
|
|
||||||
"additionalParameters": {
|
|
||||||
"location": "query"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"GetMentionsOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"location": "json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
responseClass
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``responseClass`` attribute is used to define the return value of an operation (what is returned by calling the
|
|
||||||
``getResult()`` method of a command object). The value set in the responseClass attribute can be one of "primitive"
|
|
||||||
(meaning the result with be primitive type like a string), a class name meaning the result will be an instance of a
|
|
||||||
specific user-land class, or a model name meaning the result will be a ``Guzzle\Service\Resource\Model`` object that
|
|
||||||
uses a :ref:`model schema <model-schema>` to define how the HTTP response is parsed.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Using a class name with a ``responseClass`` will only work if it is supported by the ``class`` that is instantiated
|
|
||||||
for the operation. Keep this in mind when specifying a custom ``class`` attribute that points to a custom
|
|
||||||
``Guzzle\Service\Command\CommandInterface`` class. The default ``class``,
|
|
||||||
``Guzzle\Service\Command\OperationCommand``, does support setting custom ``class`` attributes.
|
|
||||||
|
|
||||||
You can specify the name of a class to return a more customized result from the operation (for example, a domain model
|
|
||||||
object). When using the name of a PHP class, the class must implement ``Guzzle\Service\Command\ResponseClassInterface``.
|
|
||||||
Here's a very simple example of implementing a custom responseClass object.
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"operations": {
|
|
||||||
"test": {
|
|
||||||
"responseClass": "MyApplication\\User"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace MyApplication;
|
|
||||||
|
|
||||||
use Guzzle\Service\Command\ResponseClassInterface;
|
|
||||||
use Guzzle\Service\Command\OperationCommand;
|
|
||||||
|
|
||||||
class User implements ResponseClassInterface
|
|
||||||
{
|
|
||||||
protected $name;
|
|
||||||
|
|
||||||
public static function fromCommand(OperationCommand $command)
|
|
||||||
{
|
|
||||||
$response = $command->getResponse();
|
|
||||||
$xml = $response->xml();
|
|
||||||
|
|
||||||
return new self((string) $xml->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct($name)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorResponses
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
``errorResponses`` is an array containing objects that define the errors that could occur while executing the
|
|
||||||
operation. Each item of the array is an object that can contain a 'code' (HTTP response status code of the error),
|
|
||||||
'reason' (reason phrase or description of the error), and 'class' (an exception class that will be raised when this
|
|
||||||
error is encountered).
|
|
||||||
|
|
||||||
ErrorResponsePlugin
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Error responses are by default only used for documentation. If you don't need very complex exception logic for your web
|
|
||||||
service errors, then you can use the ``Guzzle\Plugin\ErrorResponse\ErrorResponsePlugin`` to automatically throw defined
|
|
||||||
exceptions when one of the ``errorResponse`` rules are matched. The error response plugin will listen for the
|
|
||||||
``request.complete`` event of a request created by a command object. Every response (including a successful response) is
|
|
||||||
checked against the list of error responses for an exact match using the following order of checks:
|
|
||||||
|
|
||||||
1. Does the errorResponse have a defined ``class``?
|
|
||||||
2. Is the errorResponse ``code`` equal to the status code of the response?
|
|
||||||
3. Is the errorResponse ``reason`` equal to the reason phrase of the response?
|
|
||||||
4. Throw the exception stored in the ``class`` attribute of the errorResponse.
|
|
||||||
|
|
||||||
The ``class`` attribute must point to a class that implements
|
|
||||||
``Guzzle\Plugin\ErrorResponse\ErrorResponseExceptionInterface``. This interface requires that an error response class
|
|
||||||
implements ``public static function fromCommand(CommandInterface $command, Response $response)``. This method must
|
|
||||||
return an object that extends from ``\Exception``. After an exception is returned, it is thrown by the plugin.
|
|
||||||
|
|
||||||
.. _parameter-schema:
|
|
||||||
|
|
||||||
Parameter schema
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Parameters in both operations and models are represented using the
|
|
||||||
`JSON schema <http://tools.ietf.org/id/draft-zyp-json-schema-04.html>`_ syntax.
|
|
||||||
|
|
||||||
.. csv-table::
|
|
||||||
:header: "Property Name", "Value", "Description"
|
|
||||||
:widths: 20, 15, 65
|
|
||||||
|
|
||||||
"name", "string", "Unique name of the parameter"
|
|
||||||
"type", "string|array", "Type of variable (string, number, integer, boolean, object, array, numeric, null, any). Types are using for validation and determining the structure of a parameter. You can use a union type by providing an array of simple types. If one of the union types matches the provided value, then the value is valid."
|
|
||||||
"instanceOf", "string", "When the type is an object, you can specify the class that the object must implement"
|
|
||||||
"required", "boolean", "Whether or not the parameter is required"
|
|
||||||
"default", "mixed", "Default value to use if no value is supplied"
|
|
||||||
"static", "boolean", "Set to true to specify that the parameter value cannot be changed from the default setting"
|
|
||||||
"description", "string", "Documentation of the parameter"
|
|
||||||
"location", "string", "The location of a request used to apply a parameter. Custom locations can be registered with a command, but the defaults are uri, query, statusCode, reasonPhrase, header, body, json, xml, postField, postFile, responseBody"
|
|
||||||
"sentAs", "string", "Specifies how the data being modeled is sent over the wire. For example, you may wish to include certain headers in a response model that have a normalized casing of FooBar, but the actual header is x-foo-bar. In this case, sentAs would be set to x-foo-bar."
|
|
||||||
"filters", "array", "Array of functions to to run a parameter value through."
|
|
||||||
|
|
||||||
filters
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
Each value in the array must be a string containing the full class path to a static method or an array of complex
|
|
||||||
filter information. You can specify static methods of classes using the full namespace class name followed by
|
|
||||||
"::" (e.g. ``FooBar::baz()``). Some filters require arguments in order to properly filter a value. For complex filters,
|
|
||||||
use an object containing a ``method`` attribute pointing to a function, and an ``args`` attribute containing an
|
|
||||||
array of positional arguments to pass to the function. Arguments can contain keywords that are replaced when filtering
|
|
||||||
a value: ``@value`` is replaced with the value being filtered, and ``@api`` is replaced with the actual Parameter
|
|
||||||
object.
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"filters": [
|
|
||||||
"strtolower",
|
|
||||||
{
|
|
||||||
"method": "MyClass::convertString",
|
|
||||||
"args": [ "test", "@value", "@api" ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
The above example will filter a parameter using ``strtolower``. It will then call the ``convertString`` static method
|
|
||||||
of ``MyClass``, passing in "test", the actual value of the parameter, and a ``Guzzle\Service\Description\Parameter``
|
|
||||||
object.
|
|
||||||
|
|
||||||
Operation parameter location attributes
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The location field of top-level parameters control how a parameter is serialized when generating a request.
|
|
||||||
|
|
||||||
uri location
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are injected into the ``uri`` attribute of the operation using
|
|
||||||
`URI-template expansion <http://tools.ietf.org/html/rfc6570>`_.
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"operations": {
|
|
||||||
"uriTest": {
|
|
||||||
"uri": "/test/{testValue}",
|
|
||||||
"parameters": {
|
|
||||||
"testValue": {
|
|
||||||
"location": "uri"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query location
|
|
||||||
^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are injected into the query string of a request. Query values can be nested, which would result in a PHP
|
|
||||||
style nested query string. The name of a parameter is the default name of the query string parameter added to the
|
|
||||||
request. You can override this behavior by specifying the ``sentAs`` attribute on the parameter.
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"operations": {
|
|
||||||
"queryTest": {
|
|
||||||
"parameters": {
|
|
||||||
"testValue": {
|
|
||||||
"location": "query",
|
|
||||||
"sentAs": "test_value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header location
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are injected as headers on an HTTP request. The name of the parameter is used as the name of the header by
|
|
||||||
default. You can change the name of the header created by the parameter using the ``sentAs`` attribute.
|
|
||||||
|
|
||||||
Headers that are of type ``object`` will be added as multiple headers to a request using the key of the input array as
|
|
||||||
the header key. Setting a ``sentAs`` attribute along with a type ``object`` will use the value of ``sentAs`` as a
|
|
||||||
prefix for each header key.
|
|
||||||
|
|
||||||
body location
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are injected as the body of a request. The input of these parameters may be anything that can be cast to a
|
|
||||||
string or a ``Guzzle\Http\EntityBodyInterface`` object.
|
|
||||||
|
|
||||||
postField location
|
|
||||||
^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are inserted as POST fields in a request. Nested values may be supplied and will be represented using
|
|
||||||
PHP style nested query strings. The POST field name is the same as the parameter name by default. You can use the
|
|
||||||
``sentAs`` parameter to override the POST field name.
|
|
||||||
|
|
||||||
postFile location
|
|
||||||
^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are added as POST files. A postFile value may be a string pointing to a local filename or a
|
|
||||||
``Guzzle\Http\Message\PostFileInterface`` object. The name of the POST file will be the name of the parameter by
|
|
||||||
default. You can use a custom POST file name by using the ``sentAs`` attribute.
|
|
||||||
|
|
||||||
Supports "string" and "array" types.
|
|
||||||
|
|
||||||
json location
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are added to the body of a request as top level keys of a JSON document. Nested values may be specified,
|
|
||||||
with any number of nested ``Guzzle\Common\ToArrayInterface`` objects. When JSON parameters are specified, the
|
|
||||||
``Content-Type`` of the request will change to ``application/json`` if a ``Content-Type`` has not already been specified
|
|
||||||
on the request.
|
|
||||||
|
|
||||||
xml location
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Parameters are added to the body of a request as top level nodes of an XML document. Nested values may be specified,
|
|
||||||
with any number of nested ``Guzzle\Common\ToArrayInterface`` objects. When XML parameters are specified, the
|
|
||||||
``Content-Type`` of the request will change to ``application/xml`` if a ``Content-Type`` has not already been specified
|
|
||||||
on the request.
|
|
||||||
|
|
||||||
responseBody location
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Specifies the EntityBody of a response. This can be used to download the response body to a file or a custom Guzzle
|
|
||||||
EntityBody object.
|
|
||||||
|
|
||||||
No location
|
|
||||||
^^^^^^^^^^^
|
|
||||||
|
|
||||||
If a parameter has no location attribute, then the parameter is simply used as a data value.
|
|
||||||
|
|
||||||
Other locations
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Custom locations can be registered as new locations or override default locations if needed.
|
|
||||||
|
|
||||||
.. _model-schema:
|
|
||||||
|
|
||||||
Model Schema
|
|
||||||
------------
|
|
||||||
|
|
||||||
Models are used in service descriptions to provide generic JSON schema definitions that can be extended from or used in
|
|
||||||
``$ref`` attributes. Models can also be referenced in a ``responseClass`` attribute to provide valuable output to an
|
|
||||||
operation. Models are JSON schema documents and use the exact syntax and attributes used in parameters.
|
|
||||||
|
|
||||||
Response Models
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Response models describe how a response is parsed into a ``Guzzle\Service\Resource\Model`` object. Response models are
|
|
||||||
always modeled as JSON schema objects. When an HTTP response is parsed using a response model, the rules specified on
|
|
||||||
each property of a response model will translate 1:1 as keys in a PHP associative array. When a ``sentAs`` attribute is
|
|
||||||
found in response model parameters, the value retrieved from the HTTP response is retrieved using the ``sentAs``
|
|
||||||
parameter but stored in the response model using the name of the parameter.
|
|
||||||
|
|
||||||
The location field of top-level parameters in a response model tell response parsers how data is retrieved from a
|
|
||||||
response.
|
|
||||||
|
|
||||||
statusCode location
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves the status code of the response.
|
|
||||||
|
|
||||||
reasonPhrase location
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves the reason phrase of the response.
|
|
||||||
|
|
||||||
header location
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves a header from the HTTP response.
|
|
||||||
|
|
||||||
body location
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves the body of an HTTP response.
|
|
||||||
|
|
||||||
json location
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves a top-level parameter from a JSON document contained in an HTTP response.
|
|
||||||
|
|
||||||
You can use ``additionalProperties`` if the JSON document is wrapped in an outer array. This allows you to parse the
|
|
||||||
contents of each item in the array using the parsing rules defined in the ``additionalProperties`` schema.
|
|
||||||
|
|
||||||
xml location
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Retrieves a top-level node value from an XML document contained in an HTTP response.
|
|
||||||
|
|
||||||
Other locations
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Custom locations can be registered as new locations or override default locations if needed.
|
|
||||||
|
|
||||||
Example service description
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Let's say you're interacting with a web service called 'Foo' that allows for the following routes and methods::
|
|
||||||
|
|
||||||
GET/POST /users
|
|
||||||
GET/DELETE /users/:id
|
|
||||||
|
|
||||||
The following JSON service description implements this simple web service:
|
|
||||||
|
|
||||||
.. class:: overflow-height-500px
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Foo",
|
|
||||||
"apiVersion": "2012-10-14",
|
|
||||||
"baseUrl": "http://api.foo.com",
|
|
||||||
"description": "Foo is an API that allows you to Baz Bar",
|
|
||||||
"operations": {
|
|
||||||
"GetUsers": {
|
|
||||||
"httpMethod": "GET",
|
|
||||||
"uri": "/users",
|
|
||||||
"summary": "Gets a list of users",
|
|
||||||
"responseClass": "GetUsersOutput"
|
|
||||||
},
|
|
||||||
"CreateUser": {
|
|
||||||
"httpMethod": "POST",
|
|
||||||
"uri": "/users",
|
|
||||||
"summary": "Creates a new user",
|
|
||||||
"responseClass": "CreateUserOutput",
|
|
||||||
"parameters": {
|
|
||||||
"name": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"age": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"GetUser": {
|
|
||||||
"httpMethod": "GET",
|
|
||||||
"uri": "/users/{id}",
|
|
||||||
"summary": "Retrieves a single user",
|
|
||||||
"responseClass": "GetUserOutput",
|
|
||||||
"parameters": {
|
|
||||||
"id": {
|
|
||||||
"location": "uri",
|
|
||||||
"description": "User to retrieve by ID",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"DeleteUser": {
|
|
||||||
"httpMethod": "DELETE",
|
|
||||||
"uri": "/users/{id}",
|
|
||||||
"summary": "Deletes a user",
|
|
||||||
"responseClass": "DeleteUserOutput",
|
|
||||||
"parameters": {
|
|
||||||
"id": {
|
|
||||||
"location": "uri",
|
|
||||||
"description": "User to delete by ID",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"GetUsersOutput": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"age": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"CreateUserOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"location": {
|
|
||||||
"location": "header",
|
|
||||||
"sentAs": "Location",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"GetUserOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"age": {
|
|
||||||
"location": "json",
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"DeleteUserOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"status": {
|
|
||||||
"location": "statusCode",
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
If you attach this service description to a client, you would completely configure the client to interact with the
|
|
||||||
Foo web service and provide valuable response models for each operation.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Service\Description\ServiceDescription;
|
|
||||||
|
|
||||||
$description = ServiceDescription::factory('/path/to/client.json');
|
|
||||||
$client->setDescription($description);
|
|
||||||
|
|
||||||
$command = $client->getCommand('DeleteUser', array('id' => 123));
|
|
||||||
$responseModel = $client->execute($command);
|
|
||||||
echo $responseModel['status'];
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
You can add the service description to your client's factory method or constructor.
|
|
@ -1,316 +0,0 @@
|
|||||||
=======================
|
|
||||||
Using a service builder
|
|
||||||
=======================
|
|
||||||
|
|
||||||
The best way to instantiate Guzzle web service clients is to let Guzzle handle building the clients for you using a
|
|
||||||
ServiceBuilder. A ServiceBuilder is responsible for creating concrete client objects based on configuration settings
|
|
||||||
and helps to manage credentials for different environments.
|
|
||||||
|
|
||||||
You don't have to use a service builder, but they help to decouple your application from concrete classes and help to
|
|
||||||
share configuration data across multiple clients. Consider the following example. Here we are creating two clients that
|
|
||||||
require the same API public key and secret key. The clients are created using their ``factory()`` methods.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use MyService\FooClient;
|
|
||||||
use MyService\BarClient;
|
|
||||||
|
|
||||||
$foo = FooClient::factory(array(
|
|
||||||
'key' => 'abc',
|
|
||||||
'secret' => '123',
|
|
||||||
'custom' => 'and above all'
|
|
||||||
));
|
|
||||||
|
|
||||||
$bar = BarClient::factory(array(
|
|
||||||
'key' => 'abc',
|
|
||||||
'secret' => '123',
|
|
||||||
'custom' => 'listen to me'
|
|
||||||
));
|
|
||||||
|
|
||||||
The redundant specification of the API keys can be removed using a service builder.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Service\Builder\ServiceBuilder;
|
|
||||||
|
|
||||||
$builder = ServiceBuilder::factory(array(
|
|
||||||
'services' => array(
|
|
||||||
'abstract_client' => array(
|
|
||||||
'params' => array(
|
|
||||||
'key' => 'abc',
|
|
||||||
'secret' => '123'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'foo' => array(
|
|
||||||
'extends' => 'abstract_client',
|
|
||||||
'class' => 'MyService\FooClient',
|
|
||||||
'params' => array(
|
|
||||||
'custom' => 'and above all'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'bar' => array(
|
|
||||||
'extends' => 'abstract_client',
|
|
||||||
'class' => 'MyService\FooClient',
|
|
||||||
'params' => array(
|
|
||||||
'custom' => 'listen to me'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
$foo = $builder->get('foo');
|
|
||||||
$bar = $builder->get('bar');
|
|
||||||
|
|
||||||
You can make managing your API keys even easier by saving the service builder configuration in a JSON format in a
|
|
||||||
.json file.
|
|
||||||
|
|
||||||
Creating a service builder
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
A ServiceBuilder can source information from an array, an PHP include file that returns an array, or a JSON file.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Service\Builder\ServiceBuilder;
|
|
||||||
|
|
||||||
// Source service definitions from a JSON file
|
|
||||||
$builder = ServiceBuilder::factory('services.json');
|
|
||||||
|
|
||||||
Sourcing data from an array
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Data can be source from a PHP array. The array must contain an associative ``services`` array that maps the name of a
|
|
||||||
client to the configuration information used by the service builder to create the client. Clients are given names
|
|
||||||
which are used to identify how a client is retrieved from a service builder. This can be useful for using multiple
|
|
||||||
accounts for the same service or creating development clients vs. production clients.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$services = array(
|
|
||||||
'includes' => array(
|
|
||||||
'/path/to/other/services.json',
|
|
||||||
'/path/to/other/php_services.php'
|
|
||||||
),
|
|
||||||
'services' => array(
|
|
||||||
'abstract.foo' => array(
|
|
||||||
'params' => array(
|
|
||||||
'username' => 'foo',
|
|
||||||
'password' => 'bar'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'bar' => array(
|
|
||||||
'extends' => 'abstract.foo',
|
|
||||||
'class' => 'MyClientClass',
|
|
||||||
'params' => array(
|
|
||||||
'other' => 'abc'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
A service builder configuration array contains two top-level array keys:
|
|
||||||
|
|
||||||
+------------+---------------------------------------------------------------------------------------------------------+
|
|
||||||
| Key | Description |
|
|
||||||
+============+=========================================================================================================+
|
|
||||||
| includes | Array of paths to JSON or PHP include files to include in the configuration. |
|
|
||||||
+------------+---------------------------------------------------------------------------------------------------------+
|
|
||||||
| services | Associative array of defined services that can be created by the service builder. Each service can |
|
|
||||||
| | contain the following keys: |
|
|
||||||
| | |
|
|
||||||
| | +------------+----------------------------------------------------------------------------------------+ |
|
|
||||||
| | | Key | Description | |
|
|
||||||
| | +============+========================================================================================+ |
|
|
||||||
| | | class | The concrete class to instantiate that implements the | |
|
|
||||||
| | | | ``Guzzle\Common\FromConfigInterface``. | |
|
|
||||||
| | +------------+----------------------------------------------------------------------------------------+ |
|
|
||||||
| | | extends | The name of a previously defined service to extend from | |
|
|
||||||
| | +------------+----------------------------------------------------------------------------------------+ |
|
|
||||||
| | | params | Associative array of parameters to pass to the factory method of the service it is | |
|
|
||||||
| | | | instantiated | |
|
|
||||||
| | +------------+----------------------------------------------------------------------------------------+ |
|
|
||||||
| | | alias | An alias that can be used in addition to the array key for retrieving a client from | |
|
|
||||||
| | | | the service builder. | |
|
|
||||||
| | +------------+----------------------------------------------------------------------------------------+ |
|
|
||||||
+------------+---------------------------------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
The first client defined, ``abstract.foo``, is used as a placeholder of shared configuration values. Any service
|
|
||||||
extending abstract.foo will inherit its params. As an example, this can be useful when clients share the same username
|
|
||||||
and password.
|
|
||||||
|
|
||||||
The next client, ``bar``, extends from ``abstract.foo`` using the ``extends`` attribute referencing the client from
|
|
||||||
which to extend. Additional parameters can be merged into the original service definition when extending a parent
|
|
||||||
service.
|
|
||||||
|
|
||||||
.. important::
|
|
||||||
|
|
||||||
Each client that you intend to instantiate must specify a ``class`` attribute that references the full class name
|
|
||||||
of the client being created. The class referenced in the ``class`` parameter must implement a static ``factory()``
|
|
||||||
method that accepts an array or ``Guzzle\Common\Collection`` object and returns an instantiated object.
|
|
||||||
|
|
||||||
Sourcing from a PHP include
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can create service builder configurations using a PHP include file. This can be useful if you wish to take
|
|
||||||
advantage of an opcode cache like APC to speed up the process of loading and processing the configuration. The PHP
|
|
||||||
include file is the same format as an array, but you simply create a PHP script that returns an array and save the
|
|
||||||
file with the .php file extension.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
<?php return array('services' => '...');
|
|
||||||
// Saved as config.php
|
|
||||||
|
|
||||||
This configuration file can then be used with a service builder.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$builder = ServiceBuilder::factory('/path/to/config.php');
|
|
||||||
|
|
||||||
Sourcing from a JSON document
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can use JSON documents to serialize your service descriptions. The JSON format uses the exact same structure as
|
|
||||||
the PHP array syntax, but it's just serialized using JSON.
|
|
||||||
|
|
||||||
.. code-block:: javascript
|
|
||||||
|
|
||||||
{
|
|
||||||
"includes": ["/path/to/other/services.json", "/path/to/other/php_services.php"],
|
|
||||||
"services": {
|
|
||||||
"abstract.foo": {
|
|
||||||
"params": {
|
|
||||||
"username": "foo",
|
|
||||||
"password": "bar"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"extends": "abstract.foo",
|
|
||||||
"class": "MyClientClass",
|
|
||||||
"params": {
|
|
||||||
"other": "abc"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Referencing other clients in parameters
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If one of your clients depends on another client as one of its parameters, you can reference that client by name by
|
|
||||||
enclosing the client's reference key in ``{}``.
|
|
||||||
|
|
||||||
.. code-block:: javascript
|
|
||||||
|
|
||||||
{
|
|
||||||
"services": {
|
|
||||||
"token": {
|
|
||||||
"class": "My\Token\TokenFactory",
|
|
||||||
"params": {
|
|
||||||
"access_key": "xyz"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"client": {
|
|
||||||
"class": "My\Client",
|
|
||||||
"params": {
|
|
||||||
"token_client": "{token}",
|
|
||||||
"version": "1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
When ``client`` is constructed by the service builder, the service builder will first create the ``token`` service
|
|
||||||
and then inject the token service into ``client``'s factory method in the ``token_client`` parameter.
|
|
||||||
|
|
||||||
Retrieving clients from a service builder
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
Clients are referenced using a customizable name you provide in your service definition. The ServiceBuilder is a sort
|
|
||||||
of multiton object-- it will only instantiate a client once and return that client for subsequent retrievals. Clients
|
|
||||||
are retrieved by name (the array key used in the configuration) or by the ``alias`` setting of a service.
|
|
||||||
|
|
||||||
Here's an example of retrieving a client from your ServiceBuilder:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = $builder->get('foo');
|
|
||||||
|
|
||||||
// You can also use the ServiceBuilder object as an array
|
|
||||||
$client = $builder['foo'];
|
|
||||||
|
|
||||||
Creating throwaway clients
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can get a "throwaway" client (a client that is not persisted by the ServiceBuilder) by passing ``true`` in the
|
|
||||||
second argument of ``ServiceBuilder::get()``. This allows you to create a client that will not be returned by other
|
|
||||||
parts of your code that use the service builder. Instead of passing ``true``, you can pass an array of configuration
|
|
||||||
settings that will override the configuration settings specified in the service builder.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Get a throwaway client and overwrite the "custom" setting of the client
|
|
||||||
$foo = $builder->get('foo', array(
|
|
||||||
'custom' => 'in this world there are rules'
|
|
||||||
));
|
|
||||||
|
|
||||||
Getting raw configuration settings
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can get the raw configuration settings provided to the service builder for a specific service using the
|
|
||||||
``getData($name)`` method of a service builder. This method will null if the service was not found in the service
|
|
||||||
builder or an array of configuration settings if the service was found.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$data = $builder->getData('foo');
|
|
||||||
echo $data['key'] . "\n";
|
|
||||||
echo $data['secret'] . "\n";
|
|
||||||
echo $data['custom'] . "\n";
|
|
||||||
|
|
||||||
Adding a plugin to all clients
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
You can add a plugin to all clients created by a service builder using the ``addGlobalPlugin($plugin)`` method of a
|
|
||||||
service builder and passing a ``Symfony\Component\EventDispatcher\EventSubscriberInterface`` object. The service builder
|
|
||||||
will then attach each global plugin to every client as it is created. This allows you to, for example, add a LogPlugin
|
|
||||||
to every request created by a service builder for easy debugging.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Plugin\Log\LogPlugin;
|
|
||||||
|
|
||||||
// Add a debug log plugin to every client as it is created
|
|
||||||
$builder->addGlobalPlugin(LogPlugin::getDebugPlugin());
|
|
||||||
|
|
||||||
$foo = $builder->get('foo');
|
|
||||||
$foo->get('/')->send();
|
|
||||||
// Should output all of the data sent over the wire
|
|
||||||
|
|
||||||
.. _service-builder-events:
|
|
||||||
|
|
||||||
Events emitted from a service builder
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
A ``Guzzle\Service\Builder\ServiceBuilder`` object emits the following events:
|
|
||||||
|
|
||||||
+-------------------------------+--------------------------------------------+-----------------------------------------+
|
|
||||||
| Event name | Description | Event data |
|
|
||||||
+===============================+============================================+=========================================+
|
|
||||||
| service_builder.create_client | Called when a client is created | * client: The created client object |
|
|
||||||
+-------------------------------+--------------------------------------------+-----------------------------------------+
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
use Guzzle\Service\Builder\ServiceBuilder;
|
|
||||||
|
|
||||||
$builder = ServiceBuilder::factory('/path/to/config.json');
|
|
||||||
|
|
||||||
// Add an event listener to print out each client client as it is created
|
|
||||||
$builder->getEventDispatcher()->addListener('service_builder.create_client', function (Event $e) {
|
|
||||||
echo 'Client created: ' . get_class($e['client']) . "\n";
|
|
||||||
});
|
|
||||||
|
|
||||||
$foo = $builder->get('foo');
|
|
||||||
// Should output the class used for the "foo" client
|
|
@ -1,659 +0,0 @@
|
|||||||
======================
|
|
||||||
The web service client
|
|
||||||
======================
|
|
||||||
|
|
||||||
The ``Guzzle\Service`` namespace contains various abstractions that help to make it easier to interact with a web
|
|
||||||
service API, including commands, service descriptions, and resource iterators.
|
|
||||||
|
|
||||||
In this chapter, we'll build a simple `Twitter API client <https://dev.twitter.com/docs/api/1.1>`_.
|
|
||||||
|
|
||||||
Creating a client
|
|
||||||
=================
|
|
||||||
|
|
||||||
A class that extends from ``Guzzle\Service\Client`` or implements ``Guzzle\Service\ClientInterface`` must implement a
|
|
||||||
``factory()`` method in order to be used with a :doc:`service builder <using-the-service-builder>`.
|
|
||||||
|
|
||||||
Factory method
|
|
||||||
--------------
|
|
||||||
|
|
||||||
You can use the ``factory()`` method of a client directly if you do not need a service builder.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use mtdowling\TwitterClient;
|
|
||||||
|
|
||||||
// Create a client and pass an array of configuration data
|
|
||||||
$twitter = TwitterClient::factory(array(
|
|
||||||
'consumer_key' => '****',
|
|
||||||
'consumer_secret' => '****',
|
|
||||||
'token' => '****',
|
|
||||||
'token_secret' => '****'
|
|
||||||
));
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If you'd like to follow along, here's how to get your Twitter API credentials:
|
|
||||||
|
|
||||||
1. Visit https://dev.twitter.com/apps
|
|
||||||
2. Click on an application that you've created
|
|
||||||
3. Click on the "OAuth tool" tab
|
|
||||||
4. Copy all of the settings under "OAuth Settings"
|
|
||||||
|
|
||||||
Implementing a factory method
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
Creating a client and its factory method is pretty simple. You just need to implement ``Guzzle\Service\ClientInterface``
|
|
||||||
or extend from ``Guzzle\Service\Client``.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace mtdowling;
|
|
||||||
|
|
||||||
use Guzzle\Common\Collection;
|
|
||||||
use Guzzle\Plugin\Oauth\OauthPlugin;
|
|
||||||
use Guzzle\Service\Client;
|
|
||||||
use Guzzle\Service\Description\ServiceDescription;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple Twitter API client
|
|
||||||
*/
|
|
||||||
class TwitterClient extends Client
|
|
||||||
{
|
|
||||||
public static function factory($config = array())
|
|
||||||
{
|
|
||||||
// Provide a hash of default client configuration options
|
|
||||||
$default = array('base_url' => 'https://api.twitter.com/1.1');
|
|
||||||
|
|
||||||
// The following values are required when creating the client
|
|
||||||
$required = array(
|
|
||||||
'base_url',
|
|
||||||
'consumer_key',
|
|
||||||
'consumer_secret',
|
|
||||||
'token',
|
|
||||||
'token_secret'
|
|
||||||
);
|
|
||||||
|
|
||||||
// Merge in default settings and validate the config
|
|
||||||
$config = Collection::fromConfig($config, $default, $required);
|
|
||||||
|
|
||||||
// Create a new Twitter client
|
|
||||||
$client = new self($config->get('base_url'), $config);
|
|
||||||
|
|
||||||
// Ensure that the OauthPlugin is attached to the client
|
|
||||||
$client->addSubscriber(new OauthPlugin($config->toArray()));
|
|
||||||
|
|
||||||
return $client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Service Builder
|
|
||||||
---------------
|
|
||||||
|
|
||||||
A service builder is used to easily create web service clients, provides a simple configuration driven approach to
|
|
||||||
creating clients, and allows you to share configuration settings across multiple clients. You can find out more about
|
|
||||||
Guzzle's service builder in :doc:`using-the-service-builder`.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Service\Builder\ServiceBuilder;
|
|
||||||
|
|
||||||
// Create a service builder and provide client configuration data
|
|
||||||
$builder = ServiceBuilder::factory('/path/to/client_config.json');
|
|
||||||
|
|
||||||
// Get the client from the service builder by name
|
|
||||||
$twitter = $builder->get('twitter');
|
|
||||||
|
|
||||||
The above example assumes you have JSON data similar to the following stored in "/path/to/client_config.json":
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"services": {
|
|
||||||
"twitter": {
|
|
||||||
"class": "mtdowling\\TwitterClient",
|
|
||||||
"params": {
|
|
||||||
"consumer_key": "****",
|
|
||||||
"consumer_secret": "****",
|
|
||||||
"token": "****",
|
|
||||||
"token_secret": "****"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
A service builder becomes much more valuable when using multiple web service clients in a single application or
|
|
||||||
if you need to utilize the same client with varying configuration settings (e.g. multiple accounts).
|
|
||||||
|
|
||||||
Commands
|
|
||||||
========
|
|
||||||
|
|
||||||
Commands are a concept in Guzzle that helps to hide the underlying implementation of an API by providing an easy to use
|
|
||||||
parameter driven object for each action of an API. A command is responsible for accepting an array of configuration
|
|
||||||
parameters, serializing an HTTP request, and parsing an HTTP response. Following the
|
|
||||||
`command pattern <http://en.wikipedia.org/wiki/Command_pattern>`_, commands in Guzzle offer a greater level of
|
|
||||||
flexibility when implementing and utilizing a web service client.
|
|
||||||
|
|
||||||
Executing commands
|
|
||||||
------------------
|
|
||||||
|
|
||||||
You must explicitly execute a command after creating a command using the ``getCommand()`` method. A command has an
|
|
||||||
``execute()`` method that may be called, or you can use the ``execute()`` method of a client object and pass in the
|
|
||||||
command object. Calling either of these execute methods will return the result value of the command. The result value is
|
|
||||||
the result of parsing the HTTP response with the ``process()`` method.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Get a command from the client and pass an array of parameters
|
|
||||||
$command = $twitter->getCommand('getMentions', array(
|
|
||||||
'count' => 5
|
|
||||||
));
|
|
||||||
|
|
||||||
// Other parameters can be set on the command after it is created
|
|
||||||
$command['trim_user'] = false;
|
|
||||||
|
|
||||||
// Execute the command using the command object.
|
|
||||||
// The result value contains an array of JSON data from the response
|
|
||||||
$result = $command->execute();
|
|
||||||
|
|
||||||
// You can retrieve the result of the command later too
|
|
||||||
$result = $command->getResult().
|
|
||||||
|
|
||||||
Command object also contains methods that allow you to inspect the HTTP request and response that was utilized with
|
|
||||||
the command.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$request = $command->getRequest();
|
|
||||||
$response = $command->getResponse();
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The format and notation used to retrieve commands from a client can be customized by injecting a custom command
|
|
||||||
factory, ``Guzzle\Service\Command\Factory\FactoryInterface``, on the client using ``$client->setCommandFactory()``.
|
|
||||||
|
|
||||||
Executing with magic methods
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
When using method missing magic methods with a command, the command will be executed right away and the result of the
|
|
||||||
command is returned.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$jsonData = $twitter->getMentions(array(
|
|
||||||
'count' => 5,
|
|
||||||
'trim_user' => true
|
|
||||||
));
|
|
||||||
|
|
||||||
Creating commands
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Commands are created using either the ``getCommand()`` method of a client or a magic missing method of a client. Using
|
|
||||||
the ``getCommand()`` method allows you to create a command without executing it, allowing for customization of the
|
|
||||||
command or the request serialized by the command.
|
|
||||||
|
|
||||||
When a client attempts to create a command, it uses the client's ``Guzzle\Service\Command\Factory\FactoryInterface``.
|
|
||||||
By default, Guzzle will utilize a command factory that first looks for a concrete class for a particular command
|
|
||||||
(concrete commands) followed by a command defined by a service description (operation commands). We'll learn more about
|
|
||||||
concrete commands and operation commands later in this chapter.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Get a command from the twitter client.
|
|
||||||
$command = $twitter->getCommand('getMentions');
|
|
||||||
$result = $command->execute();
|
|
||||||
|
|
||||||
Unless you've skipped ahead, running the above code will throw an exception.
|
|
||||||
|
|
||||||
PHP Fatal error: Uncaught exception 'Guzzle\Common\Exception\InvalidArgumentException' with message
|
|
||||||
'Command was not found matching getMentions'
|
|
||||||
|
|
||||||
This exception was thrown because the "getMentions" command has not yet been implemented. Let's implement one now.
|
|
||||||
|
|
||||||
Concrete commands
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Commands can be created in one of two ways: create a concrete command class that extends
|
|
||||||
``Guzzle\Service\Command\AbstractCommand`` or
|
|
||||||
:doc:`create an OperationCommand based on a service description <guzzle-service-descriptions>`. The recommended
|
|
||||||
approach is to use a service description to define your web service, but you can use concrete commands when custom
|
|
||||||
logic must be implemented for marshaling or unmarshaling a HTTP message.
|
|
||||||
|
|
||||||
Commands are the method in which you abstract away the underlying format of the requests that need to be sent to take
|
|
||||||
action on a web service. Commands in Guzzle are meant to be built by executing a series of setter methods on a command
|
|
||||||
object. Commands are only validated right before they are executed. A ``Guzzle\Service\Client`` object is responsible
|
|
||||||
for executing commands. Commands created for your web service must implement
|
|
||||||
``Guzzle\Service\Command\CommandInterface``, but it's easier to extend the ``Guzzle\Service\Command\AbstractCommand``
|
|
||||||
class, implement the ``build()`` method, and optionally implement the ``process()`` method.
|
|
||||||
|
|
||||||
Serializing requests
|
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
The ``build()`` method of a command is responsible for using the arguments of the command to build and serialize a
|
|
||||||
HTTP request and set the request on the ``$request`` property of the command object. This step is usually taken care of
|
|
||||||
for you when using a service description driven command that uses the default
|
|
||||||
``Guzzle\Service\Command\OperationCommand``. You may wish to implement the process method yourself when you aren't
|
|
||||||
using a service description or need to implement more complex request serialization.
|
|
||||||
|
|
||||||
.. important::::
|
|
||||||
|
|
||||||
When implementing a custom ``build()`` method, be sure to set the class property of ``$this->request`` to an
|
|
||||||
instantiated and ready to send request.
|
|
||||||
|
|
||||||
The following example shows how to implement the ``getMentions``
|
|
||||||
`Twitter API <https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline>`_ method using a concrete command.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
namespace mtdowling\Twitter\Command;
|
|
||||||
|
|
||||||
use Guzzle\Service\Command\AbstractCommand;
|
|
||||||
|
|
||||||
class GetMentions extends AbstractCommand
|
|
||||||
{
|
|
||||||
protected function build()
|
|
||||||
{
|
|
||||||
// Create the request property of the command
|
|
||||||
$this->request = $this->client->get('statuses/mentions_timeline.json');
|
|
||||||
|
|
||||||
// Grab the query object of the request because we will use it for
|
|
||||||
// serializing command parameters on the request
|
|
||||||
$query = $this->request->getQuery();
|
|
||||||
|
|
||||||
if ($this['count']) {
|
|
||||||
$query->set('count', $this['count']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this['since_id']) {
|
|
||||||
$query->set('since_id', $this['since_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this['max_id']) {
|
|
||||||
$query->set('max_id', $this['max_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this['trim_user'] !== null) {
|
|
||||||
$query->set('trim_user', $this['trim_user'] ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this['contributor_details'] !== null) {
|
|
||||||
$query->set('contributor_details', $this['contributor_details'] ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this['include_entities'] !== null) {
|
|
||||||
$query->set('include_entities', $this['include_entities'] ? 'true' : 'false');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
By default, a client will attempt to find concrete command classes under the ``Command`` namespace of a client. First
|
|
||||||
the client will attempt to find an exact match for the name of the command to the name of the command class. If an
|
|
||||||
exact match is not found, the client will calculate a class name using inflection. This is calculated based on the
|
|
||||||
folder hierarchy of a command and converting the CamelCased named commands into snake_case. Here are some examples on
|
|
||||||
how the command names are calculated:
|
|
||||||
|
|
||||||
#. ``Foo\Command\JarJar`` **->** jar_jar
|
|
||||||
#. ``Foo\Command\Test`` **->** test
|
|
||||||
#. ``Foo\Command\People\GetCurrentPerson`` **->** people.get_current_person
|
|
||||||
|
|
||||||
Notice how any sub-namespace beneath ``Command`` is converted from ``\`` to ``.`` (a period). CamelCasing is converted
|
|
||||||
to lowercased snake_casing (e.g. JarJar == jar_jar).
|
|
||||||
|
|
||||||
Parsing responses
|
|
||||||
^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
The ``process()`` method of a command is responsible for converting an HTTP response into something more useful. For
|
|
||||||
example, a service description operation that has specified a model object in the ``responseClass`` attribute of the
|
|
||||||
operation will set a ``Guzzle\Service\Resource\Model`` object as the result of the command. This behavior can be
|
|
||||||
completely modified as needed-- even if you are using operations and responseClass models. Simply implement a custom
|
|
||||||
``process()`` method that sets the ``$this->result`` class property to whatever you choose. You can reuse parts of the
|
|
||||||
default Guzzle response parsing functionality or get inspiration from existing code by using
|
|
||||||
``Guzzle\Service\Command\OperationResponseParser`` and ``Guzzle\Service\Command\DefaultResponseParser`` classes.
|
|
||||||
|
|
||||||
If you do not implement a custom ``process()`` method and are not using a service description, then Guzzle will attempt
|
|
||||||
to guess how a response should be processed based on the Content-Type header of the response. Because the Twitter API
|
|
||||||
sets a ``Content-Type: application/json`` header on this response, we do not need to implement any custom response
|
|
||||||
parsing.
|
|
||||||
|
|
||||||
Operation commands
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Operation commands are commands in which the serialization of an HTTP request and the parsing of an HTTP response are
|
|
||||||
driven by a Guzzle service description. Because request serialization, validation, and response parsing are
|
|
||||||
described using a DSL, creating operation commands is a much faster process than writing concrete commands.
|
|
||||||
|
|
||||||
Creating operation commands for our Twitter client can remove a great deal of redundancy from the previous concrete
|
|
||||||
command, and allows for a deeper runtime introspection of the API. Here's an example service description we can use to
|
|
||||||
create the Twitter API client:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Twitter",
|
|
||||||
"apiVersion": "1.1",
|
|
||||||
"baseUrl": "https://api.twitter.com/1.1",
|
|
||||||
"description": "Twitter REST API client",
|
|
||||||
"operations": {
|
|
||||||
"GetMentions": {
|
|
||||||
"httpMethod": "GET",
|
|
||||||
"uri": "statuses/mentions_timeline.json",
|
|
||||||
"summary": "Returns the 20 most recent mentions for the authenticating user.",
|
|
||||||
"responseClass": "GetMentionsOutput",
|
|
||||||
"parameters": {
|
|
||||||
"count": {
|
|
||||||
"description": "Specifies the number of tweets to try and retrieve",
|
|
||||||
"type": "integer",
|
|
||||||
"location": "query"
|
|
||||||
},
|
|
||||||
"since_id": {
|
|
||||||
"description": "Returns results with an ID greater than the specified ID",
|
|
||||||
"type": "integer",
|
|
||||||
"location": "query"
|
|
||||||
},
|
|
||||||
"max_id": {
|
|
||||||
"description": "Returns results with an ID less than or equal to the specified ID.",
|
|
||||||
"type": "integer",
|
|
||||||
"location": "query"
|
|
||||||
},
|
|
||||||
"trim_user": {
|
|
||||||
"description": "Limits the amount of data returned for each user",
|
|
||||||
"type": "boolean",
|
|
||||||
"location": "query"
|
|
||||||
},
|
|
||||||
"contributor_details": {
|
|
||||||
"description": "Adds more data to contributor elements",
|
|
||||||
"type": "boolean",
|
|
||||||
"location": "query"
|
|
||||||
},
|
|
||||||
"include_entities": {
|
|
||||||
"description": "The entities node will be disincluded when set to false.",
|
|
||||||
"type": "boolean",
|
|
||||||
"location": "query"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"GetMentionsOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"location": "json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
If you're lazy, you can define the API in a less descriptive manner using ``additionalParameters``.
|
|
||||||
``additionalParameters`` define the serialization and validation rules of parameters that are not explicitly defined
|
|
||||||
in a service description.
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Twitter",
|
|
||||||
"apiVersion": "1.1",
|
|
||||||
"baseUrl": "https://api.twitter.com/1.1",
|
|
||||||
"description": "Twitter REST API client",
|
|
||||||
"operations": {
|
|
||||||
"GetMentions": {
|
|
||||||
"httpMethod": "GET",
|
|
||||||
"uri": "statuses/mentions_timeline.json",
|
|
||||||
"summary": "Returns the 20 most recent mentions for the authenticating user.",
|
|
||||||
"responseClass": "GetMentionsOutput",
|
|
||||||
"additionalParameters": {
|
|
||||||
"location": "query"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models": {
|
|
||||||
"GetMentionsOutput": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"location": "json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
You should attach the service description to the client at the end of the client's factory method:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// ...
|
|
||||||
class TwitterClient extends Client
|
|
||||||
{
|
|
||||||
public static function factory($config = array())
|
|
||||||
{
|
|
||||||
// ... same code as before ...
|
|
||||||
|
|
||||||
// Set the service description
|
|
||||||
$client->setDescription(ServiceDescription::factory('path/to/twitter.json'));
|
|
||||||
|
|
||||||
return $client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The client can now use operations defined in the service description instead of requiring you to create concrete
|
|
||||||
command classes. Feel free to delete the concrete command class we created earlier.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$jsonData = $twitter->getMentions(array(
|
|
||||||
'count' => 5,
|
|
||||||
'trim_user' => true
|
|
||||||
));
|
|
||||||
|
|
||||||
Executing commands in parallel
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
Much like HTTP requests, Guzzle allows you to send multiple commands in parallel. You can send commands in parallel by
|
|
||||||
passing an array of command objects to a client's ``execute()`` method. The client will serialize each request and
|
|
||||||
send them all in parallel. If an error is encountered during the transfer, then a
|
|
||||||
``Guzzle\Service\Exception\CommandTransferException`` is thrown, which allows you to retrieve a list of commands that
|
|
||||||
succeeded and a list of commands that failed.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Service\Exception\CommandTransferException;
|
|
||||||
|
|
||||||
$commands = array();
|
|
||||||
$commands[] = $twitter->getCommand('getMentions');
|
|
||||||
$commands[] = $twitter->getCommand('otherCommandName');
|
|
||||||
// etc...
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $client->execute($commands);
|
|
||||||
foreach ($result as $command) {
|
|
||||||
echo $command->getName() . ': ' . $command->getResponse()->getStatusCode() . "\n";
|
|
||||||
}
|
|
||||||
} catch (CommandTransferException $e) {
|
|
||||||
// Get an array of the commands that succeeded
|
|
||||||
foreach ($e->getSuccessfulCommands() as $command) {
|
|
||||||
echo $command->getName() . " succeeded\n";
|
|
||||||
}
|
|
||||||
// Get an array of the commands that failed
|
|
||||||
foreach ($e->getFailedCommands() as $command) {
|
|
||||||
echo $command->getName() . " failed\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
All commands executed from a client using an array must originate from the same client.
|
|
||||||
|
|
||||||
Special command options
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Guzzle exposes several options that help to control how commands are validated, serialized, and parsed.
|
|
||||||
Command options can be specified when creating a command or in the ``command.params`` parameter in the
|
|
||||||
``Guzzle\Service\Client``.
|
|
||||||
|
|
||||||
=========================== ============================================================================================
|
|
||||||
command.request_options Option used to add :ref:`Request options <request-options>` to the request created by a
|
|
||||||
command
|
|
||||||
command.hidden_params An array of the names of parameters ignored by the ``additionalParameters`` parameter schema
|
|
||||||
command.disable_validation Set to true to disable JSON schema validation of the command's input parameters
|
|
||||||
command.response_processing Determines how the default response parser will parse the command. One of "raw" no parsing,
|
|
||||||
"model" (the default method used to parse commands using response models defined in service
|
|
||||||
descriptions)
|
|
||||||
command.headers (deprecated) Option used to specify custom headers. Use ``command.request_options`` instead
|
|
||||||
command.on_complete (deprecated) Option used to add an onComplete method to a command. Use
|
|
||||||
``command.after_send`` event instead
|
|
||||||
command.response_body (deprecated) Option used to change the entity body used to store a response.
|
|
||||||
Use ``command.request_options`` instead
|
|
||||||
=========================== ============================================================================================
|
|
||||||
|
|
||||||
Advanced client configuration
|
|
||||||
=============================
|
|
||||||
|
|
||||||
Default command parameters
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
When creating a client object, you can specify default command parameters to pass into all commands. Any key value pair
|
|
||||||
present in the ``command.params`` settings of a client will be added as default parameters to any command created
|
|
||||||
by the client.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$client = new Guzzle\Service\Client(array(
|
|
||||||
'command.params' => array(
|
|
||||||
'default_1' => 'foo',
|
|
||||||
'another' => 'bar'
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
Magic methods
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Client objects will, by default, attempt to create and execute commands when a missing method is invoked on a client.
|
|
||||||
This powerful concept applies to both concrete commands and operation commands powered by a service description. This
|
|
||||||
makes it appear to the end user that you have defined actual methods on a client object, when in fact, the methods are
|
|
||||||
invoked using PHP's magic ``__call`` method.
|
|
||||||
|
|
||||||
The ``__call`` method uses the ``getCommand()`` method of a client, which uses the client's internal
|
|
||||||
``Guzzle\Service\Command\Factory\FactoryInterface`` object. The default command factory allows you to instantiate
|
|
||||||
operations defined in a client's service description. The method in which a client determines which command to
|
|
||||||
execute is defined as follows:
|
|
||||||
|
|
||||||
1. The client will first try to find a literal match for an operation in the service description.
|
|
||||||
2. If the literal match is not found, the client will try to uppercase the first character of the operation and find
|
|
||||||
the match again.
|
|
||||||
3. If a match is still not found, the command factory will inflect the method name from CamelCase to snake_case and
|
|
||||||
attempt to find a matching command.
|
|
||||||
4. If a command still does not match, an exception is thrown.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
// Use the magic method
|
|
||||||
$result = $twitter->getMentions();
|
|
||||||
|
|
||||||
// This is exactly the same as:
|
|
||||||
$result = $twitter->getCommand('getMentions')->execute();
|
|
||||||
|
|
||||||
You can disable magic methods on a client by passing ``false`` to the ``enableMagicMethod()`` method.
|
|
||||||
|
|
||||||
Custom command factory
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
A client by default uses the ``Guzzle\Service\Command\Factory\CompositeFactory`` which allows multiple command
|
|
||||||
factories to attempt to create a command by a certain name. The default CompositeFactory uses a ``ConcreteClassFactory``
|
|
||||||
and a ``ServiceDescriptionFactory`` if a service description is specified on a client. You can specify a custom
|
|
||||||
command factory if your client requires custom command creation logic using the ``setCommandFactory()`` method of
|
|
||||||
a client.
|
|
||||||
|
|
||||||
Custom resource Iterator factory
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Resource iterators can be retrieved from a client using the ``getIterator($name)`` method of a client. This method uses
|
|
||||||
a client's internal ``Guzzle\Service\Resource\ResourceIteratorFactoryInterface`` object. A client by default uses a
|
|
||||||
``Guzzle\Service\Resource\ResourceIteratorClassFactory`` to attempt to find concrete classes that implement resource
|
|
||||||
iterators. The default factory will first look for matching iterators in the ``Iterator`` subdirectory of the client
|
|
||||||
followed by the ``Model`` subdirectory of a client. Use the ``setResourceIteratorFactory()`` method of a client to
|
|
||||||
specify a custom resource iterator factory.
|
|
||||||
|
|
||||||
Plugins and events
|
|
||||||
==================
|
|
||||||
|
|
||||||
``Guzzle\Service\Client`` exposes various events that allow you to hook in custom logic. A client object owns a
|
|
||||||
``Symfony\Component\EventDispatcher\EventDispatcher`` object that can be accessed by calling
|
|
||||||
``$client->getEventDispatcher()``. You can use the event dispatcher to add listeners (a simple callback function) or
|
|
||||||
event subscribers (classes that listen to specific events of a dispatcher).
|
|
||||||
|
|
||||||
.. _service-client-events:
|
|
||||||
|
|
||||||
Events emitted from a Service Client
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
A ``Guzzle\Service\Client`` object emits the following events:
|
|
||||||
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| Event name | Description | Event data |
|
|
||||||
+==============================+============================================+==========================================+
|
|
||||||
| client.command.create | The client created a command object | * client: Client object |
|
|
||||||
| | | * command: Command object |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| command.before_prepare | Before a command is validated and built. | * command: Command being prepared |
|
|
||||||
| | This is also before a request is created. | |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| command.after_prepare | After a command instantiates and | * command: Command that was prepared |
|
|
||||||
| | configures its request object. | |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| command.before_send | The client is about to execute a prepared | * command: Command to execute |
|
|
||||||
| | command | |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| command.after_send | The client successfully completed | * command: The command that was executed |
|
|
||||||
| | executing a command | |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
| command.parse_response | Called when ``responseType`` is ``class`` | * command: The command with a response |
|
|
||||||
| | and the response is about to be parsed. | about to be parsed. |
|
|
||||||
+------------------------------+--------------------------------------------+------------------------------------------+
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
use Guzzle\Service\Client;
|
|
||||||
|
|
||||||
$client = new Client();
|
|
||||||
|
|
||||||
// create an event listener that operates on request objects
|
|
||||||
$client->getEventDispatcher()->addListener('command.after_prepare', function (Event $event) {
|
|
||||||
$command = $event['command'];
|
|
||||||
$request = $command->getRequest();
|
|
||||||
|
|
||||||
// do something with request
|
|
||||||
});
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Guzzle\Common\Event;
|
|
||||||
use Guzzle\Common\Client;
|
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
||||||
|
|
||||||
class EventSubscriber implements EventSubscriberInterface
|
|
||||||
{
|
|
||||||
public static function getSubscribedEvents()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
'client.command.create' => 'onCommandCreate',
|
|
||||||
'command.parse_response' => 'onParseResponse'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onCommandCreate(Event $event)
|
|
||||||
{
|
|
||||||
$client = $event['client'];
|
|
||||||
$command = $event['command'];
|
|
||||||
// operate on client and command
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onParseResponse(Event $event)
|
|
||||||
{
|
|
||||||
$command = $event['command'];
|
|
||||||
// operate on the command
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$client = new Client();
|
|
||||||
|
|
||||||
$client->addSubscriber(new EventSubscriber());
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
Phar::mapPhar('guzzle.phar');
|
|
||||||
|
|
||||||
require_once 'phar://guzzle.phar/vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
|
||||||
|
|
||||||
$classLoader = new Symfony\Component\ClassLoader\UniversalClassLoader();
|
|
||||||
$classLoader->registerNamespaces(array(
|
|
||||||
'Guzzle' => 'phar://guzzle.phar/src',
|
|
||||||
'Symfony\\Component\\EventDispatcher' => 'phar://guzzle.phar/vendor/symfony/event-dispatcher',
|
|
||||||
'Doctrine' => 'phar://guzzle.phar/vendor/doctrine/common/lib',
|
|
||||||
'Monolog' => 'phar://guzzle.phar/vendor/monolog/monolog/src'
|
|
||||||
));
|
|
||||||
$classLoader->register();
|
|
||||||
|
|
||||||
__HALT_COMPILER();
|
|
@ -1,16 +0,0 @@
|
|||||||
# you may need to update this if you're working on a fork.
|
|
||||||
guzzle.remote=git@github.com:guzzle/guzzle.git
|
|
||||||
|
|
||||||
# github credentials -- only used by GitHub API calls to create subtree repos
|
|
||||||
github.basicauth=username:password
|
|
||||||
# for the subtree split and testing
|
|
||||||
github.org=guzzle
|
|
||||||
|
|
||||||
# your git path
|
|
||||||
cmd.git=git
|
|
||||||
|
|
||||||
# your composer command
|
|
||||||
cmd.composer=composer
|
|
||||||
|
|
||||||
# test server start
|
|
||||||
cmd.testserver=node
|
|
@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project basedir="../../" default="install-dependencies">
|
|
||||||
|
|
||||||
<property name="cmd.composer" value="" />
|
|
||||||
<property name="cmd.git" value="" />
|
|
||||||
<property name="cmd.testserver" value="" />
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Our custom tasks
|
|
||||||
-->
|
|
||||||
<taskdef name="composerlint" classname="phing.tasks.ComposerLintTask" />
|
|
||||||
<taskdef name="guzzlesubsplit" classname="phing.tasks.GuzzleSubSplitTask" />
|
|
||||||
<taskdef name="guzzlepear" classname="phing.tasks.GuzzlePearPharPackageTask" />
|
|
||||||
|
|
||||||
<target name="find-git">
|
|
||||||
<if>
|
|
||||||
<contains string="${cmd.git}" substring="git" />
|
|
||||||
<then>
|
|
||||||
<echo>using git at ${cmd.git}</echo>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<exec command="which git" outputProperty="cmd.git" />
|
|
||||||
<echo>found git at ${cmd.git}</echo>
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean-dependencies">
|
|
||||||
<delete dir="${project.basedir}/vendor"/>
|
|
||||||
<delete file="${project.basedir}/composer.lock" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,142 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project basedir="../../" default="deploy">
|
|
||||||
|
|
||||||
<property name="git.status" value=""/>
|
|
||||||
<property name="git.currentbranch" value=""/>
|
|
||||||
<target name="check-git-branch-status">
|
|
||||||
<exec command="git status -s -b" outputProperty="git.currentbranch" />
|
|
||||||
<echo msg="${git.currentbranch}"/>
|
|
||||||
<if>
|
|
||||||
<contains string="${git.currentbranch}" substring="${head}"/>
|
|
||||||
<then>
|
|
||||||
<echo>On branch ${head}</echo>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<fail message="-Dhead=${head} arg did not match ${git.currentbranch}"/>
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
<exec command="git status -s" outputProperty="git.status" />
|
|
||||||
<if>
|
|
||||||
<equals arg1="${git.status}" arg2="" trim="true"/>
|
|
||||||
<then>
|
|
||||||
<echo>working directory clean</echo>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<echo>${git.status}</echo>
|
|
||||||
<fail message="Working directory isn't clean." />
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<property name="version.changelog" value=""/>
|
|
||||||
<property name="version.version" value=""/>
|
|
||||||
<target name="check-changelog-version">
|
|
||||||
<exec executable="fgrep" outputProperty="version.changelog">
|
|
||||||
<arg value="${new.version} ("/>
|
|
||||||
<arg value="${project.basedir}/CHANGELOG.md"/>
|
|
||||||
</exec>
|
|
||||||
<if>
|
|
||||||
<equals arg1="${version.changelog}" arg2="" trim="true"/>
|
|
||||||
<then>
|
|
||||||
<fail message="${new.version} not mentioned in CHANGELOG"/>
|
|
||||||
</then>
|
|
||||||
</if>
|
|
||||||
|
|
||||||
<exec executable="fgrep" outputProperty="version.version">
|
|
||||||
<arg value="const VERSION = '${new.version}'"/>
|
|
||||||
<arg value="${project.basedir}/src/Guzzle/Common/Version.php"/>
|
|
||||||
</exec>
|
|
||||||
<if>
|
|
||||||
<equals arg1="${version.version}" arg2="" trim="true"/>
|
|
||||||
<then>
|
|
||||||
<fail message="${new.version} not mentioned in Guzzle\Common\Version"/>
|
|
||||||
</then>
|
|
||||||
</if>
|
|
||||||
|
|
||||||
<echo>ChangeLog Match: ${version.changelog}</echo>
|
|
||||||
<echo>Guzzle\Common\Version Match: ${version.version}</echo>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="help" description="HELP AND REMINDERS about what you can do with this project">
|
|
||||||
<echo>releasing: phing -Dnew.version=3.0.x -Dhead=master release</echo>
|
|
||||||
<echo>--</echo>
|
|
||||||
<exec command="phing -l" passthru="true"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="release" depends="check-changelog-version,check-git-branch-status"
|
|
||||||
description="tag, subtree split, package, deploy: Use: phing -Dnew.version=[TAG] -Dhead=[BRANCH] release">
|
|
||||||
<if>
|
|
||||||
<isset property="new.version" />
|
|
||||||
<then>
|
|
||||||
<if>
|
|
||||||
<contains string="${new.version}" substring="v" casesensitive="false" />
|
|
||||||
<then>
|
|
||||||
<fail message="Please specify version as [0-9].[0-9].[0-9]. (I'll add v for you.)"/>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
|
|
||||||
<echo>BEGINNING RELEASE FOR ${new.version}</echo>
|
|
||||||
|
|
||||||
<!-- checkout the specified branch -->
|
|
||||||
<!-- <gitcheckout repository="${repo.dir}" branchname="${head}" gitPath="${cmd.git}" /> -->
|
|
||||||
<!-- Ensure that the tag exists -->
|
|
||||||
<!-- push the tag up so subsplit will get it -->
|
|
||||||
<!--gitpush repository="${repo.dir}" tags="true" gitPath="${cmd.git}" /-->
|
|
||||||
|
|
||||||
<!-- now do the subsplits -->
|
|
||||||
<guzzlesubsplit
|
|
||||||
repository="${repo.dir}"
|
|
||||||
remote="${guzzle.remote}"
|
|
||||||
heads="${head}"
|
|
||||||
tags="v${new.version}"
|
|
||||||
base="src"
|
|
||||||
subIndicatorFile="composer.json"
|
|
||||||
gitPath="${cmd.git}" />
|
|
||||||
|
|
||||||
<!-- Copy .md files into the PEAR package -->
|
|
||||||
<copy file="${repo.dir}/LICENSE" tofile=".subsplit/src/Guzzle/LICENSE.md" />
|
|
||||||
<copy file="${repo.dir}/README.md" tofile=".subsplit/src/Guzzle/README.md" />
|
|
||||||
<copy file="${repo.dir}/CHANGELOG.md" tofile=".subsplit/src/Guzzle/CHANGELOG.md" />
|
|
||||||
|
|
||||||
<!-- and now the pear packages -->
|
|
||||||
<guzzlepear
|
|
||||||
version="${new.version}"
|
|
||||||
makephar="true"
|
|
||||||
/>
|
|
||||||
</else>
|
|
||||||
|
|
||||||
</if>
|
|
||||||
</then>
|
|
||||||
|
|
||||||
<else>
|
|
||||||
<echo>Tip: to create a new release, do: phing -Dnew.version=[TAG] -Dhead=[BRANCH] release</echo>
|
|
||||||
</else>
|
|
||||||
|
|
||||||
</if>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="pear-channel">
|
|
||||||
<guzzlepear version="${new.version}" deploy="true" makephar="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="package-phar" description="Create a phar with an autoloader">
|
|
||||||
<pharpackage
|
|
||||||
destfile="${dir.output}/guzzle.phar"
|
|
||||||
basedir="${project.basedir}/.subsplit"
|
|
||||||
stub="phar-stub.php"
|
|
||||||
signature="md5">
|
|
||||||
<fileset dir="${project.basedir}/.subsplit">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
<include name="src/**/*.pem" />
|
|
||||||
<include name="vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php" />
|
|
||||||
<include name="vendor/symfony/event-dispatcher/**/*.php" />
|
|
||||||
<include name="vendor/doctrine/common/lib/Doctrine/Common/Cache/*.php" />
|
|
||||||
<include name="vendor/monolog/monolog/src/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
<metadata>
|
|
||||||
<element name="author" value="Michael Dowling" />
|
|
||||||
</metadata>
|
|
||||||
</pharpackage>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,152 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Phing task for composer validation.
|
|
||||||
*
|
|
||||||
* @copyright 2012 Clay Loveless <clay@php.net>
|
|
||||||
* @license http://claylo.mit-license.org/2012/ MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once 'phing/Task.php';
|
|
||||||
|
|
||||||
class ComposerLintTask extends Task
|
|
||||||
{
|
|
||||||
protected $dir = null;
|
|
||||||
protected $file = null;
|
|
||||||
protected $passthru = false;
|
|
||||||
protected $composer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The setter for the dir
|
|
||||||
*
|
|
||||||
* @param string $str Directory to crawl recursively for composer files
|
|
||||||
*/
|
|
||||||
public function setDir($str)
|
|
||||||
{
|
|
||||||
$this->dir = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The setter for the file
|
|
||||||
*
|
|
||||||
* @param string $str Individual file to validate
|
|
||||||
*/
|
|
||||||
public function setFile($str)
|
|
||||||
{
|
|
||||||
$this->file = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to use PHP's passthru() function instead of exec()
|
|
||||||
*
|
|
||||||
* @param boolean $passthru If passthru shall be used
|
|
||||||
*/
|
|
||||||
public function setPassthru($passthru)
|
|
||||||
{
|
|
||||||
$this->passthru = (bool) $passthru;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Composer to execute. If unset, will attempt composer.phar in project
|
|
||||||
* basedir, and if that fails, will attempt global composer
|
|
||||||
* installation.
|
|
||||||
*
|
|
||||||
* @param string $str Individual file to validate
|
|
||||||
*/
|
|
||||||
public function setComposer($str)
|
|
||||||
{
|
|
||||||
$this->file = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The init method: do init steps
|
|
||||||
*/
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
// nothing needed here
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main entry point
|
|
||||||
*/
|
|
||||||
public function main()
|
|
||||||
{
|
|
||||||
if ($this->composer === null) {
|
|
||||||
$this->findComposer();
|
|
||||||
}
|
|
||||||
|
|
||||||
$files = array();
|
|
||||||
if (!empty($this->file) && file_exists($this->file)) {
|
|
||||||
$files[] = $this->file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->dir)) {
|
|
||||||
$found = $this->findFiles();
|
|
||||||
foreach ($found as $file) {
|
|
||||||
$files[] = $this->dir . DIRECTORY_SEPARATOR . $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
|
|
||||||
$cmd = $this->composer . ' validate ' . $file;
|
|
||||||
$cmd = escapeshellcmd($cmd);
|
|
||||||
|
|
||||||
if ($this->passthru) {
|
|
||||||
$retval = null;
|
|
||||||
passthru($cmd, $retval);
|
|
||||||
if ($retval == 1) {
|
|
||||||
throw new BuildException('invalid composer.json');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$out = array();
|
|
||||||
$retval = null;
|
|
||||||
exec($cmd, $out, $retval);
|
|
||||||
if ($retval == 1) {
|
|
||||||
$err = join("\n", $out);
|
|
||||||
throw new BuildException($err);
|
|
||||||
} else {
|
|
||||||
$this->log($out[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the composer.json files using Phing's directory scanner
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function findFiles()
|
|
||||||
{
|
|
||||||
$ds = new DirectoryScanner();
|
|
||||||
$ds->setBasedir($this->dir);
|
|
||||||
$ds->setIncludes(array('**/composer.json'));
|
|
||||||
$ds->scan();
|
|
||||||
return $ds->getIncludedFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find composer installation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function findComposer()
|
|
||||||
{
|
|
||||||
$basedir = $this->project->getBasedir();
|
|
||||||
$php = $this->project->getProperty('php.interpreter');
|
|
||||||
|
|
||||||
if (file_exists($basedir . '/composer.phar')) {
|
|
||||||
$this->composer = "$php $basedir/composer.phar";
|
|
||||||
} else {
|
|
||||||
$out = array();
|
|
||||||
exec('which composer', $out);
|
|
||||||
if (empty($out)) {
|
|
||||||
throw new BuildException(
|
|
||||||
'Could not determine composer location.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->composer = $out[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,338 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* This file is part of Guzzle's build process.
|
|
||||||
*
|
|
||||||
* @copyright 2012 Clay Loveless <clay@php.net>
|
|
||||||
* @license http://claylo.mit-license.org/2012/ MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once 'phing/Task.php';
|
|
||||||
require_once 'PEAR/PackageFileManager2.php';
|
|
||||||
require_once 'PEAR/PackageFileManager/File.php';
|
|
||||||
require_once 'PEAR/Packager.php';
|
|
||||||
|
|
||||||
class GuzzlePearPharPackageTask extends Task
|
|
||||||
{
|
|
||||||
private $version;
|
|
||||||
private $deploy = true;
|
|
||||||
private $makephar = true;
|
|
||||||
|
|
||||||
private $subpackages = array();
|
|
||||||
|
|
||||||
public function setVersion($str)
|
|
||||||
{
|
|
||||||
$this->version = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersion()
|
|
||||||
{
|
|
||||||
return $this->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDeploy($deploy)
|
|
||||||
{
|
|
||||||
$this->deploy = (bool) $deploy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDeploy()
|
|
||||||
{
|
|
||||||
return $this->deploy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setMakephar($makephar)
|
|
||||||
{
|
|
||||||
$this->makephar = (bool) $makephar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMakephar()
|
|
||||||
{
|
|
||||||
return $this->makephar;
|
|
||||||
}
|
|
||||||
|
|
||||||
private $basedir;
|
|
||||||
private $guzzleinfo;
|
|
||||||
private $changelog_release_date;
|
|
||||||
private $changelog_notes = '-';
|
|
||||||
|
|
||||||
public function main()
|
|
||||||
{
|
|
||||||
$this->basedir = $this->getProject()->getBasedir();
|
|
||||||
|
|
||||||
if (!is_dir((string) $this->basedir.'/.subsplit')) {
|
|
||||||
throw new BuildException('PEAR packaging requires .subsplit directory');
|
|
||||||
}
|
|
||||||
|
|
||||||
// main composer file
|
|
||||||
$composer_file = file_get_contents((string) $this->basedir.'/.subsplit/composer.json');
|
|
||||||
$this->guzzleinfo = json_decode($composer_file, true);
|
|
||||||
|
|
||||||
// make sure we have a target
|
|
||||||
$pearwork = (string) $this->basedir . '/build/pearwork';
|
|
||||||
if (!is_dir($pearwork)) {
|
|
||||||
mkdir($pearwork, 0777, true);
|
|
||||||
}
|
|
||||||
$pearlogs = (string) $this->basedir . '/build/artifacts/logs';
|
|
||||||
if (!is_dir($pearlogs)) {
|
|
||||||
mkdir($pearlogs, 0777, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$version = $this->getVersion();
|
|
||||||
$this->grabChangelog();
|
|
||||||
if ($version[0] == '2') {
|
|
||||||
$this->log('building single PEAR package');
|
|
||||||
$this->buildSinglePackage();
|
|
||||||
} else {
|
|
||||||
// $this->log("building PEAR subpackages");
|
|
||||||
// $this->createSubPackages();
|
|
||||||
// $this->log("building PEAR bundle package");
|
|
||||||
$this->buildSinglePackage();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getMakephar()) {
|
|
||||||
$this->log("building PHAR");
|
|
||||||
$this->getProject()->executeTarget('package-phar');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getDeploy()) {
|
|
||||||
$this->doDeployment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function doDeployment()
|
|
||||||
{
|
|
||||||
$basedir = (string) $this->basedir;
|
|
||||||
$this->log('beginning PEAR/PHAR deployment');
|
|
||||||
|
|
||||||
chdir($basedir . '/build/pearwork');
|
|
||||||
if (!is_dir('./channel')) {
|
|
||||||
mkdir('./channel');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pull the PEAR channel down locally
|
|
||||||
passthru('aws s3 sync s3://pear.guzzlephp.org ./channel');
|
|
||||||
|
|
||||||
// add PEAR packages
|
|
||||||
foreach (scandir('./') as $file) {
|
|
||||||
if (substr($file, -4) == '.tgz') {
|
|
||||||
passthru('pirum add ./channel ' . $file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have a new phar, add it
|
|
||||||
if ($this->getMakephar() && file_exists($basedir . '/build/artifacts/guzzle.phar')) {
|
|
||||||
rename($basedir . '/build/artifacts/guzzle.phar', './channel/guzzle.phar');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync up with the S3 bucket
|
|
||||||
chdir($basedir . '/build/pearwork/channel');
|
|
||||||
passthru('aws s3 sync . s3://pear.guzzlephp.org');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildSinglePackage()
|
|
||||||
{
|
|
||||||
$v = $this->getVersion();
|
|
||||||
$apiversion = $v[0] . '.0.0';
|
|
||||||
|
|
||||||
$opts = array(
|
|
||||||
'packagedirectory' => (string) $this->basedir . '/.subsplit/src/',
|
|
||||||
'filelistgenerator' => 'file',
|
|
||||||
'ignore' => array('*composer.json'),
|
|
||||||
'baseinstalldir' => '/',
|
|
||||||
'packagefile' => 'package.xml'
|
|
||||||
//'outputdirectory' => (string) $this->basedir . '/build/pearwork/'
|
|
||||||
);
|
|
||||||
$pfm = new PEAR_PackageFileManager2();
|
|
||||||
$pfm->setOptions($opts);
|
|
||||||
$pfm->addRole('md', 'doc');
|
|
||||||
$pfm->addRole('pem', 'php');
|
|
||||||
$pfm->setPackage('Guzzle');
|
|
||||||
$pfm->setSummary("Object-oriented PHP HTTP Client for PHP 5.3+");
|
|
||||||
$pfm->setDescription($this->guzzleinfo['description']);
|
|
||||||
$pfm->setPackageType('php');
|
|
||||||
$pfm->setChannel('guzzlephp.org/pear');
|
|
||||||
$pfm->setAPIVersion($apiversion);
|
|
||||||
$pfm->setReleaseVersion($this->getVersion());
|
|
||||||
$pfm->setAPIStability('stable');
|
|
||||||
$pfm->setReleaseStability('stable');
|
|
||||||
$pfm->setNotes($this->changelog_notes);
|
|
||||||
$pfm->setPackageType('php');
|
|
||||||
$pfm->setLicense('MIT', 'http://github.com/guzzle/guzzle/blob/master/LICENSE');
|
|
||||||
$pfm->addMaintainer('lead', 'mtdowling', 'Michael Dowling', 'mtdowling@gmail.com', 'yes');
|
|
||||||
$pfm->setDate($this->changelog_release_date);
|
|
||||||
$pfm->generateContents();
|
|
||||||
|
|
||||||
$phpdep = $this->guzzleinfo['require']['php'];
|
|
||||||
$phpdep = str_replace('>=', '', $phpdep);
|
|
||||||
$pfm->setPhpDep($phpdep);
|
|
||||||
$pfm->addExtensionDep('required', 'curl');
|
|
||||||
$pfm->setPearinstallerDep('1.4.6');
|
|
||||||
$pfm->addPackageDepWithChannel('required', 'EventDispatcher', 'pear.symfony.com', '2.1.0');
|
|
||||||
if (!empty($this->subpackages)) {
|
|
||||||
foreach ($this->subpackages as $package) {
|
|
||||||
$pkg = dirname($package);
|
|
||||||
$pkg = str_replace('/', '_', $pkg);
|
|
||||||
$pfm->addConflictingPackageDepWithChannel($pkg, 'guzzlephp.org/pear', false, $apiversion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ob_start();
|
|
||||||
$startdir = getcwd();
|
|
||||||
chdir((string) $this->basedir . '/build/pearwork');
|
|
||||||
|
|
||||||
echo "DEBUGGING GENERATED PACKAGE FILE\n";
|
|
||||||
$result = $pfm->debugPackageFile();
|
|
||||||
if ($result) {
|
|
||||||
$out = $pfm->writePackageFile();
|
|
||||||
echo "\n\n\nWRITE PACKAGE FILE RESULT:\n";
|
|
||||||
var_dump($out);
|
|
||||||
// load up package file and build package
|
|
||||||
$packager = new PEAR_Packager();
|
|
||||||
echo "\n\n\nBUILDING PACKAGE FROM PACKAGE FILE:\n";
|
|
||||||
$dest_package = $packager->package($opts['packagedirectory'].'package.xml');
|
|
||||||
var_dump($dest_package);
|
|
||||||
} else {
|
|
||||||
echo "\n\n\nDEBUGGING RESULT:\n";
|
|
||||||
var_dump($result);
|
|
||||||
}
|
|
||||||
echo "removing package.xml";
|
|
||||||
unlink($opts['packagedirectory'].'package.xml');
|
|
||||||
$log = ob_get_clean();
|
|
||||||
file_put_contents((string) $this->basedir . '/build/artifacts/logs/pear_package.log', $log);
|
|
||||||
chdir($startdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createSubPackages()
|
|
||||||
{
|
|
||||||
$this->findComponents();
|
|
||||||
|
|
||||||
foreach ($this->subpackages as $package) {
|
|
||||||
$baseinstalldir = dirname($package);
|
|
||||||
$dir = (string) $this->basedir.'/.subsplit/src/' . $baseinstalldir;
|
|
||||||
$composer_file = file_get_contents((string) $this->basedir.'/.subsplit/src/'. $package);
|
|
||||||
$package_info = json_decode($composer_file, true);
|
|
||||||
$this->log('building ' . $package_info['target-dir'] . ' subpackage');
|
|
||||||
$this->buildSubPackage($dir, $baseinstalldir, $package_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildSubPackage($dir, $baseinstalldir, $info)
|
|
||||||
{
|
|
||||||
$package = str_replace('/', '_', $baseinstalldir);
|
|
||||||
$opts = array(
|
|
||||||
'packagedirectory' => $dir,
|
|
||||||
'filelistgenerator' => 'file',
|
|
||||||
'ignore' => array('*composer.json', '*package.xml'),
|
|
||||||
'baseinstalldir' => '/' . $info['target-dir'],
|
|
||||||
'packagefile' => 'package.xml'
|
|
||||||
);
|
|
||||||
$pfm = new PEAR_PackageFileManager2();
|
|
||||||
$pfm->setOptions($opts);
|
|
||||||
$pfm->setPackage($package);
|
|
||||||
$pfm->setSummary($info['description']);
|
|
||||||
$pfm->setDescription($info['description']);
|
|
||||||
$pfm->setPackageType('php');
|
|
||||||
$pfm->setChannel('guzzlephp.org/pear');
|
|
||||||
$pfm->setAPIVersion('3.0.0');
|
|
||||||
$pfm->setReleaseVersion($this->getVersion());
|
|
||||||
$pfm->setAPIStability('stable');
|
|
||||||
$pfm->setReleaseStability('stable');
|
|
||||||
$pfm->setNotes($this->changelog_notes);
|
|
||||||
$pfm->setPackageType('php');
|
|
||||||
$pfm->setLicense('MIT', 'http://github.com/guzzle/guzzle/blob/master/LICENSE');
|
|
||||||
$pfm->addMaintainer('lead', 'mtdowling', 'Michael Dowling', 'mtdowling@gmail.com', 'yes');
|
|
||||||
$pfm->setDate($this->changelog_release_date);
|
|
||||||
$pfm->generateContents();
|
|
||||||
|
|
||||||
$phpdep = $this->guzzleinfo['require']['php'];
|
|
||||||
$phpdep = str_replace('>=', '', $phpdep);
|
|
||||||
$pfm->setPhpDep($phpdep);
|
|
||||||
$pfm->setPearinstallerDep('1.4.6');
|
|
||||||
|
|
||||||
foreach ($info['require'] as $type => $version) {
|
|
||||||
if ($type == 'php') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($type == 'symfony/event-dispatcher') {
|
|
||||||
$pfm->addPackageDepWithChannel('required', 'EventDispatcher', 'pear.symfony.com', '2.1.0');
|
|
||||||
}
|
|
||||||
if ($type == 'ext-curl') {
|
|
||||||
$pfm->addExtensionDep('required', 'curl');
|
|
||||||
}
|
|
||||||
if (substr($type, 0, 6) == 'guzzle') {
|
|
||||||
$gdep = str_replace('/', ' ', $type);
|
|
||||||
$gdep = ucwords($gdep);
|
|
||||||
$gdep = str_replace(' ', '_', $gdep);
|
|
||||||
$pfm->addPackageDepWithChannel('required', $gdep, 'guzzlephp.org/pear', $this->getVersion());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// can't have main Guzzle package AND sub-packages
|
|
||||||
$pfm->addConflictingPackageDepWithChannel('Guzzle', 'guzzlephp.org/pear', false, $apiversion);
|
|
||||||
|
|
||||||
ob_start();
|
|
||||||
$startdir = getcwd();
|
|
||||||
chdir((string) $this->basedir . '/build/pearwork');
|
|
||||||
|
|
||||||
echo "DEBUGGING GENERATED PACKAGE FILE\n";
|
|
||||||
$result = $pfm->debugPackageFile();
|
|
||||||
if ($result) {
|
|
||||||
$out = $pfm->writePackageFile();
|
|
||||||
echo "\n\n\nWRITE PACKAGE FILE RESULT:\n";
|
|
||||||
var_dump($out);
|
|
||||||
// load up package file and build package
|
|
||||||
$packager = new PEAR_Packager();
|
|
||||||
echo "\n\n\nBUILDING PACKAGE FROM PACKAGE FILE:\n";
|
|
||||||
$dest_package = $packager->package($opts['packagedirectory'].'/package.xml');
|
|
||||||
var_dump($dest_package);
|
|
||||||
} else {
|
|
||||||
echo "\n\n\nDEBUGGING RESULT:\n";
|
|
||||||
var_dump($result);
|
|
||||||
}
|
|
||||||
echo "removing package.xml";
|
|
||||||
unlink($opts['packagedirectory'].'/package.xml');
|
|
||||||
$log = ob_get_clean();
|
|
||||||
file_put_contents((string) $this->basedir . '/build/artifacts/logs/pear_package_'.$package.'.log', $log);
|
|
||||||
chdir($startdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findComponents()
|
|
||||||
{
|
|
||||||
$ds = new DirectoryScanner();
|
|
||||||
$ds->setBasedir((string) $this->basedir.'/.subsplit/src');
|
|
||||||
$ds->setIncludes(array('**/composer.json'));
|
|
||||||
$ds->scan();
|
|
||||||
$files = $ds->getIncludedFiles();
|
|
||||||
$this->subpackages = $files;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function grabChangelog()
|
|
||||||
{
|
|
||||||
$cl = file((string) $this->basedir.'/.subsplit/CHANGELOG.md');
|
|
||||||
$notes = '';
|
|
||||||
$in_version = false;
|
|
||||||
$release_date = null;
|
|
||||||
|
|
||||||
foreach ($cl as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
if (preg_match('/^\* '.$this->getVersion().' \(([0-9\-]+)\)$/', $line, $matches)) {
|
|
||||||
$release_date = $matches[1];
|
|
||||||
$in_version = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($in_version && empty($line) && empty($notes)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($in_version && ! empty($line)) {
|
|
||||||
$notes .= $line."\n";
|
|
||||||
}
|
|
||||||
if ($in_version && empty($line) && !empty($notes)) {
|
|
||||||
$in_version = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->changelog_release_date = $release_date;
|
|
||||||
|
|
||||||
if (! empty($notes)) {
|
|
||||||
$this->changelog_notes = $notes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,385 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Phing wrapper around git subsplit.
|
|
||||||
*
|
|
||||||
* @see https://github.com/dflydev/git-subsplit
|
|
||||||
* @copyright 2012 Clay Loveless <clay@php.net>
|
|
||||||
* @license http://claylo.mit-license.org/2012/ MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once 'phing/tasks/ext/git/GitBaseTask.php';
|
|
||||||
|
|
||||||
// base - base of tree to split out
|
|
||||||
// subIndicatorFile - composer.json, package.xml?
|
|
||||||
class GuzzleSubSplitTask extends GitBaseTask
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* What git repository to pull from and publish to
|
|
||||||
*/
|
|
||||||
protected $remote = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Publish for comma-separated heads instead of all heads
|
|
||||||
*/
|
|
||||||
protected $heads = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Publish for comma-separated tags instead of all tags
|
|
||||||
*/
|
|
||||||
protected $tags = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base of the tree RELATIVE TO .subsplit working dir
|
|
||||||
*/
|
|
||||||
protected $base = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The presence of this file will indicate that the directory it resides
|
|
||||||
* in is at the top level of a split.
|
|
||||||
*/
|
|
||||||
protected $subIndicatorFile = 'composer.json';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do everything except actually send the update.
|
|
||||||
*/
|
|
||||||
protected $dryRun = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not sync any heads.
|
|
||||||
*/
|
|
||||||
protected $noHeads = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not sync any tags.
|
|
||||||
*/
|
|
||||||
protected $noTags = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The splits we found in the heads
|
|
||||||
*/
|
|
||||||
protected $splits;
|
|
||||||
|
|
||||||
public function setRemote($str)
|
|
||||||
{
|
|
||||||
$this->remote = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRemote()
|
|
||||||
{
|
|
||||||
return $this->remote;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHeads($str)
|
|
||||||
{
|
|
||||||
$this->heads = explode(',', $str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHeads()
|
|
||||||
{
|
|
||||||
return $this->heads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTags($str)
|
|
||||||
{
|
|
||||||
$this->tags = explode(',', $str);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTags()
|
|
||||||
{
|
|
||||||
return $this->tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setBase($str)
|
|
||||||
{
|
|
||||||
$this->base = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBase()
|
|
||||||
{
|
|
||||||
return $this->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSubIndicatorFile($str)
|
|
||||||
{
|
|
||||||
$this->subIndicatorFile = $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubIndicatorFile()
|
|
||||||
{
|
|
||||||
return $this->subIndicatorFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDryRun($bool)
|
|
||||||
{
|
|
||||||
$this->dryRun = (bool) $bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDryRun()
|
|
||||||
{
|
|
||||||
return $this->dryRun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setNoHeads($bool)
|
|
||||||
{
|
|
||||||
$this->noHeads = (bool) $bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNoHeads()
|
|
||||||
{
|
|
||||||
return $this->noHeads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setNoTags($bool)
|
|
||||||
{
|
|
||||||
$this->noTags = (bool) $bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNoTags()
|
|
||||||
{
|
|
||||||
return $this->noTags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GitClient from VersionControl_Git
|
|
||||||
*/
|
|
||||||
protected $client = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main entry point
|
|
||||||
*/
|
|
||||||
public function main()
|
|
||||||
{
|
|
||||||
$repo = $this->getRepository();
|
|
||||||
if (empty($repo)) {
|
|
||||||
throw new BuildException('"repository" is a required parameter');
|
|
||||||
}
|
|
||||||
|
|
||||||
$remote = $this->getRemote();
|
|
||||||
if (empty($remote)) {
|
|
||||||
throw new BuildException('"remote" is a required parameter');
|
|
||||||
}
|
|
||||||
|
|
||||||
chdir($repo);
|
|
||||||
$this->client = $this->getGitClient(false, $repo);
|
|
||||||
|
|
||||||
// initalized yet?
|
|
||||||
if (!is_dir('.subsplit')) {
|
|
||||||
$this->subsplitInit();
|
|
||||||
} else {
|
|
||||||
// update
|
|
||||||
$this->subsplitUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// find all splits based on heads requested
|
|
||||||
$this->findSplits();
|
|
||||||
|
|
||||||
// check that GitHub has the repos
|
|
||||||
$this->verifyRepos();
|
|
||||||
|
|
||||||
// execute the subsplits
|
|
||||||
$this->publish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function publish()
|
|
||||||
{
|
|
||||||
$this->log('DRY RUN ONLY FOR NOW');
|
|
||||||
$base = $this->getBase();
|
|
||||||
$base = rtrim($base, '/') . '/';
|
|
||||||
$org = $this->getOwningTarget()->getProject()->getProperty('github.org');
|
|
||||||
|
|
||||||
$splits = array();
|
|
||||||
|
|
||||||
$heads = $this->getHeads();
|
|
||||||
foreach ($heads as $head) {
|
|
||||||
foreach ($this->splits[$head] as $component => $meta) {
|
|
||||||
$splits[] = $base . $component . ':git@github.com:'. $org.'/'.$meta['repo'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$cmd = 'git subsplit publish ';
|
|
||||||
$cmd .= escapeshellarg(implode(' ', $splits));
|
|
||||||
|
|
||||||
if ($this->getNoHeads()) {
|
|
||||||
$cmd .= ' --no-heads';
|
|
||||||
} else {
|
|
||||||
$cmd .= ' --heads='.$head;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getNoTags()) {
|
|
||||||
$cmd .= ' --no-tags';
|
|
||||||
} else {
|
|
||||||
if ($this->getTags()) {
|
|
||||||
$cmd .= ' --tags=' . escapeshellarg(implode(' ', $this->getTags()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
passthru($cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs `git subsplit update`
|
|
||||||
*/
|
|
||||||
public function subsplitUpdate()
|
|
||||||
{
|
|
||||||
$repo = $this->getRepository();
|
|
||||||
$this->log('git-subsplit update...');
|
|
||||||
$cmd = $this->client->getCommand('subsplit');
|
|
||||||
$cmd->addArgument('update');
|
|
||||||
try {
|
|
||||||
$cmd->execute();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw new BuildException('git subsplit update failed'. $e);
|
|
||||||
}
|
|
||||||
chdir($repo . '/.subsplit');
|
|
||||||
passthru('php ../composer.phar update --dev');
|
|
||||||
chdir($repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs `git subsplit init` based on the remote repository.
|
|
||||||
*/
|
|
||||||
public function subsplitInit()
|
|
||||||
{
|
|
||||||
$remote = $this->getRemote();
|
|
||||||
$cmd = $this->client->getCommand('subsplit');
|
|
||||||
$this->log('running git-subsplit init ' . $remote);
|
|
||||||
|
|
||||||
$cmd->setArguments(array(
|
|
||||||
'init',
|
|
||||||
$remote
|
|
||||||
));
|
|
||||||
|
|
||||||
try {
|
|
||||||
$output = $cmd->execute();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw new BuildException('git subsplit init failed'. $e);
|
|
||||||
}
|
|
||||||
$this->log(trim($output), Project::MSG_INFO);
|
|
||||||
$repo = $this->getRepository();
|
|
||||||
chdir($repo . '/.subsplit');
|
|
||||||
passthru('php ../composer.phar install --dev');
|
|
||||||
chdir($repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the composer.json files using Phing's directory scanner
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function findSplits()
|
|
||||||
{
|
|
||||||
$this->log("checking heads for subsplits");
|
|
||||||
$repo = $this->getRepository();
|
|
||||||
$base = $this->getBase();
|
|
||||||
|
|
||||||
$splits = array();
|
|
||||||
$heads = $this->getHeads();
|
|
||||||
|
|
||||||
if (!empty($base)) {
|
|
||||||
$base = '/' . ltrim($base, '/');
|
|
||||||
} else {
|
|
||||||
$base = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
chdir($repo . '/.subsplit');
|
|
||||||
foreach ($heads as $head) {
|
|
||||||
$splits[$head] = array();
|
|
||||||
|
|
||||||
// check each head requested *BEFORE* the actual subtree split command gets it
|
|
||||||
passthru("git checkout '$head'");
|
|
||||||
$ds = new DirectoryScanner();
|
|
||||||
$ds->setBasedir($repo . '/.subsplit' . $base);
|
|
||||||
$ds->setIncludes(array('**/'.$this->subIndicatorFile));
|
|
||||||
$ds->scan();
|
|
||||||
$files = $ds->getIncludedFiles();
|
|
||||||
|
|
||||||
// Process the files we found
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$pkg = file_get_contents($repo . '/.subsplit' . $base .'/'. $file);
|
|
||||||
$pkg_json = json_decode($pkg, true);
|
|
||||||
$name = $pkg_json['name'];
|
|
||||||
$component = str_replace('/composer.json', '', $file);
|
|
||||||
// keep this for split cmd
|
|
||||||
$tmpreponame = explode('/', $name);
|
|
||||||
$reponame = $tmpreponame[1];
|
|
||||||
$splits[$head][$component]['repo'] = $reponame;
|
|
||||||
$nscomponent = str_replace('/', '\\', $component);
|
|
||||||
$splits[$head][$component]['desc'] = "[READ ONLY] Subtree split of $nscomponent: " . $pkg_json['description'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go back to how we found it
|
|
||||||
passthru("git checkout master");
|
|
||||||
chdir($repo);
|
|
||||||
$this->splits = $splits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on list of repositories we determined we *should* have, talk
|
|
||||||
* to GitHub and make sure they're all there.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected function verifyRepos()
|
|
||||||
{
|
|
||||||
$this->log('verifying GitHub target repos');
|
|
||||||
$github_org = $this->getOwningTarget()->getProject()->getProperty('github.org');
|
|
||||||
$github_creds = $this->getOwningTarget()->getProject()->getProperty('github.basicauth');
|
|
||||||
|
|
||||||
if ($github_creds == 'username:password') {
|
|
||||||
$this->log('Skipping GitHub repo checks. Update github.basicauth in build.properties to verify repos.', 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ch = curl_init('https://api.github.com/orgs/'.$github_org.'/repos?type=all');
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_USERPWD, $github_creds);
|
|
||||||
// change this when we know we can use our bundled CA bundle!
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
$result = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
$repos = json_decode($result, true);
|
|
||||||
$existing_repos = array();
|
|
||||||
|
|
||||||
// parse out the repos we found on GitHub
|
|
||||||
foreach ($repos as $repo) {
|
|
||||||
$tmpreponame = explode('/', $repo['full_name']);
|
|
||||||
$reponame = $tmpreponame[1];
|
|
||||||
$existing_repos[$reponame] = $repo['description'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$heads = $this->getHeads();
|
|
||||||
foreach ($heads as $head) {
|
|
||||||
foreach ($this->splits[$head] as $component => $meta) {
|
|
||||||
|
|
||||||
$reponame = $meta['repo'];
|
|
||||||
|
|
||||||
if (!isset($existing_repos[$reponame])) {
|
|
||||||
$this->log("Creating missing repo $reponame");
|
|
||||||
$payload = array(
|
|
||||||
'name' => $reponame,
|
|
||||||
'description' => $meta['desc'],
|
|
||||||
'homepage' => 'http://www.guzzlephp.org/',
|
|
||||||
'private' => true,
|
|
||||||
'has_issues' => false,
|
|
||||||
'has_wiki' => false,
|
|
||||||
'has_downloads' => true,
|
|
||||||
'auto_init' => false
|
|
||||||
);
|
|
||||||
$ch = curl_init('https://api.github.com/orgs/'.$github_org.'/repos');
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_USERPWD, $github_creds);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
|
||||||
// change this when we know we can use our bundled CA bundle!
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
$result = curl_exec($ch);
|
|
||||||
echo "Response code: ".curl_getinfo($ch, CURLINFO_HTTP_CODE)."\n";
|
|
||||||
curl_close($ch);
|
|
||||||
} else {
|
|
||||||
$this->log("Repo $reponame exists", 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user