summaryrefslogtreecommitdiff
path: root/vendor/pimple
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/pimple')
-rw-r--r--vendor/pimple/pimple/.gitignore3
-rw-r--r--vendor/pimple/pimple/.travis.yml32
-rw-r--r--vendor/pimple/pimple/CHANGELOG35
-rw-r--r--vendor/pimple/pimple/LICENSE19
-rw-r--r--vendor/pimple/pimple/README.rst201
-rw-r--r--vendor/pimple/pimple/composer.json25
-rw-r--r--vendor/pimple/pimple/ext/pimple/.gitignore30
-rw-r--r--vendor/pimple/pimple/ext/pimple/README.md12
-rw-r--r--vendor/pimple/pimple/ext/pimple/config.m463
-rw-r--r--vendor/pimple/pimple/ext/pimple/config.w3213
-rw-r--r--vendor/pimple/pimple/ext/pimple/php_pimple.h121
-rw-r--r--vendor/pimple/pimple/ext/pimple/pimple.c922
-rw-r--r--vendor/pimple/pimple/ext/pimple/pimple_compat.h81
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/001.phpt45
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/002.phpt15
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/003.phpt16
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/004.phpt30
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/005.phpt27
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/006.phpt51
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/007.phpt22
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/008.phpt29
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/009.phpt13
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/010.phpt45
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/011.phpt19
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/012.phpt28
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/013.phpt33
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/014.phpt30
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/015.phpt17
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/016.phpt24
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/017.phpt17
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/017_1.phpt17
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/018.phpt23
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/019.phpt18
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/bench.phpb51
-rw-r--r--vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb25
-rw-r--r--vendor/pimple/pimple/phpunit.xml.dist14
-rw-r--r--vendor/pimple/pimple/src/Pimple/Container.php282
-rw-r--r--vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php46
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php38
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php34
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php54
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php35
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php76
-rw-r--r--vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php440
44 files changed, 3171 insertions, 0 deletions
diff --git a/vendor/pimple/pimple/.gitignore b/vendor/pimple/pimple/.gitignore
new file mode 100644
index 00000000..c089b095
--- /dev/null
+++ b/vendor/pimple/pimple/.gitignore
@@ -0,0 +1,3 @@
+phpunit.xml
+composer.lock
+/vendor/
diff --git a/vendor/pimple/pimple/.travis.yml b/vendor/pimple/pimple/.travis.yml
new file mode 100644
index 00000000..5f8bb7c9
--- /dev/null
+++ b/vendor/pimple/pimple/.travis.yml
@@ -0,0 +1,32 @@
+language: php
+
+env:
+ matrix:
+ - PIMPLE_EXT=no
+ - PIMPLE_EXT=yes
+ global:
+ - REPORT_EXIT_STATUS=1
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+before_script:
+ - composer self-update
+ - COMPOSER_ROOT_VERSION=dev-master composer dump-autoload
+ - if [ "$PIMPLE_EXT" == "yes" ]; then sh -c "cd ext/pimple && phpize && ./configure && make && sudo make install"; fi
+ - if [ "$PIMPLE_EXT" == "yes" ]; then echo "extension=pimple.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
+
+script:
+ - cd ext/pimple
+ - if [ "$PIMPLE_EXT" == "yes" ]; then yes n | make test | tee output ; grep -E 'Tests failed +. +0' output; fi
+ - cd ../..
+ - phpunit
+
+matrix:
+ exclude:
+ - php: hhvm
+ env: PIMPLE_EXT=yes
diff --git a/vendor/pimple/pimple/CHANGELOG b/vendor/pimple/pimple/CHANGELOG
new file mode 100644
index 00000000..cc679972
--- /dev/null
+++ b/vendor/pimple/pimple/CHANGELOG
@@ -0,0 +1,35 @@
+* 3.0.2 (2015-09-11)
+
+ * refactored the C extension
+ * minor non-significant changes
+
+* 3.0.1 (2015-07-30)
+
+ * simplified some code
+ * fixed a segfault in the C extension
+
+* 3.0.0 (2014-07-24)
+
+ * removed the Pimple class alias (use Pimple\Container instead)
+
+* 2.1.1 (2014-07-24)
+
+ * fixed compiler warnings for the C extension
+ * fixed code when dealing with circular references
+
+* 2.1.0 (2014-06-24)
+
+ * moved the Pimple to Pimple\Container (with a BC layer -- Pimple is now a
+ deprecated alias which will be removed in Pimple 3.0)
+ * added Pimple\ServiceProviderInterface (and Pimple::register())
+
+* 2.0.0 (2014-02-10)
+
+ * changed extend to automatically re-assign the extended service and keep it as shared or factory
+ (to keep BC, extend still returns the extended service)
+ * changed services to be shared by default (use factory() for factory
+ services)
+
+* 1.0.0
+
+ * initial version
diff --git a/vendor/pimple/pimple/LICENSE b/vendor/pimple/pimple/LICENSE
new file mode 100644
index 00000000..d7949e2f
--- /dev/null
+++ b/vendor/pimple/pimple/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2009-2015 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/pimple/pimple/README.rst b/vendor/pimple/pimple/README.rst
new file mode 100644
index 00000000..93fb35a8
--- /dev/null
+++ b/vendor/pimple/pimple/README.rst
@@ -0,0 +1,201 @@
+Pimple
+======
+
+.. caution::
+
+ This is the documentation for Pimple 3.x. If you are using Pimple 1.x, read
+ the `Pimple 1.x documentation`_. Reading the Pimple 1.x code is also a good
+ way to learn more about how to create a simple Dependency Injection
+ Container (recent versions of Pimple are more focused on performance).
+
+Pimple is a small Dependency Injection Container for PHP.
+
+Installation
+------------
+
+Before using Pimple in your project, add it to your ``composer.json`` file:
+
+.. code-block:: bash
+
+ $ ./composer.phar require pimple/pimple ~3.0
+
+Alternatively, Pimple is also available as a PHP C extension:
+
+.. code-block:: bash
+
+ $ git clone https://github.com/silexphp/Pimple
+ $ cd Pimple/ext/pimple
+ $ phpize
+ $ ./configure
+ $ make
+ $ make install
+
+Usage
+-----
+
+Creating a container is a matter of creating a ``Container`` instance:
+
+.. code-block:: php
+
+ use Pimple\Container;
+
+ $container = new Container();
+
+As many other dependency injection containers, Pimple manages two different
+kind of data: **services** and **parameters**.
+
+Defining Services
+~~~~~~~~~~~~~~~~~
+
+A service is an object that does something as part of a larger system. Examples
+of services: a database connection, a templating engine, or a mailer. Almost
+any **global** object can be a service.
+
+Services are defined by **anonymous functions** that return an instance of an
+object:
+
+.. code-block:: php
+
+ // define some services
+ $container['session_storage'] = function ($c) {
+ return new SessionStorage('SESSION_ID');
+ };
+
+ $container['session'] = function ($c) {
+ return new Session($c['session_storage']);
+ };
+
+Notice that the anonymous function has access to the current container
+instance, allowing references to other services or parameters.
+
+As objects are only created when you get them, the order of the definitions
+does not matter.
+
+Using the defined services is also very easy:
+
+.. code-block:: php
+
+ // get the session object
+ $session = $container['session'];
+
+ // the above call is roughly equivalent to the following code:
+ // $storage = new SessionStorage('SESSION_ID');
+ // $session = new Session($storage);
+
+Defining Factory Services
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, each time you get a service, Pimple returns the **same instance**
+of it. If you want a different instance to be returned for all calls, wrap your
+anonymous function with the ``factory()`` method
+
+.. code-block:: php
+
+ $container['session'] = $container->factory(function ($c) {
+ return new Session($c['session_storage']);
+ });
+
+Now, each call to ``$container['session']`` returns a new instance of the
+session.
+
+Defining Parameters
+~~~~~~~~~~~~~~~~~~~
+
+Defining a parameter allows to ease the configuration of your container from
+the outside and to store global values:
+
+.. code-block:: php
+
+ // define some parameters
+ $container['cookie_name'] = 'SESSION_ID';
+ $container['session_storage_class'] = 'SessionStorage';
+
+If you change the ``session_storage`` service definition like below:
+
+.. code-block:: php
+
+ $container['session_storage'] = function ($c) {
+ return new $c['session_storage_class']($c['cookie_name']);
+ };
+
+You can now easily change the cookie name by overriding the
+``session_storage_class`` parameter instead of redefining the service
+definition.
+
+Protecting Parameters
+~~~~~~~~~~~~~~~~~~~~~
+
+Because Pimple sees anonymous functions as service definitions, you need to
+wrap anonymous functions with the ``protect()`` method to store them as
+parameters:
+
+.. code-block:: php
+
+ $container['random_func'] = $container->protect(function () {
+ return rand();
+ });
+
+Modifying Services after Definition
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In some cases you may want to modify a service definition after it has been
+defined. You can use the ``extend()`` method to define additional code to be
+run on your service just after it is created:
+
+.. code-block:: php
+
+ $container['session_storage'] = function ($c) {
+ return new $c['session_storage_class']($c['cookie_name']);
+ };
+
+ $container->extend('session_storage', function ($storage, $c) {
+ $storage->...();
+
+ return $storage;
+ });
+
+The first argument is the name of the service to extend, the second a function
+that gets access to the object instance and the container.
+
+Extending a Container
+~~~~~~~~~~~~~~~~~~~~~
+
+If you use the same libraries over and over, you might want to reuse some
+services from one project to the next one; package your services into a
+**provider** by implementing ``Pimple\ServiceProviderInterface``:
+
+.. code-block:: php
+
+ use Pimple\Container;
+
+ class FooProvider implements Pimple\ServiceProviderInterface
+ {
+ public function register(Container $pimple)
+ {
+ // register some services and parameters
+ // on $pimple
+ }
+ }
+
+Then, register the provider on a Container:
+
+.. code-block:: php
+
+ $pimple->register(new FooProvider());
+
+Fetching the Service Creation Function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you access an object, Pimple automatically calls the anonymous function
+that you defined, which creates the service object for you. If you want to get
+raw access to this function, you can use the ``raw()`` method:
+
+.. code-block:: php
+
+ $container['session'] = function ($c) {
+ return new Session($c['session_storage']);
+ };
+
+ $sessionFunction = $container->raw('session');
+
+.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1
diff --git a/vendor/pimple/pimple/composer.json b/vendor/pimple/pimple/composer.json
new file mode 100644
index 00000000..a5268f16
--- /dev/null
+++ b/vendor/pimple/pimple/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "pimple/pimple",
+ "type": "library",
+ "description": "Pimple, a simple Dependency Injection Container",
+ "keywords": ["dependency injection", "container"],
+ "homepage": "http://pimple.sensiolabs.org",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-0": { "Pimple": "src/" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/pimple/pimple/ext/pimple/.gitignore b/vendor/pimple/pimple/ext/pimple/.gitignore
new file mode 100644
index 00000000..1861088a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/.gitignore
@@ -0,0 +1,30 @@
+*.sw*
+.deps
+Makefile
+Makefile.fragments
+Makefile.global
+Makefile.objects
+acinclude.m4
+aclocal.m4
+build/
+config.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.nice
+config.status
+config.sub
+configure
+configure.in
+install-sh
+libtool
+ltmain.sh
+missing
+mkinstalldirs
+run-tests.php
+*.loT
+.libs/
+modules/
+*.la
+*.lo
diff --git a/vendor/pimple/pimple/ext/pimple/README.md b/vendor/pimple/pimple/ext/pimple/README.md
new file mode 100644
index 00000000..7b39eb29
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/README.md
@@ -0,0 +1,12 @@
+This is Pimple 2 implemented in C
+
+* PHP >= 5.3
+* Not tested under Windows, might work
+
+Install
+=======
+
+ > phpize
+ > ./configure
+ > make
+ > make install
diff --git a/vendor/pimple/pimple/ext/pimple/config.m4 b/vendor/pimple/pimple/ext/pimple/config.m4
new file mode 100644
index 00000000..c9ba17dd
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/config.m4
@@ -0,0 +1,63 @@
+dnl $Id$
+dnl config.m4 for extension pimple
+
+dnl Comments in this file start with the string 'dnl'.
+dnl Remove where necessary. This file will not work
+dnl without editing.
+
+dnl If your extension references something external, use with:
+
+dnl PHP_ARG_WITH(pimple, for pimple support,
+dnl Make sure that the comment is aligned:
+dnl [ --with-pimple Include pimple support])
+
+dnl Otherwise use enable:
+
+PHP_ARG_ENABLE(pimple, whether to enable pimple support,
+dnl Make sure that the comment is aligned:
+[ --enable-pimple Enable pimple support])
+
+if test "$PHP_PIMPLE" != "no"; then
+ dnl Write more examples of tests here...
+
+ dnl # --with-pimple -> check with-path
+ dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
+ dnl SEARCH_FOR="/include/pimple.h" # you most likely want to change this
+ dnl if test -r $PHP_PIMPLE/$SEARCH_FOR; then # path given as parameter
+ dnl PIMPLE_DIR=$PHP_PIMPLE
+ dnl else # search default path list
+ dnl AC_MSG_CHECKING([for pimple files in default path])
+ dnl for i in $SEARCH_PATH ; do
+ dnl if test -r $i/$SEARCH_FOR; then
+ dnl PIMPLE_DIR=$i
+ dnl AC_MSG_RESULT(found in $i)
+ dnl fi
+ dnl done
+ dnl fi
+ dnl
+ dnl if test -z "$PIMPLE_DIR"; then
+ dnl AC_MSG_RESULT([not found])
+ dnl AC_MSG_ERROR([Please reinstall the pimple distribution])
+ dnl fi
+
+ dnl # --with-pimple -> add include path
+ dnl PHP_ADD_INCLUDE($PIMPLE_DIR/include)
+
+ dnl # --with-pimple -> check for lib and symbol presence
+ dnl LIBNAME=pimple # you may want to change this
+ dnl LIBSYMBOL=pimple # you most likely want to change this
+
+ dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
+ dnl [
+ dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $PIMPLE_DIR/lib, PIMPLE_SHARED_LIBADD)
+ dnl AC_DEFINE(HAVE_PIMPLELIB,1,[ ])
+ dnl ],[
+ dnl AC_MSG_ERROR([wrong pimple lib version or lib not found])
+ dnl ],[
+ dnl -L$PIMPLE_DIR/lib -lm
+ dnl ])
+ dnl
+ dnl PHP_SUBST(PIMPLE_SHARED_LIBADD)
+
+ PHP_NEW_EXTENSION(pimple, pimple.c, $ext_shared)
+fi
diff --git a/vendor/pimple/pimple/ext/pimple/config.w32 b/vendor/pimple/pimple/ext/pimple/config.w32
new file mode 100644
index 00000000..39857b32
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/config.w32
@@ -0,0 +1,13 @@
+// $Id$
+// vim:ft=javascript
+
+// If your extension references something external, use ARG_WITH
+// ARG_WITH("pimple", "for pimple support", "no");
+
+// Otherwise, use ARG_ENABLE
+// ARG_ENABLE("pimple", "enable pimple support", "no");
+
+if (PHP_PIMPLE != "no") {
+ EXTENSION("pimple", "pimple.c");
+}
+
diff --git a/vendor/pimple/pimple/ext/pimple/php_pimple.h b/vendor/pimple/pimple/ext/pimple/php_pimple.h
new file mode 100644
index 00000000..49431f08
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/php_pimple.h
@@ -0,0 +1,121 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PHP_PIMPLE_H
+#define PHP_PIMPLE_H
+
+extern zend_module_entry pimple_module_entry;
+#define phpext_pimple_ptr &pimple_module_entry
+
+#ifdef PHP_WIN32
+# define PHP_PIMPLE_API __declspec(dllexport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define PHP_PIMPLE_API __attribute__ ((visibility("default")))
+#else
+# define PHP_PIMPLE_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#define PIMPLE_VERSION "3.0.2"
+#define PIMPLE_NS "Pimple"
+
+#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5
+#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10
+
+zend_module_entry *get_module(void);
+
+PHP_MINIT_FUNCTION(pimple);
+PHP_MINFO_FUNCTION(pimple);
+
+PHP_METHOD(Pimple, __construct);
+PHP_METHOD(Pimple, factory);
+PHP_METHOD(Pimple, protect);
+PHP_METHOD(Pimple, raw);
+PHP_METHOD(Pimple, extend);
+PHP_METHOD(Pimple, keys);
+PHP_METHOD(Pimple, register);
+PHP_METHOD(Pimple, offsetSet);
+PHP_METHOD(Pimple, offsetUnset);
+PHP_METHOD(Pimple, offsetGet);
+PHP_METHOD(Pimple, offsetExists);
+
+PHP_METHOD(PimpleClosure, invoker);
+
+typedef struct _pimple_bucket_value {
+ zval *value; /* Must be the first element */
+ zval *raw;
+ zend_object_handle handle_num;
+ enum {
+ PIMPLE_IS_PARAM = 0,
+ PIMPLE_IS_SERVICE = 2
+ } type;
+ zend_bool initialized;
+ zend_fcall_info_cache fcc;
+} pimple_bucket_value;
+
+typedef struct _pimple_object {
+ zend_object zobj;
+ HashTable values;
+ HashTable factories;
+ HashTable protected;
+} pimple_object;
+
+typedef struct _pimple_closure_object {
+ zend_object zobj;
+ zval *callable;
+ zval *factory;
+} pimple_closure_object;
+
+static const char sensiolabs_logo[] = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAUCAMAAABvRTlyAAAAz1BMVEUAAAAAAAAAAAAsThWB5j4AAACD6T8AAACC6D+C6D6C6D+C6D4AAAAAAACC6D4AAAAAAACC6D8AAAAAAAAAAAAAAAAAAAAAAACC6D4AAAAAAAAAAACC6D4AAAAAAAAAAAAAAAAAAAAAAACC6D8AAACC6D4AAAAAAAAAAAAAAAAAAACC6D8AAACC6D6C6D+B6D+C6D+C6D+C6D8AAACC6D6C6D4AAACC6D/K/2KC6D+B6D6C6D6C6D+C6D8sTxUyWRhEeiEAAACC6D+C5z6B6D7drnEVAAAAQXRSTlMAE3oCNSUuDHFHzxaF9UFsu+irX+zlKzYimaJXktyOSFD6BolxqT7QGMMdarMIpuO28r9EolXKgR16OphfXYd4V14GtB4AAAMpSURBVEjHvVSJctowEF1jjME2RziMwUCoMfd9heZqG4n//6buLpJjkmYm03byZmxJa2nf6u2uQcG2bfhqRN4LoTKBzyGDm68M7mAwcOEdjo4zhA/Rf9Go/CVtTgiRhXfIC3EDH8F/eUX1/9KexRo+QgOdtHDsEe/sM7QT32/+K61Z1LFXcXJxN4pTbu1aTQUzuy2PIA0rDo0/0Aa5XFaJvKaVTrubywXvaa1Wq4Vu/Snr3Y7Aojh4VccwykW2N2oQ8wmjyut6+Q1t5ywIG5Npj1sh5E0B7YOzFDjfuRfaOh3O+MbbVNfTWS9COZk3Obd2su5d0a6IU9KLREbw8gEehWSr1r2sPWciXLG38r5NdW0xu9eioU87omjC9yNaMi5GNf6WppVSOqXCFkmCvMB3p9SROLoYQn5pDgQOujA1xjYvqH+plUdkwnmII8VxR/PKYkrfLLomhVlE3b/LhNbNr7hp0H2JaOc4v8dFB58HSsFTSafaqtY1sT3GO8wsy5rhokYPlRJdjPMajyYqTt1EHF/2uqSWQWmAjCUSmQ1MS3g8Btf1XOsy7YIC0CB1b5Xw1Vhba0zbxiCAQLH9TNPmHJXQUtJAN0KcDsoqLxsNvJrJExa7mKIdp2lRE2WexiS4pqWk/0jROlw6K6bV9YOBDGAuqMJ0bnuUKGB0L27bxgRhGEbzihbhxxXaQC88Vkwq8ldCi86RApWUb0Q+4VDosBCc+1s81lUdnBavH4Zp2mm3O44USwOfvSo9oBiwpFg71lMS1VKJLKljS3j9p+fOTvXXlsSNuEv6YPaZda9uRope0VJfKdo7fPiYfSmvFjXQbkhY0d9hCbBWIktRgEDieDhf1N3wbbkmNNgRy8hyl620yGQat/grV3HMpc2HDKTVmOPFz6ylPCKt/nXcAyV260jaAowwIW0YuBzrOgb/KrddZS9OmJaLgpWK4JX2DDuklcLZSDGcn8Vmx9YDNvT6UsjyBApRyFQVX7Vxm9TGxE16nmfRd8/zQoDmggQOTRh5Hv8pMt9Q/L2JmSwkMCE7dA4BuDjHJwfu0Om4QAhOjrN5XkIatglfiN/bUPdCQFjTYgAAAABJRU5ErkJggg==\">";
+
+static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
+static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC);
+
+static void pimple_bucket_dtor(pimple_bucket_value *bucket);
+static void pimple_free_bucket(pimple_bucket_value *bucket);
+
+static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
+static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
+static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
+static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC);
+static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC);
+static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC);
+
+static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC);
+static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC);
+static zend_function *pimple_closure_get_constructor(zval * TSRMLS_DC);
+static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC);
+
+#ifdef ZTS
+#define PIMPLE_G(v) TSRMG(pimple_globals_id, zend_pimple_globals *, v)
+#else
+#define PIMPLE_G(v) (pimple_globals.v)
+#endif
+
+#endif /* PHP_PIMPLE_H */
+
diff --git a/vendor/pimple/pimple/ext/pimple/pimple.c b/vendor/pimple/pimple/ext/pimple/pimple.c
new file mode 100644
index 00000000..239c01d6
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/pimple.c
@@ -0,0 +1,922 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_pimple.h"
+#include "pimple_compat.h"
+#include "zend_interfaces.h"
+#include "zend.h"
+#include "Zend/zend_closures.h"
+#include "ext/spl/spl_exceptions.h"
+#include "Zend/zend_exceptions.h"
+#include "main/php_output.h"
+#include "SAPI.h"
+
+static zend_class_entry *pimple_ce;
+static zend_object_handlers pimple_object_handlers;
+static zend_class_entry *pimple_closure_ce;
+static zend_class_entry *pimple_serviceprovider_ce;
+static zend_object_handlers pimple_closure_object_handlers;
+static zend_internal_function pimple_closure_invoker_function;
+
+#define FETCH_DIM_HANDLERS_VARS pimple_object *pimple_obj = NULL; \
+ ulong index; \
+ pimple_obj = (pimple_object *)zend_object_store_get_object(object TSRMLS_CC); \
+
+#define PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS do { \
+ if (ce != pimple_ce) { \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetget"), (void **)&function); \
+ if (function->common.scope != ce) { /* if the function is not defined in this actual class */ \
+ pimple_object_handlers.read_dimension = pimple_object_read_dimension; /* then overwrite the handler to use custom one */ \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetset"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetexists"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
+ } \
+ zend_hash_find(&ce->function_table, ZEND_STRS("offsetunset"), (void **)&function); \
+ if (function->common.scope != ce) { \
+ pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
+ } \
+ } else { \
+ pimple_object_handlers.read_dimension = pimple_object_read_dimension; \
+ pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
+ pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
+ pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
+ }\
+ } while(0);
+
+#define PIMPLE_CALL_CB do { \
+ zend_fcall_info_argn(&fci TSRMLS_CC, 1, &object); \
+ fci.size = sizeof(fci); \
+ fci.object_ptr = retval->fcc.object_ptr; \
+ fci.function_name = retval->value; \
+ fci.no_separation = 1; \
+ fci.retval_ptr_ptr = &retval_ptr_ptr; \
+\
+ zend_call_function(&fci, &retval->fcc TSRMLS_CC); \
+ efree(fci.params); \
+ if (EG(exception)) { \
+ return EG(uninitialized_zval_ptr); \
+ } \
+ } while(0);
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0)
+ZEND_ARG_ARRAY_INFO(0, value, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetset, 0, 0, 2)
+ZEND_ARG_INFO(0, offset)
+ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetget, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetexists, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetunset, 0, 0, 1)
+ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_factory, 0, 0, 1)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_protect, 0, 0, 1)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_raw, 0, 0, 1)
+ZEND_ARG_INFO(0, id)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_extend, 0, 0, 2)
+ZEND_ARG_INFO(0, id)
+ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_keys, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_register, 0, 0, 1)
+ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0)
+ZEND_ARG_ARRAY_INFO(0, values, 1)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
+ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry pimple_ce_functions[] = {
+ PHP_ME(Pimple, __construct, arginfo___construct, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, factory, arginfo_factory, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, protect, arginfo_protect, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, raw, arginfo_raw, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, extend, arginfo_extend, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, keys, arginfo_keys, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, register, arginfo_register, ZEND_ACC_PUBLIC)
+
+ PHP_ME(Pimple, offsetSet, arginfo_offsetset, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetGet, arginfo_offsetget, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetExists, arginfo_offsetexists, ZEND_ACC_PUBLIC)
+ PHP_ME(Pimple, offsetUnset, arginfo_offsetunset, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = {
+ PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
+ PHP_FE_END
+};
+
+static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC)
+{
+ zend_object_std_dtor(&obj->zobj TSRMLS_CC);
+ if (obj->factory) {
+ zval_ptr_dtor(&obj->factory);
+ }
+ if (obj->callable) {
+ zval_ptr_dtor(&obj->callable);
+ }
+ efree(obj);
+}
+
+static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC)
+{
+ zend_hash_destroy(&obj->factories);
+ zend_hash_destroy(&obj->protected);
+ zend_hash_destroy(&obj->values);
+ zend_object_std_dtor(&obj->zobj TSRMLS_CC);
+ efree(obj);
+}
+
+static void pimple_free_bucket(pimple_bucket_value *bucket)
+{
+ if (bucket->raw) {
+ zval_ptr_dtor(&bucket->raw);
+ }
+}
+
+static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ pimple_closure_object *pimple_closure_obj = NULL;
+
+ pimple_closure_obj = ecalloc(1, sizeof(pimple_closure_object));
+ ZEND_OBJ_INIT(&pimple_closure_obj->zobj, ce);
+
+ pimple_closure_object_handlers.get_constructor = pimple_closure_get_constructor;
+ retval.handlers = &pimple_closure_object_handlers;
+ retval.handle = zend_objects_store_put(pimple_closure_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_closure_free_object_storage, NULL TSRMLS_CC);
+
+ return retval;
+}
+
+static zend_function *pimple_closure_get_constructor(zval *obj TSRMLS_DC)
+{
+ zend_error(E_ERROR, "Pimple\\ContainerClosure is an internal class and cannot be instantiated");
+
+ return NULL;
+}
+
+static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC)
+{
+ *zobj_ptr = obj;
+ *ce_ptr = Z_OBJCE_P(obj);
+ *fptr_ptr = (zend_function *)&pimple_closure_invoker_function;
+
+ return SUCCESS;
+}
+
+static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ pimple_object *pimple_obj = NULL;
+ zend_function *function = NULL;
+
+ pimple_obj = emalloc(sizeof(pimple_object));
+ ZEND_OBJ_INIT(&pimple_obj->zobj, ce);
+
+ PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS
+
+ retval.handlers = &pimple_object_handlers;
+ retval.handle = zend_objects_store_put(pimple_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_free_object_storage, NULL TSRMLS_CC);
+
+ zend_hash_init(&pimple_obj->factories, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+ zend_hash_init(&pimple_obj->protected, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+ zend_hash_init(&pimple_obj->values, PIMPLE_DEFAULT_ZVAL_VALUES_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
+
+ return retval;
+}
+
+static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value pimple_value = {0}, *found_value = NULL;
+ ulong hash;
+
+ pimple_zval_to_pimpleval(value, &pimple_value TSRMLS_CC);
+
+ if (!offset) {/* $p[] = 'foo' when not overloaded */
+ zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(value);
+ return;
+ }
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ hash = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value);
+ if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
+ pimple_free_bucket(&pimple_value);
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%s\".", Z_STRVAL_P(offset));
+ return;
+ }
+ if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
+ pimple_free_bucket(&pimple_value);
+ return;
+ }
+ Z_ADDREF_P(value);
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value);
+ if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
+ pimple_free_bucket(&pimple_value);
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%ld\".", index);
+ return;
+ }
+ if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
+ pimple_free_bucket(&pimple_value);
+ return;
+ }
+ Z_ADDREF_P(value);
+ break;
+ case IS_NULL: /* $p[] = 'foo' when overloaded */
+ zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(value);
+ break;
+ default:
+ pimple_free_bucket(&pimple_value);
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+}
+
+static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ zend_symtable_del(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_symtable_del(&pimple_obj->factories, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ zend_symtable_del(&pimple_obj->protected, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ zend_hash_index_del(&pimple_obj->values, index);
+ zend_hash_index_del(&pimple_obj->factories, index);
+ zend_hash_index_del(&pimple_obj->protected, index);
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+}
+
+static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value *retval = NULL;
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == SUCCESS) {
+ switch (check_empty) {
+ case 0: /* isset */
+ return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;) */
+ case 1: /* empty */
+ default:
+ return zend_is_true(retval->value);
+ }
+ }
+ return 0;
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == SUCCESS) {
+ switch (check_empty) {
+ case 0: /* isset */
+ return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;)*/
+ case 1: /* empty */
+ default:
+ return zend_is_true(retval->value);
+ }
+ }
+ return 0;
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ return 0;
+ }
+}
+
+static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
+{
+ FETCH_DIM_HANDLERS_VARS
+
+ pimple_bucket_value *retval = NULL;
+ zend_fcall_info fci = {0};
+ zval *retval_ptr_ptr = NULL;
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ return EG(uninitialized_zval_ptr);
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == FAILURE) {
+ return EG(uninitialized_zval_ptr);
+ }
+ break;
+ case IS_NULL: /* $p[][3] = 'foo' first dim access */
+ return EG(uninitialized_zval_ptr);
+ break;
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ return EG(uninitialized_zval_ptr);
+ }
+
+ if(retval->type == PIMPLE_IS_PARAM) {
+ return retval->value;
+ }
+
+ if (zend_hash_index_exists(&pimple_obj->protected, retval->handle_num)) {
+ /* Service is protected, return the value every time */
+ return retval->value;
+ }
+
+ if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) {
+ /* Service is a factory, call it everytime and never cache its result */
+ PIMPLE_CALL_CB
+ Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */
+ return retval_ptr_ptr;
+ }
+
+ if (retval->initialized == 1) {
+ /* Service has already been called, return its cached value */
+ return retval->value;
+ }
+
+ ALLOC_INIT_ZVAL(retval->raw);
+ MAKE_COPY_ZVAL(&retval->value, retval->raw);
+
+ PIMPLE_CALL_CB
+
+ retval->initialized = 1;
+ zval_ptr_dtor(&retval->value);
+ retval->value = retval_ptr_ptr;
+
+ return retval->value;
+}
+
+static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
+{
+ if (Z_TYPE_P(_zval) != IS_OBJECT) {
+ return FAILURE;
+ }
+
+ if (_pimple_bucket_value->fcc.called_scope) {
+ return SUCCESS;
+ }
+
+ if (Z_OBJ_HANDLER_P(_zval, get_closure) && Z_OBJ_HANDLER_P(_zval, get_closure)(_zval, &_pimple_bucket_value->fcc.calling_scope, &_pimple_bucket_value->fcc.function_handler, &_pimple_bucket_value->fcc.object_ptr TSRMLS_CC) == SUCCESS) {
+ _pimple_bucket_value->fcc.called_scope = _pimple_bucket_value->fcc.calling_scope;
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+
+static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
+{
+ _pimple_bucket_value->value = _zval;
+
+ if (Z_TYPE_P(_zval) != IS_OBJECT) {
+ return PIMPLE_IS_PARAM;
+ }
+
+ if (pimple_zval_is_valid_callback(_zval, _pimple_bucket_value TSRMLS_CC) == SUCCESS) {
+ _pimple_bucket_value->type = PIMPLE_IS_SERVICE;
+ _pimple_bucket_value->handle_num = Z_OBJ_HANDLE_P(_zval);
+ }
+
+ return PIMPLE_IS_SERVICE;
+}
+
+static void pimple_bucket_dtor(pimple_bucket_value *bucket)
+{
+ zval_ptr_dtor(&bucket->value);
+ pimple_free_bucket(bucket);
+}
+
+PHP_METHOD(Pimple, protect)
+{
+ zval *protected = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value bucket = {0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &protected) == FAILURE) {
+ return;
+ }
+
+ if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
+ return;
+ }
+
+ pimple_zval_to_pimpleval(protected, &bucket TSRMLS_CC);
+ pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (zend_hash_index_update(&pobj->protected, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
+ Z_ADDREF_P(protected);
+ RETURN_ZVAL(protected, 1 , 0);
+ } else {
+ pimple_free_bucket(&bucket);
+ }
+ RETURN_FALSE;
+}
+
+PHP_METHOD(Pimple, raw)
+{
+ zval *offset = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value *value = NULL;
+ ulong index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
+ RETURN_NULL();
+ }
+ break;
+ case IS_NULL:
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+
+ if (value->raw) {
+ RETVAL_ZVAL(value->raw, 1, 0);
+ } else {
+ RETVAL_ZVAL(value->value, 1, 0);
+ }
+}
+
+PHP_METHOD(Pimple, extend)
+{
+ zval *offset = NULL, *callable = NULL, *pimple_closure_obj = NULL;
+ pimple_bucket_value bucket = {0}, *value = NULL;
+ pimple_object *pobj = NULL;
+ pimple_closure_object *pcobj = NULL;
+ ulong index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &callable) == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ switch (Z_TYPE_P(offset)) {
+ case IS_STRING:
+ if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" does not contain an object definition.", Z_STRVAL_P(offset));
+ RETURN_NULL();
+ }
+ break;
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_LONG:
+ if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ index = (ulong)Z_DVAL_P(offset);
+ } else {
+ index = Z_LVAL_P(offset);
+ }
+ if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" is not defined.", index);
+ RETURN_NULL();
+ }
+ if (value->type != PIMPLE_IS_SERVICE) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" does not contain an object definition.", index);
+ RETURN_NULL();
+ }
+ break;
+ case IS_NULL:
+ default:
+ zend_error(E_WARNING, "Unsupported offset type");
+ }
+
+ if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+ pimple_free_bucket(&bucket);
+
+ ALLOC_INIT_ZVAL(pimple_closure_obj);
+ object_init_ex(pimple_closure_obj, pimple_closure_ce);
+
+ pcobj = zend_object_store_get_object(pimple_closure_obj TSRMLS_CC);
+ pcobj->callable = callable;
+ pcobj->factory = value->value;
+ Z_ADDREF_P(callable);
+ Z_ADDREF_P(value->value);
+
+ if (zend_hash_index_exists(&pobj->factories, value->handle_num)) {
+ pimple_zval_to_pimpleval(pimple_closure_obj, &bucket TSRMLS_CC);
+ zend_hash_index_del(&pobj->factories, value->handle_num);
+ zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL);
+ Z_ADDREF_P(pimple_closure_obj);
+ }
+
+ pimple_object_write_dimension(getThis(), offset, pimple_closure_obj TSRMLS_CC);
+
+ RETVAL_ZVAL(pimple_closure_obj, 1, 1);
+}
+
+PHP_METHOD(Pimple, keys)
+{
+ HashPosition pos;
+ pimple_object *pobj = NULL;
+ zval **value = NULL;
+ zval *endval = NULL;
+ char *str_index = NULL;
+ int str_len;
+ ulong num_index;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+ array_init_size(return_value, zend_hash_num_elements(&pobj->values));
+
+ zend_hash_internal_pointer_reset_ex(&pobj->values, &pos);
+
+ while(zend_hash_get_current_data_ex(&pobj->values, (void **)&value, &pos) == SUCCESS) {
+ MAKE_STD_ZVAL(endval);
+ switch (zend_hash_get_current_key_ex(&pobj->values, &str_index, (uint *)&str_len, &num_index, 0, &pos)) {
+ case HASH_KEY_IS_STRING:
+ ZVAL_STRINGL(endval, str_index, str_len - 1, 1);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
+ break;
+ case HASH_KEY_IS_LONG:
+ ZVAL_LONG(endval, num_index);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
+ break;
+ }
+ zend_hash_move_forward_ex(&pobj->values, &pos);
+ }
+}
+
+PHP_METHOD(Pimple, factory)
+{
+ zval *factory = NULL;
+ pimple_object *pobj = NULL;
+ pimple_bucket_value bucket = {0};
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &factory) == FAILURE) {
+ return;
+ }
+
+ if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) {
+ pimple_free_bucket(&bucket);
+ zend_throw_exception(spl_ce_InvalidArgumentException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
+ return;
+ }
+
+ pimple_zval_to_pimpleval(factory, &bucket TSRMLS_CC);
+ pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
+ Z_ADDREF_P(factory);
+ RETURN_ZVAL(factory, 1 , 0);
+ } else {
+ pimple_free_bucket(&bucket);
+ }
+
+ RETURN_FALSE;
+}
+
+PHP_METHOD(Pimple, offsetSet)
+{
+ zval *offset = NULL, *value = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &value) == FAILURE) {
+ return;
+ }
+
+ pimple_object_write_dimension(getThis(), offset, value TSRMLS_CC);
+}
+
+PHP_METHOD(Pimple, offsetGet)
+{
+ zval *offset = NULL, *retval = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ retval = pimple_object_read_dimension(getThis(), offset, 0 TSRMLS_CC);
+
+ RETVAL_ZVAL(retval, 1, 0);
+}
+
+PHP_METHOD(Pimple, offsetUnset)
+{
+ zval *offset = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ pimple_object_unset_dimension(getThis(), offset TSRMLS_CC);
+}
+
+PHP_METHOD(Pimple, offsetExists)
+{
+ zval *offset = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ return;
+ }
+
+ RETVAL_BOOL(pimple_object_has_dimension(getThis(), offset, 1 TSRMLS_CC));
+}
+
+PHP_METHOD(Pimple, register)
+{
+ zval *provider;
+ zval **data;
+ zval *retval = NULL;
+ zval key;
+
+ HashTable *array = NULL;
+ HashPosition pos;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|h", &provider, pimple_serviceprovider_ce, &array) == FAILURE) {
+ return;
+ }
+
+ RETVAL_ZVAL(getThis(), 1, 0);
+
+ zend_call_method_with_1_params(&provider, Z_OBJCE_P(provider), NULL, "register", &retval, getThis());
+
+ if (retval) {
+ zval_ptr_dtor(&retval);
+ }
+
+ if (!array) {
+ return;
+ }
+
+ zend_hash_internal_pointer_reset_ex(array, &pos);
+
+ while(zend_hash_get_current_data_ex(array, (void **)&data, &pos) == SUCCESS) {
+ zend_hash_get_current_key_zval_ex(array, &key, &pos);
+ pimple_object_write_dimension(getThis(), &key, *data TSRMLS_CC);
+ zend_hash_move_forward_ex(array, &pos);
+ }
+}
+
+PHP_METHOD(Pimple, __construct)
+{
+ zval *values = NULL, **pData = NULL, offset;
+ HashPosition pos;
+ char *str_index = NULL;
+ zend_uint str_length;
+ ulong num_index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE || !values) {
+ return;
+ }
+
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos);
+ while (zend_hash_has_more_elements_ex(Z_ARRVAL_P(values), &pos) == SUCCESS) {
+ zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&pData, &pos);
+ zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &str_index, &str_length, &num_index, 0, &pos);
+ INIT_ZVAL(offset);
+ if (zend_hash_get_current_key_type_ex(Z_ARRVAL_P(values), &pos) == HASH_KEY_IS_LONG) {
+ ZVAL_LONG(&offset, num_index);
+ } else {
+ ZVAL_STRINGL(&offset, str_index, (str_length - 1), 0);
+ }
+ pimple_object_write_dimension(getThis(), &offset, *pData TSRMLS_CC);
+ zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos);
+ }
+}
+
+/*
+ * This is PHP code snippet handling extend()s calls :
+
+ $extended = function ($c) use ($callable, $factory) {
+ return $callable($factory($c), $c);
+ };
+
+ */
+PHP_METHOD(PimpleClosure, invoker)
+{
+ pimple_closure_object *pcobj = NULL;
+ zval *arg = NULL, *retval = NULL, *newretval = NULL;
+ zend_fcall_info fci = {0};
+ zval **args[2];
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
+ return;
+ }
+
+ pcobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ fci.function_name = pcobj->factory;
+ args[0] = &arg;
+ zend_fcall_info_argp(&fci TSRMLS_CC, 1, args);
+ fci.retval_ptr_ptr = &retval;
+ fci.size = sizeof(fci);
+
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
+ efree(fci.params);
+ return; /* Should here return default zval */
+ }
+
+ efree(fci.params);
+ memset(&fci, 0, sizeof(fci));
+ fci.size = sizeof(fci);
+
+ fci.function_name = pcobj->callable;
+ args[0] = &retval;
+ args[1] = &arg;
+ zend_fcall_info_argp(&fci TSRMLS_CC, 2, args);
+ fci.retval_ptr_ptr = &newretval;
+
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
+ efree(fci.params);
+ zval_ptr_dtor(&retval);
+ return;
+ }
+
+ efree(fci.params);
+ zval_ptr_dtor(&retval);
+
+ RETVAL_ZVAL(newretval, 1 ,1);
+}
+
+PHP_MINIT_FUNCTION(pimple)
+{
+ zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
+ INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions);
+ INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL);
+ INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions);
+
+ tmp_pimple_ce.create_object = pimple_object_create;
+ tmp_pimple_closure_ce.create_object = pimple_closure_object_create;
+
+ pimple_ce = zend_register_internal_class(&tmp_pimple_ce TSRMLS_CC);
+ zend_class_implements(pimple_ce TSRMLS_CC, 1, zend_ce_arrayaccess);
+
+ pimple_closure_ce = zend_register_internal_class(&tmp_pimple_closure_ce TSRMLS_CC);
+ pimple_closure_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+
+ pimple_serviceprovider_ce = zend_register_internal_interface(&tmp_pimple_serviceprovider_iface_ce TSRMLS_CC);
+
+ memcpy(&pimple_closure_object_handlers, zend_get_std_object_handlers(), sizeof(*zend_get_std_object_handlers()));
+ pimple_object_handlers = std_object_handlers;
+ pimple_closure_object_handlers.get_closure = pimple_closure_get_closure;
+
+ pimple_closure_invoker_function.function_name = "Pimple closure internal invoker";
+ pimple_closure_invoker_function.fn_flags |= ZEND_ACC_CLOSURE;
+ pimple_closure_invoker_function.handler = ZEND_MN(PimpleClosure_invoker);
+ pimple_closure_invoker_function.num_args = 1;
+ pimple_closure_invoker_function.required_num_args = 1;
+ pimple_closure_invoker_function.scope = pimple_closure_ce;
+ pimple_closure_invoker_function.type = ZEND_INTERNAL_FUNCTION;
+ pimple_closure_invoker_function.module = &pimple_module_entry;
+
+ return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(pimple)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "SensioLabs Pimple C support", "enabled");
+ php_info_print_table_row(2, "Pimple supported version", PIMPLE_VERSION);
+ php_info_print_table_end();
+
+ php_info_print_box_start(0);
+ php_write((void *)ZEND_STRL("SensioLabs Pimple C support developed by Julien Pauli") TSRMLS_CC);
+ if (!sapi_module.phpinfo_as_text) {
+ php_write((void *)ZEND_STRL(sensiolabs_logo) TSRMLS_CC);
+ }
+ php_info_print_box_end();
+}
+
+zend_module_entry pimple_module_entry = {
+ STANDARD_MODULE_HEADER,
+ "pimple",
+ NULL,
+ PHP_MINIT(pimple),
+ NULL,
+ NULL,
+ NULL,
+ PHP_MINFO(pimple),
+ PIMPLE_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_PIMPLE
+ZEND_GET_MODULE(pimple)
+#endif
diff --git a/vendor/pimple/pimple/ext/pimple/pimple_compat.h b/vendor/pimple/pimple/ext/pimple/pimple_compat.h
new file mode 100644
index 00000000..d234e174
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/pimple_compat.h
@@ -0,0 +1,81 @@
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2014 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PIMPLE_COMPAT_H_
+#define PIMPLE_COMPAT_H_
+
+#include "Zend/zend_extensions.h" /* for ZEND_EXTENSION_API_NO */
+
+#define PHP_5_0_X_API_NO 220040412
+#define PHP_5_1_X_API_NO 220051025
+#define PHP_5_2_X_API_NO 220060519
+#define PHP_5_3_X_API_NO 220090626
+#define PHP_5_4_X_API_NO 220100525
+#define PHP_5_5_X_API_NO 220121212
+#define PHP_5_6_X_API_NO 220131226
+
+#define IS_PHP_56 ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO
+#define IS_AT_LEAST_PHP_56 ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO
+
+#define IS_PHP_55 ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO
+#define IS_AT_LEAST_PHP_55 ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+
+#define IS_PHP_54 ZEND_EXTENSION_API_NO == PHP_5_4_X_API_NO
+#define IS_AT_LEAST_PHP_54 ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
+
+#define IS_PHP_53 ZEND_EXTENSION_API_NO == PHP_5_3_X_API_NO
+#define IS_AT_LEAST_PHP_53 ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+
+#if IS_PHP_53
+#define object_properties_init(obj, ce) do { \
+ zend_hash_copy(obj->properties, &ce->default_properties, zval_copy_property_ctor(ce), NULL, sizeof(zval *)); \
+ } while (0);
+#endif
+
+#define ZEND_OBJ_INIT(obj, ce) do { \
+ zend_object_std_init(obj, ce TSRMLS_CC); \
+ object_properties_init((obj), (ce)); \
+ } while(0);
+
+#if IS_PHP_53 || IS_PHP_54
+static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
+ Bucket *p;
+
+ p = pos ? (*pos) : ht->pInternalPointer;
+
+ if (!p) {
+ Z_TYPE_P(key) = IS_NULL;
+ } else if (p->nKeyLength) {
+ Z_TYPE_P(key) = IS_STRING;
+ Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
+ Z_STRLEN_P(key) = p->nKeyLength - 1;
+ } else {
+ Z_TYPE_P(key) = IS_LONG;
+ Z_LVAL_P(key) = p->h;
+ }
+}
+#endif
+
+#endif /* PIMPLE_COMPAT_H_ */
diff --git a/vendor/pimple/pimple/ext/pimple/tests/001.phpt b/vendor/pimple/pimple/ext/pimple/tests/001.phpt
new file mode 100644
index 00000000..0809ea23
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/001.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test for read_dim/write_dim handlers
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p[42] = 'foo';
+$p['foo'] = 42;
+
+echo $p[42];
+echo "\n";
+echo $p['foo'];
+echo "\n";
+try {
+ var_dump($p['nonexistant']);
+ echo "Exception excpected";
+} catch (InvalidArgumentException $e) { }
+
+$p[54.2] = 'foo2';
+echo $p[54];
+echo "\n";
+$p[242.99] = 'foo99';
+echo $p[242];
+
+echo "\n";
+
+$p[5] = 'bar';
+$p[5] = 'baz';
+echo $p[5];
+
+echo "\n";
+
+$p['str'] = 'str';
+$p['str'] = 'strstr';
+echo $p['str'];
+?>
+
+--EXPECTF--
+foo
+42
+foo2
+foo99
+baz
+strstr \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/002.phpt b/vendor/pimple/pimple/ext/pimple/tests/002.phpt
new file mode 100644
index 00000000..7b56d2c1
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/002.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Test for constructor
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+var_dump($p[42]);
+
+$p = new Pimple\Container(array(42=>'foo'));
+var_dump($p[42]);
+?>
+--EXPECT--
+NULL
+string(3) "foo"
diff --git a/vendor/pimple/pimple/ext/pimple/tests/003.phpt b/vendor/pimple/pimple/ext/pimple/tests/003.phpt
new file mode 100644
index 00000000..a22cfa35
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/003.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Test empty dimensions
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p[] = 42;
+var_dump($p[0]);
+$p[41] = 'foo';
+$p[] = 'bar';
+var_dump($p[42]);
+?>
+--EXPECT--
+int(42)
+string(3) "bar" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/004.phpt b/vendor/pimple/pimple/ext/pimple/tests/004.phpt
new file mode 100644
index 00000000..1e1d2513
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/004.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test has/unset dim handlers
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p[] = 42;
+var_dump($p[0]);
+unset($p[0]);
+var_dump($p[0]);
+$p['foo'] = 'bar';
+var_dump(isset($p['foo']));
+unset($p['foo']);
+try {
+ var_dump($p['foo']);
+ echo "Excpected exception";
+} catch (InvalidArgumentException $e) { }
+var_dump(isset($p['bar']));
+$p['bar'] = NULL;
+var_dump(isset($p['bar']));
+var_dump(empty($p['bar']));
+?>
+--EXPECT--
+int(42)
+NULL
+bool(true)
+bool(false)
+bool(true)
+bool(true) \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/005.phpt b/vendor/pimple/pimple/ext/pimple/tests/005.phpt
new file mode 100644
index 00000000..0479ee05
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/005.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Test simple class inheritance
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+class MyPimple extends Pimple\Container
+{
+ public $someAttr = 'fooAttr';
+
+ public function offsetget($o)
+ {
+ var_dump("hit");
+ return parent::offsetget($o);
+ }
+}
+
+$p = new MyPimple;
+$p[42] = 'foo';
+echo $p[42];
+echo "\n";
+echo $p->someAttr;
+?>
+--EXPECT--
+string(3) "hit"
+foo
+fooAttr \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/006.phpt b/vendor/pimple/pimple/ext/pimple/tests/006.phpt
new file mode 100644
index 00000000..cfe8a119
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/006.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Test complex class inheritance
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+class MyPimple extends Pimple\Container
+{
+ public function offsetget($o)
+ {
+ var_dump("hit offsetget in " . __CLASS__);
+ return parent::offsetget($o);
+ }
+}
+
+class TestPimple extends MyPimple
+{
+ public function __construct($values)
+ {
+ array_shift($values);
+ parent::__construct($values);
+ }
+
+ public function offsetget($o)
+ {
+ var_dump('hit offsetget in ' . __CLASS__);
+ return parent::offsetget($o);
+ }
+
+ public function offsetset($o, $v)
+ {
+ var_dump('hit offsetset');
+ return parent::offsetset($o, $v);
+ }
+}
+
+$defaultValues = array('foo' => 'bar', 88 => 'baz');
+
+$p = new TestPimple($defaultValues);
+$p[42] = 'foo';
+var_dump($p[42]);
+var_dump($p[0]);
+?>
+--EXPECT--
+string(13) "hit offsetset"
+string(27) "hit offsetget in TestPimple"
+string(25) "hit offsetget in MyPimple"
+string(3) "foo"
+string(27) "hit offsetget in TestPimple"
+string(25) "hit offsetget in MyPimple"
+string(3) "baz" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/007.phpt b/vendor/pimple/pimple/ext/pimple/tests/007.phpt
new file mode 100644
index 00000000..5aac6838
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/007.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test for read_dim/write_dim handlers
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p[42] = 'foo';
+$p['foo'] = 42;
+
+echo $p[42];
+echo "\n";
+echo $p['foo'];
+echo "\n";
+try {
+ var_dump($p['nonexistant']);
+ echo "Exception excpected";
+} catch (InvalidArgumentException $e) { }
+?>
+--EXPECTF--
+foo
+42 \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/008.phpt b/vendor/pimple/pimple/ext/pimple/tests/008.phpt
new file mode 100644
index 00000000..db7eeec4
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/008.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Test frozen services
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p[42] = 'foo';
+$p[42] = 'bar';
+
+$p['foo'] = function () { };
+$p['foo'] = function () { };
+
+$a = $p['foo'];
+
+try {
+ $p['foo'] = function () { };
+ echo "Exception excpected";
+} catch (RuntimeException $e) { }
+
+$p[42] = function() { };
+$a = $p[42];
+
+try {
+ $p[42] = function () { };
+ echo "Exception excpected";
+} catch (RuntimeException $e) { }
+?>
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/009.phpt b/vendor/pimple/pimple/ext/pimple/tests/009.phpt
new file mode 100644
index 00000000..bb05ea29
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/009.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Test service is called as callback, and only once
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+$p = new Pimple\Container();
+$p['foo'] = function($arg) use ($p) { var_dump($p === $arg); };
+$a = $p['foo'];
+$b = $p['foo']; /* should return not calling the callback */
+?>
+--EXPECTF--
+bool(true) \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/010.phpt b/vendor/pimple/pimple/ext/pimple/tests/010.phpt
new file mode 100644
index 00000000..badce014
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/010.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test service is called as callback for every callback type
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+function callme()
+{
+ return 'called';
+}
+
+$a = function() { return 'called'; };
+
+class Foo
+{
+ public static function bar()
+ {
+ return 'called';
+ }
+}
+
+$p = new Pimple\Container();
+$p['foo'] = 'callme';
+echo $p['foo'] . "\n";
+
+$p['bar'] = $a;
+echo $p['bar'] . "\n";
+
+$p['baz'] = "Foo::bar";
+echo $p['baz'] . "\n";
+
+$p['foobar'] = array('Foo', 'bar');
+var_dump($p['foobar']);
+
+?>
+--EXPECTF--
+callme
+called
+Foo::bar
+array(2) {
+ [0]=>
+ string(3) "Foo"
+ [1]=>
+ string(3) "bar"
+} \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/011.phpt b/vendor/pimple/pimple/ext/pimple/tests/011.phpt
new file mode 100644
index 00000000..6682ab8e
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/011.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Test service callback throwing an exception
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+class CallBackException extends RuntimeException { }
+
+$p = new Pimple\Container();
+$p['foo'] = function () { throw new CallBackException; };
+try {
+ echo $p['foo'] . "\n";
+ echo "should not come here";
+} catch (CallBackException $e) {
+ echo "all right!";
+}
+?>
+--EXPECTF--
+all right! \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/012.phpt b/vendor/pimple/pimple/ext/pimple/tests/012.phpt
new file mode 100644
index 00000000..4c6ac486
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/012.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test service factory
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+
+$p->factory($f = function() { var_dump('called-1'); return 'ret-1';});
+
+$p[] = $f;
+
+$p[] = function () { var_dump('called-2'); return 'ret-2'; };
+
+var_dump($p[0]);
+var_dump($p[0]);
+var_dump($p[1]);
+var_dump($p[1]);
+?>
+--EXPECTF--
+string(8) "called-1"
+string(5) "ret-1"
+string(8) "called-1"
+string(5) "ret-1"
+string(8) "called-2"
+string(5) "ret-2"
+string(5) "ret-2" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/013.phpt b/vendor/pimple/pimple/ext/pimple/tests/013.phpt
new file mode 100644
index 00000000..f419958c
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/013.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test keys()
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+
+var_dump($p->keys());
+
+$p['foo'] = 'bar';
+$p[] = 'foo';
+
+var_dump($p->keys());
+
+unset($p['foo']);
+
+var_dump($p->keys());
+?>
+--EXPECTF--
+array(0) {
+}
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ int(0)
+}
+array(1) {
+ [0]=>
+ int(0)
+} \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/014.phpt b/vendor/pimple/pimple/ext/pimple/tests/014.phpt
new file mode 100644
index 00000000..ac937213
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/014.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test raw()
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+$f = function () { var_dump('called-2'); return 'ret-2'; };
+
+$p['foo'] = $f;
+$p[42] = $f;
+
+var_dump($p['foo']);
+var_dump($p->raw('foo'));
+var_dump($p[42]);
+
+unset($p['foo']);
+
+try {
+ $p->raw('foo');
+ echo "expected exception";
+} catch (InvalidArgumentException $e) { }
+--EXPECTF--
+string(8) "called-2"
+string(5) "ret-2"
+object(Closure)#%i (0) {
+}
+string(8) "called-2"
+string(5) "ret-2" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/015.phpt b/vendor/pimple/pimple/ext/pimple/tests/015.phpt
new file mode 100644
index 00000000..314f008a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/015.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test protect()
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+$f = function () { return 'foo'; };
+$p['foo'] = $f;
+
+$p->protect($f);
+
+var_dump($p['foo']);
+--EXPECTF--
+object(Closure)#%i (0) {
+} \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/016.phpt b/vendor/pimple/pimple/ext/pimple/tests/016.phpt
new file mode 100644
index 00000000..e55edb0a
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/016.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test extend()
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+/*
+ This is part of Pimple::extend() code :
+
+ $extended = function ($c) use ($callable, $factory) {
+ return $callable($factory($c), $c);
+ };
+*/
+
+$p = new Pimple\Container();
+$p[12] = function ($v) { var_dump($v); return 'foo';}; /* $factory in code above */
+
+$c = $p->extend(12, function ($w) { var_dump($w); return 'bar'; }); /* $callable in code above */
+
+var_dump($c('param'));
+--EXPECTF--
+string(5) "param"
+string(3) "foo"
+string(3) "bar" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/017.phpt b/vendor/pimple/pimple/ext/pimple/tests/017.phpt
new file mode 100644
index 00000000..bac23ce0
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/017.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test extend() with exception in service extension
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+$p[12] = function ($v) { return 'foo';};
+
+$c = $p->extend(12, function ($w) { throw new BadMethodCallException; });
+
+try {
+ $p[12];
+ echo "Exception expected";
+} catch (BadMethodCallException $e) { }
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt b/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt
new file mode 100644
index 00000000..8f881d6e
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test extend() with exception in service factory
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+$p = new Pimple\Container();
+$p[12] = function ($v) { throw new BadMethodCallException; };
+
+$c = $p->extend(12, function ($w) { return 'foobar'; });
+
+try {
+ $p[12];
+ echo "Exception expected";
+} catch (BadMethodCallException $e) { }
+--EXPECTF--
diff --git a/vendor/pimple/pimple/ext/pimple/tests/018.phpt b/vendor/pimple/pimple/ext/pimple/tests/018.phpt
new file mode 100644
index 00000000..27c12a14
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/018.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test register()
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+class Foo implements Pimple\ServiceProviderInterface
+{
+ public function register(Pimple\Container $p)
+ {
+ var_dump($p);
+ }
+}
+
+$p = new Pimple\Container();
+$p->register(new Foo, array(42 => 'bar'));
+
+var_dump($p[42]);
+--EXPECTF--
+object(Pimple\Container)#1 (0) {
+}
+string(3) "bar" \ No newline at end of file
diff --git a/vendor/pimple/pimple/ext/pimple/tests/019.phpt b/vendor/pimple/pimple/ext/pimple/tests/019.phpt
new file mode 100644
index 00000000..28a9aeca
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/019.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test register() returns static and is a fluent interface
+--SKIPIF--
+<?php if (!extension_loaded("pimple")) print "skip"; ?>
+--FILE--
+<?php
+
+class Foo implements Pimple\ServiceProviderInterface
+{
+ public function register(Pimple\Container $p)
+ {
+ }
+}
+
+$p = new Pimple\Container();
+var_dump($p === $p->register(new Foo));
+--EXPECTF--
+bool(true)
diff --git a/vendor/pimple/pimple/ext/pimple/tests/bench.phpb b/vendor/pimple/pimple/ext/pimple/tests/bench.phpb
new file mode 100644
index 00000000..8f983e65
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/bench.phpb
@@ -0,0 +1,51 @@
+<?php
+
+if (!class_exists('Pimple\Container')) {
+ require_once __DIR__ . '/../../../src/Pimple/Container.php';
+} else {
+ echo "pimple-c extension detected, using...\n\n";
+}
+
+$time = microtime(true);
+
+function foo() { }
+$factory = function () { };
+
+for ($i=0; $i<10000; $i++) {
+
+$p = new Pimple\Container;
+
+$p['foo'] = 'bar';
+
+if (!isset($p[3])) {
+ $p[3] = $p['foo'];
+ $p[] = 'bar';
+}
+
+$p[2] = 42;
+
+if (isset($p[2])) {
+ unset($p[2]);
+}
+
+$p[42] = $p['foo'];
+
+$p['cb'] = function($arg) { };
+
+$p[] = $p['cb'];
+
+echo $p['cb'];
+echo $p['cb'];
+echo $p['cb'];
+
+//$p->factory($factory);
+
+$p['factory'] = $factory;
+
+echo $p['factory'];
+echo $p['factory'];
+echo $p['factory'];
+
+}
+
+echo microtime(true) - $time;
diff --git a/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb b/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb
new file mode 100644
index 00000000..aec541f0
--- /dev/null
+++ b/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb
@@ -0,0 +1,25 @@
+<?php
+
+if (!class_exists('Pimple\Container')) {
+ require_once __DIR__ . '/../../../src/Pimple/Container.php';
+} else {
+ echo "pimple-c extension detected, using...\n\n";
+}
+
+$time = microtime(true);
+
+
+$service = function ($arg) { return "I'm a service"; };
+
+for ($i=0; $i<10000; $i++) {
+
+$p = new Pimple\Container;
+$p['my_service'] = $service;
+
+$a = $p['my_service'];
+$b = $p['my_service'];
+
+}
+
+echo microtime(true) - $time;
+?>
diff --git a/vendor/pimple/pimple/phpunit.xml.dist b/vendor/pimple/pimple/phpunit.xml.dist
new file mode 100644
index 00000000..5c8d487f
--- /dev/null
+++ b/vendor/pimple/pimple/phpunit.xml.dist
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <testsuites>
+ <testsuite name="Pimple Test Suite">
+ <directory>./src/Pimple/Tests</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>
diff --git a/vendor/pimple/pimple/src/Pimple/Container.php b/vendor/pimple/pimple/src/Pimple/Container.php
new file mode 100644
index 00000000..c976431e
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Container.php
@@ -0,0 +1,282 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple;
+
+/**
+ * Container main class.
+ *
+ * @author Fabien Potencier
+ */
+class Container implements \ArrayAccess
+{
+ private $values = array();
+ private $factories;
+ private $protected;
+ private $frozen = array();
+ private $raw = array();
+ private $keys = array();
+
+ /**
+ * Instantiate the container.
+ *
+ * Objects and parameters can be passed as argument to the constructor.
+ *
+ * @param array $values The parameters or objects.
+ */
+ public function __construct(array $values = array())
+ {
+ $this->factories = new \SplObjectStorage();
+ $this->protected = new \SplObjectStorage();
+
+ foreach ($values as $key => $value) {
+ $this->offsetSet($key, $value);
+ }
+ }
+
+ /**
+ * Sets a parameter or an object.
+ *
+ * Objects must be defined as Closures.
+ *
+ * Allowing any PHP callable leads to difficult to debug problems
+ * as function names (strings) are callable (creating a function with
+ * the same name as an existing parameter would break your container).
+ *
+ * @param string $id The unique identifier for the parameter or object
+ * @param mixed $value The value of the parameter or a closure to define an object
+ *
+ * @throws \RuntimeException Prevent override of a frozen service
+ */
+ public function offsetSet($id, $value)
+ {
+ if (isset($this->frozen[$id])) {
+ throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
+ }
+
+ $this->values[$id] = $value;
+ $this->keys[$id] = true;
+ }
+
+ /**
+ * Gets a parameter or an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return mixed The value of the parameter or an object
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined
+ */
+ public function offsetGet($id)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (
+ isset($this->raw[$id])
+ || !is_object($this->values[$id])
+ || isset($this->protected[$this->values[$id]])
+ || !method_exists($this->values[$id], '__invoke')
+ ) {
+ return $this->values[$id];
+ }
+
+ if (isset($this->factories[$this->values[$id]])) {
+ return $this->values[$id]($this);
+ }
+
+ $raw = $this->values[$id];
+ $val = $this->values[$id] = $raw($this);
+ $this->raw[$id] = $raw;
+
+ $this->frozen[$id] = true;
+
+ return $val;
+ }
+
+ /**
+ * Checks if a parameter or an object is set.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return bool
+ */
+ public function offsetExists($id)
+ {
+ return isset($this->keys[$id]);
+ }
+
+ /**
+ * Unsets a parameter or an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ */
+ public function offsetUnset($id)
+ {
+ if (isset($this->keys[$id])) {
+ if (is_object($this->values[$id])) {
+ unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
+ }
+
+ unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
+ }
+ }
+
+ /**
+ * Marks a callable as being a factory service.
+ *
+ * @param callable $callable A service definition to be used as a factory
+ *
+ * @return callable The passed callable
+ *
+ * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
+ */
+ public function factory($callable)
+ {
+ if (!method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
+ }
+
+ $this->factories->attach($callable);
+
+ return $callable;
+ }
+
+ /**
+ * Protects a callable from being interpreted as a service.
+ *
+ * This is useful when you want to store a callable as a parameter.
+ *
+ * @param callable $callable A callable to protect from being evaluated
+ *
+ * @return callable The passed callable
+ *
+ * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
+ */
+ public function protect($callable)
+ {
+ if (!method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
+ }
+
+ $this->protected->attach($callable);
+
+ return $callable;
+ }
+
+ /**
+ * Gets a parameter or the closure defining an object.
+ *
+ * @param string $id The unique identifier for the parameter or object
+ *
+ * @return mixed The value of the parameter or the closure defining an object
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined
+ */
+ public function raw($id)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (isset($this->raw[$id])) {
+ return $this->raw[$id];
+ }
+
+ return $this->values[$id];
+ }
+
+ /**
+ * Extends an object definition.
+ *
+ * Useful when you want to extend an existing object definition,
+ * without necessarily loading that object.
+ *
+ * @param string $id The unique identifier for the object
+ * @param callable $callable A service definition to extend the original
+ *
+ * @return callable The wrapped callable
+ *
+ * @throws \InvalidArgumentException if the identifier is not defined or not a service definition
+ */
+ public function extend($id, $callable)
+ {
+ if (!isset($this->keys[$id])) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+
+ if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
+ throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
+ }
+
+ if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+ throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
+ }
+
+ $factory = $this->values[$id];
+
+ $extended = function ($c) use ($callable, $factory) {
+ return $callable($factory($c), $c);
+ };
+
+ if (isset($this->factories[$factory])) {
+ $this->factories->detach($factory);
+ $this->factories->attach($extended);
+ }
+
+ return $this[$id] = $extended;
+ }
+
+ /**
+ * Returns all defined value names.
+ *
+ * @return array An array of value names
+ */
+ public function keys()
+ {
+ return array_keys($this->values);
+ }
+
+ /**
+ * Registers a service provider.
+ *
+ * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
+ * @param array $values An array of values that customizes the provider
+ *
+ * @return static
+ */
+ public function register(ServiceProviderInterface $provider, array $values = array())
+ {
+ $provider->register($this);
+
+ foreach ($values as $key => $value) {
+ $this[$key] = $value;
+ }
+
+ return $this;
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php b/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php
new file mode 100644
index 00000000..c004594b
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple;
+
+/**
+ * Pimple service provider interface.
+ *
+ * @author Fabien Potencier
+ * @author Dominik Zogg
+ */
+interface ServiceProviderInterface
+{
+ /**
+ * Registers services on the given container.
+ *
+ * This method should only be used to configure services and parameters.
+ * It should not get services.
+ *
+ * @param Container $pimple A container instance
+ */
+ public function register(Container $pimple);
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php
new file mode 100644
index 00000000..aba453bf
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+class Invokable
+{
+ public function __invoke($value = null)
+ {
+ $service = new Service();
+ $service->value = $value;
+
+ return $service;
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php
new file mode 100644
index 00000000..33cd4e54
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+class NonInvokable
+{
+ public function __call($a, $b)
+ {
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php
new file mode 100644
index 00000000..0c910af7
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+class PimpleServiceProvider implements ServiceProviderInterface
+{
+ /**
+ * Registers services on the given container.
+ *
+ * This method should only be used to configure services and parameters.
+ * It should not get services.
+ *
+ * @param Container $pimple An Container instance
+ */
+ public function register(Container $pimple)
+ {
+ $pimple['param'] = 'value';
+
+ $pimple['service'] = function () {
+ return new Service();
+ };
+
+ $pimple['factory'] = $pimple->factory(function () {
+ return new Service();
+ });
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php
new file mode 100644
index 00000000..d71b184d
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests\Fixtures;
+
+/**
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class Service
+{
+ public $value;
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php b/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php
new file mode 100644
index 00000000..8e5c4c73
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests;
+
+use Pimple\Container;
+
+/**
+ * @author Dominik Zogg <dominik.zogg@gmail.com>
+ */
+class PimpleServiceProviderInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+ public function testProvider()
+ {
+ $pimple = new Container();
+
+ $pimpleServiceProvider = new Fixtures\PimpleServiceProvider();
+ $pimpleServiceProvider->register($pimple);
+
+ $this->assertEquals('value', $pimple['param']);
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+ $serviceOne = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+
+ public function testProviderWithRegisterMethod()
+ {
+ $pimple = new Container();
+
+ $pimple->register(new Fixtures\PimpleServiceProvider(), array(
+ 'anotherParameter' => 'anotherValue',
+ ));
+
+ $this->assertEquals('value', $pimple['param']);
+ $this->assertEquals('anotherValue', $pimple['anotherParameter']);
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+
+ $serviceOne = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['factory'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+}
diff --git a/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php b/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
new file mode 100644
index 00000000..918f620d
--- /dev/null
+++ b/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php
@@ -0,0 +1,440 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Pimple\Tests;
+
+use Pimple\Container;
+
+/**
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class PimpleTest extends \PHPUnit_Framework_TestCase
+{
+ public function testWithString()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+
+ $this->assertEquals('value', $pimple['param']);
+ }
+
+ public function testWithClosure()
+ {
+ $pimple = new Container();
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
+ }
+
+ public function testServicesShouldBeDifferent()
+ {
+ $pimple = new Container();
+ $pimple['service'] = $pimple->factory(function () {
+ return new Fixtures\Service();
+ });
+
+ $serviceOne = $pimple['service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ }
+
+ public function testShouldPassContainerAsParameter()
+ {
+ $pimple = new Container();
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+ $pimple['container'] = function ($container) {
+ return $container;
+ };
+
+ $this->assertNotSame($pimple, $pimple['service']);
+ $this->assertSame($pimple, $pimple['container']);
+ }
+
+ public function testIsset()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ $pimple['null'] = null;
+
+ $this->assertTrue(isset($pimple['param']));
+ $this->assertTrue(isset($pimple['service']));
+ $this->assertTrue(isset($pimple['null']));
+ $this->assertFalse(isset($pimple['non_existent']));
+ }
+
+ public function testConstructorInjection()
+ {
+ $params = array('param' => 'value');
+ $pimple = new Container($params);
+
+ $this->assertSame($params['param'], $pimple['param']);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testOffsetGetValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ echo $pimple['foo'];
+ }
+
+ public function testOffsetGetHonorsNullValues()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = null;
+ $this->assertNull($pimple['foo']);
+ }
+
+ public function testUnset()
+ {
+ $pimple = new Container();
+ $pimple['param'] = 'value';
+ $pimple['service'] = function () {
+ return new Fixtures\Service();
+ };
+
+ unset($pimple['param'], $pimple['service']);
+ $this->assertFalse(isset($pimple['param']));
+ $this->assertFalse(isset($pimple['service']));
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testShare($service)
+ {
+ $pimple = new Container();
+ $pimple['shared_service'] = $service;
+
+ $serviceOne = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+
+ $serviceTwo = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+
+ $this->assertSame($serviceOne, $serviceTwo);
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testProtect($service)
+ {
+ $pimple = new Container();
+ $pimple['protected'] = $pimple->protect($service);
+
+ $this->assertSame($service, $pimple['protected']);
+ }
+
+ public function testGlobalFunctionNameAsParameterValue()
+ {
+ $pimple = new Container();
+ $pimple['global_function'] = 'strlen';
+ $this->assertSame('strlen', $pimple['global_function']);
+ }
+
+ public function testRaw()
+ {
+ $pimple = new Container();
+ $pimple['service'] = $definition = $pimple->factory(function () { return 'foo'; });
+ $this->assertSame($definition, $pimple->raw('service'));
+ }
+
+ public function testRawHonorsNullValues()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = null;
+ $this->assertNull($pimple->raw('foo'));
+ }
+
+ public function testFluentRegister()
+ {
+ $pimple = new Container();
+ $this->assertSame($pimple, $pimple->register($this->getMock('Pimple\ServiceProviderInterface')));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testRawValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->raw('foo');
+ }
+
+ /**
+ * @dataProvider serviceDefinitionProvider
+ */
+ public function testExtend($service)
+ {
+ $pimple = new Container();
+ $pimple['shared_service'] = function () {
+ return new Fixtures\Service();
+ };
+ $pimple['factory_service'] = $pimple->factory(function () {
+ return new Fixtures\Service();
+ });
+
+ $pimple->extend('shared_service', $service);
+ $serviceOne = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+ $serviceTwo = $pimple['shared_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+ $this->assertSame($serviceOne, $serviceTwo);
+ $this->assertSame($serviceOne->value, $serviceTwo->value);
+
+ $pimple->extend('factory_service', $service);
+ $serviceOne = $pimple['factory_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
+ $serviceTwo = $pimple['factory_service'];
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
+ $this->assertNotSame($serviceOne, $serviceTwo);
+ $this->assertNotSame($serviceOne->value, $serviceTwo->value);
+ }
+
+ public function testExtendDoesNotLeakWithFactories()
+ {
+ if (extension_loaded('pimple')) {
+ $this->markTestSkipped('Pimple extension does not support this test');
+ }
+ $pimple = new Container();
+
+ $pimple['foo'] = $pimple->factory(function () { return; });
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) { return; });
+ unset($pimple['foo']);
+
+ $p = new \ReflectionProperty($pimple, 'values');
+ $p->setAccessible(true);
+ $this->assertEmpty($p->getValue($pimple));
+
+ $p = new \ReflectionProperty($pimple, 'factories');
+ $p->setAccessible(true);
+ $this->assertCount(0, $p->getValue($pimple));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" is not defined.
+ */
+ public function testExtendValidatesKeyIsPresent()
+ {
+ $pimple = new Container();
+ $pimple->extend('foo', function () {});
+ }
+
+ public function testKeys()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = 123;
+ $pimple['bar'] = 123;
+
+ $this->assertEquals(array('foo', 'bar'), $pimple->keys());
+ }
+
+ /** @test */
+ public function settingAnInvokableObjectShouldTreatItAsFactory()
+ {
+ $pimple = new Container();
+ $pimple['invokable'] = new Fixtures\Invokable();
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']);
+ }
+
+ /** @test */
+ public function settingNonInvokableObjectShouldTreatItAsParameter()
+ {
+ $pimple = new Container();
+ $pimple['non_invokable'] = new Fixtures\NonInvokable();
+
+ $this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Service definition is not a Closure or invokable object.
+ */
+ public function testFactoryFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->factory($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Callable is not a Closure or invokable object.
+ */
+ public function testProtectFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple->protect($service);
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Identifier "foo" does not contain an object definition.
+ */
+ public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = $service;
+ $pimple->extend('foo', function () {});
+ }
+
+ /**
+ * @dataProvider badServiceDefinitionProvider
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Extension service definition is not a Closure or invokable object.
+ */
+ public function testExtendFailsForInvalidServiceDefinitions($service)
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {};
+ $pimple->extend('foo', $service);
+ }
+
+ /**
+ * Provider for invalid service definitions.
+ */
+ public function badServiceDefinitionProvider()
+ {
+ return array(
+ array(123),
+ array(new Fixtures\NonInvokable()),
+ );
+ }
+
+ /**
+ * Provider for service definitions.
+ */
+ public function serviceDefinitionProvider()
+ {
+ return array(
+ array(function ($value) {
+ $service = new Fixtures\Service();
+ $service->value = $value;
+
+ return $service;
+ }),
+ array(new Fixtures\Invokable()),
+ );
+ }
+
+ public function testDefiningNewServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['bar'] = function () {
+ return 'bar';
+ };
+ $this->assertSame('bar', $pimple['bar']);
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Cannot override frozen service "foo".
+ */
+ public function testOverridingServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['foo'] = function () {
+ return 'bar';
+ };
+ }
+
+ public function testRemovingServiceAfterFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $foo = $pimple['foo'];
+
+ unset($pimple['foo']);
+ $pimple['foo'] = function () {
+ return 'bar';
+ };
+ $this->assertSame('bar', $pimple['foo']);
+ }
+
+ public function testExtendingService()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+ return "$foo.bar";
+ });
+ $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
+ return "$foo.baz";
+ });
+ $this->assertSame('foo.bar.baz', $pimple['foo']);
+ }
+
+ public function testExtendingServiceAfterOtherServiceFreeze()
+ {
+ $pimple = new Container();
+ $pimple['foo'] = function () {
+ return 'foo';
+ };
+ $pimple['bar'] = function () {
+ return 'bar';
+ };
+ $foo = $pimple['foo'];
+
+ $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) {
+ return "$bar.baz";
+ });
+ $this->assertSame('bar.baz', $pimple['bar']);
+ }
+}