From 5a1a74b2bc6eb22cf98feaa0e0a10ab862ed0876 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Mon, 23 Dec 2013 17:24:40 +0200 Subject: [PATCH] add external files for Routes (Espo/routes.json, Espo/Modules/Crm/routes.json) --- application/Espo/Controllers/App.php | 13 + application/Espo/Controllers/User.php | 1 + application/Espo/Core/Application.php | 55 +- application/Espo/Core/Utils/Route.php | 140 ++++ application/Espo/Modules/Crm/routes.json | 2 + application/Espo/routes.json | 140 ++++ composer.lock | 37 +- composer.phar | Bin 934848 -> 938890 bytes vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 6 +- vendor/composer/installed.json | 227 ++--- vendor/slim/slim/.travis.yml | 1 + vendor/slim/slim/README.markdown | 59 +- vendor/slim/slim/Slim/Environment.php | 71 +- vendor/slim/slim/Slim/Exception/Pass.php | 3 +- vendor/slim/slim/Slim/Exception/Stop.php | 3 +- vendor/slim/slim/Slim/Http/Headers.php | 167 +--- vendor/slim/slim/Slim/Http/Request.php | 195 +++-- vendor/slim/slim/Slim/Http/Response.php | 167 ++-- vendor/slim/slim/Slim/Http/Util.php | 103 ++- vendor/slim/slim/Slim/Log.php | 188 ++++- vendor/slim/slim/Slim/LogWriter.php | 4 +- vendor/slim/slim/Slim/Middleware.php | 10 +- .../slim/Slim/Middleware/ContentTypes.php | 12 +- vendor/slim/slim/Slim/Middleware/Flash.php | 16 +- .../slim/Slim/Middleware/MethodOverride.php | 10 +- .../slim/Slim/Middleware/PrettyExceptions.php | 4 +- .../slim/Slim/Middleware/SessionCookie.php | 87 +- vendor/slim/slim/Slim/Route.php | 64 +- vendor/slim/slim/Slim/Router.php | 106 ++- vendor/slim/slim/Slim/Slim.php | 374 +++++---- vendor/slim/slim/Slim/View.php | 252 +++--- vendor/slim/slim/composer.json | 3 + vendor/slim/slim/index.php | 43 +- vendor/slim/slim/tests/EnvironmentTest.php | 24 +- vendor/slim/slim/tests/Http/HeadersTest.php | 122 +-- vendor/slim/slim/tests/Http/RequestTest.php | 112 +-- vendor/slim/slim/tests/Http/ResponseTest.php | 493 +++-------- vendor/slim/slim/tests/Http/UtilTest.php | 46 +- vendor/slim/slim/tests/LogTest.php | 70 +- vendor/slim/slim/tests/LogWriterTest.php | 2 +- .../tests/Middleware/ContentTypesTest.php | 9 +- .../slim/slim/tests/Middleware/FlashTest.php | 17 +- .../tests/Middleware/MethodOverrideTest.php | 10 +- .../tests/Middleware/PrettyExceptionsTest.php | 30 +- .../tests/Middleware/SessionCookieTest.php | 388 ++++++++- vendor/slim/slim/tests/MiddlewareTest.php | 69 +- vendor/slim/slim/tests/RouteTest.php | 774 +++++++++--------- vendor/slim/slim/tests/RouterTest.php | 672 ++++----------- vendor/slim/slim/tests/SlimTest.php | 216 +++-- vendor/slim/slim/tests/ViewTest.php | 261 +++--- .../Symfony/Component/Console/Application.php | 252 +++--- .../Symfony/Component/Console/CHANGELOG.md | 7 + .../Component/Console/Command/Command.php | 43 +- .../Component/Console/Command/HelpCommand.php | 8 +- .../Component/Console/Command/ListCommand.php | 8 +- .../Console/Descriptor/Descriptor.php | 41 +- .../Descriptor/DescriptorInterface.php | 11 +- .../Console/Descriptor/JsonDescriptor.php | 126 ++- .../Console/Descriptor/MarkdownDescriptor.php | 64 +- .../Console/Descriptor/TextDescriptor.php | 99 ++- .../Console/Descriptor/XmlDescriptor.php | 310 ++++--- .../Console/Event/ConsoleCommandEvent.php | 2 - .../Console/Event/ConsoleExceptionEvent.php | 2 +- .../Console/Event/ConsoleTerminateEvent.php | 2 +- .../Console/Helper/DescriptorHelper.php | 20 +- .../Component/Console/Helper/DialogHelper.php | 6 +- .../Component/Console/Helper/HelperSet.php | 10 +- .../Console/Helper/ProgressHelper.php | 31 +- .../Component/Console/Helper/TableHelper.php | 62 +- .../Symfony/Component/Console/Input/Input.php | 9 +- .../Console/Input/InputDefinition.php | 14 +- .../Component/Console/Output/Output.php | 22 +- .../Symfony/Component/Console/Shell.php | 3 +- .../Console/Tester/ApplicationTester.php | 13 +- .../Console/Tester/CommandTester.php | 22 +- .../Console/Tests/ApplicationTest.php | 129 ++- .../Descriptor/AbstractDescriptorTest.php | 18 +- .../Console/Tests/Fixtures/application_1.json | 2 +- .../Console/Tests/Fixtures/application_1.md | 4 +- .../Console/Tests/Fixtures/application_1.xml | 8 +- .../Console/Tests/Fixtures/application_2.json | 2 +- .../Console/Tests/Fixtures/application_2.md | 4 +- .../Console/Tests/Fixtures/application_2.xml | 10 +- .../Tests/Fixtures/application_astext1.txt | 2 +- .../Tests/Fixtures/application_astext2.txt | 2 +- .../Tests/Fixtures/application_asxml1.txt | 8 +- .../Tests/Fixtures/application_run2.txt | 3 +- .../Tests/Fixtures/application_run3.txt | 3 +- .../OutputFormatterStyleStackTest.php | 2 +- .../Console/Tests/Helper/DialogHelperTest.php | 13 + .../Console/Tests/Helper/HelperSetTest.php | 17 + .../Tests/Helper/ProgressHelperTest.php | 14 + .../Console/Tests/Helper/TableHelperTest.php | 46 +- .../Console/Tests/Output/OutputTest.php | 29 + .../Tests/Tester/ApplicationTesterTest.php | 5 + .../Tests/Tester/CommandTesterTest.php | 22 + .../Symfony/Component/Console/composer.json | 2 +- .../Yaml/Tests/Fixtures/YtsBasicTests.yml | 2 +- .../Fixtures/YtsSpecificationExamples.yml | 2 +- .../Yaml/Tests/Fixtures/YtsTypeTransfers.yml | 4 +- .../Component/Yaml/Tests/InlineTest.php | 1 - .../yaml/Symfony/Component/Yaml/composer.json | 2 +- 103 files changed, 4206 insertions(+), 3217 deletions(-) create mode 100644 application/Espo/Controllers/App.php create mode 100644 application/Espo/Core/Utils/Route.php create mode 100644 application/Espo/Modules/Crm/routes.json create mode 100644 application/Espo/routes.json mode change 100644 => 100755 composer.phar diff --git a/application/Espo/Controllers/App.php b/application/Espo/Controllers/App.php new file mode 100644 index 0000000000..3256772931 --- /dev/null +++ b/application/Espo/Controllers/App.php @@ -0,0 +1,13 @@ +get('entityManager'), $container); $this->getSlim()->add($auth); - $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container) { - $conditions = $slim->router()->getCurrentRoute()->getConditions(); - $routeParams = $slim->router()->getCurrentRoute()->getParams(); - if (!empty($routeParams)) { - $slim->router()->getCurrentRoute()->setParams($routeParams); - } - }); - $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container, $serviceFactory) { $route = $slim->router()->getCurrentRoute(); - $conditions = $route->getConditions(); + $conditions = $route->getConditions(); if (isset($conditions['useController']) && $conditions['useController'] == false) { return; @@ -123,7 +115,7 @@ class Application $value = $params[$paramName]; } $controllerParams[$key] = $value; - } + } $controllerName = ucfirst($controllerParams['controller']); @@ -135,7 +127,7 @@ class Application } try { - $controllerManager = new \Espo\Core\ControllerManager($container, $serviceFactory); + $controllerManager = new \Espo\Core\ControllerManager($container, $serviceFactory); $result = $controllerManager->process($controllerName, $actionName, $params, $data); $container->get('output')->render($result); } catch (\Exception $e) { @@ -152,26 +144,28 @@ class Application protected function initRoutes() { - //$this->getSlim()->get('/', '\Espo\Utils\Api\Rest::main')->conditions( array('useController' => false) ); + $routes = new \Espo\Core\Utils\Route($this->getContainer()->get('config'), $this->getContainer()->get('fileManager')); - //TODO move routing to metadata - $routes = array( - array( - 'method' => 'get', - 'route' => 'metadata', - 'params' => array( - 'controller' => 'Metadata', - ), - ), - array( - 'method' => 'get', - 'route' => 'settings', - 'params' => array( - 'controller' => 'Settings', - ), - ), - ); + $crudList = array_keys( (array) $this->getContainer()->get('config')->get('crud') ); + foreach($routes->getAll() as $route) { + + $method = strtolower($route['method']); + if (!in_array($method, $crudList)) { + $GLOBALS['log']->add('ERROR', 'Route: Method ['.$method.'] does not exist. Please check your route ['.$route['route'].']'); + continue; + } + + $currentRoute = $this->getSlim()->$method($route['route'], function() use ($route) { //todo change "use" for php 5.4 + return $route['params']; + }); + + if (isset($route['conditions'])) { + $currentRoute->conditions($route['conditions']); + } + } + + /* //todo remove when it is tested $this->getSlim()->get('/', function() { return $template = "

EspoCRM REST API

"; }); @@ -270,7 +264,8 @@ class Application 'link' => ':link', 'foreignId' => ':foreignId' ); - }); + }); */ + } } diff --git a/application/Espo/Core/Utils/Route.php b/application/Espo/Core/Utils/Route.php new file mode 100644 index 0000000000..1b70ce1ea4 --- /dev/null +++ b/application/Espo/Core/Utils/Route.php @@ -0,0 +1,140 @@ +config = $config; + $this->fileManager = $fileManager; + } + + protected function getConfig() + { + return $this->config; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + + public function get($key = '', $returns = null) + { + if (!isset($this->data)) { + $this->init(); + } + + if (empty($key)) { + return $this->data; + } + + $keys = explode('.', $key); + + $lastRoute = $this->data; + foreach($keys as $keyName) { + if (isset($lastRoute[$keyName]) && is_array($lastRoute)) { + $lastRoute = $lastRoute[$keyName]; + } else { + return $returns; + } + } + + return $lastRoute; + } + + + public function getAll() + { + return $this->get(); + } + + + protected function init() + { + $cacheFile = Util::concatPath($this->getConfig()->get('cachePath'), $this->cacheFileName); + + if (file_exists($cacheFile) && $this->getConfig()->get('useCache')) { + $this->data = $this->getFileManager()->getContent($cacheFile); + } else { + $this->data = $this->uniteFiles(); + + $result = $this->getFileManager()->setContentPHP($this->data, $cacheFile); + if ($result == false) { + $GLOBALS['log']->add('EXCEPTION', 'Route::init() - Cannot save Routes to a file'); + throw new \Espo\Core\Exceptions\Error(); + } + } + } + + protected function uniteFiles($isCustom = false) + { + $dirName = $isCustom ? '/Custom' : ''; + + $data = array(); + + $moduleDir = 'application/Espo'.$dirName.'/Modules'; + if (file_exists($moduleDir)) { + $dirList= $this->getFileManager()->getFileList($moduleDir, false, '', 'dir'); + + foreach($dirList as $currentDirName) { + + $dirNameFull = Util::concatPath($moduleDir, $currentDirName); + $routeFile = Util::concatPath($dirNameFull, $this->fileName); + + $data = $this->getAddData($data, $routeFile); + } + } + + //if need this path to high priority, move up this code + $routeFile = Util::concatPath('application/Espo'.$dirName, $this->fileName); + $data = $this->getAddData($data, $routeFile); + + if (!$isCustom) { + $data = $this->addToData($this->uniteFiles(true), $data); + } + + return $data; + } + + protected function getAddData($currData, $routeFile) + { + if (file_exists($routeFile)) { + $content= $this->getFileManager()->getContent($routeFile); + $arrayContent = Json::getArrayData($content); + if (empty($arrayContent)) { + $GLOBALS['log']->add('ERROR', 'Route::uniteFiles() - Empty file or syntax error - ['.$routeFile.']'); + return $currData; + } + + $currData = $this->addToData($currData, $arrayContent); + } + + return $currData; + } + + + protected function addToData($data, $newData) + { + if (!is_array($newData)) { + return $data; + } + + foreach($newData as $route) { + $data[] = $route; + } + + return $data; + } + +} \ No newline at end of file diff --git a/application/Espo/Modules/Crm/routes.json b/application/Espo/Modules/Crm/routes.json new file mode 100644 index 0000000000..ad5f28065c --- /dev/null +++ b/application/Espo/Modules/Crm/routes.json @@ -0,0 +1,2 @@ +[ +] \ No newline at end of file diff --git a/application/Espo/routes.json b/application/Espo/routes.json new file mode 100644 index 0000000000..567600b988 --- /dev/null +++ b/application/Espo/routes.json @@ -0,0 +1,140 @@ +[ + { + "route":"/", + "method":"get", + "params":"

EspoCRM REST API<\/h1>" + }, + + { + "route":"/App/user/", + "method":"get", + "params":{ + "controller":"App", + "action":"user" + } + }, + + { + "route":"/Metadata/", + "method":"get", + "params":{ + "controller":"Metadata" + } + }, + + { + "route":"/Settings/", + "method":"get", + "params":{ + "controller":"Settings" + }, + "conditions":{ + "auth":false + } + }, + + { + "route":"/Settings/", + "method":"patch", + "params":{ + "controller":"Settings" + } + }, + + { + "route":"/:controller/layout/:name/", + "method":"get", + "params":{ + "controller":"Layout", + "scope":":controller" + } + }, + + { + "route":"/:controller/layout/:name/", + "method":"put", + "params":{ + "controller":"Layout", + "scope":":controller" + } + }, + + { + "route":"/:controller/layout/:name/", + "method":"patch", + "params":{ + "controller":"Layout", + "scope":":controller" + } + }, + + { + "route":"/Admin/rebuild/", + "method":"get", + "params":{ + "controller":"Admin", + "action":"rebuild" + } + }, + + { + "route":"/:controller/:id/", + "method":"get", + "params":{ + "controller":":controller", + "action":"read", + "id":":id" + } + }, + + { + "route":"/:controller/", + "method":"get", + "params":{ + "controller":":controller", + "action":"index" + } + }, + + { + "route":"/:controller/", + "method":"post", + "params":{ + "controller":":controller", + "action":"create" + } + }, + + { + "route":"/:controller/:id/", + "method":"put", + "params":{ + "controller":":controller", + "action":"update", + "id":":id" + } + }, + + { + "route":"/:controller/:id/", + "method":"patch", + "params":{ + "controller":":controller", + "action":"patch", + "id":":id" + } + }, + + { + "route":"/:controller/:id/:link/:foreignId/", + "method":"get", + "params":{ + "controller":":controller", + "action":"readRelated", + "id":":id", + "link":":link", + "foreignId":":foreignId" + } + } + +] \ No newline at end of file diff --git a/composer.lock b/composer.lock index a210e4f40c..dd0186358d 100644 --- a/composer.lock +++ b/composer.lock @@ -554,21 +554,24 @@ }, { "name": "slim/slim", - "version": "2.2.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/codeguy/Slim.git", - "reference": "b8181de1112a1e2f565b40158b621c34ded38053" + "reference": "ff7d7148848fa4f45712984d7b91ac3cbced586b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/codeguy/Slim/zipball/b8181de1112a1e2f565b40158b621c34ded38053", - "reference": "b8181de1112a1e2f565b40158b621c34ded38053", + "url": "https://api.github.com/repos/codeguy/Slim/zipball/ff7d7148848fa4f45712984d7b91ac3cbced586b", + "reference": "ff7d7148848fa4f45712984d7b91ac3cbced586b", "shasum": "" }, "require": { "php": ">=5.3.0" }, + "suggest": { + "ext-mcrypt": "Required for HTTP cookie encryption" + }, "type": "library", "autoload": { "psr-0": { @@ -593,21 +596,21 @@ "rest", "router" ], - "time": "2012-12-13 02:15:50" + "time": "2013-11-29 20:33:36" }, { "name": "symfony/console", - "version": "v2.3.7", + "version": "v2.4.0", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18" + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/00848d3e13cf512e77c7498c2b3b0192f61f4b18", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18", + "url": "https://api.github.com/repos/symfony/Console/zipball/3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", "shasum": "" }, "require": { @@ -622,7 +625,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -646,21 +649,21 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-11-13 21:27:40" + "time": "2013-11-27 09:10:40" }, { "name": "symfony/yaml", - "version": "v2.3.7", + "version": "v2.4.0", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b" + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/c1bda5b459d792cb253de12c65beba3040163b2b", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", "shasum": "" }, "require": { @@ -669,7 +672,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -693,7 +696,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-10-17 11:48:01" + "time": "2013-11-26 16:40:27" } ], "packages-dev": [ diff --git a/composer.phar b/composer.phar old mode 100644 new mode 100755 index 9ff64bb441d81333a9f963cb7ba111510b44b0a3..3a4e0722d397fc2f05b0bff542c14294cb0deb16 GIT binary patch delta 8910 zcmcIo3s_TEw$A&U1VT=D1Of<$7)*Ev5abPlqNu#ITCD#thcYP`%kVo7 zo&k0RwYXJLNV3XOqBmWfTE4DNDHFFbcqO>zvjU#7Ri`=}upJdy<;PU--h+z7U5LcoBUCSaSohU{}uJ&oAAfRga% zuOeRo<>pv0sL_BHO&kHN(##<8u!e@G4WSNvB#}t|uxVjA${JPZ521P395RboJdOa* zoPAdOW+?Rw%j=K%J{sF@QD_{|(n%$frdwXT8!VqdwSFCH;9gcyEiARp zhfQPATn>#QTF;|gCtCLF#};z6G|buBdgA>f+G#|7tfgVw!WxL;J!rd)S^g_1jp*zR zx`erc*W-5uJib1h#zj$dV=NEapV~rV88n1|u5isJT?jXfP61a6mbtlmuYeQr*h~m0 z*Cmqu?7FGkUnWuzmZwhT1wdl78QiC1!27yr0{Tiv&$fh{L7W;w(LC~HW8)^y3Pes% zFt2g5i8Sh`64|7u$B>3nGV+024z`8Roloc|5Wp3EEs^EnG*S;b4)5DLp9K98X0Sgz znJj)9UdEk?r|x07Wk=wzB=duYP;gsB6t^|lBUom4-2D#HrU`s4VkWU*h-@TsS!5Nb zDx#LKw4L_64fY$cPaJ45Xu#FTPy+levXKOtgetT2_+P702VhV%*bqel4@J=|xKU*B zzbc3d0yq$Dh#(d+40S}VHqZ!PH_(m7)k@(q_g|FSo|dBDhatDG4UU(ZgKs zWT{8G&2ptW1Q+IZRJWLFOXI7F^}FIJO}rXEhgiLWPMaw?wilH1N#JU{8qAzP%c5ff z&F*3p@3Fi;e2pqL6`Y@7BvzyeG=udCv}Oc_L~_gL8*T@ev^aJ>csn7S(}z(1uvBiF z8Xfe{N-Pv7(&*MCQnucgSVlhodm_CO@_CxIdxG*bU&kFqG>e-E%f9mAKZ2qpnzDhU zg+%$oq%`idmV&UNM+2nJ>;CclOn+D76xoHvBbiYCQ1W; zGf~Sm6X~fp>Lil#ExXJphS*KX;o$H@N*iY;-a_>9&Gb;$nirAh_st9F=gF-^K9qbb zk=K*y=XH~uLTP?I?KeNmv$8-;>@&A6~ssAF;j5_VLa%3?QEv~wL z_#4C*Mt~RhTIp4I(pp6T%kv}>U;A_UV$}3BVqy1TGFe8gnQd8Cx z0)$z#9nWUji1XitOC*-$p_dVD8o_Z}6qseBw`zxtUhhxZD4l+3qy3SUP4n&v%4dS| zN;VxT(hwUR5NlUaPRl{pbPf%8bq)on(O~feTk9e-5h zZ=KDhE~iYUJG&;+quxE4;=c~c^1LiAbtz30mVKWO7Lq)~=7s6!j13;TI06BC^0G-r zE(B#lKBd1!`3p&AbclZnZhK1v|Ck>KP86BJ-|}g3M@?xoc9qh7u=EKJuG@op8~;oN zw&FbCEl`;nTwcMCiSP*OV0?C14h<|iJqoQFg_SM)h~}B8$*)D+Ttpslcj1bVWtjmV-RH<3GwyhJ7x+eyIB zqB=fgJSqYGB~$bbcAuXPY72A8M&Qk2dXHL4<`A_NCG`3@T(Xorr&w`-Is2Mlk_x{r)hS}9NuyI-h(Y_z~eW)qW5nRXvUr(dH ztEW?+UDK(LuTO6#7PG1yMEVW`hFAj2|h|Jw=@?9 z#uADR{;ZCU+*|8txL?(^aFwxC0n4!c{V~LYh6bB%h2SO@UqOY4EP?~|F5*Rc1C?7E zXb7@KYHVraT(bULWAHAUOYgeQxl73B$L3O;bso*>hIurqFXqwQF2054_P{N)Vw(}W zp1FOCZ&N+W$UGjLn9qT}`SikCKcDV>eLg+U1qh)Jp&FDgG!pRQh4e6wE%cM;ibeE{b}XW27IPa7c-?KC#Ms>^Ar~rtej9L4 zy}{Vx-~hjv9{7pHRC($W>gmoU0#TlXJo&7{xf>j;p~_d5gn-tj7_#%KCYqXaP1Hzz zGv$ikHB--QEi}Br79YV!Eu|^;ETv<@{-v|H-)7MB#PY#5hX{;zdIvAD(-~#hPV*eo zN_(TXmDc=wL0RIU&yPB2TC`4@4u4Rda#FoQf#Mz#=q&SvkWM1ph)TKrTdoqMx6w2uGYYE~kO?)XI@bw7AnpM2e%>gIv?mj4-UJV_jh?#@=o+7&R2Q5(Tk+u*Y&hv4RW{P<}MjqLaYho`$+a61KOI^Wt8;Qbw*o-QZv z_5{!#J;*zk-`^wn`BtIN<93og-GbkrX)4yV`UHDtvF7F=MpJ_>Eyr-woF7Om?-v3A z;+dZh=K3cC^MDVArtA2Chj)^|kZXY=aCRsvkw-s2v{5N<1C6_rfo4cIJn^}LSn;ph zrK!^4`$vp=v)Lc82YUSI5X~+(`nwAqeMXtD$8Ak1*0|butBp^B`}-M#iUNm^ox8%o zg>yo~hOb<(%A+yF-P6^@mzE+E2-E69>FF zyO|icCQq3b9Rw_(Wr_A)h5l*Gcrgwx{*@vUW`3y9$ci;Ud*Q7(v)AK6Tk>vUCEtMl zwBE4um1Agb6)tDW%wG6yzrq-Hv+3cJm#5E!^AeP)Fv~3sgWs%?z6-CqB* zuxy*uu=xeK4thEnrMRg;+L=cbM5M5!Ed5_oc2mMemy=LJY|x${je+7W>AiXsj!y{m z_}nB-DCcnZy$XZqeM;(cz!MR2HJts8)C9}+$vJVlUiPjuo8;e&YdxdPVRv*0{G>_z zjn5fn?T#9Mo!~&#X!rG5;r1+f1ni8EMZ?4qRR|o2kfp*eMY#bC9ag}d|0_)pnMm0y zi(?&KcE7(x=ymx6eyim+mv^eq(cxMlSW?6z9$AM5uK$}<11oNqor0&{SLoo`e7OQ< z+#!pBFQ&*?ao!!W9rNLuy=*4DI-m@NtDa}8p_h{>#fFozP$}HT%Jdpkpn;9K!SSt_5iWXQME?Wej*~qBiqK_3( zaO7Eeo%q%#vO_Z1axco#y9OBtfA#?r2M^RL6|m_&g<3rLnasedl7wz=piew~P1c}? z_kN-cZ&MiH>>ct*amy3(YzCS>2#qQER~5}2 zqcvbbsu>nOllKRFEk429Wp@Zx3vWs1Eg9&S`Ir4#6yS@pB^Wa>OrX<$~ak-*!P0`ODTMGAFGBl_OW`{{i6IS_y{XYfxU0YqQ&f&m>RERJ+wj!$T+ zOu?cd)F9q}U9m9*UapX9#~U>{QMrb7Yc#wWdyl`O4Kl>6;3HxQPmj+bG}r?jnU*ZX z`sBvQ#Bd8fPW;C-d%%v_aMT9sZNcswWkXtG)-fbJ;7}B@qk8x$T8_9&{Ix~7qO2cN zrpv*bY4euycAwAQH);x9DnbBd5I6SXU{{akrD^no;5Ch&QGQmq&}&sj*$tra566Kx zEW1yr^x6B}$h5zST;QYB^Z&RV-3>E$u*my^k&gy*gX5Ic#+@Dy7Rv%{;H*aJ9J{Rz&}qok}JGHPiQ$QsB97)Nyj8AigCiLs|G|PG*AV&&wjk z%iT(WiM^RsQ^vd23T>EDUv5CWv~;i` z+KKSeE2<*6`Bn65_aT)H{^M1ZUOazD#Yv&rr-c*Id zq}LGDUOuLpkspoH7Z4l)!ATO(ZFf883jUrhn3SvH#ko@E9aVDhZb9SE=xPAfz6lLB zh}v9%7Kg_v@bKVHS+eEdKvBz#mem*TZ4$6fVT&}63L{^MoK>nLCj|H zPR9IziH`!&u+wHo!!Ft`m;v&LY9Fq4Y7Mzafe$)Q#>h5L4;ma@ZXVr;9f%4M@894= z0NJLBaAz~C)*#~Z@tBK?pe}|nD9G~0hnOVM9K}2$#d$S|=L}2(GnR%plGudrC5(EE z&xYg%u5xOl!%fq1e$Xi0-cF`ZcMj+MAC{ zJi{}`e**HRiCHH5Q7dq_m8lV*PG)ZXaZ?zVA}+8nxj&8*5$?NjNJxUC!|rZJGdp7P ze^a^QsZ^%w`yPhfl)Yjooxw!HE`w?kteDF%kk4ln;x96o3;e&nMTrmBG3QevHN1wW zMdGFNaEHeaNBS6phP)b~_b3e-DSDYK@#$WsE!^7HIwi-MlkXJT3JaaK0zt^l5%OAv zDXn>Vxdqu%+VTqW+OqQ}3$SE8lc>$f$g%O+wxYb;qP(1ej`fV#v7R;O!J}0QG*>;X zQHX;F*bh}%>K3P+bE?;8X?ACRj-puli=Vrb(-Ak^1`>Ssm*dU2*c;EsZDT4gxUZu_cCJaU(~}VS#`SB=4g~s7^l5ie zi~OB;^5}{ma|EByjfU|utz&c`w6^FYTvi(zD$3@B4oLfN(EmRLg5I-&JrWEzxHpO% zz1rUB#*dn@AT>=y_J>de>J+{h?z_)+qBQz^OL9zDPcv@pF+V$)4~jJ*H)H= z^0cr!e+n)lxLpn(cuX4xld{4lY<^0sfby)cB(Xj#Y<^_C{o}UmTTSLqFXmSiTn>5T SEB*WHYtdJKk{Ok?mHz~>ifn`c delta 6361 zcma)9dt6l2zMuD=Jr8EjFbodQ0Y+z#*YFw{-VX&)RKQ30Kp0?nBmxdl);TDeN~UJI zZZ6R}(y7c$gY=`@d$g-oC!eXAT3TN0=~3&TolG;$yY~8xUc2{?6aRc?ul4=Cf9tmv z&%NO~(Bm4Y7Aw<6rKGqVi7BX2yhOS?YXuq-J1N>F$rNWx(kS-&zE4V0={F8HvWo1L%IGJd@k&2m1o1dgH3lY#UfSDi72Mt`sRnqVs+k-iNOE zDNJ;uQza7pb;&?4(i4^C3L{n7q$r@+ugIgMAVR9xW1aL+I+QVR8lO)BM*R4-KgwY; zsnh}{hvETd3`M09zQ-vcpy!m3s*}oms{I2-Bx-pnDIT3tStARZnmwaipKNJvb=P^k z@okN5S4R}-Po7iG%=Ndbj>bpvk@Q+)@zoQ&$5b9H@P?ai} z61r4H6c4E&JgpiW_*x_qeYCbBhhz-|7OEi+>(t|@#^Z$0e`(8p)RzFJIZXh^X}~W5 zm#ojUKQuR86HKLaVv(qF%Dc~^d7&Wnn#RPPQh=0zFD+jd@-UizY67U#f0A5>+xF`p zZX|0V%<rtRYzy*fyb5VGp z6+N$G&_!J!CEe0NZ8Nzd>eK*<=H;Ku%GPpr#B+MeImV5rXx8UZtkgppVu8K{_+*_`eFt2@ptuXk`EpHU>ZzT1aFe8`1)N1P%q7{HcaG(?p63Oc3D-6C4>+ zAf%`+a00b(kQIq!le(|@+@M86*8(A*_XDA=i-#3ba*YOX}$R5KzQYt2E_dZ@XSVw)Mx#cnesL>vU2HZ};n>DnrhLEhY4n3u2wsoQh8egR;;}Fu1?;(f`7xh^cB&yG9K!1khiSbpJe#iH3x_Mg zX@RsY_u&_oiQEa_DH5>xdUXLxkAR%@L{w1WuOec&Of6UyuyWDWRrIKJM;p<&NEpg% zNJjF9ZQ4x>)i%N(ov<-zQ>2n=*cu6Q;BF*nE{=k-m+3^Job}tRB!-~1!wu+A6wHmm zs3}y=X@#mTvQDSp7p>D^eRvJUjl&>gC>_o}dG5_DBYWjD+^c90?A0kA!|Y0Jt^=&e+(P zTxwuNOgfj~8;%0T@7OyQosF?_-O*4c0hj)3)GhP{xp+>+%8@PBKqWI{Qz>@DCUYP8 zu5ke`{YP&)xyA)@2qg@~Cea`ZBqEXN`L7emWeb|d#~C@BZ)gd)>ulAlbbbqFR>gtz zwm9g!AL25owwQRxh?6w!2hP2%s5Kb0^~M{x9+C~AqXqmeNxTeQkB80k@oFl4IUalw zlaUfvbL}p5bYTLEiV|QZRVIw0M4SM}@lt|=I)C3F64{0iyiew)869^7pm7ekRvR5~ zzi)NGJpI`L=OZBz^4{vhejg4c!mA>NjH3hmgf19rN#veRf`At!0f8kii!I6tO|&Qa zlGJD@32qrS83t2nGEBY=$uPJsC48GrP&z7XI>(BO?{Hr70pyo7z0>!XSK)w75_^0f#)yo(I%|2UKf*XH&E9 zS+tVWPaq4p?1Xpo1M&mCP|Rg%&E_yN`2?nb4TZnH_kdYO)TW^BbQLOg!9`H-YNUaF z?5d}jp58+7t@JjEVHs{3@D9?)ADEAb(8A17`ck*I9bRe`$F8l@E<%fH{83?6Jj%_6(N&Q>p4&^hMDSj~#ql2<5^SQY z*?v^hui0*jRXLRu_vgTOR4xRtG8bmsjof*3-;>u&@l0MP#ghD5?!Fof2>46)h?{7C zegoZ%E|^Z;>zN=D9o~BBI7*xxj0SQeQNn07I#<9^(iI;mg&f9p&tH6-#xTCnf!2)n zr_!s5-yc+VH2OAD(e2UTJ39t^ZW;qVo)|NmYD_4srTAjuWQx}cXHqOKs-pN-(Hx5A zu@Gz5Sjgr#V?j@GF~qp1xPdy*L|!Mm`VJpPvAJ1jb+Ht(9V`anp;>BFQ#p)U z?y7{;d|3%fCe4Of@weIFnWGBA>#Oooen2&(xV0Ld3Hz(ZaeHE+o&rwWH%p7mZn%SI zx#5kn(+znZRs&~aehu{e1s`VC!uMZlAuZZENJqO5&)0#R%LBZP9(c?AAIK?Fm z76Es@(NLIUcPDyMYTYUIt{Qi3eO+>0ts~9jNKJ9p)Ym7~B|BMiFcYmG3z6n>MiyNYf}rMG&g&^ zaoOI^7JGEG4jw`a^2?E(FC~InN>UheMm6c_&d24L~`_W~K zt-QdNq3Xi(m& zy{Waul4G&ed7iLY(k*D)jWT?rOdcX`!-?CZ{(iqBM(-T)Z&)#1#eN+q^*NY$uowH{x%D^~N1jFMww zBTZFDV^e!vcCEX%(PJ4g!h*BA=X6Ozd|Q0e0?FG`arGIA z2KRp}8-Yua+#j#rqR`^pbg3NWo(#wRqoqo8{b>b0az-+UPj^WD`N6Z28wR>2yCT_$ zKVem&_}&;skDsrS`r+dn88wb6B%hy47z2*VQwQTAmrRWZd1(QE>8j)d30{7g(c-vp z*1&)MgT$hgH?_BWI(YHVl2SeV#@#wu7~jcA>z_f6nP-J8VJ~&ruUiXSbEhVe?ZKoy(KN%+T=l20h;um5V zEA9$rDj!*};}?^e0=^-H879Vkp-cd_TNw^t4`!739jC^`e;Ue2rFd7&qdVegd@-I0 z#-0eqj%(J)jCf!fIRlrP=VoQf|JUx6mmM9aO^qdRQy-HHUMpY$&4>O zC1dcFJkq~?R+i;2oKt2g(HF0)aoSa}flnM%9@OKl>trgSvv1r`2H-?TxtqQ#OGAue0oBF)Z*~KV?%w@roN713&Z=J6EnN^|sb} z+S}99Cr=qYro0?axWj&ftM0IIQsHa$9rkp<|Djm2vMr8SoM>mv_~pZ_j(_%7)?b1n z@302E@D8h$5y48n{~p^b#(DSHAiVTGtH%TPSq?9_&xYa~H)X*%_q0U8e{rAPtQTAO z#d?*6!LOKAWB7jzQ|T)B+ij{7jk1=`=H{Mb=T-c%^Xe@NF{9J^;eFFJssK8Dy`DO+ z`$@~6|4eQO;i|$5YBa;hwI-|_k{OznVnK=vx7K!gz2woCq54Cjn21K=5~Gac zzn!I7@FTxqlJ;N-{`PA!LC5E4b$s4jtvx@yw$7cDL~d$VjVrk(In`O~s&&>losLwO z+vQ5D zjA!o9YUQ?ARdfb==jq{mZjN8PG35ID&acb?MS;f(V@eLJf4%M1TSvX*6(}mopOF7Q D|FgCB diff --git a/vendor/autoload.php b/vendor/autoload.php index cea0f7a69d..76e7b3236c 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitcb7c1594bf378622122ae8e77daf1532::getLoader(); +return ComposerAutoloaderInit1983a0e55fe28bbf984fa65ef179598e::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 71686893fd..6960e054cc 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitcb7c1594bf378622122ae8e77daf1532 +class ComposerAutoloaderInit1983a0e55fe28bbf984fa65ef179598e { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInitcb7c1594bf378622122ae8e77daf1532 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitcb7c1594bf378622122ae8e77daf1532', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit1983a0e55fe28bbf984fa65ef179598e', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitcb7c1594bf378622122ae8e77daf1532', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit1983a0e55fe28bbf984fa65ef179598e', 'loadClassLoader')); $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index dcadf3a689..9cc6d43233 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -559,61 +559,6 @@ "spl" ] }, - { - "name": "symfony/console", - "version": "v2.3.7", - "version_normalized": "2.3.7.0", - "target-dir": "Symfony/Component/Console", - "source": { - "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/00848d3e13cf512e77c7498c2b3b0192f61f4b18", - "reference": "00848d3e13cf512e77c7498c2b3b0192f61f4b18", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/event-dispatcher": "~2.1" - }, - "suggest": { - "symfony/event-dispatcher": "" - }, - "time": "2013-11-13 21:27:40", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "http://symfony.com" - }, { "name": "doctrine/dbal", "version": "v2.4.1", @@ -760,55 +705,6 @@ "orm" ] }, - { - "name": "symfony/yaml", - "version": "v2.3.7", - "version_normalized": "2.3.7.0", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/c1bda5b459d792cb253de12c65beba3040163b2b", - "reference": "c1bda5b459d792cb253de12c65beba3040163b2b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2013-10-17 11:48:01", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com" - }, { "name": "phpunit/php-token-stream", "version": "1.2.1", @@ -1048,24 +944,76 @@ ] }, { - "name": "slim/slim", - "version": "2.2.0", - "version_normalized": "2.2.0.0", + "name": "symfony/yaml", + "version": "v2.4.0", + "version_normalized": "2.4.0.0", + "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", - "url": "https://github.com/codeguy/Slim.git", - "reference": "b8181de1112a1e2f565b40158b621c34ded38053" + "url": "https://github.com/symfony/Yaml.git", + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/codeguy/Slim/zipball/b8181de1112a1e2f565b40158b621c34ded38053", - "reference": "b8181de1112a1e2f565b40158b621c34ded38053", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", + "reference": "1ae235a1b9d3ad3d9f3860ff20acc072df95b7f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2013-11-26 16:40:27", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com" + }, + { + "name": "slim/slim", + "version": "2.4.0", + "version_normalized": "2.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/codeguy/Slim.git", + "reference": "ff7d7148848fa4f45712984d7b91ac3cbced586b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/codeguy/Slim/zipball/ff7d7148848fa4f45712984d7b91ac3cbced586b", + "reference": "ff7d7148848fa4f45712984d7b91ac3cbced586b", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2012-12-13 02:15:50", + "suggest": { + "ext-mcrypt": "Required for HTTP cookie encryption" + }, + "time": "2013-11-29 20:33:36", "type": "library", "installation-source": "dist", "autoload": { @@ -1091,5 +1039,60 @@ "rest", "router" ] + }, + { + "name": "symfony/console", + "version": "v2.4.0", + "version_normalized": "2.4.0.0", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", + "reference": "3c1496ae96d24ccc6c340fcc25f71d7a1ab4c12c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/event-dispatcher": "~2.1" + }, + "suggest": { + "symfony/event-dispatcher": "" + }, + "time": "2013-11-27 09:10:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com" } ] diff --git a/vendor/slim/slim/.travis.yml b/vendor/slim/slim/.travis.yml index e5f88b3479..ac79ecea1d 100644 --- a/vendor/slim/slim/.travis.yml +++ b/vendor/slim/slim/.travis.yml @@ -3,5 +3,6 @@ language: php php: - 5.3 - 5.4 + - 5.5 script: phpunit --coverage-text diff --git a/vendor/slim/slim/README.markdown b/vendor/slim/slim/README.markdown index cad57a6121..802624b50b 100644 --- a/vendor/slim/slim/README.markdown +++ b/vendor/slim/slim/README.markdown @@ -1,6 +1,6 @@ # Slim Framework -[![Build Status](https://secure.travis-ci.org/codeguy/Slim.png)](http://travis-ci.org/codeguy/Slim) +[![Build Status](https://secure.travis-ci.org/codeguy/Slim.png?branch=master)](http://travis-ci.org/codeguy/Slim) Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs. Slim is easy to use for both beginners and professionals. Slim favors cleanliness over terseness and common cases @@ -14,6 +14,7 @@ Thank you for choosing the Slim Framework for your next project. I think you're * Route parameters with wildcards and conditions * Route redirect, halt, and pass * Route middleware +* Resource Locator and DI container * Template rendering with custom views * Flash messages * Secure cookies with AES-256 encryption @@ -29,7 +30,7 @@ Thank you for choosing the Slim Framework for your next project. I think you're You may install the Slim Framework with Composer (recommended) or manually. -[Read how to install Slim](http://docs.slimframework.com/pages/getting-started-install) +[Read how to install Slim](http://docs.slimframework.com/#Installation) ### System Requirements @@ -64,12 +65,38 @@ should contain this code: #### Nginx -Your nginx configuration file should contain this code (along with other settings you may need) in your `location` block: +The nginx configuration file should contain this code (along with other settings you may need) in your `location` block: - try_files $uri $uri/ /index.php; + try_files $uri $uri/ /index.php?$args; This assumes that Slim's `index.php` is in the root folder of your project (www root). +#### HipHop Virtual Machine for PHP + +Your HipHop Virtual Machine configuration file should contain this code (along with other settings you may need). +Be sure you change the `ServerRoot` setting to point to your Slim app's document root directory. + + Server { + SourceRoot = /path/to/public/directory + } + + ServerVariables { + SCRIPT_NAME = /index.php + } + + VirtualHost { + * { + Pattern = .* + RewriteRules { + * { + pattern = ^(.*)$ + to = index.php/$1 + qsa = true + } + } + } + } + #### lighttpd #### Your lighttpd configuration file should contain this code (along with other settings you may need). This code requires @@ -79,6 +106,28 @@ lighttpd >= 1.4.24. This assumes that Slim's `index.php` is in the root folder of your project (www root). +#### IIS + +Ensure the `Web.config` and `index.php` files are in the same public-accessible directory. The `Web.config` file should contain this code: + + + + + + + + + + + + + + + + + + + ## Documentation @@ -118,7 +167,7 @@ Follow [@slimphp](http://www.twitter.com/slimphp) on Twitter to receive news and ## Author -The Slim Framework is created and maintained by [Josh Lockhart](https://www.joshlockhart.com). Josh is a senior +The Slim Framework is created and maintained by [Josh Lockhart](http://www.joshlockhart.com). Josh is a senior web developer at [New Media Campaigns](http://www.newmediacampaigns.com/). Josh also created and maintains [PHP: The Right Way](http://www.phptherightway.com/), a popular movement in the PHP community to introduce new PHP programmers to best practices and good information. diff --git a/vendor/slim/slim/Slim/Environment.php b/vendor/slim/slim/Slim/Environment.php index 147d00f206..8350b60444 100644 --- a/vendor/slim/slim/Slim/Environment.php +++ b/vendor/slim/slim/Slim/Environment.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -87,7 +87,7 @@ class Environment implements \ArrayAccess, \IteratorAggregate */ public static function mock($userSettings = array()) { - self::$environment = new self(array_merge(array( + $defaults = array( 'REQUEST_METHOD' => 'GET', 'SCRIPT_NAME' => '', 'PATH_INFO' => '', @@ -102,7 +102,8 @@ class Environment implements \ArrayAccess, \IteratorAggregate 'slim.url_scheme' => 'http', 'slim.input' => '', 'slim.errors' => @fopen('php://stderr', 'w') - ), $userSettings)); + ); + self::$environment = new self(array_merge($defaults, $userSettings)); return self::$environment; } @@ -125,35 +126,26 @@ class Environment implements \ArrayAccess, \IteratorAggregate //The IP $env['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR']; - /** - * Application paths - * - * This derives two paths: SCRIPT_NAME and PATH_INFO. The SCRIPT_NAME - * is the real, physical path to the application, be it in the root - * directory or a subdirectory of the public document root. The PATH_INFO is the - * virtual path to the requested resource within the application context. - * - * With htaccess, the SCRIPT_NAME will be an absolute path (without file name); - * if not using htaccess, it will also include the file name. If it is "/", - * it is set to an empty string (since it cannot have a trailing slash). - * - * The PATH_INFO will be an absolute path with a leading slash; this will be - * used for application routing. - */ - if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) { - $env['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME']; //Without URL rewrite - } else { - $env['SCRIPT_NAME'] = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']) ); //With URL rewrite - } - $env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME'])); - if (strpos($env['PATH_INFO'], '?') !== false) { - $env['PATH_INFO'] = substr_replace($env['PATH_INFO'], '', strpos($env['PATH_INFO'], '?')); //query string is not removed automatically - } - $env['SCRIPT_NAME'] = rtrim($env['SCRIPT_NAME'], '/'); - $env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/'); + // Server params + $scriptName = $_SERVER['SCRIPT_NAME']; // <-- "/foo/index.php" + $requestUri = $_SERVER['REQUEST_URI']; // <-- "/foo/bar?test=abc" or "/foo/index.php/bar?test=abc" + $queryString = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; // <-- "test=abc" or "" - //The portion of the request URI following the '?' - $env['QUERY_STRING'] = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; + // Physical path + if (strpos($requestUri, $scriptName) !== false) { + $physicalPath = $scriptName; // <-- Without rewriting + } else { + $physicalPath = str_replace('\\', '', dirname($scriptName)); // <-- With rewriting + } + $env['SCRIPT_NAME'] = rtrim($physicalPath, '/'); // <-- Remove trailing slashes + + // Virtual path + $env['PATH_INFO'] = substr_replace($requestUri, '', 0, strlen($physicalPath)); // <-- Remove physical path + $env['PATH_INFO'] = str_replace('?' . $queryString, '', $env['PATH_INFO']); // <-- Remove query string + $env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/'); // <-- Ensure leading slash + + // Query string (without leading "?") + $env['QUERY_STRING'] = $queryString; //Name of server host that is running the script $env['SERVER_NAME'] = $_SERVER['SERVER_NAME']; @@ -161,21 +153,16 @@ class Environment implements \ArrayAccess, \IteratorAggregate //Number of server port that is running the script $env['SERVER_PORT'] = $_SERVER['SERVER_PORT']; - //HTTP request headers - $specialHeaders = array('CONTENT_TYPE', 'CONTENT_LENGTH', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'PHP_AUTH_DIGEST', 'AUTH_TYPE'); - foreach ($_SERVER as $key => $value) { - $value = is_string($value) ? trim($value) : $value; - if (strpos($key, 'HTTP_') === 0) { - $env[substr($key, 5)] = $value; - } elseif (strpos($key, 'X_') === 0 || in_array($key, $specialHeaders)) { - $env[$key] = $value; - } + //HTTP request headers (retains HTTP_ prefix to match $_SERVER) + $headers = \Slim\Http\Headers::extract($_SERVER); + foreach ($headers as $key => $value) { + $env[$key] = $value; } //Is the application running under HTTPS or HTTP protocol? $env['slim.url_scheme'] = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ? 'http' : 'https'; - //Input stream (readable one time only; not available for mutipart/form-data requests) + //Input stream (readable one time only; not available for multipart/form-data requests) $rawInput = @file_get_contents('php://input'); if (!$rawInput) { $rawInput = ''; @@ -183,7 +170,7 @@ class Environment implements \ArrayAccess, \IteratorAggregate $env['slim.input'] = $rawInput; //Error stream - $env['slim.errors'] = fopen('php://stderr', 'w'); + $env['slim.errors'] = @fopen('php://stderr', 'w'); $this->properties = $env; } diff --git a/vendor/slim/slim/Slim/Exception/Pass.php b/vendor/slim/slim/Slim/Exception/Pass.php index f4f25fac57..15c822ea4e 100644 --- a/vendor/slim/slim/Slim/Exception/Pass.php +++ b/vendor/slim/slim/Slim/Exception/Pass.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -46,5 +46,4 @@ namespace Slim\Exception; */ class Pass extends \Exception { - } diff --git a/vendor/slim/slim/Slim/Exception/Stop.php b/vendor/slim/slim/Slim/Exception/Stop.php index f008959a49..ffb0560168 100644 --- a/vendor/slim/slim/Slim/Exception/Stop.php +++ b/vendor/slim/slim/Slim/Exception/Stop.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -44,5 +44,4 @@ namespace Slim\Exception; */ class Stop extends \Exception { - } diff --git a/vendor/slim/slim/Slim/Http/Headers.php b/vendor/slim/slim/Slim/Http/Headers.php index 0185f086b8..ac05df3422 100644 --- a/vendor/slim/slim/Slim/Http/Headers.php +++ b/vendor/slim/slim/Slim/Http/Headers.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -35,147 +35,70 @@ namespace Slim\Http; /** * HTTP Headers * - * This class is an abstraction of the HTTP response headers and - * provides array access to the header list while automatically - * stores and retrieves headers with lowercase canonical keys regardless - * of the input format. - * - * This class also implements the `Iterator` and `Countable` - * interfaces for even more convenient usage. - * * @package Slim * @author Josh Lockhart * @since 1.6.0 */ -class Headers implements \ArrayAccess, \Iterator, \Countable +class Headers extends \Slim\Helper\Set { - /** - * @var array HTTP headers - */ - protected $headers; + /******************************************************************************** + * Static interface + *******************************************************************************/ /** - * @var array Map canonical header name to original header name + * Special-case HTTP headers that are otherwise unidentifiable as HTTP headers. + * Typically, HTTP headers in the $_SERVER array will be prefixed with + * `HTTP_` or `X_`. These are not so we list them here for later reference. + * + * @var array */ - protected $map; + protected static $special = array( + 'CONTENT_TYPE', + 'CONTENT_LENGTH', + 'PHP_AUTH_USER', + 'PHP_AUTH_PW', + 'PHP_AUTH_DIGEST', + 'AUTH_TYPE' + ); /** - * Constructor - * @param array $headers + * Extract HTTP headers from an array of data (e.g. $_SERVER) + * @param array $data + * @return array */ - public function __construct($headers = array()) + public static function extract($data) { - $this->merge($headers); - } - - /** - * Merge Headers - * @param array $headers - */ - public function merge($headers) - { - foreach ($headers as $name => $value) { - $this[$name] = $value; + $results = array(); + foreach ($data as $key => $value) { + $key = strtoupper($key); + if (strpos($key, 'X_') === 0 || strpos($key, 'HTTP_') === 0 || in_array($key, static::$special)) { + if ($key === 'HTTP_CONTENT_TYPE' || $key === 'HTTP_CONTENT_LENGTH') { + continue; + } + $results[$key] = $value; + } } + + return $results; } + /******************************************************************************** + * Instance interface + *******************************************************************************/ + /** * Transform header name into canonical form - * @param string $name + * @param string $key * @return string */ - protected function canonical($name) + protected function normalizeKey($key) { - return strtolower(trim($name)); - } + $key = strtolower($key); + $key = str_replace(array('-', '_'), ' ', $key); + $key = preg_replace('#^http #', '', $key); + $key = ucwords($key); + $key = str_replace(' ', '-', $key); - /** - * Array Access: Offset Exists - */ - public function offsetExists($offset) - { - return isset($this->headers[$this->canonical($offset)]); - } - - /** - * Array Access: Offset Get - */ - public function offsetGet($offset) - { - $canonical = $this->canonical($offset); - if (isset($this->headers[$canonical])) { - return $this->headers[$canonical]; - } else { - return null; - } - } - - /** - * Array Access: Offset Set - */ - public function offsetSet($offset, $value) - { - $canonical = $this->canonical($offset); - $this->headers[$canonical] = $value; - $this->map[$canonical] = $offset; - } - - /** - * Array Access: Offset Unset - */ - public function offsetUnset($offset) - { - $canonical = $this->canonical($offset); - unset($this->headers[$canonical], $this->map[$canonical]); - } - - /** - * Countable: Count - */ - public function count() - { - return count($this->headers); - } - - /** - * Iterator: Rewind - */ - public function rewind() - { - reset($this->headers); - } - - /** - * Iterator: Current - */ - public function current() - { - return current($this->headers); - } - - /** - * Iterator: Key - */ - public function key() - { - $key = key($this->headers); - - return $this->map[$key]; - } - - /** - * Iterator: Next - */ - public function next() - { - return next($this->headers); - } - - /** - * Iterator: Valid - */ - public function valid() - { - return current($this->headers) !== false; + return $key; } } diff --git a/vendor/slim/slim/Slim/Http/Request.php b/vendor/slim/slim/Slim/Http/Request.php index e508394ada..2a62242ac0 100644 --- a/vendor/slim/slim/Slim/Http/Request.php +++ b/vendor/slim/slim/Slim/Http/Request.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -48,6 +48,7 @@ class Request const METHOD_GET = 'GET'; const METHOD_POST = 'POST'; const METHOD_PUT = 'PUT'; + const METHOD_PATCH = 'PATCH'; const METHOD_DELETE = 'DELETE'; const METHOD_OPTIONS = 'OPTIONS'; const METHOD_OVERRIDE = '_METHOD'; @@ -58,18 +59,32 @@ class Request protected static $formDataMediaTypes = array('application/x-www-form-urlencoded'); /** - * @var array + * Application Environment + * @var \Slim\Environment */ protected $env; /** - * Constructor - * @param array $env - * @see \Slim\Environment + * HTTP Headers + * @var \Slim\Http\Headers */ - public function __construct($env) + public $headers; + + /** + * HTTP Cookies + * @var \Slim\Helper\Set + */ + public $cookies; + + /** + * Constructor + * @param \Slim\Environment $env + */ + public function __construct(\Slim\Environment $env) { $this->env = $env; + $this->headers = new \Slim\Http\Headers(\Slim\Http\Headers::extract($env)); + $this->cookies = new \Slim\Helper\Set(\Slim\Http\Util::parseCookieHeader($env['HTTP_COOKIE'])); } /** @@ -108,6 +123,15 @@ class Request return $this->getMethod() === self::METHOD_PUT; } + /** + * Is this a PATCH request? + * @return bool + */ + public function isPatch() + { + return $this->getMethod() === self::METHOD_PATCH; + } + /** * Is this a DELETE request? * @return bool @@ -143,7 +167,7 @@ class Request { if ($this->params('isajax')) { return true; - } elseif (isset($this->env['X_REQUESTED_WITH']) && $this->env['X_REQUESTED_WITH'] === 'XMLHttpRequest') { + } elseif (isset($this->headers['X_REQUESTED_WITH']) && $this->headers['X_REQUESTED_WITH'] === 'XMLHttpRequest') { return true; } else { return false; @@ -172,14 +196,10 @@ class Request { $union = array_merge($this->get(), $this->post()); if ($key) { - if (isset($union[$key])) { - return $union[$key]; - } else { - return null; - } - } else { - return $union; + return isset($union[$key]) ? $union[$key] : null; } + + return $union; } /** @@ -189,9 +209,10 @@ class Request * the value of the array key if requested; if the array key does not exist, NULL is returned. * * @param string $key + * @param mixed $default Default return value when key does not exist * @return array|mixed|null */ - public function get($key = null) + public function get($key = null, $default = null) { if (!isset($this->env['slim.request.query_hash'])) { $output = array(); @@ -206,7 +227,7 @@ class Request if (isset($this->env['slim.request.query_hash'][$key])) { return $this->env['slim.request.query_hash'][$key]; } else { - return null; + return $default; } } else { return $this->env['slim.request.query_hash']; @@ -220,10 +241,11 @@ class Request * the value of a hash key if requested; if the array key does not exist, NULL is returned. * * @param string $key + * @param mixed $default Default return value when key does not exist * @return array|mixed|null * @throws \RuntimeException If environment input is not available */ - public function post($key = null) + public function post($key = null, $default = null) { if (!isset($this->env['slim.input'])) { throw new \RuntimeException('Missing slim.input in environment variables'); @@ -246,7 +268,7 @@ class Request if (isset($this->env['slim.request.form_hash'][$key])) { return $this->env['slim.request.form_hash'][$key]; } else { - return null; + return $default; } } else { return $this->env['slim.request.form_hash']; @@ -256,21 +278,34 @@ class Request /** * Fetch PUT data (alias for \Slim\Http\Request::post) * @param string $key + * @param mixed $default Default return value when key does not exist * @return array|mixed|null */ - public function put($key = null) + public function put($key = null, $default = null) { - return $this->post($key); + return $this->post($key, $default); + } + + /** + * Fetch PATCH data (alias for \Slim\Http\Request::post) + * @param string $key + * @param mixed $default Default return value when key does not exist + * @return array|mixed|null + */ + public function patch($key = null, $default = null) + { + return $this->post($key, $default); } /** * Fetch DELETE data (alias for \Slim\Http\Request::post) * @param string $key + * @param mixed $default Default return value when key does not exist * @return array|mixed|null */ - public function delete($key = null) + public function delete($key = null, $default = null) { - return $this->post($key); + return $this->post($key, $default); } /** @@ -284,23 +319,28 @@ class Request */ public function cookies($key = null) { - if (!isset($this->env['slim.request.cookie_hash'])) { - $cookieHeader = isset($this->env['COOKIE']) ? $this->env['COOKIE'] : ''; - $this->env['slim.request.cookie_hash'] = Util::parseCookieHeader($cookieHeader); - } if ($key) { - if (isset($this->env['slim.request.cookie_hash'][$key])) { - return $this->env['slim.request.cookie_hash'][$key]; - } else { - return null; - } - } else { - return $this->env['slim.request.cookie_hash']; + return $this->cookies->get($key); } + + return $this->cookies; + // if (!isset($this->env['slim.request.cookie_hash'])) { + // $cookieHeader = isset($this->env['COOKIE']) ? $this->env['COOKIE'] : ''; + // $this->env['slim.request.cookie_hash'] = Util::parseCookieHeader($cookieHeader); + // } + // if ($key) { + // if (isset($this->env['slim.request.cookie_hash'][$key])) { + // return $this->env['slim.request.cookie_hash'][$key]; + // } else { + // return null; + // } + // } else { + // return $this->env['slim.request.cookie_hash']; + // } } /** - * Does the Request body contain parseable form data? + * Does the Request body contain parsed form data? * @return bool */ public function isFormData() @@ -323,24 +363,29 @@ class Request public function headers($key = null, $default = null) { if ($key) { - $key = strtoupper($key); - $key = str_replace('-', '_', $key); - $key = preg_replace('@^HTTP_@', '', $key); - if (isset($this->env[$key])) { - return $this->env[$key]; - } else { - return $default; - } - } else { - $headers = array(); - foreach ($this->env as $key => $value) { - if (strpos($key, 'slim.') !== 0) { - $headers[$key] = $value; - } - } - - return $headers; + return $this->headers->get($key, $default); } + + return $this->headers; + // if ($key) { + // $key = strtoupper($key); + // $key = str_replace('-', '_', $key); + // $key = preg_replace('@^HTTP_@', '', $key); + // if (isset($this->env[$key])) { + // return $this->env[$key]; + // } else { + // return $default; + // } + // } else { + // $headers = array(); + // foreach ($this->env as $key => $value) { + // if (strpos($key, 'slim.') !== 0) { + // $headers[$key] = $value; + // } + // } + // + // return $headers; + // } } /** @@ -354,15 +399,11 @@ class Request /** * Get Content Type - * @return string + * @return string|null */ public function getContentType() { - if (isset($this->env['CONTENT_TYPE'])) { - return $this->env['CONTENT_TYPE']; - } else { - return null; - } + return $this->headers->get('CONTENT_TYPE'); } /** @@ -376,9 +417,9 @@ class Request $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); return strtolower($contentTypeParts[0]); - } else { - return null; } + + return null; } /** @@ -410,9 +451,9 @@ class Request $mediaTypeParams = $this->getMediaTypeParams(); if (isset($mediaTypeParams['charset'])) { return $mediaTypeParams['charset']; - } else { - return null; } + + return null; } /** @@ -421,11 +462,7 @@ class Request */ public function getContentLength() { - if (isset($this->env['CONTENT_LENGTH'])) { - return (int) $this->env['CONTENT_LENGTH']; - } else { - return 0; - } + return $this->headers->get('CONTENT_LENGTH', 0); } /** @@ -434,17 +471,17 @@ class Request */ public function getHost() { - if (isset($this->env['HOST'])) { - if (strpos($this->env['HOST'], ':') !== false) { - $hostParts = explode(':', $this->env['HOST']); + if (isset($this->env['HTTP_HOST'])) { + if (strpos($this->env['HTTP_HOST'], ':') !== false) { + $hostParts = explode(':', $this->env['HTTP_HOST']); return $hostParts[0]; } - return $this->env['HOST']; - } else { - return $this->env['SERVER_NAME']; + return $this->env['HTTP_HOST']; } + + return $this->env['SERVER_NAME']; } /** @@ -462,7 +499,7 @@ class Request */ public function getPort() { - return (int) $this->env['SERVER_PORT']; + return (int)$this->env['SERVER_PORT']; } /** @@ -554,11 +591,7 @@ class Request */ public function getReferrer() { - if (isset($this->env['REFERER'])) { - return $this->env['REFERER']; - } else { - return null; - } + return $this->headers->get('HTTP_REFERER'); } /** @@ -576,10 +609,6 @@ class Request */ public function getUserAgent() { - if (isset($this->env['USER_AGENT'])) { - return $this->env['USER_AGENT']; - } else { - return null; - } + return $this->headers->get('HTTP_USER_AGENT'); } } diff --git a/vendor/slim/slim/Slim/Http/Response.php b/vendor/slim/slim/Slim/Http/Response.php index 8e95b376fb..b740214f19 100644 --- a/vendor/slim/slim/Slim/Http/Response.php +++ b/vendor/slim/slim/Slim/Http/Response.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -51,9 +51,14 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate protected $status; /** - * @var \Slim\Http\Headers List of HTTP response headers + * @var \Slim\Http\Headers */ - protected $header; + public $headers; + + /** + * @var \Slim\Http\Cookies + */ + public $cookies; /** * @var string HTTP response body @@ -108,6 +113,7 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate 415 => '415 Unsupported Media Type', 416 => '416 Requested Range Not Satisfiable', 417 => '417 Expectation Failed', + 418 => '418 I\'m a teapot', 422 => '422 Unprocessable Entity', 423 => '423 Locked', //Server Error 5xx @@ -123,21 +129,30 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate * Constructor * @param string $body The HTTP response body * @param int $status The HTTP response status - * @param \Slim\Http\Headers|array $header The HTTP response headers + * @param \Slim\Http\Headers|array $headers The HTTP response headers */ - public function __construct($body = '', $status = 200, $header = array()) + public function __construct($body = '', $status = 200, $headers = array()) { - $this->status = (int) $status; - $headers = array(); - foreach ($header as $key => $value) { - $headers[$key] = $value; - } - $this->header = new Headers(array_merge(array('Content-Type' => 'text/html'), $headers)); - $this->body = ''; + $this->setStatus($status); + $this->headers = new \Slim\Http\Headers(array('Content-Type' => 'text/html')); + $this->headers->replace($headers); + $this->cookies = new \Slim\Http\Cookies(); $this->write($body); } + public function getStatus() + { + return $this->status; + } + + public function setStatus($status) + { + $this->status = (int)$status; + } + /** + * DEPRECATION WARNING! Use `getStatus` or `setStatus` instead. + * * Get and set status * @param int|null $status * @return int @@ -152,6 +167,8 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate } /** + * DEPRECATION WARNING! Access `headers` property directly. + * * Get and set header * @param string $name Header name * @param string|null $value Header value @@ -160,22 +177,36 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate public function header($name, $value = null) { if (!is_null($value)) { - $this[$name] = $value; + $this->headers->set($name, $value); } - return $this[$name]; + return $this->headers->get($name); } /** + * DEPRECATION WARNING! Access `headers` property directly. + * * Get headers * @return \Slim\Http\Headers */ public function headers() { - return $this->header; + return $this->headers; + } + + public function getBody() + { + return $this->body; + } + + public function setBody($content) + { + $this->write($content, true); } /** + * DEPRECATION WARNING! use `getBody` or `setBody` instead. + * * Get and set body * @param string|null $body Content of HTTP response body * @return string @@ -190,6 +221,31 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate } /** + * Append HTTP response body + * @param string $body Content to append to the current HTTP response body + * @param bool $replace Overwrite existing response body? + * @return string The updated HTTP response body + */ + public function write($body, $replace = false) + { + if ($replace) { + $this->body = $body; + } else { + $this->body .= (string)$body; + } + $this->length = strlen($this->body); + + return $this->body; + } + + public function getLength() + { + return $this->length; + } + + /** + * DEPRECATION WARNING! Use `getLength` or `write` or `body` instead. + * * Get and set length * @param int|null $length * @return int @@ -203,24 +259,6 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate return $this->length; } - /** - * Append HTTP response body - * @param string $body Content to append to the current HTTP response body - * @param bool $replace Overwrite existing response body? - * @return string The updated HTTP response body - */ - public function write($body, $replace = false) - { - if ($replace) { - $this->body = $body; - } else { - $this->body .= (string) $body; - } - $this->length = strlen($this->body); - - return $this->body; - } - /** * Finalize * @@ -232,16 +270,19 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function finalize() { + // Prepare response if (in_array($this->status, array(204, 304))) { - unset($this['Content-Type'], $this['Content-Length']); - - return array($this->status, $this->header, ''); - } else { - return array($this->status, $this->header, $this->body); + $this->headers->remove('Content-Type'); + $this->headers->remove('Content-Length'); + $this->setBody(''); } + + return array($this->status, $this->headers, $this->body); } /** + * DEPRECATION WARNING! Access `cookies` property directly. + * * Set cookie * * Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie` @@ -256,10 +297,13 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function setCookie($name, $value) { - Util::setCookieHeader($this->header, $name, $value); + // Util::setCookieHeader($this->header, $name, $value); + $this->cookies->set($name, $value); } /** + * DEPRECATION WARNING! Access `cookies` property directly. + * * Delete cookie * * Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie` @@ -274,12 +318,13 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate * array, only the Cookie with the given name AND domain will be removed. The invalidating cookie * sent with this response will adopt all properties of the second argument. * - * @param string $name The name of the cookie - * @param array $value Properties for cookie including: value, expire, path, domain, secure, httponly + * @param string $name The name of the cookie + * @param array $settings Properties for cookie including: value, expire, path, domain, secure, httponly */ - public function deleteCookie($name, $value = array()) + public function deleteCookie($name, $settings = array()) { - Util::deleteCookieHeader($this->header, $name, $value); + $this->cookies->remove($name, $settings); + // Util::deleteCookieHeader($this->header, $name, $value); } /** @@ -293,8 +338,8 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function redirect ($url, $status = 302) { - $this->status = $status; - $this['Location'] = $url; + $this->setStatus($status); + $this->headers->set('Location', $url); } /** @@ -387,24 +432,25 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate return $this->status >= 500 && $this->status < 600; } + /** + * DEPRECATION WARNING! ArrayAccess interface will be removed from \Slim\Http\Response. + * Iterate `headers` or `cookies` properties directly. + */ + /** * Array Access: Offset Exists */ - public function offsetExists( $offset ) + public function offsetExists($offset) { - return isset($this->header[$offset]); + return isset($this->headers[$offset]); } /** * Array Access: Offset Get */ - public function offsetGet( $offset ) + public function offsetGet($offset) { - if (isset($this->header[$offset])) { - return $this->header[$offset]; - } else { - return null; - } + return $this->headers[$offset]; } /** @@ -412,7 +458,7 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function offsetSet($offset, $value) { - $this->header[$offset] = $value; + $this->headers[$offset] = $value; } /** @@ -420,18 +466,24 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function offsetUnset($offset) { - unset($this->header[$offset]); + unset($this->headers[$offset]); } /** + * DEPRECATION WARNING! Countable interface will be removed from \Slim\Http\Response. + * Call `count` on `headers` or `cookies` properties directly. + * * Countable: Count */ public function count() { - return count($this->header); + return count($this->headers); } /** + * DEPRECATION WARNING! IteratorAggregate interface will be removed from \Slim\Http\Response. + * Iterate `headers` or `cookies` properties directly. + * * Get Iterator * * This returns the contained `\Slim\Http\Headers` instance which @@ -441,11 +493,12 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate */ public function getIterator() { - return $this->header; + return $this->headers->getIterator(); } /** * Get message for HTTP status code + * @param int $status * @return string|null */ public static function getMessageForCode($status) diff --git a/vendor/slim/slim/Slim/Http/Util.php b/vendor/slim/slim/Slim/Http/Util.php index f7e99a9624..b95fe3ddd0 100644 --- a/vendor/slim/slim/Slim/Http/Util.php +++ b/vendor/slim/slim/Slim/Http/Util.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -51,14 +51,15 @@ class Util * override the magic quotes setting with either TRUE or FALSE as the send argument * to force this method to strip or not strip slashes from its input. * - * @var array|string $rawData + * @param array|string $rawData + * @param bool $overrideStripSlashes * @return array|string */ public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null) { $strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes; if ($strip) { - return self::_stripSlashes($rawData); + return self::stripSlashes($rawData); } else { return $rawData; } @@ -69,9 +70,9 @@ class Util * @param array|string $rawData * @return array|string */ - protected static function _stripSlashes($rawData) + protected static function stripSlashes($rawData) { - return is_array($rawData) ? array_map(array('self', '_stripSlashes'), $rawData) : stripslashes($rawData); + return is_array($rawData) ? array_map(array('self', 'stripSlashes'), $rawData) : stripslashes($rawData); } /** @@ -95,10 +96,11 @@ class Util } //Merge settings with defaults - $settings = array_merge(array( + $defaults = array( 'algorithm' => MCRYPT_RIJNDAEL_256, 'mode' => MCRYPT_MODE_CBC - ), $settings); + ); + $settings = array_merge($defaults, $settings); //Get module $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], ''); @@ -144,10 +146,11 @@ class Util } //Merge settings with defaults - $settings = array_merge(array( + $defaults = array( 'algorithm' => MCRYPT_RIJNDAEL_256, 'mode' => MCRYPT_MODE_CBC - ), $settings); + ); + $settings = array_merge($defaults, $settings); //Get module $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], ''); @@ -167,12 +170,44 @@ class Util //Decrypt value mcrypt_generic_init($module, $key, $iv); $decryptedData = @mdecrypt_generic($module, $data); - $res = str_replace("\x0", '', $decryptedData); + $res = rtrim($decryptedData, "\0"); mcrypt_generic_deinit($module); return $res; } + /** + * Serialize Response cookies into raw HTTP header + * @param \Slim\Http\Headers $headers The Response headers + * @param \Slim\Http\Cookies $cookies The Response cookies + * @param array $config The Slim app settings + */ + public static function serializeCookies(\Slim\Http\Headers &$headers, \Slim\Http\Cookies $cookies, array $config) + { + if ($config['cookies.encrypt']) { + foreach ($cookies as $name => $settings) { + if (is_string($settings['expires'])) { + $expires = strtotime($settings['expires']); + } else { + $expires = (int) $settings['expires']; + } + + $settings['value'] = static::encodeSecureCookie( + $settings['value'], + $expires, + $config['cookies.secret_key'], + $config['cookies.cipher'], + $config['cookies.cipher_mode'] + ); + static::setCookieHeader($headers, $name, $settings); + } + } else { + foreach ($cookies as $name => $settings) { + static::setCookieHeader($headers, $name, $settings); + } + } + } + /** * Encode secure cookie value * @@ -180,21 +215,28 @@ class Util * cookie value is encrypted and hashed so that its value is * secure and checked for integrity when read in subsequent requests. * - * @param string $value The unsecure HTTP cookie value + * @param string $value The insecure HTTP cookie value * @param int $expires The UNIX timestamp at which this cookie will expire * @param string $secret The secret key used to hash the cookie value * @param int $algorithm The algorithm to use for encryption * @param int $mode The algorithm mode to use for encryption - * @param string + * @return string */ public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode) { $key = hash_hmac('sha1', $expires, $secret); - $iv = self::get_iv($expires, $secret); - $secureString = base64_encode(self::encrypt($value, $key, $iv, array( - 'algorithm' => $algorithm, - 'mode' => $mode - ))); + $iv = self::getIv($expires, $secret); + $secureString = base64_encode( + self::encrypt( + $value, + $key, + $iv, + array( + 'algorithm' => $algorithm, + 'mode' => $mode + ) + ) + ); $verificationString = hash_hmac('sha1', $expires . $value, $key); return implode('|', array($expires, $secureString, $verificationString)); @@ -208,11 +250,10 @@ class Util * secure and checked for integrity when read in subsequent requests. * * @param string $value The secure HTTP cookie value - * @param int $expires The UNIX timestamp at which this cookie will expire * @param string $secret The secret key used to hash the cookie value * @param int $algorithm The algorithm to use for encryption * @param int $mode The algorithm mode to use for encryption - * @param string + * @return bool|string */ public static function decodeSecureCookie($value, $secret, $algorithm, $mode) { @@ -220,11 +261,16 @@ class Util $value = explode('|', $value); if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) { $key = hash_hmac('sha1', $value[0], $secret); - $iv = self::get_iv($value[0], $secret); - $data = self::decrypt(base64_decode($value[1]), $key, $iv, array( - 'algorithm' => $algorithm, - 'mode' => $mode - )); + $iv = self::getIv($value[0], $secret); + $data = self::decrypt( + base64_decode($value[1]), + $key, + $iv, + array( + 'algorithm' => $algorithm, + 'mode' => $mode + ) + ); $verificationString = hash_hmac('sha1', $value[0] . $data, $key); if ($verificationString === $value[2]) { return $data; @@ -310,7 +356,7 @@ class Util * * @param array $header * @param string $name - * @param string $value + * @param array $value */ public static function deleteCookieHeader(&$header, $name, $value = array()) { @@ -343,7 +389,7 @@ class Util /** * Parse cookie header * - * This method will parse the HTTP requst's `Cookie` header + * This method will parse the HTTP request's `Cookie` header * and extract cookies into an associative array. * * @param string @@ -376,14 +422,13 @@ class Util * * @param int $expires The UNIX timestamp at which this cookie will expire * @param string $secret The secret key used to hash the cookie value - * @return binary string with length 40 + * @return string Hash */ - private static function get_iv($expires, $secret) + private static function getIv($expires, $secret) { $data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret); $data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret); return pack("h*", $data1.$data2); } - } diff --git a/vendor/slim/slim/Slim/Log.php b/vendor/slim/slim/Slim/Log.php index 7706b2f24d..eb9543e6a4 100644 --- a/vendor/slim/slim/Slim/Log.php +++ b/vendor/slim/slim/Slim/Log.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -39,11 +39,15 @@ namespace Slim; * a Log Writer in conjunction with this Log to write to various output * destinations (e.g. a file). This class provides this interface: * - * debug( mixed $object ) - * info( mixed $object ) - * warn( mixed $object ) - * error( mixed $object ) - * fatal( mixed $object ) + * debug( mixed $object, array $context ) + * info( mixed $object, array $context ) + * notice( mixed $object, array $context ) + * warning( mixed $object, array $context ) + * error( mixed $object, array $context ) + * critical( mixed $object, array $context ) + * alert( mixed $object, array $context ) + * emergency( mixed $object, array $context ) + * log( mixed $level, mixed $object, array $context ) * * This class assumes only that your Log Writer has a public `write()` method * that accepts any object as its one and only argument. The Log Writer @@ -56,21 +60,28 @@ namespace Slim; */ class Log { - const FATAL = 0; - const ERROR = 1; - const WARN = 2; - const INFO = 3; - const DEBUG = 4; + const EMERGENCY = 1; + const ALERT = 2; + const CRITICAL = 3; + const FATAL = 3; //DEPRECATED replace with CRITICAL + const ERROR = 4; + const WARN = 5; + const NOTICE = 6; + const INFO = 7; + const DEBUG = 8; /** * @var array */ protected static $levels = array( - self::FATAL => 'FATAL', - self::ERROR => 'ERROR', - self::WARN => 'WARN', - self::INFO => 'INFO', - self::DEBUG => 'DEBUG' + self::EMERGENCY => 'EMERGENCY', + self::ALERT => 'ALERT', + self::CRITICAL => 'CRITICAL', + self::ERROR => 'ERROR', + self::WARN => 'WARNING', + self::NOTICE => 'NOTICE', + self::INFO => 'INFO', + self::DEBUG => 'DEBUG' ); /** @@ -173,65 +184,166 @@ class Log /** * Log debug message * @param mixed $object - * @return mixed|false What the Logger returns, or false if Logger not set or not enabled + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled */ - public function debug($object) + public function debug($object, $context = array()) { - return $this->write($object, self::DEBUG); + return $this->log(self::DEBUG, $object, $context); } /** * Log info message * @param mixed $object - * @return mixed|false What the Logger returns, or false if Logger not set or not enabled + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled */ - public function info($object) + public function info($object, $context = array()) { - return $this->write($object, self::INFO); + return $this->log(self::INFO, $object, $context); } /** - * Log warn message + * Log notice message * @param mixed $object - * @return mixed|false What the Logger returns, or false if Logger not set or not enabled + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled */ - public function warn($object) + public function notice($object, $context = array()) { - return $this->write($object, self::WARN); + return $this->log(self::NOTICE, $object, $context); + } + + /** + * Log warning message + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + */ + public function warning($object, $context = array()) + { + return $this->log(self::WARN, $object, $context); + } + + /** + * DEPRECATED for function warning + * Log warning message + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + */ + public function warn($object, $context = array()) + { + return $this->log(self::WARN, $object, $context); } /** * Log error message * @param mixed $object - * @return mixed|false What the Logger returns, or false if Logger not set or not enabled + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled */ - public function error($object) + public function error($object, $context = array()) { - return $this->write($object, self::ERROR); + return $this->log(self::ERROR, $object, $context); } /** + * Log critical message + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + */ + public function critical($object, $context = array()) + { + return $this->log(self::CRITICAL, $object, $context); + } + + /** + * DEPRECATED for function critical * Log fatal message * @param mixed $object - * @return mixed|false What the Logger returns, or false if Logger not set or not enabled + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled */ - public function fatal($object) + public function fatal($object, $context = array()) { - return $this->write($object, self::FATAL); + return $this->log(self::CRITICAL, $object, $context); + } + + /** + * Log alert message + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + */ + public function alert($object, $context = array()) + { + return $this->log(self::ALERT, $object, $context); + } + + /** + * Log emergency message + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + */ + public function emergency($object, $context = array()) + { + return $this->log(self::EMERGENCY, $object, $context); } /** * Log message - * @param mixed The object to log - * @param int The message level - * @return int|false + * @param mixed $level + * @param mixed $object + * @param array $context + * @return mixed|bool What the Logger returns, or false if Logger not set or not enabled + * @throws \InvalidArgumentException If invalid log level */ - protected function write($object, $level) + public function log($level, $object, $context = array()) { - if ($this->enabled && $this->writer && $level <= $this->level) { - return $this->writer->write($object, $level); + if (!isset(self::$levels[$level])) { + throw new \InvalidArgumentException('Invalid log level supplied to function'); + } else if ($this->enabled && $this->writer && $level <= $this->level) { + $message = (string)$object; + if (count($context) > 0) { + if (isset($context['exception']) && $context['exception'] instanceof \Exception) { + $message .= ' - ' . $context['exception']; + unset($context['exception']); + } + $message = $this->interpolate($message, $context); + } + return $this->writer->write($message, $level); } else { return false; } } + + /** + * DEPRECATED for function log + * Log message + * @param mixed $object The object to log + * @param int $level The message level + * @return int|bool + */ + protected function write($object, $level) + { + return $this->log($level, $object); + } + + /** + * Interpolate log message + * @param mixed $message The log message + * @param array $context An array of placeholder values + * @return string The processed string + */ + protected function interpolate($message, $context = array()) + { + $replace = array(); + foreach ($context as $key => $value) { + $replace['{' . $key . '}'] = $value; + } + return strtr($message, $replace); + } } diff --git a/vendor/slim/slim/Slim/LogWriter.php b/vendor/slim/slim/Slim/LogWriter.php index f26eb0fcbd..e230899a65 100644 --- a/vendor/slim/slim/Slim/LogWriter.php +++ b/vendor/slim/slim/Slim/LogWriter.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -66,7 +66,7 @@ class LogWriter * Write message * @param mixed $message * @param int $level - * @return int|false + * @return int|bool */ public function write($message, $level = null) { diff --git a/vendor/slim/slim/Slim/Middleware.php b/vendor/slim/slim/Slim/Middleware.php index 641226a680..61d670b0f0 100644 --- a/vendor/slim/slim/Slim/Middleware.php +++ b/vendor/slim/slim/Slim/Middleware.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -42,7 +42,7 @@ namespace Slim; abstract class Middleware { /** - * @var \Slim Reference to the primary application instance + * @var \Slim\Slim Reference to the primary application instance */ protected $app; @@ -57,7 +57,7 @@ abstract class Middleware * This method injects the primary Slim application instance into * this middleware. * - * @param \Slim $application + * @param \Slim\Slim $application */ final public function setApplication($application) { @@ -70,7 +70,7 @@ abstract class Middleware * This method retrieves the application previously injected * into this middleware. * - * @return \Slim + * @return \Slim\Slim */ final public function getApplication() { @@ -97,7 +97,7 @@ abstract class Middleware * This method retrieves the next downstream middleware * previously injected into this middleware. * - * @return \Slim|\Slim\Middleware + * @return \Slim\Slim|\Slim\Middleware */ final public function getNextMiddleware() { diff --git a/vendor/slim/slim/Slim/Middleware/ContentTypes.php b/vendor/slim/slim/Slim/Middleware/ContentTypes.php index b11e460523..3bdde0d585 100644 --- a/vendor/slim/slim/Slim/Middleware/ContentTypes.php +++ b/vendor/slim/slim/Slim/Middleware/ContentTypes.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -58,12 +58,13 @@ class ContentTypes extends \Slim\Middleware */ public function __construct($settings = array()) { - $this->contentTypes = array_merge(array( + $defaults = array( 'application/json' => array($this, 'parseJson'), 'application/xml' => array($this, 'parseXml'), 'text/xml' => array($this, 'parseXml'), 'text/csv' => array($this, 'parseCsv') - ), $settings); + ); + $this->contentTypes = array_merge($defaults, $settings); } /** @@ -136,7 +137,10 @@ class ContentTypes extends \Slim\Middleware { if (class_exists('SimpleXMLElement')) { try { - return new \SimpleXMLElement($input); + $backup = libxml_disable_entity_loader(true); + $result = new \SimpleXMLElement($input); + libxml_disable_entity_loader($backup); + return $result; } catch (\Exception $e) { // Do nothing } diff --git a/vendor/slim/slim/Slim/Middleware/Flash.php b/vendor/slim/slim/Slim/Middleware/Flash.php index 510bca3002..5cea0dba2c 100644 --- a/vendor/slim/slim/Slim/Middleware/Flash.php +++ b/vendor/slim/slim/Slim/Middleware/Flash.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -45,7 +45,7 @@ namespace Slim\Middleware; * @author Josh Lockhart * @since 1.6.0 */ -class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate +class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate, \Countable { /** * @var array @@ -59,7 +59,6 @@ class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate /** * Constructor - * @param \Slim $app * @param array $settings */ public function __construct($settings = array()) @@ -199,4 +198,15 @@ class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate return new \ArrayIterator($messages); } + + /** + * Countable: Count + */ + public function count() + { + return count($this->getMessages()); + } + + + } diff --git a/vendor/slim/slim/Slim/Middleware/MethodOverride.php b/vendor/slim/slim/Slim/Middleware/MethodOverride.php index 6f5fffb109..25ea749ab8 100644 --- a/vendor/slim/slim/Slim/Middleware/MethodOverride.php +++ b/vendor/slim/slim/Slim/Middleware/MethodOverride.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -36,7 +36,7 @@ namespace Slim\Middleware; * HTTP Method Override * * This is middleware for a Slim application that allows traditional - * desktop browsers to submit psuedo PUT and DELETE requests by relying + * desktop browsers to submit pseudo PUT and DELETE requests by relying * on a pre-determined request parameter. Without this middleware, * desktop browsers are only able to submit GET and POST requests. * @@ -55,7 +55,6 @@ class MethodOverride extends \Slim\Middleware /** * Constructor - * @param \Slim $app * @param array $settings */ public function __construct($settings = array()) @@ -72,16 +71,15 @@ class MethodOverride extends \Slim\Middleware * modifies the environment settings so downstream middleware and/or the Slim * application will treat the request with the desired HTTP method. * - * @param array $env * @return array[status, header, body] */ public function call() { $env = $this->app->environment(); - if (isset($env['X_HTTP_METHOD_OVERRIDE'])) { + if (isset($env['HTTP_X_HTTP_METHOD_OVERRIDE'])) { // Header commonly used by Backbone.js and others $env['slim.method_override.original_method'] = $env['REQUEST_METHOD']; - $env['REQUEST_METHOD'] = strtoupper($env['X_HTTP_METHOD_OVERRIDE']); + $env['REQUEST_METHOD'] = strtoupper($env['HTTP_X_HTTP_METHOD_OVERRIDE']); } elseif (isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST') { // HTML Form Override $req = new \Slim\Http\Request($env); diff --git a/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php b/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php index e079e30f54..3afb966f63 100644 --- a/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php +++ b/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -66,7 +66,9 @@ class PrettyExceptions extends \Slim\Middleware try { $this->next->call(); } catch (\Exception $e) { + $log = $this->app->getLog(); // Force Slim to append log to env if not already $env = $this->app->environment(); + $env['slim.log'] = $log; $env['slim.log']->error($e); $this->app->contentType('text/html'); $this->app->response()->status(500); diff --git a/vendor/slim/slim/Slim/Middleware/SessionCookie.php b/vendor/slim/slim/Slim/Middleware/SessionCookie.php index 1747a8677d..cf6a02cf62 100644 --- a/vendor/slim/slim/Slim/Middleware/SessionCookie.php +++ b/vendor/slim/slim/Slim/Middleware/SessionCookie.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -40,18 +40,14 @@ namespace Slim\Middleware; * and instead serializes/unserializes the $_SESSION global * variable to/from an HTTP cookie. * - * If a secret key is provided with this middleware, the HTTP - * cookie will be checked for integrity to ensure the client-side - * cookie is not changed. - * * You should NEVER store sensitive data in a client-side cookie - * in any format, encrypted or not. If you need to store sensitive - * user information in a session, you should rely on PHP's native - * session implementation, or use other middleware to store - * session data in a database or alternative server-side cache. + * in any format, encrypted (with cookies.encrypt) or not. If you + * need to store sensitive user information in a session, you should + * rely on PHP's native session implementation, or use other middleware + * to store session data in a database or alternative server-side cache. * * Because this class stores serialized session data in an HTTP cookie, - * you are inherently limtied to 4 Kb. If you attempt to store + * you are inherently limited to 4 Kb. If you attempt to store * more than this amount, serialization will fail. * * @package Slim @@ -68,21 +64,19 @@ class SessionCookie extends \Slim\Middleware /** * Constructor * - * @param array $settings + * @param array $settings */ public function __construct($settings = array()) { - $this->settings = array_merge(array( + $defaults = array( 'expires' => '20 minutes', 'path' => '/', 'domain' => null, 'secure' => false, 'httponly' => false, 'name' => 'slim_session', - 'secret' => 'CHANGE_ME', - 'cipher' => MCRYPT_RIJNDAEL_256, - 'cipher_mode' => MCRYPT_MODE_CBC - ), $settings); + ); + $this->settings = array_merge($defaults, $settings); if (is_string($this->settings['expires'])) { $this->settings['expires'] = strtotime($this->settings['expires']); } @@ -119,7 +113,6 @@ class SessionCookie extends \Slim\Middleware /** * Load session - * @param array $env */ protected function loadSession() { @@ -127,14 +120,14 @@ class SessionCookie extends \Slim\Middleware session_start(); } - $value = \Slim\Http\Util::decodeSecureCookie( - $this->app->request()->cookies($this->settings['name']), - $this->settings['secret'], - $this->settings['cipher'], - $this->settings['cipher_mode'] - ); + $value = $this->app->getCookie($this->settings['name']); + if ($value) { - $_SESSION = unserialize($value); + try { + $_SESSION = unserialize($value); + } catch (\Exception $e) { + $this->app->getLog()->error('Error unserializing session cookie value! ' . $e->getMessage()); + } } else { $_SESSION = array(); } @@ -145,57 +138,71 @@ class SessionCookie extends \Slim\Middleware */ protected function saveSession() { - $value = \Slim\Http\Util::encodeSecureCookie( - serialize($_SESSION), - $this->settings['expires'], - $this->settings['secret'], - $this->settings['cipher'], - $this->settings['cipher_mode'] - ); + $value = serialize($_SESSION); + if (strlen($value) > 4096) { $this->app->getLog()->error('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.'); } else { - $this->app->response()->setCookie($this->settings['name'], array( - 'value' => $value, - 'domain' => $this->settings['domain'], - 'path' => $this->settings['path'], - 'expires' => $this->settings['expires'], - 'secure' => $this->settings['secure'], - 'httponly' => $this->settings['httponly'] - )); + $this->app->setCookie( + $this->settings['name'], + $value, + $this->settings['expires'], + $this->settings['path'], + $this->settings['domain'], + $this->settings['secure'], + $this->settings['httponly'] + ); } - session_destroy(); + // session_destroy(); } /******************************************************************************** * Session Handler *******************************************************************************/ + /** + * @codeCoverageIgnore + */ public function open($savePath, $sessionName) { return true; } + /** + * @codeCoverageIgnore + */ public function close() { return true; } + /** + * @codeCoverageIgnore + */ public function read($id) { return ''; } + /** + * @codeCoverageIgnore + */ public function write($id, $data) { return true; } + /** + * @codeCoverageIgnore + */ public function destroy($id) { return true; } + /** + * @codeCoverageIgnore + */ public function gc($maxlifetime) { return true; diff --git a/vendor/slim/slim/Slim/Route.php b/vendor/slim/slim/Slim/Route.php index 445fbe9d59..2d963c73dd 100644 --- a/vendor/slim/slim/Slim/Route.php +++ b/vendor/slim/slim/Slim/Route.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.0.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -92,8 +92,8 @@ class Route /** * Constructor - * @param string $pattern The URL pattern (e.g. "/books/:id") - * @param mixed $callable Anything that returns TRUE for is_callable() + * @param string $pattern The URL pattern (e.g. "/books/:id") + * @param mixed $callable Anything that returns TRUE for is_callable() */ public function __construct($pattern, $callable) { @@ -154,6 +154,11 @@ class Route */ public function setCallable($callable) { + $matches = array(); + if (is_string($callable) && preg_match('!^([^\:]+)\:([[:alnum:]]+)$!', $callable, $matches)) { + $callable = array(new $matches[1], $matches[2]); + } + if (!is_callable($callable)) { throw new \InvalidArgumentException('Route callable must be callable'); } @@ -194,7 +199,7 @@ class Route */ public function setName($name) { - $this->name = (string) $name; + $this->name = (string)$name; } /** @@ -217,7 +222,7 @@ class Route /** * Get route parameter value - * @param string $index Name of URL parameter + * @param string $index Name of URL parameter * @return string * @throws \InvalidArgumentException If route parameter does not exist at index */ @@ -232,8 +237,8 @@ class Route /** * Set route parameter value - * @param string $index Name of URL parameter - * @param mixed $value The new parameter value + * @param string $index Name of URL parameter + * @param mixed $value The new parameter value * @throws \InvalidArgumentException If route parameter does not exist at index */ public function setParam($index, $value) @@ -285,6 +290,7 @@ class Route /** * Detect support for an HTTP method + * @param string $method * @return bool */ public function supportsHttpMethod($method) @@ -320,7 +326,7 @@ class Route if (is_callable($middleware)) { $this->middleware[] = $middleware; } elseif (is_array($middleware)) { - foreach($middleware as $callable) { + foreach ($middleware as $callable) { if (!is_callable($callable)) { throw new \InvalidArgumentException('All Route middleware must be callable'); } @@ -347,8 +353,11 @@ class Route public function matches($resourceUri) { //Convert URL params into regex patterns, construct a regex for this route, init params - $patternAsRegex = preg_replace_callback('#:([\w]+)\+?#', array($this, 'matchesCallback'), - str_replace(')', ')?', (string) $this->pattern)); + $patternAsRegex = preg_replace_callback( + '#:([\w]+)\+?#', + array($this, 'matchesCallback'), + str_replace(')', ')?', (string)$this->pattern) + ); if (substr($this->pattern, -1) === '/') { $patternAsRegex .= '?'; } @@ -359,7 +368,7 @@ class Route } foreach ($this->paramNames as $name) { if (isset($paramValues[$name])) { - if (isset($this->paramNamesPath[ $name ])) { + if (isset($this->paramNamesPath[$name])) { $this->params[$name] = explode('/', urldecode($paramValues[$name])); } else { $this->params[$name] = urldecode($paramValues[$name]); @@ -372,17 +381,17 @@ class Route /** * Convert a URL parameter (e.g. ":id", ":id+") into a regular expression - * @param array URL parameters - * @return string Regular expression for URL parameter + * @param array $m URL parameters + * @return string Regular expression for URL parameter */ protected function matchesCallback($m) { $this->paramNames[] = $m[1]; - if (isset($this->conditions[ $m[1] ])) { - return '(?P<' . $m[1] . '>' . $this->conditions[ $m[1] ] . ')'; + if (isset($this->conditions[$m[1]])) { + return '(?P<' . $m[1] . '>' . $this->conditions[$m[1]] . ')'; } if (substr($m[0], -1) === '+') { - $this->paramNamesPath[ $m[1] ] = 1; + $this->paramNamesPath[$m[1]] = 1; return '(?P<' . $m[1] . '>.+)'; } @@ -392,7 +401,7 @@ class Route /** * Set route name - * @param string $name The name of the route + * @param string $name The name of the route * @return \Slim\Route */ public function name($name) @@ -404,7 +413,7 @@ class Route /** * Merge route conditions - * @param array $conditions Key-value array of URL parameter conditions + * @param array $conditions Key-value array of URL parameter conditions * @return \Slim\Route */ public function conditions(array $conditions) @@ -413,4 +422,23 @@ class Route return $this; } + + /** + * Dispatch route + * + * This method invokes the route object's callable. If middleware is + * registered for the route, each callable middleware is invoked in + * the order specified. + * + * @return bool + */ + public function dispatch() + { + foreach ($this->middleware as $mw) { + call_user_func_array($mw, array($this)); + } + + $return = call_user_func_array($this->getCallable(), array_values($this->getParams())); + return ($return === false) ? false : true; + } } diff --git a/vendor/slim/slim/Slim/Router.php b/vendor/slim/slim/Slim/Router.php index 44979ea0a9..0ff47b906c 100644 --- a/vendor/slim/slim/Slim/Router.php +++ b/vendor/slim/slim/Slim/Router.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -63,12 +63,18 @@ class Router */ protected $matchedRoutes; + /** + * @var array Array containing all route groups + */ + protected $routeGroups; + /** * Constructor */ public function __construct() { $this->routes = array(); + $this->routeGroups = array(); } /** @@ -100,7 +106,7 @@ class Router if ($reload || is_null($this->matchedRoutes)) { $this->matchedRoutes = array(); foreach ($this->routes as $route) { - if (!$route->supportsHttpMethod($httpMethod)) { + if (!$route->supportsHttpMethod($httpMethod) && !$route->supportsHttpMethod("ANY")) { continue; } @@ -114,25 +120,66 @@ class Router } /** - * Map a route object to a callback function - * @param string $pattern The URL pattern (ie. "/books/:id") - * @param mixed $callable Anything that returns TRUE for is_callable() - * @return \Slim\Route + * Add a route object to the router + * @param \Slim\Route $route The Slim Route */ - public function map($pattern, $callable) + public function map(\Slim\Route $route) { - $route = new \Slim\Route($pattern, $callable); + list($groupPattern, $groupMiddleware) = $this->processGroups(); + + $route->setPattern($groupPattern . $route->getPattern()); $this->routes[] = $route; - return $route; + + foreach ($groupMiddleware as $middleware) { + $route->setMiddleware($middleware); + } + } + + /** + * A helper function for processing the group's pattern and middleware + * @return array Returns an array with the elements: pattern, middlewareArr + */ + protected function processGroups() + { + $pattern = ""; + $middleware = array(); + foreach ($this->routeGroups as $group) { + $k = key($group); + $pattern .= $k; + if (is_array($group[$k])) { + $middleware = array_merge($middleware, $group[$k]); + } + } + return array($pattern, $middleware); + } + + /** + * Add a route group to the array + * @param string $group The group pattern (ie. "/books/:id") + * @param array|null $middleware Optional parameter array of middleware + * @return int The index of the new group + */ + public function pushGroup($group, $middleware = array()) + { + return array_push($this->routeGroups, array($group => $middleware)); + } + + /** + * Removes the last route group from the array + * @return bool True if successful, else False + */ + public function popGroup() + { + return (array_pop($this->routeGroups) !== null); } /** * Get URL for named route * @param string $name The name of the route - * @param array Associative array of URL parameter names and replacement values - * @throws RuntimeException If named route not found - * @return string The URL for the given route populated with provided replacement values + * @param array $params Associative array of URL parameter names and replacement values + * @throws \RuntimeException If named route not found + * @return string The URL for the given route populated with provided replacement values */ public function urlFor($name, $params = array()) { @@ -140,45 +187,20 @@ class Router throw new \RuntimeException('Named route not found for name: ' . $name); } $search = array(); - foreach (array_keys($params) as $key) { - $search[] = '#:' . $key . '\+?(?!\w)#'; + foreach ($params as $key => $value) { + $search[] = '#:' . preg_quote($key, '#') . '\+?(?!\w)#'; } $pattern = preg_replace($search, $params, $this->getNamedRoute($name)->getPattern()); - //Remove remnants of unpopulated, trailing optional pattern segments - return preg_replace('#\(/?:.+\)|\(|\)#', '', $pattern); - } - - /** - * Dispatch route - * - * This method invokes the route object's callable. If middleware is - * registered for the route, each callable middleware is invoked in - * the order specified. - * - * @param \Slim\Route $route The route object - * @return bool Was route callable invoked successfully? - */ - public function dispatch(\Slim\Route $route) - { - $this->currentRoute = $route; - - //Invoke middleware - foreach ($route->getMiddleware() as $mw) { - call_user_func_array($mw, array($route)); - } - - //Invoke callable - call_user_func_array($route->getCallable(), array_values($route->getParams())); - - return true; + //Remove remnants of unpopulated, trailing optional pattern segments, escaped special characters + return preg_replace('#\(/?:.+\)|\(|\)|\\\\#', '', $pattern); } /** * Add named route * @param string $name The route name * @param \Slim\Route $route The route object - * @throws \RuntimeException If a named route already exists with the same name + * @throws \RuntimeException If a named route already exists with the same name */ public function addNamedRoute($name, \Slim\Route $route) { diff --git a/vendor/slim/slim/Slim/Slim.php b/vendor/slim/slim/Slim/Slim.php index 4cd2ff8bb4..6369b028af 100644 --- a/vendor/slim/slim/Slim/Slim.php +++ b/vendor/slim/slim/Slim/Slim.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -40,16 +40,26 @@ if (!extension_loaded('mcrypt')) { /** * Slim - * @package Slim - * @author Josh Lockhart - * @since 1.0.0 + * @package Slim + * @author Josh Lockhart + * @since 1.0.0 + * + * @property \Slim\Environment $environment + * @property \Slim\Http\Response $response + * @property \Slim\Http\Request $request + * @property \Slim\Router $router */ class Slim { /** * @const string */ - const VERSION = '2.2.0'; + const VERSION = '2.4.0'; + + /** + * @var \Slim\Helper\Set + */ + public $container; /** * @var array[\Slim] @@ -61,41 +71,6 @@ class Slim */ protected $name; - /** - * @var array - */ - protected $environment; - - /** - * @var \Slim\Http\Request - */ - protected $request; - - /** - * @var \Slim\Http\Response - */ - protected $response; - - /** - * @var \Slim\Router - */ - protected $router; - - /** - * @var \Slim\View - */ - protected $view; - - /** - * @var array - */ - protected $settings; - - /** - * @var string - */ - protected $mode; - /** * @var array */ @@ -173,44 +148,111 @@ class Slim * Constructor * @param array $userSettings Associative array of application settings */ - public function __construct($userSettings = array()) + public function __construct(array $userSettings = array()) { - // Setup Slim application - $this->settings = array_merge(static::getDefaultSettings(), $userSettings); - $this->environment = \Slim\Environment::getInstance(); - $this->request = new \Slim\Http\Request($this->environment); - $this->response = new \Slim\Http\Response(); - $this->router = new \Slim\Router(); + // Setup IoC container + $this->container = new \Slim\Helper\Set(); + $this->container['settings'] = array_merge(static::getDefaultSettings(), $userSettings); + + // Default environment + $this->container->singleton('environment', function ($c) { + return \Slim\Environment::getInstance(); + }); + + // Default request + $this->container->singleton('request', function ($c) { + return new \Slim\Http\Request($c['environment']); + }); + + // Default response + $this->container->singleton('response', function ($c) { + return new \Slim\Http\Response(); + }); + + // Default router + $this->container->singleton('router', function ($c) { + return new \Slim\Router(); + }); + + // Default view + $this->container->singleton('view', function ($c) { + $viewClass = $c['settings']['view']; + $templatesPath = $c['settings']['templates.path']; + + $view = ($viewClass instanceOf \Slim\View) ? $viewClass : new $viewClass; + $view->setTemplatesDirectory($templatesPath); + return $view; + }); + + // Default log writer + $this->container->singleton('logWriter', function ($c) { + $logWriter = $c['settings']['log.writer']; + + return is_object($logWriter) ? $logWriter : new \Slim\LogWriter($c['environment']['slim.errors']); + }); + + // Default log + $this->container->singleton('log', function ($c) { + $log = new \Slim\Log($c['logWriter']); + $log->setEnabled($c['settings']['log.enabled']); + $log->setLevel($c['settings']['log.level']); + $env = $c['environment']; + $env['slim.log'] = $log; + + return $log; + }); + + // Default mode + $this->container['mode'] = function ($c) { + $mode = $c['settings']['mode']; + + if (isset($_ENV['SLIM_MODE'])) { + $mode = $_ENV['SLIM_MODE']; + } else { + $envMode = getenv('SLIM_MODE'); + if ($envMode !== false) { + $mode = $envMode; + } + } + + return $mode; + }; + + // Define default middleware stack $this->middleware = array($this); $this->add(new \Slim\Middleware\Flash()); $this->add(new \Slim\Middleware\MethodOverride()); - // Determine application mode - $this->getMode(); - - // Setup view - $this->view($this->config('view')); - // Make default if first instance if (is_null(static::getInstance())) { $this->setName('default'); } + } - // Set default logger that writes to stderr (may be overridden with middleware) - $logWriter = $this->config('log.writer'); - if (!$logWriter) { - $logWriter = new \Slim\LogWriter($this->environment['slim.errors']); - } - $log = new \Slim\Log($logWriter); - $log->setEnabled($this->config('log.enabled')); - $log->setLevel($this->config('log.level')); - $this->environment['slim.log'] = $log; + public function __get($name) + { + return $this->container[$name]; + } + + public function __set($name, $value) + { + $this->container[$name] = $value; + } + + public function __isset($name) + { + return isset($this->container[$name]); + } + + public function __unset($name) + { + unset($this->container[$name]); } /** * Get application instance by name * @param string $name The name of the Slim application - * @return \Slim|null + * @return \Slim\Slim|null */ public static function getInstance($name = 'default') { @@ -255,6 +297,7 @@ class Slim 'templates.path' => './templates', 'view' => '\Slim\View', // Cookies + 'cookies.encrypt' => false, 'cookies.lifetime' => '20 minutes', 'cookies.path' => '/', 'cookies.domain' => null, @@ -297,7 +340,9 @@ class Slim return isset($this->settings[$name]) ? $this->settings[$name] : null; } } else { - $this->settings[$name] = $value; + $settings = $this->settings; + $settings[$name] = $value; + $this->settings = $settings; } } @@ -316,19 +361,6 @@ class Slim */ public function getMode() { - if (!isset($this->mode)) { - if (isset($_ENV['SLIM_MODE'])) { - $this->mode = $_ENV['SLIM_MODE']; - } else { - $envMode = getenv('SLIM_MODE'); - if ($envMode !== false) { - $this->mode = $envMode; - } else { - $this->mode = $this->config('mode'); - } - } - } - return $this->mode; } @@ -361,7 +393,7 @@ class Slim */ public function getLog() { - return $this->environment['slim.log']; + return $this->log; } /******************************************************************************** @@ -369,7 +401,7 @@ class Slim *******************************************************************************/ /** - * Add GET|POST|PUT|DELETE route + * Add GET|POST|PUT|PATCH|DELETE route * * Adds a new route to the router with associated callable. This * route will only be invoked when the HTTP request's method matches @@ -402,7 +434,8 @@ class Slim { $pattern = array_shift($args); $callable = array_pop($args); - $route = $this->router->map($pattern, $callable); + $route = new \Slim\Route($pattern, $callable); + $this->router->map($route); if (count($args) > 0) { $route->setMiddleware($args); } @@ -458,6 +491,18 @@ class Slim return $this->mapRoute($args)->via(\Slim\Http\Request::METHOD_PUT); } + /** + * Add PATCH route + * @see mapRoute() + * @return \Slim\Route + */ + public function patch() + { + $args = func_get_args(); + + return $this->mapRoute($args)->via(\Slim\Http\Request::METHOD_PATCH); + } + /** * Add DELETE route * @see mapRoute() @@ -482,6 +527,40 @@ class Slim return $this->mapRoute($args)->via(\Slim\Http\Request::METHOD_OPTIONS); } + /** + * Route Groups + * + * This method accepts a route pattern and a callback all Route + * declarations in the callback will be prepended by the group(s) + * that it is in + * + * Accepts the same parameters as a standard route so: + * (pattern, middleware1, middleware2, ..., $callback) + */ + public function group() + { + $args = func_get_args(); + $pattern = array_shift($args); + $callable = array_pop($args); + $this->router->pushGroup($pattern, $args); + if (is_callable($callable)) { + call_user_func($callable); + } + $this->router->popGroup(); + } + + /* + * Add route for any HTTP method + * @see mapRoute() + * @return \Slim\Route + */ + public function any() + { + $args = func_get_args(); + + return $this->mapRoute($args)->via("ANY"); + } + /** * Not Found Handler * @@ -503,12 +582,13 @@ class Slim * * @param mixed $callable Anything that returns true for is_callable() */ - public function notFound( $callable = null ) { - if ( is_callable($callable) ) { + public function notFound ($callable = null) + { + if (is_callable($callable)) { $this->notFound = $callable; } else { ob_start(); - if ( is_callable($this->notFound) ) { + if (is_callable($this->notFound)) { call_user_func($this->notFound); } else { call_user_func(array($this, 'defaultNotFound')); @@ -566,7 +646,7 @@ class Slim protected function callErrorHandler($argument = null) { ob_start(); - if ( is_callable($this->error) ) { + if (is_callable($this->error)) { call_user_func_array($this->error, array($argument)); } else { call_user_func_array(array($this, 'defaultError'), array($argument)); @@ -653,7 +733,7 @@ class Slim /** * Render a template * - * Call this method within a GET, POST, PUT, DELETE, NOT FOUND, or ERROR + * Call this method within a GET, POST, PUT, PATCH, DELETE, NOT FOUND, or ERROR * callable to render a template whose output is appended to the * current HTTP response body. How the template is rendered is * delegated to the current View. @@ -667,7 +747,6 @@ class Slim if (!is_null($status)) { $this->response->status($status); } - $this->view->setTemplatesDirectory($this->config('templates.path')); $this->view->appendData($data); $this->view->display($template); } @@ -692,8 +771,8 @@ class Slim public function lastModified($time) { if (is_integer($time)) { - $this->response['Last-Modified'] = date(DATE_RFC1123, $time); - if ($time === strtotime($this->request->headers('IF_MODIFIED_SINCE'))) { + $this->response->headers->set('Last-Modified', gmdate('D, d M Y H:i:s T', $time)); + if ($time === strtotime($this->request->headers->get('IF_MODIFIED_SINCE'))) { $this->halt(304); } } else { @@ -726,11 +805,13 @@ class Slim //Set etag value $value = '"' . $value . '"'; - if ($type === 'weak') $value = 'W/'.$value; + if ($type === 'weak') { + $value = 'W/'.$value; + } $this->response['ETag'] = $value; //Check conditional GET - if ($etagsHeader = $this->request->headers('IF_NONE_MATCH')) { + if ($etagsHeader = $this->request->headers->get('IF_NONE_MATCH')) { $etags = preg_split('@\s*,\s*@', $etagsHeader); if (in_array($value, $etags) || in_array('*', $etags)) { $this->halt(304); @@ -756,7 +837,7 @@ class Slim if (is_string($time)) { $time = strtotime($time); } - $this->response['Expires'] = gmdate(DATE_RFC1123, $time); + $this->response->headers->set('Expires', gmdate('D, d M Y H:i:s T', $time)); } /******************************************************************************** @@ -764,7 +845,7 @@ class Slim *******************************************************************************/ /** - * Set unencrypted HTTP cookie + * Set HTTP cookie to be sent with the HTTP response * * @param string $name The cookie name * @param string $value The cookie value @@ -779,32 +860,52 @@ class Slim */ public function setCookie($name, $value, $time = null, $path = null, $domain = null, $secure = null, $httponly = null) { - $this->response->setCookie($name, array( + $settings = array( 'value' => $value, 'expires' => is_null($time) ? $this->config('cookies.lifetime') : $time, 'path' => is_null($path) ? $this->config('cookies.path') : $path, 'domain' => is_null($domain) ? $this->config('cookies.domain') : $domain, 'secure' => is_null($secure) ? $this->config('cookies.secure') : $secure, 'httponly' => is_null($httponly) ? $this->config('cookies.httponly') : $httponly - )); + ); + $this->response->cookies->set($name, $settings); } /** - * Get value of unencrypted HTTP cookie + * Get value of HTTP cookie from the current HTTP request * * Return the value of a cookie from the current HTTP request, * or return NULL if cookie does not exist. Cookies created during * the current request will not be available until the next request. * * @param string $name + * @param bool $deleteIfInvalid * @return string|null */ - public function getCookie($name) + public function getCookie($name, $deleteIfInvalid = true) { - return $this->request->cookies($name); + // Get cookie value + $value = $this->request->cookies->get($name); + + // Decode if encrypted + if ($this->config('cookies.encrypt')) { + $value = \Slim\Http\Util::decodeSecureCookie( + $value, + $this->config('cookies.secret_key'), + $this->config('cookies.cipher'), + $this->config('cookies.cipher_mode') + ); + if ($value === false && $deleteIfInvalid) { + $this->deleteCookie($name); + } + } + + return $value; } /** + * DEPRECATION WARNING! Use `setCookie` with the `cookies.encrypt` app setting set to `true`. + * * Set encrypted HTTP cookie * * @param string $name The cookie name @@ -818,23 +919,14 @@ class Slim * HTTPS connection from the client * @param bool $httponly When TRUE the cookie will be made accessible only through the HTTP protocol */ - public function setEncryptedCookie($name, $value, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null) + public function setEncryptedCookie($name, $value, $expires = null, $path = null, $domain = null, $secure = false, $httponly = false) { - $expires = is_null($expires) ? $this->config('cookies.lifetime') : $expires; - if (is_string($expires)) { - $expires = strtotime($expires); - } - $secureValue = \Slim\Http\Util::encodeSecureCookie( - $value, - $expires, - $this->config('cookies.secret_key'), - $this->config('cookies.cipher'), - $this->config('cookies.cipher_mode') - ); - $this->setCookie($name, $secureValue, $expires, $path, $domain, $secure, $httponly); + $this->setCookie($name, $value, $expires, $path, $domain, $secure, $httponly); } /** + * DEPRECATION WARNING! Use `getCookie` with the `cookies.encrypt` app setting set to `true`. + * * Get value of encrypted HTTP cookie * * Return the value of an encrypted cookie from the current HTTP request, @@ -842,21 +934,12 @@ class Slim * the current request will not be available until the next request. * * @param string $name - * @return string|false + * @param bool $deleteIfInvalid + * @return string|bool */ public function getEncryptedCookie($name, $deleteIfInvalid = true) { - $value = \Slim\Http\Util::decodeSecureCookie( - $this->request->cookies($name), - $this->config('cookies.secret_key'), - $this->config('cookies.cipher'), - $this->config('cookies.cipher_mode') - ); - if ($value === false && $deleteIfInvalid) { - $this->deleteCookie($name); - } - - return $value; + return $this->getCookie($name, $deleteIfInvalid); } /** @@ -877,12 +960,13 @@ class Slim */ public function deleteCookie($name, $path = null, $domain = null, $secure = null, $httponly = null) { - $this->response->deleteCookie($name, array( + $settings = array( 'domain' => is_null($domain) ? $this->config('cookies.domain') : $domain, 'path' => is_null($path) ? $this->config('cookies.path') : $path, 'secure' => is_null($secure) ? $this->config('cookies.secure') : $secure, 'httponly' => is_null($httponly) ? $this->config('cookies.httponly') : $httponly - )); + ); + $this->response->cookies->remove($name, $settings); } /******************************************************************************** @@ -968,16 +1052,16 @@ class Slim */ public function contentType($type) { - $this->response['Content-Type'] = $type; + $this->response->headers->set('Content-Type', $type); } /** * Set the HTTP response status code - * @param int $status The HTTP response status code + * @param int $code The HTTP response status code */ public function status($code) { - $this->response->status($code); + $this->response->setStatus($code); } /** @@ -1071,7 +1155,7 @@ class Slim /** * Invoke hook * @param string $name The hook name - * @param mixed $hookArgs (Optional) Argument for hooked functions + * @param mixed $hookArg (Optional) Argument for hooked functions */ public function applyHook($name, $hookArg = null) { @@ -1165,16 +1249,22 @@ class Slim */ public function run() { - //set_error_handler(array('\Slim\Slim', 'handleErrors')); //Espo: no needs to use this handler + //set_error_handler(array('\Slim\Slim', 'handleErrors')); //Espo: no needs to use this handler //Apply final outer middleware layers - //$this->add(new \Slim\Middleware\PrettyExceptions()); //Espo: no needs to use this handler + if ($this->config('debug')) { + //Apply pretty exceptions only in debug to avoid accidental information leakage in production + //$this->add(new \Slim\Middleware\PrettyExceptions()); //Espo: no needs to use this handler + } //Invoke middleware and application stack $this->middleware[0]->call(); //Fetch status, header, and body - list($status, $header, $body) = $this->response->finalize(); + list($status, $headers, $body) = $this->response->finalize(); + + // Serialize cookies (with optional encryption) + \Slim\Http\Util::serializeCookies($headers, $this->response->cookies, $this->settings); //Send headers if (headers_sent() === false) { @@ -1186,7 +1276,7 @@ class Slim } //Send headers - foreach ($header as $name => $value) { + foreach ($headers as $name => $value) { $hValues = explode("\n", $value); foreach ($hValues as $hVal) { header("$name: $hVal", false); @@ -1194,8 +1284,10 @@ class Slim } } - //Send body - echo $body; + //Send body, but only if it isn't a HEAD request + if (!$this->request->isHead()) { + echo $body; + } restore_error_handler(); } @@ -1219,7 +1311,7 @@ class Slim foreach ($matchedRoutes as $route) { try { $this->applyHook('slim.before.dispatch'); - $dispatched = $this->router->dispatch($route); + $dispatched = $route->dispatch(); $this->applyHook('slim.after.dispatch'); if ($dispatched) { break; @@ -1229,7 +1321,7 @@ class Slim } } if (!$dispatched) { - $this->notFound(); + $this->notFound(); } $this->applyHook('slim.after.router'); $this->stop(); @@ -1264,16 +1356,16 @@ class Slim * @param string $errstr The error message * @param string $errfile The absolute path to the affected file * @param int $errline The line number of the error in the affected file - * @return true + * @return bool * @throws \ErrorException */ public static function handleErrors($errno, $errstr = '', $errfile = '', $errline = '') { - if (error_reporting() & $errno) { - throw new \ErrorException($errstr, $errno, 0, $errfile, $errline); + if (!($errno & error_reporting())) { + return; } - return true; + throw new \ErrorException($errstr, $errno, 0, $errfile, $errline); } /** @@ -1304,6 +1396,6 @@ class Slim protected function defaultError($e) { $this->getLog()->error($e); - echo self::generateTemplateMarkup('Error', '

A website error has occured. The website administrator has been notified of the issue. Sorry for the temporary inconvenience.

'); + echo self::generateTemplateMarkup('Error', '

A website error has occurred. The website administrator has been notified of the issue. Sorry for the temporary inconvenience.

'); } } diff --git a/vendor/slim/slim/Slim/View.php b/vendor/slim/slim/Slim/View.php index 0ce9568999..eff83aaef5 100644 --- a/vendor/slim/slim/Slim/View.php +++ b/vendor/slim/slim/Slim/View.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * @package Slim * * MIT LICENSE @@ -50,95 +50,166 @@ namespace Slim; class View { /** - * @var string Absolute or relative filesystem path to a specific template - * - * DEPRECATION WARNING! - * This variable will be removed in the near future + * Data available to the view templates + * @var \Slim\Helper\Set */ - protected $templatePath = ''; + protected $data; /** - * @var array Associative array of template variables - */ - protected $data = array(); - - /** - * @var string Absolute or relative path to the application's templates directory + * Path to templates base directory (without trailing slash) + * @var string */ protected $templatesDirectory; /** * Constructor - * - * This is empty but may be implemented in a subclass */ public function __construct() { + $this->data = new \Slim\Helper\Set(); + } + /******************************************************************************** + * Data methods + *******************************************************************************/ + + /** + * Does view data have value with key? + * @param string $key + * @return boolean + */ + public function has($key) + { + return $this->data->has($key); } /** - * Get data - * @param string|null $key - * @return mixed If key is null, array of template data; - * If key exists, value of datum with key; - * If key does not exist, null; + * Return view data value with key + * @param string $key + * @return mixed + */ + public function get($key) + { + return $this->data->get($key); + } + + /** + * Set view data value with key + * @param string $key + * @param mixed $value + */ + public function set($key, $value) + { + $this->data->set($key, $value); + } + + /** + * Set view data value as Closure with key + * @param string $key + * @param mixed $value + */ + public function keep($key, Closure $value) + { + $this->data->keep($key, $value); + } + + /** + * Return view data + * @return array + */ + public function all() + { + return $this->data->all(); + } + + /** + * Replace view data + * @param array $data + */ + public function replace(array $data) + { + $this->data->replace($data); + } + + /** + * Clear view data + */ + public function clear() + { + $this->data->clear(); + } + + /******************************************************************************** + * Legacy data methods + *******************************************************************************/ + + /** + * DEPRECATION WARNING! This method will be removed in the next major point release + * + * Get data from view */ public function getData($key = null) { if (!is_null($key)) { return isset($this->data[$key]) ? $this->data[$key] : null; } else { - return $this->data; + return $this->data->all(); } } /** - * Set data + * DEPRECATION WARNING! This method will be removed in the next major point release * - * If two arguments: - * A single datum with key is assigned value; - * - * $view->setData('color', 'red'); - * - * If one argument: - * Replace all data with provided array keys and values; - * - * $view->setData(array('color' => 'red', 'number' => 1)); - * - * @param mixed - * @param mixed - * @throws InvalidArgumentException If incorrect method signature + * Set data for view */ public function setData() { $args = func_get_args(); if (count($args) === 1 && is_array($args[0])) { - $this->data = $args[0]; + $this->data->replace($args[0]); } elseif (count($args) === 2) { - $this->data[(string) $args[0]] = $args[1]; + // Ensure original behavior is maintained. DO NOT invoke stored Closures. + if (is_object($args[1]) && method_exists($args[1], '__invoke')) { + $this->data->set($args[0], $this->data->protect($args[1])); + } else { + $this->data->set($args[0], $args[1]); + } } else { throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`'); } } /** - * Append new data to existing template data - * @param array - * @throws InvalidArgumentException If not given an array argument + * DEPRECATION WARNING! This method will be removed in the next major point release + * + * Append data to view + * @param array $data */ public function appendData($data) { if (!is_array($data)) { throw new \InvalidArgumentException('Cannot append view data. Expected array argument.'); } - $this->data = array_merge($this->data, $data); + $this->data->replace($data); + } + + /******************************************************************************** + * Resolve template paths + *******************************************************************************/ + + /** + * Set the base directory that contains view templates + * @param string $directory + * @throws \InvalidArgumentException If directory is not a directory + */ + public function setTemplatesDirectory($directory) + { + $this->templatesDirectory = rtrim($directory, DIRECTORY_SEPARATOR); } /** - * Get templates directory - * @return string|null Path to templates directory without trailing slash; - * Returns null if templates directory not set; + * Get templates base directory + * @return string */ public function getTemplatesDirectory() { @@ -146,70 +217,65 @@ class View } /** - * Set templates directory - * @param string $dir + * Get fully qualified path to template file using templates base directory + * @param string $file The template file pathname relative to templates base directory + * @return string */ - public function setTemplatesDirectory($dir) + public function getTemplatePathname($file) { - $this->templatesDirectory = rtrim($dir, '/'); + return $this->templatesDirectory . DIRECTORY_SEPARATOR . ltrim($file, DIRECTORY_SEPARATOR); } - /** - * Set template - * @param string $template - * @throws RuntimeException If template file does not exist - * - * DEPRECATION WARNING! - * This method will be removed in the near future. - */ - public function setTemplate($template) - { - $this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/'); - if (!file_exists($this->templatePath)) { - throw new \RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.'); - } - } + /******************************************************************************** + * Rendering + *******************************************************************************/ /** * Display template * * This method echoes the rendered template to the current output buffer * - * @param string $template Pathname of template file relative to templates directoy - */ - public function display($template) - { - echo $this->fetch($template); - } - - /** - * Fetch rendered template - * - * This method returns the rendered template - * - * @param string $template Pathname of template file relative to templates directory - * @return string - */ - public function fetch($template) - { - return $this->render($template); - } - - /** - * Render template - * * @param string $template Pathname of template file relative to templates directory - * @return string - * - * DEPRECATION WARNING! - * Use `\Slim\View::fetch` to return a rendered template instead of `\Slim\View::render`. + * @param array $data Any additonal data to be passed to the template. */ - public function render($template) + public function display($template, $data = null) { - $this->setTemplate($template); - extract($this->data); + echo $this->fetch($template, $data); + } + + /** + * Return the contents of a rendered template file + * + * @param string $template The template pathname, relative to the template base directory + * @param array $data Any additonal data to be passed to the template. + * @return string The rendered template + */ + public function fetch($template, $data = null) + { + return $this->render($template, $data); + } + + /** + * Render a template file + * + * NOTE: This method should be overridden by custom view subclasses + * + * @param string $template The template pathname, relative to the template base directory + * @param array $data Any additonal data to be passed to the template. + * @return string The rendered template + * @throws \RuntimeException If resolved template pathname is not a valid file + */ + protected function render($template, $data = null) + { + $templatePathname = $this->getTemplatePathname($template); + if (!is_file($templatePathname)) { + throw new \RuntimeException("View cannot render `$template` because the template does not exist"); + } + + $data = array_merge($this->data->all(), (array) $data); + extract($data); ob_start(); - require $this->templatePath; + require $templatePathname; return ob_get_clean(); } diff --git a/vendor/slim/slim/composer.json b/vendor/slim/slim/composer.json index a49c05ec20..0becfe687b 100644 --- a/vendor/slim/slim/composer.json +++ b/vendor/slim/slim/composer.json @@ -15,6 +15,9 @@ "require": { "php": ">=5.3.0" }, + "suggest": { + "ext-mcrypt": "Required for HTTP cookie encryption" + }, "autoload": { "psr-0": { "Slim": "." } } diff --git a/vendor/slim/slim/index.php b/vendor/slim/slim/index.php index c3e67454cd..9bfd62d988 100644 --- a/vendor/slim/slim/index.php +++ b/vendor/slim/slim/index.php @@ -26,13 +26,15 @@ $app = new \Slim\Slim(); * * Here we define several Slim application routes that respond * to appropriate HTTP request methods. In this example, the second - * argument for `Slim::get`, `Slim::post`, `Slim::put`, and `Slim::delete` + * argument for `Slim::get`, `Slim::post`, `Slim::put`, `Slim::patch`, and `Slim::delete` * is an anonymous function. */ // GET route -$app->get('/', function () { - $template = <<get( + '/', + function () { + $template = << @@ -125,23 +127,38 @@ $app->get('/', function () { EOT; - echo $template; -}); + echo $template; + } +); // POST route -$app->post('/post', function () { - echo 'This is a POST route'; -}); +$app->post( + '/post', + function () { + echo 'This is a POST route'; + } +); // PUT route -$app->put('/put', function () { - echo 'This is a PUT route'; +$app->put( + '/put', + function () { + echo 'This is a PUT route'; + } +); + +// PATCH route +$app->patch('/patch', function () { + echo 'This is a PATCH route'; }); // DELETE route -$app->delete('/delete', function () { - echo 'This is a DELETE route'; -}); +$app->delete( + '/delete', + function () { + echo 'This is a DELETE route'; + } +); /** * Step 4: Run the Slim application diff --git a/vendor/slim/slim/tests/EnvironmentTest.php b/vendor/slim/slim/tests/EnvironmentTest.php index 91505b8ce7..cb2b500ae7 100644 --- a/vendor/slim/slim/tests/EnvironmentTest.php +++ b/vendor/slim/slim/tests/EnvironmentTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -43,6 +43,8 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function setUp() { + $_SERVER['DOCUMENT_ROOT'] = '/var/www'; + $_SERVER['SCRIPT_FILENAME'] = '/var/www/foo/index.php'; $_SERVER['SERVER_NAME'] = 'slim'; $_SERVER['SERVER_PORT'] = '80'; $_SERVER['SCRIPT_NAME'] = '/foo/index.php'; @@ -106,6 +108,7 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function testParsesPathsWithoutUrlRewriteInRootDirectory() { + $_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php'; $_SERVER['REQUEST_URI'] = '/index.php/bar/xyz'; $_SERVER['SCRIPT_NAME'] = '/index.php'; $env = \Slim\Environment::getInstance(true); @@ -123,6 +126,7 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function testParsesPathsWithoutUrlRewriteInRootDirectoryForAppRootUri() { + $_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php'; $_SERVER['REQUEST_URI'] = '/index.php'; $_SERVER['SCRIPT_NAME'] = '/index.php'; unset($_SERVER['PATH_INFO']); @@ -157,6 +161,7 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function testParsesPathsWithUrlRewriteInRootDirectory() { + $_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php'; $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['REQUEST_URI'] = '/bar/xyz'; unset($_SERVER['PATH_INFO']); @@ -175,6 +180,7 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function testParsesPathsWithUrlRewriteInRootDirectoryForAppRootUri() { + $_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php'; $_SERVER['REQUEST_URI'] = '/'; $_SERVER['SCRIPT_NAME'] = '/index.php'; unset($_SERVER['PATH_INFO']); @@ -224,6 +230,7 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase */ public function testPathInfoRetainsUrlEncodedCharacters() { + $_SERVER['SCRIPT_FILENAME'] = '/var/www/index.php'; $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['REQUEST_URI'] = '/foo/%23bar'; //<-- URL-encoded "#bar" $env = \Slim\Environment::getInstance(true); @@ -292,7 +299,20 @@ class EnvironmentTest extends PHPUnit_Framework_TestCase $env = \Slim\Environment::getInstance(true); $this->assertEquals('text/csv', $env['CONTENT_TYPE']); $this->assertEquals('100', $env['CONTENT_LENGTH']); - $this->assertEquals('XmlHttpRequest', $env['X_REQUESTED_WITH']); + $this->assertEquals('XmlHttpRequest', $env['HTTP_X_REQUESTED_WITH']); + } + + /** + * Tests X-HTTP-Method-Override is allowed through unmolested. + * + * Pre-conditions: + * X_HTTP_METHOD_OVERRIDE is sent in client HTTP request; + * X_HTTP_METHOD_OVERRIDE is not empty; + */ + public function testSetsHttpMethodOverrideHeader() { + $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'DELETE'; + $env = \Slim\Environment::getInstance(true); + $this->assertEquals('DELETE', $env['HTTP_X_HTTP_METHOD_OVERRIDE']); } /** diff --git a/vendor/slim/slim/tests/Http/HeadersTest.php b/vendor/slim/slim/tests/Http/HeadersTest.php index 0b06d3ab1a..4245806b30 100644 --- a/vendor/slim/slim/tests/Http/HeadersTest.php +++ b/vendor/slim/slim/tests/Http/HeadersTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -32,112 +32,28 @@ class HeadersTest extends PHPUnit_Framework_TestCase { - /** - * Test constructor without args - */ - public function testConstructorWithoutArgs() + public function testNormalizesKey() { $h = new \Slim\Http\Headers(); - $this->assertEquals(0, count($h)); + $h->set('Http_Content_Type', 'text/html'); + $prop = new \ReflectionProperty($h, 'data'); + $prop->setAccessible(true); + $this->assertArrayHasKey('Content-Type', $prop->getValue($h)); } - /** - * Test constructor with args - */ - public function testConstructorWithArgs() + public function testExtractHeaders() { - $h = new \Slim\Http\Headers(array('Content-Type' => 'text/html')); - $this->assertEquals(1, count($h)); - } - - /** - * Test get and set header - */ - public function testSetAndGetHeader() - { - $h = new \Slim\Http\Headers(); - $h['Content-Type'] = 'text/html'; - $this->assertEquals('text/html', $h['Content-Type']); - $this->assertEquals('text/html', $h['Content-type']); - $this->assertEquals('text/html', $h['content-type']); - } - - /** - * Test get non-existent header - */ - public function testGetNonExistentHeader() - { - $h = new \Slim\Http\Headers(); - $this->assertNull($h['foo']); - } - - /** - * Test isset header - */ - public function testHeaderIsSet() - { - $h = new \Slim\Http\Headers(); - $h['Content-Type'] = 'text/html'; - $this->assertTrue(isset($h['Content-Type'])); - $this->assertTrue(isset($h['Content-type'])); - $this->assertTrue(isset($h['content-type'])); - $this->assertFalse(isset($h['foo'])); - } - - /** - * Test unset header - */ - public function testUnsetHeader() - { - $h = new \Slim\Http\Headers(); - $h['Content-Type'] = 'text/html'; - $this->assertEquals(1, count($h)); - unset($h['Content-Type']); - $this->assertEquals(0, count($h)); - } - - /** - * Test merge headers - */ - public function testMergeHeaders() - { - $h = new \Slim\Http\Headers(); - $h['Content-Type'] = 'text/html'; - $this->assertEquals(1, count($h)); - $h->merge(array('Content-type' => 'text/csv', 'content-length' => 10)); - $this->assertEquals(2, count($h)); - $this->assertEquals('text/csv', $h['content-type']); - $this->assertEquals(10, $h['Content-length']); - } - - /** - * Test iteration - */ - public function testIteration() - { - $h = new \Slim\Http\Headers(); - $h['One'] = 'Foo'; - $h['Two'] = 'Bar'; - $output = ''; - foreach ($h as $key => $value) { - $output .= $key . $value; - } - $this->assertEquals('OneFooTwoBar', $output); - } - - /** - * Test outputs header name in original form, not canonical form - */ - public function testOutputsOriginalNotCanonicalName() - { - $h = new \Slim\Http\Headers(); - $h['X-Powered-By'] = 'Slim'; - $h['Content-Type'] = 'text/csv'; - $keys = array(); - foreach ($h as $name => $value) { - $keys[] = $name; - } - $this->assertContains('X-Powered-By', $keys); - $this->assertContains('Content-Type', $keys); + $test = array( + 'HTTP_HOST' => 'foo.com', + 'SERVER_NAME' => 'foo', + 'CONTENT_TYPE' => 'text/html', + 'X_FORWARDED_FOR' => '127.0.0.1' + ); + $results = \Slim\Http\Headers::extract($test); + $this->assertEquals(array( + 'HTTP_HOST' => 'foo.com', + 'CONTENT_TYPE' => 'text/html', + 'X_FORWARDED_FOR' => '127.0.0.1' + ), $results); } } diff --git a/vendor/slim/slim/tests/Http/RequestTest.php b/vendor/slim/slim/tests/Http/RequestTest.php index b2d3def74c..9ffea71300 100644 --- a/vendor/slim/slim/tests/Http/RequestTest.php +++ b/vendor/slim/slim/tests/Http/RequestTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -54,11 +54,6 @@ class RequestTest extends PHPUnit_Framework_TestCase )); $req = new \Slim\Http\Request($env); $this->assertTrue($req->isGet()); - $this->assertFalse($req->isPost()); - $this->assertFalse($req->isPut()); - $this->assertFalse($req->isDelete()); - $this->assertFalse($req->isOptions()); - $this->assertFalse($req->isHead()); } /** @@ -70,12 +65,7 @@ class RequestTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'POST', )); $req = new \Slim\Http\Request($env); - $this->assertFalse($req->isGet()); $this->assertTrue($req->isPost()); - $this->assertFalse($req->isPut()); - $this->assertFalse($req->isDelete()); - $this->assertFalse($req->isOptions()); - $this->assertFalse($req->isHead()); } /** @@ -87,12 +77,7 @@ class RequestTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'PUT', )); $req = new \Slim\Http\Request($env); - $this->assertFalse($req->isGet()); - $this->assertFalse($req->isPost()); $this->assertTrue($req->isPut()); - $this->assertFalse($req->isDelete()); - $this->assertFalse($req->isOptions()); - $this->assertFalse($req->isHead()); } /** @@ -104,12 +89,7 @@ class RequestTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'DELETE', )); $req = new \Slim\Http\Request($env); - $this->assertFalse($req->isGet()); - $this->assertFalse($req->isPost()); - $this->assertFalse($req->isPut()); $this->assertTrue($req->isDelete()); - $this->assertFalse($req->isOptions()); - $this->assertFalse($req->isHead()); } /** @@ -121,12 +101,7 @@ class RequestTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'OPTIONS', )); $req = new \Slim\Http\Request($env); - $this->assertFalse($req->isGet()); - $this->assertFalse($req->isPost()); - $this->assertFalse($req->isPut()); - $this->assertFalse($req->isDelete()); $this->assertTrue($req->isOptions()); - $this->assertFalse($req->isHead()); } /** @@ -138,14 +113,21 @@ class RequestTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'HEAD', )); $req = new \Slim\Http\Request($env); - $this->assertFalse($req->isGet()); - $this->assertFalse($req->isPost()); - $this->assertFalse($req->isPut()); - $this->assertFalse($req->isDelete()); - $this->assertFalse($req->isOptions()); $this->assertTrue($req->isHead()); } + /** + * Test HTTP PATCH method detection + */ + public function testIsPatch() + { + $env = \Slim\Environment::mock(array( + 'REQUEST_METHOD' => 'PATCH', + )); + $req = new \Slim\Http\Request($env); + $this->assertTrue($req->isPatch()); + } + /** * Test AJAX method detection w/ header */ @@ -165,7 +147,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testIsAjaxWithQueryParameter() { $env = \Slim\Environment::mock(array( - 'QUERY_STRING' => 'one=1&two=2&three=3&isajax=1', + 'QUERY_STRING' => 'isajax=1', )); $req = new \Slim\Http\Request($env); $this->assertTrue($req->isAjax()); @@ -173,7 +155,7 @@ class RequestTest extends PHPUnit_Framework_TestCase } /** - * Test AJAX method detection wihtout header or query paramter + * Test AJAX method detection without header or query parameter */ public function testIsAjaxWithoutHeaderOrQueryParameter() { @@ -239,6 +221,7 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals(3, count($req->get())); $this->assertEquals('1', $req->get('one')); $this->assertNull($req->get('foo')); + $this->assertFalse($req->get('foo', false)); } /** @@ -254,6 +237,7 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals(3, count($req->get())); $this->assertEquals('1', $req->get('one')); $this->assertNull($req->get('foo')); + $this->assertFalse($req->get('foo', false)); } /** @@ -271,6 +255,7 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals(2, count($req->post())); $this->assertEquals('bar', $req->post('foo')); $this->assertNull($req->post('xyz')); + $this->assertFalse($req->post('xyz', false)); } /** @@ -289,6 +274,7 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals(2, count($req->post())); $this->assertEquals('bar', $req->post('foo')); $this->assertNull($req->post('xyz')); + $this->assertFalse($req->post('xyz', false)); } /** @@ -337,6 +323,26 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals('bar', $req->put('foo')); $this->assertEquals('bar', $req->params('foo')); $this->assertNull($req->put('xyz')); + $this->assertFalse($req->put('xyz', false)); + } + + /** + * Test fetch PATCH params + */ + public function testPatch() + { + $env = \Slim\Environment::mock(array( + 'REQUEST_METHOD' => 'PATCH', + 'slim.input' => 'foo=bar&abc=123', + 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', + 'CONTENT_LENGTH' => 15 + )); + $req = new \Slim\Http\Request($env); + $this->assertEquals(2, count($req->patch())); + $this->assertEquals('bar', $req->patch('foo')); + $this->assertEquals('bar', $req->params('foo')); + $this->assertNull($req->patch('xyz')); + $this->assertFalse($req->patch('xyz', false)); } /** @@ -355,6 +361,7 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals('bar', $req->delete('foo')); $this->assertEquals('bar', $req->params('foo')); $this->assertNull($req->delete('xyz')); + $this->assertFalse($req->delete('xyz', false)); } /** @@ -363,7 +370,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testCookies() { $env = \Slim\Environment::mock(array( - 'COOKIE' => 'foo=bar; abc=123' + 'HTTP_COOKIE' => 'foo=bar; abc=123' )); $req = new \Slim\Http\Request($env); $this->assertEquals(2, count($req->cookies())); @@ -431,12 +438,11 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testHeaders() { $env = \Slim\Environment::mock(array( - 'ACCEPT_ENCODING' => 'gzip' + 'HTTP_ACCEPT_ENCODING' => 'gzip' )); $req = new \Slim\Http\Request($env); $headers = $req->headers(); - $this->assertTrue(is_array($headers)); - $this->assertArrayHasKey('ACCEPT_ENCODING', $headers); + $this->assertInstanceOf('\Slim\Http\Headers', $headers); $this->assertEquals('gzip', $req->headers('HTTP_ACCEPT_ENCODING')); $this->assertEquals('gzip', $req->headers('HTTP-ACCEPT-ENCODING')); $this->assertEquals('gzip', $req->headers('http_accept_encoding')); @@ -632,7 +638,7 @@ class RequestTest extends PHPUnit_Framework_TestCase { $env = \Slim\Environment::mock(array( 'SERVER_NAME' => 'slim', - 'HOST' => 'slimframework.com' + 'HTTP_HOST' => 'slimframework.com' )); $req = new \Slim\Http\Request($env); $this->assertEquals('slimframework.com', $req->getHost()); //Uses HTTP_HOST if available @@ -645,7 +651,7 @@ class RequestTest extends PHPUnit_Framework_TestCase { $env = \Slim\Environment::mock(array( 'SERVER_NAME' => 'slim', - 'HOST' => 'slimframework.com:80' + 'HTTP_HOST' => 'slimframework.com:80' )); $req = new \Slim\Http\Request($env); $this->assertEquals('slimframework.com', $req->getHost()); //Uses HTTP_HOST if available @@ -658,9 +664,9 @@ class RequestTest extends PHPUnit_Framework_TestCase { $env = \Slim\Environment::mock(array( 'SERVER_NAME' => 'slim', - 'HOST' => 'slimframework.com' + 'HTTP_HOST' => 'slimframework.com' )); - unset($env['HOST']); + unset($env['HTTP_HOST']); $req = new \Slim\Http\Request($env); $this->assertEquals('slim', $req->getHost()); //Uses SERVER_NAME as backup } @@ -671,7 +677,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetHostWithPort() { $env = \Slim\Environment::mock(array( - 'HOST' => 'slimframework.com', + 'HTTP_HOST' => 'slimframework.com', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http' @@ -681,12 +687,12 @@ class RequestTest extends PHPUnit_Framework_TestCase } /** - * Test get host with port doesn't dulplicate port numbers + * Test get host with port doesn't duplicate port numbers */ - public function testGetHostDoesntDulplicatePort() + public function testGetHostDoesntDuplicatePort() { $env = \Slim\Environment::mock(array( - 'HOST' => 'slimframework.com:80', + 'HTTP_HOST' => 'slimframework.com:80', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http' @@ -806,7 +812,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetUrl() { $env = \Slim\Environment::mock(array( - 'HOST' => 'slimframework.com', + 'HTTP_HOST' => 'slimframework.com', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http' @@ -821,7 +827,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetUrlWithCustomPort() { $env = \Slim\Environment::mock(array( - 'HOST' => 'slimframework.com', + 'HTTP_HOST' => 'slimframework.com', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 8080, 'slim.url_scheme' => 'http' @@ -836,7 +842,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetUrlWithHttps() { $env = \Slim\Environment::mock(array( - 'HOST' => 'slimframework.com', + 'HTTP_HOST' => 'slimframework.com', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 443, 'slim.url_scheme' => 'https' @@ -885,12 +891,12 @@ class RequestTest extends PHPUnit_Framework_TestCase } /** - * Test get refererer + * Test get referer */ public function testGetReferrer() { $env = \Slim\Environment::mock(array( - 'REFERER' => 'http://foo.com' + 'HTTP_REFERER' => 'http://foo.com' )); $req = new \Slim\Http\Request($env); $this->assertEquals('http://foo.com', $req->getReferrer()); @@ -898,7 +904,7 @@ class RequestTest extends PHPUnit_Framework_TestCase } /** - * Test get refererer + * Test get referer */ public function testGetReferrerWhenNotExists() { @@ -914,7 +920,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetUserAgent() { $env = \Slim\Environment::mock(array( - 'USER_AGENT' => 'user-agent-string' + 'HTTP_USER_AGENT' => 'user-agent-string' )); $req = new \Slim\Http\Request($env); $this->assertEquals('user-agent-string', $req->getUserAgent()); @@ -926,7 +932,7 @@ class RequestTest extends PHPUnit_Framework_TestCase public function testGetUserAgentWhenNotExists() { $env = \Slim\Environment::mock(); - unset($env['USER_AGENT']); + unset($env['HTTP_USER_AGENT']); $req = new \Slim\Http\Request($env); $this->assertNull($req->getUserAgent()); } diff --git a/vendor/slim/slim/tests/Http/ResponseTest.php b/vendor/slim/slim/tests/Http/ResponseTest.php index 2321e613c4..0b80445c1b 100644 --- a/vendor/slim/slim/tests/Http/ResponseTest.php +++ b/vendor/slim/slim/tests/Http/ResponseTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -32,541 +32,238 @@ class ResponseTest extends PHPUnit_Framework_TestCase { - /** - * Test constructor without args - */ - public function testConstructorWithoutArgs() + public function testConstructWithoutArgs() { - $r = new \Slim\Http\Response(); - $this->assertEquals('', $r->body()); - $this->assertEquals(200, $r->status()); - $this->assertEquals(0, $r->length()); - $this->assertEquals('text/html', $r['Content-Type']); + $res = new \Slim\Http\Response(); + + $this->assertAttributeEquals(200, 'status', $res); + $this->assertAttributeEquals('', 'body', $res); } - /** - * Test constructor with args - */ - public function testConstructorWithArgs() + public function testConstructWithArgs() { - $r = new \Slim\Http\Response('Page Not Found', 404, array('Content-Type' => 'application/json', 'X-Created-By' => 'Slim')); - $this->assertEquals('Page Not Found', $r->body()); - $this->assertEquals(404, $r->status()); - $this->assertEquals(14, $r->length()); - $this->assertEquals('application/json', $r['Content-Type']); - $this->assertEquals('Slim', $r['X-Created-By']); + $res = new \Slim\Http\Response('Foo', 201); + + $this->assertAttributeEquals(201, 'status', $res); + $this->assertAttributeEquals('Foo', 'body', $res); } - /** - * Test get status - */ public function testGetStatus() { - $r = new \Slim\Http\Response(); - $this->assertEquals(200, $r->status()); + $res = new \Slim\Http\Response(); + + $this->assertEquals(200, $res->getStatus()); } - /** - * Test set status - */ public function testSetStatus() { - $r = new \Slim\Http\Response(); - $r->status(500); - $this->assertEquals(500, $r->status()); + $res = new \Slim\Http\Response(); + $res->setStatus(301); + + $this->assertAttributeEquals(301, 'status', $res); } /** - * Test get headers + * DEPRECATION WARNING! */ - public function testGetHeaders() + public function testStatusGetOld() { - $r = new \Slim\Http\Response(); - $headers = $r->headers(); - $this->assertEquals(1, count($headers)); - $this->assertEquals('text/html', $headers['Content-Type']); + $res = new \Slim\Http\Response('', 201); + $this->assertEquals(201, $res->status()); } /** - * Test get and set header (without Array Access) + * DEPRECATION WARNING! */ - public function testGetAndSetHeader() + public function testStatusSetOld() { - $r = new \Slim\Http\Response(); - $r->header('X-Foo', 'Bar'); - $this->assertEquals('Bar', $r->header('X-Foo')); + $res = new \Slim\Http\Response(); + $prop = new \ReflectionProperty($res, 'status'); + $prop->setAccessible(true); + $res->status(301); + + $this->assertEquals(301, $prop->getValue($res)); } - /** - * Test get body - */ public function testGetBody() { - $r = new \Slim\Http\Response('Foo'); - $this->assertEquals('Foo', $r->body()); + $res = new \Slim\Http\Response(); + $property = new \ReflectionProperty($res, 'body'); + $property->setAccessible(true); + $property->setValue($res, 'foo'); + + $this->assertEquals('foo', $res->getBody()); } - /** - * Test set body - */ public function testSetBody() { - $r = new \Slim\Http\Response(); - $r->body('Foo'); - $this->assertEquals('Foo', $r->body()); + $res = new \Slim\Http\Response('bar'); + $res->setBody('foo'); // <-- Should replace body + + $this->assertAttributeEquals('foo', 'body', $res); } - /** - * Test get length - */ - public function testGetLength() + public function testWrite() { - $r = new \Slim\Http\Response('Foo'); - $this->assertEquals(3, $r->length()); + $res = new \Slim\Http\Response(); + $property = new \ReflectionProperty($res, 'body'); + $property->setAccessible(true); + $property->setValue($res, 'foo'); + $res->write('bar'); // <-- Should append to body + + $this->assertAttributeEquals('foobar', 'body', $res); } - /** - * Test set length - */ - public function testSetLength() + public function testLength() { - $r = new \Slim\Http\Response(); - $r->length(3); - $this->assertEquals(3, $r->length()); + $res = new \Slim\Http\Response('foo'); // <-- Sets body and length + + $this->assertEquals(3, $res->getLength()); } - /** - * Test write for appending - */ - public function testWriteAppend() - { - $r = new \Slim\Http\Response('Foo'); - $r->write('Bar'); - $this->assertEquals('FooBar', $r->body()); - } - - /** - * Test write for replacing - */ - public function testWriteReplace() - { - $r = new \Slim\Http\Response('Foo'); - $r->write('Bar', true); - $this->assertEquals('Bar', $r->body()); - } - - /** - * Test finalize - */ public function testFinalize() { - $r = new \Slim\Http\Response(); - $r->status(404); - $r['Content-Type'] = 'application/json'; - $r->write('Foo'); - $result = $r->finalize(); - $this->assertEquals(3, count($result)); - $this->assertEquals(404, $result[0]); - $this->assertFalse(is_null($result[1]['Content-Type'])); + $res = new \Slim\Http\Response(); + $resFinal = $res->finalize(); + + $this->assertTrue(is_array($resFinal)); + $this->assertEquals(3, count($resFinal)); + $this->assertEquals(200, $resFinal[0]); + $this->assertInstanceOf('\Slim\Http\Headers', $resFinal[1]); + $this->assertEquals('', $resFinal[2]); } - /** - * Test finalize - */ - public function testFinalizeWithoutBody() + public function testFinalizeWithEmptyBody() { - $r = new \Slim\Http\Response(); - $r->status(204); - $r['Content-Type'] = 'application/json'; - $r->write('Foo'); - $result = $r->finalize(); - $this->assertEquals(3, count($result)); - $this->assertEquals('', $result[2]); + $res = new \Slim\Http\Response('Foo', 304); + $resFinal = $res->finalize(); + + $this->assertEquals('', $resFinal[2]); } - /** - * Test set cookie with only name and value - */ - public function testSetCookieWithNameAndValue() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', 'bar'); - $this->assertEquals('foo=bar', $r['Set-Cookie']); - } - - /** - * Test set multiple cookies with only name and value - */ - public function testSetMultipleCookiesWithNameAndValue() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', 'bar'); - $r->setCookie('abc', '123'); - $this->assertEquals("foo=bar\nabc=123", $r['Set-Cookie']); - } - - /** - * Test set cookie only name and value and expires (as int) - */ - public function testSetMultipleCookiesWithNameAndValueAndExpiresAsInt() - { - $now = time(); - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'expires' => $now - )); - $this->assertEquals("foo=bar; expires=" . gmdate('D, d-M-Y H:i:s e', $now), $r['Set-Cookie']); - } - - /** - * Test set cookie with only name and value and expires (as string) - */ - public function testSetMultipleCookiesWithNameAndValueAndExpiresAsString() - { - $expires = 'next Tuesday'; - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'expires' => $expires - )); - $this->assertEquals("foo=bar; expires=" . gmdate('D, d-M-Y H:i:s e', strtotime($expires)), $r['Set-Cookie']); - } - - /** - * Test set cookie with name, value, domain - */ - public function testSetCookieWithNameAndValueAndDomain() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'domain' => '.slimframework.com' - )); - $this->assertEquals('foo=bar; domain=.slimframework.com', $r['Set-Cookie']); - } - - /** - * Test set cookie with name, value, domain, path - */ - public function testSetCookieWithNameAndValueAndDomainAndPath() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'domain' => '.slimframework.com', - 'path' => '/foo' - )); - $this->assertEquals($r['Set-Cookie'], 'foo=bar; domain=.slimframework.com; path=/foo'); - } - - /** - * Test set cookie with only name and value and secure flag - */ - public function testSetCookieWithNameAndValueAndSecureFlag() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'secure' => true - )); - $this->assertEquals('foo=bar; secure', $r['Set-Cookie']); - } - - /** - * Test set cookie with only name and value and secure flag (as non-truthy) - */ - public function testSetCookieWithNameAndValueAndSecureFlagAsNonTruthy() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'secure' => 0 - )); - $this->assertEquals('foo=bar', $r['Set-Cookie']); - } - - /** - * Test set cookie with only name and value and httponly flag - */ - public function testSetCookieWithNameAndValueAndHttpOnlyFlag() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'httponly' => true - )); - $this->assertEquals('foo=bar; HttpOnly', $r['Set-Cookie']); - } - - /** - * Test set cookie with only name and value and httponly flag (as non-truthy) - */ - public function testSetCookieWithNameAndValueAndHttpOnlyFlagAsNonTruthy() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'httponly' => 0 - )); - $this->assertEquals('foo=bar', $r['Set-Cookie']); - } - - /* - * Test delete cookie by name - */ - public function testDeleteCookieByName() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', 'bar'); - $r->setCookie('abc', '123'); - $r->deleteCookie('foo'); - $this->assertEquals(1, preg_match("@abc=123\nfoo=; expires=@", $r['Set-Cookie'])); - } - - /* - * Test delete cookie by name and domain - */ - public function testDeleteCookieByNameAndDomain1() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', 'bar'); //Note: This does not have domain associated with it - $r->setCookie('abc', '123'); - $r->deleteCookie('foo', array('domain' => '.slimframework.com')); //This SHOULD NOT remove the `foo` cookie - $this->assertEquals(1, preg_match("@foo=bar\nabc=123\nfoo=; domain=.slimframework.com; expires=@", $r['Set-Cookie'])); - } - - /* - * Test delete cookie by name and domain - */ - public function testDeleteCookieByNameAndDomain2() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', array( - 'value' => 'bar', - 'domain' => '.slimframework.com' //Note: This does have domain associated with it - )); - $r->setCookie('abc', '123'); - $r->deleteCookie('foo', array('domain' => '.slimframework.com')); //This SHOULD remove the `foo` cookie - $this->assertEquals(1, preg_match("@abc=123\nfoo=; domain=.slimframework.com; expires=@", $r['Set-Cookie'])); - } - - /** - * Test delete cookie by name and custom props - */ - public function testDeleteCookieByNameAndCustomProps() - { - $r = new \Slim\Http\Response(); - $r->setCookie('foo', 'bar'); - $r->setCookie('abc', '123'); - $r->deleteCookie('foo', array( - 'secure' => true, - 'httponly' => true - )); - $this->assertEquals(1, preg_match("@abc=123\nfoo=; expires=.*; secure; HttpOnly@", $r['Set-Cookie'])); - } - - /** - * Test redirect - */ public function testRedirect() { - $r = new \Slim\Http\Response(); - $r->redirect('/foo'); - $this->assertEquals(302, $r->status()); - $this->assertEquals('/foo', $r['Location']); + $res = new \Slim\Http\Response(); + $res->redirect('/foo'); + + $pStatus = new \ReflectionProperty($res, 'status'); + $pStatus->setAccessible(true); + + $this->assertEquals(302, $pStatus->getValue($res)); + $this->assertEquals('/foo', $res->headers['Location']); } - /** - * Test redirect with custom status - */ - public function testRedirectWithCustomStatus() - { - $r = new \Slim\Http\Response(); - $r->redirect('/foo', 307); - $this->assertEquals(307, $r->status()); - $this->assertEquals('/foo', $r['Location']); - } - - /** - * Test isEmpty - */ public function testIsEmpty() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(404); - $r2->status(201); + $r1->setStatus(404); + $r2->setStatus(201); $this->assertFalse($r1->isEmpty()); $this->assertTrue($r2->isEmpty()); } - /** - * Test isClientError - */ public function testIsClientError() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(404); - $r2->status(500); + $r1->setStatus(404); + $r2->setStatus(500); $this->assertTrue($r1->isClientError()); $this->assertFalse($r2->isClientError()); } - /** - * Test isForbidden - */ public function testIsForbidden() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(403); - $r2->status(500); + $r1->setStatus(403); + $r2->setStatus(500); $this->assertTrue($r1->isForbidden()); $this->assertFalse($r2->isForbidden()); } - /** - * Test isInformational - */ public function testIsInformational() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(100); - $r2->status(200); + $r1->setStatus(100); + $r2->setStatus(200); $this->assertTrue($r1->isInformational()); $this->assertFalse($r2->isInformational()); } - /** - * Test isInformational - */ public function testIsNotFound() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(404); - $r2->status(200); + $r1->setStatus(404); + $r2->setStatus(200); $this->assertTrue($r1->isNotFound()); $this->assertFalse($r2->isNotFound()); } - /** - * Test isOk - */ public function testIsOk() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(200); - $r2->status(201); + $r1->setStatus(200); + $r2->setStatus(201); $this->assertTrue($r1->isOk()); $this->assertFalse($r2->isOk()); } - /** - * Test isSuccessful - */ public function testIsSuccessful() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); $r3 = new \Slim\Http\Response(); - $r1->status(200); - $r2->status(201); - $r3->status(302); + $r1->setStatus(200); + $r2->setStatus(201); + $r3->setStatus(302); $this->assertTrue($r1->isSuccessful()); $this->assertTrue($r2->isSuccessful()); $this->assertFalse($r3->isSuccessful()); } - /** - * Test isRedirect - */ public function testIsRedirect() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(307); - $r2->status(304); + $r1->setStatus(307); + $r2->setStatus(304); $this->assertTrue($r1->isRedirect()); $this->assertFalse($r2->isRedirect()); } - /** - * Test isRedirection - */ public function testIsRedirection() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); $r3 = new \Slim\Http\Response(); - $r1->status(307); - $r2->status(304); - $r3->status(200); + $r1->setStatus(307); + $r2->setStatus(304); + $r3->setStatus(200); $this->assertTrue($r1->isRedirection()); $this->assertTrue($r2->isRedirection()); $this->assertFalse($r3->isRedirection()); } - /** - * Test isServerError - */ public function testIsServerError() { $r1 = new \Slim\Http\Response(); $r2 = new \Slim\Http\Response(); - $r1->status(500); - $r2->status(400); + $r1->setStatus(500); + $r2->setStatus(400); $this->assertTrue($r1->isServerError()); $this->assertFalse($r2->isServerError()); } - /** - * Test offset exists and offset get - */ - public function testOffsetExistsAndGet() - { - $r = new \Slim\Http\Response(); - $this->assertFalse(empty($r['Content-Type'])); - $this->assertNull($r['foo']); - } - - /** - * Test iteration - */ - public function testIteration() - { - $h = new \Slim\Http\Response(); - $output = ''; - foreach ($h as $key => $value) { - $output .= $key . $value; - } - $this->assertEquals('Content-Typetext/html', $output); - } - - /** - * Test countable - */ - public function testCountable() - { - $r1 = new \Slim\Http\Response(); - $this->assertEquals(1, count($r1)); //Content-Type - } - - /** - * Test message for code when message exists - */ public function testMessageForCode() { $this->assertEquals('200 OK', \Slim\Http\Response::getMessageForCode(200)); } - /** - * Test message for code when message exists - */ public function testMessageForCodeWithInvalidCode() { $this->assertNull(\Slim\Http\Response::getMessageForCode(600)); diff --git a/vendor/slim/slim/tests/Http/UtilTest.php b/vendor/slim/slim/tests/Http/UtilTest.php index 4eb0b4d30a..544a664b75 100644 --- a/vendor/slim/slim/tests/Http/UtilTest.php +++ b/vendor/slim/slim/tests/Http/UtilTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -324,6 +324,50 @@ class SlimHttpUtilTest extends PHPUnit_Framework_TestCase $this->assertEquals('foo=bar; domain=foo.com; path=/foo; expires=' . $expiresFormat . '; secure; HttpOnly', $header['Set-Cookie']); } + /** + * Test serializeCookies and decrypt with string expires + * + * In this test a cookie with a string typed value for 'expires' is set, + * which should be parsed by `strtotime` to a timestamp when it's added to + * the headers; this timestamp should then be correctly parsed, and the + * value correctly decrypted, by `decodeSecureCookie`. + */ + public function testSerializeCookiesAndDecryptWithStringExpires() + { + $value = 'bar'; + + $headers = new \Slim\Http\Headers(); + + $settings = array( + 'cookies.encrypt' => true, + 'cookies.secret_key' => 'secret', + 'cookies.cipher' => MCRYPT_RIJNDAEL_256, + 'cookies.cipher_mode' => MCRYPT_MODE_CBC + ); + + $cookies = new \Slim\Http\Cookies(); + $cookies->set('foo', array( + 'value' => $value, + 'expires' => '1 hour' + )); + + \Slim\Http\Util::serializeCookies($headers, $cookies, $settings); + + $encrypted = $headers->get('Set-Cookie'); + $encrypted = strstr($encrypted, ';', true); + $encrypted = urldecode(substr(strstr($encrypted, '='), 1)); + + $decrypted = \Slim\Http\Util::decodeSecureCookie( + $encrypted, + $settings['cookies.secret_key'], + $settings['cookies.cipher'], + $settings['cookies.cipher_mode'] + ); + + $this->assertEquals($value, $decrypted); + $this->assertTrue($value !== $encrypted); + } + public function testDeleteCookieHeaderWithSurvivingCookie() { $header = array('Set-Cookie' => "foo=bar\none=two"); diff --git a/vendor/slim/slim/tests/LogTest.php b/vendor/slim/slim/tests/LogTest.php index d390e45c4c..04954c5a43 100644 --- a/vendor/slim/slim/tests/LogTest.php +++ b/vendor/slim/slim/tests/LogTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -96,6 +96,21 @@ class LogTest extends PHPUnit_Framework_TestCase } public function testLogInfoExcludedByLevel() + { + $log = new \Slim\Log(new MyWriter()); + $log->setLevel(\Slim\Log::NOTICE); + $this->assertFalse($log->info('Info')); + } + + public function testLogNotice() + { + $this->expectOutputString('Notice'); + $log = new \Slim\Log(new MyWriter()); + $result = $log->notice('Notice'); + $this->assertTrue($result); + } + + public function testLogNoticeExcludedByLevel() { $log = new \Slim\Log(new MyWriter()); $log->setLevel(\Slim\Log::WARN); @@ -106,7 +121,7 @@ class LogTest extends PHPUnit_Framework_TestCase { $this->expectOutputString('Warn'); $log = new \Slim\Log(new MyWriter()); - $result = $log->warn('Warn'); + $result = $log->warning('Warn'); $this->assertTrue($result); } @@ -114,7 +129,7 @@ class LogTest extends PHPUnit_Framework_TestCase { $log = new \Slim\Log(new MyWriter()); $log->setLevel(\Slim\Log::ERROR); - $this->assertFalse($log->warn('Warn')); + $this->assertFalse($log->warning('Warn')); } public function testLogError() @@ -128,15 +143,56 @@ class LogTest extends PHPUnit_Framework_TestCase public function testLogErrorExcludedByLevel() { $log = new \Slim\Log(new MyWriter()); - $log->setLevel(\Slim\Log::FATAL); + $log->setLevel(\Slim\Log::CRITICAL); $this->assertFalse($log->error('Error')); } - public function testLogFatal() + public function testLogCritical() { - $this->expectOutputString('Fatal'); + $this->expectOutputString('Critical'); $log = new \Slim\Log(new MyWriter()); - $result = $log->fatal('Fatal'); + $result = $log->critical('Critical'); + $this->assertTrue($result); + } + + public function testLogCriticalExcludedByLevel() + { + $log = new \Slim\Log(new MyWriter()); + $log->setLevel(\Slim\Log::ALERT); + $this->assertFalse($log->critical('Critical')); + } + + public function testLogAlert() + { + $this->expectOutputString('Alert'); + $log = new \Slim\Log(new MyWriter()); + $result = $log->alert('Alert'); + $this->assertTrue($result); + } + + public function testLogAlertExcludedByLevel() + { + $log = new \Slim\Log(new MyWriter()); + $log->setLevel(\Slim\Log::EMERGENCY); + $this->assertFalse($log->alert('Alert')); + } + + public function testLogEmergency() + { + $this->expectOutputString('Emergency'); + $log = new \Slim\Log(new MyWriter()); + $result = $log->emergency('Emergency'); + $this->assertTrue($result); + } + + public function testInterpolateMessage() + { + $this->expectOutputString('Hello Slim !'); + $log = new \Slim\Log(new MyWriter()); + $result = $log->debug( + 'Hello {framework} !', + array('framework' => "Slim") + ); $this->assertTrue($result); } diff --git a/vendor/slim/slim/tests/LogWriterTest.php b/vendor/slim/slim/tests/LogWriterTest.php index 3c30d8039b..e116f37ee9 100644 --- a/vendor/slim/slim/tests/LogWriterTest.php +++ b/vendor/slim/slim/tests/LogWriterTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * diff --git a/vendor/slim/slim/tests/Middleware/ContentTypesTest.php b/vendor/slim/slim/tests/Middleware/ContentTypesTest.php index 3857b3428c..3fdfad1987 100644 --- a/vendor/slim/slim/tests/Middleware/ContentTypesTest.php +++ b/vendor/slim/slim/tests/Middleware/ContentTypesTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -104,10 +104,11 @@ class ContentTypesTest extends PHPUnit_Framework_TestCase */ public function testParsesXmlWithError() { + libxml_use_internal_errors(true); \Slim\Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'application/xml', - 'CONENT_LENGTH' => 68, + 'CONTENT_LENGTH' => 68, 'slim.input' => '1Clive Cussler' //<-- This should be incorrect! )); $s = new \Slim\Slim(); @@ -126,7 +127,7 @@ class ContentTypesTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'text/csv', - 'CONENT_LENGTH' => 44, + 'CONTENT_LENGTH' => 44, 'slim.input' => "John,Doe,000-111-2222\nJane,Doe,111-222-3333" )); $s = new \Slim\Slim(); @@ -148,7 +149,7 @@ class ContentTypesTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'application/json; charset=ISO-8859-4', - 'CONENT_LENGTH' => 13, + 'CONTENT_LENGTH' => 13, 'slim.input' => '{"foo":"bar"}' )); $s = new \Slim\Slim(); diff --git a/vendor/slim/slim/tests/Middleware/FlashTest.php b/vendor/slim/slim/tests/Middleware/FlashTest.php index 09da70a8a9..24238e1f6c 100644 --- a/vendor/slim/slim/tests/Middleware/FlashTest.php +++ b/vendor/slim/slim/tests/Middleware/FlashTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -86,7 +86,7 @@ class SlimFlashTest extends PHPUnit_Framework_TestCase } /** - * Test flash messages from preivous request do not persist to next request + * Test flash messages from previous request do not persist to next request */ public function testFlashMessagesFromPreviousRequestDoNotPersist() { @@ -125,4 +125,17 @@ class SlimFlashTest extends PHPUnit_Framework_TestCase } $this->assertEquals('infofooerrorbar', $output); } + + /** + * Test countable + */ + public function testCountable() + { + $_SESSION['slim.flash'] = array('info' => 'foo', 'error' => 'bar'); + $f = new \Slim\MiddleWare\Flash(); + $f->loadMessages(); + $this->assertEquals(2, count($f)); + } + + } diff --git a/vendor/slim/slim/tests/Middleware/MethodOverrideTest.php b/vendor/slim/slim/tests/Middleware/MethodOverrideTest.php index 55484883cd..1427d1339b 100644 --- a/vendor/slim/slim/tests/Middleware/MethodOverrideTest.php +++ b/vendor/slim/slim/tests/Middleware/MethodOverrideTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -64,7 +64,7 @@ class MethodOverrideTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', - 'CONENT_LENGTH' => 11, + 'CONTENT_LENGTH' => 11, 'slim.input' => '_METHOD=PUT' )); $app = new CustomAppMethod(); @@ -98,7 +98,7 @@ class MethodOverrideTest extends PHPUnit_Framework_TestCase } /** - * Test does not override method if no method ovveride parameter + * Test does not override method if no method override parameter */ public function testDoesNotOverrideMethodAsPostWithoutParameter() { @@ -132,9 +132,9 @@ class MethodOverrideTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'application/json', - 'CONENT_LENGTH' => 0, + 'CONTENT_LENGTH' => 0, 'slim.input' => '', - 'X_HTTP_METHOD_OVERRIDE' => 'DELETE' + 'HTTP_X_HTTP_METHOD_OVERRIDE' => 'DELETE' )); $app = new CustomAppMethod(); $mw = new \Slim\Middleware\MethodOverride(); diff --git a/vendor/slim/slim/tests/Middleware/PrettyExceptionsTest.php b/vendor/slim/slim/tests/Middleware/PrettyExceptionsTest.php index 4f41b2d523..97c6956d74 100644 --- a/vendor/slim/slim/tests/Middleware/PrettyExceptionsTest.php +++ b/vendor/slim/slim/tests/Middleware/PrettyExceptionsTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -122,4 +122,32 @@ class PrettyExceptionsTest extends PHPUnit_Framework_TestCase $this->assertContains('LogicException', $app->response()->body()); } + + /** + * Test with custom log + */ + public function testWithCustomLogWriter() + { + $this->setExpectedException('\LogicException'); + + \Slim\Environment::mock(array( + 'SCRIPT_NAME' => '/index.php', + 'PATH_INFO' => '/foo' + )); + $app = new \Slim\Slim(array( + 'log.enabled' => false + )); + $app->container->singleton('log', function () use ($app) { + return new \Slim\Log(new \Slim\LogWriter('php://temp')); + }); + $app->get('/foo', function () use ($app) { + throw new \LogicException('Test Message', 100); + }); + $mw = new \Slim\Middleware\PrettyExceptions(); + $mw->setApplication($app); + $mw->setNextMiddleware($app); + $mw->call(); + + $this->assertContains('LogicException', $app->response()->body()); + } } diff --git a/vendor/slim/slim/tests/Middleware/SessionCookieTest.php b/vendor/slim/slim/tests/Middleware/SessionCookieTest.php index 8ef12ef0cb..e281f4fbcb 100644 --- a/vendor/slim/slim/tests/Middleware/SessionCookieTest.php +++ b/vendor/slim/slim/tests/Middleware/SessionCookieTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -34,10 +34,6 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase { public function setUp() { - if ( session_id() !== '' ) { - session_unset(); - session_destroy(); - } $_SESSION = array(); } @@ -45,10 +41,11 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase * Test session cookie is set and constructed correctly * * We test for two things: - * 1) That the HTTP cookie is added to the `Set-Cookie:` response header; - * 2) That the HTTP cookie is constructed in the expected format; + * + * 1) That the HTTP cookie exists with the correct name; + * 2) That the HTTP cookie's value is the expected value; */ - public function testSessionCookieIsCreatedAndEncrypted() + public function testSessionCookieIsCreated() { \Slim\Environment::mock(array( 'SCRIPT_NAME' => '/index.php', @@ -56,6 +53,7 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase )); $app = new \Slim\Slim(); $app->get('/foo', function () { + $_SESSION['foo'] = 'bar'; echo "Success"; }); $mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years')); @@ -63,26 +61,29 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase $mw->setNextMiddleware($app); $mw->call(); list($status, $header, $body) = $app->response()->finalize(); - $matches = array(); - preg_match_all('@^slim_session=.+|.+|.+; expires=@', $header['Set-Cookie'], $matches, PREG_SET_ORDER); - $this->assertEquals(1, count($matches)); + $this->assertTrue($app->response->cookies->has('slim_session')); + $cookie = $app->response->cookies->get('slim_session'); + $this->assertEquals(serialize(array('foo' => 'bar')), $cookie['value']); } /** - * Test $_SESSION is populated from HTTP cookie + * Test $_SESSION is populated from an encrypted HTTP cookie * - * The HTTP cookie in this test was created using the previous test; the encrypted cookie contains - * the serialized array ['foo' => 'bar']. The middleware secret, cipher, and cipher mode are assumed - * to be the default values. + * The encrypted cookie contains the serialized array ['foo' => 'bar']. The + * global secret, cipher, and cipher mode are assumed to be the default + * values. */ - public function testSessionIsPopulatedFromCookie() + public function testSessionIsPopulatedFromEncryptedCookie() { \Slim\Environment::mock(array( 'SCRIPT_NAME' => '/index.php', 'PATH_INFO' => '/foo', - 'COOKIE' => 'slim_session=1644004961%7CLKkYPwqKIMvBK7MWl6D%2BxeuhLuMaW4quN%2F512ZAaVIY%3D%7Ce0f007fa852c7101e8224bb529e26be4d0dfbd63', + 'HTTP_COOKIE' => 'slim_session=1644004961%7CLKkYPwqKIMvBK7MWl6D%2BxeuhLuMaW4quN%2F512ZAaVIY%3D%7Ce0f007fa852c7101e8224bb529e26be4d0dfbd63', )); $app = new \Slim\Slim(); + // The cookie value in the test is encrypted, so cookies.encrypt must + // be set to true + $app->config('cookies.encrypt', true); $app->get('/foo', function () { echo "Success"; }); @@ -93,6 +94,66 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase $this->assertEquals(array('foo' => 'bar'), $_SESSION); } + /** + * Test $_SESSION is populated from an unencrypted HTTP cookie + * + * The unencrypted cookie contains the serialized array ['foo' => 'bar']. + * The global cookies.encrypt setting is set to false + */ + public function testSessionIsPopulatedFromUnencryptedCookie() + { + \Slim\Environment::mock(array( + 'SCRIPT_NAME' => '/index.php', + 'PATH_INFO' => '/foo', + 'HTTP_COOKIE' => 'slim_session=a%3A1%3A%7Bs%3A3%3A%22foo%22%3Bs%3A3%3A%22bar%22%3B%7D', + )); + $app = new \Slim\Slim(); + // The cookie value in the test is unencrypted, so cookies.encrypt must + // be set to false + $app->config('cookies.encrypt', false); + $app->get('/foo', function () { + echo "Success"; + }); + $mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years')); + $mw->setApplication($app); + $mw->setNextMiddleware($app); + $mw->call(); + $this->assertEquals(array('foo' => 'bar'), $_SESSION); + } + + public function testUnserializeErrorsAreCaughtAndLogged() + { + \Slim\Environment::mock(array( + 'SCRIPT_NAME' => '/index.php', + 'PATH_INFO' => '/foo', + 'HTTP_COOKIE' => 'slim_session=1644004961%7CLKkYPwqKIMvBK7MWl6D%2BxeuhLuMaW4quN%2F512ZAaVIY%3D%7Ce0f007fa852c7101e8224bb529e26be4d0dfbd63', + )); + + $logWriter = $this->getMockBuilder('Slim\LogWriter') + ->disableOriginalConstructor() + ->getMock(); + + $logWriter->expects($this->once()) + ->method('write'); + $oldLevel = error_reporting(E_ALL); + + $app = new \Slim\Slim(array( + 'log.writer' => $logWriter + )); + // Unserializing an encrypted value fails if cookie not decrpyted + $app->config('cookies.encrypt', false); + $app->get('/foo', function () { + echo "Success"; + }); + $mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years')); + $mw->setApplication($app); + $mw->setNextMiddleware($app); + $mw->call(); + $this->assertEquals(array(), $_SESSION); + + error_reporting($oldLevel); + } + /** * Test $_SESSION is populated as empty array if no HTTP cookie */ @@ -112,4 +173,297 @@ class SessionCookieTest extends PHPUnit_Framework_TestCase $mw->call(); $this->assertEquals(array(), $_SESSION); } + + public function testSerializingTooLongValueWritesLogAndDoesntCreateCookie() + { + \Slim\Environment::mock(array( + 'SCRIPT_NAME' => '/index.php', + 'PATH_INFO' => '/foo' + )); + + $logWriter = $this->getMockBuilder('Slim\LogWriter') + ->disableOriginalConstructor() + ->getMock(); + + $logWriter->expects($this->once()) + ->method('write') + ->with('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.', \Slim\Log::ERROR); + + $app = new \Slim\Slim(array( + 'log.writer' => $logWriter + )); + + $tooLongValue = $this->getTooLongValue(); + + $app->get('/foo', function () use ($tooLongValue) { + $_SESSION['test'] = $tooLongValue; + echo "Success"; + }); + + $mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years')); + $mw->setApplication($app); + $mw->setNextMiddleware($app); + $mw->call(); + list($status, $header, $body) = $app->response()->finalize(); + $this->assertFalse($app->response->cookies->has('slim_session')); + } + + /** + * Generated by http://www.random.org/strings/ + */ + protected function getTooLongValue() + { + return <<next->call(); - echo "After"; - } -} - -class My_Application -{ - public function call() - { - echo "Application"; - } + public function call() {} } class MiddlewareTest extends PHPUnit_Framework_TestCase { - /** - * Get and set application - */ - public function testGetAndSetApplication() + public function testSetApplication() { - $app = new My_Application(); - $mw = new My_Middleware(); + $app = new stdClass(); + $mw = new MyMiddleware(); $mw->setApplication($app); + + $this->assertAttributeSame($app, 'app', $mw); + } + + public function testGetApplication() + { + $app = new stdClass(); + $mw = new MyMiddleware(); + $property = new \ReflectionProperty($mw, 'app'); + $property->setAccessible(true); + $property->setValue($mw, $app); + $this->assertSame($app, $mw->getApplication()); } - /** - * Get and set next middleware - */ - public function testGetAndSetNextMiddleware() + public function testSetNextMiddleware() { - $mw1 = new My_Middleware(); - $mw2 = new My_Middleware(); + $mw1 = new MyMiddleware(); + $mw2 = new MyMiddleware(); $mw1->setNextMiddleware($mw2); - $this->assertSame($mw2, $mw1->getNextMiddleware()); + + $this->assertAttributeSame($mw2, 'next', $mw1); } - /** - * Test call - */ - public function testCall() + public function testGetNextMiddleware() { - $this->expectOutputString('BeforeApplicationAfter'); - $app = new My_Application(); - $mw = new My_Middleware(); - $mw->setNextMiddleware($app); - $mw->call(); + $mw1 = new MyMiddleware(); + $mw2 = new MyMiddleware(); + $property = new \ReflectionProperty($mw1, 'next'); + $property->setAccessible(true); + $property->setValue($mw1, $mw2); + + $this->assertSame($mw2, $mw1->getNextMiddleware()); } } diff --git a/vendor/slim/slim/tests/RouteTest.php b/vendor/slim/slim/tests/RouteTest.php index decec7d4fc..5d0ee7ab96 100644 --- a/vendor/slim/slim/tests/RouteTest.php +++ b/vendor/slim/slim/tests/RouteTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -29,292 +29,202 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// Used for passing callable via string -function testCallable() {} - class RouteTest extends PHPUnit_Framework_TestCase { - /** - * Route should set name - */ - public function testRouteSetsName() + public function testGetPattern() { - $route = new \Slim\Route('/foo/bar', function () {}); - $route->name('foo'); + $route = new \Slim\Route('/foo', function () {}); + + $this->assertEquals('/foo', $route->getPattern()); + } + + public function testGetName() + { + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'name'); + $property->setAccessible(true); + $property->setValue($route, 'foo'); + $this->assertEquals('foo', $route->getName()); } - /** - * Route should set pattern - */ - public function testRouteSetsPattern() + public function testSetName() { - $route1 = new \Slim\Route('/foo/bar', function () {}); - $this->assertEquals('/foo/bar', $route1->getPattern()); + $route = new \Slim\Route('/foo', function () {}); + $route->name('foo'); // <-- Alias for `setName()` + + $this->assertAttributeEquals('foo', 'name', $route); } - /** - * Route sets pattern with params - */ - public function testRouteSetsPatternWithParams() + public function testGetCallable() { - $route = new \Slim\Route('/hello/:first/:last', function () {}); - $this->assertEquals('/hello/:first/:last', $route->getPattern()); - } + $callable = function () { + echo 'Foo'; + }; + $route = new \Slim\Route('/foo', $callable); - /** - * Route sets custom pattern that overrides pattern - */ - public function testRouteSetsCustomTemplate() - { - $route = new \Slim\Route('/hello/*', function () {}); - $route->setPattern('/hello/:name'); - $this->assertEquals('/hello/:name', $route->getPattern()); - } - - /** - * Route should store a reference to the callable - * anonymous function. - */ - public function testRouteSetsCallableAsFunction() - { - $callable = function () { echo "Foo!"; }; - $route = new \Slim\Route('/foo/bar', $callable); $this->assertSame($callable, $route->getCallable()); } - /** - * Route should store a reference to the callable - * regular function (for PHP 5 < 5.3) - */ - public function testRouteSetsCallableAsString() + public function testGetCallableAsClass() { - $route = new \Slim\Route('/foo/bar', 'testCallable'); - $this->assertEquals('testCallable', $route->getCallable()); + $route = new \Slim\Route('/foo', '\Slim\Router:getCurrentRoute'); + + $callable = $route->getCallable(); + $this->assertInstanceOf('\Slim\Router', $callable[0]); + $this->assertEquals('getCurrentRoute', $callable[1]); } - /** - * Route should throw exception when creating with an invalid callable - */ - public function testRouteThrowsExecptionWithInvalidCallable() + public function testGetCallableAsStaticMethod() { - $this->setExpectedException('InvalidArgumentException'); - $route = new \Slim\Route('/foo/bar', 'fnDoesNotExist'); + $route = new \Slim\Route('/bar', '\Slim\Slim::getInstance'); + + $callable = $route->getCallable(); + $this->assertEquals('\Slim\Slim::getInstance', $callable); } - /** - * Route should throw exception when setting an invalid callable - */ - public function testRouteThrowsExecptionWhenSettingInvalidCallable() + public function testSetCallable() { - $route = new \Slim\Route('/foo/bar', function () {}); - try - { - $route->setCallable('fnDoesNotExist'); - $this->fail('Did not catch InvalidArgumentException when setting invalid callable'); - } catch(\InvalidArgumentException $e) {} + $callable = function () { + echo 'Foo'; + }; + $route = new \Slim\Route('/foo', $callable); // <-- Called inside __construct() + + $this->assertAttributeSame($callable, 'callable', $route); } - /** - * Test gets all params - */ - public function testGetRouteParams() + public function testSetCallableWithInvalidArgument() + { + $this->setExpectedException('\InvalidArgumentException'); + $route = new \Slim\Route('/foo', 'doesNotExist'); // <-- Called inside __construct() + } + + public function testGetParams() { - // Prepare route - $requestUri = '/hello/mr/anderson'; $route = new \Slim\Route('/hello/:first/:last', function () {}); + $route->matches('/hello/mr/anderson'); // <-- Parses params from argument - // Parse route params - $this->assertTrue($route->matches($requestUri)); - - // Get params - $params = $route->getParams(); - $this->assertEquals(2, count($params)); - $this->assertEquals('mr', $params['first']); - $this->assertEquals('anderson', $params['last']); + $this->assertEquals(array( + 'first' => 'mr', + 'last' => 'anderson' + ), $route->getParams()); } - /** - * Test sets all params - */ - public function testSetRouteParams() + public function testSetParams() { - // Prepare route - $requestUri = '/hello/mr/anderson'; $route = new \Slim\Route('/hello/:first/:last', function () {}); - - // Parse route params - $this->assertTrue($route->matches($requestUri)); - - // Get params - $params = $route->getParams(); - $this->assertEquals(2, count($params)); - $this->assertEquals('mr', $params['first']); - $this->assertEquals('anderson', $params['last']); - - // Replace params + $route->matches('/hello/mr/anderson'); // <-- Parses params from argument $route->setParams(array( - 'first' => 'john', + 'first' => 'agent', 'last' => 'smith' )); - // Get new params - $params = $route->getParams(); - $this->assertEquals(2, count($params)); - $this->assertEquals('john', $params['first']); - $this->assertEquals('smith', $params['last']); + $this->assertAttributeEquals(array( + 'first' => 'agent', + 'last' => 'smith' + ), 'params', $route); } - /** - * Test gets param when exists - */ - public function testGetRouteParamWhenExists() + public function testGetParam() { - // Prepare route - $requestUri = '/hello/mr/anderson'; $route = new \Slim\Route('/hello/:first/:last', function () {}); - // Parse route params - $this->assertTrue($route->matches($requestUri)); + $property = new \ReflectionProperty($route, 'params'); + $property->setAccessible(true); + $property->setValue($route, array( + 'first' => 'foo', + 'last' => 'bar' + )); - // Get param - $this->assertEquals('anderson', $route->getParam('last')); + $this->assertEquals('foo', $route->getParam('first')); } - /** - * Test gets param when not exists - */ - public function testGetRouteParamWhenNotExists() + public function testGetParamThatDoesNotExist() { - // Prepare route - $requestUri = '/hello/mr/anderson'; + $this->setExpectedException('InvalidArgumentException'); + $route = new \Slim\Route('/hello/:first/:last', function () {}); - // Parse route params - $this->assertTrue($route->matches($requestUri)); + $property = new \ReflectionProperty($route, 'params'); + $property->setAccessible(true); + $property->setValue($route, array( + 'first' => 'foo', + 'last' => 'bar' + )); - // Get param - try { - $param = $route->getParam('foo'); - $this->fail('Did not catch expected InvalidArgumentException'); - } catch ( \InvalidArgumentException $e ) {} + $route->getParam('middle'); } - /** - * Test sets param when exists - */ - public function testSetRouteParamWhenExists() + public function testSetParam() { - // Prepare route - $requestUri = '/hello/mr/anderson'; $route = new \Slim\Route('/hello/:first/:last', function () {}); - - // Parse route params - $this->assertTrue($route->matches($requestUri)); - - // Get param - $this->assertEquals('anderson', $route->getParam('last')); - - // Set param + $route->matches('/hello/mr/anderson'); // <-- Parses params from argument $route->setParam('last', 'smith'); - // Get new param - $this->assertEquals('smith', $route->getParam('last')); + $this->assertAttributeEquals(array( + 'first' => 'mr', + 'last' => 'smith' + ), 'params', $route); } - /** - * Test sets param when not exists - */ - public function testSetRouteParamWhenNotExists() + public function testSetParamThatDoesNotExist() { - // Prepare route - $requestUri = '/hello/mr/anderson'; + $this->setExpectedException('InvalidArgumentException'); + $route = new \Slim\Route('/hello/:first/:last', function () {}); - - // Parse route params - $this->assertTrue($route->matches($requestUri)); - - // Get param - try { - $param = $route->setParam('foo', 'bar'); - $this->fail('Did not catch expected InvalidArgumentException'); - } catch ( \InvalidArgumentException $e ) {} + $route->matches('/hello/mr/anderson'); // <-- Parses params from argument + $route->setParam('middle', 'smith'); // <-- Should trigger InvalidArgumentException } - /** - * If route matches a resource URI, param should be extracted. - */ - public function testRouteMatchesAndParamExtracted() + public function testMatches() { - $resource = '/hello/Josh'; $route = new \Slim\Route('/hello/:name', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('name' => 'Josh'), $route->getParams()); + + $this->assertTrue($route->matches('/hello/josh')); } - /** - * If route matches a resource URI, multiple params should be extracted. - */ - public function testRouteMatchesAndMultipleParamsExtracted() + public function testMatchesIsFalse() + { + $route = new \Slim\Route('/foo', function () {}); + + $this->assertFalse($route->matches('/bar')); + } + + public function testMatchesPatternWithTrailingSlash() + { + $route = new \Slim\Route('/foo/', function () {}); + + $this->assertTrue($route->matches('/foo/')); + $this->assertTrue($route->matches('/foo')); + } + + public function testMatchesPatternWithoutTrailingSlash() + { + $route = new \Slim\Route('/foo', function () {}); + + $this->assertFalse($route->matches('/foo/')); + $this->assertTrue($route->matches('/foo')); + } + + public function testMatchesWithConditions() { - $resource = '/hello/Josh/and/John'; $route = new \Slim\Route('/hello/:first/and/:second', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('first' => 'Josh', 'second' => 'John'), $route->getParams()); + $route->conditions(array( + 'first' => '[a-zA-Z]{3,}' + )); + + $this->assertTrue($route->matches('/hello/Josh/and/John')); } - /** - * If route does not match a resource URI, params remain an empty array - */ - public function testRouteDoesNotMatchAndParamsNotExtracted() + public function testMatchesWithConditionsIsFalse() { - $resource = '/foo/bar'; - $route = new \Slim\Route('/hello/:name', function () {}); - $result = $route->matches($resource); - $this->assertFalse($result); - $this->assertEquals(array(), $route->getParams()); - } - - /** - * Route matches URI with trailing slash - * - */ - public function testRouteMatchesWithTrailingSlash() - { - $resource1 = '/foo/bar/'; - $resource2 = '/foo/bar'; - $route = new \Slim\Route('/foo/:one/', function () {}); - $this->assertTrue($route->matches($resource1)); - $this->assertTrue($route->matches($resource2)); - } - - /** - * Route matches URI with conditions - */ - public function testRouteMatchesResourceWithConditions() - { - $resource = '/hello/Josh/and/John'; $route = new \Slim\Route('/hello/:first/and/:second', function () {}); - $route->conditions(array('first' => '[a-zA-Z]{3,}')); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('first' => 'Josh', 'second' => 'John'), $route->getParams()); - } + $route->conditions(array( + 'first' => '[a-z]{3,}' + )); - /** - * Route does not match URI with conditions - */ - public function testRouteDoesNotMatchResourceWithConditions() - { - $resource = '/hello/Josh/and/John'; - $route = new \Slim\Route('/hello/:first/and/:second', function () {}); - $route->conditions(array('first' => '[a-z]{3,}')); - $result = $route->matches($resource); - $this->assertFalse($result); - $this->assertEquals(array(), $route->getParams()); + $this->assertFalse($route->matches('/hello/Josh/and/John')); } /* @@ -324,14 +234,12 @@ class RouteTest extends PHPUnit_Framework_TestCase * * Excludes "+" which is valid but decodes into a space character */ - public function testRouteMatchesResourceWithValidRfc2396PathComponent() + public function testMatchesWithValidRfc2396PathComponent() { $symbols = ':@&=$,'; - $resource = '/rfc2386/' . $symbols; $route = new \Slim\Route('/rfc2386/:symbols', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('symbols' => $symbols), $route->getParams()); + + $this->assertTrue($route->matches('/rfc2386/' . $symbols)); } /* @@ -339,221 +247,289 @@ class RouteTest extends PHPUnit_Framework_TestCase * * "Uniform Resource Identifiers (URI): Generic Syntax" http://www.ietf.org/rfc/rfc2396.txt */ - public function testRouteMatchesResourceWithUnreservedMarks() + public function testMatchesWithUnreservedMarks() { $marks = "-_.!~*'()"; - $resource = '/marks/' . $marks; $route = new \Slim\Route('/marks/:marks', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('marks' => $marks), $route->getParams()); + + $this->assertTrue($route->matches('/marks/' . $marks)); } - /** - * Route optional parameters - * - * Pre-conditions: - * Route pattern requires :year, optionally accepts :month and :day - * - * Post-conditions: - * All: Year is 2010 - * Case A: Month and day default values are used - * Case B: Month is "05" and day default value is used - * Case C: Month is "05" and day is "13" - */ - public function testRouteOptionalParameters() + public function testMatchesOptionalParameters() { $pattern = '/archive/:year(/:month(/:day))'; - //Case A - $routeA = new \Slim\Route($pattern, function () {}); - $resourceA = '/archive/2010'; - $resultA = $routeA->matches($resourceA); - $this->assertTrue($resultA); - $this->assertEquals(array('year' => '2010'), $routeA->getParams()); + $route1 = new \Slim\Route($pattern, function () {}); + $this->assertTrue($route1->matches('/archive/2010')); + $this->assertEquals(array('year' => '2010'), $route1->getParams()); - //Case B - $routeB = new \Slim\Route($pattern, function () {}); - $resourceB = '/archive/2010/05'; - $resultB = $routeB->matches($resourceB); - $this->assertTrue($resultB); - $this->assertEquals(array('year' => '2010', 'month' => '05'), $routeB->getParams()); + $route2 = new \Slim\Route($pattern, function () {}); + $this->assertTrue($route2->matches('/archive/2010/05')); + $this->assertEquals(array('year' => '2010', 'month' => '05'), $route2->getParams()); - //Case C - $routeC = new \Slim\Route($pattern, function () {}); - $resourceC = '/archive/2010/05/13'; - $resultC = $routeC->matches($resourceC); - $this->assertTrue($resultC); - $this->assertEquals(array('year' => '2010', 'month' => '05', 'day' => '13'), $routeC->getParams()); + $route3 = new \Slim\Route($pattern, function () {}); + $this->assertTrue($route3->matches('/archive/2010/05/13')); + $this->assertEquals(array('year' => '2010', 'month' => '05', 'day' => '13'), $route3->getParams()); } - /** - * Test route default conditions - * - * Pre-conditions: - * Route class has default conditions; - * - * Post-conditions: - * Case A: Route instance has default conditions; - * Case B: Route instance has newly merged conditions; - */ - public function testRouteDefaultConditions() + public function testGetConditions() { - \Slim\Route::setDefaultConditions(array('id' => '\d+')); - $r = new \Slim\Route('/foo', function () {}); - //Case A - $this->assertEquals(\Slim\Route::getDefaultConditions(), $r->getConditions()); - //Case B - $r->conditions(array('name' => '[a-z]{2,5}')); - $c = $r->getConditions(); - $this->assertArrayHasKey('id', $c); - $this->assertArrayHasKey('name', $c); + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'conditions'); + $property->setAccessible(true); + $property->setValue($route, array('foo' => '\d{3}')); + + $this->assertEquals(array('foo' => '\d{3}'), $route->getConditions()); } - /** - * Route matches URI with wildcard - */ - public function testRouteMatchesResourceWithWildcard() + public function testSetDefaultConditions() + { + \Slim\Route::setDefaultConditions(array( + 'id' => '\d+' + )); + + $property = new \ReflectionProperty('\Slim\Route', 'defaultConditions'); + $property->setAccessible(true); + + $this->assertEquals(array( + 'id' => '\d+' + ), $property->getValue()); + } + + public function testGetDefaultConditions() + { + $property = new \ReflectionProperty('\Slim\Route', 'defaultConditions'); + $property->setAccessible(true); + $property->setValue(array( + 'id' => '\d+' + )); + + $this->assertEquals(array( + 'id' => '\d+' + ), \Slim\Route::getDefaultConditions()); + } + + public function testDefaultConditionsAssignedToInstance() + { + $staticProperty = new \ReflectionProperty('\Slim\Route', 'defaultConditions'); + $staticProperty->setAccessible(true); + $staticProperty->setValue(array( + 'id' => '\d+' + )); + $route = new \Slim\Route('/foo', function () {}); + + $this->assertAttributeEquals(array( + 'id' => '\d+' + ), 'conditions', $route); + } + + public function testMatchesWildcard() { - $resource = '/hello/foo/bar/world'; $route = new \Slim\Route('/hello/:path+/world', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('path'=>array('foo', 'bar')), $route->getParams()); + + $this->assertTrue($route->matches('/hello/foo/bar/world')); + $this->assertAttributeEquals(array( + 'path' => array('foo', 'bar') + ), 'params', $route); } - /** - * Route matches URI with more than one wildcard - */ - public function testRouteMatchesResourceWithMultipleWildcards() + public function testMatchesMultipleWildcards() { - $resource = '/hello/foo/bar/world/2012/03/10'; $route = new \Slim\Route('/hello/:path+/world/:date+', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('path'=>array('foo', 'bar'), 'date'=>array('2012', '03', '10')), $route->getParams()); + + $this->assertTrue($route->matches('/hello/foo/bar/world/2012/03/10')); + $this->assertAttributeEquals(array( + 'path' => array('foo', 'bar'), + 'date' => array('2012', '03', '10') + ), 'params', $route); } - /** - * Route matches URI with wildcards and parameters - */ - public function testRouteMatchesResourceWithWildcardsAndParams() + public function testMatchesParamsAndWildcards() { - $resource = '/hello/foo/bar/world/2012/03/10/first/second'; $route = new \Slim\Route('/hello/:path+/world/:year/:month/:day/:path2+', function () {}); - $result = $route->matches($resource); - $this->assertTrue($result); - $this->assertEquals(array('path'=>array('foo', 'bar'), 'year'=>'2012', 'month'=>'03', 'day'=>'10', 'path2'=>array('first', 'second')), $route->getParams()); + + $this->assertTrue($route->matches('/hello/foo/bar/world/2012/03/10/first/second')); + $this->assertAttributeEquals(array( + 'path' => array('foo', 'bar'), + 'year' => '2012', + 'month' => '03', + 'day' => '10', + 'path2' => array('first', 'second') + ), 'params', $route); + } + + public function testMatchesParamsWithOptionalWildcard() + { + $route = new \Slim\Route('/hello(/:foo(/:bar+))', function () {}); + + $this->assertTrue($route->matches('/hello')); + $this->assertTrue($route->matches('/hello/world')); + $this->assertTrue($route->matches('/hello/world/foo')); + $this->assertTrue($route->matches('/hello/world/foo/bar')); + } + + public function testSetMiddleware() + { + $route = new \Slim\Route('/foo', function () {}); + $mw = function () { + echo 'Foo'; + }; + $route->setMiddleware($mw); + + $this->assertAttributeContains($mw, 'middleware', $route); + } + + public function testSetMiddlewareMultipleTimes() + { + $route = new \Slim\Route('/foo', function () {}); + $mw1 = function () { + echo 'Foo'; + }; + $mw2 = function () { + echo 'Bar'; + }; + $route->setMiddleware($mw1); + $route->setMiddleware($mw2); + + $this->assertAttributeContains($mw1, 'middleware', $route); + $this->assertAttributeContains($mw2, 'middleware', $route); + } + + public function testSetMiddlewareWithArray() + { + $route = new \Slim\Route('/foo', function () {}); + $mw1 = function () { + echo 'Foo'; + }; + $mw2 = function () { + echo 'Bar'; + }; + $route->setMiddleware(array($mw1, $mw2)); + + $this->assertAttributeContains($mw1, 'middleware', $route); + $this->assertAttributeContains($mw2, 'middleware', $route); + } + + public function testSetMiddlewareWithInvalidArgument() + { + $this->setExpectedException('InvalidArgumentException'); + + $route = new \Slim\Route('/foo', function () {}); + $route->setMiddleware('doesNotExist'); // <-- Should throw InvalidArgumentException + } + + public function testSetMiddlewareWithArrayWithInvalidArgument() + { + $this->setExpectedException('InvalidArgumentException'); + + $route = new \Slim\Route('/foo', function () {}); + $route->setMiddleware(array('doesNotExist')); + } + + public function testGetMiddleware() + { + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'middleware'); + $property->setAccessible(true); + $property->setValue($route, array('foo' => 'bar')); + + $this->assertEquals(array('foo' => 'bar'), $route->getMiddleware()); + } + + public function testSetHttpMethods() + { + $route = new \Slim\Route('/foo', function () {}); + $route->setHttpMethods('GET', 'POST'); + + $this->assertAttributeEquals(array('GET', 'POST'), 'methods', $route); + } + + public function testGetHttpMethods() + { + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'methods'); + $property->setAccessible(true); + $property->setValue($route, array('GET', 'POST')); + + $this->assertEquals(array('GET', 'POST'), $route->getHttpMethods()); + } + + public function testAppendHttpMethods() + { + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'methods'); + $property->setAccessible(true); + $property->setValue($route, array('GET', 'POST')); + + $route->appendHttpMethods('PUT'); + + $this->assertAttributeEquals(array('GET', 'POST', 'PUT'), 'methods', $route); + } + + public function testAppendHttpMethodsWithVia() + { + $route = new \Slim\Route('/foo', function () {}); + $route->via('PUT'); + + $this->assertAttributeContains('PUT', 'methods', $route); + } + + public function testSupportsHttpMethod() + { + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($route, 'methods'); + $property->setAccessible(true); + $property->setValue($route, array('POST')); + + $this->assertTrue($route->supportsHttpMethod('POST')); + $this->assertFalse($route->supportsHttpMethod('PUT')); } /** - * Route matches URI with optional wildcard and parameter + * Test dispatch with params */ - public function testRouteMatchesResourceWithOptionalWildcardsAndParams() + public function testDispatch() { - $resourceA = '/hello/world/foo/bar'; - $routeA = new \Slim\Route('/hello(/:world(/:path+))', function () {}); - $this->assertTrue($routeA->matches($resourceA)); - $this->assertEquals(array('world'=>'world', 'path'=>array('foo', 'bar')), $routeA->getParams()); - - $resourceB = '/hello/world'; - $routeB = new \Slim\Route('/hello(/:world(/:path))', function () {}); - $this->assertTrue($routeB->matches($resourceB)); - $this->assertEquals(array('world'=>'world'), $routeB->getParams()); + $this->expectOutputString('Hello josh'); + $route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; }); + $route->matches('/hello/josh'); //<-- Extracts params from resource URI + $route->dispatch(); } /** - * Route does not match URI with wildcard + * Test dispatch with middleware */ - public function testRouteDoesNotMatchResourceWithWildcard() + public function testDispatchWithMiddleware() { - $resource = '/hello'; - $route = new \Slim\Route('/hello/:path+', function () {}); - $result = $route->matches($resource); - $this->assertFalse($result); - $this->assertEquals(array(), $route->getParams()); + $this->expectOutputString('First! Second! Hello josh'); + $route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; }); + $route->setMiddleware(function () { + echo "First! "; + }); + $route->setMiddleware(function () { + echo "Second! "; + }); + $route->matches('/hello/josh'); //<-- Extracts params from resource URI + $route->dispatch(); } /** - * Test route sets and gets middleware - * - * Pre-conditions: - * Route instantiated - * - * Post-conditions: - * Case A: Middleware set as callable, not array - * Case B: Middleware set after other middleware already set - * Case C: Middleware set as array of callables - * Case D: Middleware set as a callable array - * Case E: Middleware is invalid; throws InvalidArgumentException - * Case F: Middleware is an array with one invalid callable; throws InvalidArgumentException + * Test middleware with arguments */ - public function testRouteMiddleware() + public function testRouteMiddlwareArguments() { - $callable1 = function () {}; - $callable2 = function () {}; - //Case A - $r1 = new \Slim\Route('/foo', function () {}); - $r1->setMiddleware($callable1); - $mw = $r1->getMiddleware(); - $this->assertInternalType('array', $mw); - $this->assertEquals(1, count($mw)); - //Case B - $r1->setMiddleware($callable2); - $mw = $r1->getMiddleware(); - $this->assertEquals(2, count($mw)); - //Case C - $r2 = new \Slim\Route('/foo', function () {}); - $r2->setMiddleware(array($callable1, $callable2)); - $mw = $r2->getMiddleware(); - $this->assertInternalType('array', $mw); - $this->assertEquals(2, count($mw)); - //Case D - $r3 = new \Slim\Route('/foo', function () {}); - $r3->setMiddleware(array($this, 'callableTestFunction')); - $mw = $r3->getMiddleware(); - $this->assertInternalType('array', $mw); - $this->assertEquals(1, count($mw)); - //Case E - try { - $r3->setMiddleware('sdjfsoi788'); - $this->fail('Did not catch InvalidArgumentException when setting invalid route middleware'); - } catch ( \InvalidArgumentException $e ) {} - //Case F - try { - $r3->setMiddleware(array($callable1, $callable2, 'sdjfsoi788')); - $this->fail('Did not catch InvalidArgumentException when setting an array with one invalid route middleware'); - } catch ( \InvalidArgumentException $e ) {} - } - - public function callableTestFunction() {} - - /** - * Test that a Route manages the HTTP methods that it supports - * - * Case A: Route initially supports no HTTP methods - * Case B: Route can set its supported HTTP methods - * Case C: Route can append supported HTTP methods - * Case D: Route can test if it supports an HTTP method - * Case E: Route can lazily declare supported HTTP methods with `via` - */ - public function testHttpMethods() - { - //Case A - $r = new \Slim\Route('/foo', function () {}); - $this->assertEmpty($r->getHttpMethods()); - //Case B - $r->setHttpMethods('GET'); - $this->assertEquals(array('GET'), $r->getHttpMethods()); - //Case C - $r->appendHttpMethods('POST', 'PUT'); - $this->assertEquals(array('GET', 'POST', 'PUT'), $r->getHttpMethods()); - //Case D - $this->assertTrue($r->supportsHttpMethod('GET')); - $this->assertFalse($r->supportsHttpMethod('DELETE')); - //Case E - $viaResult = $r->via('DELETE'); - $this->assertTrue($viaResult instanceof \Slim\Route); - $this->assertTrue($r->supportsHttpMethod('DELETE')); + $this->expectOutputString('foobar'); + $route = new \Slim\Route('/foo', function () { echo "bar"; }); + $route->setName('foo'); + $route->setMiddleware(function ($route) { + echo $route->getName(); + }); + $route->matches('/foo'); //<-- Extracts params from resource URI + $route->dispatch(); } } diff --git a/vendor/slim/slim/tests/RouterTest.php b/vendor/slim/slim/tests/RouterTest.php index cb5cc33f11..a128b2343d 100644 --- a/vendor/slim/slim/tests/RouterTest.php +++ b/vendor/slim/slim/tests/RouterTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -32,571 +32,219 @@ class RouterTest extends PHPUnit_Framework_TestCase { - protected $env; - protected $req; - protected $res; - - public function setUp() + /** + * Constructor should initialize routes as empty array + */ + public function testConstruct() { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/bar', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); + $router = new \Slim\Router(); + + $this->assertAttributeEquals(array(), 'routes', $router); } /** - * Router::urlFor should return a full route pattern - * even if no params data is provided. + * Map should set and return instance of \Slim\Route */ - public function testUrlForNamedRouteWithoutParams() + public function testMap() { $router = new \Slim\Router(); - $route = $router->map('/foo/bar', function () {})->via('GET'); + $route = new \Slim\Route('/foo', function() {}); + $router->map($route); + + $this->assertAttributeContains($route, 'routes', $router); + } + + /** + * Named route should be added and indexed by name + */ + public function testAddNamedRoute() + { + $router = new \Slim\Router(); + $route = new \Slim\Route('/foo', function () {}); $router->addNamedRoute('foo', $route); - $this->assertEquals('/foo/bar', $router->urlFor('foo')); + + $property = new \ReflectionProperty($router, 'namedRoutes'); + $property->setAccessible(true); + + $rV = $property->getValue($router); + $this->assertSame($route, $rV['foo']); } /** - * Router::urlFor should return a full route pattern if - * param data is provided. + * Named route should have unique name */ - public function testUrlForNamedRouteWithParams() + public function testAddNamedRouteWithDuplicateKey() { + $this->setExpectedException('RuntimeException'); + $router = new \Slim\Router(); - $route = $router->map('/foo/:one/and/:two', function ($one, $two) {})->via('GET'); + $route = new \Slim\Route('/foo', function () {}); + $router->addNamedRoute('foo', $route); $router->addNamedRoute('foo', $route); - $this->assertEquals('/foo/Josh/and/John', $router->urlFor('foo', array('one' => 'Josh', 'two' => 'John'))); } /** - * Router::urlFor should throw an exception if Route with name - * does not exist. - * @expectedException \RuntimeException + * Router should return named route by name, or null if not found */ - public function testUrlForNamedRouteThatDoesNotExist() + public function testGetNamedRoute() { $router = new \Slim\Router(); - $route = $router->map('/foo/bar', function () {})->via('GET'); - $router->addNamedRoute('bar', $route); - $router->urlFor('foo'); + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($router, 'namedRoutes'); + $property->setAccessible(true); + $property->setValue($router, array('foo' => $route)); + + $this->assertSame($route, $router->getNamedRoute('foo')); + $this->assertNull($router->getNamedRoute('bar')); } /** - * Router::addNamedRoute should throw an exception if named Route - * with same name already exists. + * Router should determine named routes and cache results */ - public function testNamedRouteWithExistingName() + public function testGetNamedRoutes() { - $this->setExpectedException('\RuntimeException'); $router = new \Slim\Router(); - $route1 = $router->map('/foo/bar', function () {})->via('GET'); - $route2 = $router->map('/foo/bar/2', function () {})->via('GET'); - $router->addNamedRoute('bar', $route1); - $router->addNamedRoute('bar', $route2); + $route1 = new \Slim\Route('/foo', function () {}); + $route2 = new \Slim\Route('/bar', function () {}); + + // Init router routes to array + $propertyRouterRoutes = new \ReflectionProperty($router, 'routes'); + $propertyRouterRoutes->setAccessible(true); + $propertyRouterRoutes->setValue($router, array($route1, $route2)); + + // Init router named routes to null + $propertyRouterNamedRoutes = new \ReflectionProperty($router, 'namedRoutes'); + $propertyRouterNamedRoutes->setAccessible(true); + $propertyRouterNamedRoutes->setValue($router, null); + + // Init route name + $propertyRouteName = new \ReflectionProperty($route2, 'name'); + $propertyRouteName->setAccessible(true); + $propertyRouteName->setValue($route2, 'bar'); + + $namedRoutes = $router->getNamedRoutes(); + $this->assertCount(1, $namedRoutes); + $this->assertSame($route2, $namedRoutes['bar']); } /** - * Test if named route exists - * - * Pre-conditions: - * Slim app instantiated; - * Named route created; - * - * Post-conditions: - * Named route found to exist; - * Non-existant route found not to exist; + * Router should detect presence of a named route by name */ public function testHasNamedRoute() { $router = new \Slim\Router(); - $route = $router->map('/foo', function () {})->via('GET'); - $router->addNamedRoute('foo', $route); + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($router, 'namedRoutes'); + $property->setAccessible(true); + $property->setValue($router, array('foo' => $route)); + $this->assertTrue($router->hasNamedRoute('foo')); $this->assertFalse($router->hasNamedRoute('bar')); } /** - * Test Router gets named route - * - * Pre-conditions; - * Slim app instantiated; - * Named route created; - * - * Post-conditions: - * Named route fetched by named; - * NULL is returned if named route does not exist; - */ - public function testGetNamedRoute() - { - $router = new \Slim\Router(); - $route1 = $router->map('/foo', function () {})->via('GET'); - $router->addNamedRoute('foo', $route1); - $this->assertSame($route1, $router->getNamedRoute('foo')); - $this->assertNull($router->getNamedRoute('bar')); - } - - /** - * Test external iterator for Router's named routes - * - * Pre-conditions: - * Slim app instantiated; - * Named routes created; - * - * Post-conditions: - * Array iterator returned for named routes; - */ - public function testGetNamedRoutes() - { - $router = new \Slim\Router(); - $route1 = $router->map('/foo', function () {})->via('GET'); - $route2 = $router->map('/bar', function () {})->via('POST'); - $router->addNamedRoute('foo', $route1); - $router->addNamedRoute('bar', $route2); - $namedRoutesIterator = $router->getNamedRoutes(); - $this->assertInstanceOf('ArrayIterator', $namedRoutesIterator); - $this->assertEquals(2, $namedRoutesIterator->count()); - } - - /** - * Router considers HEAD requests as GET requests - */ - public function testRouterConsidersHeadAsGet() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'HEAD', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/bar', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); - $router = new \Slim\Router(); - $route = $router->map('/bar', function () {})->via('GET', 'HEAD'); - $numberOfMatchingRoutes = count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())); - $this->assertEquals(1, $numberOfMatchingRoutes); - } - - /** - * Router::urlFor - */ - public function testRouterUrlFor() - { - $router = new \Slim\Router(); - $route1 = $router->map('/foo/bar', function () {})->via('GET'); - $route2 = $router->map('/foo/:one/:two', function () {})->via('GET'); - $route3 = $router->map('/foo/:one(/:two)', function () {})->via('GET'); - $route4 = $router->map('/foo/:one/(:two/)', function () {})->via('GET'); - $route5 = $router->map('/foo/:one/(:two/(:three/))', function () {})->via('GET'); - $route6 = $router->map('/foo/:path+/bar', function (){})->via('GET'); - $route7 = $router->map('/foo/:path+/:path2+/bar', function (){})->via('GET'); - $route8 = $router->map('/foo/:path+', function (){})->via('GET'); - $route9 = $router->map('/foo/:var/:var2', function (){})->via('GET'); - $route1->setName('route1'); - $route2->setName('route2'); - $route3->setName('route3'); - $route4->setName('route4'); - $route5->setName('route5'); - $route6->setName('route6'); - $route7->setName('route7'); - $route8->setName('route8'); - $route9->setName('route9'); - //Route - $this->assertEquals('/foo/bar', $router->urlFor('route1')); - //Route with params - $this->assertEquals('/foo/foo/bar', $router->urlFor('route2', array('one' => 'foo', 'two' => 'bar'))); - $this->assertEquals('/foo/foo/:two', $router->urlFor('route2', array('one' => 'foo'))); - $this->assertEquals('/foo/:one/bar', $router->urlFor('route2', array('two' => 'bar'))); - //Route with params and optional segments - $this->assertEquals('/foo/foo/bar', $router->urlFor('route3', array('one' => 'foo', 'two' => 'bar'))); - $this->assertEquals('/foo/foo', $router->urlFor('route3', array('one' => 'foo'))); - $this->assertEquals('/foo/:one/bar', $router->urlFor('route3', array('two' => 'bar'))); - $this->assertEquals('/foo/:one', $router->urlFor('route3')); - //Route with params and optional segments - $this->assertEquals('/foo/foo/bar/', $router->urlFor('route4', array('one' => 'foo', 'two' => 'bar'))); - $this->assertEquals('/foo/foo/', $router->urlFor('route4', array('one' => 'foo'))); - $this->assertEquals('/foo/:one/bar/', $router->urlFor('route4', array('two' => 'bar'))); - $this->assertEquals('/foo/:one/', $router->urlFor('route4')); - //Route with params and optional segments - $this->assertEquals('/foo/foo/bar/what/', $router->urlFor('route5', array('one' => 'foo', 'two' => 'bar', 'three' => 'what'))); - $this->assertEquals('/foo/foo/', $router->urlFor('route5', array('one' => 'foo'))); - $this->assertEquals('/foo/:one/bar/', $router->urlFor('route5', array('two' => 'bar'))); - $this->assertEquals('/foo/:one/bar/what/', $router->urlFor('route5', array('two' => 'bar', 'three' => 'what'))); - $this->assertEquals('/foo/:one/', $router->urlFor('route5')); - //Route with wildcard params - $this->assertEquals('/foo/bar/bar', $router->urlFor('route6', array('path'=>'bar'))); - $this->assertEquals('/foo/foo/bar/bar', $router->urlFor('route7', array('path'=>'foo', 'path2'=>'bar'))); - $this->assertEquals('/foo/bar', $router->urlFor('route8', array('path'=>'bar'))); - //Route with similar param names, test greedy matching - $this->assertEquals('/foo/1/2', $router->urlFor('route9', array('var2'=>'2', 'var'=>'1'))); - $this->assertEquals('/foo/1/2', $router->urlFor('route9', array('var'=>'1', 'var2'=>'2'))); - } - - /** - * Test that router returns no matches when neither HTTP method nor URI match. - */ - public function testRouterMatchesRoutesNone() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); - $router = new \Slim\Router(); - $router->map('/bar', function () {})->via('POST'); - $router->map('/foo', function () {})->via('POST'); - $router->map('/foo', function () {})->via('PUT'); - $router->map('/foo/bar/xyz', function () {})->via('DELETE'); - $this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri()))); - } - - /** - * Test that router returns no matches when HTTP method matches but URI does not. - */ - public function testRouterMatchesRoutesNoneWhenMethodMatchesUriDoesNot() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); - $router = new \Slim\Router(); - $router->map('/fooNOMATCH', function () {})->via('GET'); - $router->map('/foo', function () {})->via('POST'); - $router->map('/foo', function () {})->via('PUT'); - $router->map('/foo/bar/xyz', function () {})->via('DELETE'); - $this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri()))); - } - - /** - * Test that router returns no matches when HTTP method does not match but URI does. - */ - public function testRouterMatchesRoutesNoneWhenMethodDoesNotMatchUriMatches() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); - $router = new \Slim\Router(); - $router->map('/foo', function () {})->via('OPTIONS'); - $router->map('/foo', function () {})->via('POST'); - $router->map('/foo', function () {})->via('PUT'); - $router->map('/foo/bar/xyz', function () {})->via('DELETE'); - $this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri()))); - } - - /** - * Test that router returns matched routes based on HTTP method and URI. - */ - public function testRouterMatchesRoutes() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $this->env = \Slim\Environment::getInstance(); - $this->req = new \Slim\Http\Request($this->env); - $this->res = new \Slim\Http\Response(); - $router = new \Slim\Router(); - $router->map('/foo', function () {})->via('GET'); - $router->map('/foo', function () {})->via('POST'); - $router->map('/foo', function () {})->via('PUT'); - $router->map('/foo/bar/xyz', function () {})->via('DELETE'); - $this->assertEquals(1, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri()))); - } - - /** - * Test get current route + * Router should return current route if set during iteration */ public function testGetCurrentRoute() { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () { - echo "Foo"; - }); - $app->call(); - $this->assertSame($route2, $app->router()->getCurrentRoute()); - } - - /** - * Test calling get current route before routing doesn't cause errors - */ - public function testGetCurrentRouteBeforeRoutingDoesntError() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () { - echo "Foo"; - }); - - $app->router()->getCurrentRoute(); - - $app->call(); - } - - /** - * Test get current route before routing returns null - */ - public function testGetCurrentRouteBeforeRoutingReturnsNull() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () { - echo "Foo"; - }); - - $this->assertSame(null, $app->router()->getCurrentRoute()); - } - - /** - * Test get current route during slim.before.dispatch hook - */ - public function testGetCurrentRouteDuringBeforeDispatchHook() - { - $route = null; - - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $app->hook('slim.before.dispatch', function() use(&$route, $app) { - $route = $app->router()->getCurrentRoute(); - }); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () { - echo "Foo"; - }); - - $app->call(); - $this->assertSame($route2, $route); - } - - /** - * Test get current route during routing - */ - public function testGetCurrentRouteDuringRouting() - { - $route = null; - - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () use (&$route, $app) { - echo "Foo"; - $route = $app->router()->getCurrentRoute(); - }); - - $app->call(); - $this->assertSame($route2, $route); - } - - /** - * Test get current route after routing - */ - public function testGetCurrentRouteAfterRouting() - { - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $app = new \Slim\Slim(); - $route1 = $app->get('/bar', function () { - echo "Bar"; - }); - $route2 = $app->get('/foo', function () { - echo "Foo"; - }); - $app->call(); - $this->assertSame($route2, $app->router()->getCurrentRoute()); - } - - public function testDispatch() - { - $this->expectOutputString('Hello josh'); - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/hello/josh', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $env = \Slim\Environment::getInstance(); - $req = new \Slim\Http\Request($env); $router = new \Slim\Router(); - $route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; }); - $route->matches($req->getResourceUri()); //<-- Extracts params from resource URI - $router->dispatch($route); + $route = new \Slim\Route('/foo', function () {}); + + $property = new \ReflectionProperty($router, 'currentRoute'); + $property->setAccessible(true); + $property->setValue($router, $route); + + $this->assertSame($route, $router->getCurrentRoute()); } - public function testDispatchWithMiddlware() + /** + * Router should return first matching route if current route not set yet by iteration + */ + public function testGetCurrentRouteIfMatchedRoutes() { - $this->expectOutputString('First! Second! Hello josh'); - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/hello/josh', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $env = \Slim\Environment::getInstance(); - $req = new \Slim\Http\Request($env); $router = new \Slim\Router(); - $route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; }); - $route->setMiddleware(function () { - echo "First! "; - }); - $route->setMiddleware(function () { - echo "Second! "; - }); - $route->matches($req->getResourceUri()); //<-- Extracts params from resource URI - $router->dispatch($route); + $route = new \Slim\Route('/foo', function () {}); + + $propertyMatchedRoutes = new \ReflectionProperty($router, 'matchedRoutes'); + $propertyMatchedRoutes->setAccessible(true); + $propertyMatchedRoutes->setValue($router, array($route)); + + $propertyCurrentRoute = new \ReflectionProperty($router, 'currentRoute'); + $propertyCurrentRoute->setAccessible(true); + $propertyCurrentRoute->setValue($router, null); + + $this->assertSame($route, $router->getCurrentRoute()); } - public function testRouteMiddlwareArguments() + /** + * Router should return `null` if current route not set yet and there are no matching routes + */ + public function testGetCurrentRouteIfNoMatchedRoutes() { - $this->expectOutputString('foobar'); - \Slim\Environment::mock(array( - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/foo' //<-- Virtual - )); - $env = \Slim\Environment::getInstance(); - $req = new \Slim\Http\Request($env); $router = new \Slim\Router(); - $route = new \Slim\Route('/foo', function () { echo "bar"; }); - $route->setName('foo'); - $route->setMiddleware(function ($route) { - echo $route->getName(); - }); - $route->matches($req->getResourceUri()); //<-- Extracts params from resource URI - $router->dispatch($route); + + $propertyMatchedRoutes = new \ReflectionProperty($router, 'matchedRoutes'); + $propertyMatchedRoutes->setAccessible(true); + $propertyMatchedRoutes->setValue($router, array()); + + $propertyCurrentRoute = new \ReflectionProperty($router, 'currentRoute'); + $propertyCurrentRoute->setAccessible(true); + $propertyCurrentRoute->setValue($router, null); + + $this->assertNull($router->getCurrentRoute()); } - public function testDispatchWithoutCallable() + public function testGetMatchedRoutes() { - $this->setExpectedException('InvalidArgumentException'); - \Slim\Environment::mock(array( - 'REQUEST_METHOD' => 'GET', - 'REMOTE_ADDR' => '127.0.0.1', - 'SCRIPT_NAME' => '', //<-- Physical - 'PATH_INFO' => '/hello/josh', //<-- Virtual - 'QUERY_STRING' => 'one=1&two=2&three=3', - 'SERVER_NAME' => 'slim', - 'SERVER_PORT' => 80, - 'slim.url_scheme' => 'http', - 'slim.input' => '', - 'slim.errors' => fopen('php://stderr', 'w'), - 'HTTP_HOST' => 'slim' - )); - $env = \Slim\Environment::getInstance(); - $req = new \Slim\Http\Request($env); $router = new \Slim\Router(); - $route = new \Slim\Route('/hello/:name', 'foo'); // <-- Fail fast + + $route1 = new \Slim\Route('/foo', function () {}); + $route1 = $route1->via('GET'); + + $route2 = new \Slim\Route('/foo', function () {}); + $route2 = $route2->via('POST'); + + $route3 = new \Slim\Route('/bar', function () {}); + $route3 = $route3->via('PUT'); + + $routes = new \ReflectionProperty($router, 'routes'); + $routes->setAccessible(true); + $routes->setValue($router, array($route1, $route2, $route3)); + + $matchedRoutes = $router->getMatchedRoutes('GET', '/foo'); + $this->assertSame($route1, $matchedRoutes[0]); + } + + // Test url for named route + + public function testUrlFor() + { + $router = new \Slim\Router(); + + $route1 = new \Slim\Route('/hello/:first/:last', function () {}); + $route1 = $route1->via('GET')->name('hello'); + + $route2 = new \Slim\Route('/path/(:foo\.:bar)', function () {}); + $route2 = $route2->via('GET')->name('regexRoute'); + + $routes = new \ReflectionProperty($router, 'namedRoutes'); + $routes->setAccessible(true); + $routes->setValue($router, array( + 'hello' => $route1, + 'regexRoute' => $route2 + )); + + $this->assertEquals('/hello/Josh/Lockhart', $router->urlFor('hello', array('first' => 'Josh', 'last' => 'Lockhart'))); + $this->assertEquals('/path/Hello.Josh', $router->urlFor('regexRoute', array('foo' => 'Hello', 'bar' => 'Josh'))); + } + + public function testUrlForIfNoSuchRoute() + { + $this->setExpectedException('RuntimeException'); + + $router = new \Slim\Router(); + $router->urlFor('foo', array('abc' => '123')); } } diff --git a/vendor/slim/slim/tests/SlimTest.php b/vendor/slim/slim/tests/SlimTest.php index a1aa3ad761..3a0deb12cf 100644 --- a/vendor/slim/slim/tests/SlimTest.php +++ b/vendor/slim/slim/tests/SlimTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -33,7 +33,7 @@ //Mock custom view class CustomView extends \Slim\View { - public function render($template) { echo "Custom view"; } + public function render($template, $data = null) { echo "Custom view"; } } //Echo Logger @@ -371,6 +371,27 @@ class SlimTest extends PHPUnit_Framework_TestCase $this->assertSame($callable, $route->getCallable()); } + /** + * Test PATCH route + */ + public function testPatchRoute() + { + \Slim\Environment::mock(array( + 'REQUEST_METHOD' => 'PATCH', + 'SCRIPT_NAME' => '/foo', //<-- Physical + 'PATH_INFO' => '/bar', //<-- Virtual + )); + $s = new \Slim\Slim(); + $mw1 = function () { echo "foo"; }; + $mw2 = function () { echo "bar"; }; + $callable = function () { echo "xyz"; }; + $route = $s->patch('/bar', $mw1, $mw2, $callable); + $s->call(); + $this->assertEquals('foobarxyz', $s->response()->body()); + $this->assertEquals('/bar', $route->getPattern()); + $this->assertSame($callable, $route->getCallable()); + } + /** * Test DELETE route */ @@ -413,6 +434,51 @@ class SlimTest extends PHPUnit_Framework_TestCase $this->assertSame($callable, $route->getCallable()); } + /** + * Test route groups + */ + public function testRouteGroups() + { + \Slim\Environment::mock(array( + 'REQUEST_METHOD' => 'GET', + 'SCRIPT_NAME' => '/foo', //<-- Physical + 'PATH_INFO' => '/bar/baz', //<-- Virtual' + )); + $s = new \Slim\Slim(); + $mw1 = function () { echo "foo"; }; + $mw2 = function () { echo "bar"; }; + $callable = function () { echo "xyz"; }; + $s->group('/bar', $mw1, function () use ($s, $mw2, $callable) { + $s->get('/baz', $mw2, $callable); + }); + $s->call(); + $this->assertEquals('foobarxyz', $s->response()->body()); + } + + /* + * Test ANY route + */ + public function testAnyRoute() + { + $mw1 = function () { echo "foo"; }; + $mw2 = function () { echo "bar"; }; + $callable = function () { echo "xyz"; }; + $methods = array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'); + foreach ($methods as $i => $method) { + \Slim\Environment::mock(array( + 'REQUEST_METHOD' => $method, + 'SCRIPT_NAME' => '/foo', //<-- Physical + 'PATH_INFO' => '/bar', //<-- Virtual + )); + $s = new \Slim\Slim(); + $route = $s->any('/bar', $mw1, $mw2, $callable); + $s->call(); + $this->assertEquals('foobarxyz', $s->response()->body()); + $this->assertEquals('/bar', $route->getPattern()); + $this->assertSame($callable, $route->getCallable()); + } + } + /** * Test if route does NOT expect trailing slash and URL has one */ @@ -485,6 +551,16 @@ class SlimTest extends PHPUnit_Framework_TestCase * RENDERING ************************************************/ + /** + * Test template path is passed to view + */ + public function testViewGetsTemplatesPath() + { + $path = dirname(__FILE__) . '/templates'; + $s = new \Slim\Slim(array('templates.path' => $path)); + $this->assertEquals($s->view->getTemplatesDirectory(), $path); + } + /** * Test render with template and data */ @@ -545,7 +621,7 @@ class SlimTest extends PHPUnit_Framework_TestCase 'REQUEST_METHOD' => 'GET', 'SCRIPT_NAME' => '/foo', //<-- Physical 'PATH_INFO' => '/bar', //<-- Virtual - 'IF_MODIFIED_SINCE' => 'Sun, 03 Oct 2010 17:00:52 -0400', + 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 03 Oct 2010 21:00:52 GMT', )); $s = new \Slim\Slim(); $s->get('/bar', function () use ($s) { @@ -563,7 +639,7 @@ class SlimTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'SCRIPT_NAME' => '/foo', //<-- Physical 'PATH_INFO' => '/bar', //<-- Virtual - 'IF_MODIFIED_SINCE' => 'Sun, 03 Oct 2010 17:00:52 -0400', + 'IF_MODIFIED_SINCE' => 'Sun, 03 Oct 2010 21:00:52 GMT', )); $s = new \Slim\Slim(); $s->get('/bar', function () use ($s) { @@ -587,6 +663,25 @@ class SlimTest extends PHPUnit_Framework_TestCase $s->call(); } + /** + * Test Last Modified header format + */ + public function testLastModifiedHeaderFormat() + { + \Slim\Environment::mock(array( + 'SCRIPT_NAME' => '/foo', //<-- Physical + 'PATH_INFO' => '/bar', //<-- Virtual + )); + $s = new \Slim\Slim(); + $s->get('/bar', function () use ($s) { + $s->lastModified(1286139652); + }); + $s->call(); + list($status, $header, $body) = $s->response()->finalize(); + $this->assertTrue(isset($header['Last-Modified'])); + $this->assertEquals('Sun, 03 Oct 2010 21:00:52 GMT', $header['Last-Modified']); + } + /** * Test ETag matches */ @@ -595,7 +690,7 @@ class SlimTest extends PHPUnit_Framework_TestCase \Slim\Environment::mock(array( 'SCRIPT_NAME' => '/foo', //<-- Physical 'PATH_INFO' => '/bar', //<-- Virtual - 'IF_NONE_MATCH' => '"abc123"', + 'HTTP_IF_NONE_MATCH' => '"abc123"', )); $s = new \Slim\Slim(); $s->get('/bar', function () use ($s) { @@ -650,7 +745,7 @@ class SlimTest extends PHPUnit_Framework_TestCase 'SCRIPT_NAME' => '/foo', //<-- Physical 'PATH_INFO' => '/bar', //<-- Virtual )); - $expectedDate = gmdate('D, d M Y', strtotime('5 days')); //Just the day, month, and year + $expectedDate = gmdate('D, d M Y H:i:s T', strtotime('5 days')); $s = new \Slim\Slim(); $s->get('/bar', function () use ($s) { $s->expires('5 days'); @@ -658,7 +753,7 @@ class SlimTest extends PHPUnit_Framework_TestCase $s->call(); list($status, $header, $body) = $s->response()->finalize(); $this->assertTrue(isset($header['Expires'])); - $this->assertEquals(0, strpos($header['Expires'], $expectedDate)); + $this->assertEquals($header['Expires'], $expectedDate); } /** @@ -671,7 +766,7 @@ class SlimTest extends PHPUnit_Framework_TestCase 'PATH_INFO' => '/bar', //<-- Virtual )); $fiveDaysFromNow = time() + (60 * 60 * 24 * 5); - $expectedDate = gmdate('D, d M Y', $fiveDaysFromNow); //Just the day, month, and year + $expectedDate = gmdate('D, d M Y H:i:s T', $fiveDaysFromNow); $s = new \Slim\Slim(); $s->get('/bar', function () use ($s, $fiveDaysFromNow) { $s->expires($fiveDaysFromNow); @@ -679,7 +774,7 @@ class SlimTest extends PHPUnit_Framework_TestCase $s->call(); list($status, $header, $body) = $s->response()->finalize(); $this->assertTrue(isset($header['Expires'])); - $this->assertEquals(0, strpos($header['Expires'], $expectedDate)); + $this->assertEquals($header['Expires'], $expectedDate); } /************************************************ @@ -706,11 +801,11 @@ class SlimTest extends PHPUnit_Framework_TestCase $s->setCookie('foo1', 'bar1', '2 days'); }); $s->call(); - list($status, $header, $body) = $s->response()->finalize(); - $cookies = explode("\n", $header['Set-Cookie']); - $this->assertEquals(2, count($cookies)); - $this->assertEquals(1, preg_match('@foo=bar@', $cookies[0])); - $this->assertEquals(1, preg_match('@foo1=bar1@', $cookies[1])); + $cookie1 = $s->response->cookies->get('foo'); + $cookie2 = $s->response->cookies->get('foo1'); + $this->assertEquals(2, count($s->response->cookies)); + $this->assertEquals('bar', $cookie1['value']); + $this->assertEquals('bar1', $cookie2['value']); } /** @@ -730,7 +825,7 @@ class SlimTest extends PHPUnit_Framework_TestCase 'QUERY_STRING' => 'one=foo&two=bar', 'SERVER_NAME' => 'slimframework.com', 'SERVER_PORT' => 80, - 'COOKIE' => 'foo=bar; foo2=bar2', + 'HTTP_COOKIE' => 'foo=bar; foo2=bar2', 'slim.url_scheme' => 'http', 'slim.input' => '', 'slim.errors' => @fopen('php://stderr', 'w') @@ -773,60 +868,10 @@ class SlimTest extends PHPUnit_Framework_TestCase $s->deleteCookie('foo'); }); $s->call(); - list($status, $header, $body) = $s->response()->finalize(); - $cookies = explode("\n", $header['Set-Cookie']); - $this->assertEquals(1, count($cookies)); - $this->assertEquals(1, preg_match('@^foo=;@', $cookies[0])); - } - - /** - * Test set encrypted cookie - * - * This method ensures that the `Set-Cookie:` HTTP request - * header is set. The implementation is tested in a separate file. - */ - public function testSetEncryptedCookie() - { - $s = new \Slim\Slim(); - $s->setEncryptedCookie('foo', 'bar'); - $r = $s->response(); - $this->assertEquals(1, preg_match("@^foo=.+%7C.+%7C.+@", $r['Set-Cookie'])); //<-- %7C is a url-encoded pipe - } - - /** - * Test get encrypted cookie - * - * This only tests that this method runs without error. The implementation of - * fetching the encrypted cookie is tested separately. - */ - public function testGetEncryptedCookieAndDeletingIt() - { - \Slim\Environment::mock(array( - 'SCRIPT_NAME' => '/foo', //<-- Physical - 'PATH_INFO' => '/bar', //<-- Virtual - )); - $s = new \Slim\Slim(); - $r = $s->response(); - $this->assertFalse($s->getEncryptedCookie('foo')); - $this->assertEquals(1, preg_match("@foo=;.*@", $r['Set-Cookie'])); - } - - /** - * Test get encrypted cookie WITHOUT deleting it - * - * This only tests that this method runs without error. The implementation of - * fetching the encrypted cookie is tested separately. - */ - public function testGetEncryptedCookieWithoutDeletingIt() - { - \Slim\Environment::mock(array( - 'SCRIPT_NAME' => '/foo', //<-- Physical - 'PATH_INFO' => '/bar', //<-- Virtual - )); - $s = new \Slim\Slim(); - $r = $s->response(); - $this->assertFalse($s->getEncryptedCookie('foo', false)); - $this->assertEquals(0, preg_match("@foo=;.*@", $r['Set-Cookie'])); + $cookie = $s->response->cookies->get('foo'); + $this->assertEquals(1, count($s->response->cookies)); + $this->assertEquals('', $cookie['value']); + $this->assertLessThan(time(), $cookie['expires']); } /************************************************ @@ -1195,7 +1240,9 @@ class SlimTest extends PHPUnit_Framework_TestCase */ public function testSlimError() { - $s = new \Slim\Slim(); + $s = new \Slim\Slim(array( + "log.enabled" => false + )); $s->get('/bar', function () use ($s) { $s->error(); }); @@ -1215,13 +1262,13 @@ class SlimTest extends PHPUnit_Framework_TestCase public function testDefaultHandlerLogsTheErrorWhenDebugIsFalse() { $s = new \Slim\Slim(array('debug' => false)); + $s->container->singleton('log', function ($c) { + return new EchoErrorLogger(); + }); $s->get('/bar', function () use ($s) { throw new \InvalidArgumentException('my specific error message'); }); - $env = $s->environment(); - $env['slim.log'] = new EchoErrorLogger(); // <-- inject the fake logger - ob_start(); $s->run(); $output = ob_get_clean(); @@ -1276,7 +1323,8 @@ class SlimTest extends PHPUnit_Framework_TestCase public function testErrorWithMultipleApps() { $s1 = new \Slim\Slim(array( - 'debug' => false + 'debug' => false, + 'log.enabled' => false )); $s2 = new \Slim\Slim(); $s1->get('/bar', function () use ($s1) { @@ -1323,22 +1371,20 @@ class SlimTest extends PHPUnit_Framework_TestCase { $defaultErrorReporting = error_reporting(); - // Assert Slim ignores E_NOTICE errors + // Test 1 error_reporting(E_ALL ^ E_NOTICE); // <-- Report all errors EXCEPT notices try { - $this->assertTrue(\Slim\Slim::handleErrors(E_NOTICE, 'test error', 'Slim.php', 119)); + \Slim\Slim::handleErrors(E_NOTICE, 'test error', 'Slim.php', 119); } catch (\ErrorException $e) { $this->fail('Slim::handleErrors reported a disabled error level.'); } - // Assert Slim reports E_STRICT errors + // Test 2 error_reporting(E_ALL | E_STRICT); // <-- Report all errors, including E_STRICT try { \Slim\Slim::handleErrors(E_STRICT, 'test error', 'Slim.php', 119); $this->fail('Slim::handleErrors didn\'t report a enabled error level'); - } catch (\ErrorException $e) { - $this->assertEquals('test error', $e->getMessage()); - } + } catch (\ErrorException $e) {} error_reporting($defaultErrorReporting); } @@ -1357,8 +1403,8 @@ class SlimTest extends PHPUnit_Framework_TestCase * Slim should throw a Slim_Exception_Stop if error callback is not callable */ public function testErrorHandlerIfNotCallable() { - $this->setExpectedException('\Slim\Exception\Stop'); - $s = new \Slim\Slim(); + $this->setExpectedException('\Slim\Exception\Stop'); + $s = new \Slim\Slim(array("log.enabled" => false)); $errCallback = 'foo'; $s->error($errCallback); } @@ -1377,7 +1423,7 @@ class SlimTest extends PHPUnit_Framework_TestCase * Slim should throw a Slim_Exception_Stop if NotFound callback is not callable */ public function testNotFoundHandlerIfNotCallable() { - $this->setExpectedException('\Slim\Exception\Stop'); + $this->setExpectedException('\Slim\Exception\Stop'); $s = new \Slim\Slim(); $notFoundCallback = 'foo'; $s->notFound($notFoundCallback); @@ -1473,13 +1519,13 @@ class SlimTest extends PHPUnit_Framework_TestCase $this->assertEquals(array(array()), $app->getHooks('test.hook.one')); } - /** + /** * Test late static binding * * Pre-conditions: * Slim app is extended by Derived class and instantiated; * Derived class overrides the 'getDefaultSettings' function and adds an extra default config value - * Test that the new config value exists + * Test that the new config value exists * * Post-conditions: * Config value exists and is equal to expected value diff --git a/vendor/slim/slim/tests/ViewTest.php b/vendor/slim/slim/tests/ViewTest.php index d7f501cef8..e0f681db9a 100644 --- a/vendor/slim/slim/tests/ViewTest.php +++ b/vendor/slim/slim/tests/ViewTest.php @@ -6,7 +6,7 @@ * @copyright 2011 Josh Lockhart * @link http://www.slimframework.com * @license http://www.slimframework.com/license - * @version 2.2.0 + * @version 2.4.0 * * MIT LICENSE * @@ -32,164 +32,167 @@ class ViewTest extends PHPUnit_Framework_TestCase { - public function setUp() + public function testGetDataAll() { - $this->view = new \Slim\View(); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $prop->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + + $this->assertSame(array('foo' => 'bar'), $view->getData()); } - public function generateTestData() + public function testGetDataKeyExists() { - return array('a' => 1, 'b' => 2, 'c' => 3); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $prop->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + + $this->assertEquals('bar', $view->getData('foo')); } - /** - * Test initial View data is an empty array - * - * Pre-conditions: - * None - * - * Post-conditions: - * The View object's data attribute is an empty array - */ - public function testViewIsConstructedWithDataArray() + public function testGetDataKeyNotExists() { - $this->assertEquals(array(), $this->view->getData()); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $prop->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + + $this->assertNull($view->getData('abc')); } - /** - * Test View sets and gets data - * - * Pre-conditions: - * Case A: Set view data key/value - * Case B: Set view data as array - * Case C: Set view data with one argument that is not an array - * - * Post-conditions: - * Case A: Data key/value are set - * Case B: Data is set to array - * Case C: An InvalidArgumentException is thrown - */ - public function testViewSetAndGetData() + public function testSetDataKeyValue() { - //Case A - $this->view->setData('one', 1); - $this->assertEquals(1, $this->view->getData('one')); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $view->setData('foo', 'bar'); - //Case B - $data = array('foo' => 'bar', 'a' => 'A'); - $this->view->setData($data); - $this->assertSame($data, $this->view->getData()); - - //Case C - try { - $this->view->setData('foo'); - $this->fail('Setting View data with non-array single argument did not throw exception'); - } catch ( \InvalidArgumentException $e ) {} + $this->assertEquals(array('foo' => 'bar'), $prop->getValue($view)->all()); } - /** - * Test View appends data - * - * Pre-conditions: - * Case A: Append data to View several times - * Case B: Append view data which is not an array - * - * Post-conditions: - * Case A: The View data contains all appended data - * Case B: An InvalidArgumentException is thrown - */ - public function testViewAppendsData() + public function testSetDataKeyValueAsClosure() { - //Case A - $this->view->appendData(array('a' => 'A')); - $this->view->appendData(array('b' => 'B')); - $this->assertEquals(array('a' => 'A', 'b' => 'B'), $this->view->getData()); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); - //Case B - try { - $this->view->appendData('not an array'); - $this->fail('Appending View data with non-array argument did not throw exception'); - } catch ( \InvalidArgumentException $e ) {} + $view->setData('fooClosure', function () { + return 'foo'; + }); + $value = $prop->getValue($view)->get('fooClosure'); + $this->assertInstanceOf('Closure', $value); + $this->assertEquals('foo', $value()); } - /** - * Test View templates directory - * - * Pre-conditions: - * View templates directory is set to an existing directory - * - * Post-conditions: - * The templates directory is set correctly. - */ - public function testSetsTemplatesDirectory() + public function testSetDataArray() { - $templatesDirectory = dirname(__FILE__) . '/templates'; - $this->view->setTemplatesDirectory($templatesDirectory); - $this->assertEquals($templatesDirectory, $this->view->getTemplatesDirectory()); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $view->setData(array('foo' => 'bar')); + + $this->assertEquals(array('foo' => 'bar'), $prop->getValue($view)->all()); } - /** - * Test View templates directory may have a trailing slash when set - * - * Pre-conditions: - * View templates directory is set to an existing directory with a trailing slash - * - * Post-conditions: - * The View templates directory is set correctly without a trailing slash - */ - public function testTemplatesDirectoryWithTrailingSlash() + public function testSetDataInvalidArgument() { - $this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates/'); - $this->assertEquals(dirname(__FILE__) . '/templates', $this->view->getTemplatesDirectory()); + $this->setExpectedException('InvalidArgumentException'); + + $view = new \Slim\View(); + $view->setData('foo'); } - /** - * Test View renders template - * - * Pre-conditions: - * View templates directory is set to an existing directory. - * View data is set without errors - * Case A: View renders an existing template - * Case B: View renders a non-existing template - * - * Post-conditions: - * Case A: The rendered template is returned as a string - * Case B: A RuntimeException is thrown - */ - public function testRendersTemplateWithData() + public function testAppendData() { - $this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates'); - $this->view->setData(array('foo' => 'bar')); + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $view->appendData(array('foo' => 'bar')); - //Case A - $output = $this->view->render('test.php'); - $this->assertEquals('test output bar', $output); - - //Case B - try { - $output = $this->view->render('foo.php'); - $this->fail('Rendering non-existent template did not throw exception'); - } catch ( \RuntimeException $e ) {} + $this->assertEquals(array('foo' => 'bar'), $prop->getValue($view)->all()); } - /** - * Test View displays template - * - * Pre-conditions: - * View templates directory is set to an existing directory. - * View data is set without errors - * View is displayed - * - * Post-conditions: - * The output buffer contains the rendered template - */ - public function testDisplaysTemplateWithData() + public function testLocalData() + { + $view = new \Slim\View(); + $prop1 = new \ReflectionProperty($view, 'data'); + $prop1->setAccessible(true); + $prop1->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + + $prop2 = new \ReflectionProperty($view, 'templatesDirectory'); + $prop2->setAccessible(true); + $prop2->setValue($view, dirname(__FILE__) . '/templates'); + + $output = $view->fetch('test.php', array('foo' => 'baz')); + $this->assertEquals('test output baz', $output); + } + + public function testAppendDataOverwrite() + { + $view = new \Slim\View(); + $prop = new \ReflectionProperty($view, 'data'); + $prop->setAccessible(true); + $prop->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + $view->appendData(array('foo' => '123')); + + $this->assertEquals(array('foo' => '123'), $prop->getValue($view)->all()); + } + + public function testAppendDataInvalidArgument() + { + $this->setExpectedException('InvalidArgumentException'); + + $view = new \Slim\View(); + $view->appendData('foo'); + } + + public function testGetTemplatesDirectory() + { + $view = new \Slim\View(); + $property = new \ReflectionProperty($view, 'templatesDirectory'); + $property->setAccessible(true); + $property->setValue($view, 'templates'); + + $this->assertEquals('templates', $view->getTemplatesDirectory()); + } + + public function testSetTemplatesDirectory() + { + $view = new \Slim\View(); + $view->setTemplatesDirectory('templates/'); // <-- Should strip trailing slash + + $this->assertAttributeEquals('templates', 'templatesDirectory', $view); + } + + public function testDisplay() { $this->expectOutputString('test output bar'); - $this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates'); - $this->view->setData(array('foo' => 'bar')); - $this->view->display('test.php'); + + $view = new \Slim\View(); + $prop1 = new \ReflectionProperty($view, 'data'); + $prop1->setAccessible(true); + $prop1->setValue($view, new \Slim\Helper\Set(array('foo' => 'bar'))); + + $prop2 = new \ReflectionProperty($view, 'templatesDirectory'); + $prop2->setAccessible(true); + $prop2->setValue($view, dirname(__FILE__) . '/templates'); + + $view->display('test.php'); } + public function testDisplayTemplateThatDoesNotExist() + { + $this->setExpectedException('\RuntimeException'); + + $view = new \Slim\View(); + + $prop2 = new \ReflectionProperty($view, 'templatesDirectory'); + $prop2->setAccessible(true); + $prop2->setValue($view, dirname(__FILE__) . '/templates'); + + $view->display('foo.php'); + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Application.php b/vendor/symfony/console/Symfony/Component/Console/Application.php index 718aef46d4..6806f06b11 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Application.php +++ b/vendor/symfony/console/Symfony/Component/Console/Application.php @@ -19,6 +19,8 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputAwareInterface; +use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\ConsoleOutputInterface; @@ -54,16 +56,17 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; */ class Application { - private $commands; + private $commands = array(); private $wantHelps = false; private $runningCommand; private $name; private $version; - private $catchExceptions; - private $autoExit; + private $catchExceptions = true; + private $autoExit = true; private $definition; private $helperSet; private $dispatcher; + private $terminalDimensions; /** * Constructor. @@ -77,9 +80,6 @@ class Application { $this->name = $name; $this->version = $version; - $this->catchExceptions = true; - $this->autoExit = true; - $this->commands = array(); $this->helperSet = $this->getDefaultHelperSet(); $this->definition = $this->getDefaultInputDefinition(); @@ -404,6 +404,10 @@ class Application return; } + if (null === $command->getDefinition()) { + throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); + } + $this->commands[$command->getName()] = $command; foreach ($command->getAliases() as $alias) { @@ -491,51 +495,31 @@ class Application public function findNamespace($namespace) { $allNamespaces = $this->getNamespaces(); - $found = ''; - foreach (explode(':', $namespace) as $i => $part) { - // select sub-namespaces matching the current namespace we found - $namespaces = array(); - foreach ($allNamespaces as $n) { - if ('' === $found || 0 === strpos($n, $found)) { - $namespaces[$n] = explode(':', $n); - } - } + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace); + $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces); - $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $namespaces))))); + if (empty($namespaces)) { + $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); - if (!isset($abbrevs[$part])) { - $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); - - if (1 <= $i) { - $part = $found.':'.$part; + if ($alternatives = $this->findAlternatives($namespace, $allNamespaces, array())) { + if (1 == count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; } - if ($alternatives = $this->findAlternativeNamespace($part, $abbrevs)) { - if (1 == count($alternatives)) { - $message .= "\n\nDid you mean this?\n "; - } else { - $message .= "\n\nDid you mean one of these?\n "; - } - - $message .= implode("\n ", $alternatives); - } - - throw new \InvalidArgumentException($message); + $message .= implode("\n ", $alternatives); } - // there are multiple matches, but $part is an exact match of one of them so we select it - if (in_array($part, $abbrevs[$part])) { - $abbrevs[$part] = array($part); - } - - if (count($abbrevs[$part]) > 1) { - throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$part]))); - } - - $found .= $found ? ':' . $abbrevs[$part][0] : $abbrevs[$part][0]; + throw new \InvalidArgumentException($message); } - return $found; + $exact = in_array($namespace, $namespaces, true); + if (count($namespaces) > 1 && !$exact) { + throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); + } + + return $exact ? $namespace : reset($namespaces); } /** @@ -554,58 +538,19 @@ class Application */ public function find($name) { - // namespace - $namespace = ''; - $searchName = $name; - if (false !== $pos = strrpos($name, ':')) { - $namespace = $this->findNamespace(substr($name, 0, $pos)); - $searchName = $namespace.substr($name, $pos); - } + $allCommands = array_keys($this->commands); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); + $commands = preg_grep('{^'.$expr.'}', $allCommands); - // name - $commands = array(); - foreach ($this->commands as $command) { - $extractedNamespace = $this->extractNamespace($command->getName()); - if ($extractedNamespace === $namespace - || !empty($namespace) && 0 === strpos($extractedNamespace, $namespace) - ) { - $commands[] = $command->getName(); + if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) { + if (false !== $pos = strrpos($name, ':')) { + // check if a namespace exists and contains commands + $this->findNamespace(substr($name, 0, $pos)); } - } - $abbrevs = static::getAbbreviations(array_unique($commands)); - if (isset($abbrevs[$searchName]) && 1 == count($abbrevs[$searchName])) { - return $this->get($abbrevs[$searchName][0]); - } - - if (isset($abbrevs[$searchName]) && in_array($searchName, $abbrevs[$searchName])) { - return $this->get($searchName); - } - - if (isset($abbrevs[$searchName]) && count($abbrevs[$searchName]) > 1) { - $suggestions = $this->getAbbreviationSuggestions($abbrevs[$searchName]); - - throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); - } - - // aliases - $aliases = array(); - foreach ($this->commands as $command) { - foreach ($command->getAliases() as $alias) { - $extractedNamespace = $this->extractNamespace($alias); - if ($extractedNamespace === $namespace - || !empty($namespace) && 0 === strpos($extractedNamespace, $namespace) - ) { - $aliases[] = $alias; - } - } - } - - $aliases = static::getAbbreviations(array_unique($aliases)); - if (!isset($aliases[$searchName])) { $message = sprintf('Command "%s" is not defined.', $name); - if ($alternatives = $this->findAlternativeCommands($searchName, $abbrevs)) { + if ($alternatives = $this->findAlternatives($name, $allCommands, array())) { if (1 == count($alternatives)) { $message .= "\n\nDid you mean this?\n "; } else { @@ -617,11 +562,14 @@ class Application throw new \InvalidArgumentException($message); } - if (count($aliases[$searchName]) > 1) { - throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($aliases[$searchName]))); + $exact = in_array($name, $commands, true); + if (count($commands) > 1 && !$exact) { + $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); + + throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); } - return $this->get($aliases[$searchName][0]); + return $this->get($exact ? $name : reset($commands)); } /** @@ -684,8 +632,10 @@ class Application public function asText($namespace = null, $raw = false) { $descriptor = new TextDescriptor(); + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw); + $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true)); - return $descriptor->describe($this, array('namespace' => $namespace, 'raw_text' => $raw)); + return $output->fetch(); } /** @@ -702,7 +652,14 @@ class Application { $descriptor = new XmlDescriptor(); - return $descriptor->describe($this, array('namespace' => $namespace, 'as_dom' => $asDom)); + if ($asDom) { + return $descriptor->getApplicationDocument($this, $namespace); + } + + $output = new BufferedOutput(); + $descriptor->describe($output, $this, array('namespace' => $namespace)); + + return $output->fetch(); } /** @@ -818,6 +775,10 @@ class Application */ public function getTerminalDimensions() { + if ($this->terminalDimensions) { + return $this->terminalDimensions; + } + if (defined('PHP_WINDOWS_VERSION_BUILD')) { // extract [w, H] from "wxh (WxH)" if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) { @@ -843,6 +804,23 @@ class Application return array(null, null); } + /** + * Sets terminal dimensions. + * + * Can be useful to force terminal dimensions for functional tests. + * + * @param integer $width The width + * @param integer $height The height + * + * @return Application The current application + */ + public function setTerminalDimensions($width, $height) + { + $this->terminalDimensions = array($width, $height); + + return $this; + } + /** * Configures the input and output instances based on the user arguments and options. * @@ -893,6 +871,12 @@ class Application */ protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) { + foreach ($command->getHelperSet() as $helper) { + if ($helper instanceof InputAwareInterface) { + $helper->setInput($input); + } + } + if (null === $this->dispatcher) { return $command->run($input, $output); } @@ -1054,72 +1038,50 @@ class Application } /** - * Finds alternative commands of $name - * - * @param string $name The full name of the command - * @param array $abbrevs The abbreviations - * - * @return array A sorted array of similar commands - */ - private function findAlternativeCommands($name, $abbrevs) - { - $callback = function($item) { - return $item->getName(); - }; - - return $this->findAlternatives($name, $this->commands, $abbrevs, $callback); - } - - /** - * Finds alternative namespace of $name - * - * @param string $name The full name of the namespace - * @param array $abbrevs The abbreviations - * - * @return array A sorted array of similar namespace - */ - private function findAlternativeNamespace($name, $abbrevs) - { - return $this->findAlternatives($name, $this->getNamespaces(), $abbrevs); - } - - /** - * Finds alternative of $name among $collection, - * if nothing is found in $collection, try in $abbrevs + * Finds alternative of $name among $collection * * @param string $name The string * @param array|Traversable $collection The collection - * @param array $abbrevs The abbreviations - * @param Closure|string|array $callback The callable to transform collection item before comparison * * @return array A sorted array of similar string */ - private function findAlternatives($name, $collection, $abbrevs, $callback = null) + private function findAlternatives($name, $collection) { + $threshold = 1e3; $alternatives = array(); + $collectionParts = array(); foreach ($collection as $item) { - if (null !== $callback) { - $item = call_user_func($callback, $item); - } - - $lev = levenshtein($name, $item); - if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { - $alternatives[$item] = $lev; - } + $collectionParts[$item] = explode(':', $item); } - if (!$alternatives) { - foreach ($abbrevs as $key => $values) { - $lev = levenshtein($name, $key); - if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) { - foreach ($values as $value) { - $alternatives[$value] = $lev; - } + foreach (explode(':', $name) as $i => $subname) { + foreach ($collectionParts as $collectionName => $parts) { + $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { + $alternatives[$collectionName] += $threshold; + continue; + } elseif (!isset($parts[$i])) { + continue; + } + + $lev = levenshtein($subname, $parts[$i]); + if ($lev <= strlen($subname) / 3 || false !== strpos($parts[$i], $subname)) { + $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + } elseif ($exists) { + $alternatives[$collectionName] += $threshold; } } } + foreach ($collection as $item) { + $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + } + } + + $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2*$threshold; }); asort($alternatives); return array_keys($alternatives); diff --git a/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md b/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md index e4213af338..4d00cbb428 100644 --- a/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md +++ b/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md @@ -1,6 +1,13 @@ CHANGELOG ========= +2.4.0 +----- + + * added a way to force terminal dimensions + * added a convenient method to detect verbosity level + * [BC BREAK] made descriptors use output instead of returning a string + 2.3.0 ----- diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/Command.php b/vendor/symfony/console/Symfony/Component/Console/Command/Command.php index af1b91f2b1..614a034c8c 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Command/Command.php +++ b/vendor/symfony/console/Symfony/Component/Console/Command/Command.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Application; use Symfony\Component\Console\Helper\HelperSet; @@ -32,13 +33,13 @@ class Command { private $application; private $name; - private $aliases; + private $aliases = array(); private $definition; private $help; private $description; - private $ignoreValidationErrors; - private $applicationDefinitionMerged; - private $applicationDefinitionMergedWithArgs; + private $ignoreValidationErrors = false; + private $applicationDefinitionMerged = false; + private $applicationDefinitionMergedWithArgs = false; private $code; private $synopsis; private $helperSet; @@ -46,7 +47,7 @@ class Command /** * Constructor. * - * @param string $name The name of the command + * @param string|null $name The name of the command; passing null means it must be set in configure() * * @throws \LogicException When the command name is empty * @@ -55,10 +56,6 @@ class Command public function __construct($name = null) { $this->definition = new InputDefinition(); - $this->ignoreValidationErrors = false; - $this->applicationDefinitionMerged = false; - $this->applicationDefinitionMergedWithArgs = false; - $this->aliases = array(); if (null !== $name) { $this->setName($name); @@ -401,7 +398,7 @@ class Command * * @return Command The current instance * - * @throws \InvalidArgumentException When command name given is empty + * @throws \InvalidArgumentException When the name is invalid * * @api */ @@ -511,6 +508,8 @@ class Command * * @return Command The current instance * + * @throws \InvalidArgumentException When an alias is invalid + * * @api */ public function setAliases($aliases) @@ -576,8 +575,10 @@ class Command public function asText() { $descriptor = new TextDescriptor(); + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); + $descriptor->describe($output, $this, array('raw_output' => true)); - return $descriptor->describe($this); + return $output->fetch(); } /** @@ -593,12 +594,28 @@ class Command { $descriptor = new XmlDescriptor(); - return $descriptor->describe($this, array('as_dom' => $asDom)); + if ($asDom) { + return $descriptor->getCommandDocument($this); + } + + $output = new BufferedOutput(); + $descriptor->describe($output, $this); + + return $output->fetch(); } + /** + * Validates a command name. + * + * It must be non-empty and parts can optionally be separated by ":". + * + * @param string $name + * + * @throws \InvalidArgumentException When the name is invalid + */ private function validateName($name) { - if (!preg_match('/^[^\:]+(\:[^\:]+)*$/', $name)) { + if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php b/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php index 2aa933ea0f..e76044a3a7 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php +++ b/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php @@ -38,7 +38,7 @@ class HelpCommand extends Command ->setDefinition(array( new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output help in other formats'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output help in other formats', 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), )) ->setDescription('Displays help for a command') @@ -81,7 +81,11 @@ EOF } $helper = new DescriptorHelper(); - $helper->describe($output, $this->command, $input->getOption('format'), $input->getOption('raw')); + $helper->describe($output, $this->command, array( + 'format' => $input->getOption('format'), + 'raw' => $input->getOption('raw'), + )); + $this->command = null; } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php b/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php index f3d7438d09..25c21205e4 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php +++ b/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php @@ -73,7 +73,11 @@ EOF } $helper = new DescriptorHelper(); - $helper->describe($output, $this->getApplication(), $input->getOption('format'), $input->getOption('raw'), $input->getArgument('namespace')); + $helper->describe($output, $this->getApplication(), array( + 'format' => $input->getOption('format'), + 'raw_text' => $input->getOption('raw'), + 'namespace' => $input->getArgument('namespace'), + )); } /** @@ -85,7 +89,7 @@ EOF new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output list in other formats'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output list in other formats', 'txt'), )); } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php index 659b8f4cc7..23a7dca86f 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php @@ -16,28 +16,55 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; /** * @author Jean-François Simon */ abstract class Descriptor implements DescriptorInterface { - public function describe($object, array $options = array()) + /** + * @var OutputInterface + */ + private $output; + + /** + * {@inheritdoc} + */ + public function describe(OutputInterface $output, $object, array $options = array()) { + $this->output = $output; + switch (true) { case $object instanceof InputArgument: - return $this->describeInputArgument($object, $options); + $this->describeInputArgument($object, $options); + break; case $object instanceof InputOption: - return $this->describeInputOption($object, $options); + $this->describeInputOption($object, $options); + break; case $object instanceof InputDefinition: - return $this->describeInputDefinition($object, $options); + $this->describeInputDefinition($object, $options); + break; case $object instanceof Command: - return $this->describeCommand($object, $options); + $this->describeCommand($object, $options); + break; case $object instanceof Application: - return $this->describeApplication($object, $options); + $this->describeApplication($object, $options); + break; + default: + throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object))); } + } - throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object))); + /** + * Writes content to output. + * + * @param string $content + * @param boolean $decorated + */ + protected function write($content, $decorated = false) + { + $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW); } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php index a4e8633e8b..3929b6d9ed 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Console\Descriptor; +use Symfony\Component\Console\Output\OutputInterface; + /** * Descriptor interface. * @@ -21,10 +23,9 @@ interface DescriptorInterface /** * Describes an InputArgument instance. * - * @param object $object - * @param array $options - * - * @return string|mixed + * @param OutputInterface $output + * @param object $object + * @param array $options */ - public function describe($object, array $options = array()); + public function describe(OutputInterface $output, $object, array $options = array()); } diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php index c2b2a53387..05adf0fbd0 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php @@ -29,13 +29,7 @@ class JsonDescriptor extends Descriptor */ protected function describeInputArgument(InputArgument $argument, array $options = array()) { - return $this->output(array( - 'name' => $argument->getName(), - 'is_required' => $argument->isRequired(), - 'is_array' => $argument->isArray(), - 'description' => $argument->getDescription(), - 'default' => $argument->getDefault(), - ), $options); + $this->writeData($this->getInputArgumentData($argument), $options); } /** @@ -43,15 +37,7 @@ class JsonDescriptor extends Descriptor */ protected function describeInputOption(InputOption $option, array $options = array()) { - return $this->output(array( - 'name' => '--'.$option->getName(), - 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '', - 'accept_value' => $option->acceptValue(), - 'is_value_required' => $option->isValueRequired(), - 'is_multiple' => $option->isArray(), - 'description' => $option->getDescription(), - 'default' => $option->getDefault(), - ), $options); + $this->writeData($this->getInputOptionData($option), $options); } /** @@ -59,17 +45,7 @@ class JsonDescriptor extends Descriptor */ protected function describeInputDefinition(InputDefinition $definition, array $options = array()) { - $inputArguments = array(); - foreach ($definition->getArguments() as $name => $argument) { - $inputArguments[$name] = $this->describeInputArgument($argument, array('as_array' => true)); - } - - $inputOptions = array(); - foreach ($definition->getOptions() as $name => $option) { - $inputOptions[$name] = $this->describeInputOption($option, array('as_array' => true)); - } - - return $this->output(array('arguments' => $inputArguments, 'options' => $inputOptions), $options); + $this->writeData($this->getInputDefinitionData($definition), $options); } /** @@ -77,17 +53,7 @@ class JsonDescriptor extends Descriptor */ protected function describeCommand(Command $command, array $options = array()) { - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - return $this->output(array( - 'name' => $command->getName(), - 'usage' => $command->getSynopsis(), - 'description' => $command->getDescription(), - 'help' => $command->getProcessedHelp(), - 'aliases' => $command->getAliases(), - 'definition' => $this->describeInputDefinition($command->getNativeDefinition(), array('as_array' => true)), - ), $options); + $this->writeData($this->getCommandData($command), $options); } /** @@ -100,30 +66,100 @@ class JsonDescriptor extends Descriptor $commands = array(); foreach ($description->getCommands() as $command) { - $commands[] = $this->describeCommand($command, array('as_array' => true)); + $commands[] = $this->getCommandData($command); } $data = $describedNamespace ? array('commands' => $commands, 'namespace' => $describedNamespace) : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces())); - return $this->output($data, $options); + $this->writeData($data, $options); } /** - * Outputs data as array or string according to options. + * Writes data as json. * * @param array $data * @param array $options * * @return array|string */ - private function output(array $data, array $options) + private function writeData(array $data, array $options) { - if (isset($options['as_array']) && $options['as_array']) { - return $data; + $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0)); + } + + /** + * @param InputArgument $argument + * + * @return array + */ + private function getInputArgumentData(InputArgument $argument) + { + return array( + 'name' => $argument->getName(), + 'is_required' => $argument->isRequired(), + 'is_array' => $argument->isArray(), + 'description' => $argument->getDescription(), + 'default' => $argument->getDefault(), + ); + } + + /** + * @param InputOption $option + * + * @return array + */ + private function getInputOptionData(InputOption $option) + { + return array( + 'name' => '--'.$option->getName(), + 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '', + 'accept_value' => $option->acceptValue(), + 'is_value_required' => $option->isValueRequired(), + 'is_multiple' => $option->isArray(), + 'description' => $option->getDescription(), + 'default' => $option->getDefault(), + ); + } + + /** + * @param InputDefinition $definition + * + * @return array + */ + private function getInputDefinitionData(InputDefinition $definition) + { + $inputArguments = array(); + foreach ($definition->getArguments() as $name => $argument) { + $inputArguments[$name] = $this->getInputArgumentData($argument); } - return json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0); + $inputOptions = array(); + foreach ($definition->getOptions() as $name => $option) { + $inputOptions[$name] = $this->getInputOptionData($option); + } + + return array('arguments' => $inputArguments, 'options' => $inputOptions); + } + + /** + * @param Command $command + * + * @return array + */ + private function getCommandData(Command $command) + { + $command->getSynopsis(); + $command->mergeApplicationDefinition(false); + + return array( + 'name' => $command->getName(), + 'usage' => $command->getSynopsis(), + 'description' => $command->getDescription(), + 'help' => $command->getProcessedHelp(), + 'aliases' => $command->getAliases(), + 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()), + ); } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php index 770af38c93..7bc5808523 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php @@ -29,12 +29,14 @@ class MarkdownDescriptor extends Descriptor */ protected function describeInputArgument(InputArgument $argument, array $options = array()) { - return '**'.$argument->getName().':**'."\n\n" + $this->write( + '**'.$argument->getName().':**'."\n\n" .'* Name: '.($argument->getName() ?: '')."\n" .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" .'* Description: '.($argument->getDescription() ?: '')."\n" - .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'; + .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`' + ); } /** @@ -42,14 +44,16 @@ class MarkdownDescriptor extends Descriptor */ protected function describeInputOption(InputOption $option, array $options = array()) { - return '**'.$option->getName().':**'."\n\n" + $this->write( + '**'.$option->getName().':**'."\n\n" .'* Name: `--'.$option->getName().'`'."\n" .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '')."\n" .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" .'* Description: '.($option->getDescription() ?: '')."\n" - .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'; + .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`' + ); } /** @@ -57,23 +61,25 @@ class MarkdownDescriptor extends Descriptor */ protected function describeInputDefinition(InputDefinition $definition, array $options = array()) { - $blocks = array(); - - if (count($definition->getArguments()) > 0) { - $blocks[] = '### Arguments:'; + if ($showArguments = count($definition->getArguments()) > 0) { + $this->write('### Arguments:'); foreach ($definition->getArguments() as $argument) { - $blocks[] = $this->describeInputArgument($argument); + $this->write("\n\n"); + $this->write($this->describeInputArgument($argument)); } } if (count($definition->getOptions()) > 0) { - $blocks[] = '### Options:'; + if ($showArguments) { + $this->write("\n\n"); + } + + $this->write('### Options:'); foreach ($definition->getOptions() as $option) { - $blocks[] = $this->describeInputOption($option); + $this->write("\n\n"); + $this->write($this->describeInputOption($option)); } } - - return implode("\n\n", $blocks); } /** @@ -84,21 +90,23 @@ class MarkdownDescriptor extends Descriptor $command->getSynopsis(); $command->mergeApplicationDefinition(false); - $markdown = $command->getName()."\n" + $this->write( + $command->getName()."\n" .str_repeat('-', strlen($command->getName()))."\n\n" .'* Description: '.($command->getDescription() ?: '')."\n" .'* Usage: `'.$command->getSynopsis().'`'."\n" - .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : ''); + .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : '') + ); if ($help = $command->getProcessedHelp()) { - $markdown .= "\n\n".$help; + $this->write("\n\n"); + $this->write($help); } - if ($definitionMarkdown = $this->describeInputDefinition($command->getNativeDefinition())) { - $markdown .= "\n\n".$definitionMarkdown; + if ($definition = $command->getNativeDefinition()) { + $this->write("\n\n"); + $this->describeInputDefinition($command->getNativeDefinition()); } - - return $markdown; } /** @@ -108,22 +116,24 @@ class MarkdownDescriptor extends Descriptor { $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; $description = new ApplicationDescription($application, $describedNamespace); - $blocks = array($application->getName()."\n".str_repeat('=', strlen($application->getName()))); + + $this->write($application->getName()."\n".str_repeat('=', strlen($application->getName()))); foreach ($description->getNamespaces() as $namespace) { if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $blocks[] = '**'.$namespace['id'].':**'; + $this->write("\n\n"); + $this->write('**'.$namespace['id'].':**'); } - $blocks[] = implode("\n", array_map(function ($commandName) { + $this->write("\n\n"); + $this->write(implode("\n", array_map(function ($commandName) { return '* '.$commandName; - } , $namespace['commands'])); + } , $namespace['commands']))); } foreach ($description->getCommands() as $command) { - $blocks[] = $this->describeCommand($command); + $this->write("\n\n"); + $this->write($this->describeCommand($command)); } - - return implode("\n\n", $blocks); } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php index 2003237441..f979fa7db2 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php @@ -36,10 +36,12 @@ class TextDescriptor extends Descriptor } $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($argument->getName()); - $output = str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $argument->getDescription()); - $output = sprintf(" %-${nameWidth}s %s%s", $argument->getName(), $output, $default); - return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output; + $this->writeText(sprintf(" %-${nameWidth}s %s%s", + $argument->getName(), + str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $argument->getDescription()), + $default + ), $options); } /** @@ -56,15 +58,13 @@ class TextDescriptor extends Descriptor $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($option->getName()); $nameWithShortcutWidth = $nameWidth - strlen($option->getName()) - 2; - $output = sprintf(" %s %-${nameWithShortcutWidth}s%s%s%s", + $this->writeText(sprintf(" %s %-${nameWithShortcutWidth}s%s%s%s", '--'.$option->getName(), $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '', str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $option->getDescription()), $default, $option->isArray() ? ' (multiple values allowed)' : '' - ); - - return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output; + ), $options); } /** @@ -85,27 +85,27 @@ class TextDescriptor extends Descriptor } ++$nameWidth; - $messages = array(); - if ($definition->getArguments()) { - $messages[] = 'Arguments:'; + $this->writeText('Arguments:', $options); + $this->writeText("\n"); foreach ($definition->getArguments() as $argument) { - $messages[] = $this->describeInputArgument($argument, array('name_width' => $nameWidth)); + $this->describeInputArgument($argument, array_merge($options, array('name_width' => $nameWidth))); + $this->writeText("\n"); } - $messages[] = ''; + } + + if ($definition->getArguments() && $definition->getOptions()) { + $this->writeText("\n"); } if ($definition->getOptions()) { - $messages[] = 'Options:'; + $this->writeText('Options:', $options); + $this->writeText("\n"); foreach ($definition->getOptions() as $option) { - $messages[] = $this->describeInputOption($option, array('name_width' => $nameWidth)); + $this->describeInputOption($option, array_merge($options, array('name_width' => $nameWidth))); + $this->writeText("\n"); } - $messages[] = ''; } - - $output = implode("\n", $messages); - - return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output; } /** @@ -115,22 +115,30 @@ class TextDescriptor extends Descriptor { $command->getSynopsis(); $command->mergeApplicationDefinition(false); - $messages = array('Usage:', ' '.$command->getSynopsis(), ''); - if ($command->getAliases()) { - $messages[] = 'Aliases: '.implode(', ', $command->getAliases()).''; + $this->writeText('Usage:', $options); + $this->writeText("\n"); + $this->writeText(' '.$command->getSynopsis(), $options); + $this->writeText("\n"); + + if (count($command->getAliases()) > 0) { + $this->writeText("\n"); + $this->writeText('Aliases: '.implode(', ', $command->getAliases()).'', $options); } - $messages[] = $this->describeInputDefinition($command->getNativeDefinition()); + if ($definition = $command->getNativeDefinition()) { + $this->writeText("\n"); + $this->describeInputDefinition($definition, $options); + } + + $this->writeText("\n"); if ($help = $command->getProcessedHelp()) { - $messages[] = 'Help:'; - $messages[] = ' '.str_replace("\n", "\n ", $help)."\n"; + $this->writeText('Help:', $options); + $this->writeText("\n"); + $this->writeText(' '.str_replace("\n", "\n ", $help), $options); + $this->writeText("\n"); } - - $output = implode("\n", $messages); - - return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output; } /** @@ -140,41 +148,52 @@ class TextDescriptor extends Descriptor { $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; $description = new ApplicationDescription($application, $describedNamespace); - $messages = array(); if (isset($options['raw_text']) && $options['raw_text']) { $width = $this->getColumnWidth($description->getCommands()); foreach ($description->getCommands() as $command) { - $messages[] = sprintf("%-${width}s %s", $command->getName(), $command->getDescription()); + $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options); + $this->writeText("\n"); } } else { $width = $this->getColumnWidth($description->getCommands()); - $messages[] = $application->getHelp(); - $messages[] = ''; + $this->writeText($application->getHelp(), $options); + $this->writeText("\n\n"); if ($describedNamespace) { - $messages[] = sprintf("Available commands for the \"%s\" namespace:", $describedNamespace); + $this->writeText(sprintf("Available commands for the \"%s\" namespace:", $describedNamespace), $options); } else { - $messages[] = 'Available commands:'; + $this->writeText('Available commands:', $options); } // add commands by namespace foreach ($description->getNamespaces() as $namespace) { if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { - $messages[] = ''.$namespace['id'].''; + $this->writeText("\n"); + $this->writeText(''.$namespace['id'].'', $options); } foreach ($namespace['commands'] as $name) { - $messages[] = sprintf(" %-${width}s %s", $name, $description->getCommand($name)->getDescription()); + $this->writeText("\n"); + $this->writeText(sprintf(" %-${width}s %s", $name, $description->getCommand($name)->getDescription()), $options); } } + + $this->writeText("\n"); } + } - $output = implode("\n", $messages); - - return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output; + /** + * {@inheritdoc} + */ + private function writeText($content, array $options = array()) + { + $this->write( + isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, + isset($options['raw_output']) ? !$options['raw_output'] : true + ); } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php index c828a9ceb8..ac1e25e3af 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php +++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php @@ -24,10 +24,185 @@ use Symfony\Component\Console\Input\InputOption; */ class XmlDescriptor extends Descriptor { + /** + * @param InputDefinition $definition + * + * @return \DOMDocument + */ + public function getInputDefinitionDocument(InputDefinition $definition) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($definitionXML = $dom->createElement('definition')); + + $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); + foreach ($definition->getArguments() as $argument) { + $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument)); + } + + $definitionXML->appendChild($optionsXML = $dom->createElement('options')); + foreach ($definition->getOptions() as $option) { + $this->appendDocument($optionsXML, $this->getInputOptionDocument($option)); + } + + return $dom; + } + + /** + * @param Command $command + * + * @return \DOMDocument + */ + public function getCommandDocument(Command $command) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($commandXML = $dom->createElement('command')); + + $command->getSynopsis(); + $command->mergeApplicationDefinition(false); + + $commandXML->setAttribute('id', $command->getName()); + $commandXML->setAttribute('name', $command->getName()); + + $commandXML->appendChild($usageXML = $dom->createElement('usage')); + $usageXML->appendChild($dom->createTextNode(sprintf($command->getSynopsis(), ''))); + + $commandXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription()))); + + $commandXML->appendChild($helpXML = $dom->createElement('help')); + $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp()))); + + $commandXML->appendChild($aliasesXML = $dom->createElement('aliases')); + foreach ($command->getAliases() as $alias) { + $aliasesXML->appendChild($aliasXML = $dom->createElement('alias')); + $aliasXML->appendChild($dom->createTextNode($alias)); + } + + $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition()); + $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); + + return $dom; + } + + /** + * @param Application $application + * @param string|null $namespace + * + * @return \DOMDocument + */ + public function getApplicationDocument(Application $application, $namespace = null) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($rootXml = $dom->createElement('symfony')); + + if ($application->getName() !== 'UNKNOWN') { + $rootXml->setAttribute('name', $application->getName()); + if ($application->getVersion() !== 'UNKNOWN') { + $rootXml->setAttribute('version', $application->getVersion()); + } + } + + $rootXml->appendChild($commandsXML = $dom->createElement('commands')); + + $description = new ApplicationDescription($application, $namespace); + + if ($namespace) { + $commandsXML->setAttribute('namespace', $namespace); + } + + foreach ($description->getCommands() as $command) { + $this->appendDocument($commandsXML, $this->getCommandDocument($command)); + } + + if (!$namespace) { + $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); + + foreach ($description->getNamespaces() as $namespaceDescription) { + $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); + $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']); + + foreach ($namespaceDescription['commands'] as $name) { + $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); + $commandXML->appendChild($dom->createTextNode($name)); + } + } + } + + return $dom; + } + /** * {@inheritdoc} */ protected function describeInputArgument(InputArgument $argument, array $options = array()) + { + $this->writeDocument($this->getInputArgumentDocument($argument)); + } + + /** + * {@inheritdoc} + */ + protected function describeInputOption(InputOption $option, array $options = array()) + { + $this->writeDocument($this->getInputOptionDocument($option)); + } + + /** + * {@inheritdoc} + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = array()) + { + $this->writeDocument($this->getInputDefinitionDocument($definition)); + } + + /** + * {@inheritdoc} + */ + protected function describeCommand(Command $command, array $options = array()) + { + $this->writeDocument($this->getCommandDocument($command)); + } + + /** + * {@inheritdoc} + */ + protected function describeApplication(Application $application, array $options = array()) + { + $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null)); + } + + /** + * Appends document children to parent node. + * + * @param \DOMNode $parentNode + * @param \DOMNode $importedParent + */ + private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) + { + foreach ($importedParent->childNodes as $childNode) { + $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true)); + } + } + + /** + * Writes DOM document. + * + * @param \DOMDocument $dom + * + * @return \DOMDocument|string + */ + private function writeDocument(\DOMDocument $dom) + { + $dom->formatOutput = true; + $this->write($dom->saveXML()); + } + + /** + * @param InputArgument $argument + * + * @return \DOMDocument + */ + private function getInputArgumentDocument(InputArgument $argument) { $dom = new \DOMDocument('1.0', 'UTF-8'); @@ -45,13 +220,15 @@ class XmlDescriptor extends Descriptor $defaultXML->appendChild($dom->createTextNode($default)); } - return $this->output($dom, $options); + return $dom; } /** - * {@inheritdoc} + * @param InputOption $option + * + * @return \DOMDocument */ - protected function describeInputOption(InputOption $option, array $options = array()) + private function getInputOptionDocument(InputOption $option) { $dom = new \DOMDocument('1.0', 'UTF-8'); @@ -82,131 +259,6 @@ class XmlDescriptor extends Descriptor } } - return $this->output($dom, $options); - } - - /** - * {@inheritdoc} - */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($definitionXML = $dom->createElement('definition')); - - $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); - foreach ($definition->getArguments() as $argument) { - $this->appendDocument($argumentsXML, $this->describeInputArgument($argument, array('as_dom' => true))); - } - - $definitionXML->appendChild($optionsXML = $dom->createElement('options')); - foreach ($definition->getOptions() as $option) { - $this->appendDocument($optionsXML, $this->describeInputOption($option, array('as_dom' => true))); - } - - return $this->output($dom, $options); - } - - /** - * {@inheritdoc} - */ - protected function describeCommand(Command $command, array $options = array()) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($commandXML = $dom->createElement('command')); - - $command->getSynopsis(); - $command->mergeApplicationDefinition(false); - - $commandXML->setAttribute('id', $command->getName()); - $commandXML->setAttribute('name', $command->getName()); - - $commandXML->appendChild($usageXML = $dom->createElement('usage')); - $usageXML->appendChild($dom->createTextNode(sprintf($command->getSynopsis(), ''))); - - $commandXML->appendChild($descriptionXML = $dom->createElement('description')); - $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription()))); - - $commandXML->appendChild($helpXML = $dom->createElement('help')); - $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp()))); - - $commandXML->appendChild($aliasesXML = $dom->createElement('aliases')); - foreach ($command->getAliases() as $alias) { - $aliasesXML->appendChild($aliasXML = $dom->createElement('alias')); - $aliasXML->appendChild($dom->createTextNode($alias)); - } - - $definitionXML = $this->describeInputDefinition($command->getNativeDefinition(), array('as_dom' => true)); - $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); - - return $this->output($dom, $options); - } - - /** - * {@inheritdoc} - */ - protected function describeApplication(Application $application, array $options = array()) - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->appendChild($rootXml = $dom->createElement('symfony')); - $rootXml->appendChild($commandsXML = $dom->createElement('commands')); - - $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; - $description = new ApplicationDescription($application, $describedNamespace); - - if ($describedNamespace) { - $commandsXML->setAttribute('namespace', $describedNamespace); - } - - foreach ($description->getCommands() as $command) { - $this->appendDocument($commandsXML, $this->describeCommand($command, array('as_dom' => true))); - } - - if (!$describedNamespace) { - $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); - - foreach ($description->getNamespaces() as $namespace) { - $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); - $namespaceArrayXML->setAttribute('id', $namespace['id']); - - foreach ($namespace['commands'] as $name) { - $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); - $commandXML->appendChild($dom->createTextNode($name)); - } - } - } - - return $this->output($dom, $options); - } - - /** - * Appends document children to parent node. - * - * @param \DOMNode $parentNode - * @param \DOMNode $importedParent - */ - private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) - { - foreach ($importedParent->childNodes as $childNode) { - $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true)); - } - } - - /** - * Outputs document as DOMDocument or string according to options. - * - * @param \DOMDocument $dom - * @param array $options - * - * @return \DOMDocument|string - */ - private function output(\DOMDocument $dom, array $options) - { - if (isset($options['as_dom']) && $options['as_dom']) { - return $dom; - } - - $dom->formatOutput = true; - - return $dom->saveXML(); + return $dom; } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php index 222838ce6a..47ac68b688 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php +++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Console\Event; -use Symfony\Component\Console\Command\Command; - /** * Allows to do things before the command is executed. * diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php index fa054ec223..a8619b713f 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php +++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php @@ -30,7 +30,7 @@ class ConsoleExceptionEvent extends ConsoleEvent parent::__construct($command, $input, $output); $this->setException($exception); - $this->exitCode = $exitCode; + $this->exitCode = (int) $exitCode; } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php index 9f80cb70a0..7eeea60da4 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php +++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php @@ -43,7 +43,7 @@ class ConsoleTerminateEvent extends ConsoleEvent */ public function setExitCode($exitCode) { - $this->exitCode = $exitCode; + $this->exitCode = (int) $exitCode; } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php index 0317d5d08d..932dd0f299 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php +++ b/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php @@ -46,23 +46,29 @@ class DescriptorHelper extends Helper /** * Describes an object if supported. * + * Available options are: + * * format: string, the output format name + * * raw_text: boolean, sets output type as raw + * * @param OutputInterface $output * @param object $object - * @param string $format - * @param boolean $raw + * @param array $options + * + * @throws \InvalidArgumentException */ - public function describe(OutputInterface $output, $object, $format = null, $raw = false, $namespace = null) + public function describe(OutputInterface $output, $object, array $options = array()) { - $options = array('raw_text' => $raw, 'format' => $format ?: 'txt', 'namespace' => $namespace); - $type = !$raw && 'txt' === $options['format'] ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW; + $options = array_merge(array( + 'raw_text' => false, + 'format' => 'txt', + ), $options); if (!isset($this->descriptors[$options['format']])) { throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); } $descriptor = $this->descriptors[$options['format']]; - - $output->writeln($descriptor->describe($object, $options), $type); + $descriptor->describe($output, $object, $options); } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php index 98d37ad254..20382d0166 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php +++ b/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php @@ -19,7 +19,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterStyle; * * @author Fabien Potencier */ -class DialogHelper extends Helper +class DialogHelper extends InputAwareHelper { private $inputStream; private static $shell; @@ -98,6 +98,10 @@ class DialogHelper extends Helper */ public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) { + if ($this->input && !$this->input->isInteractive()) { + return $default; + } + $output->write($question); $inputStream = $this->inputStream ?: STDIN; diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php index d95c9a3036..e080678bce 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php +++ b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php @@ -18,9 +18,9 @@ use Symfony\Component\Console\Command\Command; * * @author Fabien Potencier */ -class HelperSet +class HelperSet implements \IteratorAggregate { - private $helpers; + private $helpers = array(); private $command; /** @@ -30,7 +30,6 @@ class HelperSet */ public function __construct(array $helpers = array()) { - $this->helpers = array(); foreach ($helpers as $alias => $helper) { $this->set($helper, is_int($alias) ? null : $alias); } @@ -101,4 +100,9 @@ class HelperSet { return $this->command; } + + public function getIterator() + { + return new \ArrayIterator($this->helpers); + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php index c3d6cb363c..1c2ecc2a8a 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php +++ b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php @@ -227,22 +227,7 @@ class ProgressHelper extends Helper */ public function advance($step = 1, $redraw = false) { - if (null === $this->startTime) { - throw new \LogicException('You must start the progress bar before calling advance().'); - } - - if (0 === $this->current) { - $redraw = true; - } - - $prevPeriod = intval($this->current / $this->redrawFreq); - - $this->current += $step; - - $currPeriod = intval($this->current / $this->redrawFreq); - if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) { - $this->display(); - } + $this->setCurrent($this->current + $step, $redraw); } /** @@ -272,7 +257,7 @@ class ProgressHelper extends Helper $prevPeriod = intval($this->current / $this->redrawFreq); $this->current = $current; - + $currPeriod = intval($this->current / $this->redrawFreq); if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) { $this->display(); @@ -299,6 +284,18 @@ class ProgressHelper extends Helper $this->overwrite($this->output, $message); } + /** + * Removes the progress bar from the current line. + * + * This is useful if you wish to write some output + * while a progress bar is running. + * Call display() to show the progress bar again. + */ + public function clear() + { + $this->overwrite($this->output, ''); + } + /** * Finishes the progress output. */ diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php index c18f29598a..e1b1e149a1 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php +++ b/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php @@ -23,6 +23,7 @@ class TableHelper extends Helper { const LAYOUT_DEFAULT = 0; const LAYOUT_BORDERLESS = 1; + const LAYOUT_COMPACT = 2; /** * Table headers. @@ -45,6 +46,7 @@ class TableHelper extends Helper private $crossingChar; private $cellHeaderFormat; private $cellRowFormat; + private $cellRowContentFormat; private $borderFormat; private $padType; @@ -89,7 +91,22 @@ class TableHelper extends Helper ->setVerticalBorderChar(' ') ->setCrossingChar(' ') ->setCellHeaderFormat('%s') - ->setCellRowFormat('%s') + ->setCellRowFormat('%s') + ->setCellRowContentFormat(' %s ') + ->setBorderFormat('%s') + ->setPadType(STR_PAD_RIGHT) + ; + break; + + case self::LAYOUT_COMPACT: + $this + ->setPaddingChar(' ') + ->setHorizontalBorderChar('') + ->setVerticalBorderChar(' ') + ->setCrossingChar('') + ->setCellHeaderFormat('%s') + ->setCellRowFormat('%s') + ->setCellRowContentFormat('%s') ->setBorderFormat('%s') ->setPadType(STR_PAD_RIGHT) ; @@ -102,7 +119,8 @@ class TableHelper extends Helper ->setVerticalBorderChar('|') ->setCrossingChar('+') ->setCellHeaderFormat('%s') - ->setCellRowFormat('%s') + ->setCellRowFormat('%s') + ->setCellRowContentFormat(' %s ') ->setBorderFormat('%s') ->setPadType(STR_PAD_RIGHT) ; @@ -162,6 +180,10 @@ class TableHelper extends Helper */ public function setPaddingChar($paddingChar) { + if (!$paddingChar) { + throw new \LogicException('The padding char must not be empty'); + } + $this->paddingChar = $paddingChar; return $this; @@ -237,6 +259,20 @@ class TableHelper extends Helper return $this; } + /** + * Sets row cell content format. + * + * @param string $cellRowContentFormat + * + * @return TableHelper + */ + public function setCellRowContentFormat($cellRowContentFormat) + { + $this->cellRowContentFormat = $cellRowContentFormat; + + return $this; + } + /** * Sets table border format. * @@ -309,11 +345,13 @@ class TableHelper extends Helper return; } + if (!$this->horizontalBorderChar && !$this->crossingChar) { + return; + } + $markup = $this->crossingChar; for ($column = 0; $column < $count; $column++) { - $markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column)) - .$this->crossingChar - ; + $markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column)).$this->crossingChar; } $this->output->writeln(sprintf($this->borderFormat, $markup)); @@ -366,15 +404,9 @@ class TableHelper extends Helper $width += strlen($cell) - mb_strlen($cell, $encoding); } - $this->output->write(sprintf( - $cellFormat, - str_pad( - $this->paddingChar.$cell.$this->paddingChar, - $width, - $this->paddingChar, - $this->padType - ) - )); + $content = sprintf($this->cellRowContentFormat, $cell); + + $this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->paddingChar, $this->padType))); } /** @@ -416,7 +448,7 @@ class TableHelper extends Helper $lengths[] = $this->getCellWidth($row, $column); } - return $this->columnWidths[$column] = max($lengths) + 2; + return $this->columnWidths[$column] = max($lengths) + strlen($this->cellRowContentFormat) - 2; } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/Input.php b/vendor/symfony/console/Symfony/Component/Console/Input/Input.php index fb84cf829e..a55029ec19 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Input/Input.php +++ b/vendor/symfony/console/Symfony/Component/Console/Input/Input.php @@ -24,9 +24,12 @@ namespace Symfony\Component\Console\Input; */ abstract class Input implements InputInterface { + /** + * @var InputDefinition + */ protected $definition; - protected $options; - protected $arguments; + protected $options = array(); + protected $arguments = array(); protected $interactive = true; /** @@ -37,8 +40,6 @@ abstract class Input implements InputInterface public function __construct(InputDefinition $definition = null) { if (null === $definition) { - $this->arguments = array(); - $this->options = array(); $this->definition = new InputDefinition(); } else { $this->bind($definition); diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php index 93ca9167dc..c1cab5be34 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php +++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php @@ -18,6 +18,7 @@ if (!defined('JSON_UNESCAPED_UNICODE')) { use Symfony\Component\Console\Descriptor\TextDescriptor; use Symfony\Component\Console\Descriptor\XmlDescriptor; +use Symfony\Component\Console\Output\BufferedOutput; /** * A InputDefinition represents a set of valid command line arguments and options. @@ -426,8 +427,10 @@ class InputDefinition public function asText() { $descriptor = new TextDescriptor(); + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); + $descriptor->describe($output, $this, array('raw_output' => true)); - return $descriptor->describe($this); + return $output->fetch(); } /** @@ -443,6 +446,13 @@ class InputDefinition { $descriptor = new XmlDescriptor(); - return $descriptor->describe($this, array('as_dom' => $asDom)); + if ($asDom) { + return $descriptor->getInputDefinitionDocument($this); + } + + $output = new BufferedOutput(); + $descriptor->describe($output, $this); + + return $output->fetch(); } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/Output.php b/vendor/symfony/console/Symfony/Component/Console/Output/Output.php index 0daedc3eaf..94b9c88d76 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Output/Output.php +++ b/vendor/symfony/console/Symfony/Component/Console/Output/Output.php @@ -46,7 +46,7 @@ abstract class Output implements OutputInterface public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null) { $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity; - $this->formatter = null === $formatter ? new OutputFormatter() : $formatter; + $this->formatter = $formatter ?: new OutputFormatter(); $this->formatter->setDecorated($decorated); } @@ -98,6 +98,26 @@ abstract class Output implements OutputInterface return $this->verbosity; } + public function isQuiet() + { + return self::VERBOSITY_QUIET === $this->verbosity; + } + + public function isVerbose() + { + return self::VERBOSITY_VERBOSE <= $this->verbosity; + } + + public function isVeryVerbose() + { + return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; + } + + public function isDebug() + { + return self::VERBOSITY_DEBUG <= $this->verbosity; + } + /** * {@inheritdoc} */ diff --git a/vendor/symfony/console/Symfony/Component/Console/Shell.php b/vendor/symfony/console/Symfony/Component/Console/Shell.php index ff8bef5f74..5ddbd27536 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Shell.php +++ b/vendor/symfony/console/Symfony/Component/Console/Shell.php @@ -32,7 +32,7 @@ class Shell private $history; private $output; private $hasReadline; - private $processIsolation; + private $processIsolation = false; /** * Constructor. @@ -48,7 +48,6 @@ class Shell $this->application = $application; $this->history = getenv('HOME').'/.history_'.$application->getName(); $this->output = new ConsoleOutput(); - $this->processIsolation = false; } /** diff --git a/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php b/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php index 2e57e1a35d..dd7c2a5dc0 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php @@ -32,6 +32,7 @@ class ApplicationTester private $application; private $input; private $output; + private $statusCode; /** * Constructor. @@ -72,7 +73,7 @@ class ApplicationTester $this->output->setVerbosity($options['verbosity']); } - return $this->application->run($this->input, $this->output); + return $this->statusCode = $this->application->run($this->input, $this->output); } /** @@ -114,4 +115,14 @@ class ApplicationTester { return $this->output; } + + /** + * Gets the status code returned by the last execution of the application. + * + * @return integer The status code + */ + public function getStatusCode() + { + return $this->statusCode; + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php b/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php index 02715b00e3..6866bc6420 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php @@ -27,6 +27,7 @@ class CommandTester private $command; private $input; private $output; + private $statusCode; /** * Constructor. @@ -54,6 +55,15 @@ class CommandTester */ public function execute(array $input, array $options = array()) { + // set the command name automatically if the application requires + // this argument and no command name was passed + if (!isset($input['command']) + && (null !== $application = $this->command->getApplication()) + && $application->getDefinition()->hasArgument('command') + ) { + $input['command'] = $this->command->getName(); + } + $this->input = new ArrayInput($input); if (isset($options['interactive'])) { $this->input->setInteractive($options['interactive']); @@ -67,7 +77,7 @@ class CommandTester $this->output->setVerbosity($options['verbosity']); } - return $this->command->run($this->input, $this->output); + return $this->statusCode = $this->command->run($this->input, $this->output); } /** @@ -109,4 +119,14 @@ class CommandTester { return $this->output; } + + /** + * Gets the status code returned by the last execution of the application. + * + * @return integer The status code + */ + public function getStatusCode() + { + return $this->statusCode; + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php index e45464a177..719a98b32b 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Tests; use Symfony\Component\Console\Application; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; @@ -22,6 +23,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\StreamOutput; use Symfony\Component\Console\Tester\ApplicationTester; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleExceptionEvent; @@ -40,6 +42,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase require_once self::$fixturesPath.'/Foo2Command.php'; require_once self::$fixturesPath.'/Foo3Command.php'; require_once self::$fixturesPath.'/Foo4Command.php'; + require_once self::$fixturesPath.'/Foo5Command.php'; + require_once self::$fixturesPath.'/FoobarCommand.php'; + require_once self::$fixturesPath.'/BarBucCommand.php'; } protected function normalizeLineBreaks($text) @@ -124,6 +129,16 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands'); } + /** + * @expectedException \LogicException + * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor. + */ + public function testAddCommandWithEmptyConstructor() + { + $application = new Application(); + $application->add(new \Foo5Command()); + } + public function testHasGet() { $application = new Application(); @@ -193,6 +208,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function testFindAmbiguousNamespace() { $application = new Application(); + $application->add(new \BarBucCommand()); $application->add(new \FooCommand()); $application->add(new \Foo2Command()); $application->findNamespace('f'); @@ -208,6 +224,20 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $application->findNamespace('bar'); } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Command "foo1" is not defined + */ + public function testFindUniqueNameButNamespaceName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + $application->find($commandName = 'foo1'); + } + public function testFind() { $application = new Application(); @@ -240,7 +270,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase return array( array('f', 'Command "f" is not defined.'), array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'), - array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1).') + array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).') ); } @@ -254,6 +284,23 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name'); } + public function testFindCommandWithAmbiguousNamespacesButUniqueName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \FoobarCommand()); + + $this->assertInstanceOf('FoobarCommand', $application->find('f:f')); + } + + public function testFindCommandWithMissingNamespace() + { + $application = new Application(); + $application->add(new \Foo4Command()); + + $this->assertInstanceOf('Foo4Command', $application->find('f::t')); + } + /** * @dataProvider provideInvalidCommandNamesSingle * @expectedException \InvalidArgumentException @@ -262,15 +309,15 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function testFindAlternativeExceptionMessageSingle($name) { $application = new Application(); - $application->add(new \FooCommand()); + $application->add(new \Foo3Command()); $application->find($name); } public function provideInvalidCommandNamesSingle() { return array( - array('foo:baR'), - array('foO:bar') + array('foo3:baR'), + array('foO3:bar') ); } @@ -288,6 +335,8 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase } catch (\Exception $e) { $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1:bar/', $e->getMessage()); + $this->assertRegExp('/foo:bar/', $e->getMessage()); } // Namespace + plural @@ -297,6 +346,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase } catch (\Exception $e) { $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1/', $e->getMessage()); } $application->add(new \Foo3Command()); @@ -329,26 +379,17 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without alternatives'); } + // Test if "bar1" command throw an "\InvalidArgumentException" and does not contain + // "foo:bar" as alternative because "bar1" is too far from "foo:bar" try { - $application->find($commandName = 'foo'); + $application->find($commandName = 'bar1'); $this->fail('->find() throws an \InvalidArgumentException if command does not exist'); } catch (\Exception $e) { $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist'); $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); - $this->assertRegExp('/foo:bar/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar"'); - $this->assertRegExp('/foo1:bar/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo1:bar"'); + $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "afoobar1"'); $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar1"'); - } - - // Test if "foo1" command throw an "\InvalidArgumentException" and does not contain - // "foo:bar" as alternative because "foo1" is too far from "foo:bar" - try { - $application->find($commandName = 'foo1'); - $this->fail('->find() throws an \InvalidArgumentException if command does not exist'); - } catch (\Exception $e) { - $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist'); - $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives'); - $this->assertFalse(strpos($e->getMessage(), 'foo:bar'), '->find() throws an \InvalidArgumentException if command does not exist, without "foo:bar" alternative'); + $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without "foo:bar" alternative'); } } @@ -561,6 +602,29 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed'); } + /** + * Issue #9285 + * + * If the "verbose" option is just before an argument in ArgvInput, + * an argument value should not be treated as verbosity value. + * This test will fail with "Not enough arguments." if broken + */ + public function testVerboseValueNotBreakArguments() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add(new \FooCommand()); + + $output = new StreamOutput(fopen('php://memory', 'w', false)); + + $input = new ArgvInput(array('cli.php', '-v', 'foo:bar')); + $application->run($input, $output); + + $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar')); + $application->run($input, $output); + } + public function testRunReturnsIntegerExitCode() { $exception = new \Exception('', 4); @@ -734,10 +798,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function testRunWithDispatcher() { - if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { - $this->markTestSkipped('The "EventDispatcher" component is not available'); - } - $application = new Application(); $application->setAutoExit(false); $application->setDispatcher($this->getDispatcher()); @@ -757,10 +817,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase */ public function testRunWithExceptionAndDispatcher() { - if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { - $this->markTestSkipped('The "EventDispatcher" component is not available'); - } - $application = new Application(); $application->setDispatcher($this->getDispatcher()); $application->setAutoExit(false); @@ -776,10 +832,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function testRunDispatchesAllEventsWithException() { - if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { - $this->markTestSkipped('The "EventDispatcher" component is not available'); - } - $application = new Application(); $application->setDispatcher($this->getDispatcher()); $application->setAutoExit(false); @@ -795,9 +847,24 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertContains('before.foo.after.caught.', $tester->getDisplay()); } + public function testTerminalDimensions() + { + $application = new Application(); + $originalDimensions = $application->getTerminalDimensions(); + $this->assertCount(2, $originalDimensions); + + $width = 80; + if ($originalDimensions[0] == $width) { + $width = 100; + } + + $application->setTerminalDimensions($width, 80); + $this->assertSame(array($width, 80), $application->getTerminalDimensions()); + } + protected function getDispatcher() { - $dispatcher = new EventDispatcher; + $dispatcher = new EventDispatcher(); $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) { $event->getOutput()->write('before.'); }); diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php index aab1cf3761..406c6599ba 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php @@ -16,31 +16,32 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\BufferedOutput; abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase { /** @dataProvider getDescribeInputArgumentTestData */ public function testDescribeInputArgument(InputArgument $argument, $expectedDescription) { - $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($argument))); + $this->assertDescription($expectedDescription, $argument); } /** @dataProvider getDescribeInputOptionTestData */ public function testDescribeInputOption(InputOption $option, $expectedDescription) { - $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($option))); + $this->assertDescription($expectedDescription, $option); } /** @dataProvider getDescribeInputDefinitionTestData */ public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription) { - $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($definition))); + $this->assertDescription($expectedDescription, $definition); } /** @dataProvider getDescribeCommandTestData */ public function testDescribeCommand(Command $command, $expectedDescription) { - $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($command))); + $this->assertDescription($expectedDescription, $command); } /** @dataProvider getDescribeApplicationTestData */ @@ -53,7 +54,7 @@ abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp())); } - $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $this->getDescriptor()->describe($application)))); + $this->assertDescription($expectedDescription, $application); } public function getDescribeInputArgumentTestData() @@ -94,4 +95,11 @@ abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase return $data; } + + private function assertDescription($expectedDescription, $describedObject) + { + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); + $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true)); + $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch()))); + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json index 84b587e268..09adbd419a 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json @@ -1 +1 @@ -{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":null},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":null}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]} +{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]} diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md index ae815a8d5b..a789251ed2 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md @@ -51,7 +51,7 @@ To display the list of available commands, please use the list comm * Is value required: yes * Is multiple: no * Description: To output help in other formats -* Default: `NULL` +* Default: `'txt'` **raw:** @@ -196,4 +196,4 @@ It's also possible to get raw list of commands (useful for embedding command run * Is value required: yes * Is multiple: no * Description: To output list in other formats -* Default: `NULL` +* Default: `'txt'` diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml index d5c57be401..bfe5de0095 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml @@ -28,7 +28,9 @@ diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json index e0c4b9ad02..27745c15d2 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json @@ -1 +1 @@ -{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":null},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":null}}}},{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]} +{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}},{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}},{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message.","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message.","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version.","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output.","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output.","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question.","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]} diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md index bb242b7362..e52ecd3fc4 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md @@ -58,7 +58,7 @@ To display the list of available commands, please use the list comm * Is value required: yes * Is multiple: no * Description: To output help in other formats -* Default: `NULL` +* Default: `'txt'` **raw:** @@ -203,7 +203,7 @@ It's also possible to get raw list of commands (useful for embedding command run * Is value required: yes * Is multiple: no * Description: To output list in other formats -* Default: `NULL` +* Default: `'txt'` descriptor:command1 ------------------- diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml index 9aa77bbeec..9fc3a216f0 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml @@ -1,5 +1,5 @@ - + help [--xml] [--format="..."] [--raw] [command_name] @@ -28,7 +28,9 @@ diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt index 8e5a162504..dca37e2eda 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt @@ -17,4 +17,4 @@ help Displays help for a command list Lists commands foo - foo:bar The foo:bar command \ No newline at end of file + foo:bar The foo:bar command diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt index d27af91e4b..827c406ba7 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt @@ -13,4 +13,4 @@ --no-interaction -n Do not ask any interactive question. Available commands for the "foo" namespace: - foo:bar The foo:bar command \ No newline at end of file + foo:bar The foo:bar command diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt index 2eb3c3088a..94a68638f5 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt @@ -28,7 +28,9 @@ diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt index b9dab9a7e5..33c24427d8 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt @@ -7,7 +7,7 @@ Arguments: Options: --xml To output help as XML - --format To output help in other formats + --format To output help in other formats (default: "txt") --raw To output raw command help --help (-h) Display this help message. --quiet (-q) Do not output any message. @@ -27,4 +27,3 @@ Help: php app/console help --format=xml list To display the list of available commands, please use the list command. - diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt index 68bf516ded..0139775505 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt @@ -7,7 +7,7 @@ Arguments: Options: --xml To output list as XML --raw To output raw command list - --format To output list in other formats + --format To output list in other formats (default: "txt") Help: The list command lists all commands: @@ -25,4 +25,3 @@ Help: It's also possible to get raw list of commands (useful for embedding command runner): php app/console list --raw - diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php index e99ebc5778..774df268ba 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php @@ -59,7 +59,7 @@ class OutputFormatterStyleStackTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException \InvalidArgumentException */ public function testInvalidPop() { diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php index 118cc44dbb..7b21e4913c 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Tests\Helper; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; @@ -156,6 +157,18 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase } } + public function testNoInteration() + { + $dialog = new DialogHelper(); + + $input = new ArrayInput(array()); + $input->setInteractive(false); + + $dialog->setInput($input); + + $this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet')); + } + protected function getInputStream($input) { $stream = fopen('php://memory', 'r+', false); diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php index c9832736a2..a6ccde2d23 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php @@ -111,6 +111,23 @@ class HelperSetTest extends \PHPUnit_Framework_TestCase $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command'); } + /** + * @covers \Symfony\Component\Console\Helper\HelperSet::getIterator + */ + public function testIteration() + { + $helperset = new HelperSet(); + $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset)); + $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset)); + + $helpers = array('fake_helper_01', 'fake_helper_02'); + $i = 0; + + foreach ($helperset as $helper) { + $this->assertEquals($helpers[$i++], $helper->getName()); + } + } + /** * Create a generic mock for the helper interface. Optionally check for a call to setHelperSet with a specific * helperset instance. diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php index 266cc3d1c3..40d856f542 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressHelperTest.php @@ -166,6 +166,20 @@ class ProgressHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->generateOutput(' 3 [■■■>------------------------]'), stream_get_contents($output->getStream())); } + public function testClear() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 50); + $progress->setCurrent(25); + $progress->clear(); + + rewind($output->getStream()); + $this->assertEquals( + $this->generateOutput(' 25/50 [==============>-------------] 50%') . $this->generateOutput(''), + stream_get_contents($output->getStream()) + ); + } + public function testPercentNotHundredBeforeComplete() { $progress = new ProgressHelper(); diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php index 5873a7fda6..0c9629aa90 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableHelperTest.php @@ -81,15 +81,17 @@ class TableHelperTest extends \PHPUnit_Framework_TestCase public function testRenderProvider() { + $books = array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ); + return array( array( array('ISBN', 'Title', 'Author'), - array( - array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), - array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), - array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), - array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), - ), + $books, TableHelper::LAYOUT_DEFAULT, <<setVerbosity(Output::VERBOSITY_QUIET); $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity'); + + $this->assertTrue($output->isQuiet()); + $this->assertFalse($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_NORMAL); + $this->assertFalse($output->isQuiet()); + $this->assertFalse($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_VERBOSE); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertTrue($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_DEBUG); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertTrue($output->isVeryVerbose()); + $this->assertTrue($output->isDebug()); } public function testWriteWithVerbosityQuiet() diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php index 6ce30ab0fc..a8389dd186 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php @@ -61,4 +61,9 @@ class ApplicationTesterTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution'); } + + public function testGetStatusCode() + { + $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code'); + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php index da5bf84e22..b54c00e83d 100644 --- a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php +++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Tests\Tester; +use Symfony\Component\Console\Application; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Tester\CommandTester; @@ -59,4 +60,25 @@ class CommandTesterTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution'); } + + public function testGetStatusCode() + { + $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code'); + } + + public function testCommandFromApplication() + { + $application = new Application(); + $application->setAutoExit(false); + + $command = new Command('foo'); + $command->setCode(function ($input, $output) { $output->writeln('foo'); }); + + $application->add($command); + + $tester = new CommandTester($application->find('foo')); + + // check that there is no need to pass the command name here + $this->assertEquals(0, $tester->execute(array())); + } } diff --git a/vendor/symfony/console/Symfony/Component/Console/composer.json b/vendor/symfony/console/Symfony/Component/Console/composer.json index 472b4f23c2..77777aa4b2 100644 --- a/vendor/symfony/console/Symfony/Component/Console/composer.json +++ b/vendor/symfony/console/Symfony/Component/Console/composer.json @@ -31,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } } } diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml index 5542b0dc63..ac0efa88d1 100644 --- a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml +++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml @@ -56,7 +56,7 @@ test: Simple Mapping brief: | You can add a keyed list (also known as a dictionary or hash) to your document by placing each member of the - list on a new line, with a colon seperating the key + list on a new line, with a colon separating the key from its value. In YAML, this type of list is called a mapping. yaml: | diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml index 6f99f75453..1e59f3bf98 100644 --- a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml +++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml @@ -222,7 +222,7 @@ yaml: | # Following node labeled SS - &SS Sammy Sosa rbi: - - *SS # Subsequent occurance + - *SS # Subsequent occurrence - Ken Griffey php: | array( diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml index 9972c1f0d9..aac4e68077 100644 --- a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml +++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml @@ -226,11 +226,11 @@ brief: > time zone. yaml: | iso8601: 2001-12-14t21:59:43.10-05:00 - space seperated: 2001-12-14 21:59:43.10 -05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 php: | array( 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), - 'space seperated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ) + 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ) ) --- test: Date diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php index af5018f202..dc497ca21c 100644 --- a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php @@ -196,7 +196,6 @@ class InlineTest extends \PHPUnit_Framework_TestCase '.Inf' => -log(0), '-.Inf' => log(0), "'686e444'" => '686e444', - '.Inf' => 646e444, '"foo\r\nbar"' => "foo\r\nbar", "'foo#bar'" => 'foo#bar', "'foo # bar'" => 'foo # bar', diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json b/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json index 1a009c16d6..33c2985354 100644 --- a/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json +++ b/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.4-dev" } } }