diff --git a/exercises/legacy_create_video/README.md b/exercises/legacy_create_video/README.md new file mode 100644 index 00000000..d0bb2f64 --- /dev/null +++ b/exercises/legacy_create_video/README.md @@ -0,0 +1,20 @@ +# Legacy create video + +Try to add new features to the legacy code + +## User story + +There is an HTTP API endpoint to create Codely videos. +When creating videos, we want to ensure that: + +- The words "frontend", "Frontend" and "front-end" must be + transformed to "Front-end". +- If the title contains any whitespace at the beginning or +the end, it must be removed. +- If the title contains a final dot, it must be removed. + +## Exercise + +Available languages: + +- [PHP Symfony](base/php-symfony/README.md) \ No newline at end of file diff --git a/exercises/legacy_create_video/base/php-symfony/.gitignore b/exercises/legacy_create_video/base/php-symfony/.gitignore new file mode 100644 index 00000000..b67f201b --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/.gitignore @@ -0,0 +1,8 @@ +/web/bundles/ +/app/cache/* +/app/logs/* +/build/ +/vendor/ +/bin/ +/composer.phar +app/config/parameters.yml diff --git a/exercises/legacy_create_video/base/php-symfony/.travis.yml b/exercises/legacy_create_video/base/php-symfony/.travis.yml new file mode 100644 index 00000000..6dec8cee --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/.travis.yml @@ -0,0 +1,22 @@ +language: php + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +php: + - 5.5 + - 5.6 + - 7.0 + - hhvm + +before_install: + - composer self-update + +install: composer update $COMPOSER_FLAGS --prefer-dist + +after_failure: "cat /home/travis/build/gimler/symfony-rest-edition/app/logs/test.log" + +script: phpunit -c app diff --git a/exercises/legacy_create_video/base/php-symfony/LICENSE b/exercises/legacy_create_video/base/php-symfony/LICENSE new file mode 100644 index 00000000..88a57f8d --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2013 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/exercises/legacy_create_video/base/php-symfony/README.md b/exercises/legacy_create_video/base/php-symfony/README.md new file mode 100644 index 00000000..478c0c67 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/README.md @@ -0,0 +1,32 @@ + + + +> Keep it simple :) + +[![CodelyTV](https://img.shields.io/badge/code-codely-green.svg?style=flat-square)](codely.tv) + +**CodelyTv** is the way to rediscover the programming ;) Trusted by more than 1000 youtube subscribers. + +Trust in **Codely**, trust in **you**. + +## Quick Start +This is a simple demo of a coupled code. + +### 1. Clone this repo +Execute: `git clone https://github.com/CodelyTV/coupled-code-example` + +### 2. Install all the dependencies +Composer is used to handle the dependencies. You can download it executing: +`curl -sS https://getcomposer.org/installer | php` + +And then you can install all the dependencies executing: +`php composer.phar install` + +### 3. Run the tests! +Once you have all the dependencies, in order to execute the tests, run this command: +`bin/phpunit` + +## Extra +This code was show in the [From framework coupled code to #microservices through #DDD](http://codely.tv/screencasts/codigo-acoplado-framework-microservicios-ddd) talk. + +You have the *CQRS* version of the code [here](https://github.com/CodelyTV/cqrs-ddd-example) diff --git a/exercises/legacy_create_video/base/php-symfony/app/.htaccess b/exercises/legacy_create_video/base/php-symfony/app/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/exercises/legacy_create_video/base/php-symfony/app/AppCache.php b/exercises/legacy_create_video/base/php-symfony/app/AppCache.php new file mode 100644 index 00000000..ddb51db0 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/AppCache.php @@ -0,0 +1,9 @@ +getEnvironment(), array('dev', 'test'))) { + $bundles[] = new AppBundle\AppBundle(); + $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); + $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); + $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); + } + + return $bundles; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/app/Resources/views/base.html.twig b/exercises/legacy_create_video/base/php-symfony/app/Resources/views/base.html.twig new file mode 100644 index 00000000..bafd28d3 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/Resources/views/base.html.twig @@ -0,0 +1,13 @@ + + + + + {% block title %}Welcome!{% endblock %} + {% block stylesheets %}{% endblock %} + + + + {% block body %}{% endblock %} + {% block javascripts %}{% endblock %} + + diff --git a/exercises/legacy_create_video/base/php-symfony/app/SymfonyRequirements.php b/exercises/legacy_create_video/base/php-symfony/app/SymfonyRequirements.php new file mode 100644 index 00000000..28b0dcdb --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/SymfonyRequirements.php @@ -0,0 +1,764 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/* + * Users of PHP 5.2 should be able to run the requirements checks. + * This is why the file and all classes must be compatible with PHP 5.2+ + * (e.g. not using namespaces and closures). + * + * ************** CAUTION ************** + * + * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of + * the installation/update process. The original file resides in the + * SensioDistributionBundle. + * + * ************** CAUTION ************** + */ + +/** + * Represents a single PHP requirement, e.g. an installed extension. + * It can be a mandatory requirement or an optional recommendation. + * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. + * + * @author Tobias Schultze + */ +class Requirement +{ + private $fulfilled; + private $testMessage; + private $helpText; + private $helpHtml; + private $optional; + + /** + * Constructor that initializes the requirement. + * + * @param bool $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) + { + $this->fulfilled = (bool) $fulfilled; + $this->testMessage = (string) $testMessage; + $this->helpHtml = (string) $helpHtml; + $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; + $this->optional = (bool) $optional; + } + + /** + * Returns whether the requirement is fulfilled. + * + * @return bool true if fulfilled, otherwise false + */ + public function isFulfilled() + { + return $this->fulfilled; + } + + /** + * Returns the message for testing the requirement. + * + * @return string The test message + */ + public function getTestMessage() + { + return $this->testMessage; + } + + /** + * Returns the help text for resolving the problem. + * + * @return string The help text + */ + public function getHelpText() + { + return $this->helpText; + } + + /** + * Returns the help text formatted in HTML. + * + * @return string The HTML help + */ + public function getHelpHtml() + { + return $this->helpHtml; + } + + /** + * Returns whether this is only an optional recommendation and not a mandatory requirement. + * + * @return bool true if optional, false if mandatory + */ + public function isOptional() + { + return $this->optional; + } +} + +/** + * Represents a PHP requirement in form of a php.ini configuration. + * + * @author Tobias Schultze + */ +class PhpIniRequirement extends Requirement +{ + /** + * Constructor that initializes the requirement. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) + { + $cfgValue = ini_get($cfgName); + + if (is_callable($evaluation)) { + if (null === $testMessage || null === $helpHtml) { + throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); + } + + $fulfilled = call_user_func($evaluation, $cfgValue); + } else { + if (null === $testMessage) { + $testMessage = sprintf('%s %s be %s in php.ini', + $cfgName, + $optional ? 'should' : 'must', + $evaluation ? 'enabled' : 'disabled' + ); + } + + if (null === $helpHtml) { + $helpHtml = sprintf('Set %s to %s in php.ini*.', + $cfgName, + $evaluation ? 'on' : 'off' + ); + } + + $fulfilled = $evaluation == $cfgValue; + } + + parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); + } +} + +/** + * A RequirementCollection represents a set of Requirement instances. + * + * @author Tobias Schultze + */ +class RequirementCollection implements IteratorAggregate +{ + private $requirements = array(); + + /** + * Gets the current RequirementCollection as an Iterator. + * + * @return Traversable A Traversable interface + */ + public function getIterator() + { + return new ArrayIterator($this->requirements); + } + + /** + * Adds a Requirement. + * + * @param Requirement $requirement A Requirement instance + */ + public function add(Requirement $requirement) + { + $this->requirements[] = $requirement; + } + + /** + * Adds a mandatory requirement. + * + * @param bool $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation. + * + * @param bool $fulfilled Whether the recommendation is fulfilled + * @param string $testMessage The message for testing the recommendation + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a mandatory requirement in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a requirement collection to the current set of requirements. + * + * @param RequirementCollection $collection A RequirementCollection instance + */ + public function addCollection(RequirementCollection $collection) + { + $this->requirements = array_merge($this->requirements, $collection->all()); + } + + /** + * Returns both requirements and recommendations. + * + * @return array Array of Requirement instances + */ + public function all() + { + return $this->requirements; + } + + /** + * Returns all mandatory requirements. + * + * @return array Array of Requirement instances + */ + public function getRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the mandatory requirements that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && !$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns all optional recommendations. + * + * @return array Array of Requirement instances + */ + public function getRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if ($req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the recommendations that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns whether a php.ini configuration is not correct. + * + * @return bool php.ini configuration problem? + */ + public function hasPhpIniConfigIssue() + { + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { + return true; + } + } + + return false; + } + + /** + * Returns the PHP configuration file (php.ini) path. + * + * @return string|false php.ini file path + */ + public function getPhpIniConfigPath() + { + return get_cfg_var('cfg_file_path'); + } +} + +/** + * This class specifies all requirements and optional recommendations that + * are necessary to run the Symfony Standard Edition. + * + * @author Tobias Schultze + * @author Fabien Potencier + */ +class SymfonyRequirements extends RequirementCollection +{ + const REQUIRED_PHP_VERSION = '5.3.3'; + + /** + * Constructor that initializes the requirements. + */ + public function __construct() + { + /* mandatory requirements follow */ + + $installedPhpVersion = phpversion(); + + $this->addRequirement( + version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='), + sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion), + sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. + Before using Symfony, upgrade your PHP installation, preferably to the latest version.', + $installedPhpVersion, self::REQUIRED_PHP_VERSION), + sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion) + ); + + $this->addRequirement( + version_compare($installedPhpVersion, '5.3.16', '!='), + 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it', + 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)' + ); + + $this->addRequirement( + is_dir(__DIR__.'/../vendor/composer'), + 'Vendor libraries must be installed', + 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. '. + 'Then run "php composer.phar install" to install them.' + ); + + $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache'; + + $this->addRequirement( + is_writable($cacheDir), + 'app/cache/ or var/cache/ directory must be writable', + 'Change the permissions of either "app/cache/" or "var/cache/" directory so that the web server can write into it.' + ); + + $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs'; + + $this->addRequirement( + is_writable($logsDir), + 'app/logs/ or var/logs/ directory must be writable', + 'Change the permissions of either "app/logs/" or "var/logs/" directory so that the web server can write into it.' + ); + + $this->addPhpIniRequirement( + 'date.timezone', true, false, + 'date.timezone setting must be set', + 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' + ); + + if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { + $timezones = array(); + foreach (DateTimeZone::listAbbreviations() as $abbreviations) { + foreach ($abbreviations as $abbreviation) { + $timezones[$abbreviation['timezone_id']] = true; + } + } + + $this->addRequirement( + isset($timezones[@date_default_timezone_get()]), + sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()), + 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.' + ); + } + + $this->addRequirement( + function_exists('iconv'), + 'iconv() must be available', + 'Install and enable the iconv extension.' + ); + + $this->addRequirement( + function_exists('json_encode'), + 'json_encode() must be available', + 'Install and enable the JSON extension.' + ); + + $this->addRequirement( + function_exists('session_start'), + 'session_start() must be available', + 'Install and enable the session extension.' + ); + + $this->addRequirement( + function_exists('ctype_alpha'), + 'ctype_alpha() must be available', + 'Install and enable the ctype extension.' + ); + + $this->addRequirement( + function_exists('token_get_all'), + 'token_get_all() must be available', + 'Install and enable the Tokenizer extension.' + ); + + $this->addRequirement( + function_exists('simplexml_import_dom'), + 'simplexml_import_dom() must be available', + 'Install and enable the SimpleXML extension.' + ); + + if (function_exists('apc_store') && ini_get('apc.enabled')) { + if (version_compare($installedPhpVersion, '5.4.0', '>=')) { + $this->addRequirement( + version_compare(phpversion('apc'), '3.1.13', '>='), + 'APC version must be at least 3.1.13 when using PHP 5.4', + 'Upgrade your APC extension (3.1.13+).' + ); + } else { + $this->addRequirement( + version_compare(phpversion('apc'), '3.0.17', '>='), + 'APC version must be at least 3.0.17', + 'Upgrade your APC extension (3.0.17+).' + ); + } + } + + $this->addPhpIniRequirement('detect_unicode', false); + + if (extension_loaded('suhosin')) { + $this->addPhpIniRequirement( + 'suhosin.executor.include.whitelist', + create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), + false, + 'suhosin.executor.include.whitelist must be configured correctly in php.ini', + 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' + ); + } + + if (extension_loaded('xdebug')) { + $this->addPhpIniRequirement( + 'xdebug.show_exception_trace', false, true + ); + + $this->addPhpIniRequirement( + 'xdebug.scream', false, true + ); + + $this->addPhpIniRecommendation( + 'xdebug.max_nesting_level', + create_function('$cfgValue', 'return $cfgValue > 100;'), + true, + 'xdebug.max_nesting_level should be above 100 in php.ini', + 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.' + ); + } + + $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; + + $this->addRequirement( + null !== $pcreVersion, + 'PCRE extension must be available', + 'Install the PCRE extension (version 8.0+).' + ); + + if (extension_loaded('mbstring')) { + $this->addPhpIniRequirement( + 'mbstring.func_overload', + create_function('$cfgValue', 'return (int) $cfgValue === 0;'), + true, + 'string functions should not be overloaded', + 'Set "mbstring.func_overload" to 0 in php.ini* to disable function overloading by the mbstring extension.' + ); + } + + /* optional recommendations follow */ + + if (file_exists(__DIR__.'/../vendor/composer')) { + require_once __DIR__.'/../vendor/autoload.php'; + + try { + $r = new ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle'); + + $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php'); + } catch (ReflectionException $e) { + $contents = ''; + } + $this->addRecommendation( + file_get_contents(__FILE__) === $contents, + 'Requirements file should be up-to-date', + 'Your requirements file is outdated. Run composer install and re-check your configuration.' + ); + } + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.3.4', '>='), + 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', + 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.3.8', '>='), + 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', + 'Install PHP 5.3.8 or newer if your project uses annotations.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.4.0', '!='), + 'You should not use PHP 5.4.0 due to the PHP bug #61453', + 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.4.11', '>='), + 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)', + 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' + ); + + $this->addRecommendation( + (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) + || + version_compare($installedPhpVersion, '5.4.8', '>='), + 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909', + 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' + ); + + if (null !== $pcreVersion) { + $this->addRecommendation( + $pcreVersion >= 8.0, + sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), + 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' + ); + } + + $this->addRecommendation( + class_exists('DomDocument'), + 'PHP-DOM and PHP-XML modules should be installed', + 'Install and enable the PHP-DOM and the PHP-XML modules.' + ); + + $this->addRecommendation( + function_exists('mb_strlen'), + 'mb_strlen() should be available', + 'Install and enable the mbstring extension.' + ); + + $this->addRecommendation( + function_exists('iconv'), + 'iconv() should be available', + 'Install and enable the iconv extension.' + ); + + $this->addRecommendation( + function_exists('utf8_decode'), + 'utf8_decode() should be available', + 'Install and enable the XML extension.' + ); + + $this->addRecommendation( + function_exists('filter_var'), + 'filter_var() should be available', + 'Install and enable the filter extension.' + ); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->addRecommendation( + function_exists('posix_isatty'), + 'posix_isatty() should be available', + 'Install and enable the php_posix extension (used to colorize the CLI output).' + ); + } + + $this->addRecommendation( + extension_loaded('intl'), + 'intl extension should be available', + 'Install and enable the intl extension (used for validators).' + ); + + if (extension_loaded('intl')) { + // in some WAMP server installations, new Collator() returns null + $this->addRecommendation( + null !== new Collator('fr_FR'), + 'intl extension should be correctly configured', + 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' + ); + + // check for compatible ICU versions (only done when you have the intl extension) + if (defined('INTL_ICU_VERSION')) { + $version = INTL_ICU_VERSION; + } else { + $reflector = new ReflectionExtension('intl'); + + ob_start(); + $reflector->info(); + $output = strip_tags(ob_get_clean()); + + preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); + $version = $matches[1]; + } + + $this->addRecommendation( + version_compare($version, '4.0', '>='), + 'intl ICU version should be at least 4+', + 'Upgrade your intl extension with a newer ICU version (4+).' + ); + + $this->addPhpIniRecommendation( + 'intl.error_level', + create_function('$cfgValue', 'return (int) $cfgValue === 0;'), + true, + 'intl.error_level should be 0 in php.ini', + 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.' + ); + } + + $accelerator = + (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) + || + (extension_loaded('apc') && ini_get('apc.enabled')) + || + (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable')) + || + (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) + || + (extension_loaded('xcache') && ini_get('xcache.cacher')) + || + (extension_loaded('wincache') && ini_get('wincache.ocenabled')) + ; + + $this->addRecommendation( + $accelerator, + 'a PHP accelerator should be installed', + 'Install and/or enable a PHP accelerator (highly recommended).' + ); + + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { + $this->addRecommendation( + $this->getRealpathCacheSize() > 1000, + 'realpath_cache_size should be above 1024 in php.ini', + 'Set "realpath_cache_size" to e.g. "1024" in php.ini* to improve performance on windows.' + ); + } + + $this->addPhpIniRecommendation('short_open_tag', false); + + $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); + + $this->addPhpIniRecommendation('register_globals', false, true); + + $this->addPhpIniRecommendation('session.auto_start', false); + + $this->addRecommendation( + class_exists('PDO'), + 'PDO should be installed', + 'Install PDO (mandatory for Doctrine).' + ); + + if (class_exists('PDO')) { + $drivers = PDO::getAvailableDrivers(); + $this->addRecommendation( + count($drivers) > 0, + sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), + 'Install PDO drivers (mandatory for Doctrine).' + ); + } + } + + /** + * Loads realpath_cache_size from php.ini and converts it to int. + * + * (e.g. 16k is converted to 16384 int) + * + * @return int + */ + protected function getRealpathCacheSize() + { + $size = ini_get('realpath_cache_size'); + $size = trim($size); + $unit = strtolower(substr($size, -1, 1)); + switch ($unit) { + case 'g': + return $size * 1024 * 1024 * 1024; + case 'm': + return $size * 1024 * 1024; + case 'k': + return $size * 1024; + default: + return (int) $size; + } + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/app/autoload.php b/exercises/legacy_create_video/base/php-symfony/app/autoload.php new file mode 100644 index 00000000..75069ac3 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/autoload.php @@ -0,0 +1,14 @@ +parameters = $parameters; +} +public function all() +{ +return $this->parameters; +} +public function keys() +{ +return array_keys($this->parameters); +} +public function replace(array $parameters = array()) +{ +$this->parameters = $parameters; +} +public function add(array $parameters = array()) +{ +$this->parameters = array_replace($this->parameters, $parameters); +} +public function get($path, $default = null, $deep = false) +{ +if (!$deep || false === $pos = strpos($path,'[')) { +return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default; +} +$root = substr($path, 0, $pos); +if (!array_key_exists($root, $this->parameters)) { +return $default; +} +$value = $this->parameters[$root]; +$currentKey = null; +for ($i = $pos, $c = strlen($path); $i < $c; ++$i) { +$char = $path[$i]; +if ('['=== $char) { +if (null !== $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); +} +$currentKey =''; +} elseif (']'=== $char) { +if (null === $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); +} +if (!is_array($value) || !array_key_exists($currentKey, $value)) { +return $default; +} +$value = $value[$currentKey]; +$currentKey = null; +} else { +if (null === $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); +} +$currentKey .= $char; +} +} +if (null !== $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); +} +return $value; +} +public function set($key, $value) +{ +$this->parameters[$key] = $value; +} +public function has($key) +{ +return array_key_exists($key, $this->parameters); +} +public function remove($key) +{ +unset($this->parameters[$key]); +} +public function getAlpha($key, $default ='', $deep = false) +{ +return preg_replace('/[^[:alpha:]]/','', $this->get($key, $default, $deep)); +} +public function getAlnum($key, $default ='', $deep = false) +{ +return preg_replace('/[^[:alnum:]]/','', $this->get($key, $default, $deep)); +} +public function getDigits($key, $default ='', $deep = false) +{ +return str_replace(array('-','+'),'', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT)); +} +public function getInt($key, $default = 0, $deep = false) +{ +return (int) $this->get($key, $default, $deep); +} +public function getBoolean($key, $default = false, $deep = false) +{ +return $this->filter($key, $default, $deep, FILTER_VALIDATE_BOOLEAN); +} +public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array()) +{ +$value = $this->get($key, $default, $deep); +if (!is_array($options) && $options) { +$options = array('flags'=> $options); +} +if (is_array($value) && !isset($options['flags'])) { +$options['flags'] = FILTER_REQUIRE_ARRAY; +} +return filter_var($value, $filter, $options); +} +public function getIterator() +{ +return new \ArrayIterator($this->parameters); +} +public function count() +{ +return count($this->parameters); +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class HeaderBag implements \IteratorAggregate, \Countable +{ +protected $headers = array(); +protected $cacheControl = array(); +public function __construct(array $headers = array()) +{ +foreach ($headers as $key => $values) { +$this->set($key, $values); +} +} +public function __toString() +{ +if (!$this->headers) { +return''; +} +$max = max(array_map('strlen', array_keys($this->headers))) + 1; +$content =''; +ksort($this->headers); +foreach ($this->headers as $name => $values) { +$name = implode('-', array_map('ucfirst', explode('-', $name))); +foreach ($values as $value) { +$content .= sprintf("%-{$max}s %s\r\n", $name.':', $value); +} +} +return $content; +} +public function all() +{ +return $this->headers; +} +public function keys() +{ +return array_keys($this->headers); +} +public function replace(array $headers = array()) +{ +$this->headers = array(); +$this->add($headers); +} +public function add(array $headers) +{ +foreach ($headers as $key => $values) { +$this->set($key, $values); +} +} +public function get($key, $default = null, $first = true) +{ +$key = str_replace('_','-', strtolower($key)); +if (!array_key_exists($key, $this->headers)) { +if (null === $default) { +return $first ? null : array(); +} +return $first ? $default : array($default); +} +if ($first) { +return count($this->headers[$key]) ? $this->headers[$key][0] : $default; +} +return $this->headers[$key]; +} +public function set($key, $values, $replace = true) +{ +$key = str_replace('_','-', strtolower($key)); +$values = array_values((array) $values); +if (true === $replace || !isset($this->headers[$key])) { +$this->headers[$key] = $values; +} else { +$this->headers[$key] = array_merge($this->headers[$key], $values); +} +if ('cache-control'=== $key) { +$this->cacheControl = $this->parseCacheControl($values[0]); +} +} +public function has($key) +{ +return array_key_exists(str_replace('_','-', strtolower($key)), $this->headers); +} +public function contains($key, $value) +{ +return in_array($value, $this->get($key, null, false)); +} +public function remove($key) +{ +$key = str_replace('_','-', strtolower($key)); +unset($this->headers[$key]); +if ('cache-control'=== $key) { +$this->cacheControl = array(); +} +} +public function getDate($key, \DateTime $default = null) +{ +if (null === $value = $this->get($key)) { +return $default; +} +if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { +throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value)); +} +return $date; +} +public function addCacheControlDirective($key, $value = true) +{ +$this->cacheControl[$key] = $value; +$this->set('Cache-Control', $this->getCacheControlHeader()); +} +public function hasCacheControlDirective($key) +{ +return array_key_exists($key, $this->cacheControl); +} +public function getCacheControlDirective($key) +{ +return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; +} +public function removeCacheControlDirective($key) +{ +unset($this->cacheControl[$key]); +$this->set('Cache-Control', $this->getCacheControlHeader()); +} +public function getIterator() +{ +return new \ArrayIterator($this->headers); +} +public function count() +{ +return count($this->headers); +} +protected function getCacheControlHeader() +{ +$parts = array(); +ksort($this->cacheControl); +foreach ($this->cacheControl as $key => $value) { +if (true === $value) { +$parts[] = $key; +} else { +if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { +$value ='"'.$value.'"'; +} +$parts[] = "$key=$value"; +} +} +return implode(', ', $parts); +} +protected function parseCacheControl($header) +{ +$cacheControl = array(); +preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER); +foreach ($matches as $match) { +$cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true); +} +return $cacheControl; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +use Symfony\Component\HttpFoundation\File\UploadedFile; +class FileBag extends ParameterBag +{ +private static $fileKeys = array('error','name','size','tmp_name','type'); +public function __construct(array $parameters = array()) +{ +$this->replace($parameters); +} +public function replace(array $files = array()) +{ +$this->parameters = array(); +$this->add($files); +} +public function set($key, $value) +{ +if (!is_array($value) && !$value instanceof UploadedFile) { +throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.'); +} +parent::set($key, $this->convertFileInformation($value)); +} +public function add(array $files = array()) +{ +foreach ($files as $key => $file) { +$this->set($key, $file); +} +} +protected function convertFileInformation($file) +{ +if ($file instanceof UploadedFile) { +return $file; +} +$file = $this->fixPhpFilesArray($file); +if (is_array($file)) { +$keys = array_keys($file); +sort($keys); +if ($keys == self::$fileKeys) { +if (UPLOAD_ERR_NO_FILE == $file['error']) { +$file = null; +} else { +$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']); +} +} else { +$file = array_map(array($this,'convertFileInformation'), $file); +} +} +return $file; +} +protected function fixPhpFilesArray($data) +{ +if (!is_array($data)) { +return $data; +} +$keys = array_keys($data); +sort($keys); +if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) { +return $data; +} +$files = $data; +foreach (self::$fileKeys as $k) { +unset($files[$k]); +} +foreach ($data['name'] as $key => $name) { +$files[$key] = $this->fixPhpFilesArray(array('error'=> $data['error'][$key],'name'=> $name,'type'=> $data['type'][$key],'tmp_name'=> $data['tmp_name'][$key],'size'=> $data['size'][$key], +)); +} +return $files; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class ServerBag extends ParameterBag +{ +public function getHeaders() +{ +$headers = array(); +$contentHeaders = array('CONTENT_LENGTH'=> true,'CONTENT_MD5'=> true,'CONTENT_TYPE'=> true); +foreach ($this->parameters as $key => $value) { +if (0 === strpos($key,'HTTP_')) { +$headers[substr($key, 5)] = $value; +} +elseif (isset($contentHeaders[$key])) { +$headers[$key] = $value; +} +} +if (isset($this->parameters['PHP_AUTH_USER'])) { +$headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER']; +$headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] :''; +} else { +$authorizationHeader = null; +if (isset($this->parameters['HTTP_AUTHORIZATION'])) { +$authorizationHeader = $this->parameters['HTTP_AUTHORIZATION']; +} elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) { +$authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION']; +} +if (null !== $authorizationHeader) { +if (0 === stripos($authorizationHeader,'basic ')) { +$exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2); +if (count($exploded) == 2) { +list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded; +} +} elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader,'digest '))) { +$headers['PHP_AUTH_DIGEST'] = $authorizationHeader; +$this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader; +} elseif (0 === stripos($authorizationHeader,'bearer ')) { +$headers['AUTHORIZATION'] = $authorizationHeader; +} +} +} +if (isset($headers['AUTHORIZATION'])) { +return $headers; +} +if (isset($headers['PHP_AUTH_USER'])) { +$headers['AUTHORIZATION'] ='Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']); +} elseif (isset($headers['PHP_AUTH_DIGEST'])) { +$headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST']; +} +return $headers; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +use Symfony\Component\HttpFoundation\Session\SessionInterface; +class Request +{ +const HEADER_FORWARDED ='forwarded'; +const HEADER_CLIENT_IP ='client_ip'; +const HEADER_CLIENT_HOST ='client_host'; +const HEADER_CLIENT_PROTO ='client_proto'; +const HEADER_CLIENT_PORT ='client_port'; +const METHOD_HEAD ='HEAD'; +const METHOD_GET ='GET'; +const METHOD_POST ='POST'; +const METHOD_PUT ='PUT'; +const METHOD_PATCH ='PATCH'; +const METHOD_DELETE ='DELETE'; +const METHOD_PURGE ='PURGE'; +const METHOD_OPTIONS ='OPTIONS'; +const METHOD_TRACE ='TRACE'; +const METHOD_CONNECT ='CONNECT'; +protected static $trustedProxies = array(); +protected static $trustedHostPatterns = array(); +protected static $trustedHosts = array(); +protected static $trustedHeaders = array( +self::HEADER_FORWARDED =>'FORWARDED', +self::HEADER_CLIENT_IP =>'X_FORWARDED_FOR', +self::HEADER_CLIENT_HOST =>'X_FORWARDED_HOST', +self::HEADER_CLIENT_PROTO =>'X_FORWARDED_PROTO', +self::HEADER_CLIENT_PORT =>'X_FORWARDED_PORT', +); +protected static $httpMethodParameterOverride = false; +public $attributes; +public $request; +public $query; +public $server; +public $files; +public $cookies; +public $headers; +protected $content; +protected $languages; +protected $charsets; +protected $encodings; +protected $acceptableContentTypes; +protected $pathInfo; +protected $requestUri; +protected $baseUrl; +protected $basePath; +protected $method; +protected $format; +protected $session; +protected $locale; +protected $defaultLocale ='en'; +protected static $formats; +protected static $requestFactory; +public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content); +} +public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +$this->request = new ParameterBag($request); +$this->query = new ParameterBag($query); +$this->attributes = new ParameterBag($attributes); +$this->cookies = new ParameterBag($cookies); +$this->files = new FileBag($files); +$this->server = new ServerBag($server); +$this->headers = new HeaderBag($this->server->getHeaders()); +$this->content = $content; +$this->languages = null; +$this->charsets = null; +$this->encodings = null; +$this->acceptableContentTypes = null; +$this->pathInfo = null; +$this->requestUri = null; +$this->baseUrl = null; +$this->basePath = null; +$this->method = null; +$this->format = null; +} +public static function createFromGlobals() +{ +$server = $_SERVER; +if ('cli-server'=== PHP_SAPI) { +if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) { +$server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH']; +} +if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) { +$server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE']; +} +} +$request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server); +if (0 === strpos($request->headers->get('CONTENT_TYPE'),'application/x-www-form-urlencoded') +&& in_array(strtoupper($request->server->get('REQUEST_METHOD','GET')), array('PUT','DELETE','PATCH')) +) { +parse_str($request->getContent(), $data); +$request->request = new ParameterBag($data); +} +return $request; +} +public static function create($uri, $method ='GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) +{ +$server = array_replace(array('SERVER_NAME'=>'localhost','SERVER_PORT'=> 80,'HTTP_HOST'=>'localhost','HTTP_USER_AGENT'=>'Symfony/2.X','HTTP_ACCEPT'=>'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','HTTP_ACCEPT_LANGUAGE'=>'en-us,en;q=0.5','HTTP_ACCEPT_CHARSET'=>'ISO-8859-1,utf-8;q=0.7,*;q=0.7','REMOTE_ADDR'=>'127.0.0.1','SCRIPT_NAME'=>'','SCRIPT_FILENAME'=>'','SERVER_PROTOCOL'=>'HTTP/1.1','REQUEST_TIME'=> time(), +), $server); +$server['PATH_INFO'] =''; +$server['REQUEST_METHOD'] = strtoupper($method); +$components = parse_url($uri); +if (isset($components['host'])) { +$server['SERVER_NAME'] = $components['host']; +$server['HTTP_HOST'] = $components['host']; +} +if (isset($components['scheme'])) { +if ('https'=== $components['scheme']) { +$server['HTTPS'] ='on'; +$server['SERVER_PORT'] = 443; +} else { +unset($server['HTTPS']); +$server['SERVER_PORT'] = 80; +} +} +if (isset($components['port'])) { +$server['SERVER_PORT'] = $components['port']; +$server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port']; +} +if (isset($components['user'])) { +$server['PHP_AUTH_USER'] = $components['user']; +} +if (isset($components['pass'])) { +$server['PHP_AUTH_PW'] = $components['pass']; +} +if (!isset($components['path'])) { +$components['path'] ='/'; +} +switch (strtoupper($method)) { +case'POST': +case'PUT': +case'DELETE': +if (!isset($server['CONTENT_TYPE'])) { +$server['CONTENT_TYPE'] ='application/x-www-form-urlencoded'; +} +case'PATCH': +$request = $parameters; +$query = array(); +break; +default: +$request = array(); +$query = $parameters; +break; +} +$queryString =''; +if (isset($components['query'])) { +parse_str(html_entity_decode($components['query']), $qs); +if ($query) { +$query = array_replace($qs, $query); +$queryString = http_build_query($query,'','&'); +} else { +$query = $qs; +$queryString = $components['query']; +} +} elseif ($query) { +$queryString = http_build_query($query,'','&'); +} +$server['REQUEST_URI'] = $components['path'].(''!== $queryString ?'?'.$queryString :''); +$server['QUERY_STRING'] = $queryString; +return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content); +} +public static function setFactory($callable) +{ +self::$requestFactory = $callable; +} +public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) +{ +$dup = clone $this; +if ($query !== null) { +$dup->query = new ParameterBag($query); +} +if ($request !== null) { +$dup->request = new ParameterBag($request); +} +if ($attributes !== null) { +$dup->attributes = new ParameterBag($attributes); +} +if ($cookies !== null) { +$dup->cookies = new ParameterBag($cookies); +} +if ($files !== null) { +$dup->files = new FileBag($files); +} +if ($server !== null) { +$dup->server = new ServerBag($server); +$dup->headers = new HeaderBag($dup->server->getHeaders()); +} +$dup->languages = null; +$dup->charsets = null; +$dup->encodings = null; +$dup->acceptableContentTypes = null; +$dup->pathInfo = null; +$dup->requestUri = null; +$dup->baseUrl = null; +$dup->basePath = null; +$dup->method = null; +$dup->format = null; +if (!$dup->get('_format') && $this->get('_format')) { +$dup->attributes->set('_format', $this->get('_format')); +} +if (!$dup->getRequestFormat(null)) { +$dup->setRequestFormat($this->getRequestFormat(null)); +} +return $dup; +} +public function __clone() +{ +$this->query = clone $this->query; +$this->request = clone $this->request; +$this->attributes = clone $this->attributes; +$this->cookies = clone $this->cookies; +$this->files = clone $this->files; +$this->server = clone $this->server; +$this->headers = clone $this->headers; +} +public function __toString() +{ +try { +$content = $this->getContent(); +} catch (\LogicException $e) { +return trigger_error($e, E_USER_ERROR); +} +return +sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n". +$this->headers."\r\n". +$content; +} +public function overrideGlobals() +{ +$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null,'&'))); +$_GET = $this->query->all(); +$_POST = $this->request->all(); +$_SERVER = $this->server->all(); +$_COOKIE = $this->cookies->all(); +foreach ($this->headers->all() as $key => $value) { +$key = strtoupper(str_replace('-','_', $key)); +if (in_array($key, array('CONTENT_TYPE','CONTENT_LENGTH'))) { +$_SERVER[$key] = implode(', ', $value); +} else { +$_SERVER['HTTP_'.$key] = implode(', ', $value); +} +} +$request = array('g'=> $_GET,'p'=> $_POST,'c'=> $_COOKIE); +$requestOrder = ini_get('request_order') ?: ini_get('variables_order'); +$requestOrder = preg_replace('#[^cgp]#','', strtolower($requestOrder)) ?:'gp'; +$_REQUEST = array(); +foreach (str_split($requestOrder) as $order) { +$_REQUEST = array_merge($_REQUEST, $request[$order]); +} +} +public static function setTrustedProxies(array $proxies) +{ +self::$trustedProxies = $proxies; +} +public static function getTrustedProxies() +{ +return self::$trustedProxies; +} +public static function setTrustedHosts(array $hostPatterns) +{ +self::$trustedHostPatterns = array_map(function ($hostPattern) { +return sprintf('#%s#i', $hostPattern); +}, $hostPatterns); +self::$trustedHosts = array(); +} +public static function getTrustedHosts() +{ +return self::$trustedHostPatterns; +} +public static function setTrustedHeaderName($key, $value) +{ +if (!array_key_exists($key, self::$trustedHeaders)) { +throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key)); +} +self::$trustedHeaders[$key] = $value; +} +public static function getTrustedHeaderName($key) +{ +if (!array_key_exists($key, self::$trustedHeaders)) { +throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key)); +} +return self::$trustedHeaders[$key]; +} +public static function normalizeQueryString($qs) +{ +if (''== $qs) { +return''; +} +$parts = array(); +$order = array(); +foreach (explode('&', $qs) as $param) { +if (''=== $param ||'='=== $param[0]) { +continue; +} +$keyValuePair = explode('=', $param, 2); +$parts[] = isset($keyValuePair[1]) ? +rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) : +rawurlencode(urldecode($keyValuePair[0])); +$order[] = urldecode($keyValuePair[0]); +} +array_multisort($order, SORT_ASC, $parts); +return implode('&', $parts); +} +public static function enableHttpMethodParameterOverride() +{ +self::$httpMethodParameterOverride = true; +} +public static function getHttpMethodParameterOverride() +{ +return self::$httpMethodParameterOverride; +} +public function get($key, $default = null, $deep = false) +{ +if ($this !== $result = $this->query->get($key, $this, $deep)) { +return $result; +} +if ($this !== $result = $this->attributes->get($key, $this, $deep)) { +return $result; +} +if ($this !== $result = $this->request->get($key, $this, $deep)) { +return $result; +} +return $default; +} +public function getSession() +{ +return $this->session; +} +public function hasPreviousSession() +{ +return $this->hasSession() && $this->cookies->has($this->session->getName()); +} +public function hasSession() +{ +return null !== $this->session; +} +public function setSession(SessionInterface $session) +{ +$this->session = $session; +} +public function getClientIps() +{ +$clientIps = array(); +$ip = $this->server->get('REMOTE_ADDR'); +if (!$this->isFromTrustedProxy()) { +return array($ip); +} +if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { +$forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); +preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); +$clientIps = $matches[3]; +} elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { +$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); +} +$clientIps[] = $ip; $firstTrustedIp = null; +foreach ($clientIps as $key => $clientIp) { +if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) { +$clientIps[$key] = $clientIp = $match[1]; +} +if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { +unset($clientIps[$key]); +continue; +} +if (IpUtils::checkIp($clientIp, self::$trustedProxies)) { +unset($clientIps[$key]); +if (null === $firstTrustedIp) { +$firstTrustedIp = $clientIp; +} +} +} +return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp); +} +public function getClientIp() +{ +$ipAddresses = $this->getClientIps(); +return $ipAddresses[0]; +} +public function getScriptName() +{ +return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME','')); +} +public function getPathInfo() +{ +if (null === $this->pathInfo) { +$this->pathInfo = $this->preparePathInfo(); +} +return $this->pathInfo; +} +public function getBasePath() +{ +if (null === $this->basePath) { +$this->basePath = $this->prepareBasePath(); +} +return $this->basePath; +} +public function getBaseUrl() +{ +if (null === $this->baseUrl) { +$this->baseUrl = $this->prepareBaseUrl(); +} +return $this->baseUrl; +} +public function getScheme() +{ +return $this->isSecure() ?'https':'http'; +} +public function getPort() +{ +if ($this->isFromTrustedProxy()) { +if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { +return $port; +} +if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] &&'https'=== $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO],'http')) { +return 443; +} +} +if ($host = $this->headers->get('HOST')) { +if ($host[0] ==='[') { +$pos = strpos($host,':', strrpos($host,']')); +} else { +$pos = strrpos($host,':'); +} +if (false !== $pos) { +return (int) substr($host, $pos + 1); +} +return'https'=== $this->getScheme() ? 443 : 80; +} +return $this->server->get('SERVER_PORT'); +} +public function getUser() +{ +return $this->headers->get('PHP_AUTH_USER'); +} +public function getPassword() +{ +return $this->headers->get('PHP_AUTH_PW'); +} +public function getUserInfo() +{ +$userinfo = $this->getUser(); +$pass = $this->getPassword(); +if (''!= $pass) { +$userinfo .= ":$pass"; +} +return $userinfo; +} +public function getHttpHost() +{ +$scheme = $this->getScheme(); +$port = $this->getPort(); +if (('http'== $scheme && $port == 80) || ('https'== $scheme && $port == 443)) { +return $this->getHost(); +} +return $this->getHost().':'.$port; +} +public function getRequestUri() +{ +if (null === $this->requestUri) { +$this->requestUri = $this->prepareRequestUri(); +} +return $this->requestUri; +} +public function getSchemeAndHttpHost() +{ +return $this->getScheme().'://'.$this->getHttpHost(); +} +public function getUri() +{ +if (null !== $qs = $this->getQueryString()) { +$qs ='?'.$qs; +} +return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs; +} +public function getUriForPath($path) +{ +return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path; +} +public function getRelativeUriForPath($path) +{ +if (!isset($path[0]) ||'/'!== $path[0]) { +return $path; +} +if ($path === $basePath = $this->getPathInfo()) { +return''; +} +$sourceDirs = explode('/', isset($basePath[0]) &&'/'=== $basePath[0] ? substr($basePath, 1) : $basePath); +$targetDirs = explode('/', isset($path[0]) &&'/'=== $path[0] ? substr($path, 1) : $path); +array_pop($sourceDirs); +$targetFile = array_pop($targetDirs); +foreach ($sourceDirs as $i => $dir) { +if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) { +unset($sourceDirs[$i], $targetDirs[$i]); +} else { +break; +} +} +$targetDirs[] = $targetFile; +$path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs); +return !isset($path[0]) ||'/'=== $path[0] +|| false !== ($colonPos = strpos($path,':')) && ($colonPos < ($slashPos = strpos($path,'/')) || false === $slashPos) +? "./$path" : $path; +} +public function getQueryString() +{ +$qs = static::normalizeQueryString($this->server->get('QUERY_STRING')); +return''=== $qs ? null : $qs; +} +public function isSecure() +{ +if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { +return in_array(strtolower(current(explode(',', $proto))), array('https','on','ssl','1')); +} +$https = $this->server->get('HTTPS'); +return !empty($https) &&'off'!== strtolower($https); +} +public function getHost() +{ +if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { +$elements = explode(',', $host); +$host = $elements[count($elements) - 1]; +} elseif (!$host = $this->headers->get('HOST')) { +if (!$host = $this->server->get('SERVER_NAME')) { +$host = $this->server->get('SERVER_ADDR',''); +} +} +$host = strtolower(preg_replace('/:\d+$/','', trim($host))); +if ($host &&''!== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/','', $host)) { +throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host)); +} +if (count(self::$trustedHostPatterns) > 0) { +if (in_array($host, self::$trustedHosts)) { +return $host; +} +foreach (self::$trustedHostPatterns as $pattern) { +if (preg_match($pattern, $host)) { +self::$trustedHosts[] = $host; +return $host; +} +} +throw new \UnexpectedValueException(sprintf('Untrusted Host "%s"', $host)); +} +return $host; +} +public function setMethod($method) +{ +$this->method = null; +$this->server->set('REQUEST_METHOD', $method); +} +public function getMethod() +{ +if (null === $this->method) { +$this->method = strtoupper($this->server->get('REQUEST_METHOD','GET')); +if ('POST'=== $this->method) { +if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) { +$this->method = strtoupper($method); +} elseif (self::$httpMethodParameterOverride) { +$this->method = strtoupper($this->request->get('_method', $this->query->get('_method','POST'))); +} +} +} +return $this->method; +} +public function getRealMethod() +{ +return strtoupper($this->server->get('REQUEST_METHOD','GET')); +} +public function getMimeType($format) +{ +if (null === static::$formats) { +static::initializeFormats(); +} +return isset(static::$formats[$format]) ? static::$formats[$format][0] : null; +} +public function getFormat($mimeType) +{ +$canonicalMimeType = null; +if (false !== $pos = strpos($mimeType,';')) { +$canonicalMimeType = substr($mimeType, 0, $pos); +} +if (null === static::$formats) { +static::initializeFormats(); +} +foreach (static::$formats as $format => $mimeTypes) { +if (in_array($mimeType, (array) $mimeTypes)) { +return $format; +} +if (null !== $canonicalMimeType && in_array($canonicalMimeType, (array) $mimeTypes)) { +return $format; +} +} +} +public function setFormat($format, $mimeTypes) +{ +if (null === static::$formats) { +static::initializeFormats(); +} +static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes); +} +public function getRequestFormat($default ='html') +{ +if (null === $this->format) { +$this->format = $this->get('_format', $default); +} +return $this->format; +} +public function setRequestFormat($format) +{ +$this->format = $format; +} +public function getContentType() +{ +return $this->getFormat($this->headers->get('CONTENT_TYPE')); +} +public function setDefaultLocale($locale) +{ +$this->defaultLocale = $locale; +if (null === $this->locale) { +$this->setPhpDefaultLocale($locale); +} +} +public function getDefaultLocale() +{ +return $this->defaultLocale; +} +public function setLocale($locale) +{ +$this->setPhpDefaultLocale($this->locale = $locale); +} +public function getLocale() +{ +return null === $this->locale ? $this->defaultLocale : $this->locale; +} +public function isMethod($method) +{ +return $this->getMethod() === strtoupper($method); +} +public function isMethodSafe() +{ +return in_array($this->getMethod(), array('GET','HEAD')); +} +public function getContent($asResource = false) +{ +$currentContentIsResource = is_resource($this->content); +if (PHP_VERSION_ID < 50600 && false === $this->content) { +throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.'); +} +if (true === $asResource) { +if ($currentContentIsResource) { +rewind($this->content); +return $this->content; +} +if (is_string($this->content)) { +$resource = fopen('php://temp','r+'); +fwrite($resource, $this->content); +rewind($resource); +return $resource; +} +$this->content = false; +return fopen('php://input','rb'); +} +if ($currentContentIsResource) { +rewind($this->content); +return stream_get_contents($this->content); +} +if (null === $this->content) { +$this->content = file_get_contents('php://input'); +} +return $this->content; +} +public function getETags() +{ +return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY); +} +public function isNoCache() +{ +return $this->headers->hasCacheControlDirective('no-cache') ||'no-cache'== $this->headers->get('Pragma'); +} +public function getPreferredLanguage(array $locales = null) +{ +$preferredLanguages = $this->getLanguages(); +if (empty($locales)) { +return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null; +} +if (!$preferredLanguages) { +return $locales[0]; +} +$extendedPreferredLanguages = array(); +foreach ($preferredLanguages as $language) { +$extendedPreferredLanguages[] = $language; +if (false !== $position = strpos($language,'_')) { +$superLanguage = substr($language, 0, $position); +if (!in_array($superLanguage, $preferredLanguages)) { +$extendedPreferredLanguages[] = $superLanguage; +} +} +} +$preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales)); +return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0]; +} +public function getLanguages() +{ +if (null !== $this->languages) { +return $this->languages; +} +$languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); +$this->languages = array(); +foreach ($languages as $lang => $acceptHeaderItem) { +if (false !== strpos($lang,'-')) { +$codes = explode('-', $lang); +if ('i'=== $codes[0]) { +if (count($codes) > 1) { +$lang = $codes[1]; +} +} else { +for ($i = 0, $max = count($codes); $i < $max; ++$i) { +if ($i === 0) { +$lang = strtolower($codes[0]); +} else { +$lang .='_'.strtoupper($codes[$i]); +} +} +} +} +$this->languages[] = $lang; +} +return $this->languages; +} +public function getCharsets() +{ +if (null !== $this->charsets) { +return $this->charsets; +} +return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all()); +} +public function getEncodings() +{ +if (null !== $this->encodings) { +return $this->encodings; +} +return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all()); +} +public function getAcceptableContentTypes() +{ +if (null !== $this->acceptableContentTypes) { +return $this->acceptableContentTypes; +} +return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all()); +} +public function isXmlHttpRequest() +{ +return'XMLHttpRequest'== $this->headers->get('X-Requested-With'); +} +protected function prepareRequestUri() +{ +$requestUri =''; +if ($this->headers->has('X_ORIGINAL_URL')) { +$requestUri = $this->headers->get('X_ORIGINAL_URL'); +$this->headers->remove('X_ORIGINAL_URL'); +$this->server->remove('HTTP_X_ORIGINAL_URL'); +$this->server->remove('UNENCODED_URL'); +$this->server->remove('IIS_WasUrlRewritten'); +} elseif ($this->headers->has('X_REWRITE_URL')) { +$requestUri = $this->headers->get('X_REWRITE_URL'); +$this->headers->remove('X_REWRITE_URL'); +} elseif ($this->server->get('IIS_WasUrlRewritten') =='1'&& $this->server->get('UNENCODED_URL') !='') { +$requestUri = $this->server->get('UNENCODED_URL'); +$this->server->remove('UNENCODED_URL'); +$this->server->remove('IIS_WasUrlRewritten'); +} elseif ($this->server->has('REQUEST_URI')) { +$requestUri = $this->server->get('REQUEST_URI'); +$schemeAndHttpHost = $this->getSchemeAndHttpHost(); +if (strpos($requestUri, $schemeAndHttpHost) === 0) { +$requestUri = substr($requestUri, strlen($schemeAndHttpHost)); +} +} elseif ($this->server->has('ORIG_PATH_INFO')) { +$requestUri = $this->server->get('ORIG_PATH_INFO'); +if (''!= $this->server->get('QUERY_STRING')) { +$requestUri .='?'.$this->server->get('QUERY_STRING'); +} +$this->server->remove('ORIG_PATH_INFO'); +} +$this->server->set('REQUEST_URI', $requestUri); +return $requestUri; +} +protected function prepareBaseUrl() +{ +$filename = basename($this->server->get('SCRIPT_FILENAME')); +if (basename($this->server->get('SCRIPT_NAME')) === $filename) { +$baseUrl = $this->server->get('SCRIPT_NAME'); +} elseif (basename($this->server->get('PHP_SELF')) === $filename) { +$baseUrl = $this->server->get('PHP_SELF'); +} elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) { +$baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); } else { +$path = $this->server->get('PHP_SELF',''); +$file = $this->server->get('SCRIPT_FILENAME',''); +$segs = explode('/', trim($file,'/')); +$segs = array_reverse($segs); +$index = 0; +$last = count($segs); +$baseUrl =''; +do { +$seg = $segs[$index]; +$baseUrl ='/'.$seg.$baseUrl; +++$index; +} while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos); +} +$requestUri = $this->getRequestUri(); +if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) { +return $prefix; +} +if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl),'/'.DIRECTORY_SEPARATOR).'/')) { +return rtrim($prefix,'/'.DIRECTORY_SEPARATOR); +} +$truncatedRequestUri = $requestUri; +if (false !== $pos = strpos($requestUri,'?')) { +$truncatedRequestUri = substr($requestUri, 0, $pos); +} +$basename = basename($baseUrl); +if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { +return''; +} +if (strlen($requestUri) >= strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && $pos !== 0) { +$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); +} +return rtrim($baseUrl,'/'.DIRECTORY_SEPARATOR); +} +protected function prepareBasePath() +{ +$filename = basename($this->server->get('SCRIPT_FILENAME')); +$baseUrl = $this->getBaseUrl(); +if (empty($baseUrl)) { +return''; +} +if (basename($baseUrl) === $filename) { +$basePath = dirname($baseUrl); +} else { +$basePath = $baseUrl; +} +if ('\\'=== DIRECTORY_SEPARATOR) { +$basePath = str_replace('\\','/', $basePath); +} +return rtrim($basePath,'/'); +} +protected function preparePathInfo() +{ +$baseUrl = $this->getBaseUrl(); +if (null === ($requestUri = $this->getRequestUri())) { +return'/'; +} +if ($pos = strpos($requestUri,'?')) { +$requestUri = substr($requestUri, 0, $pos); +} +$pathInfo = substr($requestUri, strlen($baseUrl)); +if (null !== $baseUrl && (false === $pathInfo ||''=== $pathInfo)) { +return'/'; +} elseif (null === $baseUrl) { +return $requestUri; +} +return (string) $pathInfo; +} +protected static function initializeFormats() +{ +static::$formats = array('html'=> array('text/html','application/xhtml+xml'),'txt'=> array('text/plain'),'js'=> array('application/javascript','application/x-javascript','text/javascript'),'css'=> array('text/css'),'json'=> array('application/json','application/x-json'),'xml'=> array('text/xml','application/xml','application/x-xml'),'rdf'=> array('application/rdf+xml'),'atom'=> array('application/atom+xml'),'rss'=> array('application/rss+xml'),'form'=> array('application/x-www-form-urlencoded'), +); +} +private function setPhpDefaultLocale($locale) +{ +try { +if (class_exists('Locale', false)) { +\Locale::setDefault($locale); +} +} catch (\Exception $e) { +} +} +private function getUrlencodedPrefix($string, $prefix) +{ +if (0 !== strpos(rawurldecode($string), $prefix)) { +return false; +} +$len = strlen($prefix); +if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) { +return $match[0]; +} +return false; +} +private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +if (self::$requestFactory) { +$request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content); +if (!$request instanceof self) { +throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.'); +} +return $request; +} +return new static($query, $request, $attributes, $cookies, $files, $server, $content); +} +private function isFromTrustedProxy() +{ +return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class Response +{ +const HTTP_CONTINUE = 100; +const HTTP_SWITCHING_PROTOCOLS = 101; +const HTTP_PROCESSING = 102; const HTTP_OK = 200; +const HTTP_CREATED = 201; +const HTTP_ACCEPTED = 202; +const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; +const HTTP_NO_CONTENT = 204; +const HTTP_RESET_CONTENT = 205; +const HTTP_PARTIAL_CONTENT = 206; +const HTTP_MULTI_STATUS = 207; const HTTP_ALREADY_REPORTED = 208; const HTTP_IM_USED = 226; const HTTP_MULTIPLE_CHOICES = 300; +const HTTP_MOVED_PERMANENTLY = 301; +const HTTP_FOUND = 302; +const HTTP_SEE_OTHER = 303; +const HTTP_NOT_MODIFIED = 304; +const HTTP_USE_PROXY = 305; +const HTTP_RESERVED = 306; +const HTTP_TEMPORARY_REDIRECT = 307; +const HTTP_PERMANENTLY_REDIRECT = 308; const HTTP_BAD_REQUEST = 400; +const HTTP_UNAUTHORIZED = 401; +const HTTP_PAYMENT_REQUIRED = 402; +const HTTP_FORBIDDEN = 403; +const HTTP_NOT_FOUND = 404; +const HTTP_METHOD_NOT_ALLOWED = 405; +const HTTP_NOT_ACCEPTABLE = 406; +const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; +const HTTP_REQUEST_TIMEOUT = 408; +const HTTP_CONFLICT = 409; +const HTTP_GONE = 410; +const HTTP_LENGTH_REQUIRED = 411; +const HTTP_PRECONDITION_FAILED = 412; +const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; +const HTTP_REQUEST_URI_TOO_LONG = 414; +const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; +const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; +const HTTP_EXPECTATION_FAILED = 417; +const HTTP_I_AM_A_TEAPOT = 418; const HTTP_MISDIRECTED_REQUEST = 421; const HTTP_UNPROCESSABLE_ENTITY = 422; const HTTP_LOCKED = 423; const HTTP_FAILED_DEPENDENCY = 424; const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; const HTTP_UPGRADE_REQUIRED = 426; const HTTP_PRECONDITION_REQUIRED = 428; const HTTP_TOO_MANY_REQUESTS = 429; const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; +const HTTP_INTERNAL_SERVER_ERROR = 500; +const HTTP_NOT_IMPLEMENTED = 501; +const HTTP_BAD_GATEWAY = 502; +const HTTP_SERVICE_UNAVAILABLE = 503; +const HTTP_GATEWAY_TIMEOUT = 504; +const HTTP_VERSION_NOT_SUPPORTED = 505; +const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; const HTTP_INSUFFICIENT_STORAGE = 507; const HTTP_LOOP_DETECTED = 508; const HTTP_NOT_EXTENDED = 510; const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; +public $headers; +protected $content; +protected $version; +protected $statusCode; +protected $statusText; +protected $charset; +public static $statusTexts = array( +100 =>'Continue', +101 =>'Switching Protocols', +102 =>'Processing', 200 =>'OK', +201 =>'Created', +202 =>'Accepted', +203 =>'Non-Authoritative Information', +204 =>'No Content', +205 =>'Reset Content', +206 =>'Partial Content', +207 =>'Multi-Status', 208 =>'Already Reported', 226 =>'IM Used', 300 =>'Multiple Choices', +301 =>'Moved Permanently', +302 =>'Found', +303 =>'See Other', +304 =>'Not Modified', +305 =>'Use Proxy', +306 =>'Reserved', +307 =>'Temporary Redirect', +308 =>'Permanent Redirect', 400 =>'Bad Request', +401 =>'Unauthorized', +402 =>'Payment Required', +403 =>'Forbidden', +404 =>'Not Found', +405 =>'Method Not Allowed', +406 =>'Not Acceptable', +407 =>'Proxy Authentication Required', +408 =>'Request Timeout', +409 =>'Conflict', +410 =>'Gone', +411 =>'Length Required', +412 =>'Precondition Failed', +413 =>'Request Entity Too Large', +414 =>'Request-URI Too Long', +415 =>'Unsupported Media Type', +416 =>'Requested Range Not Satisfiable', +417 =>'Expectation Failed', +418 =>'I\'m a teapot', 421 =>'Misdirected Request', 422 =>'Unprocessable Entity', 423 =>'Locked', 424 =>'Failed Dependency', 425 =>'Reserved for WebDAV advanced collections expired proposal', 426 =>'Upgrade Required', 428 =>'Precondition Required', 429 =>'Too Many Requests', 431 =>'Request Header Fields Too Large', 451 =>'Unavailable For Legal Reasons', 500 =>'Internal Server Error', +501 =>'Not Implemented', +502 =>'Bad Gateway', +503 =>'Service Unavailable', +504 =>'Gateway Timeout', +505 =>'HTTP Version Not Supported', +506 =>'Variant Also Negotiates (Experimental)', 507 =>'Insufficient Storage', 508 =>'Loop Detected', 510 =>'Not Extended', 511 =>'Network Authentication Required', ); +public function __construct($content ='', $status = 200, $headers = array()) +{ +$this->headers = new ResponseHeaderBag($headers); +$this->setContent($content); +$this->setStatusCode($status); +$this->setProtocolVersion('1.0'); +if (!$this->headers->has('Date')) { +$this->setDate(\DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC'))); +} +} +public static function create($content ='', $status = 200, $headers = array()) +{ +return new static($content, $status, $headers); +} +public function __toString() +{ +return +sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". +$this->headers."\r\n". +$this->getContent(); +} +public function __clone() +{ +$this->headers = clone $this->headers; +} +public function prepare(Request $request) +{ +$headers = $this->headers; +if ($this->isInformational() || $this->isEmpty()) { +$this->setContent(null); +$headers->remove('Content-Type'); +$headers->remove('Content-Length'); +} else { +if (!$headers->has('Content-Type')) { +$format = $request->getRequestFormat(); +if (null !== $format && $mimeType = $request->getMimeType($format)) { +$headers->set('Content-Type', $mimeType); +} +} +$charset = $this->charset ?:'UTF-8'; +if (!$headers->has('Content-Type')) { +$headers->set('Content-Type','text/html; charset='.$charset); +} elseif (0 === stripos($headers->get('Content-Type'),'text/') && false === stripos($headers->get('Content-Type'),'charset')) { +$headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset); +} +if ($headers->has('Transfer-Encoding')) { +$headers->remove('Content-Length'); +} +if ($request->isMethod('HEAD')) { +$length = $headers->get('Content-Length'); +$this->setContent(null); +if ($length) { +$headers->set('Content-Length', $length); +} +} +} +if ('HTTP/1.0'!= $request->server->get('SERVER_PROTOCOL')) { +$this->setProtocolVersion('1.1'); +} +if ('1.0'== $this->getProtocolVersion() &&'no-cache'== $this->headers->get('Cache-Control')) { +$this->headers->set('pragma','no-cache'); +$this->headers->set('expires', -1); +} +$this->ensureIEOverSSLCompatibility($request); +return $this; +} +public function sendHeaders() +{ +if (headers_sent()) { +return $this; +} +foreach ($this->headers->allPreserveCase() as $name => $values) { +foreach ($values as $value) { +header($name.': '.$value, false); +} +} +header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); +foreach ($this->headers->getCookies() as $cookie) { +setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); +} +return $this; +} +public function sendContent() +{ +echo $this->content; +return $this; +} +public function send() +{ +$this->sendHeaders(); +$this->sendContent(); +if (function_exists('fastcgi_finish_request')) { +fastcgi_finish_request(); +} elseif ('cli'!== PHP_SAPI) { +static::closeOutputBuffers(0, true); +} +return $this; +} +public function setContent($content) +{ +if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content,'__toString'))) { +throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content))); +} +$this->content = (string) $content; +return $this; +} +public function getContent() +{ +return $this->content; +} +public function setProtocolVersion($version) +{ +$this->version = $version; +return $this; +} +public function getProtocolVersion() +{ +return $this->version; +} +public function setStatusCode($code, $text = null) +{ +$this->statusCode = $code = (int) $code; +if ($this->isInvalid()) { +throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); +} +if (null === $text) { +$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] :'unknown status'; +return $this; +} +if (false === $text) { +$this->statusText =''; +return $this; +} +$this->statusText = $text; +return $this; +} +public function getStatusCode() +{ +return $this->statusCode; +} +public function setCharset($charset) +{ +$this->charset = $charset; +return $this; +} +public function getCharset() +{ +return $this->charset; +} +public function isCacheable() +{ +if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) { +return false; +} +if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) { +return false; +} +return $this->isValidateable() || $this->isFresh(); +} +public function isFresh() +{ +return $this->getTtl() > 0; +} +public function isValidateable() +{ +return $this->headers->has('Last-Modified') || $this->headers->has('ETag'); +} +public function setPrivate() +{ +$this->headers->removeCacheControlDirective('public'); +$this->headers->addCacheControlDirective('private'); +return $this; +} +public function setPublic() +{ +$this->headers->addCacheControlDirective('public'); +$this->headers->removeCacheControlDirective('private'); +return $this; +} +public function mustRevalidate() +{ +return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate'); +} +public function getDate() +{ +return $this->headers->getDate('Date', new \DateTime()); +} +public function setDate(\DateTime $date) +{ +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT'); +return $this; +} +public function getAge() +{ +if (null !== $age = $this->headers->get('Age')) { +return (int) $age; +} +return max(time() - $this->getDate()->format('U'), 0); +} +public function expire() +{ +if ($this->isFresh()) { +$this->headers->set('Age', $this->getMaxAge()); +} +return $this; +} +public function getExpires() +{ +try { +return $this->headers->getDate('Expires'); +} catch (\RuntimeException $e) { +return \DateTime::createFromFormat(DATE_RFC2822,'Sat, 01 Jan 00 00:00:00 +0000'); +} +} +public function setExpires(\DateTime $date = null) +{ +if (null === $date) { +$this->headers->remove('Expires'); +} else { +$date = clone $date; +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT'); +} +return $this; +} +public function getMaxAge() +{ +if ($this->headers->hasCacheControlDirective('s-maxage')) { +return (int) $this->headers->getCacheControlDirective('s-maxage'); +} +if ($this->headers->hasCacheControlDirective('max-age')) { +return (int) $this->headers->getCacheControlDirective('max-age'); +} +if (null !== $this->getExpires()) { +return $this->getExpires()->format('U') - $this->getDate()->format('U'); +} +} +public function setMaxAge($value) +{ +$this->headers->addCacheControlDirective('max-age', $value); +return $this; +} +public function setSharedMaxAge($value) +{ +$this->setPublic(); +$this->headers->addCacheControlDirective('s-maxage', $value); +return $this; +} +public function getTtl() +{ +if (null !== $maxAge = $this->getMaxAge()) { +return $maxAge - $this->getAge(); +} +} +public function setTtl($seconds) +{ +$this->setSharedMaxAge($this->getAge() + $seconds); +return $this; +} +public function setClientTtl($seconds) +{ +$this->setMaxAge($this->getAge() + $seconds); +return $this; +} +public function getLastModified() +{ +return $this->headers->getDate('Last-Modified'); +} +public function setLastModified(\DateTime $date = null) +{ +if (null === $date) { +$this->headers->remove('Last-Modified'); +} else { +$date = clone $date; +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT'); +} +return $this; +} +public function getEtag() +{ +return $this->headers->get('ETag'); +} +public function setEtag($etag = null, $weak = false) +{ +if (null === $etag) { +$this->headers->remove('Etag'); +} else { +if (0 !== strpos($etag,'"')) { +$etag ='"'.$etag.'"'; +} +$this->headers->set('ETag', (true === $weak ?'W/':'').$etag); +} +return $this; +} +public function setCache(array $options) +{ +if ($diff = array_diff(array_keys($options), array('etag','last_modified','max_age','s_maxage','private','public'))) { +throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff)))); +} +if (isset($options['etag'])) { +$this->setEtag($options['etag']); +} +if (isset($options['last_modified'])) { +$this->setLastModified($options['last_modified']); +} +if (isset($options['max_age'])) { +$this->setMaxAge($options['max_age']); +} +if (isset($options['s_maxage'])) { +$this->setSharedMaxAge($options['s_maxage']); +} +if (isset($options['public'])) { +if ($options['public']) { +$this->setPublic(); +} else { +$this->setPrivate(); +} +} +if (isset($options['private'])) { +if ($options['private']) { +$this->setPrivate(); +} else { +$this->setPublic(); +} +} +return $this; +} +public function setNotModified() +{ +$this->setStatusCode(304); +$this->setContent(null); +foreach (array('Allow','Content-Encoding','Content-Language','Content-Length','Content-MD5','Content-Type','Last-Modified') as $header) { +$this->headers->remove($header); +} +return $this; +} +public function hasVary() +{ +return null !== $this->headers->get('Vary'); +} +public function getVary() +{ +if (!$vary = $this->headers->get('Vary', null, false)) { +return array(); +} +$ret = array(); +foreach ($vary as $item) { +$ret = array_merge($ret, preg_split('/[\s,]+/', $item)); +} +return $ret; +} +public function setVary($headers, $replace = true) +{ +$this->headers->set('Vary', $headers, $replace); +return $this; +} +public function isNotModified(Request $request) +{ +if (!$request->isMethodSafe()) { +return false; +} +$notModified = false; +$lastModified = $this->headers->get('Last-Modified'); +$modifiedSince = $request->headers->get('If-Modified-Since'); +if ($etags = $request->getETags()) { +$notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags); +} +if ($modifiedSince && $lastModified) { +$notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified); +} +if ($notModified) { +$this->setNotModified(); +} +return $notModified; +} +public function isInvalid() +{ +return $this->statusCode < 100 || $this->statusCode >= 600; +} +public function isInformational() +{ +return $this->statusCode >= 100 && $this->statusCode < 200; +} +public function isSuccessful() +{ +return $this->statusCode >= 200 && $this->statusCode < 300; +} +public function isRedirection() +{ +return $this->statusCode >= 300 && $this->statusCode < 400; +} +public function isClientError() +{ +return $this->statusCode >= 400 && $this->statusCode < 500; +} +public function isServerError() +{ +return $this->statusCode >= 500 && $this->statusCode < 600; +} +public function isOk() +{ +return 200 === $this->statusCode; +} +public function isForbidden() +{ +return 403 === $this->statusCode; +} +public function isNotFound() +{ +return 404 === $this->statusCode; +} +public function isRedirect($location = null) +{ +return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location')); +} +public function isEmpty() +{ +return in_array($this->statusCode, array(204, 304)); +} +public static function closeOutputBuffers($targetLevel, $flush) +{ +$status = ob_get_status(true); +$level = count($status); +$flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1; +while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) { +if ($flush) { +ob_end_flush(); +} else { +ob_end_clean(); +} +} +} +protected function ensureIEOverSSLCompatibility(Request $request) +{ +if (false !== stripos($this->headers->get('Content-Disposition'),'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) { +if ((int) preg_replace('/(MSIE )(.*?);/','$2', $match[0]) < 9) { +$this->headers->remove('Cache-Control'); +} +} +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class ResponseHeaderBag extends HeaderBag +{ +const COOKIES_FLAT ='flat'; +const COOKIES_ARRAY ='array'; +const DISPOSITION_ATTACHMENT ='attachment'; +const DISPOSITION_INLINE ='inline'; +protected $computedCacheControl = array(); +protected $cookies = array(); +protected $headerNames = array(); +public function __construct(array $headers = array()) +{ +parent::__construct($headers); +if (!isset($this->headers['cache-control'])) { +$this->set('Cache-Control',''); +} +} +public function __toString() +{ +$cookies =''; +foreach ($this->getCookies() as $cookie) { +$cookies .='Set-Cookie: '.$cookie."\r\n"; +} +ksort($this->headerNames); +return parent::__toString().$cookies; +} +public function allPreserveCase() +{ +return array_combine($this->headerNames, $this->headers); +} +public function replace(array $headers = array()) +{ +$this->headerNames = array(); +parent::replace($headers); +if (!isset($this->headers['cache-control'])) { +$this->set('Cache-Control',''); +} +} +public function set($key, $values, $replace = true) +{ +parent::set($key, $values, $replace); +$uniqueKey = str_replace('_','-', strtolower($key)); +$this->headerNames[$uniqueKey] = $key; +if (in_array($uniqueKey, array('cache-control','etag','last-modified','expires'))) { +$computed = $this->computeCacheControlValue(); +$this->headers['cache-control'] = array($computed); +$this->headerNames['cache-control'] ='Cache-Control'; +$this->computedCacheControl = $this->parseCacheControl($computed); +} +} +public function remove($key) +{ +parent::remove($key); +$uniqueKey = str_replace('_','-', strtolower($key)); +unset($this->headerNames[$uniqueKey]); +if ('cache-control'=== $uniqueKey) { +$this->computedCacheControl = array(); +} +} +public function hasCacheControlDirective($key) +{ +return array_key_exists($key, $this->computedCacheControl); +} +public function getCacheControlDirective($key) +{ +return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; +} +public function setCookie(Cookie $cookie) +{ +$this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; +} +public function removeCookie($name, $path ='/', $domain = null) +{ +if (null === $path) { +$path ='/'; +} +unset($this->cookies[$domain][$path][$name]); +if (empty($this->cookies[$domain][$path])) { +unset($this->cookies[$domain][$path]); +if (empty($this->cookies[$domain])) { +unset($this->cookies[$domain]); +} +} +} +public function getCookies($format = self::COOKIES_FLAT) +{ +if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) { +throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY)))); +} +if (self::COOKIES_ARRAY === $format) { +return $this->cookies; +} +$flattenedCookies = array(); +foreach ($this->cookies as $path) { +foreach ($path as $cookies) { +foreach ($cookies as $cookie) { +$flattenedCookies[] = $cookie; +} +} +} +return $flattenedCookies; +} +public function clearCookie($name, $path ='/', $domain = null, $secure = false, $httpOnly = true) +{ +$this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly)); +} +public function makeDisposition($disposition, $filename, $filenameFallback ='') +{ +if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) { +throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE)); +} +if (''== $filenameFallback) { +$filenameFallback = $filename; +} +if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) { +throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.'); +} +if (false !== strpos($filenameFallback,'%')) { +throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); +} +if (false !== strpos($filename,'/') || false !== strpos($filename,'\\') || false !== strpos($filenameFallback,'/') || false !== strpos($filenameFallback,'\\')) { +throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); +} +$output = sprintf('%s; filename="%s"', $disposition, str_replace('"','\\"', $filenameFallback)); +if ($filename !== $filenameFallback) { +$output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename)); +} +return $output; +} +protected function computeCacheControlValue() +{ +if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { +return'no-cache'; +} +if (!$this->cacheControl) { +return'private, must-revalidate'; +} +$header = $this->getCacheControlHeader(); +if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) { +return $header; +} +if (!isset($this->cacheControl['s-maxage'])) { +return $header.', private'; +} +return $header; +} +} +} +namespace Symfony\Component\DependencyInjection +{ +interface ContainerAwareInterface +{ +public function setContainer(ContainerInterface $container = null); +} +} +namespace Symfony\Component\DependencyInjection +{ +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +interface ContainerInterface +{ +const EXCEPTION_ON_INVALID_REFERENCE = 1; +const NULL_ON_INVALID_REFERENCE = 2; +const IGNORE_ON_INVALID_REFERENCE = 3; +const SCOPE_CONTAINER ='container'; +const SCOPE_PROTOTYPE ='prototype'; +public function set($id, $service, $scope = self::SCOPE_CONTAINER); +public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE); +public function has($id); +public function getParameter($name); +public function hasParameter($name); +public function setParameter($name, $value); +public function enterScope($name); +public function leaveScope($name); +public function addScope(ScopeInterface $scope); +public function hasScope($name); +public function isScopeActive($name); +} +} +namespace Symfony\Component\DependencyInjection +{ +interface IntrospectableContainerInterface extends ContainerInterface +{ +public function initialized($id); +} +} +namespace Symfony\Component\DependencyInjection +{ +use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +class Container implements IntrospectableContainerInterface +{ +protected $parameterBag; +protected $services = array(); +protected $methodMap = array(); +protected $aliases = array(); +protected $scopes = array(); +protected $scopeChildren = array(); +protected $scopedServices = array(); +protected $scopeStacks = array(); +protected $loading = array(); +private $underscoreMap = array('_'=>'','.'=>'_','\\'=>'_'); +public function __construct(ParameterBagInterface $parameterBag = null) +{ +$this->parameterBag = $parameterBag ?: new ParameterBag(); +} +public function compile() +{ +$this->parameterBag->resolve(); +$this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); +} +public function isFrozen() +{ +return $this->parameterBag instanceof FrozenParameterBag; +} +public function getParameterBag() +{ +return $this->parameterBag; +} +public function getParameter($name) +{ +return $this->parameterBag->get($name); +} +public function hasParameter($name) +{ +return $this->parameterBag->has($name); +} +public function setParameter($name, $value) +{ +$this->parameterBag->set($name, $value); +} +public function set($id, $service, $scope = self::SCOPE_CONTAINER) +{ +if (self::SCOPE_PROTOTYPE === $scope) { +throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id)); +} +$id = strtolower($id); +if ('service_container'=== $id) { +return; +} +if (self::SCOPE_CONTAINER !== $scope) { +if (!isset($this->scopedServices[$scope])) { +throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id)); +} +$this->scopedServices[$scope][$id] = $service; +} +if (isset($this->aliases[$id])) { +unset($this->aliases[$id]); +} +$this->services[$id] = $service; +if (method_exists($this, $method ='synchronize'.strtr($id, $this->underscoreMap).'Service')) { +$this->$method(); +} +if (null === $service) { +if (self::SCOPE_CONTAINER !== $scope) { +unset($this->scopedServices[$scope][$id]); +} +unset($this->services[$id]); +} +} +public function has($id) +{ +for ($i = 2;;) { +if ('service_container'=== $id +|| isset($this->aliases[$id]) +|| isset($this->services[$id]) +|| array_key_exists($id, $this->services) +) { +return true; +} +if (--$i && $id !== $lcId = strtolower($id)) { +$id = $lcId; +} else { +return method_exists($this,'get'.strtr($id, $this->underscoreMap).'Service'); +} +} +} +public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) +{ +for ($i = 2;;) { +if ('service_container'=== $id) { +return $this; +} +if (isset($this->aliases[$id])) { +$id = $this->aliases[$id]; +} +if (isset($this->services[$id]) || array_key_exists($id, $this->services)) { +return $this->services[$id]; +} +if (isset($this->loading[$id])) { +throw new ServiceCircularReferenceException($id, array_keys($this->loading)); +} +if (isset($this->methodMap[$id])) { +$method = $this->methodMap[$id]; +} elseif (--$i && $id !== $lcId = strtolower($id)) { +$id = $lcId; +continue; +} elseif (method_exists($this, $method ='get'.strtr($id, $this->underscoreMap).'Service')) { +} else { +if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { +if (!$id) { +throw new ServiceNotFoundException($id); +} +$alternatives = array(); +foreach ($this->services as $key => $associatedService) { +$lev = levenshtein($id, $key); +if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) { +$alternatives[] = $key; +} +} +throw new ServiceNotFoundException($id, null, null, $alternatives); +} +return; +} +$this->loading[$id] = true; +try { +$service = $this->$method(); +} catch (\Exception $e) { +unset($this->loading[$id]); +unset($this->services[$id]); +if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { +return; +} +throw $e; +} catch (\Throwable $e) { +unset($this->loading[$id]); +unset($this->services[$id]); +throw $e; +} +unset($this->loading[$id]); +return $service; +} +} +public function initialized($id) +{ +$id = strtolower($id); +if ('service_container'=== $id) { +return true; +} +if (isset($this->aliases[$id])) { +$id = $this->aliases[$id]; +} +return isset($this->services[$id]) || array_key_exists($id, $this->services); +} +public function getServiceIds() +{ +$ids = array(); +foreach (get_class_methods($this) as $method) { +if (preg_match('/^get(.+)Service$/', $method, $match)) { +$ids[] = self::underscore($match[1]); +} +} +$ids[] ='service_container'; +return array_unique(array_merge($ids, array_keys($this->services))); +} +public function enterScope($name) +{ +if (!isset($this->scopes[$name])) { +throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); +} +if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { +throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); +} +if (isset($this->scopedServices[$name])) { +$services = array($this->services, $name => $this->scopedServices[$name]); +unset($this->scopedServices[$name]); +foreach ($this->scopeChildren[$name] as $child) { +if (isset($this->scopedServices[$child])) { +$services[$child] = $this->scopedServices[$child]; +unset($this->scopedServices[$child]); +} +} +$this->services = call_user_func_array('array_diff_key', $services); +array_shift($services); +if (!isset($this->scopeStacks[$name])) { +$this->scopeStacks[$name] = new \SplStack(); +} +$this->scopeStacks[$name]->push($services); +} +$this->scopedServices[$name] = array(); +} +public function leaveScope($name) +{ +if (!isset($this->scopedServices[$name])) { +throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); +} +$services = array($this->services, $this->scopedServices[$name]); +unset($this->scopedServices[$name]); +foreach ($this->scopeChildren[$name] as $child) { +if (isset($this->scopedServices[$child])) { +$services[] = $this->scopedServices[$child]; +unset($this->scopedServices[$child]); +} +} +$this->services = call_user_func_array('array_diff_key', $services); +if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { +$services = $this->scopeStacks[$name]->pop(); +$this->scopedServices += $services; +if ($this->scopeStacks[$name]->isEmpty()) { +unset($this->scopeStacks[$name]); +} +foreach ($services as $array) { +foreach ($array as $id => $service) { +$this->set($id, $service, $name); +} +} +} +} +public function addScope(ScopeInterface $scope) +{ +$name = $scope->getName(); +$parentScope = $scope->getParentName(); +if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { +throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); +} +if (isset($this->scopes[$name])) { +throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); +} +if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { +throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); +} +$this->scopes[$name] = $parentScope; +$this->scopeChildren[$name] = array(); +while ($parentScope !== self::SCOPE_CONTAINER) { +$this->scopeChildren[$parentScope][] = $name; +$parentScope = $this->scopes[$parentScope]; +} +} +public function hasScope($name) +{ +return isset($this->scopes[$name]); +} +public function isScopeActive($name) +{ +return isset($this->scopedServices[$name]); +} +public static function camelize($id) +{ +return strtr(ucwords(strtr($id, array('_'=>' ','.'=>'_ ','\\'=>'_ '))), array(' '=>'')); +} +public static function underscore($id) +{ +return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/','/([a-z\d])([A-Z])/'), array('\\1_\\2','\\1_\\2'), str_replace('_','.', $id))); +} +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +interface HttpKernelInterface +{ +const MASTER_REQUEST = 1; +const SUB_REQUEST = 2; +public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\Config\Loader\LoaderInterface; +interface KernelInterface extends HttpKernelInterface, \Serializable +{ +public function registerBundles(); +public function registerContainerConfiguration(LoaderInterface $loader); +public function boot(); +public function shutdown(); +public function getBundles(); +public function isClassInActiveBundle($class); +public function getBundle($name, $first = true); +public function locateResource($name, $dir = null, $first = true); +public function getName(); +public function getEnvironment(); +public function isDebug(); +public function getRootDir(); +public function getContainer(); +public function getStartTime(); +public function getCacheDir(); +public function getLogDir(); +public function getCharset(); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +interface TerminableInterface +{ +public function terminate(Request $request, Response $response); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\HttpKernel\Config\EnvParametersResource; +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\ClassLoader\ClassCollectionLoader; +abstract class Kernel implements KernelInterface, TerminableInterface +{ +protected $bundles = array(); +protected $bundleMap; +protected $container; +protected $rootDir; +protected $environment; +protected $debug; +protected $booted = false; +protected $name; +protected $startTime; +protected $loadClassCache; +const VERSION ='2.7.14'; +const VERSION_ID = 20714; +const MAJOR_VERSION = 2; +const MINOR_VERSION = 7; +const RELEASE_VERSION = 14; +const EXTRA_VERSION =''; +const END_OF_MAINTENANCE ='05/2018'; +const END_OF_LIFE ='05/2019'; +public function __construct($environment, $debug) +{ +$this->environment = $environment; +$this->debug = (bool) $debug; +$this->rootDir = $this->getRootDir(); +$this->name = $this->getName(); +if ($this->debug) { +$this->startTime = microtime(true); +} +$defClass = new \ReflectionMethod($this,'init'); +$defClass = $defClass->getDeclaringClass()->name; +if (__CLASS__ !== $defClass) { +@trigger_error(sprintf('Calling the %s::init() method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', $defClass), E_USER_DEPRECATED); +$this->init(); +} +} +public function init() +{ +@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', E_USER_DEPRECATED); +} +public function __clone() +{ +if ($this->debug) { +$this->startTime = microtime(true); +} +$this->booted = false; +$this->container = null; +} +public function boot() +{ +if (true === $this->booted) { +return; +} +if ($this->loadClassCache) { +$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]); +} +$this->initializeBundles(); +$this->initializeContainer(); +foreach ($this->getBundles() as $bundle) { +$bundle->setContainer($this->container); +$bundle->boot(); +} +$this->booted = true; +} +public function terminate(Request $request, Response $response) +{ +if (false === $this->booted) { +return; +} +if ($this->getHttpKernel() instanceof TerminableInterface) { +$this->getHttpKernel()->terminate($request, $response); +} +} +public function shutdown() +{ +if (false === $this->booted) { +return; +} +$this->booted = false; +foreach ($this->getBundles() as $bundle) { +$bundle->shutdown(); +$bundle->setContainer(null); +} +$this->container = null; +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +if (false === $this->booted) { +$this->boot(); +} +return $this->getHttpKernel()->handle($request, $type, $catch); +} +protected function getHttpKernel() +{ +return $this->container->get('http_kernel'); +} +public function getBundles() +{ +return $this->bundles; +} +public function isClassInActiveBundle($class) +{ +@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in version 3.0.', E_USER_DEPRECATED); +foreach ($this->getBundles() as $bundle) { +if (0 === strpos($class, $bundle->getNamespace())) { +return true; +} +} +return false; +} +public function getBundle($name, $first = true) +{ +if (!isset($this->bundleMap[$name])) { +throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, get_class($this))); +} +if (true === $first) { +return $this->bundleMap[$name][0]; +} +return $this->bundleMap[$name]; +} +public function locateResource($name, $dir = null, $first = true) +{ +if ('@'!== $name[0]) { +throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); +} +if (false !== strpos($name,'..')) { +throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); +} +$bundleName = substr($name, 1); +$path =''; +if (false !== strpos($bundleName,'/')) { +list($bundleName, $path) = explode('/', $bundleName, 2); +} +$isResource = 0 === strpos($path,'Resources') && null !== $dir; +$overridePath = substr($path, 9); +$resourceBundle = null; +$bundles = $this->getBundle($bundleName, false); +$files = array(); +foreach ($bundles as $bundle) { +if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { +if (null !== $resourceBundle) { +throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', +$file, +$resourceBundle, +$dir.'/'.$bundles[0]->getName().$overridePath +)); +} +if ($first) { +return $file; +} +$files[] = $file; +} +if (file_exists($file = $bundle->getPath().'/'.$path)) { +if ($first && !$isResource) { +return $file; +} +$files[] = $file; +$resourceBundle = $bundle->getName(); +} +} +if (count($files) > 0) { +return $first && $isResource ? $files[0] : $files; +} +throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); +} +public function getName() +{ +if (null === $this->name) { +$this->name = preg_replace('/[^a-zA-Z0-9_]+/','', basename($this->rootDir)); +} +return $this->name; +} +public function getEnvironment() +{ +return $this->environment; +} +public function isDebug() +{ +return $this->debug; +} +public function getRootDir() +{ +if (null === $this->rootDir) { +$r = new \ReflectionObject($this); +$this->rootDir = dirname($r->getFileName()); +} +return $this->rootDir; +} +public function getContainer() +{ +return $this->container; +} +public function loadClassCache($name ='classes', $extension ='.php') +{ +$this->loadClassCache = array($name, $extension); +} +public function setClassCache(array $classes) +{ +file_put_contents($this->getCacheDir().'/classes.map', sprintf('debug ? $this->startTime : -INF; +} +public function getCacheDir() +{ +return $this->rootDir.'/cache/'.$this->environment; +} +public function getLogDir() +{ +return $this->rootDir.'/logs'; +} +public function getCharset() +{ +return'UTF-8'; +} +protected function doLoadClassCache($name, $extension) +{ +if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) { +ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); +} +} +protected function initializeBundles() +{ +$this->bundles = array(); +$topMostBundles = array(); +$directChildren = array(); +foreach ($this->registerBundles() as $bundle) { +$name = $bundle->getName(); +if (isset($this->bundles[$name])) { +throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); +} +$this->bundles[$name] = $bundle; +if ($parentName = $bundle->getParent()) { +if (isset($directChildren[$parentName])) { +throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); +} +if ($parentName == $name) { +throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); +} +$directChildren[$parentName] = $name; +} else { +$topMostBundles[$name] = $bundle; +} +} +if (!empty($directChildren) && count($diff = array_diff_key($directChildren, $this->bundles))) { +$diff = array_keys($diff); +throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); +} +$this->bundleMap = array(); +foreach ($topMostBundles as $name => $bundle) { +$bundleMap = array($bundle); +$hierarchy = array($name); +while (isset($directChildren[$name])) { +$name = $directChildren[$name]; +array_unshift($bundleMap, $this->bundles[$name]); +$hierarchy[] = $name; +} +foreach ($hierarchy as $bundle) { +$this->bundleMap[$bundle] = $bundleMap; +array_pop($bundleMap); +} +} +} +protected function getContainerClass() +{ +return $this->name.ucfirst($this->environment).($this->debug ?'Debug':'').'ProjectContainer'; +} +protected function getContainerBaseClass() +{ +return'Container'; +} +protected function initializeContainer() +{ +$class = $this->getContainerClass(); +$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); +$fresh = true; +if (!$cache->isFresh()) { +$container = $this->buildContainer(); +$container->compile(); +$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); +$fresh = false; +} +require_once $cache->getPath(); +$this->container = new $class(); +$this->container->set('kernel', $this); +if (!$fresh && $this->container->has('cache_warmer')) { +$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); +} +} +protected function getKernelParameters() +{ +$bundles = array(); +foreach ($this->bundles as $name => $bundle) { +$bundles[$name] = get_class($bundle); +} +return array_merge( +array('kernel.root_dir'=> realpath($this->rootDir) ?: $this->rootDir,'kernel.environment'=> $this->environment,'kernel.debug'=> $this->debug,'kernel.name'=> $this->name,'kernel.cache_dir'=> realpath($this->getCacheDir()) ?: $this->getCacheDir(),'kernel.logs_dir'=> realpath($this->getLogDir()) ?: $this->getLogDir(),'kernel.bundles'=> $bundles,'kernel.charset'=> $this->getCharset(),'kernel.container_class'=> $this->getContainerClass(), +), +$this->getEnvParameters() +); +} +protected function getEnvParameters() +{ +$parameters = array(); +foreach ($_SERVER as $key => $value) { +if (0 === strpos($key,'SYMFONY__')) { +$parameters[strtolower(str_replace('__','.', substr($key, 9)))] = $value; +} +} +return $parameters; +} +protected function buildContainer() +{ +foreach (array('cache'=> $this->getCacheDir(),'logs'=> $this->getLogDir()) as $name => $dir) { +if (!is_dir($dir)) { +if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { +throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); +} +} elseif (!is_writable($dir)) { +throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); +} +} +$container = $this->getContainerBuilder(); +$container->addObjectResource($this); +$this->prepareContainer($container); +if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { +$container->merge($cont); +} +$container->addCompilerPass(new AddClassesToCachePass($this)); +$container->addResource(new EnvParametersResource('SYMFONY__')); +return $container; +} +protected function prepareContainer(ContainerBuilder $container) +{ +$extensions = array(); +foreach ($this->bundles as $bundle) { +if ($extension = $bundle->getContainerExtension()) { +$container->registerExtension($extension); +$extensions[] = $extension->getAlias(); +} +if ($this->debug) { +$container->addObjectResource($bundle); +} +} +foreach ($this->bundles as $bundle) { +$bundle->build($container); +} +$container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); +} +protected function getContainerBuilder() +{ +$container = new ContainerBuilder(new ParameterBag($this->getKernelParameters())); +if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) { +$container->setProxyInstantiator(new RuntimeInstantiator()); +} +return $container; +} +protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) +{ +$dumper = new PhpDumper($container); +if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper')) { +$dumper->setProxyDumper(new ProxyDumper(md5($cache->getPath()))); +} +$content = $dumper->dump(array('class'=> $class,'base_class'=> $baseClass,'file'=> $cache->getPath(),'debug'=> $this->debug)); +$cache->write($content, $container->getResources()); +} +protected function getContainerLoader(ContainerInterface $container) +{ +$locator = new FileLocator($this); +$resolver = new LoaderResolver(array( +new XmlFileLoader($container, $locator), +new YamlFileLoader($container, $locator), +new IniFileLoader($container, $locator), +new PhpFileLoader($container, $locator), +new ClosureLoader($container), +)); +return new DelegatingLoader($resolver); +} +public static function stripComments($source) +{ +if (!function_exists('token_get_all')) { +return $source; +} +$rawChunk =''; +$output =''; +$tokens = token_get_all($source); +$ignoreSpace = false; +for ($i = 0; isset($tokens[$i]); ++$i) { +$token = $tokens[$i]; +if (!isset($token[1]) ||'b"'=== $token) { +$rawChunk .= $token; +} elseif (T_START_HEREDOC === $token[0]) { +$output .= $rawChunk.$token[1]; +do { +$token = $tokens[++$i]; +$output .= isset($token[1]) &&'b"'!== $token ? $token[1] : $token; +} while ($token[0] !== T_END_HEREDOC); +$rawChunk =''; +} elseif (T_WHITESPACE === $token[0]) { +if ($ignoreSpace) { +$ignoreSpace = false; +continue; +} +$rawChunk .= preg_replace(array('/\n{2,}/S'),"\n", $token[1]); +} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { +$ignoreSpace = true; +} else { +$rawChunk .= $token[1]; +if (T_OPEN_TAG === $token[0]) { +$ignoreSpace = true; +} +} +} +$output .= $rawChunk; +if (PHP_VERSION_ID >= 70000) { +unset($tokens, $rawChunk); +gc_mem_caches(); +} +return $output; +} +public function serialize() +{ +return serialize(array($this->environment, $this->debug)); +} +public function unserialize($data) +{ +list($environment, $debug) = unserialize($data); +$this->__construct($environment, $debug); +} +} +} +namespace Symfony\Component\ClassLoader +{ +class ApcClassLoader +{ +private $prefix; +protected $decorated; +public function __construct($prefix, $decorated) +{ +if (!function_exists('apcu_fetch')) { +throw new \RuntimeException('Unable to use ApcClassLoader as APC is not installed.'); +} +if (!method_exists($decorated,'findFile')) { +throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); +} +$this->prefix = $prefix; +$this->decorated = $decorated; +} +public function register($prepend = false) +{ +spl_autoload_register(array($this,'loadClass'), true, $prepend); +} +public function unregister() +{ +spl_autoload_unregister(array($this,'loadClass')); +} +public function loadClass($class) +{ +if ($file = $this->findFile($class)) { +require $file; +return true; +} +} +public function findFile($class) +{ +$file = apcu_fetch($this->prefix.$class, $success); +if (!$success) { +apcu_store($this->prefix.$class, $file = $this->decorated->findFile($class) ?: null); +} +return $file; +} +public function __call($method, $args) +{ +return call_user_func_array(array($this->decorated, $method), $args); +} +} +} +namespace Symfony\Component\HttpKernel\Bundle +{ +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +interface BundleInterface extends ContainerAwareInterface +{ +public function boot(); +public function shutdown(); +public function build(ContainerBuilder $container); +public function getContainerExtension(); +public function getParent(); +public function getName(); +public function getNamespace(); +public function getPath(); +} +} +namespace Symfony\Component\DependencyInjection +{ +abstract class ContainerAware implements ContainerAwareInterface +{ +protected $container; +public function setContainer(ContainerInterface $container = null) +{ +$this->container = $container; +} +} +} +namespace Symfony\Component\HttpKernel\Bundle +{ +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Console\Application; +use Symfony\Component\Finder\Finder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +abstract class Bundle extends ContainerAware implements BundleInterface +{ +protected $name; +protected $extension; +protected $path; +public function boot() +{ +} +public function shutdown() +{ +} +public function build(ContainerBuilder $container) +{ +} +public function getContainerExtension() +{ +if (null === $this->extension) { +$class = $this->getContainerExtensionClass(); +if (class_exists($class)) { +$extension = new $class(); +if (!$extension instanceof ExtensionInterface) { +throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', $class)); +} +$basename = preg_replace('/Bundle$/','', $this->getName()); +$expectedAlias = Container::underscore($basename); +if ($expectedAlias != $extension->getAlias()) { +throw new \LogicException(sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', +$expectedAlias, $extension->getAlias() +)); +} +$this->extension = $extension; +} else { +$this->extension = false; +} +} +if ($this->extension) { +return $this->extension; +} +} +public function getNamespace() +{ +$class = get_class($this); +return substr($class, 0, strrpos($class,'\\')); +} +public function getPath() +{ +if (null === $this->path) { +$reflected = new \ReflectionObject($this); +$this->path = dirname($reflected->getFileName()); +} +return $this->path; +} +public function getParent() +{ +} +final public function getName() +{ +if (null !== $this->name) { +return $this->name; +} +$name = get_class($this); +$pos = strrpos($name,'\\'); +return $this->name = false === $pos ? $name : substr($name, $pos + 1); +} +public function registerCommands(Application $application) +{ +if (!is_dir($dir = $this->getPath().'/Command')) { +return; +} +if (!class_exists('Symfony\Component\Finder\Finder')) { +throw new \RuntimeException('You need the symfony/finder component to register bundle commands.'); +} +$finder = new Finder(); +$finder->files()->name('*Command.php')->in($dir); +$prefix = $this->getNamespace().'\\Command'; +foreach ($finder as $file) { +$ns = $prefix; +if ($relativePath = $file->getRelativePath()) { +$ns .='\\'.str_replace('/','\\', $relativePath); +} +$class = $ns.'\\'.$file->getBasename('.php'); +if ($this->container) { +$alias ='console.command.'.strtolower(str_replace('\\','_', $class)); +if ($this->container->has($alias)) { +continue; +} +} +$r = new \ReflectionClass($class); +if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) { +$application->add($r->newInstance()); +} +} +} +protected function getContainerExtensionClass() +{ +$basename = preg_replace('/Bundle$/','', $this->getName()); +return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; +} +} +} +namespace Symfony\Component\Config +{ +use Symfony\Component\Config\Resource\ResourceInterface; +interface ConfigCacheInterface +{ +public function getPath(); +public function isFresh(); +public function write($content, array $metadata = null); +} +} +namespace Symfony\Component\Config +{ +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +class ConfigCache implements ConfigCacheInterface +{ +private $debug; +private $file; +public function __construct($file, $debug) +{ +$this->file = $file; +$this->debug = (bool) $debug; +} +public function __toString() +{ +@trigger_error('ConfigCache::__toString() is deprecated since version 2.7 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED); +return $this->file; +} +public function getPath() +{ +return $this->file; +} +public function isFresh() +{ +if (!is_file($this->file)) { +return false; +} +if (!$this->debug) { +return true; +} +$metadata = $this->getMetaFile(); +if (!is_file($metadata)) { +return false; +} +$time = filemtime($this->file); +$meta = unserialize(file_get_contents($metadata)); +foreach ($meta as $resource) { +if (!$resource->isFresh($time)) { +return false; +} +} +return true; +} +public function write($content, array $metadata = null) +{ +$mode = 0666; +$umask = umask(); +$filesystem = new Filesystem(); +$filesystem->dumpFile($this->file, $content, null); +try { +$filesystem->chmod($this->file, $mode, $umask); +} catch (IOException $e) { +} +if (null !== $metadata && true === $this->debug) { +$filesystem->dumpFile($this->getMetaFile(), serialize($metadata), null); +try { +$filesystem->chmod($this->getMetaFile(), $mode, $umask); +} catch (IOException $e) { +} +} +} +private function getMetaFile() +{ +return $this->file.'.meta'; +} +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +class HttpKernel implements HttpKernelInterface, TerminableInterface +{ +protected $dispatcher; +protected $resolver; +protected $requestStack; +public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null) +{ +$this->dispatcher = $dispatcher; +$this->resolver = $resolver; +$this->requestStack = $requestStack ?: new RequestStack(); +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +$request->headers->set('X-Php-Ob-Level', ob_get_level()); +try { +return $this->handleRaw($request, $type); +} catch (\Exception $e) { +if (false === $catch) { +$this->finishRequest($request, $type); +throw $e; +} +return $this->handleException($e, $request, $type); +} +} +public function terminate(Request $request, Response $response) +{ +$this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response)); +} +public function terminateWithException(\Exception $exception) +{ +if (!$request = $this->requestStack->getMasterRequest()) { +throw new \LogicException('Request stack is empty', 0, $exception); +} +$response = $this->handleException($exception, $request, self::MASTER_REQUEST); +$response->sendHeaders(); +$response->sendContent(); +$this->terminate($request, $response); +} +private function handleRaw(Request $request, $type = self::MASTER_REQUEST) +{ +$this->requestStack->push($request); +$event = new GetResponseEvent($this, $request, $type); +$this->dispatcher->dispatch(KernelEvents::REQUEST, $event); +if ($event->hasResponse()) { +return $this->filterResponse($event->getResponse(), $request, $type); +} +if (false === $controller = $this->resolver->getController($request)) { +throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); +} +$event = new FilterControllerEvent($this, $controller, $request, $type); +$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event); +$controller = $event->getController(); +$arguments = $this->resolver->getArguments($request, $controller); +$response = call_user_func_array($controller, $arguments); +if (!$response instanceof Response) { +$event = new GetResponseForControllerResultEvent($this, $request, $type, $response); +$this->dispatcher->dispatch(KernelEvents::VIEW, $event); +if ($event->hasResponse()) { +$response = $event->getResponse(); +} +if (!$response instanceof Response) { +$msg = sprintf('The controller must return a response (%s given).', $this->varToString($response)); +if (null === $response) { +$msg .=' Did you forget to add a return statement somewhere in your controller?'; +} +throw new \LogicException($msg); +} +} +return $this->filterResponse($response, $request, $type); +} +private function filterResponse(Response $response, Request $request, $type) +{ +$event = new FilterResponseEvent($this, $request, $type, $response); +$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event); +$this->finishRequest($request, $type); +return $event->getResponse(); +} +private function finishRequest(Request $request, $type) +{ +$this->dispatcher->dispatch(KernelEvents::FINISH_REQUEST, new FinishRequestEvent($this, $request, $type)); +$this->requestStack->pop(); +} +private function handleException(\Exception $e, $request, $type) +{ +$event = new GetResponseForExceptionEvent($this, $request, $type, $e); +$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event); +$e = $event->getException(); +if (!$event->hasResponse()) { +$this->finishRequest($request, $type); +throw $e; +} +$response = $event->getResponse(); +if ($response->headers->has('X-Status-Code')) { +$response->setStatusCode($response->headers->get('X-Status-Code')); +$response->headers->remove('X-Status-Code'); +} elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) { +if ($e instanceof HttpExceptionInterface) { +$response->setStatusCode($e->getStatusCode()); +$response->headers->add($e->getHeaders()); +} else { +$response->setStatusCode(500); +} +} +try { +return $this->filterResponse($response, $request, $type); +} catch (\Exception $e) { +return $response; +} +} +private function varToString($var) +{ +if (is_object($var)) { +return sprintf('Object(%s)', get_class($var)); +} +if (is_array($var)) { +$a = array(); +foreach ($var as $k => $v) { +$a[] = sprintf('%s => %s', $k, $this->varToString($v)); +} +return sprintf('Array(%s)', implode(', ', $a)); +} +if (is_resource($var)) { +return sprintf('Resource(%s)', get_resource_type($var)); +} +if (null === $var) { +return'null'; +} +if (false === $var) { +return'false'; +} +if (true === $var) { +return'true'; +} +return (string) $var; +} +} +} +namespace Symfony\Component\HttpKernel\DependencyInjection +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Scope; +class ContainerAwareHttpKernel extends HttpKernel +{ +protected $container; +public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, $triggerDeprecation = true) +{ +parent::__construct($dispatcher, $controllerResolver, $requestStack); +if ($triggerDeprecation) { +@trigger_error('The '.__CLASS__.' class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpKernel class instead.', E_USER_DEPRECATED); +} +$this->container = $container; +if (!$container->hasScope('request')) { +$container->addScope(new Scope('request')); +} +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +$this->container->enterScope('request'); +$this->container->set('request', $request,'request'); +try { +$response = parent::handle($request, $type, $catch); +} catch (\Exception $e) { +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +throw $e; +} catch (\Throwable $e) { +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +throw $e; +} +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +return $response; +} +} +} + +namespace { return $loader; } diff --git a/exercises/legacy_create_video/base/php-symfony/app/check.php b/exercises/legacy_create_video/base/php-symfony/app/check.php new file mode 100644 index 00000000..cf1e6b06 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/check.php @@ -0,0 +1,142 @@ +getPhpIniConfigPath(); + +echo_title('Symfony Requirements Checker'); + +echo '> PHP is using the following php.ini file:'.PHP_EOL; +if ($iniPath) { + echo_style('green', ' '.$iniPath); +} else { + echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!'); +} + +echo PHP_EOL.PHP_EOL; + +echo '> Checking Symfony requirements:'.PHP_EOL.' '; + +$messages = array(); +foreach ($symfonyRequirements->getRequirements() as $req) { + /** @var $req Requirement */ + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('red', 'E'); + $messages['error'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +$checkPassed = empty($messages['error']); + +foreach ($symfonyRequirements->getRecommendations() as $req) { + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('yellow', 'W'); + $messages['warning'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +if ($checkPassed) { + echo_block('success', 'OK', 'Your system is ready to run Symfony projects'); +} else { + echo_block('error', 'ERROR', 'Your system is not ready to run Symfony projects'); + + echo_title('Fix the following mandatory requirements', 'red'); + + foreach ($messages['error'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +if (!empty($messages['warning'])) { + echo_title('Optional recommendations to improve your setup', 'yellow'); + + foreach ($messages['warning'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +echo PHP_EOL; +echo_style('title', 'Note'); +echo ' The command console could use a different php.ini file'.PHP_EOL; +echo_style('title', '~~~~'); +echo ' than the one used with your web server. To be on the'.PHP_EOL; +echo ' safe side, please check the requirements from your web'.PHP_EOL; +echo ' server using the '; +echo_style('yellow', 'web/config.php'); +echo ' script.'.PHP_EOL; +echo PHP_EOL; + +exit($checkPassed ? 0 : 1); + +function get_error_message(Requirement $requirement, $lineSize) +{ + if ($requirement->isFulfilled()) { + return; + } + + $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; + $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; + + return $errorMessage; +} + +function echo_title($title, $style = null) +{ + $style = $style ?: 'title'; + + echo PHP_EOL; + echo_style($style, $title.PHP_EOL); + echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); + echo PHP_EOL; +} + +function echo_style($style, $message) +{ + // ANSI color codes + $styles = array( + 'reset' => "\033[0m", + 'red' => "\033[31m", + 'green' => "\033[32m", + 'yellow' => "\033[33m", + 'error' => "\033[37;41m", + 'success' => "\033[37;42m", + 'title' => "\033[34m", + ); + $supports = has_color_support(); + + echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); +} + +function echo_block($style, $title, $message) +{ + $message = ' '.trim($message).' '; + $width = strlen($message); + + echo PHP_EOL.PHP_EOL; + + echo_style($style, str_repeat(' ', $width).PHP_EOL); + echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_repeat(' ', $width).PHP_EOL); +} + +function has_color_support() +{ + static $support; + + if (null === $support) { + if (DIRECTORY_SEPARATOR == '\\') { + $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); + } else { + $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); + } + } + + return $support; +} diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/config.yml b/exercises/legacy_create_video/base/php-symfony/app/config/config.yml new file mode 100644 index 00000000..fc35384c --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/config.yml @@ -0,0 +1,110 @@ +imports: + - { resource: parameters.yml } + - { resource: security.yml } + +framework: + #esi: ~ + translator: { fallback: %locale% } + secret: %secret% + router: + resource: "%kernel.root_dir%/config/routing.yml" + strict_requirements: %kernel.debug% + form: + csrf_protection: false + validation: { enable_annotations: true } + templating: + engines: ['twig'] + #assets_version: SomeVersionScheme + default_locale: "%locale%" + trusted_proxies: ~ + session: false + fragments: ~ + +# Twig Configuration +twig: + debug: %kernel.debug% + strict_variables: %kernel.debug% + exception_controller: 'FOS\RestBundle\Controller\ExceptionController::showAction' + +# Assetic Configuration +assetic: + debug: %kernel.debug% + use_controller: false + bundles: [ ] + #java: /usr/bin/java + filters: + cssrewrite: ~ + #closure: + # jar: %kernel.root_dir%/Resources/java/compiler.jar + #yui_css: + # jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar + +# Doctrine Configuration +doctrine: + dbal: + driver: %database_driver% + host: %database_host% + port: %database_port% + dbname: %database_name% + user: %database_user% + password: %database_password% + charset: UTF8 + # if using pdo_sqlite as your database driver, add the path in parameters.yml + # e.g. database_path: %kernel.root_dir%/data/data.db3 + # path: %database_path% + + orm: + auto_generate_proxy_classes: %kernel.debug% + auto_mapping: true + +# Swiftmailer Configuration +swiftmailer: + transport: %mailer_transport% + host: %mailer_host% + username: %mailer_user% + password: %mailer_password% + spool: { type: memory } + +fos_rest: + disable_csrf_role: ROLE_API + param_fetcher_listener: true + view: + mime_types: + json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1', 'application/json;version=1.2'] + view_response_listener: 'force' + formats: + xml: true + json: true + templating_formats: + html: true + format_listener: + rules: + - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } + versioning: + enabled: true + resolvers: + media_type: + enabled: true + exception: + codes: + 'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404 + 'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT + messages: + 'Symfony\Component\Routing\Exception\ResourceNotFoundException': true + allowed_methods_listener: true + access_denied_listener: + json: true + body_listener: true + +fos_http_cache: + cache_control: + rules: + # the controls section values are used in a call to Response::setCache(); + - + match: + path: ^/notes + methods: [GET, HEAD] + headers: + cache_control: { public: true, max_age: 15, s_maxage: 30 } + last_modified: "-1 hour" + vary: [Accept-Encoding, Accept-Language] diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/config_dev.yml b/exercises/legacy_create_video/base/php-symfony/app/config/config_dev.yml new file mode 100644 index 00000000..c6da9ca9 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/config_dev.yml @@ -0,0 +1,29 @@ +imports: + - { resource: config.yml } + +framework: + router: { resource: "%kernel.root_dir%/config/routing_dev.yml" } + profiler: { only_exceptions: false } + +web_profiler: + toolbar: true + intercept_redirects: false + +monolog: + handlers: + main: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug + firephp: + type: firephp + level: info + chromephp: + type: chromephp + level: info + +assetic: + use_controller: true + +#swiftmailer: +# delivery_address: me@example.com diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/config_prod.yml b/exercises/legacy_create_video/base/php-symfony/app/config/config_prod.yml new file mode 100644 index 00000000..e268dd06 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/config_prod.yml @@ -0,0 +1,29 @@ +imports: + - { resource: config.yml } + +# In production environment you should know that the parameters for URL generation +# always pass the requirements. Otherwise it would break your link (or even site with +# strict_requirements = true). So we can disable the requirements check completely for +# enhanced performance with strict_requirements = null. +framework: + router: + strict_requirements: null + #validation: + # cache: apc + +#doctrine: +# orm: +# metadata_cache_driver: apc +# result_cache_driver: apc +# query_cache_driver: apc + +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/config_test.yml b/exercises/legacy_create_video/base/php-symfony/app/config/config_test.yml new file mode 100644 index 00000000..a27c240f --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/config_test.yml @@ -0,0 +1,16 @@ +imports: + - { resource: config_dev.yml } + +framework: + test: ~ + session: + storage_id: session.storage.mock_file + profiler: + enabled: false + +web_profiler: + toolbar: false + intercept_redirects: false + +swiftmailer: + disable_delivery: true diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/parameters.yml.dist b/exercises/legacy_create_video/base/php-symfony/app/config/parameters.yml.dist new file mode 100644 index 00000000..8b317c27 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/parameters.yml.dist @@ -0,0 +1,15 @@ +parameters: + database_driver: pdo_mysql + database_host: 127.0.0.1 + database_port: ~ + database_name: symfony + database_user: root + database_password: ~ + + mailer_transport: smtp + mailer_host: 127.0.0.1 + mailer_user: ~ + mailer_password: ~ + + locale: en + secret: ThisTokenIsNotSoSecretChangeIt diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/routing.yml b/exercises/legacy_create_video/base/php-symfony/app/config/routing.yml new file mode 100644 index 00000000..bb563d33 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/routing.yml @@ -0,0 +1,3 @@ +NelmioApiDocBundle: + resource: "@NelmioApiDocBundle/Resources/config/routing.yml" + prefix: /api/doc diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/routing_dev.yml b/exercises/legacy_create_video/base/php-symfony/app/config/routing_dev.yml new file mode 100644 index 00000000..4b331385 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/routing_dev.yml @@ -0,0 +1,29 @@ +_welcome: + pattern: / + defaults: + _controller: FrameworkBundle:Redirect:redirect + route: get_notes + permanent: true # this for 301 + +_demo_note: + resource: "@AppBundle/Controller/NoteController.php" + type: rest + +_demo_video: + resource: "@AppBundle/Controller/VideoController.php" + type: rest + +_wdt: + resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" + prefix: /_wdt + +_profiler: + resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" + prefix: /_profiler + +_configurator: + resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" + prefix: /_configurator + +_main: + resource: routing.yml diff --git a/exercises/legacy_create_video/base/php-symfony/app/config/security.yml b/exercises/legacy_create_video/base/php-symfony/app/config/security.yml new file mode 100644 index 00000000..43c6c84c --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/config/security.yml @@ -0,0 +1,26 @@ +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + role_hierarchy: + ROLE_ADMIN: ROLE_USER + ROLE_API: ROLE_USER + ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + + providers: + in_memory: + memory: + users: + restapi: { password: secretpw, roles: [ 'ROLE_API' ] } + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + main: + pattern: ^/ + anonymous: ~ + stateless: true + http_basic: + realm: "Demo REST API (username: restapi, password: secretpw)" diff --git a/exercises/legacy_create_video/base/php-symfony/app/console b/exercises/legacy_create_video/base/php-symfony/app/console new file mode 100755 index 00000000..129c8104 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/console @@ -0,0 +1,22 @@ +#!/usr/bin/env php +getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); +$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; + +$kernel = new AppKernel($env, $debug); +$application = new Application($kernel); +$application->run($input); diff --git a/exercises/legacy_create_video/base/php-symfony/app/phpunit.xml.dist b/exercises/legacy_create_video/base/php-symfony/app/phpunit.xml.dist new file mode 100644 index 00000000..e11a5b77 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/app/phpunit.xml.dist @@ -0,0 +1,37 @@ + + + + + + + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Tests + ../src/*Bundle/Tests + + + + + + + + ../src + + ../src/*Bundle/Resources + ../src/*Bundle/Tests + ../src/*/*Bundle/Resources + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Resources + ../src/*/Bundle/*Bundle/Tests + + + + \ No newline at end of file diff --git a/exercises/legacy_create_video/base/php-symfony/composer.json b/exercises/legacy_create_video/base/php-symfony/composer.json new file mode 100644 index 00000000..8efdfca4 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/composer.json @@ -0,0 +1,65 @@ +{ + "name": "gimler/symfony-rest-edition", + "license": "MIT", + "type": "project", + "description": "The \"Symfony REST Edition\" distribution", + "autoload": { + "psr-4": { "": "src/" } + }, + "require": { + "php": ">=5.4.0", + "symfony/symfony": "2.7.*", + "doctrine/orm": "^2.4.8", + "doctrine/doctrine-bundle": "~1.4", + "symfony/assetic-bundle": "~2.3", + "symfony/swiftmailer-bundle": "~2.3", + "symfony/monolog-bundle": "~2.4", + "sensio/distribution-bundle": "~4.0", + "sensio/framework-extra-bundle": "^3.0.2", + "incenteev/composer-parameter-handler": "~2.0", + "jms/serializer-bundle": "^1.0", + "friendsofsymfony/rest-bundle": "~2.0", + "nelmio/api-doc-bundle": "^2.4", + "friendsofsymfony/http-cache-bundle": "^1.0", + "willdurand/hateoas-bundle": "^1.0", + "hautelook/templated-uri-bundle": "^2.0", + "willdurand/rest-extra-bundle": "^1.0" + }, + "require-dev": { + "sensio/generator-bundle": "~2.3", + "phpunit/phpunit": "^5.6", + "mockery/mockery": "^0.9.5" + }, + "scripts": { + "post-install-cmd": [ + "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget" + ], + "post-update-cmd": [ + "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget" + ] + }, + "config": { + "bin-dir": "bin" + }, + "extra": { + "symfony-app-dir": "app", + "symfony-web-dir": "web", + "symfony-assets-install": "relative", + "incenteev-parameters": { + "file": "app/config/parameters.yml" + }, + "branch-alias": { + "dev-master": "2.7-dev" + } + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/composer.lock b/exercises/legacy_create_video/base/php-symfony/composer.lock new file mode 100644 index 00000000..246557be --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/composer.lock @@ -0,0 +1,4359 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "f968738081a9b5fc369b59e2bdbc4e47", + "content-hash": "aad2c2568d109345ec88ec986d9fbaa5", + "packages": [ + { + "name": "doctrine/annotations", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Annotations\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2015-08-31 12:32:49" + }, + { + "name": "doctrine/cache", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2015-12-31 16:37:02" + }, + { + "name": "doctrine/collections", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2015-04-14 22:21:58" + }, + { + "name": "doctrine/common", + "version": "v2.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "a579557bc689580c19fee4e27487a67fe60defc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0", + "reference": "a579557bc689580c19fee4e27487a67fe60defc0", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.5|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2015-12-25 13:18:31" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769", + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.7-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2016-01-05 22:11:12" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "1.6.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "fd51907c6c76acaa8a5234822a4f901c1500afc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/fd51907c6c76acaa8a5234822a4f901c1500afc1", + "reference": "fd51907c6c76acaa8a5234822a4f901c1500afc1", + "shasum": "" + }, + "require": { + "doctrine/dbal": "~2.3", + "doctrine/doctrine-cache-bundle": "~1.0", + "jdorn/sql-formatter": "~1.1", + "php": ">=5.3.2", + "symfony/console": "~2.3|~3.0", + "symfony/doctrine-bridge": "~2.2|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "doctrine/orm": "~2.3", + "phpunit/phpunit": "~4", + "satooshi/php-coveralls": "~0.6.1", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/property-info": "~2.8|~3.0", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0", + "twig/twig": "~1.10" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "orm", + "persistence" + ], + "time": "2016-04-21 19:55:56" + }, + { + "name": "doctrine/doctrine-cache-bundle", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineCacheBundle.git", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.4.2", + "doctrine/inflector": "~1.0", + "php": ">=5.3.2", + "symfony/doctrine-bridge": "~2.2|~3.0" + }, + "require-dev": { + "instaclick/coding-standard": "~1.1", + "instaclick/object-calisthenics-sniffs": "dev-master", + "instaclick/symfony2-coding-standard": "dev-remaster", + "phpunit/phpunit": "~4", + "predis/predis": "~0.8", + "satooshi/php-coveralls": "~0.6.1", + "squizlabs/php_codesniffer": "~1.5", + "symfony/console": "~2.2|~3.0", + "symfony/finder": "~2.2|~3.0", + "symfony/framework-bundle": "~2.2|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/security-acl": "~2.3|~3.0", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0" + }, + "suggest": { + "symfony/security-acl": "For using this bundle to cache ACLs" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Fabio B. Silva", + "email": "fabio.bat.silva@gmail.com" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@hotmail.com" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Bundle for Doctrine Cache", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-01-26 17:28:51" + }, + { + "name": "doctrine/inflector", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2015-11-06 14:35:42" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, + { + "name": "doctrine/orm", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/doctrine2.git", + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bc4ddbfb0114cb33438cc811c9a740d8aa304aab", + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab", + "shasum": "" + }, + "require": { + "doctrine/cache": "~1.4", + "doctrine/collections": "~1.2", + "doctrine/common": ">=2.5-dev,<2.7-dev", + "doctrine/dbal": ">=2.5-dev,<2.6-dev", + "doctrine/instantiator": "~1.0.1", + "ext-pdo": "*", + "php": ">=5.4", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "symfony/yaml": "~2.3|~3.0" + }, + "suggest": { + "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + }, + "bin": [ + "bin/doctrine", + "bin/doctrine.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\ORM\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "orm" + ], + "time": "2016-01-05 21:34:58" + }, + { + "name": "friendsofsymfony/http-cache", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCache.git", + "reference": "783f3918d85263e444db02a9e42d0f42aa7c1f43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCache/zipball/783f3918d85263e444db02a9e42d0f42aa7c1f43", + "reference": "783f3918d85263e444db02a9e42d0f42aa7c1f43", + "shasum": "" + }, + "require": { + "guzzle/guzzle": "~3.8", + "php": ">=5.3.3", + "symfony/event-dispatcher": "^2.3||^3.0", + "symfony/options-resolver": "^2.3||^3.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.1", + "monolog/monolog": "~1.0", + "symfony/http-kernel": "^2.3||^3.0", + "symfony/process": "^2.3||^3.0" + }, + "suggest": { + "monolog/monolog": "For logging issues while invalidating" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\HttpCache\\": "src/", + "FOS\\HttpCache\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache/contributors" + } + ], + "description": "Tools to manage cache invalidation", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache", + "keywords": [ + "caching", + "http", + "invalidation", + "nginx", + "purge", + "varnish" + ], + "time": "2016-02-02 12:07:34" + }, + { + "name": "friendsofsymfony/http-cache-bundle", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle.git", + "reference": "f12b74b422e46c65daae8b3363bcf555f6957eea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCacheBundle/zipball/f12b74b422e46c65daae8b3363bcf555f6957eea", + "reference": "f12b74b422e46c65daae8b3363bcf555f6957eea", + "shasum": "" + }, + "require": { + "friendsofsymfony/http-cache": "~1.4", + "php": ">=5.3.3", + "symfony/framework-bundle": "^2.3||^3.0" + }, + "conflict": { + "twig/twig": "<1.12.0" + }, + "require-dev": { + "matthiasnoback/symfony-dependency-injection-test": "^0.7.4", + "mockery/mockery": "0.9.*", + "monolog/monolog": "*", + "polishsymfonycommunity/symfony-mocker-container": "^1.0", + "sensio/framework-extra-bundle": "^2.3||^3.0", + "symfony/expression-language": "^2.4||^3.0", + "symfony/monolog-bundle": "^2.3||^3.0", + "symfony/phpunit-bridge": "^2.7||^3.0", + "symfony/symfony": "^2.3||^3.0" + }, + "suggest": { + "sensio/framework-extra-bundle": "For Tagged Cache Invalidation", + "symfony/console": "To send invalidation requests from the command line", + "symfony/expression-language": "For Tagged Cache Invalidation" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\HttpCacheBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCacheBundle/contributors" + } + ], + "description": "Set path based HTTP cache headers and send invalidation requests to your HTTP cache", + "homepage": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle", + "keywords": [ + "caching", + "esi", + "http", + "invalidation", + "purge", + "varnish" + ], + "time": "2016-02-24 21:36:18" + }, + { + "name": "friendsofsymfony/rest-bundle", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git", + "reference": "8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1", + "reference": "8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^1.0", + "php": "^5.5.9|~7.0", + "psr/log": "^1.0", + "symfony/finder": "^2.7|^3.0", + "symfony/framework-bundle": "^2.7|^3.0", + "symfony/routing": "^2.7|^3.0", + "willdurand/jsonp-callback-validator": "^1.0", + "willdurand/negotiation": "^2.0" + }, + "conflict": { + "sensio/framework-extra-bundle": "<3.0.13" + }, + "require-dev": { + "jms/serializer-bundle": "^1.0", + "phpoption/phpoption": "^1.1", + "sensio/framework-extra-bundle": "^3.0.13", + "sllh/php-cs-fixer-styleci-bridge": "^1.3", + "symfony/browser-kit": "^2.7|^3.0", + "symfony/css-selector": "^2.7|^3.0", + "symfony/dependency-injection": "^2.7|^3.0", + "symfony/expression-language": "~2.7|^3.0", + "symfony/form": "^2.7|^3.0", + "symfony/phpunit-bridge": "~2.7|^3.0", + "symfony/security-bundle": "^2.7|^3.0", + "symfony/serializer": "^2.7.11|^3.0.4", + "symfony/twig-bundle": "^2.7|^3.0", + "symfony/validator": "^2.7|^3.0", + "symfony/web-profiler-bundle": "^2.7|^3.0", + "symfony/yaml": "^2.7|^3.0" + }, + "suggest": { + "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended, requires ^1.0", + "sensio/framework-extra-bundle": "Add support for route annotations and the view response listener, requires ^3.0", + "symfony/expression-language": "Add support for using the expression language in the routing, requires ^2.7|^3.0", + "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ^2.7|^3.0", + "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ^2.7|^3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\RestBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukas Kahwe Smith", + "email": "smith@pooteeweet.org" + }, + { + "name": "FriendsOfSymfony Community", + "homepage": "https://github.com/friendsofsymfony/FOSRestBundle/contributors" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com" + } + ], + "description": "This Bundle provides various tools to rapidly develop RESTful API's with Symfony", + "homepage": "http://friendsofsymfony.github.com", + "keywords": [ + "rest" + ], + "time": "2016-06-21 08:45:19" + }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle", + "time": "2015-03-18 18:23:50" + }, + { + "name": "hautelook/templated-uri-bundle", + "version": "2.0.0", + "target-dir": "Hautelook/TemplatedUriBundle", + "source": { + "type": "git", + "url": "https://github.com/hautelook/TemplatedUriBundle.git", + "reference": "d5d32ca1c9f13ca170023fd7cb4f1c969d3fd1ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hautelook/TemplatedUriBundle/zipball/d5d32ca1c9f13ca170023fd7cb4f1c969d3fd1ad", + "reference": "d5d32ca1c9f13ca170023fd7cb4f1c969d3fd1ad", + "shasum": "" + }, + "require": { + "hautelook/templated-uri-router": "~2.0", + "php": ">=5.3.0", + "symfony/framework-bundle": "~2.1" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-0": { + "Hautelook\\TemplatedUriBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Baldur Rensch", + "email": "brensch@gmail.com" + } + ], + "description": "Symfony2 Bundle that provides a RFC-6570 compatible router and URL Generator.", + "homepage": "http://www.hautelooktech.com/", + "keywords": [ + "HATEOAS", + "RFC 6570", + "Symfony2", + "json", + "uri", + "url", + "xml" + ], + "time": "2014-07-28 21:56:22" + }, + { + "name": "hautelook/templated-uri-router", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/hautelook/TemplatedUriRouter.git", + "reference": "85479142467aa0ea230ab1aa54d2a1d050104802" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hautelook/TemplatedUriRouter/zipball/85479142467aa0ea230ab1aa54d2a1d050104802", + "reference": "85479142467aa0ea230ab1aa54d2a1d050104802", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/routing": "~2.5|~3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hautelook\\TemplatedUriRouter\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Baldur Rensch", + "email": "brensch@gmail.com" + } + ], + "description": "Symfony2 RFC-6570 compatible router and URL Generator", + "homepage": "http://www.hautelooktech.com/", + "keywords": [ + "HATEOAS", + "RFC 6570", + "Symfony2", + "json", + "router", + "uri", + "url", + "xml" + ], + "time": "2015-12-17 01:40:38" + }, + { + "name": "incenteev/composer-parameter-handler", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/Incenteev/ParameterHandler.git", + "reference": "d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Incenteev/ParameterHandler/zipball/d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc", + "reference": "d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/yaml": "~2.3|~3.0" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpspec/prophecy-phpunit": "~1.0", + "symfony/filesystem": "~2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Incenteev\\ParameterHandler\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + } + ], + "description": "Composer script handling your ignored parameter file", + "homepage": "https://github.com/Incenteev/ParameterHandler", + "keywords": [ + "parameters management" + ], + "time": "2015-11-10 17:04:01" + }, + { + "name": "jdorn/sql-formatter", + "version": "v1.2.17", + "source": { + "type": "git", + "url": "https://github.com/jdorn/sql-formatter.git", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "lib" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "http://jeremydorn.com/" + } + ], + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/jdorn/sql-formatter/", + "keywords": [ + "highlight", + "sql" + ], + "time": "2014-01-12 16:20:24" + }, + { + "name": "jms/metadata", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata.git", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/22b72455559a25777cfd28c4ffda81ff7639f353", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "doctrine/cache": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Metadata\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Class/method/property metadata management in PHP", + "keywords": [ + "annotations", + "metadata", + "xml", + "yaml" + ], + "time": "2014-07-12 07:13:19" + }, + { + "name": "jms/parser-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/parser-lib.git", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/parser-lib/zipball/c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "shasum": "" + }, + "require": { + "phpoption/phpoption": ">=0.9,<2.0-dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "description": "A library for easily creating recursive-descent parsers.", + "time": "2012-11-18 18:08:43" + }, + { + "name": "jms/serializer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/serializer.git", + "reference": "fe13a1f993ea3456e195b7820692f2eb2b6bbb48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/fe13a1f993ea3456e195b7820692f2eb2b6bbb48", + "reference": "fe13a1f993ea3456e195b7820692f2eb2b6bbb48", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/instantiator": "~1.0.3", + "jms/metadata": "~1.1", + "jms/parser-lib": "1.*", + "php": ">=5.4.0", + "phpcollection/phpcollection": "~0.1" + }, + "conflict": { + "twig/twig": "<1.12" + }, + "require-dev": { + "doctrine/orm": "~2.1", + "doctrine/phpcr-odm": "~1.0.1", + "jackalope/jackalope-doctrine-dbal": "1.0.*", + "phpunit/phpunit": "~4.0", + "propel/propel1": "~1.7", + "symfony/filesystem": "2.*", + "symfony/form": "~2.1", + "symfony/translation": "~2.0", + "symfony/validator": "~2.0", + "symfony/yaml": "2.*", + "twig/twig": "~1.12|~2.0" + }, + "suggest": { + "symfony/yaml": "Required if you'd like to serialize data to YAML format." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\Serializer": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", + "homepage": "http://jmsyst.com/libs/serializer", + "keywords": [ + "deserialization", + "jaxb", + "json", + "serialization", + "xml" + ], + "time": "2015-10-27 09:24:41" + }, + { + "name": "jms/serializer-bundle", + "version": "1.1.0", + "target-dir": "JMS/SerializerBundle", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/JMSSerializerBundle.git", + "reference": "3e396c980545350c2efb65a50041d2a9f9d6562e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/3e396c980545350c2efb65a50041d2a9f9d6562e", + "reference": "3e396c980545350c2efb65a50041d2a9f9d6562e", + "shasum": "" + }, + "require": { + "jms/serializer": "^1.0.0", + "php": ">=5.4.0", + "phpoption/phpoption": "^1.1.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "doctrine/doctrine-bundle": "*", + "doctrine/orm": "*", + "symfony/browser-kit": "*", + "symfony/class-loader": "*", + "symfony/css-selector": "*", + "symfony/finder": "*", + "symfony/form": "*", + "symfony/process": "*", + "symfony/stopwatch": "*", + "symfony/twig-bundle": "*", + "symfony/validator": "*", + "symfony/yaml": "*" + }, + "suggest": { + "jms/di-extra-bundle": "Required to get lazy loading (de)serialization visitors, ~1.3" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\SerializerBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Allows you to easily serialize, and deserialize data of any complexity", + "homepage": "http://jmsyst.com/bundles/JMSSerializerBundle", + "keywords": [ + "deserialization", + "jaxb", + "json", + "serialization", + "xml" + ], + "time": "2015-11-10 12:26:42" + }, + { + "name": "kriswallsmith/assetic", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/kriswallsmith/assetic.git", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/9928f7c4ad98b234e3559d1049abd13387f86db5", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/process": "~2.1|~3.0" + }, + "conflict": { + "twig/twig": "<1.23" + }, + "require-dev": { + "cssmin/cssmin": "3.0.1", + "joliclic/javascript-packer": "1.1", + "kamicane/packager": "1.0", + "leafo/lessphp": "^0.3.7", + "leafo/scssphp": "~0.1", + "mrclay/minify": "~2.2", + "patchwork/jsqueeze": "~1.0|~2.0", + "phpunit/phpunit": "~4.8", + "psr/log": "~1.0", + "ptachoire/cssembed": "~1.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "twig/twig": "~1.8|~2.0" + }, + "suggest": { + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", + "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", + "twig/twig": "Assetic provides the integration with the Twig templating engine" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-0": { + "Assetic": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ], + "time": "2015-11-12 13:51:40" + }, + { + "name": "michelf/php-markdown", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "156e56ee036505ec637d761ee62dc425d807183c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", + "reference": "156e56ee036505ec637d761ee62dc425d807183c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-lib": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2015-12-24 01:37:31" + }, + { + "name": "monolog/monolog", + "version": "1.19.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "raven/raven": "Allow sending log messages to a Sentry server", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2016-04-12 18:29:35" + }, + { + "name": "nelmio/api-doc-bundle", + "version": "2.11.2", + "target-dir": "Nelmio/ApiDocBundle", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioApiDocBundle.git", + "reference": "1ae2cfa9a50279d722d6b6e7b02322cef948d55d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/1ae2cfa9a50279d722d6b6e7b02322cef948d55d", + "reference": "1ae2cfa9a50279d722d6b6e7b02322cef948d55d", + "shasum": "" + }, + "require": { + "michelf/php-markdown": "~1.4", + "php": ">=5.3", + "symfony/console": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0", + "symfony/twig-bundle": "~2.3|~3.0" + }, + "conflict": { + "jms/serializer": "<0.12", + "jms/serializer-bundle": "<0.11", + "twig/twig": "<1.12" + }, + "require-dev": { + "doctrine/doctrine-bundle": "~1.5", + "doctrine/orm": "~2.3", + "dunglas/api-bundle": "~1.0@dev", + "friendsofsymfony/rest-bundle": "~1.0|~2.0", + "jms/serializer-bundle": ">=0.11", + "sensio/framework-extra-bundle": "~3.0", + "symfony/browser-kit": "~2.3|~3.0", + "symfony/css-selector": "~2.3|~3.0", + "symfony/finder": "~2.3|~3.0", + "symfony/form": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/serializer": "~2.7|~3.0", + "symfony/validator": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "suggest": { + "dunglas/api-bundle": "For making use of resources definitions of DunglasApiBundle.", + "friendsofsymfony/rest-bundle": "For making use of REST information in the doc.", + "jms/serializer": "For making use of serializer information in the doc.", + "symfony/form": "For using form definitions as input.", + "symfony/validator": "For making use of validator information in the doc." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.11-dev" + } + }, + "autoload": { + "psr-0": { + "Nelmio\\ApiDocBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nelmio", + "homepage": "http://nelm.io" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors" + } + ], + "description": "Generates documentation for your REST API from annotations", + "keywords": [ + "api", + "doc", + "documentation", + "rest" + ], + "time": "2015-12-16 15:17:51" + }, + { + "name": "paragonie/random_compat", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2016-03-18 20:34:03" + }, + { + "name": "phpcollection/phpcollection", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-collection.git", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-collection/zipball/b8bf55a0a929ca43b01232b36719f176f86c7e83", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83", + "shasum": "" + }, + "require": { + "phpoption/phpoption": "1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpCollection": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "http://jmsyst.com", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "General-Purpose Collection Library for PHP", + "keywords": [ + "collection", + "list", + "map", + "sequence", + "set" + ], + "time": "2014-03-11 13:46:42" + }, + { + "name": "phpoption/phpoption", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpOption\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "time": "2015-07-25 16:39:46" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "sensio/distribution-bundle", + "version": "v4.0.7", + "target-dir": "Sensio/Bundle/DistributionBundle", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", + "reference": "d738952285a1a7d969f9338f735108c9f65bb7f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/d738952285a1a7d969f9338f735108c9f65bb7f2", + "reference": "d738952285a1a7d969f9338f735108c9f65bb7f2", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "sensiolabs/security-checker": "~3.0", + "symfony/class-loader": "~2.2", + "symfony/framework-bundle": "~2.3", + "symfony/process": "~2.2" + }, + "require-dev": { + "symfony/form": "~2.2", + "symfony/validator": "~2.2", + "symfony/yaml": "~2.2" + }, + "suggest": { + "symfony/form": "If you want to use the configurator", + "symfony/validator": "If you want to use the configurator", + "symfony/yaml": "If you want to use the configurator" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Sensio\\Bundle\\DistributionBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Base bundle for Symfony Distributions", + "keywords": [ + "configuration", + "distribution" + ], + "time": "2016-06-23 16:10:25" + }, + { + "name": "sensio/framework-extra-bundle", + "version": "v3.0.16", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", + "reference": "507a15f56fa7699f6cc8c2c7de4080b19ce22546" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/507a15f56fa7699f6cc8c2c7de4080b19ce22546", + "reference": "507a15f56fa7699f6cc8c2c7de4080b19ce22546", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.2", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "symfony/browser-kit": "~2.3|~3.0", + "symfony/dom-crawler": "~2.3|~3.0", + "symfony/expression-language": "~2.4|~3.0", + "symfony/finder": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/security-bundle": "~2.4|~3.0", + "symfony/twig-bundle": "~2.3|~3.0", + "twig/twig": "~1.11|~2.0" + }, + "suggest": { + "symfony/expression-language": "", + "symfony/psr-http-message-bridge": "To use the PSR-7 converters", + "symfony/security-bundle": "" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2016-03-25 17:08:27" + }, + { + "name": "sensiolabs/security-checker", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/security-checker.git", + "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/21696b0daa731064c23cfb694c60a2584a7b6e93", + "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93", + "shasum": "" + }, + "require": { + "symfony/console": "~2.0|~3.0" + }, + "bin": [ + "security-checker" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-0": { + "SensioLabs\\Security": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "A security checker for your composer.lock", + "time": "2015-11-07 08:07:40" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.4.2", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "d8db871a54619458a805229a057ea2af33c753e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8", + "reference": "d8db871a54619458a805229a057ea2af33c753e8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1,<0.9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2016-05-01 08:45:47" + }, + { + "name": "symfony/assetic-bundle", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/assetic-bundle.git", + "reference": "aa5b4f8b712f38745928fa845ddb73300bb2af6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/assetic-bundle/zipball/aa5b4f8b712f38745928fa845ddb73300bb2af6d", + "reference": "aa5b4f8b712f38745928fa845ddb73300bb2af6d", + "shasum": "" + }, + "require": { + "kriswallsmith/assetic": "~1.3", + "php": ">=5.3.0", + "symfony/console": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "conflict": { + "kriswallsmith/spork": "<=0.2", + "twig/twig": "<1.20" + }, + "require-dev": { + "kriswallsmith/spork": "~0.3", + "patchwork/jsqueeze": "~1.0", + "symfony/class-loader": "~2.3|~3.0", + "symfony/css-selector": "~2.3|~3.0", + "symfony/dom-crawler": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/twig-bundle": "~2.3|~3.0" + }, + "suggest": { + "kriswallsmith/spork": "to be able to dump assets in parallel", + "symfony/twig-bundle": "to use the Twig integration" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\AsseticBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Integrates Assetic into Symfony2", + "homepage": "https://github.com/symfony/AsseticBundle", + "keywords": [ + "assets", + "compression", + "minification" + ], + "time": "2015-12-28 13:12:39" + }, + { + "name": "symfony/monolog-bundle", + "version": "2.11.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00", + "reference": "e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00", + "shasum": "" + }, + "require": { + "monolog/monolog": "~1.18", + "php": ">=5.3.2", + "symfony/config": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/http-kernel": "~2.3|~3.0", + "symfony/monolog-bridge": "~2.3|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "symfony/console": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony MonologBundle", + "homepage": "http://symfony.com", + "keywords": [ + "log", + "logging" + ], + "time": "2016-04-13 16:21:01" + }, + { + "name": "symfony/polyfill-apcu", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "6d58bceaeea2c2d3eb62503839b18646e161cd6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/6d58bceaeea2c2d3eb62503839b18646e161cd6b", + "reference": "6d58bceaeea2c2d3eb62503839b18646e161cd6b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-05-18 14:26:46" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "dff51f72b0706335131b00a7f49606168c582594" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", + "reference": "dff51f72b0706335131b00a7f49606168c582594", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-05-18 14:26:46" + }, + { + "name": "symfony/swiftmailer-bundle", + "version": "v2.3.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/swiftmailer-bundle.git", + "reference": "5e1a90f28213231ceee19c953bbebc5b5b95c690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/swiftmailer-bundle/zipball/5e1a90f28213231ceee19c953bbebc5b5b95c690", + "reference": "5e1a90f28213231ceee19c953bbebc5b5b95c690", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "swiftmailer/swiftmailer": ">=4.2.0,~5.0", + "symfony/config": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/http-kernel": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "suggest": { + "psr/log": "Allows logging" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\SwiftmailerBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony SwiftmailerBundle", + "homepage": "http://symfony.com", + "time": "2016-01-15 16:41:20" + }, + { + "name": "symfony/symfony", + "version": "v2.7.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/symfony.git", + "reference": "fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/symfony/zipball/fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1", + "reference": "fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.4", + "paragonie/random_compat": "~1.0", + "php": ">=5.3.9", + "psr/log": "~1.0", + "symfony/polyfill-apcu": "~1.1", + "symfony/polyfill-mbstring": "~1.1", + "twig/twig": "~1.23|~2.0" + }, + "replace": { + "symfony/asset": "self.version", + "symfony/browser-kit": "self.version", + "symfony/class-loader": "self.version", + "symfony/config": "self.version", + "symfony/console": "self.version", + "symfony/css-selector": "self.version", + "symfony/debug": "self.version", + "symfony/debug-bundle": "self.version", + "symfony/dependency-injection": "self.version", + "symfony/doctrine-bridge": "self.version", + "symfony/dom-crawler": "self.version", + "symfony/event-dispatcher": "self.version", + "symfony/expression-language": "self.version", + "symfony/filesystem": "self.version", + "symfony/finder": "self.version", + "symfony/form": "self.version", + "symfony/framework-bundle": "self.version", + "symfony/http-foundation": "self.version", + "symfony/http-kernel": "self.version", + "symfony/intl": "self.version", + "symfony/locale": "self.version", + "symfony/monolog-bridge": "self.version", + "symfony/options-resolver": "self.version", + "symfony/process": "self.version", + "symfony/property-access": "self.version", + "symfony/proxy-manager-bridge": "self.version", + "symfony/routing": "self.version", + "symfony/security": "self.version", + "symfony/security-acl": "self.version", + "symfony/security-bundle": "self.version", + "symfony/security-core": "self.version", + "symfony/security-csrf": "self.version", + "symfony/security-http": "self.version", + "symfony/serializer": "self.version", + "symfony/stopwatch": "self.version", + "symfony/swiftmailer-bridge": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "symfony/twig-bridge": "self.version", + "symfony/twig-bundle": "self.version", + "symfony/validator": "self.version", + "symfony/var-dumper": "self.version", + "symfony/web-profiler-bundle": "self.version", + "symfony/yaml": "self.version" + }, + "require-dev": { + "doctrine/data-fixtures": "1.0.*", + "doctrine/dbal": "~2.4", + "doctrine/doctrine-bundle": "~1.2", + "doctrine/orm": "~2.4,>=2.4.5", + "egulias/email-validator": "~1.2", + "ircmaxell/password-compat": "~1.0", + "monolog/monolog": "~1.11", + "ocramius/proxy-manager": "~0.4|~1.0|~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Doctrine\\": "src/Symfony/Bridge/Doctrine/", + "Symfony\\Bridge\\Monolog\\": "src/Symfony/Bridge/Monolog/", + "Symfony\\Bridge\\ProxyManager\\": "src/Symfony/Bridge/ProxyManager/", + "Symfony\\Bridge\\Swiftmailer\\": "src/Symfony/Bridge/Swiftmailer/", + "Symfony\\Bridge\\Twig\\": "src/Symfony/Bridge/Twig/", + "Symfony\\Bundle\\": "src/Symfony/Bundle/", + "Symfony\\Component\\": "src/Symfony/Component/" + }, + "classmap": [ + "src/Symfony/Component/HttpFoundation/Resources/stubs", + "src/Symfony/Component/Intl/Resources/stubs" + ], + "files": [ + "src/Symfony/Component/Intl/Resources/stubs/functions.php" + ], + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "The Symfony PHP framework", + "homepage": "https://symfony.com", + "keywords": [ + "framework" + ], + "time": "2016-06-06 15:23:39" + }, + { + "name": "twig/twig", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512", + "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.24-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "time": "2016-05-30 09:11:59" + }, + { + "name": "willdurand/hateoas", + "version": "2.10.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Hateoas.git", + "reference": "ada89d867e47040f8c4be3be2c8e7930a3d01189" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Hateoas/zipball/ada89d867e47040f8c4be3be2c8e7930a3d01189", + "reference": "ada89d867e47040f8c4be3be2c8e7930a3d01189", + "shasum": "" + }, + "require": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.0", + "jms/metadata": "~1.1", + "jms/serializer": "~1.0", + "php": ">=5.4", + "phpoption/phpoption": ">=1.1.0,<2.0-dev", + "symfony/expression-language": "~2.4 || ~3.0" + }, + "require-dev": { + "pagerfanta/pagerfanta": "~1.0", + "phpunit/phpunit": "~4.5", + "symfony/dependency-injection": "~2.4 || ~3.0", + "symfony/routing": "~2.4 || ~3.0", + "symfony/yaml": "~2.4 || ~3.0", + "twig/twig": "~1.12" + }, + "suggest": { + "symfony/routing": "To use the SymfonyRouteFactory.", + "symfony/yaml": "To use yaml based configuration.", + "twig/twig": "To use the Twig extensions." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + } + }, + "autoload": { + "psr-0": { + "Hateoas": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Adrien Brault", + "email": "adrien.brault@gmail.com" + }, + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "A PHP library to support implementing representations for HATEOAS REST web services", + "time": "2016-05-19 11:30:35" + }, + { + "name": "willdurand/hateoas-bundle", + "version": "1.1.1", + "target-dir": "Bazinga/Bundle/HateoasBundle", + "source": { + "type": "git", + "url": "https://github.com/willdurand/BazingaHateoasBundle.git", + "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5", + "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5", + "shasum": "" + }, + "require": { + "jms/serializer-bundle": "~1.0", + "symfony/framework-bundle": "~2.2 || ~3.0", + "willdurand/hateoas": "~2.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "symfony/expression-language": "~2.4 || ~3.0", + "twig/twig": "~1.12" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-0": { + "Bazinga\\Bundle\\HateoasBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Integration of Hateoas into Symfony2.", + "keywords": [ + "HATEOAS", + "rest" + ], + "time": "2016-02-22 13:12:41" + }, + { + "name": "willdurand/jsonp-callback-validator", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/JsonpCallbackValidator.git", + "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/JsonpCallbackValidator/zipball/1a7d388bb521959e612ef50c5c7b1691b097e909", + "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonpCallbackValidator": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com", + "homepage": "http://www.willdurand.fr" + } + ], + "description": "JSONP callback validator.", + "time": "2014-01-20 22:35:06" + }, + { + "name": "willdurand/negotiation", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Negotiation.git", + "reference": "a8ce6da7acdf07351ccd6a9359c571ebc0725a21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/a8ce6da7acdf07351ccd6a9359c571ebc0725a21", + "reference": "a8ce6da7acdf07351ccd6a9359c571ebc0725a21", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Negotiation\\": "src/Negotiation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "will+git@drnd.me" + } + ], + "description": "Content Negotiation tools for PHP provided as a standalone library.", + "homepage": "http://williamdurand.fr/Negotiation/", + "keywords": [ + "accept", + "content", + "format", + "header", + "negotiation" + ], + "time": "2015-11-21 14:23:02" + }, + { + "name": "willdurand/rest-extra-bundle", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/BazingaRestExtraBundle.git", + "reference": "36e60da837a3bcef4c38d277a154d300c089a323" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/BazingaRestExtraBundle/zipball/36e60da837a3bcef4c38d277a154d300c089a323", + "reference": "36e60da837a3bcef4c38d277a154d300c089a323", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "~2.1|~3.0" + }, + "require-dev": { + "sensio/framework-extra-bundle": "~2.1", + "symfony/browser-kit": "~2.1", + "symfony/finder": "~2.1", + "symfony/form": "~2.1", + "symfony/yaml": "~2.1" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Bazinga\\Bundle\\RestExtraBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "This bundle provides extra features for your REST APIs built using Symfony2.", + "keywords": [ + "api", + "rest" + ], + "time": "2016-03-30 10:26:31" + } + ], + "packages-dev": [ + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11 14:41:42" + }, + { + "name": "mockery/mockery", + "version": "0.9.5", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2", + "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~1.1", + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2016-05-22 21:52:33" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/ea74994a3dc7f8d2f65a06009348f2d63c81e61f", + "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2016-09-16 13:37:59" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", + "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-06-10 07:14:17" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", + "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1", + "sebastian/recursion-context": "^1.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2016-06-07 08:13:47" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5f3f7e736d6319d5f1fc402aff8b026da26709a3", + "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2016-07-26 14:39:29" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2016-05-12 18:03:57" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-09-15 10:49:45" + }, + { + "name": "phpunit/phpunit", + "version": "5.6.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "60c32c5b5e79c2248001efa2560f831da11cc2d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60c32c5b5e79c2248001efa2560f831da11cc2d7", + "reference": "60c32c5b5e79c2248001efa2560f831da11cc2d7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "^4.0.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3 || ^2.0", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/object-enumerator": "~1.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.6.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2016-10-07 13:03:26" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", + "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-10-09 07:01:45" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2016-02-13 06:45:14" + }, + { + "name": "sebastian/comparator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-12-08 07:14:41" + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-08-18 05:49:44" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-06-17 09:04:28" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/object-enumerator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", + "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-01-28 13:25:10" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-11-11 19:50:13" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28 20:34:47" + }, + { + "name": "sebastian/version", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-02-04 12:56:52" + }, + { + "name": "sensio/generator-bundle", + "version": "v2.5.3", + "target-dir": "Sensio/Bundle/GeneratorBundle", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git", + "reference": "e50108c2133ee5c9c484555faed50c17a61221d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/e50108c2133ee5c9c484555faed50c17a61221d3", + "reference": "e50108c2133ee5c9c484555faed50c17a61221d3", + "shasum": "" + }, + "require": { + "symfony/console": "~2.5", + "symfony/framework-bundle": "~2.2" + }, + "require-dev": { + "doctrine/orm": "~2.2,>=2.2.3", + "symfony/doctrine-bridge": "~2.2", + "twig/twig": "~1.11" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Sensio\\Bundle\\GeneratorBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle generates code for you", + "time": "2015-03-17 06:36:52" + }, + { + "name": "webmozart/assert", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", + "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-08-09 15:02:57" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [] +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/.htaccess b/exercises/legacy_create_video/base/php-symfony/src/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/AppBundle.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/AppBundle.php new file mode 100644 index 00000000..05123b67 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/AppBundle.php @@ -0,0 +1,9 @@ +getDoctrine() + ->getEntityManager() + ->createQueryBuilder() + ->select('c', 'v') + ->from('AppBundle\Model\Course', 'c') + ->where('c.level', '>', $request->get('from_level', 0)) + ->getQuery() + ->execute(); + } + + public function getCourseVideosAction($courseId) + { + if ($this->hasCache('course-db-' . $courseId)) { + return $this->getCache('course-db-' . $courseId); + } else { + $this->setCache( + 'course-db-' . $courseId, + $this->getDoctrine() + ->getEntityManager() + ->createQueryBuilder() + ->select('c', 'v') + ->from('AppBundle\Model\Course', 'c') + ->leftJoin('a.Video', 'v') + ->where('c.id', '=', $courseId) + ->getQuery() + ->execute() + ); + } + + return $this->getCache('course-db-' . $courseId); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/NoteController.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/NoteController.php new file mode 100644 index 00000000..90b0bb08 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/NoteController.php @@ -0,0 +1,275 @@ + + */ +class NoteController extends BaseController +{ + /** + * return \AppBundle\NoteManager + */ + public function getNoteManager() + { + return $this->get('app.note_manager'); + } + + /** + * List all notes. + * + * @ApiDoc( + * resource = true, + * statusCodes = { + * 200 = "Returned when successful" + * } + * ) + * + * @Annotations\QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing notes.") + * @Annotations\QueryParam(name="limit", requirements="\d+", default="5", description="How many notes to return.") + * + * @Annotations\View() + * + * @param ParamFetcherInterface $paramFetcher param fetcher service + * + * @return array + */ + public function getNotesAction(ParamFetcherInterface $paramFetcher) + { + $offset = $paramFetcher->get('offset'); + $start = null == $offset ? 0 : $offset + 1; + $limit = $paramFetcher->get('limit'); + + $notes = $this->getNoteManager()->fetch($start, $limit); + + return new NoteCollection($notes, $offset, $limit); + } + + /** + * Presents the form to use to create a new note. + * + * @ApiDoc( + * resource = true, + * statusCodes = { + * 200 = "Returned when successful" + * } + * ) + * + * @Annotations\View() + * + * @return FormTypeInterface + */ + public function newNoteAction() + { + return $this->createForm(new NoteType()); + } + + /** + * Get a single note. + * + * @ApiDoc( + * output = "AppBundle\Model\Note", + * statusCodes = { + * 200 = "Returned when successful", + * 404 = "Returned when the note is not found" + * } + * ) + * + * @Annotations\View(templateVar="note") + * + * @param int $id the note id + * + * @return array + * + * @throws NotFoundHttpException when note not exist + */ + public function getNoteAction($id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + throw $this->createNotFoundException("Note does not exist."); + } + + $view = new View($note); + $group = $this->container->get('security.context')->isGranted('ROLE_API') ? 'restapi' : 'standard'; + $view->getContext()->addGroup('Default'); + $view->getContext()->addGroup($group); + + return $view; + } + + /** + * Creates a new note from the submitted data. + * + * @ApiDoc( + * resource = true, + * input = "AppBundle\Form\NoteType", + * statusCodes = { + * 200 = "Returned when successful", + * 400 = "Returned when the form has errors" + * } + * ) + * + * @Annotations\View( + * template = "AppBundle:Note:newNote.html.twig", + * statusCode = Response::HTTP_BAD_REQUEST + * ) + * + * @param Request $request the request object + * + * @return FormTypeInterface[]|View + */ + public function postNotesAction(Request $request) + { + $note = new Note(); + $form = $this->createForm(new NoteType(), $note); + + $form->submit($request); + if ($form->isValid()) { + $this->getNoteManager()->set($note); + + return $this->routeRedirectView('get_note', array('id' => $note->id)); + } + + return array( + 'form' => $form + ); + } + + /** + * Presents the form to use to update an existing note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 200 = "Returned when successful", + * 404 = "Returned when the note is not found" + * } + * ) + * + * @Annotations\View() + * + * @param int $id the note id + * + * @return FormTypeInterface + * + * @throws NotFoundHttpException when note not exist + */ + public function editNotesAction($id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + throw $this->createNotFoundException("Note does not exist."); + } + + return $this->createForm(new NoteType(), $note); + } + + /** + * Update existing note from the submitted data or create a new note at a specific location. + * + * @ApiDoc( + * resource = true, + * input = "AppBundle\Form\NoteType", + * statusCodes = { + * 201 = "Returned when a new resource is created", + * 204 = "Returned when successful", + * 400 = "Returned when the form has errors" + * } + * ) + * + * @Annotations\View( + * template="AppBundle:Note:editNote.html.twig", + * templateVar="form" + * ) + * + * @param Request $request the request object + * @param int $id the note id + * + * @return FormTypeInterface|RouteRedirectView + * + * @throws NotFoundHttpException when note not exist + */ + public function putNotesAction(Request $request, $id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + $note = new Note(); + $note->id = $id; + $statusCode = Response::HTTP_CREATED; + } else { + $statusCode = Response::HTTP_NO_CONTENT; + } + + $form = $this->createForm(new NoteType(), $note); + + $form->submit($request); + if ($form->isValid()) { + $this->getNoteManager()->set($note); + + return $this->routeRedirectView('get_note', array('id' => $note->id), $statusCode); + } + + return $form; + } + + /** + * Removes a note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 204="Returned when successful" + * } + * ) + * + * @param int $id the note id + * + * @return View + */ + public function deleteNotesAction($id) + { + $this->getNoteManager()->remove($id); + + // There is a debate if this should be a 404 or a 204 + // see http://leedavis81.github.io/is-a-http-delete-requests-idempotent/ + return $this->routeRedirectView('get_notes', array(), Response::HTTP_NO_CONTENT); + } + + /** + * Removes a note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 204="Returned when successful" + * } + * ) + * + * @param int $id the note id + * + * @return View + */ + public function removeNotesAction($id) + { + return $this->deleteNotesAction($id); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/VideoController.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/VideoController.php new file mode 100644 index 00000000..ca632596 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Controller/VideoController.php @@ -0,0 +1,56 @@ +get('title')}\", + \"{$request->get('url')}\", + {$request->get('course_id')} + )"; + + // Prepare doctrine statement + $connection = $this->getDoctrine()->getConnection(); + $stmt = $connection->prepare($sql); + $stmt->execute(); + + // IMPORTANT: Obtaining the video id. Take care, it's done without another query :) + $videoId = $connection->lastInsertId(); + + $title = $request->get('title'); + $sql = "UPDATE video SET "; + if (strpos($request->get('title'), "hexagonal")) { + $title = str_replace("hexagonal", "Hexagonal", $title); + } + if (strpos($request->get('title'), "solid")) { + $title = str_replace("solid", "SOLID", $title); + } + if (strpos($request->get('title'), "tdd")) { + $title = str_replace("tdd", "TDD", $title); + } + $sql .= "title = '" . $title . "' WHERE id = " . $videoId; + $connection->query($sql); + + // And we return the video created + return [ + 'id' => $videoId, + 'title' => $title, + 'url' => $request->get('url'), + 'course_id' => $request->get('course_id'), + ]; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/DependencyInjection/AppExtension.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/DependencyInjection/AppExtension.php new file mode 100644 index 00000000..bfb9b582 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/DependencyInjection/AppExtension.php @@ -0,0 +1,17 @@ +load('services.xml'); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/EventListener/ControllerListener.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/EventListener/ControllerListener.php new file mode 100644 index 00000000..c170b9e9 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/EventListener/ControllerListener.php @@ -0,0 +1,24 @@ +extension = $extension; + } + + public function onKernelController(FilterControllerEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { + $this->extension->setController($event->getController()); + } + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Form/NoteType.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Form/NoteType.php new file mode 100644 index 00000000..b5f3e492 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Form/NoteType.php @@ -0,0 +1,31 @@ +add('message', 'textarea', array( + 'description' => 'A brief record of points or ideas written down as an aid to memory', + )); + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'AppBundle\Model\Note', + 'intention' => 'note', + 'translation_domain' => 'AppBundle' + )); + } + + public function getName() + { + return 'note'; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Course.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Course.php new file mode 100644 index 00000000..3b9f63a4 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Course.php @@ -0,0 +1,29 @@ +title ?: self::DEFAULT_TITLE; + } + + public function getLevel() + { + return $this->level ?: self::DEFAULT_LEVEL; + } + + public function getType() + { + return $this->type ?: self::DEFAULT_TYPE; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Event.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Event.php new file mode 100644 index 00000000..259fe298 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Event.php @@ -0,0 +1,35 @@ +name = $name; + $this->date = $date; + } + + public function getName() + { + return $this->name; + } + + public function getDate() + { + return $this->date; + } + + public function setName($name) + { + $this->name = $name; + } + + public function setDate(\DateTime $date) + { + $this->date = $date; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Note.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Note.php new file mode 100644 index 00000000..93888a0a --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/Note.php @@ -0,0 +1,59 @@ +message; + } + + public function getAssociatedEventsRel() + { + return 'associated_events'; + } + + public function getAssociatedEvents() + { + return array( + new Event('SymfonyCon', new \DateTime('December 12, 2013')), + new Event('Christmas Day', new \DateTime('December 25, 2013')), + ); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/NoteCollection.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/NoteCollection.php new file mode 100644 index 00000000..b00f6f66 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Model/NoteCollection.php @@ -0,0 +1,33 @@ +notes = $notes; + $this->offset = $offset; + $this->limit = $limit; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/NoteManager.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/NoteManager.php new file mode 100644 index 00000000..7f142cee --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/NoteManager.php @@ -0,0 +1,82 @@ +data = unserialize($data); + } + + $this->randomGenerator = $randomGenerator; + $this->cacheDir = $cacheDir; + } + + private function flush() + { + file_put_contents($this->cacheDir . '/sf_note_data', serialize($this->data)); + } + + public function fetch($start = 0, $limit = 5) + { + return array_slice($this->data, $start, $limit, true); + } + + public function get($id) + { + if (!isset($this->data[$id])) { + return false; + } + + return $this->data[$id]; + } + + public function set($note) + { + if (null === $note->id) { + if (empty($this->data)) { + $note->id = 0; + } else { + end($this->data); + $note->id = key($this->data) + 1; + } + } + + if (null === $note->secret) { + $note->secret = base64_encode($this->randomGenerator->nextBytes(64)); + } + + $this->data[$note->id] = $note; + $this->flush(); + } + + public function remove($id) + { + if (!isset($this->data[$id])) { + return false; + } + + unset($this->data[$id]); + $this->flush(); + + return true; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Event.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Event.yml new file mode 100644 index 00000000..275c8843 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Event.yml @@ -0,0 +1,8 @@ +AppBundle\Model\Event: + exclusion_policy: ALL + xml_root_name: event + properties: + name: + expose: true + date: + expose: true diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Note.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Note.yml new file mode 100644 index 00000000..ba76bb44 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.Note.yml @@ -0,0 +1,36 @@ +AppBundle\Model\Note: + exclusion_policy: ALL + xml_root_name: note + properties: + message: + expose: true + type: string + groups: [standard, restapi] + secret: + expose: true + type: string + groups: [restapi] + version: + expose: true + type: string + until_version: 1.1 + new_version: + expose: true + type: string + serialized_name: version + since_version: 1.1 + relations: + - + rel: self + href: + route: get_note + parameters: + id: expr(object.id) + absolute: true + - + rel: expr(object.getAssociatedEventsRel()) + embed: + content: expr(object.getAssociatedEvents()) + xmlElementName: events + exclusion: + exclude_if: expr(object.id === 0) diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml new file mode 100644 index 00000000..f2e2ee6a --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml @@ -0,0 +1,34 @@ +AppBundle\Model\NoteCollection: + exclusion_policy: ALL + xml_root_name: notes + properties: + notes: + expose: true + type: array + xml_list: + inline: true + entry_name: note + offset: + expose: true + type: integer + xml_attribute: true + limit: + expose: true + type: integer + xml_attribute: true + relations: + - + rel: self + href: + route: get_notes + absolute: true + - + rel: note + href: + route: get_note + absolute: true + generator: templated_uri + parameters: + id: "{id}" + attributes: + templated: true diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/services.xml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/services.xml new file mode 100644 index 00000000..aa0ea4ad --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/services.xml @@ -0,0 +1,23 @@ + + + + + + + + %kernel.cache_dir% + + + + + + + + + + + + + diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/validation.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/validation.yml new file mode 100644 index 00000000..ab78d0c5 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/config/validation.yml @@ -0,0 +1,4 @@ +AppBundle\Model\Note: + properties: + message: + - NotBlank: ~ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/css/demo.css b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/css/demo.css new file mode 100644 index 00000000..4dd2f16c --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/css/demo.css @@ -0,0 +1,101 @@ +body { + font-size: 14px; + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; +} +h1.title { + font-size: 45px; + padding-bottom: 30px; +} +.sf-reset h2 { + font-weight: bold; + color: #FFFFFF; + /* Font is duplicated of body (sans-serif) */ + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + + margin-bottom: 10px; + background-color: #aacd4e; + padding: 2px 4px; + display: inline-block; + text-transform: uppercase; + +} +p { + line-height: 20px; + padding-bottom: 20px; +} +ul#demo-list a { + background: url(../images/blue-arrow.png) no-repeat right 6px; + padding-right: 10px; + margin-right: 30px; +} +#symfony-header { + position: relative; + padding: 30px 30px 20px 30px; +} +.sf-reset .symfony-blocks-welcome { + overflow: hidden; +} +.sf-reset .symfony-blocks-welcome > div { + background-color: whitesmoke; + float: left; + width: 240px; + margin-right: 14px; + text-align: center; + padding: 26px 20px; +} +.sf-reset .symfony-blocks-welcome > div.block-demo { + margin-right: 0; +} +.sf-reset .symfony-blocks-welcome .illustration { + padding-bottom: 20px; +} +.sf-reset .symfony-blocks-help { + overflow: hidden; +} +.sf-reset .symfony-blocks-help { + margin-top: 30px; + padding: 18px; + border: 1px solid #E6E6E6; +} +.sf-reset .symfony-blocks-help > div { + width: 254px; + float: left; +} +.flash-message { + padding: 10px; + margin: 5px; + margin-top: 15px; + background-color: #ffe; +} +.sf-reset .error { + color: red; +} +#login label, #contact_form label { + display: block; + float: left; + width: 90px; +} +.sf-reset ul#menu { + float: right; + margin-bottom: 20px; + padding-left: 0; +} +.sf-reset #menu li { + padding-left: 0; + margin-right: 10px; + display: inline; +} +.sf-reset a, +.sf-reset li a { + color: #08C; + text-decoration: none; +} +.sf-reset a:hover, +.sf-reset li a:hover { + color: #08C; + text-decoration: underline; +} +.sf-reset .symfony-content pre { + white-space: pre; + font-family: monospace; +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/blue-arrow.png b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/blue-arrow.png new file mode 100644 index 00000000..fa82d4b4 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/blue-arrow.png differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/field-background.gif b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/field-background.gif new file mode 100644 index 00000000..7c0efc10 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/field-background.gif differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/logo.gif b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/logo.gif new file mode 100644 index 00000000..703cf45f Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/logo.gif differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/search.png b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/search.png new file mode 100644 index 00000000..3c88b6a4 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/search.png differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-configure.gif b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-configure.gif new file mode 100644 index 00000000..931179a7 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-configure.gif differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-demo.gif b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-demo.gif new file mode 100644 index 00000000..0623de54 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-demo.gif differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-quick-tour.gif b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-quick-tour.gif new file mode 100644 index 00000000..b9018b11 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/public/images/welcome-quick-tour.gif differ diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.de.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.de.yml new file mode 100644 index 00000000..950a4e8f --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.de.yml @@ -0,0 +1,20 @@ +note: + list: + link: zurück zur Notizliste + headline: Verfügbare Notizen + empty: Keine Notizen gefunden + new: + link: Neue Notiz anlegen + headline: Neue Notiz anlegen + submit: Notiz hinzufügen + edit: + link: Notiz bearbeiten + headline: Notiz \#%id% bearbeiten + submit: Notiz aktualisieren + remove: + link: entfernen + offset: Offset + limit: Limit +api: + doc: + link: API Dokumentation diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.en.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.en.yml new file mode 100644 index 00000000..e50c3a0d --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.en.yml @@ -0,0 +1,20 @@ +note: + list: + link: back to note list + headline: Available notes + empty: No notes found + new: + link: create new note + headline: Create new note + submit: add note + edit: + link: edit + headline: Edit note %id% + submit: update note + remove: + link: remove + offset: offset + limit: limit +api: + doc: + link: API documentation diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.es.yml b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.es.yml new file mode 100644 index 00000000..71b45856 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/translations/AppBundle.es.yml @@ -0,0 +1,20 @@ +note: + list: + link: de vuelta a la lista de notas + headline: Notas disponibles + empty: Ninguna nota encontrada + new: + link: crear una nota + headline: Crear nota + submit: añadir nota + edit: + link: editar + headline: Editar nota %id% + submit: actualizar nota + remove: + link: remover + offset: posición + limit: limite +api: + doc: + link: Documentación del API diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNote.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNote.html.twig new file mode 100644 index 00000000..14de63ca --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNote.html.twig @@ -0,0 +1,19 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.edit.headline'|trans({'%id%': id}, 'AppBundle') }}

+ +
+ + + {{ form_widget(form) }} + + +
+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNotes.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNotes.html.twig new file mode 100644 index 00000000..14de63ca --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/editNotes.html.twig @@ -0,0 +1,19 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.edit.headline'|trans({'%id%': id}, 'AppBundle') }}

+ +
+ + + {{ form_widget(form) }} + + +
+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNote.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNote.html.twig new file mode 100644 index 00000000..c27b195a --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNote.html.twig @@ -0,0 +1,18 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Note" %} + +{% block content_header '' %} + +{% block content %} +

Note #{{ id }}

+ +

{{ note }}

+

+ {{ 'note.list.link'|trans({}, 'AppBundle') }}
+ [{{ 'note.remove.link'|trans({}, 'AppBundle') }}] + [{{ 'note.edit.link'|trans({}, 'AppBundle') }}] +

+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNotes.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNotes.html.twig new file mode 100644 index 00000000..143c0c3b --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/getNotes.html.twig @@ -0,0 +1,30 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.list.headline'|trans({}, 'AppBundle') }}

+ +

+ {{ 'note.offset'|trans({}, 'AppBundle') }}: {{ data.offset ?: '-' }}, {{ 'note.limit'|trans({}, 'AppBundle') }}: {{ data.limit }} +

+ + +

+ {{ 'note.new.link'|trans({}, 'AppBundle') }} +

+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/newNote.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/newNote.html.twig new file mode 100644 index 00000000..b22a9ad7 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/Note/newNote.html.twig @@ -0,0 +1,21 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.new.headline'|trans({}, 'AppBundle') }}

+ + {% if (form is defined) %} +
+ + {{ form_widget(form) }} + + +
+ {% endif %} + +{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/layout.html.twig b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/layout.html.twig new file mode 100644 index 00000000..e855ab09 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Resources/views/layout.html.twig @@ -0,0 +1,35 @@ +{% extends "TwigBundle::layout.html.twig" %} + +{% block head %} + + +{% endblock %} + +{% block title 'Demo Bundle' %} + +{% block body %} + {% block content_header %} + + +
+ {% endblock %} + +
+ {% block content %}{% endblock %} + +

+ {{ 'api.doc.link'|trans({}, 'AppBundle') }} +

+
+ + {% if code is defined %} +

Code behind this page

+
+
{{ code|raw }}
+
+ {% endif %} +{% endblock %} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/CourseControllerTest.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/CourseControllerTest.php new file mode 100644 index 00000000..e1c5c2bc --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/CourseControllerTest.php @@ -0,0 +1,92 @@ + $fromLevel]); + + $container = \Mockery::mock(ContainerInterface::class); + $doctrine = \Mockery::mock(Registry::class); + $entityManager = \Mockery::mock(EntityManager::class); + $queryBuilder = \Mockery::mock(QueryBuilder::class); + $query = \Mockery::mock(AbstractQuery::class); + + $container->shouldReceive('has') + ->once() + ->with('doctrine') + ->andReturn(true); + $container->shouldReceive('get') + ->once() + ->with('doctrine') + ->andReturn($doctrine); + $doctrine->shouldReceive('getEntityManager') + ->once() + ->withNoArgs() + ->andReturn($entityManager); + $entityManager->shouldReceive('createQueryBuilder') + ->once() + ->withNoArgs() + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('select') + ->once() + ->with('c', 'v') + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('from') + ->once() + ->with('AppBundle\Model\Course', 'c') + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('where') + ->once() + ->with('c.level', '>', $fromLevel) + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('getQuery') + ->once() + ->withNoArgs() + ->andReturn($query); + $query->shouldReceive('execute') + ->once() + ->withNoArgs() + ->andReturn( + [ + [ + 'title' => 'Codely mola', + 'level' => 2, + ], + [ + 'title' => 'Aprende a decir basicamente como Javi', + 'level' => 5, + ], + ] + ); + + $controller = new CourseController(); + $controller->setContainer($container); + $controllerResult = $controller->getCourseAction($request); + $this->assertEquals( + [ + [ + 'title' => 'Codely mola', + 'level' => 2, + ], + [ + 'title' => 'Aprende a decir basicamente como Javi', + 'level' => 5, + ], + ], + $controllerResult + ); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/NoteControllerTest.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/NoteControllerTest.php new file mode 100644 index 00000000..5e463030 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Controller/NoteControllerTest.php @@ -0,0 +1,269 @@ +getClient()->getContainer()->getParameter('kernel.cache_dir'); + if (file_exists($cacheDir . '/sf_note_data')) { + unlink($cacheDir . '/sf_note_data'); + } + } + + public function testGetNotes() + { + $client = $this->getClient(true); + + // head request + $client->request('HEAD', '/notes.json'); + $response = $client->getResponse(); + $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); + + // empty list + $client->request('GET', '/notes.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"notes":[],"limit":5,"_links":{"self":{"href":"http:\/\/localhost\/notes"},"note":{"href":"http:\/\/localhost\/notes\/{id}","templated":true}}}', $response->getContent()); + + // list + $this->createNote($client, 'my note for list'); + + $client->request('GET', '/notes.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"notes":[{"secret":"XXX","message":"my note for list","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}],"limit":5,"_links":{"self":{"href":"http:\/\/localhost\/notes"},"note":{"href":"http:\/\/localhost\/notes\/{id}","templated":true}}}', $contentWithoutSecret); + } + + public function testGetNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + } + + public function testGetNoteVersioned() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json;version=1.0')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json;version=1.2')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1.1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + } + + public function testNewNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/new.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"children":{"message":{}}}', $response->getContent()); + } + + public function testPostNote() + { + $client = $this->getClient(true); + + $this->createNote($client, 'my note for post'); + + $response = $client->getResponse(); + + $this->assertJsonResponse($response, Response::HTTP_CREATED); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testEditNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0/edit.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for post'); + + $client->request('GET', '/notes/0/edit.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"children":{"message":{}}}', $response->getContent()); + } + + public function testPutShouldModifyANote() + { + $client = $this->getClient(true); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => '' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals(400, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":400,"message":"Validation Failed","errors":{"children":{"message":{"errors":["This value should not be blank."]}}}}', $response->getContent()); + + $this->createNote($client, 'my note for post'); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => 'my note for put' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testPutShouldCreateANote() + { + $client = $this->getClient(true); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => '' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals(400, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":400,"message":"Validation Failed","errors":{"children":{"message":{"errors":["This value should not be blank."]}}}}', $response->getContent()); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => 'my note for put' + ) + )); + $response = $client->getResponse(); + + $this->assertJsonResponse($response, Response::HTTP_CREATED); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testRemoveNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0/remove.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0/remove.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->assertTrue($response->headers->contains('location', 'http://localhost/notes')); + } + + public function testDeleteNote() + { + $client = $this->getClient(true); + + $client->request('DELETE', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->createNote($client, 'my note for get'); + + $client->request('DELETE', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + $this->assertTrue($response->headers->contains('location', 'http://localhost/notes')); + } + + protected function createNote(Client $client, $message) + { + $client->request('POST', '/notes.json', array( + 'note' => array( + 'message' => $message + ) + )); + $response = $client->getResponse(); + $this->assertJsonResponse($response, Response::HTTP_CREATED); + } + + private function getClient($authenticated = false) + { + $params = array(); + if ($authenticated) { + $params = array_merge($params, array( + 'PHP_AUTH_USER' => 'restapi', + 'PHP_AUTH_PW' => 'secretpw', + )); + } + + return static::createClient(array(), $params); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/CourseTest.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/CourseTest.php new file mode 100644 index 00000000..dcae1aff --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/CourseTest.php @@ -0,0 +1,18 @@ +assertEquals(Course::DEFAULT_TITLE, $course->getTitle()); + $this->assertEquals(Course::DEFAULT_LEVEL, $course->getLevel()); + $this->assertEquals(Course::DEFAULT_TYPE, $course->getType()); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/EventTest.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/EventTest.php new file mode 100644 index 00000000..b6fbd4bd --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Tests/Model/EventTest.php @@ -0,0 +1,24 @@ +setName('New name'); + $this->assertEquals('New name', $event->getName()); + } + + public function testItShouldSetADate() + { + $event = new Event('Some name ', new \DateTime()); + $newDate = new \DateTime(); + $event->setDate($newDate); + $this->assertEquals($newDate, $event->getDate()); + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Twig/Extension/DemoExtension.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Twig/Extension/DemoExtension.php new file mode 100644 index 00000000..f1751d49 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Twig/Extension/DemoExtension.php @@ -0,0 +1,81 @@ +loader = $loader; + } + + public function setController($controller) + { + $this->controller = $controller; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return array( + 'code' => new \Twig_Function_Method($this, 'getCode', array('is_safe' => array('html'))), + ); + } + + public function getCode($template) + { + // highlight_string highlights php code only if 'getControllerCode(), true); + $controller = str_replace('<?php    ', '    ', $controller); + + $template = htmlspecialchars($this->getTemplateCode($template), ENT_QUOTES, 'UTF-8'); + + // remove the code block + $template = str_replace('{% set code = code(_self) %}', '', $template); + + return <<Controller Code

+
$controller
+ +

Template Code

+
$template
+EOF; + } + + protected function getControllerCode() + { + $class = get_class($this->controller[0]); + if (class_exists('CG\Core\ClassUtils')) { + $class = ClassUtils::getUserClass($class); + } + + $r = new \ReflectionClass($class); + $m = $r->getMethod($this->controller[1]); + + $code = file($r->getFilename()); + + return ' '.$m->getDocComment()."\n".implode('', array_slice($code, $m->getStartline() - 1, $m->getEndLine() - $m->getStartline() + 1)); + } + + protected function getTemplateCode($template) + { + return $this->loader->getSource($template->getTemplateName()); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'demo'; + } +} diff --git a/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Util/Cache.php b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Util/Cache.php new file mode 100644 index 00000000..f5d901fb --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/src/AppBundle/Util/Cache.php @@ -0,0 +1,23 @@ + + RewriteEngine On + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/app.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the startpage because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) + RewriteCond %{ENV:REDIRECT_STATUS} ^$ + RewriteRule ^app\.php(/(.*)|$) %{CONTEXT_PREFIX}/$2 [R=301,L] + + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule .? - [L] + + # The following rewrites all other queries to the front controller. The + # condition ensures that if you are using Apache aliases to do mass virtual + # hosting, the base path will be prepended to allow proper resolution of the + # app.php file; it will work in non-aliased environments as well, providing + # a safe, one-size fits all solution. + RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ + RewriteRule ^(.*) - [E=BASE:%1] + RewriteRule .? %{ENV:BASE}app.php [L] + + + + + # When mod_rewrite is not available, we instruct a temporary redirect of + # the startpage to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 302 ^/$ /app.php/ + # RedirectTemp cannot be used instead + + diff --git a/exercises/legacy_create_video/base/php-symfony/web/app.php b/exercises/legacy_create_video/base/php-symfony/web/app.php new file mode 100644 index 00000000..33408737 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/web/app.php @@ -0,0 +1,25 @@ +register(true); +*/ + +require_once __DIR__.'/../app/AppKernel.php'; +//require_once __DIR__.'/../app/AppCache.php'; + +$kernel = new AppKernel('prod', false); +//$kernel = new AppCache($kernel); +Request::enableHttpMethodParameterOverride(); +$request = Request::createFromGlobals(); +$response = $kernel->handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/exercises/legacy_create_video/base/php-symfony/web/app_dev.php b/exercises/legacy_create_video/base/php-symfony/web/app_dev.php new file mode 100644 index 00000000..0d64e4f5 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/web/app_dev.php @@ -0,0 +1,27 @@ +handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/exercises/legacy_create_video/base/php-symfony/web/apple-touch-icon.png b/exercises/legacy_create_video/base/php-symfony/web/apple-touch-icon.png new file mode 100644 index 00000000..11f17e6d Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/web/apple-touch-icon.png differ diff --git a/exercises/legacy_create_video/base/php-symfony/web/config.php b/exercises/legacy_create_video/base/php-symfony/web/config.php new file mode 100644 index 00000000..74d052ac --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/web/config.php @@ -0,0 +1,128 @@ +getFailedRequirements(); +$minorProblems = $symfonyRequirements->getFailedRecommendations(); + +?> + + + + + + Symfony Configuration + + + + + +
+
+ + + +
+ +
+
+
+

Welcome!

+

Welcome to your new Symfony project.

+

+ This script will guide you through the basic configuration of your project. + You can also do the same by editing the ‘app/config/parameters.yml’ file directly. +

+ + +

Major problems

+

Major problems have been detected and must be fixed before continuing:

+
    + +
  1. getTestMessage() ?> +

    getHelpHtml() ?>

    +
  2. + +
+ + + +

Recommendations

+

+ Additionally, toTo enhance your Symfony experience, + it’s recommended that you fix the following: +

+
    + +
  1. getTestMessage() ?> +

    getHelpHtml() ?>

    +
  2. + +
+ + + hasPhpIniConfigIssue()): ?> +

* + getPhpIniConfigPath()): ?> + Changes to the php.ini file must be done in "getPhpIniConfigPath() ?>". + + To change settings, create a "php.ini". + +

+ + + +

Your configuration looks good to run Symfony.

+ + + +
+
+
+
Symfony Standard Edition
+
+ + diff --git a/exercises/legacy_create_video/base/php-symfony/web/favicon.ico b/exercises/legacy_create_video/base/php-symfony/web/favicon.ico new file mode 100644 index 00000000..86480361 Binary files /dev/null and b/exercises/legacy_create_video/base/php-symfony/web/favicon.ico differ diff --git a/exercises/legacy_create_video/base/php-symfony/web/robots.txt b/exercises/legacy_create_video/base/php-symfony/web/robots.txt new file mode 100644 index 00000000..214e4119 --- /dev/null +++ b/exercises/legacy_create_video/base/php-symfony/web/robots.txt @@ -0,0 +1,4 @@ +# www.robotstxt.org/ +# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 + +User-agent: * diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.gitignore b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.gitignore new file mode 100644 index 00000000..b67f201b --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.gitignore @@ -0,0 +1,8 @@ +/web/bundles/ +/app/cache/* +/app/logs/* +/build/ +/vendor/ +/bin/ +/composer.phar +app/config/parameters.yml diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.travis.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.travis.yml new file mode 100644 index 00000000..6dec8cee --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/.travis.yml @@ -0,0 +1,22 @@ +language: php + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +php: + - 5.5 + - 5.6 + - 7.0 + - hhvm + +before_install: + - composer self-update + +install: composer update $COMPOSER_FLAGS --prefer-dist + +after_failure: "cat /home/travis/build/gimler/symfony-rest-edition/app/logs/test.log" + +script: phpunit -c app diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/Dockerfile b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/Dockerfile new file mode 100644 index 00000000..de614991 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/Dockerfile @@ -0,0 +1,14 @@ +FROM composer:latest as composer + +FROM php:7.2-fpm + +RUN apt-get update && apt-get install -y \ + zlib1g-dev \ + libzip-dev \ + unzip + +RUN docker-php-ext-install pdo_mysql && docker-php-ext-enable pdo_mysql + +RUN pecl install xdebug && docker-php-ext-enable xdebug + +COPY --from=composer /usr/bin/composer /usr/bin/composer \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/LICENSE b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/LICENSE new file mode 100644 index 00000000..88a57f8d --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2013 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/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/README.md b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/README.md new file mode 100644 index 00000000..478c0c67 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/README.md @@ -0,0 +1,32 @@ + + + +> Keep it simple :) + +[![CodelyTV](https://img.shields.io/badge/code-codely-green.svg?style=flat-square)](codely.tv) + +**CodelyTv** is the way to rediscover the programming ;) Trusted by more than 1000 youtube subscribers. + +Trust in **Codely**, trust in **you**. + +## Quick Start +This is a simple demo of a coupled code. + +### 1. Clone this repo +Execute: `git clone https://github.com/CodelyTV/coupled-code-example` + +### 2. Install all the dependencies +Composer is used to handle the dependencies. You can download it executing: +`curl -sS https://getcomposer.org/installer | php` + +And then you can install all the dependencies executing: +`php composer.phar install` + +### 3. Run the tests! +Once you have all the dependencies, in order to execute the tests, run this command: +`bin/phpunit` + +## Extra +This code was show in the [From framework coupled code to #microservices through #DDD](http://codely.tv/screencasts/codigo-acoplado-framework-microservicios-ddd) talk. + +You have the *CQRS* version of the code [here](https://github.com/CodelyTV/cqrs-ddd-example) diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/.htaccess b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/AppCache.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/AppCache.php new file mode 100644 index 00000000..ddb51db0 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/AppCache.php @@ -0,0 +1,9 @@ +getEnvironment(), array('dev', 'test'))) { + $bundles[] = new AppBundle\AppBundle(); + $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); + $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); + $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); + } + + return $bundles; + } + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/Resources/views/base.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/Resources/views/base.html.twig new file mode 100644 index 00000000..bafd28d3 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/Resources/views/base.html.twig @@ -0,0 +1,13 @@ + + + + + {% block title %}Welcome!{% endblock %} + {% block stylesheets %}{% endblock %} + + + + {% block body %}{% endblock %} + {% block javascripts %}{% endblock %} + + diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/SymfonyRequirements.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/SymfonyRequirements.php new file mode 100644 index 00000000..28b0dcdb --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/SymfonyRequirements.php @@ -0,0 +1,764 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/* + * Users of PHP 5.2 should be able to run the requirements checks. + * This is why the file and all classes must be compatible with PHP 5.2+ + * (e.g. not using namespaces and closures). + * + * ************** CAUTION ************** + * + * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of + * the installation/update process. The original file resides in the + * SensioDistributionBundle. + * + * ************** CAUTION ************** + */ + +/** + * Represents a single PHP requirement, e.g. an installed extension. + * It can be a mandatory requirement or an optional recommendation. + * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. + * + * @author Tobias Schultze + */ +class Requirement +{ + private $fulfilled; + private $testMessage; + private $helpText; + private $helpHtml; + private $optional; + + /** + * Constructor that initializes the requirement. + * + * @param bool $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) + { + $this->fulfilled = (bool) $fulfilled; + $this->testMessage = (string) $testMessage; + $this->helpHtml = (string) $helpHtml; + $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; + $this->optional = (bool) $optional; + } + + /** + * Returns whether the requirement is fulfilled. + * + * @return bool true if fulfilled, otherwise false + */ + public function isFulfilled() + { + return $this->fulfilled; + } + + /** + * Returns the message for testing the requirement. + * + * @return string The test message + */ + public function getTestMessage() + { + return $this->testMessage; + } + + /** + * Returns the help text for resolving the problem. + * + * @return string The help text + */ + public function getHelpText() + { + return $this->helpText; + } + + /** + * Returns the help text formatted in HTML. + * + * @return string The HTML help + */ + public function getHelpHtml() + { + return $this->helpHtml; + } + + /** + * Returns whether this is only an optional recommendation and not a mandatory requirement. + * + * @return bool true if optional, false if mandatory + */ + public function isOptional() + { + return $this->optional; + } +} + +/** + * Represents a PHP requirement in form of a php.ini configuration. + * + * @author Tobias Schultze + */ +class PhpIniRequirement extends Requirement +{ + /** + * Constructor that initializes the requirement. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement + */ + public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) + { + $cfgValue = ini_get($cfgName); + + if (is_callable($evaluation)) { + if (null === $testMessage || null === $helpHtml) { + throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); + } + + $fulfilled = call_user_func($evaluation, $cfgValue); + } else { + if (null === $testMessage) { + $testMessage = sprintf('%s %s be %s in php.ini', + $cfgName, + $optional ? 'should' : 'must', + $evaluation ? 'enabled' : 'disabled' + ); + } + + if (null === $helpHtml) { + $helpHtml = sprintf('Set %s to %s in php.ini*.', + $cfgName, + $evaluation ? 'on' : 'off' + ); + } + + $fulfilled = $evaluation == $cfgValue; + } + + parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); + } +} + +/** + * A RequirementCollection represents a set of Requirement instances. + * + * @author Tobias Schultze + */ +class RequirementCollection implements IteratorAggregate +{ + private $requirements = array(); + + /** + * Gets the current RequirementCollection as an Iterator. + * + * @return Traversable A Traversable interface + */ + public function getIterator() + { + return new ArrayIterator($this->requirements); + } + + /** + * Adds a Requirement. + * + * @param Requirement $requirement A Requirement instance + */ + public function add(Requirement $requirement) + { + $this->requirements[] = $requirement; + } + + /** + * Adds a mandatory requirement. + * + * @param bool $fulfilled Whether the requirement is fulfilled + * @param string $testMessage The message for testing the requirement + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation. + * + * @param bool $fulfilled Whether the recommendation is fulfilled + * @param string $testMessage The message for testing the recommendation + * @param string $helpHtml The help text formatted in HTML for resolving the problem + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) + { + $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a mandatory requirement in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); + } + + /** + * Adds an optional recommendation in form of a php.ini configuration. + * + * @param string $cfgName The configuration name used for ini_get() + * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, + * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement + * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. + * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. + * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. + * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) + * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) + * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) + */ + public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) + { + $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); + } + + /** + * Adds a requirement collection to the current set of requirements. + * + * @param RequirementCollection $collection A RequirementCollection instance + */ + public function addCollection(RequirementCollection $collection) + { + $this->requirements = array_merge($this->requirements, $collection->all()); + } + + /** + * Returns both requirements and recommendations. + * + * @return array Array of Requirement instances + */ + public function all() + { + return $this->requirements; + } + + /** + * Returns all mandatory requirements. + * + * @return array Array of Requirement instances + */ + public function getRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the mandatory requirements that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRequirements() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && !$req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns all optional recommendations. + * + * @return array Array of Requirement instances + */ + public function getRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if ($req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns the recommendations that were not met. + * + * @return array Array of Requirement instances + */ + public function getFailedRecommendations() + { + $array = array(); + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req->isOptional()) { + $array[] = $req; + } + } + + return $array; + } + + /** + * Returns whether a php.ini configuration is not correct. + * + * @return bool php.ini configuration problem? + */ + public function hasPhpIniConfigIssue() + { + foreach ($this->requirements as $req) { + if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { + return true; + } + } + + return false; + } + + /** + * Returns the PHP configuration file (php.ini) path. + * + * @return string|false php.ini file path + */ + public function getPhpIniConfigPath() + { + return get_cfg_var('cfg_file_path'); + } +} + +/** + * This class specifies all requirements and optional recommendations that + * are necessary to run the Symfony Standard Edition. + * + * @author Tobias Schultze + * @author Fabien Potencier + */ +class SymfonyRequirements extends RequirementCollection +{ + const REQUIRED_PHP_VERSION = '5.3.3'; + + /** + * Constructor that initializes the requirements. + */ + public function __construct() + { + /* mandatory requirements follow */ + + $installedPhpVersion = phpversion(); + + $this->addRequirement( + version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='), + sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion), + sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. + Before using Symfony, upgrade your PHP installation, preferably to the latest version.', + $installedPhpVersion, self::REQUIRED_PHP_VERSION), + sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion) + ); + + $this->addRequirement( + version_compare($installedPhpVersion, '5.3.16', '!='), + 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it', + 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)' + ); + + $this->addRequirement( + is_dir(__DIR__.'/../vendor/composer'), + 'Vendor libraries must be installed', + 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. '. + 'Then run "php composer.phar install" to install them.' + ); + + $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache'; + + $this->addRequirement( + is_writable($cacheDir), + 'app/cache/ or var/cache/ directory must be writable', + 'Change the permissions of either "app/cache/" or "var/cache/" directory so that the web server can write into it.' + ); + + $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs'; + + $this->addRequirement( + is_writable($logsDir), + 'app/logs/ or var/logs/ directory must be writable', + 'Change the permissions of either "app/logs/" or "var/logs/" directory so that the web server can write into it.' + ); + + $this->addPhpIniRequirement( + 'date.timezone', true, false, + 'date.timezone setting must be set', + 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' + ); + + if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { + $timezones = array(); + foreach (DateTimeZone::listAbbreviations() as $abbreviations) { + foreach ($abbreviations as $abbreviation) { + $timezones[$abbreviation['timezone_id']] = true; + } + } + + $this->addRequirement( + isset($timezones[@date_default_timezone_get()]), + sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()), + 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.' + ); + } + + $this->addRequirement( + function_exists('iconv'), + 'iconv() must be available', + 'Install and enable the iconv extension.' + ); + + $this->addRequirement( + function_exists('json_encode'), + 'json_encode() must be available', + 'Install and enable the JSON extension.' + ); + + $this->addRequirement( + function_exists('session_start'), + 'session_start() must be available', + 'Install and enable the session extension.' + ); + + $this->addRequirement( + function_exists('ctype_alpha'), + 'ctype_alpha() must be available', + 'Install and enable the ctype extension.' + ); + + $this->addRequirement( + function_exists('token_get_all'), + 'token_get_all() must be available', + 'Install and enable the Tokenizer extension.' + ); + + $this->addRequirement( + function_exists('simplexml_import_dom'), + 'simplexml_import_dom() must be available', + 'Install and enable the SimpleXML extension.' + ); + + if (function_exists('apc_store') && ini_get('apc.enabled')) { + if (version_compare($installedPhpVersion, '5.4.0', '>=')) { + $this->addRequirement( + version_compare(phpversion('apc'), '3.1.13', '>='), + 'APC version must be at least 3.1.13 when using PHP 5.4', + 'Upgrade your APC extension (3.1.13+).' + ); + } else { + $this->addRequirement( + version_compare(phpversion('apc'), '3.0.17', '>='), + 'APC version must be at least 3.0.17', + 'Upgrade your APC extension (3.0.17+).' + ); + } + } + + $this->addPhpIniRequirement('detect_unicode', false); + + if (extension_loaded('suhosin')) { + $this->addPhpIniRequirement( + 'suhosin.executor.include.whitelist', + create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), + false, + 'suhosin.executor.include.whitelist must be configured correctly in php.ini', + 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' + ); + } + + if (extension_loaded('xdebug')) { + $this->addPhpIniRequirement( + 'xdebug.show_exception_trace', false, true + ); + + $this->addPhpIniRequirement( + 'xdebug.scream', false, true + ); + + $this->addPhpIniRecommendation( + 'xdebug.max_nesting_level', + create_function('$cfgValue', 'return $cfgValue > 100;'), + true, + 'xdebug.max_nesting_level should be above 100 in php.ini', + 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.' + ); + } + + $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; + + $this->addRequirement( + null !== $pcreVersion, + 'PCRE extension must be available', + 'Install the PCRE extension (version 8.0+).' + ); + + if (extension_loaded('mbstring')) { + $this->addPhpIniRequirement( + 'mbstring.func_overload', + create_function('$cfgValue', 'return (int) $cfgValue === 0;'), + true, + 'string functions should not be overloaded', + 'Set "mbstring.func_overload" to 0 in php.ini* to disable function overloading by the mbstring extension.' + ); + } + + /* optional recommendations follow */ + + if (file_exists(__DIR__.'/../vendor/composer')) { + require_once __DIR__.'/../vendor/autoload.php'; + + try { + $r = new ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle'); + + $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php'); + } catch (ReflectionException $e) { + $contents = ''; + } + $this->addRecommendation( + file_get_contents(__FILE__) === $contents, + 'Requirements file should be up-to-date', + 'Your requirements file is outdated. Run composer install and re-check your configuration.' + ); + } + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.3.4', '>='), + 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', + 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.3.8', '>='), + 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', + 'Install PHP 5.3.8 or newer if your project uses annotations.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.4.0', '!='), + 'You should not use PHP 5.4.0 due to the PHP bug #61453', + 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' + ); + + $this->addRecommendation( + version_compare($installedPhpVersion, '5.4.11', '>='), + 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)', + 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' + ); + + $this->addRecommendation( + (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) + || + version_compare($installedPhpVersion, '5.4.8', '>='), + 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909', + 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' + ); + + if (null !== $pcreVersion) { + $this->addRecommendation( + $pcreVersion >= 8.0, + sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), + 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' + ); + } + + $this->addRecommendation( + class_exists('DomDocument'), + 'PHP-DOM and PHP-XML modules should be installed', + 'Install and enable the PHP-DOM and the PHP-XML modules.' + ); + + $this->addRecommendation( + function_exists('mb_strlen'), + 'mb_strlen() should be available', + 'Install and enable the mbstring extension.' + ); + + $this->addRecommendation( + function_exists('iconv'), + 'iconv() should be available', + 'Install and enable the iconv extension.' + ); + + $this->addRecommendation( + function_exists('utf8_decode'), + 'utf8_decode() should be available', + 'Install and enable the XML extension.' + ); + + $this->addRecommendation( + function_exists('filter_var'), + 'filter_var() should be available', + 'Install and enable the filter extension.' + ); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->addRecommendation( + function_exists('posix_isatty'), + 'posix_isatty() should be available', + 'Install and enable the php_posix extension (used to colorize the CLI output).' + ); + } + + $this->addRecommendation( + extension_loaded('intl'), + 'intl extension should be available', + 'Install and enable the intl extension (used for validators).' + ); + + if (extension_loaded('intl')) { + // in some WAMP server installations, new Collator() returns null + $this->addRecommendation( + null !== new Collator('fr_FR'), + 'intl extension should be correctly configured', + 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' + ); + + // check for compatible ICU versions (only done when you have the intl extension) + if (defined('INTL_ICU_VERSION')) { + $version = INTL_ICU_VERSION; + } else { + $reflector = new ReflectionExtension('intl'); + + ob_start(); + $reflector->info(); + $output = strip_tags(ob_get_clean()); + + preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); + $version = $matches[1]; + } + + $this->addRecommendation( + version_compare($version, '4.0', '>='), + 'intl ICU version should be at least 4+', + 'Upgrade your intl extension with a newer ICU version (4+).' + ); + + $this->addPhpIniRecommendation( + 'intl.error_level', + create_function('$cfgValue', 'return (int) $cfgValue === 0;'), + true, + 'intl.error_level should be 0 in php.ini', + 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.' + ); + } + + $accelerator = + (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) + || + (extension_loaded('apc') && ini_get('apc.enabled')) + || + (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable')) + || + (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) + || + (extension_loaded('xcache') && ini_get('xcache.cacher')) + || + (extension_loaded('wincache') && ini_get('wincache.ocenabled')) + ; + + $this->addRecommendation( + $accelerator, + 'a PHP accelerator should be installed', + 'Install and/or enable a PHP accelerator (highly recommended).' + ); + + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { + $this->addRecommendation( + $this->getRealpathCacheSize() > 1000, + 'realpath_cache_size should be above 1024 in php.ini', + 'Set "realpath_cache_size" to e.g. "1024" in php.ini* to improve performance on windows.' + ); + } + + $this->addPhpIniRecommendation('short_open_tag', false); + + $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); + + $this->addPhpIniRecommendation('register_globals', false, true); + + $this->addPhpIniRecommendation('session.auto_start', false); + + $this->addRecommendation( + class_exists('PDO'), + 'PDO should be installed', + 'Install PDO (mandatory for Doctrine).' + ); + + if (class_exists('PDO')) { + $drivers = PDO::getAvailableDrivers(); + $this->addRecommendation( + count($drivers) > 0, + sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), + 'Install PDO drivers (mandatory for Doctrine).' + ); + } + } + + /** + * Loads realpath_cache_size from php.ini and converts it to int. + * + * (e.g. 16k is converted to 16384 int) + * + * @return int + */ + protected function getRealpathCacheSize() + { + $size = ini_get('realpath_cache_size'); + $size = trim($size); + $unit = strtolower(substr($size, -1, 1)); + switch ($unit) { + case 'g': + return $size * 1024 * 1024 * 1024; + case 'm': + return $size * 1024 * 1024; + case 'k': + return $size * 1024; + default: + return (int) $size; + } + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/autoload.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/autoload.php new file mode 100644 index 00000000..75069ac3 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/autoload.php @@ -0,0 +1,14 @@ +parameters = $parameters; +} +public function all() +{ +return $this->parameters; +} +public function keys() +{ +return array_keys($this->parameters); +} +public function replace(array $parameters = array()) +{ +$this->parameters = $parameters; +} +public function add(array $parameters = array()) +{ +$this->parameters = array_replace($this->parameters, $parameters); +} +public function get($path, $default = null, $deep = false) +{ +if (!$deep || false === $pos = strpos($path,'[')) { +return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default; +} +$root = substr($path, 0, $pos); +if (!array_key_exists($root, $this->parameters)) { +return $default; +} +$value = $this->parameters[$root]; +$currentKey = null; +for ($i = $pos, $c = strlen($path); $i < $c; ++$i) { +$char = $path[$i]; +if ('['=== $char) { +if (null !== $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); +} +$currentKey =''; +} elseif (']'=== $char) { +if (null === $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); +} +if (!is_array($value) || !array_key_exists($currentKey, $value)) { +return $default; +} +$value = $value[$currentKey]; +$currentKey = null; +} else { +if (null === $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); +} +$currentKey .= $char; +} +} +if (null !== $currentKey) { +throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); +} +return $value; +} +public function set($key, $value) +{ +$this->parameters[$key] = $value; +} +public function has($key) +{ +return array_key_exists($key, $this->parameters); +} +public function remove($key) +{ +unset($this->parameters[$key]); +} +public function getAlpha($key, $default ='', $deep = false) +{ +return preg_replace('/[^[:alpha:]]/','', $this->get($key, $default, $deep)); +} +public function getAlnum($key, $default ='', $deep = false) +{ +return preg_replace('/[^[:alnum:]]/','', $this->get($key, $default, $deep)); +} +public function getDigits($key, $default ='', $deep = false) +{ +return str_replace(array('-','+'),'', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT)); +} +public function getInt($key, $default = 0, $deep = false) +{ +return (int) $this->get($key, $default, $deep); +} +public function getBoolean($key, $default = false, $deep = false) +{ +return $this->filter($key, $default, $deep, FILTER_VALIDATE_BOOLEAN); +} +public function filter($key, $default = null, $deep = false, $filter = FILTER_DEFAULT, $options = array()) +{ +$value = $this->get($key, $default, $deep); +if (!is_array($options) && $options) { +$options = array('flags'=> $options); +} +if (is_array($value) && !isset($options['flags'])) { +$options['flags'] = FILTER_REQUIRE_ARRAY; +} +return filter_var($value, $filter, $options); +} +public function getIterator() +{ +return new \ArrayIterator($this->parameters); +} +public function count() +{ +return count($this->parameters); +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class HeaderBag implements \IteratorAggregate, \Countable +{ +protected $headers = array(); +protected $cacheControl = array(); +public function __construct(array $headers = array()) +{ +foreach ($headers as $key => $values) { +$this->set($key, $values); +} +} +public function __toString() +{ +if (!$this->headers) { +return''; +} +$max = max(array_map('strlen', array_keys($this->headers))) + 1; +$content =''; +ksort($this->headers); +foreach ($this->headers as $name => $values) { +$name = implode('-', array_map('ucfirst', explode('-', $name))); +foreach ($values as $value) { +$content .= sprintf("%-{$max}s %s\r\n", $name.':', $value); +} +} +return $content; +} +public function all() +{ +return $this->headers; +} +public function keys() +{ +return array_keys($this->headers); +} +public function replace(array $headers = array()) +{ +$this->headers = array(); +$this->add($headers); +} +public function add(array $headers) +{ +foreach ($headers as $key => $values) { +$this->set($key, $values); +} +} +public function get($key, $default = null, $first = true) +{ +$key = str_replace('_','-', strtolower($key)); +if (!array_key_exists($key, $this->headers)) { +if (null === $default) { +return $first ? null : array(); +} +return $first ? $default : array($default); +} +if ($first) { +return count($this->headers[$key]) ? $this->headers[$key][0] : $default; +} +return $this->headers[$key]; +} +public function set($key, $values, $replace = true) +{ +$key = str_replace('_','-', strtolower($key)); +$values = array_values((array) $values); +if (true === $replace || !isset($this->headers[$key])) { +$this->headers[$key] = $values; +} else { +$this->headers[$key] = array_merge($this->headers[$key], $values); +} +if ('cache-control'=== $key) { +$this->cacheControl = $this->parseCacheControl($values[0]); +} +} +public function has($key) +{ +return array_key_exists(str_replace('_','-', strtolower($key)), $this->headers); +} +public function contains($key, $value) +{ +return in_array($value, $this->get($key, null, false)); +} +public function remove($key) +{ +$key = str_replace('_','-', strtolower($key)); +unset($this->headers[$key]); +if ('cache-control'=== $key) { +$this->cacheControl = array(); +} +} +public function getDate($key, \DateTime $default = null) +{ +if (null === $value = $this->get($key)) { +return $default; +} +if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { +throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value)); +} +return $date; +} +public function addCacheControlDirective($key, $value = true) +{ +$this->cacheControl[$key] = $value; +$this->set('Cache-Control', $this->getCacheControlHeader()); +} +public function hasCacheControlDirective($key) +{ +return array_key_exists($key, $this->cacheControl); +} +public function getCacheControlDirective($key) +{ +return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; +} +public function removeCacheControlDirective($key) +{ +unset($this->cacheControl[$key]); +$this->set('Cache-Control', $this->getCacheControlHeader()); +} +public function getIterator() +{ +return new \ArrayIterator($this->headers); +} +public function count() +{ +return count($this->headers); +} +protected function getCacheControlHeader() +{ +$parts = array(); +ksort($this->cacheControl); +foreach ($this->cacheControl as $key => $value) { +if (true === $value) { +$parts[] = $key; +} else { +if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { +$value ='"'.$value.'"'; +} +$parts[] = "$key=$value"; +} +} +return implode(', ', $parts); +} +protected function parseCacheControl($header) +{ +$cacheControl = array(); +preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER); +foreach ($matches as $match) { +$cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true); +} +return $cacheControl; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +use Symfony\Component\HttpFoundation\File\UploadedFile; +class FileBag extends ParameterBag +{ +private static $fileKeys = array('error','name','size','tmp_name','type'); +public function __construct(array $parameters = array()) +{ +$this->replace($parameters); +} +public function replace(array $files = array()) +{ +$this->parameters = array(); +$this->add($files); +} +public function set($key, $value) +{ +if (!is_array($value) && !$value instanceof UploadedFile) { +throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.'); +} +parent::set($key, $this->convertFileInformation($value)); +} +public function add(array $files = array()) +{ +foreach ($files as $key => $file) { +$this->set($key, $file); +} +} +protected function convertFileInformation($file) +{ +if ($file instanceof UploadedFile) { +return $file; +} +$file = $this->fixPhpFilesArray($file); +if (is_array($file)) { +$keys = array_keys($file); +sort($keys); +if ($keys == self::$fileKeys) { +if (UPLOAD_ERR_NO_FILE == $file['error']) { +$file = null; +} else { +$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']); +} +} else { +$file = array_map(array($this,'convertFileInformation'), $file); +} +} +return $file; +} +protected function fixPhpFilesArray($data) +{ +if (!is_array($data)) { +return $data; +} +$keys = array_keys($data); +sort($keys); +if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) { +return $data; +} +$files = $data; +foreach (self::$fileKeys as $k) { +unset($files[$k]); +} +foreach ($data['name'] as $key => $name) { +$files[$key] = $this->fixPhpFilesArray(array('error'=> $data['error'][$key],'name'=> $name,'type'=> $data['type'][$key],'tmp_name'=> $data['tmp_name'][$key],'size'=> $data['size'][$key], +)); +} +return $files; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class ServerBag extends ParameterBag +{ +public function getHeaders() +{ +$headers = array(); +$contentHeaders = array('CONTENT_LENGTH'=> true,'CONTENT_MD5'=> true,'CONTENT_TYPE'=> true); +foreach ($this->parameters as $key => $value) { +if (0 === strpos($key,'HTTP_')) { +$headers[substr($key, 5)] = $value; +} +elseif (isset($contentHeaders[$key])) { +$headers[$key] = $value; +} +} +if (isset($this->parameters['PHP_AUTH_USER'])) { +$headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER']; +$headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] :''; +} else { +$authorizationHeader = null; +if (isset($this->parameters['HTTP_AUTHORIZATION'])) { +$authorizationHeader = $this->parameters['HTTP_AUTHORIZATION']; +} elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) { +$authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION']; +} +if (null !== $authorizationHeader) { +if (0 === stripos($authorizationHeader,'basic ')) { +$exploded = explode(':', base64_decode(substr($authorizationHeader, 6)), 2); +if (count($exploded) == 2) { +list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded; +} +} elseif (empty($this->parameters['PHP_AUTH_DIGEST']) && (0 === stripos($authorizationHeader,'digest '))) { +$headers['PHP_AUTH_DIGEST'] = $authorizationHeader; +$this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader; +} elseif (0 === stripos($authorizationHeader,'bearer ')) { +$headers['AUTHORIZATION'] = $authorizationHeader; +} +} +} +if (isset($headers['AUTHORIZATION'])) { +return $headers; +} +if (isset($headers['PHP_AUTH_USER'])) { +$headers['AUTHORIZATION'] ='Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']); +} elseif (isset($headers['PHP_AUTH_DIGEST'])) { +$headers['AUTHORIZATION'] = $headers['PHP_AUTH_DIGEST']; +} +return $headers; +} +} +} +namespace Symfony\Component\HttpFoundation +{ +use Symfony\Component\HttpFoundation\Session\SessionInterface; +class Request +{ +const HEADER_FORWARDED ='forwarded'; +const HEADER_CLIENT_IP ='client_ip'; +const HEADER_CLIENT_HOST ='client_host'; +const HEADER_CLIENT_PROTO ='client_proto'; +const HEADER_CLIENT_PORT ='client_port'; +const METHOD_HEAD ='HEAD'; +const METHOD_GET ='GET'; +const METHOD_POST ='POST'; +const METHOD_PUT ='PUT'; +const METHOD_PATCH ='PATCH'; +const METHOD_DELETE ='DELETE'; +const METHOD_PURGE ='PURGE'; +const METHOD_OPTIONS ='OPTIONS'; +const METHOD_TRACE ='TRACE'; +const METHOD_CONNECT ='CONNECT'; +protected static $trustedProxies = array(); +protected static $trustedHostPatterns = array(); +protected static $trustedHosts = array(); +protected static $trustedHeaders = array( +self::HEADER_FORWARDED =>'FORWARDED', +self::HEADER_CLIENT_IP =>'X_FORWARDED_FOR', +self::HEADER_CLIENT_HOST =>'X_FORWARDED_HOST', +self::HEADER_CLIENT_PROTO =>'X_FORWARDED_PROTO', +self::HEADER_CLIENT_PORT =>'X_FORWARDED_PORT', +); +protected static $httpMethodParameterOverride = false; +public $attributes; +public $request; +public $query; +public $server; +public $files; +public $cookies; +public $headers; +protected $content; +protected $languages; +protected $charsets; +protected $encodings; +protected $acceptableContentTypes; +protected $pathInfo; +protected $requestUri; +protected $baseUrl; +protected $basePath; +protected $method; +protected $format; +protected $session; +protected $locale; +protected $defaultLocale ='en'; +protected static $formats; +protected static $requestFactory; +public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content); +} +public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +$this->request = new ParameterBag($request); +$this->query = new ParameterBag($query); +$this->attributes = new ParameterBag($attributes); +$this->cookies = new ParameterBag($cookies); +$this->files = new FileBag($files); +$this->server = new ServerBag($server); +$this->headers = new HeaderBag($this->server->getHeaders()); +$this->content = $content; +$this->languages = null; +$this->charsets = null; +$this->encodings = null; +$this->acceptableContentTypes = null; +$this->pathInfo = null; +$this->requestUri = null; +$this->baseUrl = null; +$this->basePath = null; +$this->method = null; +$this->format = null; +} +public static function createFromGlobals() +{ +$server = $_SERVER; +if ('cli-server'=== PHP_SAPI) { +if (array_key_exists('HTTP_CONTENT_LENGTH', $_SERVER)) { +$server['CONTENT_LENGTH'] = $_SERVER['HTTP_CONTENT_LENGTH']; +} +if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) { +$server['CONTENT_TYPE'] = $_SERVER['HTTP_CONTENT_TYPE']; +} +} +$request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server); +if (0 === strpos($request->headers->get('CONTENT_TYPE'),'application/x-www-form-urlencoded') +&& in_array(strtoupper($request->server->get('REQUEST_METHOD','GET')), array('PUT','DELETE','PATCH')) +) { +parse_str($request->getContent(), $data); +$request->request = new ParameterBag($data); +} +return $request; +} +public static function create($uri, $method ='GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null) +{ +$server = array_replace(array('SERVER_NAME'=>'localhost','SERVER_PORT'=> 80,'HTTP_HOST'=>'localhost','HTTP_USER_AGENT'=>'Symfony/2.X','HTTP_ACCEPT'=>'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','HTTP_ACCEPT_LANGUAGE'=>'en-us,en;q=0.5','HTTP_ACCEPT_CHARSET'=>'ISO-8859-1,utf-8;q=0.7,*;q=0.7','REMOTE_ADDR'=>'127.0.0.1','SCRIPT_NAME'=>'','SCRIPT_FILENAME'=>'','SERVER_PROTOCOL'=>'HTTP/1.1','REQUEST_TIME'=> time(), +), $server); +$server['PATH_INFO'] =''; +$server['REQUEST_METHOD'] = strtoupper($method); +$components = parse_url($uri); +if (isset($components['host'])) { +$server['SERVER_NAME'] = $components['host']; +$server['HTTP_HOST'] = $components['host']; +} +if (isset($components['scheme'])) { +if ('https'=== $components['scheme']) { +$server['HTTPS'] ='on'; +$server['SERVER_PORT'] = 443; +} else { +unset($server['HTTPS']); +$server['SERVER_PORT'] = 80; +} +} +if (isset($components['port'])) { +$server['SERVER_PORT'] = $components['port']; +$server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port']; +} +if (isset($components['user'])) { +$server['PHP_AUTH_USER'] = $components['user']; +} +if (isset($components['pass'])) { +$server['PHP_AUTH_PW'] = $components['pass']; +} +if (!isset($components['path'])) { +$components['path'] ='/'; +} +switch (strtoupper($method)) { +case'POST': +case'PUT': +case'DELETE': +if (!isset($server['CONTENT_TYPE'])) { +$server['CONTENT_TYPE'] ='application/x-www-form-urlencoded'; +} +case'PATCH': +$request = $parameters; +$query = array(); +break; +default: +$request = array(); +$query = $parameters; +break; +} +$queryString =''; +if (isset($components['query'])) { +parse_str(html_entity_decode($components['query']), $qs); +if ($query) { +$query = array_replace($qs, $query); +$queryString = http_build_query($query,'','&'); +} else { +$query = $qs; +$queryString = $components['query']; +} +} elseif ($query) { +$queryString = http_build_query($query,'','&'); +} +$server['REQUEST_URI'] = $components['path'].(''!== $queryString ?'?'.$queryString :''); +$server['QUERY_STRING'] = $queryString; +return self::createRequestFromFactory($query, $request, array(), $cookies, $files, $server, $content); +} +public static function setFactory($callable) +{ +self::$requestFactory = $callable; +} +public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) +{ +$dup = clone $this; +if ($query !== null) { +$dup->query = new ParameterBag($query); +} +if ($request !== null) { +$dup->request = new ParameterBag($request); +} +if ($attributes !== null) { +$dup->attributes = new ParameterBag($attributes); +} +if ($cookies !== null) { +$dup->cookies = new ParameterBag($cookies); +} +if ($files !== null) { +$dup->files = new FileBag($files); +} +if ($server !== null) { +$dup->server = new ServerBag($server); +$dup->headers = new HeaderBag($dup->server->getHeaders()); +} +$dup->languages = null; +$dup->charsets = null; +$dup->encodings = null; +$dup->acceptableContentTypes = null; +$dup->pathInfo = null; +$dup->requestUri = null; +$dup->baseUrl = null; +$dup->basePath = null; +$dup->method = null; +$dup->format = null; +if (!$dup->get('_format') && $this->get('_format')) { +$dup->attributes->set('_format', $this->get('_format')); +} +if (!$dup->getRequestFormat(null)) { +$dup->setRequestFormat($this->getRequestFormat(null)); +} +return $dup; +} +public function __clone() +{ +$this->query = clone $this->query; +$this->request = clone $this->request; +$this->attributes = clone $this->attributes; +$this->cookies = clone $this->cookies; +$this->files = clone $this->files; +$this->server = clone $this->server; +$this->headers = clone $this->headers; +} +public function __toString() +{ +try { +$content = $this->getContent(); +} catch (\LogicException $e) { +return trigger_error($e, E_USER_ERROR); +} +return +sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n". +$this->headers."\r\n". +$content; +} +public function overrideGlobals() +{ +$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null,'&'))); +$_GET = $this->query->all(); +$_POST = $this->request->all(); +$_SERVER = $this->server->all(); +$_COOKIE = $this->cookies->all(); +foreach ($this->headers->all() as $key => $value) { +$key = strtoupper(str_replace('-','_', $key)); +if (in_array($key, array('CONTENT_TYPE','CONTENT_LENGTH'))) { +$_SERVER[$key] = implode(', ', $value); +} else { +$_SERVER['HTTP_'.$key] = implode(', ', $value); +} +} +$request = array('g'=> $_GET,'p'=> $_POST,'c'=> $_COOKIE); +$requestOrder = ini_get('request_order') ?: ini_get('variables_order'); +$requestOrder = preg_replace('#[^cgp]#','', strtolower($requestOrder)) ?:'gp'; +$_REQUEST = array(); +foreach (str_split($requestOrder) as $order) { +$_REQUEST = array_merge($_REQUEST, $request[$order]); +} +} +public static function setTrustedProxies(array $proxies) +{ +self::$trustedProxies = $proxies; +} +public static function getTrustedProxies() +{ +return self::$trustedProxies; +} +public static function setTrustedHosts(array $hostPatterns) +{ +self::$trustedHostPatterns = array_map(function ($hostPattern) { +return sprintf('#%s#i', $hostPattern); +}, $hostPatterns); +self::$trustedHosts = array(); +} +public static function getTrustedHosts() +{ +return self::$trustedHostPatterns; +} +public static function setTrustedHeaderName($key, $value) +{ +if (!array_key_exists($key, self::$trustedHeaders)) { +throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key)); +} +self::$trustedHeaders[$key] = $value; +} +public static function getTrustedHeaderName($key) +{ +if (!array_key_exists($key, self::$trustedHeaders)) { +throw new \InvalidArgumentException(sprintf('Unable to get the trusted header name for key "%s".', $key)); +} +return self::$trustedHeaders[$key]; +} +public static function normalizeQueryString($qs) +{ +if (''== $qs) { +return''; +} +$parts = array(); +$order = array(); +foreach (explode('&', $qs) as $param) { +if (''=== $param ||'='=== $param[0]) { +continue; +} +$keyValuePair = explode('=', $param, 2); +$parts[] = isset($keyValuePair[1]) ? +rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) : +rawurlencode(urldecode($keyValuePair[0])); +$order[] = urldecode($keyValuePair[0]); +} +array_multisort($order, SORT_ASC, $parts); +return implode('&', $parts); +} +public static function enableHttpMethodParameterOverride() +{ +self::$httpMethodParameterOverride = true; +} +public static function getHttpMethodParameterOverride() +{ +return self::$httpMethodParameterOverride; +} +public function get($key, $default = null, $deep = false) +{ +if ($this !== $result = $this->query->get($key, $this, $deep)) { +return $result; +} +if ($this !== $result = $this->attributes->get($key, $this, $deep)) { +return $result; +} +if ($this !== $result = $this->request->get($key, $this, $deep)) { +return $result; +} +return $default; +} +public function getSession() +{ +return $this->session; +} +public function hasPreviousSession() +{ +return $this->hasSession() && $this->cookies->has($this->session->getName()); +} +public function hasSession() +{ +return null !== $this->session; +} +public function setSession(SessionInterface $session) +{ +$this->session = $session; +} +public function getClientIps() +{ +$clientIps = array(); +$ip = $this->server->get('REMOTE_ADDR'); +if (!$this->isFromTrustedProxy()) { +return array($ip); +} +if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { +$forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); +preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); +$clientIps = $matches[3]; +} elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { +$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); +} +$clientIps[] = $ip; $firstTrustedIp = null; +foreach ($clientIps as $key => $clientIp) { +if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) { +$clientIps[$key] = $clientIp = $match[1]; +} +if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { +unset($clientIps[$key]); +continue; +} +if (IpUtils::checkIp($clientIp, self::$trustedProxies)) { +unset($clientIps[$key]); +if (null === $firstTrustedIp) { +$firstTrustedIp = $clientIp; +} +} +} +return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp); +} +public function getClientIp() +{ +$ipAddresses = $this->getClientIps(); +return $ipAddresses[0]; +} +public function getScriptName() +{ +return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME','')); +} +public function getPathInfo() +{ +if (null === $this->pathInfo) { +$this->pathInfo = $this->preparePathInfo(); +} +return $this->pathInfo; +} +public function getBasePath() +{ +if (null === $this->basePath) { +$this->basePath = $this->prepareBasePath(); +} +return $this->basePath; +} +public function getBaseUrl() +{ +if (null === $this->baseUrl) { +$this->baseUrl = $this->prepareBaseUrl(); +} +return $this->baseUrl; +} +public function getScheme() +{ +return $this->isSecure() ?'https':'http'; +} +public function getPort() +{ +if ($this->isFromTrustedProxy()) { +if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { +return $port; +} +if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] &&'https'=== $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO],'http')) { +return 443; +} +} +if ($host = $this->headers->get('HOST')) { +if ($host[0] ==='[') { +$pos = strpos($host,':', strrpos($host,']')); +} else { +$pos = strrpos($host,':'); +} +if (false !== $pos) { +return (int) substr($host, $pos + 1); +} +return'https'=== $this->getScheme() ? 443 : 80; +} +return $this->server->get('SERVER_PORT'); +} +public function getUser() +{ +return $this->headers->get('PHP_AUTH_USER'); +} +public function getPassword() +{ +return $this->headers->get('PHP_AUTH_PW'); +} +public function getUserInfo() +{ +$userinfo = $this->getUser(); +$pass = $this->getPassword(); +if (''!= $pass) { +$userinfo .= ":$pass"; +} +return $userinfo; +} +public function getHttpHost() +{ +$scheme = $this->getScheme(); +$port = $this->getPort(); +if (('http'== $scheme && $port == 80) || ('https'== $scheme && $port == 443)) { +return $this->getHost(); +} +return $this->getHost().':'.$port; +} +public function getRequestUri() +{ +if (null === $this->requestUri) { +$this->requestUri = $this->prepareRequestUri(); +} +return $this->requestUri; +} +public function getSchemeAndHttpHost() +{ +return $this->getScheme().'://'.$this->getHttpHost(); +} +public function getUri() +{ +if (null !== $qs = $this->getQueryString()) { +$qs ='?'.$qs; +} +return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs; +} +public function getUriForPath($path) +{ +return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path; +} +public function getRelativeUriForPath($path) +{ +if (!isset($path[0]) ||'/'!== $path[0]) { +return $path; +} +if ($path === $basePath = $this->getPathInfo()) { +return''; +} +$sourceDirs = explode('/', isset($basePath[0]) &&'/'=== $basePath[0] ? substr($basePath, 1) : $basePath); +$targetDirs = explode('/', isset($path[0]) &&'/'=== $path[0] ? substr($path, 1) : $path); +array_pop($sourceDirs); +$targetFile = array_pop($targetDirs); +foreach ($sourceDirs as $i => $dir) { +if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) { +unset($sourceDirs[$i], $targetDirs[$i]); +} else { +break; +} +} +$targetDirs[] = $targetFile; +$path = str_repeat('../', count($sourceDirs)).implode('/', $targetDirs); +return !isset($path[0]) ||'/'=== $path[0] +|| false !== ($colonPos = strpos($path,':')) && ($colonPos < ($slashPos = strpos($path,'/')) || false === $slashPos) +? "./$path" : $path; +} +public function getQueryString() +{ +$qs = static::normalizeQueryString($this->server->get('QUERY_STRING')); +return''=== $qs ? null : $qs; +} +public function isSecure() +{ +if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { +return in_array(strtolower(current(explode(',', $proto))), array('https','on','ssl','1')); +} +$https = $this->server->get('HTTPS'); +return !empty($https) &&'off'!== strtolower($https); +} +public function getHost() +{ +if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { +$elements = explode(',', $host); +$host = $elements[count($elements) - 1]; +} elseif (!$host = $this->headers->get('HOST')) { +if (!$host = $this->server->get('SERVER_NAME')) { +$host = $this->server->get('SERVER_ADDR',''); +} +} +$host = strtolower(preg_replace('/:\d+$/','', trim($host))); +if ($host &&''!== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/','', $host)) { +throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host)); +} +if (count(self::$trustedHostPatterns) > 0) { +if (in_array($host, self::$trustedHosts)) { +return $host; +} +foreach (self::$trustedHostPatterns as $pattern) { +if (preg_match($pattern, $host)) { +self::$trustedHosts[] = $host; +return $host; +} +} +throw new \UnexpectedValueException(sprintf('Untrusted Host "%s"', $host)); +} +return $host; +} +public function setMethod($method) +{ +$this->method = null; +$this->server->set('REQUEST_METHOD', $method); +} +public function getMethod() +{ +if (null === $this->method) { +$this->method = strtoupper($this->server->get('REQUEST_METHOD','GET')); +if ('POST'=== $this->method) { +if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) { +$this->method = strtoupper($method); +} elseif (self::$httpMethodParameterOverride) { +$this->method = strtoupper($this->request->get('_method', $this->query->get('_method','POST'))); +} +} +} +return $this->method; +} +public function getRealMethod() +{ +return strtoupper($this->server->get('REQUEST_METHOD','GET')); +} +public function getMimeType($format) +{ +if (null === static::$formats) { +static::initializeFormats(); +} +return isset(static::$formats[$format]) ? static::$formats[$format][0] : null; +} +public function getFormat($mimeType) +{ +$canonicalMimeType = null; +if (false !== $pos = strpos($mimeType,';')) { +$canonicalMimeType = substr($mimeType, 0, $pos); +} +if (null === static::$formats) { +static::initializeFormats(); +} +foreach (static::$formats as $format => $mimeTypes) { +if (in_array($mimeType, (array) $mimeTypes)) { +return $format; +} +if (null !== $canonicalMimeType && in_array($canonicalMimeType, (array) $mimeTypes)) { +return $format; +} +} +} +public function setFormat($format, $mimeTypes) +{ +if (null === static::$formats) { +static::initializeFormats(); +} +static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes); +} +public function getRequestFormat($default ='html') +{ +if (null === $this->format) { +$this->format = $this->get('_format', $default); +} +return $this->format; +} +public function setRequestFormat($format) +{ +$this->format = $format; +} +public function getContentType() +{ +return $this->getFormat($this->headers->get('CONTENT_TYPE')); +} +public function setDefaultLocale($locale) +{ +$this->defaultLocale = $locale; +if (null === $this->locale) { +$this->setPhpDefaultLocale($locale); +} +} +public function getDefaultLocale() +{ +return $this->defaultLocale; +} +public function setLocale($locale) +{ +$this->setPhpDefaultLocale($this->locale = $locale); +} +public function getLocale() +{ +return null === $this->locale ? $this->defaultLocale : $this->locale; +} +public function isMethod($method) +{ +return $this->getMethod() === strtoupper($method); +} +public function isMethodSafe() +{ +return in_array($this->getMethod(), array('GET','HEAD')); +} +public function getContent($asResource = false) +{ +$currentContentIsResource = is_resource($this->content); +if (PHP_VERSION_ID < 50600 && false === $this->content) { +throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.'); +} +if (true === $asResource) { +if ($currentContentIsResource) { +rewind($this->content); +return $this->content; +} +if (is_string($this->content)) { +$resource = fopen('php://temp','r+'); +fwrite($resource, $this->content); +rewind($resource); +return $resource; +} +$this->content = false; +return fopen('php://input','rb'); +} +if ($currentContentIsResource) { +rewind($this->content); +return stream_get_contents($this->content); +} +if (null === $this->content) { +$this->content = file_get_contents('php://input'); +} +return $this->content; +} +public function getETags() +{ +return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY); +} +public function isNoCache() +{ +return $this->headers->hasCacheControlDirective('no-cache') ||'no-cache'== $this->headers->get('Pragma'); +} +public function getPreferredLanguage(array $locales = null) +{ +$preferredLanguages = $this->getLanguages(); +if (empty($locales)) { +return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null; +} +if (!$preferredLanguages) { +return $locales[0]; +} +$extendedPreferredLanguages = array(); +foreach ($preferredLanguages as $language) { +$extendedPreferredLanguages[] = $language; +if (false !== $position = strpos($language,'_')) { +$superLanguage = substr($language, 0, $position); +if (!in_array($superLanguage, $preferredLanguages)) { +$extendedPreferredLanguages[] = $superLanguage; +} +} +} +$preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales)); +return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0]; +} +public function getLanguages() +{ +if (null !== $this->languages) { +return $this->languages; +} +$languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all(); +$this->languages = array(); +foreach ($languages as $lang => $acceptHeaderItem) { +if (false !== strpos($lang,'-')) { +$codes = explode('-', $lang); +if ('i'=== $codes[0]) { +if (count($codes) > 1) { +$lang = $codes[1]; +} +} else { +for ($i = 0, $max = count($codes); $i < $max; ++$i) { +if ($i === 0) { +$lang = strtolower($codes[0]); +} else { +$lang .='_'.strtoupper($codes[$i]); +} +} +} +} +$this->languages[] = $lang; +} +return $this->languages; +} +public function getCharsets() +{ +if (null !== $this->charsets) { +return $this->charsets; +} +return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all()); +} +public function getEncodings() +{ +if (null !== $this->encodings) { +return $this->encodings; +} +return $this->encodings = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Encoding'))->all()); +} +public function getAcceptableContentTypes() +{ +if (null !== $this->acceptableContentTypes) { +return $this->acceptableContentTypes; +} +return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all()); +} +public function isXmlHttpRequest() +{ +return'XMLHttpRequest'== $this->headers->get('X-Requested-With'); +} +protected function prepareRequestUri() +{ +$requestUri =''; +if ($this->headers->has('X_ORIGINAL_URL')) { +$requestUri = $this->headers->get('X_ORIGINAL_URL'); +$this->headers->remove('X_ORIGINAL_URL'); +$this->server->remove('HTTP_X_ORIGINAL_URL'); +$this->server->remove('UNENCODED_URL'); +$this->server->remove('IIS_WasUrlRewritten'); +} elseif ($this->headers->has('X_REWRITE_URL')) { +$requestUri = $this->headers->get('X_REWRITE_URL'); +$this->headers->remove('X_REWRITE_URL'); +} elseif ($this->server->get('IIS_WasUrlRewritten') =='1'&& $this->server->get('UNENCODED_URL') !='') { +$requestUri = $this->server->get('UNENCODED_URL'); +$this->server->remove('UNENCODED_URL'); +$this->server->remove('IIS_WasUrlRewritten'); +} elseif ($this->server->has('REQUEST_URI')) { +$requestUri = $this->server->get('REQUEST_URI'); +$schemeAndHttpHost = $this->getSchemeAndHttpHost(); +if (strpos($requestUri, $schemeAndHttpHost) === 0) { +$requestUri = substr($requestUri, strlen($schemeAndHttpHost)); +} +} elseif ($this->server->has('ORIG_PATH_INFO')) { +$requestUri = $this->server->get('ORIG_PATH_INFO'); +if (''!= $this->server->get('QUERY_STRING')) { +$requestUri .='?'.$this->server->get('QUERY_STRING'); +} +$this->server->remove('ORIG_PATH_INFO'); +} +$this->server->set('REQUEST_URI', $requestUri); +return $requestUri; +} +protected function prepareBaseUrl() +{ +$filename = basename($this->server->get('SCRIPT_FILENAME')); +if (basename($this->server->get('SCRIPT_NAME')) === $filename) { +$baseUrl = $this->server->get('SCRIPT_NAME'); +} elseif (basename($this->server->get('PHP_SELF')) === $filename) { +$baseUrl = $this->server->get('PHP_SELF'); +} elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) { +$baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); } else { +$path = $this->server->get('PHP_SELF',''); +$file = $this->server->get('SCRIPT_FILENAME',''); +$segs = explode('/', trim($file,'/')); +$segs = array_reverse($segs); +$index = 0; +$last = count($segs); +$baseUrl =''; +do { +$seg = $segs[$index]; +$baseUrl ='/'.$seg.$baseUrl; +++$index; +} while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos); +} +$requestUri = $this->getRequestUri(); +if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) { +return $prefix; +} +if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl),'/'.DIRECTORY_SEPARATOR).'/')) { +return rtrim($prefix,'/'.DIRECTORY_SEPARATOR); +} +$truncatedRequestUri = $requestUri; +if (false !== $pos = strpos($requestUri,'?')) { +$truncatedRequestUri = substr($requestUri, 0, $pos); +} +$basename = basename($baseUrl); +if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) { +return''; +} +if (strlen($requestUri) >= strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && $pos !== 0) { +$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); +} +return rtrim($baseUrl,'/'.DIRECTORY_SEPARATOR); +} +protected function prepareBasePath() +{ +$filename = basename($this->server->get('SCRIPT_FILENAME')); +$baseUrl = $this->getBaseUrl(); +if (empty($baseUrl)) { +return''; +} +if (basename($baseUrl) === $filename) { +$basePath = dirname($baseUrl); +} else { +$basePath = $baseUrl; +} +if ('\\'=== DIRECTORY_SEPARATOR) { +$basePath = str_replace('\\','/', $basePath); +} +return rtrim($basePath,'/'); +} +protected function preparePathInfo() +{ +$baseUrl = $this->getBaseUrl(); +if (null === ($requestUri = $this->getRequestUri())) { +return'/'; +} +if ($pos = strpos($requestUri,'?')) { +$requestUri = substr($requestUri, 0, $pos); +} +$pathInfo = substr($requestUri, strlen($baseUrl)); +if (null !== $baseUrl && (false === $pathInfo ||''=== $pathInfo)) { +return'/'; +} elseif (null === $baseUrl) { +return $requestUri; +} +return (string) $pathInfo; +} +protected static function initializeFormats() +{ +static::$formats = array('html'=> array('text/html','application/xhtml+xml'),'txt'=> array('text/plain'),'js'=> array('application/javascript','application/x-javascript','text/javascript'),'css'=> array('text/css'),'json'=> array('application/json','application/x-json'),'xml'=> array('text/xml','application/xml','application/x-xml'),'rdf'=> array('application/rdf+xml'),'atom'=> array('application/atom+xml'),'rss'=> array('application/rss+xml'),'form'=> array('application/x-www-form-urlencoded'), +); +} +private function setPhpDefaultLocale($locale) +{ +try { +if (class_exists('Locale', false)) { +\Locale::setDefault($locale); +} +} catch (\Exception $e) { +} +} +private function getUrlencodedPrefix($string, $prefix) +{ +if (0 !== strpos(rawurldecode($string), $prefix)) { +return false; +} +$len = strlen($prefix); +if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) { +return $match[0]; +} +return false; +} +private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) +{ +if (self::$requestFactory) { +$request = call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content); +if (!$request instanceof self) { +throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.'); +} +return $request; +} +return new static($query, $request, $attributes, $cookies, $files, $server, $content); +} +private function isFromTrustedProxy() +{ +return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class Response +{ +const HTTP_CONTINUE = 100; +const HTTP_SWITCHING_PROTOCOLS = 101; +const HTTP_PROCESSING = 102; const HTTP_OK = 200; +const HTTP_CREATED = 201; +const HTTP_ACCEPTED = 202; +const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; +const HTTP_NO_CONTENT = 204; +const HTTP_RESET_CONTENT = 205; +const HTTP_PARTIAL_CONTENT = 206; +const HTTP_MULTI_STATUS = 207; const HTTP_ALREADY_REPORTED = 208; const HTTP_IM_USED = 226; const HTTP_MULTIPLE_CHOICES = 300; +const HTTP_MOVED_PERMANENTLY = 301; +const HTTP_FOUND = 302; +const HTTP_SEE_OTHER = 303; +const HTTP_NOT_MODIFIED = 304; +const HTTP_USE_PROXY = 305; +const HTTP_RESERVED = 306; +const HTTP_TEMPORARY_REDIRECT = 307; +const HTTP_PERMANENTLY_REDIRECT = 308; const HTTP_BAD_REQUEST = 400; +const HTTP_UNAUTHORIZED = 401; +const HTTP_PAYMENT_REQUIRED = 402; +const HTTP_FORBIDDEN = 403; +const HTTP_NOT_FOUND = 404; +const HTTP_METHOD_NOT_ALLOWED = 405; +const HTTP_NOT_ACCEPTABLE = 406; +const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; +const HTTP_REQUEST_TIMEOUT = 408; +const HTTP_CONFLICT = 409; +const HTTP_GONE = 410; +const HTTP_LENGTH_REQUIRED = 411; +const HTTP_PRECONDITION_FAILED = 412; +const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; +const HTTP_REQUEST_URI_TOO_LONG = 414; +const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; +const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; +const HTTP_EXPECTATION_FAILED = 417; +const HTTP_I_AM_A_TEAPOT = 418; const HTTP_MISDIRECTED_REQUEST = 421; const HTTP_UNPROCESSABLE_ENTITY = 422; const HTTP_LOCKED = 423; const HTTP_FAILED_DEPENDENCY = 424; const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; const HTTP_UPGRADE_REQUIRED = 426; const HTTP_PRECONDITION_REQUIRED = 428; const HTTP_TOO_MANY_REQUESTS = 429; const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; +const HTTP_INTERNAL_SERVER_ERROR = 500; +const HTTP_NOT_IMPLEMENTED = 501; +const HTTP_BAD_GATEWAY = 502; +const HTTP_SERVICE_UNAVAILABLE = 503; +const HTTP_GATEWAY_TIMEOUT = 504; +const HTTP_VERSION_NOT_SUPPORTED = 505; +const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; const HTTP_INSUFFICIENT_STORAGE = 507; const HTTP_LOOP_DETECTED = 508; const HTTP_NOT_EXTENDED = 510; const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; +public $headers; +protected $content; +protected $version; +protected $statusCode; +protected $statusText; +protected $charset; +public static $statusTexts = array( +100 =>'Continue', +101 =>'Switching Protocols', +102 =>'Processing', 200 =>'OK', +201 =>'Created', +202 =>'Accepted', +203 =>'Non-Authoritative Information', +204 =>'No Content', +205 =>'Reset Content', +206 =>'Partial Content', +207 =>'Multi-Status', 208 =>'Already Reported', 226 =>'IM Used', 300 =>'Multiple Choices', +301 =>'Moved Permanently', +302 =>'Found', +303 =>'See Other', +304 =>'Not Modified', +305 =>'Use Proxy', +306 =>'Reserved', +307 =>'Temporary Redirect', +308 =>'Permanent Redirect', 400 =>'Bad Request', +401 =>'Unauthorized', +402 =>'Payment Required', +403 =>'Forbidden', +404 =>'Not Found', +405 =>'Method Not Allowed', +406 =>'Not Acceptable', +407 =>'Proxy Authentication Required', +408 =>'Request Timeout', +409 =>'Conflict', +410 =>'Gone', +411 =>'Length Required', +412 =>'Precondition Failed', +413 =>'Request Entity Too Large', +414 =>'Request-URI Too Long', +415 =>'Unsupported Media Type', +416 =>'Requested Range Not Satisfiable', +417 =>'Expectation Failed', +418 =>'I\'m a teapot', 421 =>'Misdirected Request', 422 =>'Unprocessable Entity', 423 =>'Locked', 424 =>'Failed Dependency', 425 =>'Reserved for WebDAV advanced collections expired proposal', 426 =>'Upgrade Required', 428 =>'Precondition Required', 429 =>'Too Many Requests', 431 =>'Request Header Fields Too Large', 451 =>'Unavailable For Legal Reasons', 500 =>'Internal Server Error', +501 =>'Not Implemented', +502 =>'Bad Gateway', +503 =>'Service Unavailable', +504 =>'Gateway Timeout', +505 =>'HTTP Version Not Supported', +506 =>'Variant Also Negotiates (Experimental)', 507 =>'Insufficient Storage', 508 =>'Loop Detected', 510 =>'Not Extended', 511 =>'Network Authentication Required', ); +public function __construct($content ='', $status = 200, $headers = array()) +{ +$this->headers = new ResponseHeaderBag($headers); +$this->setContent($content); +$this->setStatusCode($status); +$this->setProtocolVersion('1.0'); +if (!$this->headers->has('Date')) { +$this->setDate(\DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC'))); +} +} +public static function create($content ='', $status = 200, $headers = array()) +{ +return new static($content, $status, $headers); +} +public function __toString() +{ +return +sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". +$this->headers."\r\n". +$this->getContent(); +} +public function __clone() +{ +$this->headers = clone $this->headers; +} +public function prepare(Request $request) +{ +$headers = $this->headers; +if ($this->isInformational() || $this->isEmpty()) { +$this->setContent(null); +$headers->remove('Content-Type'); +$headers->remove('Content-Length'); +} else { +if (!$headers->has('Content-Type')) { +$format = $request->getRequestFormat(); +if (null !== $format && $mimeType = $request->getMimeType($format)) { +$headers->set('Content-Type', $mimeType); +} +} +$charset = $this->charset ?:'UTF-8'; +if (!$headers->has('Content-Type')) { +$headers->set('Content-Type','text/html; charset='.$charset); +} elseif (0 === stripos($headers->get('Content-Type'),'text/') && false === stripos($headers->get('Content-Type'),'charset')) { +$headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset); +} +if ($headers->has('Transfer-Encoding')) { +$headers->remove('Content-Length'); +} +if ($request->isMethod('HEAD')) { +$length = $headers->get('Content-Length'); +$this->setContent(null); +if ($length) { +$headers->set('Content-Length', $length); +} +} +} +if ('HTTP/1.0'!= $request->server->get('SERVER_PROTOCOL')) { +$this->setProtocolVersion('1.1'); +} +if ('1.0'== $this->getProtocolVersion() &&'no-cache'== $this->headers->get('Cache-Control')) { +$this->headers->set('pragma','no-cache'); +$this->headers->set('expires', -1); +} +$this->ensureIEOverSSLCompatibility($request); +return $this; +} +public function sendHeaders() +{ +if (headers_sent()) { +return $this; +} +foreach ($this->headers->allPreserveCase() as $name => $values) { +foreach ($values as $value) { +header($name.': '.$value, false); +} +} +header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); +foreach ($this->headers->getCookies() as $cookie) { +setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); +} +return $this; +} +public function sendContent() +{ +echo $this->content; +return $this; +} +public function send() +{ +$this->sendHeaders(); +$this->sendContent(); +if (function_exists('fastcgi_finish_request')) { +fastcgi_finish_request(); +} elseif ('cli'!== PHP_SAPI) { +static::closeOutputBuffers(0, true); +} +return $this; +} +public function setContent($content) +{ +if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content,'__toString'))) { +throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content))); +} +$this->content = (string) $content; +return $this; +} +public function getContent() +{ +return $this->content; +} +public function setProtocolVersion($version) +{ +$this->version = $version; +return $this; +} +public function getProtocolVersion() +{ +return $this->version; +} +public function setStatusCode($code, $text = null) +{ +$this->statusCode = $code = (int) $code; +if ($this->isInvalid()) { +throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); +} +if (null === $text) { +$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] :'unknown status'; +return $this; +} +if (false === $text) { +$this->statusText =''; +return $this; +} +$this->statusText = $text; +return $this; +} +public function getStatusCode() +{ +return $this->statusCode; +} +public function setCharset($charset) +{ +$this->charset = $charset; +return $this; +} +public function getCharset() +{ +return $this->charset; +} +public function isCacheable() +{ +if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) { +return false; +} +if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) { +return false; +} +return $this->isValidateable() || $this->isFresh(); +} +public function isFresh() +{ +return $this->getTtl() > 0; +} +public function isValidateable() +{ +return $this->headers->has('Last-Modified') || $this->headers->has('ETag'); +} +public function setPrivate() +{ +$this->headers->removeCacheControlDirective('public'); +$this->headers->addCacheControlDirective('private'); +return $this; +} +public function setPublic() +{ +$this->headers->addCacheControlDirective('public'); +$this->headers->removeCacheControlDirective('private'); +return $this; +} +public function mustRevalidate() +{ +return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->hasCacheControlDirective('proxy-revalidate'); +} +public function getDate() +{ +return $this->headers->getDate('Date', new \DateTime()); +} +public function setDate(\DateTime $date) +{ +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT'); +return $this; +} +public function getAge() +{ +if (null !== $age = $this->headers->get('Age')) { +return (int) $age; +} +return max(time() - $this->getDate()->format('U'), 0); +} +public function expire() +{ +if ($this->isFresh()) { +$this->headers->set('Age', $this->getMaxAge()); +} +return $this; +} +public function getExpires() +{ +try { +return $this->headers->getDate('Expires'); +} catch (\RuntimeException $e) { +return \DateTime::createFromFormat(DATE_RFC2822,'Sat, 01 Jan 00 00:00:00 +0000'); +} +} +public function setExpires(\DateTime $date = null) +{ +if (null === $date) { +$this->headers->remove('Expires'); +} else { +$date = clone $date; +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT'); +} +return $this; +} +public function getMaxAge() +{ +if ($this->headers->hasCacheControlDirective('s-maxage')) { +return (int) $this->headers->getCacheControlDirective('s-maxage'); +} +if ($this->headers->hasCacheControlDirective('max-age')) { +return (int) $this->headers->getCacheControlDirective('max-age'); +} +if (null !== $this->getExpires()) { +return $this->getExpires()->format('U') - $this->getDate()->format('U'); +} +} +public function setMaxAge($value) +{ +$this->headers->addCacheControlDirective('max-age', $value); +return $this; +} +public function setSharedMaxAge($value) +{ +$this->setPublic(); +$this->headers->addCacheControlDirective('s-maxage', $value); +return $this; +} +public function getTtl() +{ +if (null !== $maxAge = $this->getMaxAge()) { +return $maxAge - $this->getAge(); +} +} +public function setTtl($seconds) +{ +$this->setSharedMaxAge($this->getAge() + $seconds); +return $this; +} +public function setClientTtl($seconds) +{ +$this->setMaxAge($this->getAge() + $seconds); +return $this; +} +public function getLastModified() +{ +return $this->headers->getDate('Last-Modified'); +} +public function setLastModified(\DateTime $date = null) +{ +if (null === $date) { +$this->headers->remove('Last-Modified'); +} else { +$date = clone $date; +$date->setTimezone(new \DateTimeZone('UTC')); +$this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT'); +} +return $this; +} +public function getEtag() +{ +return $this->headers->get('ETag'); +} +public function setEtag($etag = null, $weak = false) +{ +if (null === $etag) { +$this->headers->remove('Etag'); +} else { +if (0 !== strpos($etag,'"')) { +$etag ='"'.$etag.'"'; +} +$this->headers->set('ETag', (true === $weak ?'W/':'').$etag); +} +return $this; +} +public function setCache(array $options) +{ +if ($diff = array_diff(array_keys($options), array('etag','last_modified','max_age','s_maxage','private','public'))) { +throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff)))); +} +if (isset($options['etag'])) { +$this->setEtag($options['etag']); +} +if (isset($options['last_modified'])) { +$this->setLastModified($options['last_modified']); +} +if (isset($options['max_age'])) { +$this->setMaxAge($options['max_age']); +} +if (isset($options['s_maxage'])) { +$this->setSharedMaxAge($options['s_maxage']); +} +if (isset($options['public'])) { +if ($options['public']) { +$this->setPublic(); +} else { +$this->setPrivate(); +} +} +if (isset($options['private'])) { +if ($options['private']) { +$this->setPrivate(); +} else { +$this->setPublic(); +} +} +return $this; +} +public function setNotModified() +{ +$this->setStatusCode(304); +$this->setContent(null); +foreach (array('Allow','Content-Encoding','Content-Language','Content-Length','Content-MD5','Content-Type','Last-Modified') as $header) { +$this->headers->remove($header); +} +return $this; +} +public function hasVary() +{ +return null !== $this->headers->get('Vary'); +} +public function getVary() +{ +if (!$vary = $this->headers->get('Vary', null, false)) { +return array(); +} +$ret = array(); +foreach ($vary as $item) { +$ret = array_merge($ret, preg_split('/[\s,]+/', $item)); +} +return $ret; +} +public function setVary($headers, $replace = true) +{ +$this->headers->set('Vary', $headers, $replace); +return $this; +} +public function isNotModified(Request $request) +{ +if (!$request->isMethodSafe()) { +return false; +} +$notModified = false; +$lastModified = $this->headers->get('Last-Modified'); +$modifiedSince = $request->headers->get('If-Modified-Since'); +if ($etags = $request->getETags()) { +$notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags); +} +if ($modifiedSince && $lastModified) { +$notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified); +} +if ($notModified) { +$this->setNotModified(); +} +return $notModified; +} +public function isInvalid() +{ +return $this->statusCode < 100 || $this->statusCode >= 600; +} +public function isInformational() +{ +return $this->statusCode >= 100 && $this->statusCode < 200; +} +public function isSuccessful() +{ +return $this->statusCode >= 200 && $this->statusCode < 300; +} +public function isRedirection() +{ +return $this->statusCode >= 300 && $this->statusCode < 400; +} +public function isClientError() +{ +return $this->statusCode >= 400 && $this->statusCode < 500; +} +public function isServerError() +{ +return $this->statusCode >= 500 && $this->statusCode < 600; +} +public function isOk() +{ +return 200 === $this->statusCode; +} +public function isForbidden() +{ +return 403 === $this->statusCode; +} +public function isNotFound() +{ +return 404 === $this->statusCode; +} +public function isRedirect($location = null) +{ +return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location')); +} +public function isEmpty() +{ +return in_array($this->statusCode, array(204, 304)); +} +public static function closeOutputBuffers($targetLevel, $flush) +{ +$status = ob_get_status(true); +$level = count($status); +$flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1; +while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) { +if ($flush) { +ob_end_flush(); +} else { +ob_end_clean(); +} +} +} +protected function ensureIEOverSSLCompatibility(Request $request) +{ +if (false !== stripos($this->headers->get('Content-Disposition'),'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) { +if ((int) preg_replace('/(MSIE )(.*?);/','$2', $match[0]) < 9) { +$this->headers->remove('Cache-Control'); +} +} +} +} +} +namespace Symfony\Component\HttpFoundation +{ +class ResponseHeaderBag extends HeaderBag +{ +const COOKIES_FLAT ='flat'; +const COOKIES_ARRAY ='array'; +const DISPOSITION_ATTACHMENT ='attachment'; +const DISPOSITION_INLINE ='inline'; +protected $computedCacheControl = array(); +protected $cookies = array(); +protected $headerNames = array(); +public function __construct(array $headers = array()) +{ +parent::__construct($headers); +if (!isset($this->headers['cache-control'])) { +$this->set('Cache-Control',''); +} +} +public function __toString() +{ +$cookies =''; +foreach ($this->getCookies() as $cookie) { +$cookies .='Set-Cookie: '.$cookie."\r\n"; +} +ksort($this->headerNames); +return parent::__toString().$cookies; +} +public function allPreserveCase() +{ +return array_combine($this->headerNames, $this->headers); +} +public function replace(array $headers = array()) +{ +$this->headerNames = array(); +parent::replace($headers); +if (!isset($this->headers['cache-control'])) { +$this->set('Cache-Control',''); +} +} +public function set($key, $values, $replace = true) +{ +parent::set($key, $values, $replace); +$uniqueKey = str_replace('_','-', strtolower($key)); +$this->headerNames[$uniqueKey] = $key; +if (in_array($uniqueKey, array('cache-control','etag','last-modified','expires'))) { +$computed = $this->computeCacheControlValue(); +$this->headers['cache-control'] = array($computed); +$this->headerNames['cache-control'] ='Cache-Control'; +$this->computedCacheControl = $this->parseCacheControl($computed); +} +} +public function remove($key) +{ +parent::remove($key); +$uniqueKey = str_replace('_','-', strtolower($key)); +unset($this->headerNames[$uniqueKey]); +if ('cache-control'=== $uniqueKey) { +$this->computedCacheControl = array(); +} +} +public function hasCacheControlDirective($key) +{ +return array_key_exists($key, $this->computedCacheControl); +} +public function getCacheControlDirective($key) +{ +return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; +} +public function setCookie(Cookie $cookie) +{ +$this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; +} +public function removeCookie($name, $path ='/', $domain = null) +{ +if (null === $path) { +$path ='/'; +} +unset($this->cookies[$domain][$path][$name]); +if (empty($this->cookies[$domain][$path])) { +unset($this->cookies[$domain][$path]); +if (empty($this->cookies[$domain])) { +unset($this->cookies[$domain]); +} +} +} +public function getCookies($format = self::COOKIES_FLAT) +{ +if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) { +throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY)))); +} +if (self::COOKIES_ARRAY === $format) { +return $this->cookies; +} +$flattenedCookies = array(); +foreach ($this->cookies as $path) { +foreach ($path as $cookies) { +foreach ($cookies as $cookie) { +$flattenedCookies[] = $cookie; +} +} +} +return $flattenedCookies; +} +public function clearCookie($name, $path ='/', $domain = null, $secure = false, $httpOnly = true) +{ +$this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly)); +} +public function makeDisposition($disposition, $filename, $filenameFallback ='') +{ +if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) { +throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE)); +} +if (''== $filenameFallback) { +$filenameFallback = $filename; +} +if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) { +throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.'); +} +if (false !== strpos($filenameFallback,'%')) { +throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); +} +if (false !== strpos($filename,'/') || false !== strpos($filename,'\\') || false !== strpos($filenameFallback,'/') || false !== strpos($filenameFallback,'\\')) { +throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); +} +$output = sprintf('%s; filename="%s"', $disposition, str_replace('"','\\"', $filenameFallback)); +if ($filename !== $filenameFallback) { +$output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename)); +} +return $output; +} +protected function computeCacheControlValue() +{ +if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { +return'no-cache'; +} +if (!$this->cacheControl) { +return'private, must-revalidate'; +} +$header = $this->getCacheControlHeader(); +if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) { +return $header; +} +if (!isset($this->cacheControl['s-maxage'])) { +return $header.', private'; +} +return $header; +} +} +} +namespace Symfony\Component\DependencyInjection +{ +interface ContainerAwareInterface +{ +public function setContainer(ContainerInterface $container = null); +} +} +namespace Symfony\Component\DependencyInjection +{ +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +interface ContainerInterface +{ +const EXCEPTION_ON_INVALID_REFERENCE = 1; +const NULL_ON_INVALID_REFERENCE = 2; +const IGNORE_ON_INVALID_REFERENCE = 3; +const SCOPE_CONTAINER ='container'; +const SCOPE_PROTOTYPE ='prototype'; +public function set($id, $service, $scope = self::SCOPE_CONTAINER); +public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE); +public function has($id); +public function getParameter($name); +public function hasParameter($name); +public function setParameter($name, $value); +public function enterScope($name); +public function leaveScope($name); +public function addScope(ScopeInterface $scope); +public function hasScope($name); +public function isScopeActive($name); +} +} +namespace Symfony\Component\DependencyInjection +{ +interface IntrospectableContainerInterface extends ContainerInterface +{ +public function initialized($id); +} +} +namespace Symfony\Component\DependencyInjection +{ +use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +class Container implements IntrospectableContainerInterface +{ +protected $parameterBag; +protected $services = array(); +protected $methodMap = array(); +protected $aliases = array(); +protected $scopes = array(); +protected $scopeChildren = array(); +protected $scopedServices = array(); +protected $scopeStacks = array(); +protected $loading = array(); +private $underscoreMap = array('_'=>'','.'=>'_','\\'=>'_'); +public function __construct(ParameterBagInterface $parameterBag = null) +{ +$this->parameterBag = $parameterBag ?: new ParameterBag(); +} +public function compile() +{ +$this->parameterBag->resolve(); +$this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); +} +public function isFrozen() +{ +return $this->parameterBag instanceof FrozenParameterBag; +} +public function getParameterBag() +{ +return $this->parameterBag; +} +public function getParameter($name) +{ +return $this->parameterBag->get($name); +} +public function hasParameter($name) +{ +return $this->parameterBag->has($name); +} +public function setParameter($name, $value) +{ +$this->parameterBag->set($name, $value); +} +public function set($id, $service, $scope = self::SCOPE_CONTAINER) +{ +if (self::SCOPE_PROTOTYPE === $scope) { +throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id)); +} +$id = strtolower($id); +if ('service_container'=== $id) { +return; +} +if (self::SCOPE_CONTAINER !== $scope) { +if (!isset($this->scopedServices[$scope])) { +throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id)); +} +$this->scopedServices[$scope][$id] = $service; +} +if (isset($this->aliases[$id])) { +unset($this->aliases[$id]); +} +$this->services[$id] = $service; +if (method_exists($this, $method ='synchronize'.strtr($id, $this->underscoreMap).'Service')) { +$this->$method(); +} +if (null === $service) { +if (self::SCOPE_CONTAINER !== $scope) { +unset($this->scopedServices[$scope][$id]); +} +unset($this->services[$id]); +} +} +public function has($id) +{ +for ($i = 2;;) { +if ('service_container'=== $id +|| isset($this->aliases[$id]) +|| isset($this->services[$id]) +|| array_key_exists($id, $this->services) +) { +return true; +} +if (--$i && $id !== $lcId = strtolower($id)) { +$id = $lcId; +} else { +return method_exists($this,'get'.strtr($id, $this->underscoreMap).'Service'); +} +} +} +public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) +{ +for ($i = 2;;) { +if ('service_container'=== $id) { +return $this; +} +if (isset($this->aliases[$id])) { +$id = $this->aliases[$id]; +} +if (isset($this->services[$id]) || array_key_exists($id, $this->services)) { +return $this->services[$id]; +} +if (isset($this->loading[$id])) { +throw new ServiceCircularReferenceException($id, array_keys($this->loading)); +} +if (isset($this->methodMap[$id])) { +$method = $this->methodMap[$id]; +} elseif (--$i && $id !== $lcId = strtolower($id)) { +$id = $lcId; +continue; +} elseif (method_exists($this, $method ='get'.strtr($id, $this->underscoreMap).'Service')) { +} else { +if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { +if (!$id) { +throw new ServiceNotFoundException($id); +} +$alternatives = array(); +foreach ($this->services as $key => $associatedService) { +$lev = levenshtein($id, $key); +if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) { +$alternatives[] = $key; +} +} +throw new ServiceNotFoundException($id, null, null, $alternatives); +} +return; +} +$this->loading[$id] = true; +try { +$service = $this->$method(); +} catch (\Exception $e) { +unset($this->loading[$id]); +unset($this->services[$id]); +if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { +return; +} +throw $e; +} catch (\Throwable $e) { +unset($this->loading[$id]); +unset($this->services[$id]); +throw $e; +} +unset($this->loading[$id]); +return $service; +} +} +public function initialized($id) +{ +$id = strtolower($id); +if ('service_container'=== $id) { +return true; +} +if (isset($this->aliases[$id])) { +$id = $this->aliases[$id]; +} +return isset($this->services[$id]) || array_key_exists($id, $this->services); +} +public function getServiceIds() +{ +$ids = array(); +foreach (get_class_methods($this) as $method) { +if (preg_match('/^get(.+)Service$/', $method, $match)) { +$ids[] = self::underscore($match[1]); +} +} +$ids[] ='service_container'; +return array_unique(array_merge($ids, array_keys($this->services))); +} +public function enterScope($name) +{ +if (!isset($this->scopes[$name])) { +throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); +} +if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { +throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); +} +if (isset($this->scopedServices[$name])) { +$services = array($this->services, $name => $this->scopedServices[$name]); +unset($this->scopedServices[$name]); +foreach ($this->scopeChildren[$name] as $child) { +if (isset($this->scopedServices[$child])) { +$services[$child] = $this->scopedServices[$child]; +unset($this->scopedServices[$child]); +} +} +$this->services = call_user_func_array('array_diff_key', $services); +array_shift($services); +if (!isset($this->scopeStacks[$name])) { +$this->scopeStacks[$name] = new \SplStack(); +} +$this->scopeStacks[$name]->push($services); +} +$this->scopedServices[$name] = array(); +} +public function leaveScope($name) +{ +if (!isset($this->scopedServices[$name])) { +throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); +} +$services = array($this->services, $this->scopedServices[$name]); +unset($this->scopedServices[$name]); +foreach ($this->scopeChildren[$name] as $child) { +if (isset($this->scopedServices[$child])) { +$services[] = $this->scopedServices[$child]; +unset($this->scopedServices[$child]); +} +} +$this->services = call_user_func_array('array_diff_key', $services); +if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { +$services = $this->scopeStacks[$name]->pop(); +$this->scopedServices += $services; +if ($this->scopeStacks[$name]->isEmpty()) { +unset($this->scopeStacks[$name]); +} +foreach ($services as $array) { +foreach ($array as $id => $service) { +$this->set($id, $service, $name); +} +} +} +} +public function addScope(ScopeInterface $scope) +{ +$name = $scope->getName(); +$parentScope = $scope->getParentName(); +if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { +throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); +} +if (isset($this->scopes[$name])) { +throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); +} +if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { +throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); +} +$this->scopes[$name] = $parentScope; +$this->scopeChildren[$name] = array(); +while ($parentScope !== self::SCOPE_CONTAINER) { +$this->scopeChildren[$parentScope][] = $name; +$parentScope = $this->scopes[$parentScope]; +} +} +public function hasScope($name) +{ +return isset($this->scopes[$name]); +} +public function isScopeActive($name) +{ +return isset($this->scopedServices[$name]); +} +public static function camelize($id) +{ +return strtr(ucwords(strtr($id, array('_'=>' ','.'=>'_ ','\\'=>'_ '))), array(' '=>'')); +} +public static function underscore($id) +{ +return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/','/([a-z\d])([A-Z])/'), array('\\1_\\2','\\1_\\2'), str_replace('_','.', $id))); +} +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +interface HttpKernelInterface +{ +const MASTER_REQUEST = 1; +const SUB_REQUEST = 2; +public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\Config\Loader\LoaderInterface; +interface KernelInterface extends HttpKernelInterface, \Serializable +{ +public function registerBundles(); +public function registerContainerConfiguration(LoaderInterface $loader); +public function boot(); +public function shutdown(); +public function getBundles(); +public function isClassInActiveBundle($class); +public function getBundle($name, $first = true); +public function locateResource($name, $dir = null, $first = true); +public function getName(); +public function getEnvironment(); +public function isDebug(); +public function getRootDir(); +public function getContainer(); +public function getStartTime(); +public function getCacheDir(); +public function getLogDir(); +public function getCharset(); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +interface TerminableInterface +{ +public function terminate(Request $request, Response $response); +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; +use Symfony\Component\HttpKernel\Config\EnvParametersResource; +use Symfony\Component\HttpKernel\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\ClassLoader\ClassCollectionLoader; +abstract class Kernel implements KernelInterface, TerminableInterface +{ +protected $bundles = array(); +protected $bundleMap; +protected $container; +protected $rootDir; +protected $environment; +protected $debug; +protected $booted = false; +protected $name; +protected $startTime; +protected $loadClassCache; +const VERSION ='2.7.14'; +const VERSION_ID = 20714; +const MAJOR_VERSION = 2; +const MINOR_VERSION = 7; +const RELEASE_VERSION = 14; +const EXTRA_VERSION =''; +const END_OF_MAINTENANCE ='05/2018'; +const END_OF_LIFE ='05/2019'; +public function __construct($environment, $debug) +{ +$this->environment = $environment; +$this->debug = (bool) $debug; +$this->rootDir = $this->getRootDir(); +$this->name = $this->getName(); +if ($this->debug) { +$this->startTime = microtime(true); +} +$defClass = new \ReflectionMethod($this,'init'); +$defClass = $defClass->getDeclaringClass()->name; +if (__CLASS__ !== $defClass) { +@trigger_error(sprintf('Calling the %s::init() method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', $defClass), E_USER_DEPRECATED); +$this->init(); +} +} +public function init() +{ +@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', E_USER_DEPRECATED); +} +public function __clone() +{ +if ($this->debug) { +$this->startTime = microtime(true); +} +$this->booted = false; +$this->container = null; +} +public function boot() +{ +if (true === $this->booted) { +return; +} +if ($this->loadClassCache) { +$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]); +} +$this->initializeBundles(); +$this->initializeContainer(); +foreach ($this->getBundles() as $bundle) { +$bundle->setContainer($this->container); +$bundle->boot(); +} +$this->booted = true; +} +public function terminate(Request $request, Response $response) +{ +if (false === $this->booted) { +return; +} +if ($this->getHttpKernel() instanceof TerminableInterface) { +$this->getHttpKernel()->terminate($request, $response); +} +} +public function shutdown() +{ +if (false === $this->booted) { +return; +} +$this->booted = false; +foreach ($this->getBundles() as $bundle) { +$bundle->shutdown(); +$bundle->setContainer(null); +} +$this->container = null; +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +if (false === $this->booted) { +$this->boot(); +} +return $this->getHttpKernel()->handle($request, $type, $catch); +} +protected function getHttpKernel() +{ +return $this->container->get('http_kernel'); +} +public function getBundles() +{ +return $this->bundles; +} +public function isClassInActiveBundle($class) +{ +@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in version 3.0.', E_USER_DEPRECATED); +foreach ($this->getBundles() as $bundle) { +if (0 === strpos($class, $bundle->getNamespace())) { +return true; +} +} +return false; +} +public function getBundle($name, $first = true) +{ +if (!isset($this->bundleMap[$name])) { +throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, get_class($this))); +} +if (true === $first) { +return $this->bundleMap[$name][0]; +} +return $this->bundleMap[$name]; +} +public function locateResource($name, $dir = null, $first = true) +{ +if ('@'!== $name[0]) { +throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); +} +if (false !== strpos($name,'..')) { +throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); +} +$bundleName = substr($name, 1); +$path =''; +if (false !== strpos($bundleName,'/')) { +list($bundleName, $path) = explode('/', $bundleName, 2); +} +$isResource = 0 === strpos($path,'Resources') && null !== $dir; +$overridePath = substr($path, 9); +$resourceBundle = null; +$bundles = $this->getBundle($bundleName, false); +$files = array(); +foreach ($bundles as $bundle) { +if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { +if (null !== $resourceBundle) { +throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', +$file, +$resourceBundle, +$dir.'/'.$bundles[0]->getName().$overridePath +)); +} +if ($first) { +return $file; +} +$files[] = $file; +} +if (file_exists($file = $bundle->getPath().'/'.$path)) { +if ($first && !$isResource) { +return $file; +} +$files[] = $file; +$resourceBundle = $bundle->getName(); +} +} +if (count($files) > 0) { +return $first && $isResource ? $files[0] : $files; +} +throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); +} +public function getName() +{ +if (null === $this->name) { +$this->name = preg_replace('/[^a-zA-Z0-9_]+/','', basename($this->rootDir)); +} +return $this->name; +} +public function getEnvironment() +{ +return $this->environment; +} +public function isDebug() +{ +return $this->debug; +} +public function getRootDir() +{ +if (null === $this->rootDir) { +$r = new \ReflectionObject($this); +$this->rootDir = dirname($r->getFileName()); +} +return $this->rootDir; +} +public function getContainer() +{ +return $this->container; +} +public function loadClassCache($name ='classes', $extension ='.php') +{ +$this->loadClassCache = array($name, $extension); +} +public function setClassCache(array $classes) +{ +file_put_contents($this->getCacheDir().'/classes.map', sprintf('debug ? $this->startTime : -INF; +} +public function getCacheDir() +{ +return $this->rootDir.'/cache/'.$this->environment; +} +public function getLogDir() +{ +return $this->rootDir.'/logs'; +} +public function getCharset() +{ +return'UTF-8'; +} +protected function doLoadClassCache($name, $extension) +{ +if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) { +ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension); +} +} +protected function initializeBundles() +{ +$this->bundles = array(); +$topMostBundles = array(); +$directChildren = array(); +foreach ($this->registerBundles() as $bundle) { +$name = $bundle->getName(); +if (isset($this->bundles[$name])) { +throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name)); +} +$this->bundles[$name] = $bundle; +if ($parentName = $bundle->getParent()) { +if (isset($directChildren[$parentName])) { +throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName])); +} +if ($parentName == $name) { +throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name)); +} +$directChildren[$parentName] = $name; +} else { +$topMostBundles[$name] = $bundle; +} +} +if (!empty($directChildren) && count($diff = array_diff_key($directChildren, $this->bundles))) { +$diff = array_keys($diff); +throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0])); +} +$this->bundleMap = array(); +foreach ($topMostBundles as $name => $bundle) { +$bundleMap = array($bundle); +$hierarchy = array($name); +while (isset($directChildren[$name])) { +$name = $directChildren[$name]; +array_unshift($bundleMap, $this->bundles[$name]); +$hierarchy[] = $name; +} +foreach ($hierarchy as $bundle) { +$this->bundleMap[$bundle] = $bundleMap; +array_pop($bundleMap); +} +} +} +protected function getContainerClass() +{ +return $this->name.ucfirst($this->environment).($this->debug ?'Debug':'').'ProjectContainer'; +} +protected function getContainerBaseClass() +{ +return'Container'; +} +protected function initializeContainer() +{ +$class = $this->getContainerClass(); +$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); +$fresh = true; +if (!$cache->isFresh()) { +$container = $this->buildContainer(); +$container->compile(); +$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass()); +$fresh = false; +} +require_once $cache->getPath(); +$this->container = new $class(); +$this->container->set('kernel', $this); +if (!$fresh && $this->container->has('cache_warmer')) { +$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')); +} +} +protected function getKernelParameters() +{ +$bundles = array(); +foreach ($this->bundles as $name => $bundle) { +$bundles[$name] = get_class($bundle); +} +return array_merge( +array('kernel.root_dir'=> realpath($this->rootDir) ?: $this->rootDir,'kernel.environment'=> $this->environment,'kernel.debug'=> $this->debug,'kernel.name'=> $this->name,'kernel.cache_dir'=> realpath($this->getCacheDir()) ?: $this->getCacheDir(),'kernel.logs_dir'=> realpath($this->getLogDir()) ?: $this->getLogDir(),'kernel.bundles'=> $bundles,'kernel.charset'=> $this->getCharset(),'kernel.container_class'=> $this->getContainerClass(), +), +$this->getEnvParameters() +); +} +protected function getEnvParameters() +{ +$parameters = array(); +foreach ($_SERVER as $key => $value) { +if (0 === strpos($key,'SYMFONY__')) { +$parameters[strtolower(str_replace('__','.', substr($key, 9)))] = $value; +} +} +return $parameters; +} +protected function buildContainer() +{ +foreach (array('cache'=> $this->getCacheDir(),'logs'=> $this->getLogDir()) as $name => $dir) { +if (!is_dir($dir)) { +if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { +throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); +} +} elseif (!is_writable($dir)) { +throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); +} +} +$container = $this->getContainerBuilder(); +$container->addObjectResource($this); +$this->prepareContainer($container); +if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { +$container->merge($cont); +} +$container->addCompilerPass(new AddClassesToCachePass($this)); +$container->addResource(new EnvParametersResource('SYMFONY__')); +return $container; +} +protected function prepareContainer(ContainerBuilder $container) +{ +$extensions = array(); +foreach ($this->bundles as $bundle) { +if ($extension = $bundle->getContainerExtension()) { +$container->registerExtension($extension); +$extensions[] = $extension->getAlias(); +} +if ($this->debug) { +$container->addObjectResource($bundle); +} +} +foreach ($this->bundles as $bundle) { +$bundle->build($container); +} +$container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); +} +protected function getContainerBuilder() +{ +$container = new ContainerBuilder(new ParameterBag($this->getKernelParameters())); +if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) { +$container->setProxyInstantiator(new RuntimeInstantiator()); +} +return $container; +} +protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) +{ +$dumper = new PhpDumper($container); +if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper')) { +$dumper->setProxyDumper(new ProxyDumper(md5($cache->getPath()))); +} +$content = $dumper->dump(array('class'=> $class,'base_class'=> $baseClass,'file'=> $cache->getPath(),'debug'=> $this->debug)); +$cache->write($content, $container->getResources()); +} +protected function getContainerLoader(ContainerInterface $container) +{ +$locator = new FileLocator($this); +$resolver = new LoaderResolver(array( +new XmlFileLoader($container, $locator), +new YamlFileLoader($container, $locator), +new IniFileLoader($container, $locator), +new PhpFileLoader($container, $locator), +new ClosureLoader($container), +)); +return new DelegatingLoader($resolver); +} +public static function stripComments($source) +{ +if (!function_exists('token_get_all')) { +return $source; +} +$rawChunk =''; +$output =''; +$tokens = token_get_all($source); +$ignoreSpace = false; +for ($i = 0; isset($tokens[$i]); ++$i) { +$token = $tokens[$i]; +if (!isset($token[1]) ||'b"'=== $token) { +$rawChunk .= $token; +} elseif (T_START_HEREDOC === $token[0]) { +$output .= $rawChunk.$token[1]; +do { +$token = $tokens[++$i]; +$output .= isset($token[1]) &&'b"'!== $token ? $token[1] : $token; +} while ($token[0] !== T_END_HEREDOC); +$rawChunk =''; +} elseif (T_WHITESPACE === $token[0]) { +if ($ignoreSpace) { +$ignoreSpace = false; +continue; +} +$rawChunk .= preg_replace(array('/\n{2,}/S'),"\n", $token[1]); +} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { +$ignoreSpace = true; +} else { +$rawChunk .= $token[1]; +if (T_OPEN_TAG === $token[0]) { +$ignoreSpace = true; +} +} +} +$output .= $rawChunk; +if (PHP_VERSION_ID >= 70000) { +unset($tokens, $rawChunk); +gc_mem_caches(); +} +return $output; +} +public function serialize() +{ +return serialize(array($this->environment, $this->debug)); +} +public function unserialize($data) +{ +list($environment, $debug) = unserialize($data); +$this->__construct($environment, $debug); +} +} +} +namespace Symfony\Component\ClassLoader +{ +class ApcClassLoader +{ +private $prefix; +protected $decorated; +public function __construct($prefix, $decorated) +{ +if (!function_exists('apcu_fetch')) { +throw new \RuntimeException('Unable to use ApcClassLoader as APC is not installed.'); +} +if (!method_exists($decorated,'findFile')) { +throw new \InvalidArgumentException('The class finder must implement a "findFile" method.'); +} +$this->prefix = $prefix; +$this->decorated = $decorated; +} +public function register($prepend = false) +{ +spl_autoload_register(array($this,'loadClass'), true, $prepend); +} +public function unregister() +{ +spl_autoload_unregister(array($this,'loadClass')); +} +public function loadClass($class) +{ +if ($file = $this->findFile($class)) { +require $file; +return true; +} +} +public function findFile($class) +{ +$file = apcu_fetch($this->prefix.$class, $success); +if (!$success) { +apcu_store($this->prefix.$class, $file = $this->decorated->findFile($class) ?: null); +} +return $file; +} +public function __call($method, $args) +{ +return call_user_func_array(array($this->decorated, $method), $args); +} +} +} +namespace Symfony\Component\HttpKernel\Bundle +{ +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +interface BundleInterface extends ContainerAwareInterface +{ +public function boot(); +public function shutdown(); +public function build(ContainerBuilder $container); +public function getContainerExtension(); +public function getParent(); +public function getName(); +public function getNamespace(); +public function getPath(); +} +} +namespace Symfony\Component\DependencyInjection +{ +abstract class ContainerAware implements ContainerAwareInterface +{ +protected $container; +public function setContainer(ContainerInterface $container = null) +{ +$this->container = $container; +} +} +} +namespace Symfony\Component\HttpKernel\Bundle +{ +use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Console\Application; +use Symfony\Component\Finder\Finder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +abstract class Bundle extends ContainerAware implements BundleInterface +{ +protected $name; +protected $extension; +protected $path; +public function boot() +{ +} +public function shutdown() +{ +} +public function build(ContainerBuilder $container) +{ +} +public function getContainerExtension() +{ +if (null === $this->extension) { +$class = $this->getContainerExtensionClass(); +if (class_exists($class)) { +$extension = new $class(); +if (!$extension instanceof ExtensionInterface) { +throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', $class)); +} +$basename = preg_replace('/Bundle$/','', $this->getName()); +$expectedAlias = Container::underscore($basename); +if ($expectedAlias != $extension->getAlias()) { +throw new \LogicException(sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', +$expectedAlias, $extension->getAlias() +)); +} +$this->extension = $extension; +} else { +$this->extension = false; +} +} +if ($this->extension) { +return $this->extension; +} +} +public function getNamespace() +{ +$class = get_class($this); +return substr($class, 0, strrpos($class,'\\')); +} +public function getPath() +{ +if (null === $this->path) { +$reflected = new \ReflectionObject($this); +$this->path = dirname($reflected->getFileName()); +} +return $this->path; +} +public function getParent() +{ +} +final public function getName() +{ +if (null !== $this->name) { +return $this->name; +} +$name = get_class($this); +$pos = strrpos($name,'\\'); +return $this->name = false === $pos ? $name : substr($name, $pos + 1); +} +public function registerCommands(Application $application) +{ +if (!is_dir($dir = $this->getPath().'/Command')) { +return; +} +if (!class_exists('Symfony\Component\Finder\Finder')) { +throw new \RuntimeException('You need the symfony/finder component to register bundle commands.'); +} +$finder = new Finder(); +$finder->files()->name('*Command.php')->in($dir); +$prefix = $this->getNamespace().'\\Command'; +foreach ($finder as $file) { +$ns = $prefix; +if ($relativePath = $file->getRelativePath()) { +$ns .='\\'.str_replace('/','\\', $relativePath); +} +$class = $ns.'\\'.$file->getBasename('.php'); +if ($this->container) { +$alias ='console.command.'.strtolower(str_replace('\\','_', $class)); +if ($this->container->has($alias)) { +continue; +} +} +$r = new \ReflectionClass($class); +if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) { +$application->add($r->newInstance()); +} +} +} +protected function getContainerExtensionClass() +{ +$basename = preg_replace('/Bundle$/','', $this->getName()); +return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension'; +} +} +} +namespace Symfony\Component\Config +{ +use Symfony\Component\Config\Resource\ResourceInterface; +interface ConfigCacheInterface +{ +public function getPath(); +public function isFresh(); +public function write($content, array $metadata = null); +} +} +namespace Symfony\Component\Config +{ +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +class ConfigCache implements ConfigCacheInterface +{ +private $debug; +private $file; +public function __construct($file, $debug) +{ +$this->file = $file; +$this->debug = (bool) $debug; +} +public function __toString() +{ +@trigger_error('ConfigCache::__toString() is deprecated since version 2.7 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED); +return $this->file; +} +public function getPath() +{ +return $this->file; +} +public function isFresh() +{ +if (!is_file($this->file)) { +return false; +} +if (!$this->debug) { +return true; +} +$metadata = $this->getMetaFile(); +if (!is_file($metadata)) { +return false; +} +$time = filemtime($this->file); +$meta = unserialize(file_get_contents($metadata)); +foreach ($meta as $resource) { +if (!$resource->isFresh($time)) { +return false; +} +} +return true; +} +public function write($content, array $metadata = null) +{ +$mode = 0666; +$umask = umask(); +$filesystem = new Filesystem(); +$filesystem->dumpFile($this->file, $content, null); +try { +$filesystem->chmod($this->file, $mode, $umask); +} catch (IOException $e) { +} +if (null !== $metadata && true === $this->debug) { +$filesystem->dumpFile($this->getMetaFile(), serialize($metadata), null); +try { +$filesystem->chmod($this->getMetaFile(), $mode, $umask); +} catch (IOException $e) { +} +} +} +private function getMetaFile() +{ +return $this->file.'.meta'; +} +} +} +namespace Symfony\Component\HttpKernel +{ +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\FinishRequestEvent; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +class HttpKernel implements HttpKernelInterface, TerminableInterface +{ +protected $dispatcher; +protected $resolver; +protected $requestStack; +public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null) +{ +$this->dispatcher = $dispatcher; +$this->resolver = $resolver; +$this->requestStack = $requestStack ?: new RequestStack(); +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +$request->headers->set('X-Php-Ob-Level', ob_get_level()); +try { +return $this->handleRaw($request, $type); +} catch (\Exception $e) { +if (false === $catch) { +$this->finishRequest($request, $type); +throw $e; +} +return $this->handleException($e, $request, $type); +} +} +public function terminate(Request $request, Response $response) +{ +$this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response)); +} +public function terminateWithException(\Exception $exception) +{ +if (!$request = $this->requestStack->getMasterRequest()) { +throw new \LogicException('Request stack is empty', 0, $exception); +} +$response = $this->handleException($exception, $request, self::MASTER_REQUEST); +$response->sendHeaders(); +$response->sendContent(); +$this->terminate($request, $response); +} +private function handleRaw(Request $request, $type = self::MASTER_REQUEST) +{ +$this->requestStack->push($request); +$event = new GetResponseEvent($this, $request, $type); +$this->dispatcher->dispatch(KernelEvents::REQUEST, $event); +if ($event->hasResponse()) { +return $this->filterResponse($event->getResponse(), $request, $type); +} +if (false === $controller = $this->resolver->getController($request)) { +throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); +} +$event = new FilterControllerEvent($this, $controller, $request, $type); +$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event); +$controller = $event->getController(); +$arguments = $this->resolver->getArguments($request, $controller); +$response = call_user_func_array($controller, $arguments); +if (!$response instanceof Response) { +$event = new GetResponseForControllerResultEvent($this, $request, $type, $response); +$this->dispatcher->dispatch(KernelEvents::VIEW, $event); +if ($event->hasResponse()) { +$response = $event->getResponse(); +} +if (!$response instanceof Response) { +$msg = sprintf('The controller must return a response (%s given).', $this->varToString($response)); +if (null === $response) { +$msg .=' Did you forget to add a return statement somewhere in your controller?'; +} +throw new \LogicException($msg); +} +} +return $this->filterResponse($response, $request, $type); +} +private function filterResponse(Response $response, Request $request, $type) +{ +$event = new FilterResponseEvent($this, $request, $type, $response); +$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event); +$this->finishRequest($request, $type); +return $event->getResponse(); +} +private function finishRequest(Request $request, $type) +{ +$this->dispatcher->dispatch(KernelEvents::FINISH_REQUEST, new FinishRequestEvent($this, $request, $type)); +$this->requestStack->pop(); +} +private function handleException(\Exception $e, $request, $type) +{ +$event = new GetResponseForExceptionEvent($this, $request, $type, $e); +$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event); +$e = $event->getException(); +if (!$event->hasResponse()) { +$this->finishRequest($request, $type); +throw $e; +} +$response = $event->getResponse(); +if ($response->headers->has('X-Status-Code')) { +$response->setStatusCode($response->headers->get('X-Status-Code')); +$response->headers->remove('X-Status-Code'); +} elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) { +if ($e instanceof HttpExceptionInterface) { +$response->setStatusCode($e->getStatusCode()); +$response->headers->add($e->getHeaders()); +} else { +$response->setStatusCode(500); +} +} +try { +return $this->filterResponse($response, $request, $type); +} catch (\Exception $e) { +return $response; +} +} +private function varToString($var) +{ +if (is_object($var)) { +return sprintf('Object(%s)', get_class($var)); +} +if (is_array($var)) { +$a = array(); +foreach ($var as $k => $v) { +$a[] = sprintf('%s => %s', $k, $this->varToString($v)); +} +return sprintf('Array(%s)', implode(', ', $a)); +} +if (is_resource($var)) { +return sprintf('Resource(%s)', get_resource_type($var)); +} +if (null === $var) { +return'null'; +} +if (false === $var) { +return'false'; +} +if (true === $var) { +return'true'; +} +return (string) $var; +} +} +} +namespace Symfony\Component\HttpKernel\DependencyInjection +{ +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Scope; +class ContainerAwareHttpKernel extends HttpKernel +{ +protected $container; +public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, $triggerDeprecation = true) +{ +parent::__construct($dispatcher, $controllerResolver, $requestStack); +if ($triggerDeprecation) { +@trigger_error('The '.__CLASS__.' class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpKernel class instead.', E_USER_DEPRECATED); +} +$this->container = $container; +if (!$container->hasScope('request')) { +$container->addScope(new Scope('request')); +} +} +public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) +{ +$this->container->enterScope('request'); +$this->container->set('request', $request,'request'); +try { +$response = parent::handle($request, $type, $catch); +} catch (\Exception $e) { +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +throw $e; +} catch (\Throwable $e) { +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +throw $e; +} +$this->container->set('request', null,'request'); +$this->container->leaveScope('request'); +return $response; +} +} +} + +namespace { return $loader; } diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/check.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/check.php new file mode 100644 index 00000000..cf1e6b06 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/check.php @@ -0,0 +1,142 @@ +getPhpIniConfigPath(); + +echo_title('Symfony Requirements Checker'); + +echo '> PHP is using the following php.ini file:'.PHP_EOL; +if ($iniPath) { + echo_style('green', ' '.$iniPath); +} else { + echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!'); +} + +echo PHP_EOL.PHP_EOL; + +echo '> Checking Symfony requirements:'.PHP_EOL.' '; + +$messages = array(); +foreach ($symfonyRequirements->getRequirements() as $req) { + /** @var $req Requirement */ + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('red', 'E'); + $messages['error'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +$checkPassed = empty($messages['error']); + +foreach ($symfonyRequirements->getRecommendations() as $req) { + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('yellow', 'W'); + $messages['warning'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +if ($checkPassed) { + echo_block('success', 'OK', 'Your system is ready to run Symfony projects'); +} else { + echo_block('error', 'ERROR', 'Your system is not ready to run Symfony projects'); + + echo_title('Fix the following mandatory requirements', 'red'); + + foreach ($messages['error'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +if (!empty($messages['warning'])) { + echo_title('Optional recommendations to improve your setup', 'yellow'); + + foreach ($messages['warning'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +echo PHP_EOL; +echo_style('title', 'Note'); +echo ' The command console could use a different php.ini file'.PHP_EOL; +echo_style('title', '~~~~'); +echo ' than the one used with your web server. To be on the'.PHP_EOL; +echo ' safe side, please check the requirements from your web'.PHP_EOL; +echo ' server using the '; +echo_style('yellow', 'web/config.php'); +echo ' script.'.PHP_EOL; +echo PHP_EOL; + +exit($checkPassed ? 0 : 1); + +function get_error_message(Requirement $requirement, $lineSize) +{ + if ($requirement->isFulfilled()) { + return; + } + + $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; + $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; + + return $errorMessage; +} + +function echo_title($title, $style = null) +{ + $style = $style ?: 'title'; + + echo PHP_EOL; + echo_style($style, $title.PHP_EOL); + echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); + echo PHP_EOL; +} + +function echo_style($style, $message) +{ + // ANSI color codes + $styles = array( + 'reset' => "\033[0m", + 'red' => "\033[31m", + 'green' => "\033[32m", + 'yellow' => "\033[33m", + 'error' => "\033[37;41m", + 'success' => "\033[37;42m", + 'title' => "\033[34m", + ); + $supports = has_color_support(); + + echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); +} + +function echo_block($style, $title, $message) +{ + $message = ' '.trim($message).' '; + $width = strlen($message); + + echo PHP_EOL.PHP_EOL; + + echo_style($style, str_repeat(' ', $width).PHP_EOL); + echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_repeat(' ', $width).PHP_EOL); +} + +function has_color_support() +{ + static $support; + + if (null === $support) { + if (DIRECTORY_SEPARATOR == '\\') { + $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); + } else { + $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); + } + } + + return $support; +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config.yml new file mode 100644 index 00000000..fc35384c --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config.yml @@ -0,0 +1,110 @@ +imports: + - { resource: parameters.yml } + - { resource: security.yml } + +framework: + #esi: ~ + translator: { fallback: %locale% } + secret: %secret% + router: + resource: "%kernel.root_dir%/config/routing.yml" + strict_requirements: %kernel.debug% + form: + csrf_protection: false + validation: { enable_annotations: true } + templating: + engines: ['twig'] + #assets_version: SomeVersionScheme + default_locale: "%locale%" + trusted_proxies: ~ + session: false + fragments: ~ + +# Twig Configuration +twig: + debug: %kernel.debug% + strict_variables: %kernel.debug% + exception_controller: 'FOS\RestBundle\Controller\ExceptionController::showAction' + +# Assetic Configuration +assetic: + debug: %kernel.debug% + use_controller: false + bundles: [ ] + #java: /usr/bin/java + filters: + cssrewrite: ~ + #closure: + # jar: %kernel.root_dir%/Resources/java/compiler.jar + #yui_css: + # jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar + +# Doctrine Configuration +doctrine: + dbal: + driver: %database_driver% + host: %database_host% + port: %database_port% + dbname: %database_name% + user: %database_user% + password: %database_password% + charset: UTF8 + # if using pdo_sqlite as your database driver, add the path in parameters.yml + # e.g. database_path: %kernel.root_dir%/data/data.db3 + # path: %database_path% + + orm: + auto_generate_proxy_classes: %kernel.debug% + auto_mapping: true + +# Swiftmailer Configuration +swiftmailer: + transport: %mailer_transport% + host: %mailer_host% + username: %mailer_user% + password: %mailer_password% + spool: { type: memory } + +fos_rest: + disable_csrf_role: ROLE_API + param_fetcher_listener: true + view: + mime_types: + json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1', 'application/json;version=1.2'] + view_response_listener: 'force' + formats: + xml: true + json: true + templating_formats: + html: true + format_listener: + rules: + - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } + versioning: + enabled: true + resolvers: + media_type: + enabled: true + exception: + codes: + 'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404 + 'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT + messages: + 'Symfony\Component\Routing\Exception\ResourceNotFoundException': true + allowed_methods_listener: true + access_denied_listener: + json: true + body_listener: true + +fos_http_cache: + cache_control: + rules: + # the controls section values are used in a call to Response::setCache(); + - + match: + path: ^/notes + methods: [GET, HEAD] + headers: + cache_control: { public: true, max_age: 15, s_maxage: 30 } + last_modified: "-1 hour" + vary: [Accept-Encoding, Accept-Language] diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_dev.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_dev.yml new file mode 100644 index 00000000..c6da9ca9 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_dev.yml @@ -0,0 +1,29 @@ +imports: + - { resource: config.yml } + +framework: + router: { resource: "%kernel.root_dir%/config/routing_dev.yml" } + profiler: { only_exceptions: false } + +web_profiler: + toolbar: true + intercept_redirects: false + +monolog: + handlers: + main: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug + firephp: + type: firephp + level: info + chromephp: + type: chromephp + level: info + +assetic: + use_controller: true + +#swiftmailer: +# delivery_address: me@example.com diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_prod.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_prod.yml new file mode 100644 index 00000000..e268dd06 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_prod.yml @@ -0,0 +1,29 @@ +imports: + - { resource: config.yml } + +# In production environment you should know that the parameters for URL generation +# always pass the requirements. Otherwise it would break your link (or even site with +# strict_requirements = true). So we can disable the requirements check completely for +# enhanced performance with strict_requirements = null. +framework: + router: + strict_requirements: null + #validation: + # cache: apc + +#doctrine: +# orm: +# metadata_cache_driver: apc +# result_cache_driver: apc +# query_cache_driver: apc + +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: %kernel.logs_dir%/%kernel.environment%.log + level: debug diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_test.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_test.yml new file mode 100644 index 00000000..a27c240f --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/config_test.yml @@ -0,0 +1,16 @@ +imports: + - { resource: config_dev.yml } + +framework: + test: ~ + session: + storage_id: session.storage.mock_file + profiler: + enabled: false + +web_profiler: + toolbar: false + intercept_redirects: false + +swiftmailer: + disable_delivery: true diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/parameters.yml.dist b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/parameters.yml.dist new file mode 100644 index 00000000..8b317c27 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/parameters.yml.dist @@ -0,0 +1,15 @@ +parameters: + database_driver: pdo_mysql + database_host: 127.0.0.1 + database_port: ~ + database_name: symfony + database_user: root + database_password: ~ + + mailer_transport: smtp + mailer_host: 127.0.0.1 + mailer_user: ~ + mailer_password: ~ + + locale: en + secret: ThisTokenIsNotSoSecretChangeIt diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing.yml new file mode 100644 index 00000000..bb563d33 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing.yml @@ -0,0 +1,3 @@ +NelmioApiDocBundle: + resource: "@NelmioApiDocBundle/Resources/config/routing.yml" + prefix: /api/doc diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing_dev.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing_dev.yml new file mode 100644 index 00000000..4b331385 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/routing_dev.yml @@ -0,0 +1,29 @@ +_welcome: + pattern: / + defaults: + _controller: FrameworkBundle:Redirect:redirect + route: get_notes + permanent: true # this for 301 + +_demo_note: + resource: "@AppBundle/Controller/NoteController.php" + type: rest + +_demo_video: + resource: "@AppBundle/Controller/VideoController.php" + type: rest + +_wdt: + resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" + prefix: /_wdt + +_profiler: + resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" + prefix: /_profiler + +_configurator: + resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" + prefix: /_configurator + +_main: + resource: routing.yml diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/security.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/security.yml new file mode 100644 index 00000000..43c6c84c --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/config/security.yml @@ -0,0 +1,26 @@ +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + role_hierarchy: + ROLE_ADMIN: ROLE_USER + ROLE_API: ROLE_USER + ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + + providers: + in_memory: + memory: + users: + restapi: { password: secretpw, roles: [ 'ROLE_API' ] } + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + main: + pattern: ^/ + anonymous: ~ + stateless: true + http_basic: + realm: "Demo REST API (username: restapi, password: secretpw)" diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/console b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/console new file mode 100755 index 00000000..129c8104 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/console @@ -0,0 +1,22 @@ +#!/usr/bin/env php +getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); +$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; + +$kernel = new AppKernel($env, $debug); +$application = new Application($kernel); +$application->run($input); diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/phpunit.xml.dist b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/phpunit.xml.dist new file mode 100644 index 00000000..e11a5b77 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/app/phpunit.xml.dist @@ -0,0 +1,37 @@ + + + + + + + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Tests + ../src/*Bundle/Tests + + + + + + + + ../src + + ../src/*Bundle/Resources + ../src/*Bundle/Tests + ../src/*/*Bundle/Resources + ../src/*/*Bundle/Tests + ../src/*/Bundle/*Bundle/Resources + ../src/*/Bundle/*Bundle/Tests + + + + \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.json b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.json new file mode 100644 index 00000000..7628fb93 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.json @@ -0,0 +1,67 @@ +{ + "name": "gimler/symfony-rest-edition", + "license": "MIT", + "type": "project", + "description": "The \"Symfony REST Edition\" distribution", + "autoload": { + "psr-4": { "": "src/" } + }, + "require": { + "php": ">=5.4.0", + "symfony/symfony": "2.7.*", + "doctrine/orm": "^2.4.8", + "doctrine/doctrine-bundle": "~1.4", + "symfony/assetic-bundle": "~2.3", + "symfony/swiftmailer-bundle": "~2.3", + "symfony/monolog-bundle": "~2.4", + "sensio/distribution-bundle": "~4.0", + "sensio/framework-extra-bundle": "^3.0.2", + "incenteev/composer-parameter-handler": "~2.0", + "jms/serializer-bundle": "^1.0", + "friendsofsymfony/rest-bundle": "~2.0", + "nelmio/api-doc-bundle": "^2.4", + "friendsofsymfony/http-cache-bundle": "^1.0", + "willdurand/hateoas-bundle": "^1.0", + "willdurand/rest-extra-bundle": "^1.0", + "hautelook/templated-uri-bundle": "^2.0", + "ext-pdo": "*", + "ext-json": "*" + }, + "require-dev": { + "sensio/generator-bundle": "~2.3", + "mockery/mockery": "^0.9.5", + "phpunit/phpunit": "^5.7" + }, + "scripts": { + "post-install-cmd": [ + "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget" + ], + "post-update-cmd": [ + "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget" + ] + }, + "config": { + "bin-dir": "bin" + }, + "extra": { + "symfony-app-dir": "app", + "symfony-web-dir": "web", + "symfony-assets-install": "relative", + "incenteev-parameters": { + "file": "app/config/parameters.yml" + }, + "branch-alias": { + "dev-master": "2.7-dev" + } + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.lock b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.lock new file mode 100644 index 00000000..b68bb3e7 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/composer.lock @@ -0,0 +1,4579 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f29365f04175e823e976a4bbeaa35d5a", + "packages": [ + { + "name": "doctrine/annotations", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Annotations\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2015-08-31T12:32:49+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2015-12-31T16:37:02+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2015-04-14T22:21:58+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "a579557bc689580c19fee4e27487a67fe60defc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0", + "reference": "a579557bc689580c19fee4e27487a67fe60defc0", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.5|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2015-12-25T13:18:31+00:00" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769", + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.7-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2016-01-05T22:11:12+00:00" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "1.6.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "fd51907c6c76acaa8a5234822a4f901c1500afc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/fd51907c6c76acaa8a5234822a4f901c1500afc1", + "reference": "fd51907c6c76acaa8a5234822a4f901c1500afc1", + "shasum": "" + }, + "require": { + "doctrine/dbal": "~2.3", + "doctrine/doctrine-cache-bundle": "~1.0", + "jdorn/sql-formatter": "~1.1", + "php": ">=5.3.2", + "symfony/console": "~2.3|~3.0", + "symfony/doctrine-bridge": "~2.2|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "doctrine/orm": "~2.3", + "phpunit/phpunit": "~4", + "satooshi/php-coveralls": "~0.6.1", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/property-info": "~2.8|~3.0", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0", + "twig/twig": "~1.10" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "orm", + "persistence" + ], + "time": "2016-04-21T19:55:56+00:00" + }, + { + "name": "doctrine/doctrine-cache-bundle", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineCacheBundle.git", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.4.2", + "doctrine/inflector": "~1.0", + "php": ">=5.3.2", + "symfony/doctrine-bridge": "~2.2|~3.0" + }, + "require-dev": { + "instaclick/coding-standard": "~1.1", + "instaclick/object-calisthenics-sniffs": "dev-master", + "instaclick/symfony2-coding-standard": "dev-remaster", + "phpunit/phpunit": "~4", + "predis/predis": "~0.8", + "satooshi/php-coveralls": "~0.6.1", + "squizlabs/php_codesniffer": "~1.5", + "symfony/console": "~2.2|~3.0", + "symfony/finder": "~2.2|~3.0", + "symfony/framework-bundle": "~2.2|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/security-acl": "~2.3|~3.0", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0" + }, + "suggest": { + "symfony/security-acl": "For using this bundle to cache ACLs" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Fabio B. Silva", + "email": "fabio.bat.silva@gmail.com" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@hotmail.com" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Bundle for Doctrine Cache", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-01-26T17:28:51+00:00" + }, + { + "name": "doctrine/inflector", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2015-11-06T14:35:42+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "doctrine/orm", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/doctrine2.git", + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bc4ddbfb0114cb33438cc811c9a740d8aa304aab", + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab", + "shasum": "" + }, + "require": { + "doctrine/cache": "~1.4", + "doctrine/collections": "~1.2", + "doctrine/common": ">=2.5-dev,<2.7-dev", + "doctrine/dbal": ">=2.5-dev,<2.6-dev", + "doctrine/instantiator": "~1.0.1", + "ext-pdo": "*", + "php": ">=5.4", + "symfony/console": "~2.5|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "symfony/yaml": "~2.3|~3.0" + }, + "suggest": { + "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + }, + "bin": [ + "bin/doctrine", + "bin/doctrine.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\ORM\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "orm" + ], + "time": "2016-01-05T21:34:58+00:00" + }, + { + "name": "friendsofsymfony/http-cache", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCache.git", + "reference": "783f3918d85263e444db02a9e42d0f42aa7c1f43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCache/zipball/783f3918d85263e444db02a9e42d0f42aa7c1f43", + "reference": "783f3918d85263e444db02a9e42d0f42aa7c1f43", + "shasum": "" + }, + "require": { + "guzzle/guzzle": "~3.8", + "php": ">=5.3.3", + "symfony/event-dispatcher": "^2.3||^3.0", + "symfony/options-resolver": "^2.3||^3.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.1", + "monolog/monolog": "~1.0", + "symfony/http-kernel": "^2.3||^3.0", + "symfony/process": "^2.3||^3.0" + }, + "suggest": { + "monolog/monolog": "For logging issues while invalidating" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\HttpCache\\": "src/", + "FOS\\HttpCache\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache/contributors" + } + ], + "description": "Tools to manage cache invalidation", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache", + "keywords": [ + "caching", + "http", + "invalidation", + "nginx", + "purge", + "varnish" + ], + "time": "2016-02-02T12:07:34+00:00" + }, + { + "name": "friendsofsymfony/http-cache-bundle", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle.git", + "reference": "f12b74b422e46c65daae8b3363bcf555f6957eea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCacheBundle/zipball/f12b74b422e46c65daae8b3363bcf555f6957eea", + "reference": "f12b74b422e46c65daae8b3363bcf555f6957eea", + "shasum": "" + }, + "require": { + "friendsofsymfony/http-cache": "~1.4", + "php": ">=5.3.3", + "symfony/framework-bundle": "^2.3||^3.0" + }, + "conflict": { + "twig/twig": "<1.12.0" + }, + "require-dev": { + "matthiasnoback/symfony-dependency-injection-test": "^0.7.4", + "mockery/mockery": "0.9.*", + "monolog/monolog": "*", + "polishsymfonycommunity/symfony-mocker-container": "^1.0", + "sensio/framework-extra-bundle": "^2.3||^3.0", + "symfony/expression-language": "^2.4||^3.0", + "symfony/monolog-bundle": "^2.3||^3.0", + "symfony/phpunit-bridge": "^2.7||^3.0", + "symfony/symfony": "^2.3||^3.0" + }, + "suggest": { + "sensio/framework-extra-bundle": "For Tagged Cache Invalidation", + "symfony/console": "To send invalidation requests from the command line", + "symfony/expression-language": "For Tagged Cache Invalidation" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\HttpCacheBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCacheBundle/contributors" + } + ], + "description": "Set path based HTTP cache headers and send invalidation requests to your HTTP cache", + "homepage": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle", + "keywords": [ + "caching", + "esi", + "http", + "invalidation", + "purge", + "varnish" + ], + "time": "2016-02-24T21:36:18+00:00" + }, + { + "name": "friendsofsymfony/rest-bundle", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git", + "reference": "8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1", + "reference": "8f79a7119962c30c2bdbf53b16ecbb73a89ae6b1", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^1.0", + "php": "^5.5.9|~7.0", + "psr/log": "^1.0", + "symfony/finder": "^2.7|^3.0", + "symfony/framework-bundle": "^2.7|^3.0", + "symfony/routing": "^2.7|^3.0", + "willdurand/jsonp-callback-validator": "^1.0", + "willdurand/negotiation": "^2.0" + }, + "conflict": { + "sensio/framework-extra-bundle": "<3.0.13" + }, + "require-dev": { + "jms/serializer-bundle": "^1.0", + "phpoption/phpoption": "^1.1", + "sensio/framework-extra-bundle": "^3.0.13", + "sllh/php-cs-fixer-styleci-bridge": "^1.3", + "symfony/browser-kit": "^2.7|^3.0", + "symfony/css-selector": "^2.7|^3.0", + "symfony/dependency-injection": "^2.7|^3.0", + "symfony/expression-language": "~2.7|^3.0", + "symfony/form": "^2.7|^3.0", + "symfony/phpunit-bridge": "~2.7|^3.0", + "symfony/security-bundle": "^2.7|^3.0", + "symfony/serializer": "^2.7.11|^3.0.4", + "symfony/twig-bundle": "^2.7|^3.0", + "symfony/validator": "^2.7|^3.0", + "symfony/web-profiler-bundle": "^2.7|^3.0", + "symfony/yaml": "^2.7|^3.0" + }, + "suggest": { + "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended, requires ^1.0", + "sensio/framework-extra-bundle": "Add support for route annotations and the view response listener, requires ^3.0", + "symfony/expression-language": "Add support for using the expression language in the routing, requires ^2.7|^3.0", + "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ^2.7|^3.0", + "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ^2.7|^3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\RestBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukas Kahwe Smith", + "email": "smith@pooteeweet.org" + }, + { + "name": "FriendsOfSymfony Community", + "homepage": "https://github.com/friendsofsymfony/FOSRestBundle/contributors" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com" + } + ], + "description": "This Bundle provides various tools to rapidly develop RESTful API's with Symfony", + "homepage": "http://friendsofsymfony.github.com", + "keywords": [ + "rest" + ], + "time": "2016-06-21T08:45:19+00:00" + }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "abandoned": "guzzlehttp/guzzle", + "time": "2015-03-18T18:23:50+00:00" + }, + { + "name": "hautelook/templated-uri-bundle", + "version": "2.0.1", + "target-dir": "Hautelook/TemplatedUriBundle", + "source": { + "type": "git", + "url": "https://github.com/goetas/TemplatedUriBundle.git", + "reference": "abf784feea984783eab0a822541c7aa3f58d445e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/goetas/TemplatedUriBundle/zipball/abf784feea984783eab0a822541c7aa3f58d445e", + "reference": "abf784feea984783eab0a822541c7aa3f58d445e", + "shasum": "" + }, + "require": { + "hautelook/templated-uri-router": "~2.0", + "php": ">=5.3.0", + "symfony/framework-bundle": "~2.1|~3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-0": { + "Hautelook\\TemplatedUriBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Baldur Rensch", + "email": "brensch@gmail.com" + } + ], + "description": "Symfony2 Bundle that provides a RFC-6570 compatible router and URL Generator.", + "homepage": "http://www.hautelooktech.com/", + "keywords": [ + "HATEOAS", + "RFC 6570", + "Symfony2", + "json", + "uri", + "url", + "xml" + ], + "support": { + "issues": "https://github.com/goetas/TemplatedUriBundle/issues", + "source": "https://github.com/goetas/TemplatedUriBundle/tree/2.0.1" + }, + "time": "2016-04-28T22:18:53+00:00" + }, + { + "name": "hautelook/templated-uri-router", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/goetas/TemplatedUriRouter.git", + "reference": "608b228c1b9dda0a2078ac3731837e3ac9295cb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/goetas/TemplatedUriRouter/zipball/608b228c1b9dda0a2078ac3731837e3ac9295cb0", + "reference": "608b228c1b9dda0a2078ac3731837e3ac9295cb0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/routing": "~2.5|~3.0|^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.7|^6.5" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hautelook\\TemplatedUriRouter\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Baldur Rensch", + "email": "brensch@gmail.com" + } + ], + "description": "Symfony2 RFC-6570 compatible router and URL Generator", + "homepage": "http://www.hautelooktech.com/", + "keywords": [ + "HATEOAS", + "RFC 6570", + "Symfony2", + "json", + "router", + "uri", + "url", + "xml" + ], + "support": { + "issues": "https://github.com/goetas/TemplatedUriRouter/issues", + "source": "https://github.com/goetas/TemplatedUriRouter/tree/2.0.3" + }, + "time": "2018-07-11T16:41:25+00:00" + }, + { + "name": "incenteev/composer-parameter-handler", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/Incenteev/ParameterHandler.git", + "reference": "d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Incenteev/ParameterHandler/zipball/d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc", + "reference": "d7ce7f06136109e81d1cb9d57066c4d4a99cf1cc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/yaml": "~2.3|~3.0" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpspec/prophecy-phpunit": "~1.0", + "symfony/filesystem": "~2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Incenteev\\ParameterHandler\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + } + ], + "description": "Composer script handling your ignored parameter file", + "homepage": "https://github.com/Incenteev/ParameterHandler", + "keywords": [ + "parameters management" + ], + "time": "2015-11-10T17:04:01+00:00" + }, + { + "name": "jdorn/sql-formatter", + "version": "v1.2.17", + "source": { + "type": "git", + "url": "https://github.com/jdorn/sql-formatter.git", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "lib" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "http://jeremydorn.com/" + } + ], + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/jdorn/sql-formatter/", + "keywords": [ + "highlight", + "sql" + ], + "time": "2014-01-12T16:20:24+00:00" + }, + { + "name": "jms/metadata", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata.git", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/22b72455559a25777cfd28c4ffda81ff7639f353", + "reference": "22b72455559a25777cfd28c4ffda81ff7639f353", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "doctrine/cache": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Metadata\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache" + ], + "authors": [ + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "Class/method/property metadata management in PHP", + "keywords": [ + "annotations", + "metadata", + "xml", + "yaml" + ], + "time": "2014-07-12T07:13:19+00:00" + }, + { + "name": "jms/parser-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/parser-lib.git", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/parser-lib/zipball/c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d", + "shasum": "" + }, + "require": { + "phpoption/phpoption": ">=0.9,<2.0-dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "description": "A library for easily creating recursive-descent parsers.", + "time": "2012-11-18T18:08:43+00:00" + }, + { + "name": "jms/serializer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/serializer.git", + "reference": "fe13a1f993ea3456e195b7820692f2eb2b6bbb48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/fe13a1f993ea3456e195b7820692f2eb2b6bbb48", + "reference": "fe13a1f993ea3456e195b7820692f2eb2b6bbb48", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/instantiator": "~1.0.3", + "jms/metadata": "~1.1", + "jms/parser-lib": "1.*", + "php": ">=5.4.0", + "phpcollection/phpcollection": "~0.1" + }, + "conflict": { + "twig/twig": "<1.12" + }, + "require-dev": { + "doctrine/orm": "~2.1", + "doctrine/phpcr-odm": "~1.0.1", + "jackalope/jackalope-doctrine-dbal": "1.0.*", + "phpunit/phpunit": "~4.0", + "propel/propel1": "~1.7", + "symfony/filesystem": "2.*", + "symfony/form": "~2.1", + "symfony/translation": "~2.0", + "symfony/validator": "~2.0", + "symfony/yaml": "2.*", + "twig/twig": "~1.12|~2.0" + }, + "suggest": { + "symfony/yaml": "Required if you'd like to serialize data to YAML format." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\Serializer": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", + "homepage": "http://jmsyst.com/libs/serializer", + "keywords": [ + "deserialization", + "jaxb", + "json", + "serialization", + "xml" + ], + "time": "2015-10-27T09:24:41+00:00" + }, + { + "name": "jms/serializer-bundle", + "version": "1.1.0", + "target-dir": "JMS/SerializerBundle", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/JMSSerializerBundle.git", + "reference": "3e396c980545350c2efb65a50041d2a9f9d6562e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/3e396c980545350c2efb65a50041d2a9f9d6562e", + "reference": "3e396c980545350c2efb65a50041d2a9f9d6562e", + "shasum": "" + }, + "require": { + "jms/serializer": "^1.0.0", + "php": ">=5.4.0", + "phpoption/phpoption": "^1.1.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "doctrine/doctrine-bundle": "*", + "doctrine/orm": "*", + "symfony/browser-kit": "*", + "symfony/class-loader": "*", + "symfony/css-selector": "*", + "symfony/finder": "*", + "symfony/form": "*", + "symfony/process": "*", + "symfony/stopwatch": "*", + "symfony/twig-bundle": "*", + "symfony/validator": "*", + "symfony/yaml": "*" + }, + "suggest": { + "jms/di-extra-bundle": "Required to get lazy loading (de)serialization visitors, ~1.3" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-0": { + "JMS\\SerializerBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Allows you to easily serialize, and deserialize data of any complexity", + "homepage": "http://jmsyst.com/bundles/JMSSerializerBundle", + "keywords": [ + "deserialization", + "jaxb", + "json", + "serialization", + "xml" + ], + "time": "2015-11-10T12:26:42+00:00" + }, + { + "name": "kriswallsmith/assetic", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/kriswallsmith/assetic.git", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/9928f7c4ad98b234e3559d1049abd13387f86db5", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/process": "~2.1|~3.0" + }, + "conflict": { + "twig/twig": "<1.23" + }, + "require-dev": { + "cssmin/cssmin": "3.0.1", + "joliclic/javascript-packer": "1.1", + "kamicane/packager": "1.0", + "leafo/lessphp": "^0.3.7", + "leafo/scssphp": "~0.1", + "mrclay/minify": "~2.2", + "patchwork/jsqueeze": "~1.0|~2.0", + "phpunit/phpunit": "~4.8", + "psr/log": "~1.0", + "ptachoire/cssembed": "~1.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "twig/twig": "~1.8|~2.0" + }, + "suggest": { + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", + "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", + "twig/twig": "Assetic provides the integration with the Twig templating engine" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-0": { + "Assetic": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ], + "time": "2015-11-12T13:51:40+00:00" + }, + { + "name": "michelf/php-markdown", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "156e56ee036505ec637d761ee62dc425d807183c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", + "reference": "156e56ee036505ec637d761ee62dc425d807183c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-lib": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2015-12-24T01:37:31+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.19.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "raven/raven": "Allow sending log messages to a Sentry server", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2016-04-12T18:29:35+00:00" + }, + { + "name": "nelmio/api-doc-bundle", + "version": "2.11.2", + "target-dir": "Nelmio/ApiDocBundle", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioApiDocBundle.git", + "reference": "1ae2cfa9a50279d722d6b6e7b02322cef948d55d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/1ae2cfa9a50279d722d6b6e7b02322cef948d55d", + "reference": "1ae2cfa9a50279d722d6b6e7b02322cef948d55d", + "shasum": "" + }, + "require": { + "michelf/php-markdown": "~1.4", + "php": ">=5.3", + "symfony/console": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0", + "symfony/twig-bundle": "~2.3|~3.0" + }, + "conflict": { + "jms/serializer": "<0.12", + "jms/serializer-bundle": "<0.11", + "twig/twig": "<1.12" + }, + "require-dev": { + "doctrine/doctrine-bundle": "~1.5", + "doctrine/orm": "~2.3", + "dunglas/api-bundle": "~1.0@dev", + "friendsofsymfony/rest-bundle": "~1.0|~2.0", + "jms/serializer-bundle": ">=0.11", + "sensio/framework-extra-bundle": "~3.0", + "symfony/browser-kit": "~2.3|~3.0", + "symfony/css-selector": "~2.3|~3.0", + "symfony/finder": "~2.3|~3.0", + "symfony/form": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/serializer": "~2.7|~3.0", + "symfony/validator": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "suggest": { + "dunglas/api-bundle": "For making use of resources definitions of DunglasApiBundle.", + "friendsofsymfony/rest-bundle": "For making use of REST information in the doc.", + "jms/serializer": "For making use of serializer information in the doc.", + "symfony/form": "For using form definitions as input.", + "symfony/validator": "For making use of validator information in the doc." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.11-dev" + } + }, + "autoload": { + "psr-0": { + "Nelmio\\ApiDocBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nelmio", + "homepage": "http://nelm.io" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors" + } + ], + "description": "Generates documentation for your REST API from annotations", + "keywords": [ + "api", + "doc", + "documentation", + "rest" + ], + "time": "2015-12-16T15:17:51+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2016-03-18T20:34:03+00:00" + }, + { + "name": "phpcollection/phpcollection", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-collection.git", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-collection/zipball/b8bf55a0a929ca43b01232b36719f176f86c7e83", + "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83", + "shasum": "" + }, + "require": { + "phpoption/phpoption": "1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpCollection": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "http://jmsyst.com", + "role": "Developer of wrapped JMSSerializerBundle" + } + ], + "description": "General-Purpose Collection Library for PHP", + "keywords": [ + "collection", + "list", + "map", + "sequence", + "set" + ], + "time": "2014-03-11T13:46:42+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-0": { + "PhpOption\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "time": "2015-07-25T16:39:46+00:00" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21T11:40:51+00:00" + }, + { + "name": "sensio/distribution-bundle", + "version": "v4.0.7", + "target-dir": "Sensio/Bundle/DistributionBundle", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", + "reference": "d738952285a1a7d969f9338f735108c9f65bb7f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/d738952285a1a7d969f9338f735108c9f65bb7f2", + "reference": "d738952285a1a7d969f9338f735108c9f65bb7f2", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "sensiolabs/security-checker": "~3.0", + "symfony/class-loader": "~2.2", + "symfony/framework-bundle": "~2.3", + "symfony/process": "~2.2" + }, + "require-dev": { + "symfony/form": "~2.2", + "symfony/validator": "~2.2", + "symfony/yaml": "~2.2" + }, + "suggest": { + "symfony/form": "If you want to use the configurator", + "symfony/validator": "If you want to use the configurator", + "symfony/yaml": "If you want to use the configurator" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Sensio\\Bundle\\DistributionBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Base bundle for Symfony Distributions", + "keywords": [ + "configuration", + "distribution" + ], + "time": "2016-06-23T16:10:25+00:00" + }, + { + "name": "sensio/framework-extra-bundle", + "version": "v3.0.16", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", + "reference": "507a15f56fa7699f6cc8c2c7de4080b19ce22546" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/507a15f56fa7699f6cc8c2c7de4080b19ce22546", + "reference": "507a15f56fa7699f6cc8c2c7de4080b19ce22546", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.2", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" + }, + "require-dev": { + "symfony/browser-kit": "~2.3|~3.0", + "symfony/dom-crawler": "~2.3|~3.0", + "symfony/expression-language": "~2.4|~3.0", + "symfony/finder": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/security-bundle": "~2.4|~3.0", + "symfony/twig-bundle": "~2.3|~3.0", + "twig/twig": "~1.11|~2.0" + }, + "suggest": { + "symfony/expression-language": "", + "symfony/psr-http-message-bridge": "To use the PSR-7 converters", + "symfony/security-bundle": "" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2016-03-25T17:08:27+00:00" + }, + { + "name": "sensiolabs/security-checker", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/security-checker.git", + "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/21696b0daa731064c23cfb694c60a2584a7b6e93", + "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93", + "shasum": "" + }, + "require": { + "symfony/console": "~2.0|~3.0" + }, + "bin": [ + "security-checker" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-0": { + "SensioLabs\\Security": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "A security checker for your composer.lock", + "time": "2015-11-07T08:07:40+00:00" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.4.2", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "d8db871a54619458a805229a057ea2af33c753e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8", + "reference": "d8db871a54619458a805229a057ea2af33c753e8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1,<0.9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2016-05-01T08:45:47+00:00" + }, + { + "name": "symfony/assetic-bundle", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/assetic-bundle.git", + "reference": "aa5b4f8b712f38745928fa845ddb73300bb2af6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/assetic-bundle/zipball/aa5b4f8b712f38745928fa845ddb73300bb2af6d", + "reference": "aa5b4f8b712f38745928fa845ddb73300bb2af6d", + "shasum": "" + }, + "require": { + "kriswallsmith/assetic": "~1.3", + "php": ">=5.3.0", + "symfony/console": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/framework-bundle": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "conflict": { + "kriswallsmith/spork": "<=0.2", + "twig/twig": "<1.20" + }, + "require-dev": { + "kriswallsmith/spork": "~0.3", + "patchwork/jsqueeze": "~1.0", + "symfony/class-loader": "~2.3|~3.0", + "symfony/css-selector": "~2.3|~3.0", + "symfony/dom-crawler": "~2.3|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/twig-bundle": "~2.3|~3.0" + }, + "suggest": { + "kriswallsmith/spork": "to be able to dump assets in parallel", + "symfony/twig-bundle": "to use the Twig integration" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\AsseticBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Integrates Assetic into Symfony2", + "homepage": "https://github.com/symfony/AsseticBundle", + "keywords": [ + "assets", + "compression", + "minification" + ], + "time": "2015-12-28T13:12:39+00:00" + }, + { + "name": "symfony/monolog-bundle", + "version": "2.11.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00", + "reference": "e7caf4936c7be82bc6d68df87f1d23a0d5bf6e00", + "shasum": "" + }, + "require": { + "monolog/monolog": "~1.18", + "php": ">=5.3.2", + "symfony/config": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/http-kernel": "~2.3|~3.0", + "symfony/monolog-bridge": "~2.3|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "symfony/console": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony MonologBundle", + "homepage": "http://symfony.com", + "keywords": [ + "log", + "logging" + ], + "time": "2016-04-13T16:21:01+00:00" + }, + { + "name": "symfony/polyfill-apcu", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "6d58bceaeea2c2d3eb62503839b18646e161cd6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/6d58bceaeea2c2d3eb62503839b18646e161cd6b", + "reference": "6d58bceaeea2c2d3eb62503839b18646e161cd6b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-05-18T14:26:46+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "dff51f72b0706335131b00a7f49606168c582594" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", + "reference": "dff51f72b0706335131b00a7f49606168c582594", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-05-18T14:26:46+00:00" + }, + { + "name": "symfony/swiftmailer-bundle", + "version": "v2.3.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/swiftmailer-bundle.git", + "reference": "5e1a90f28213231ceee19c953bbebc5b5b95c690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/swiftmailer-bundle/zipball/5e1a90f28213231ceee19c953bbebc5b5b95c690", + "reference": "5e1a90f28213231ceee19c953bbebc5b5b95c690", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "swiftmailer/swiftmailer": ">=4.2.0,~5.0", + "symfony/config": "~2.3|~3.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/http-kernel": "~2.3|~3.0", + "symfony/yaml": "~2.3|~3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "suggest": { + "psr/log": "Allows logging" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\SwiftmailerBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony SwiftmailerBundle", + "homepage": "http://symfony.com", + "time": "2016-01-15T16:41:20+00:00" + }, + { + "name": "symfony/symfony", + "version": "v2.7.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/symfony.git", + "reference": "fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/symfony/zipball/fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1", + "reference": "fe443f4a8b6b2f3977d4fe6b348e9f85a7840ea1", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.4", + "paragonie/random_compat": "~1.0", + "php": ">=5.3.9", + "psr/log": "~1.0", + "symfony/polyfill-apcu": "~1.1", + "symfony/polyfill-mbstring": "~1.1", + "twig/twig": "~1.23|~2.0" + }, + "replace": { + "symfony/asset": "self.version", + "symfony/browser-kit": "self.version", + "symfony/class-loader": "self.version", + "symfony/config": "self.version", + "symfony/console": "self.version", + "symfony/css-selector": "self.version", + "symfony/debug": "self.version", + "symfony/debug-bundle": "self.version", + "symfony/dependency-injection": "self.version", + "symfony/doctrine-bridge": "self.version", + "symfony/dom-crawler": "self.version", + "symfony/event-dispatcher": "self.version", + "symfony/expression-language": "self.version", + "symfony/filesystem": "self.version", + "symfony/finder": "self.version", + "symfony/form": "self.version", + "symfony/framework-bundle": "self.version", + "symfony/http-foundation": "self.version", + "symfony/http-kernel": "self.version", + "symfony/intl": "self.version", + "symfony/locale": "self.version", + "symfony/monolog-bridge": "self.version", + "symfony/options-resolver": "self.version", + "symfony/process": "self.version", + "symfony/property-access": "self.version", + "symfony/proxy-manager-bridge": "self.version", + "symfony/routing": "self.version", + "symfony/security": "self.version", + "symfony/security-acl": "self.version", + "symfony/security-bundle": "self.version", + "symfony/security-core": "self.version", + "symfony/security-csrf": "self.version", + "symfony/security-http": "self.version", + "symfony/serializer": "self.version", + "symfony/stopwatch": "self.version", + "symfony/swiftmailer-bridge": "self.version", + "symfony/templating": "self.version", + "symfony/translation": "self.version", + "symfony/twig-bridge": "self.version", + "symfony/twig-bundle": "self.version", + "symfony/validator": "self.version", + "symfony/var-dumper": "self.version", + "symfony/web-profiler-bundle": "self.version", + "symfony/yaml": "self.version" + }, + "require-dev": { + "doctrine/data-fixtures": "1.0.*", + "doctrine/dbal": "~2.4", + "doctrine/doctrine-bundle": "~1.2", + "doctrine/orm": "~2.4,>=2.4.5", + "egulias/email-validator": "~1.2", + "ircmaxell/password-compat": "~1.0", + "monolog/monolog": "~1.11", + "ocramius/proxy-manager": "~0.4|~1.0|~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Doctrine\\": "src/Symfony/Bridge/Doctrine/", + "Symfony\\Bridge\\Monolog\\": "src/Symfony/Bridge/Monolog/", + "Symfony\\Bridge\\ProxyManager\\": "src/Symfony/Bridge/ProxyManager/", + "Symfony\\Bridge\\Swiftmailer\\": "src/Symfony/Bridge/Swiftmailer/", + "Symfony\\Bridge\\Twig\\": "src/Symfony/Bridge/Twig/", + "Symfony\\Bundle\\": "src/Symfony/Bundle/", + "Symfony\\Component\\": "src/Symfony/Component/" + }, + "classmap": [ + "src/Symfony/Component/HttpFoundation/Resources/stubs", + "src/Symfony/Component/Intl/Resources/stubs" + ], + "files": [ + "src/Symfony/Component/Intl/Resources/stubs/functions.php" + ], + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "The Symfony PHP framework", + "homepage": "https://symfony.com", + "keywords": [ + "framework" + ], + "time": "2016-06-06T15:23:39+00:00" + }, + { + "name": "twig/twig", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512", + "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.24-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "time": "2016-05-30T09:11:59+00:00" + }, + { + "name": "willdurand/hateoas", + "version": "2.10.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Hateoas.git", + "reference": "ada89d867e47040f8c4be3be2c8e7930a3d01189" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Hateoas/zipball/ada89d867e47040f8c4be3be2c8e7930a3d01189", + "reference": "ada89d867e47040f8c4be3be2c8e7930a3d01189", + "shasum": "" + }, + "require": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.0", + "jms/metadata": "~1.1", + "jms/serializer": "~1.0", + "php": ">=5.4", + "phpoption/phpoption": ">=1.1.0,<2.0-dev", + "symfony/expression-language": "~2.4 || ~3.0" + }, + "require-dev": { + "pagerfanta/pagerfanta": "~1.0", + "phpunit/phpunit": "~4.5", + "symfony/dependency-injection": "~2.4 || ~3.0", + "symfony/routing": "~2.4 || ~3.0", + "symfony/yaml": "~2.4 || ~3.0", + "twig/twig": "~1.12" + }, + "suggest": { + "symfony/routing": "To use the SymfonyRouteFactory.", + "symfony/yaml": "To use yaml based configuration.", + "twig/twig": "To use the Twig extensions." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + } + }, + "autoload": { + "psr-0": { + "Hateoas": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Adrien Brault", + "email": "adrien.brault@gmail.com" + }, + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "A PHP library to support implementing representations for HATEOAS REST web services", + "time": "2016-05-19T11:30:35+00:00" + }, + { + "name": "willdurand/hateoas-bundle", + "version": "1.1.1", + "target-dir": "Bazinga/Bundle/HateoasBundle", + "source": { + "type": "git", + "url": "https://github.com/willdurand/BazingaHateoasBundle.git", + "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5", + "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5", + "shasum": "" + }, + "require": { + "jms/serializer-bundle": "~1.0", + "symfony/framework-bundle": "~2.2 || ~3.0", + "willdurand/hateoas": "~2.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "symfony/expression-language": "~2.4 || ~3.0", + "twig/twig": "~1.12" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-0": { + "Bazinga\\Bundle\\HateoasBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Integration of Hateoas into Symfony2.", + "keywords": [ + "HATEOAS", + "rest" + ], + "time": "2016-02-22T13:12:41+00:00" + }, + { + "name": "willdurand/jsonp-callback-validator", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/JsonpCallbackValidator.git", + "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/JsonpCallbackValidator/zipball/1a7d388bb521959e612ef50c5c7b1691b097e909", + "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonpCallbackValidator": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com", + "homepage": "http://www.willdurand.fr" + } + ], + "description": "JSONP callback validator.", + "time": "2014-01-20T22:35:06+00:00" + }, + { + "name": "willdurand/negotiation", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Negotiation.git", + "reference": "a8ce6da7acdf07351ccd6a9359c571ebc0725a21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/a8ce6da7acdf07351ccd6a9359c571ebc0725a21", + "reference": "a8ce6da7acdf07351ccd6a9359c571ebc0725a21", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Negotiation\\": "src/Negotiation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "will+git@drnd.me" + } + ], + "description": "Content Negotiation tools for PHP provided as a standalone library.", + "homepage": "http://williamdurand.fr/Negotiation/", + "keywords": [ + "accept", + "content", + "format", + "header", + "negotiation" + ], + "time": "2015-11-21T14:23:02+00:00" + }, + { + "name": "willdurand/rest-extra-bundle", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/BazingaRestExtraBundle.git", + "reference": "36e60da837a3bcef4c38d277a154d300c089a323" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/BazingaRestExtraBundle/zipball/36e60da837a3bcef4c38d277a154d300c089a323", + "reference": "36e60da837a3bcef4c38d277a154d300c089a323", + "shasum": "" + }, + "require": { + "symfony/framework-bundle": "~2.1|~3.0" + }, + "require-dev": { + "sensio/framework-extra-bundle": "~2.1", + "symfony/browser-kit": "~2.1", + "symfony/finder": "~2.1", + "symfony/form": "~2.1", + "symfony/yaml": "~2.1" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Bazinga\\Bundle\\RestExtraBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "This bundle provides extra features for your REST APIs built using Symfony2.", + "keywords": [ + "api", + "rest" + ], + "time": "2016-03-30T10:26:31+00:00" + } + ], + "packages-dev": [ + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11T14:41:42+00:00" + }, + { + "name": "mockery/mockery", + "version": "0.9.5", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2", + "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~1.1", + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2016-05-22T21:52:33+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" + }, + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/4.0" + }, + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" + }, + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/master" + }, + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + }, + "abandoned": true, + "time": "2017-11-27T05:48:46+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/5.7.27" + }, + "time": "2018-02-01T05:50:59+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", + "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.4" + }, + "abandoned": true, + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" + }, + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/1.4" + }, + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/master" + }, + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/master" + }, + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" + }, + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/master" + }, + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" + }, + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" + }, + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "sensio/generator-bundle", + "version": "v2.5.3", + "target-dir": "Sensio/Bundle/GeneratorBundle", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git", + "reference": "e50108c2133ee5c9c484555faed50c17a61221d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/e50108c2133ee5c9c484555faed50c17a61221d3", + "reference": "e50108c2133ee5c9c484555faed50c17a61221d3", + "shasum": "" + }, + "require": { + "symfony/console": "~2.5", + "symfony/framework-bundle": "~2.2" + }, + "require-dev": { + "doctrine/orm": "~2.2,>=2.2.3", + "symfony/doctrine-bridge": "~2.2", + "twig/twig": "~1.11" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Sensio\\Bundle\\GeneratorBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle generates code for you", + "time": "2015-03-17T06:36:52+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [], + "plugin-api-version": "2.1.0" +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/docker-compose.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/docker-compose.yml new file mode 100644 index 00000000..103ceebe --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3' + +services: + php: + build: . + volumes: + - ./:/var/www/html + mysql: + image: mysql:5.7 + environment: + MYSQL_USER: coupled_code + MYSQL_PASSWORD: coupled_code + MYSQL_DATABASE: coupled_code + MYSQL_ROOT_PASSWORD: coupled_code + ports: + - "3306:3306" diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/.htaccess b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/AppBundle.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/AppBundle.php new file mode 100644 index 00000000..05123b67 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/AppBundle.php @@ -0,0 +1,9 @@ +repository = $repository; + } + + public function createVideo($title, $url, $courseId): array + { + $title = $this->sanitizeTitle($title); + + $videoId = $this->repository->save($title, $url, $courseId); + + return array($title, $videoId); + } + + private function sanitizeTitle(string $title): string + { + $replacements = [ + "hexagonal" => "Hexagonal", + "solid" => "SOLID", + "tdd" => "TDD", + "frontend" => "Front-end", + ]; + + foreach ($replacements as $search => $replace) { + if (strpos($title, $search)) { + $title = str_replace($search, $replace, $title); + } + } + + return $title; + } +} \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/BaseController.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/BaseController.php new file mode 100644 index 00000000..f4d0aaed --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/BaseController.php @@ -0,0 +1,27 @@ +getDoctrine() + ->getEntityManager() + ->createQueryBuilder() + ->select('c', 'v') + ->from('AppBundle\Model\Course', 'c') + ->where('c.level', '>', $request->get('from_level', 0)) + ->getQuery() + ->execute(); + } + + public function getCourseVideosAction($courseId) + { + if ($this->hasCache('course-db-' . $courseId)) { + return $this->getCache('course-db-' . $courseId); + } else { + $this->setCache( + 'course-db-' . $courseId, + $this->getDoctrine() + ->getEntityManager() + ->createQueryBuilder() + ->select('c', 'v') + ->from('AppBundle\Model\Course', 'c') + ->leftJoin('a.Video', 'v') + ->where('c.id', '=', $courseId) + ->getQuery() + ->execute() + ); + } + + return $this->getCache('course-db-' . $courseId); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/NoteController.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/NoteController.php new file mode 100644 index 00000000..90b0bb08 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/NoteController.php @@ -0,0 +1,275 @@ + + */ +class NoteController extends BaseController +{ + /** + * return \AppBundle\NoteManager + */ + public function getNoteManager() + { + return $this->get('app.note_manager'); + } + + /** + * List all notes. + * + * @ApiDoc( + * resource = true, + * statusCodes = { + * 200 = "Returned when successful" + * } + * ) + * + * @Annotations\QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing notes.") + * @Annotations\QueryParam(name="limit", requirements="\d+", default="5", description="How many notes to return.") + * + * @Annotations\View() + * + * @param ParamFetcherInterface $paramFetcher param fetcher service + * + * @return array + */ + public function getNotesAction(ParamFetcherInterface $paramFetcher) + { + $offset = $paramFetcher->get('offset'); + $start = null == $offset ? 0 : $offset + 1; + $limit = $paramFetcher->get('limit'); + + $notes = $this->getNoteManager()->fetch($start, $limit); + + return new NoteCollection($notes, $offset, $limit); + } + + /** + * Presents the form to use to create a new note. + * + * @ApiDoc( + * resource = true, + * statusCodes = { + * 200 = "Returned when successful" + * } + * ) + * + * @Annotations\View() + * + * @return FormTypeInterface + */ + public function newNoteAction() + { + return $this->createForm(new NoteType()); + } + + /** + * Get a single note. + * + * @ApiDoc( + * output = "AppBundle\Model\Note", + * statusCodes = { + * 200 = "Returned when successful", + * 404 = "Returned when the note is not found" + * } + * ) + * + * @Annotations\View(templateVar="note") + * + * @param int $id the note id + * + * @return array + * + * @throws NotFoundHttpException when note not exist + */ + public function getNoteAction($id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + throw $this->createNotFoundException("Note does not exist."); + } + + $view = new View($note); + $group = $this->container->get('security.context')->isGranted('ROLE_API') ? 'restapi' : 'standard'; + $view->getContext()->addGroup('Default'); + $view->getContext()->addGroup($group); + + return $view; + } + + /** + * Creates a new note from the submitted data. + * + * @ApiDoc( + * resource = true, + * input = "AppBundle\Form\NoteType", + * statusCodes = { + * 200 = "Returned when successful", + * 400 = "Returned when the form has errors" + * } + * ) + * + * @Annotations\View( + * template = "AppBundle:Note:newNote.html.twig", + * statusCode = Response::HTTP_BAD_REQUEST + * ) + * + * @param Request $request the request object + * + * @return FormTypeInterface[]|View + */ + public function postNotesAction(Request $request) + { + $note = new Note(); + $form = $this->createForm(new NoteType(), $note); + + $form->submit($request); + if ($form->isValid()) { + $this->getNoteManager()->set($note); + + return $this->routeRedirectView('get_note', array('id' => $note->id)); + } + + return array( + 'form' => $form + ); + } + + /** + * Presents the form to use to update an existing note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 200 = "Returned when successful", + * 404 = "Returned when the note is not found" + * } + * ) + * + * @Annotations\View() + * + * @param int $id the note id + * + * @return FormTypeInterface + * + * @throws NotFoundHttpException when note not exist + */ + public function editNotesAction($id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + throw $this->createNotFoundException("Note does not exist."); + } + + return $this->createForm(new NoteType(), $note); + } + + /** + * Update existing note from the submitted data or create a new note at a specific location. + * + * @ApiDoc( + * resource = true, + * input = "AppBundle\Form\NoteType", + * statusCodes = { + * 201 = "Returned when a new resource is created", + * 204 = "Returned when successful", + * 400 = "Returned when the form has errors" + * } + * ) + * + * @Annotations\View( + * template="AppBundle:Note:editNote.html.twig", + * templateVar="form" + * ) + * + * @param Request $request the request object + * @param int $id the note id + * + * @return FormTypeInterface|RouteRedirectView + * + * @throws NotFoundHttpException when note not exist + */ + public function putNotesAction(Request $request, $id) + { + $note = $this->getNoteManager()->get($id); + if (false === $note) { + $note = new Note(); + $note->id = $id; + $statusCode = Response::HTTP_CREATED; + } else { + $statusCode = Response::HTTP_NO_CONTENT; + } + + $form = $this->createForm(new NoteType(), $note); + + $form->submit($request); + if ($form->isValid()) { + $this->getNoteManager()->set($note); + + return $this->routeRedirectView('get_note', array('id' => $note->id), $statusCode); + } + + return $form; + } + + /** + * Removes a note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 204="Returned when successful" + * } + * ) + * + * @param int $id the note id + * + * @return View + */ + public function deleteNotesAction($id) + { + $this->getNoteManager()->remove($id); + + // There is a debate if this should be a 404 or a 204 + // see http://leedavis81.github.io/is-a-http-delete-requests-idempotent/ + return $this->routeRedirectView('get_notes', array(), Response::HTTP_NO_CONTENT); + } + + /** + * Removes a note. + * + * @ApiDoc( + * resource = true, + * statusCodes={ + * 204="Returned when successful" + * } + * ) + * + * @param int $id the note id + * + * @return View + */ + public function removeNotesAction($id) + { + return $this->deleteNotesAction($id); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/VideoController.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/VideoController.php new file mode 100644 index 00000000..09cf98e5 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Controller/VideoController.php @@ -0,0 +1,39 @@ +get('title'); + $url = $request->get('url'); + $courseId = $request->get('course_id'); + $connection = $this->getDoctrine()->getConnection(); + $videoCreator = new VideoCreator(new MySqlVideoRepository($connection)); + + list($title, $videoId) = $videoCreator->createVideo($title, $url, $courseId); + + // And we return the video created + return [ + 'id' => $videoId, + 'title' => $title, + 'url' => $url, + 'course_id' => $courseId, + ]; + } + +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/DependencyInjection/AppExtension.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/DependencyInjection/AppExtension.php new file mode 100644 index 00000000..bfb9b582 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/DependencyInjection/AppExtension.php @@ -0,0 +1,17 @@ +load('services.xml'); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/EventListener/ControllerListener.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/EventListener/ControllerListener.php new file mode 100644 index 00000000..c170b9e9 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/EventListener/ControllerListener.php @@ -0,0 +1,24 @@ +extension = $extension; + } + + public function onKernelController(FilterControllerEvent $event) + { + if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { + $this->extension->setController($event->getController()); + } + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Form/NoteType.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Form/NoteType.php new file mode 100644 index 00000000..b5f3e492 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Form/NoteType.php @@ -0,0 +1,31 @@ +add('message', 'textarea', array( + 'description' => 'A brief record of points or ideas written down as an aid to memory', + )); + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'AppBundle\Model\Note', + 'intention' => 'note', + 'translation_domain' => 'AppBundle' + )); + } + + public function getName() + { + return 'note'; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Course.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Course.php new file mode 100644 index 00000000..3b9f63a4 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Course.php @@ -0,0 +1,29 @@ +title ?: self::DEFAULT_TITLE; + } + + public function getLevel() + { + return $this->level ?: self::DEFAULT_LEVEL; + } + + public function getType() + { + return $this->type ?: self::DEFAULT_TYPE; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Event.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Event.php new file mode 100644 index 00000000..259fe298 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Event.php @@ -0,0 +1,35 @@ +name = $name; + $this->date = $date; + } + + public function getName() + { + return $this->name; + } + + public function getDate() + { + return $this->date; + } + + public function setName($name) + { + $this->name = $name; + } + + public function setDate(\DateTime $date) + { + $this->date = $date; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Note.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Note.php new file mode 100644 index 00000000..93888a0a --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/Note.php @@ -0,0 +1,59 @@ +message; + } + + public function getAssociatedEventsRel() + { + return 'associated_events'; + } + + public function getAssociatedEvents() + { + return array( + new Event('SymfonyCon', new \DateTime('December 12, 2013')), + new Event('Christmas Day', new \DateTime('December 25, 2013')), + ); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/NoteCollection.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/NoteCollection.php new file mode 100644 index 00000000..b00f6f66 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Model/NoteCollection.php @@ -0,0 +1,33 @@ +notes = $notes; + $this->offset = $offset; + $this->limit = $limit; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/NoteManager.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/NoteManager.php new file mode 100644 index 00000000..7f142cee --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/NoteManager.php @@ -0,0 +1,82 @@ +data = unserialize($data); + } + + $this->randomGenerator = $randomGenerator; + $this->cacheDir = $cacheDir; + } + + private function flush() + { + file_put_contents($this->cacheDir . '/sf_note_data', serialize($this->data)); + } + + public function fetch($start = 0, $limit = 5) + { + return array_slice($this->data, $start, $limit, true); + } + + public function get($id) + { + if (!isset($this->data[$id])) { + return false; + } + + return $this->data[$id]; + } + + public function set($note) + { + if (null === $note->id) { + if (empty($this->data)) { + $note->id = 0; + } else { + end($this->data); + $note->id = key($this->data) + 1; + } + } + + if (null === $note->secret) { + $note->secret = base64_encode($this->randomGenerator->nextBytes(64)); + } + + $this->data[$note->id] = $note; + $this->flush(); + } + + public function remove($id) + { + if (!isset($this->data[$id])) { + return false; + } + + unset($this->data[$id]); + $this->flush(); + + return true; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Repository/MySqlVideoRepository.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Repository/MySqlVideoRepository.php new file mode 100644 index 00000000..db44efba --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Repository/MySqlVideoRepository.php @@ -0,0 +1,36 @@ +connection = $connection; + } + + public function save(string $title, $url, $courseId): string + { + $sql = "INSERT INTO video (title, url, course_id) + VALUES (\"{$title}\", + \"{$url}\", + {$courseId} + )"; + + // Prepare doctrine statement + $stmt = $this->connection->prepare($sql); + $stmt->execute(); + + // IMPORTANT: Obtaining the video id. Take care, it's done without another query :) + return $this->connection->lastInsertId(); + } +} \ No newline at end of file diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Event.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Event.yml new file mode 100644 index 00000000..275c8843 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Event.yml @@ -0,0 +1,8 @@ +AppBundle\Model\Event: + exclusion_policy: ALL + xml_root_name: event + properties: + name: + expose: true + date: + expose: true diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Note.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Note.yml new file mode 100644 index 00000000..ba76bb44 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.Note.yml @@ -0,0 +1,36 @@ +AppBundle\Model\Note: + exclusion_policy: ALL + xml_root_name: note + properties: + message: + expose: true + type: string + groups: [standard, restapi] + secret: + expose: true + type: string + groups: [restapi] + version: + expose: true + type: string + until_version: 1.1 + new_version: + expose: true + type: string + serialized_name: version + since_version: 1.1 + relations: + - + rel: self + href: + route: get_note + parameters: + id: expr(object.id) + absolute: true + - + rel: expr(object.getAssociatedEventsRel()) + embed: + content: expr(object.getAssociatedEvents()) + xmlElementName: events + exclusion: + exclude_if: expr(object.id === 0) diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml new file mode 100644 index 00000000..f2e2ee6a --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/serializer/Model.NoteCollection.yml @@ -0,0 +1,34 @@ +AppBundle\Model\NoteCollection: + exclusion_policy: ALL + xml_root_name: notes + properties: + notes: + expose: true + type: array + xml_list: + inline: true + entry_name: note + offset: + expose: true + type: integer + xml_attribute: true + limit: + expose: true + type: integer + xml_attribute: true + relations: + - + rel: self + href: + route: get_notes + absolute: true + - + rel: note + href: + route: get_note + absolute: true + generator: templated_uri + parameters: + id: "{id}" + attributes: + templated: true diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/services.xml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/services.xml new file mode 100644 index 00000000..aa0ea4ad --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/services.xml @@ -0,0 +1,23 @@ + + + + + + + + %kernel.cache_dir% + + + + + + + + + + + + + diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/validation.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/validation.yml new file mode 100644 index 00000000..ab78d0c5 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/config/validation.yml @@ -0,0 +1,4 @@ +AppBundle\Model\Note: + properties: + message: + - NotBlank: ~ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/css/demo.css b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/css/demo.css new file mode 100644 index 00000000..4dd2f16c --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/css/demo.css @@ -0,0 +1,101 @@ +body { + font-size: 14px; + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; +} +h1.title { + font-size: 45px; + padding-bottom: 30px; +} +.sf-reset h2 { + font-weight: bold; + color: #FFFFFF; + /* Font is duplicated of body (sans-serif) */ + font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + + margin-bottom: 10px; + background-color: #aacd4e; + padding: 2px 4px; + display: inline-block; + text-transform: uppercase; + +} +p { + line-height: 20px; + padding-bottom: 20px; +} +ul#demo-list a { + background: url(../images/blue-arrow.png) no-repeat right 6px; + padding-right: 10px; + margin-right: 30px; +} +#symfony-header { + position: relative; + padding: 30px 30px 20px 30px; +} +.sf-reset .symfony-blocks-welcome { + overflow: hidden; +} +.sf-reset .symfony-blocks-welcome > div { + background-color: whitesmoke; + float: left; + width: 240px; + margin-right: 14px; + text-align: center; + padding: 26px 20px; +} +.sf-reset .symfony-blocks-welcome > div.block-demo { + margin-right: 0; +} +.sf-reset .symfony-blocks-welcome .illustration { + padding-bottom: 20px; +} +.sf-reset .symfony-blocks-help { + overflow: hidden; +} +.sf-reset .symfony-blocks-help { + margin-top: 30px; + padding: 18px; + border: 1px solid #E6E6E6; +} +.sf-reset .symfony-blocks-help > div { + width: 254px; + float: left; +} +.flash-message { + padding: 10px; + margin: 5px; + margin-top: 15px; + background-color: #ffe; +} +.sf-reset .error { + color: red; +} +#login label, #contact_form label { + display: block; + float: left; + width: 90px; +} +.sf-reset ul#menu { + float: right; + margin-bottom: 20px; + padding-left: 0; +} +.sf-reset #menu li { + padding-left: 0; + margin-right: 10px; + display: inline; +} +.sf-reset a, +.sf-reset li a { + color: #08C; + text-decoration: none; +} +.sf-reset a:hover, +.sf-reset li a:hover { + color: #08C; + text-decoration: underline; +} +.sf-reset .symfony-content pre { + white-space: pre; + font-family: monospace; +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/blue-arrow.png b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/blue-arrow.png new file mode 100644 index 00000000..fa82d4b4 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/blue-arrow.png differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/field-background.gif b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/field-background.gif new file mode 100644 index 00000000..7c0efc10 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/field-background.gif differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/logo.gif b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/logo.gif new file mode 100644 index 00000000..703cf45f Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/logo.gif differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/search.png b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/search.png new file mode 100644 index 00000000..3c88b6a4 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/search.png differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-configure.gif b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-configure.gif new file mode 100644 index 00000000..931179a7 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-configure.gif differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-demo.gif b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-demo.gif new file mode 100644 index 00000000..0623de54 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-demo.gif differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-quick-tour.gif b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-quick-tour.gif new file mode 100644 index 00000000..b9018b11 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/public/images/welcome-quick-tour.gif differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.de.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.de.yml new file mode 100644 index 00000000..950a4e8f --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.de.yml @@ -0,0 +1,20 @@ +note: + list: + link: zurück zur Notizliste + headline: Verfügbare Notizen + empty: Keine Notizen gefunden + new: + link: Neue Notiz anlegen + headline: Neue Notiz anlegen + submit: Notiz hinzufügen + edit: + link: Notiz bearbeiten + headline: Notiz \#%id% bearbeiten + submit: Notiz aktualisieren + remove: + link: entfernen + offset: Offset + limit: Limit +api: + doc: + link: API Dokumentation diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.en.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.en.yml new file mode 100644 index 00000000..e50c3a0d --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.en.yml @@ -0,0 +1,20 @@ +note: + list: + link: back to note list + headline: Available notes + empty: No notes found + new: + link: create new note + headline: Create new note + submit: add note + edit: + link: edit + headline: Edit note %id% + submit: update note + remove: + link: remove + offset: offset + limit: limit +api: + doc: + link: API documentation diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.es.yml b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.es.yml new file mode 100644 index 00000000..71b45856 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/translations/AppBundle.es.yml @@ -0,0 +1,20 @@ +note: + list: + link: de vuelta a la lista de notas + headline: Notas disponibles + empty: Ninguna nota encontrada + new: + link: crear una nota + headline: Crear nota + submit: añadir nota + edit: + link: editar + headline: Editar nota %id% + submit: actualizar nota + remove: + link: remover + offset: posición + limit: limite +api: + doc: + link: Documentación del API diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNote.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNote.html.twig new file mode 100644 index 00000000..14de63ca --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNote.html.twig @@ -0,0 +1,19 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.edit.headline'|trans({'%id%': id}, 'AppBundle') }}

+ +
+ + + {{ form_widget(form) }} + + +
+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNotes.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNotes.html.twig new file mode 100644 index 00000000..14de63ca --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/editNotes.html.twig @@ -0,0 +1,19 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.edit.headline'|trans({'%id%': id}, 'AppBundle') }}

+ +
+ + + {{ form_widget(form) }} + + +
+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNote.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNote.html.twig new file mode 100644 index 00000000..c27b195a --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNote.html.twig @@ -0,0 +1,18 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Note" %} + +{% block content_header '' %} + +{% block content %} +

Note #{{ id }}

+ +

{{ note }}

+

+ {{ 'note.list.link'|trans({}, 'AppBundle') }}
+ [{{ 'note.remove.link'|trans({}, 'AppBundle') }}] + [{{ 'note.edit.link'|trans({}, 'AppBundle') }}] +

+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNotes.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNotes.html.twig new file mode 100644 index 00000000..143c0c3b --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/getNotes.html.twig @@ -0,0 +1,30 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.list.headline'|trans({}, 'AppBundle') }}

+ +

+ {{ 'note.offset'|trans({}, 'AppBundle') }}: {{ data.offset ?: '-' }}, {{ 'note.limit'|trans({}, 'AppBundle') }}: {{ data.limit }} +

+ + +

+ {{ 'note.new.link'|trans({}, 'AppBundle') }} +

+{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/newNote.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/newNote.html.twig new file mode 100644 index 00000000..b22a9ad7 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/Note/newNote.html.twig @@ -0,0 +1,21 @@ +{% extends "AppBundle::layout.html.twig" %} + +{% block title "Symfony - Notes" %} + +{% block content_header '' %} + +{% block content %} +

{{ 'note.new.headline'|trans({}, 'AppBundle') }}

+ + {% if (form is defined) %} +
+ + {{ form_widget(form) }} + + +
+ {% endif %} + +{% endblock %} + +{% set code = code(_self) %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/layout.html.twig b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/layout.html.twig new file mode 100644 index 00000000..e855ab09 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Resources/views/layout.html.twig @@ -0,0 +1,35 @@ +{% extends "TwigBundle::layout.html.twig" %} + +{% block head %} + + +{% endblock %} + +{% block title 'Demo Bundle' %} + +{% block body %} + {% block content_header %} + + +
+ {% endblock %} + +
+ {% block content %}{% endblock %} + +

+ {{ 'api.doc.link'|trans({}, 'AppBundle') }} +

+
+ + {% if code is defined %} +

Code behind this page

+
+
{{ code|raw }}
+
+ {% endif %} +{% endblock %} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Application/VideoCreatorTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Application/VideoCreatorTest.php new file mode 100644 index 00000000..183d21b6 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Application/VideoCreatorTest.php @@ -0,0 +1,23 @@ +createMock(MySqlVideoRepository::class); + $videoCreator = new VideoCreator($repository); + + list($title) = $videoCreator->createVideo("Testing frontend", "url", 3); + + $this->assertEquals("Testing Front-end", $title); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/CourseControllerTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/CourseControllerTest.php new file mode 100644 index 00000000..e1c5c2bc --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/CourseControllerTest.php @@ -0,0 +1,92 @@ + $fromLevel]); + + $container = \Mockery::mock(ContainerInterface::class); + $doctrine = \Mockery::mock(Registry::class); + $entityManager = \Mockery::mock(EntityManager::class); + $queryBuilder = \Mockery::mock(QueryBuilder::class); + $query = \Mockery::mock(AbstractQuery::class); + + $container->shouldReceive('has') + ->once() + ->with('doctrine') + ->andReturn(true); + $container->shouldReceive('get') + ->once() + ->with('doctrine') + ->andReturn($doctrine); + $doctrine->shouldReceive('getEntityManager') + ->once() + ->withNoArgs() + ->andReturn($entityManager); + $entityManager->shouldReceive('createQueryBuilder') + ->once() + ->withNoArgs() + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('select') + ->once() + ->with('c', 'v') + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('from') + ->once() + ->with('AppBundle\Model\Course', 'c') + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('where') + ->once() + ->with('c.level', '>', $fromLevel) + ->andReturn($queryBuilder); + $queryBuilder->shouldReceive('getQuery') + ->once() + ->withNoArgs() + ->andReturn($query); + $query->shouldReceive('execute') + ->once() + ->withNoArgs() + ->andReturn( + [ + [ + 'title' => 'Codely mola', + 'level' => 2, + ], + [ + 'title' => 'Aprende a decir basicamente como Javi', + 'level' => 5, + ], + ] + ); + + $controller = new CourseController(); + $controller->setContainer($container); + $controllerResult = $controller->getCourseAction($request); + $this->assertEquals( + [ + [ + 'title' => 'Codely mola', + 'level' => 2, + ], + [ + 'title' => 'Aprende a decir basicamente como Javi', + 'level' => 5, + ], + ], + $controllerResult + ); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/NoteControllerTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/NoteControllerTest.php new file mode 100644 index 00000000..5e463030 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/NoteControllerTest.php @@ -0,0 +1,269 @@ +getClient()->getContainer()->getParameter('kernel.cache_dir'); + if (file_exists($cacheDir . '/sf_note_data')) { + unlink($cacheDir . '/sf_note_data'); + } + } + + public function testGetNotes() + { + $client = $this->getClient(true); + + // head request + $client->request('HEAD', '/notes.json'); + $response = $client->getResponse(); + $this->assertEquals(200, $response->getStatusCode(), $response->getContent()); + + // empty list + $client->request('GET', '/notes.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"notes":[],"limit":5,"_links":{"self":{"href":"http:\/\/localhost\/notes"},"note":{"href":"http:\/\/localhost\/notes\/{id}","templated":true}}}', $response->getContent()); + + // list + $this->createNote($client, 'my note for list'); + + $client->request('GET', '/notes.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"notes":[{"secret":"XXX","message":"my note for list","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}],"limit":5,"_links":{"self":{"href":"http:\/\/localhost\/notes"},"note":{"href":"http:\/\/localhost\/notes\/{id}","templated":true}}}', $contentWithoutSecret); + } + + public function testGetNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + } + + public function testGetNoteVersioned() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json;version=1.0')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + + $client->request('GET', '/notes/0', array(), array(), array('HTTP_ACCEPT' => 'application/json;version=1.2')); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $contentWithoutSecret = preg_replace('/"secret":"[^"]*"/', '"secret":"XXX"', $response->getContent()); + $this->assertEquals('{"secret":"XXX","message":"my note for get","version":"1.1","_links":{"self":{"href":"http:\/\/localhost\/notes\/0"}}}', $contentWithoutSecret); + } + + public function testNewNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/new.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"children":{"message":{}}}', $response->getContent()); + } + + public function testPostNote() + { + $client = $this->getClient(true); + + $this->createNote($client, 'my note for post'); + + $response = $client->getResponse(); + + $this->assertJsonResponse($response, Response::HTTP_CREATED); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testEditNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0/edit.json'); + $response = $client->getResponse(); + + $this->assertEquals(404, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":404,"message":"Note does not exist."}', $response->getContent()); + + $this->createNote($client, 'my note for post'); + + $client->request('GET', '/notes/0/edit.json'); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $this->assertEquals('{"children":{"message":{}}}', $response->getContent()); + } + + public function testPutShouldModifyANote() + { + $client = $this->getClient(true); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => '' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals(400, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":400,"message":"Validation Failed","errors":{"children":{"message":{"errors":["This value should not be blank."]}}}}', $response->getContent()); + + $this->createNote($client, 'my note for post'); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => 'my note for put' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testPutShouldCreateANote() + { + $client = $this->getClient(true); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => '' + ) + )); + $response = $client->getResponse(); + + $this->assertEquals(400, $response->getStatusCode(), $response->getContent()); + $this->assertEquals('{"code":400,"message":"Validation Failed","errors":{"children":{"message":{"errors":["This value should not be blank."]}}}}', $response->getContent()); + + $client->request('PUT', '/notes/0.json', array( + 'note' => array( + 'message' => 'my note for put' + ) + )); + $response = $client->getResponse(); + + $this->assertJsonResponse($response, Response::HTTP_CREATED); + $this->assertEquals($response->headers->get('location'), 'http://localhost/notes/0'); + } + + public function testRemoveNote() + { + $client = $this->getClient(true); + + $client->request('GET', '/notes/0/remove.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->createNote($client, 'my note for get'); + + $client->request('GET', '/notes/0/remove.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->assertTrue($response->headers->contains('location', 'http://localhost/notes')); + } + + public function testDeleteNote() + { + $client = $this->getClient(true); + + $client->request('DELETE', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + + $this->createNote($client, 'my note for get'); + + $client->request('DELETE', '/notes/0.json'); + $response = $client->getResponse(); + + $this->assertEquals( + Response::HTTP_NO_CONTENT, $response->getStatusCode(), + $response->getContent() + ); + $this->assertTrue($response->headers->contains('location', 'http://localhost/notes')); + } + + protected function createNote(Client $client, $message) + { + $client->request('POST', '/notes.json', array( + 'note' => array( + 'message' => $message + ) + )); + $response = $client->getResponse(); + $this->assertJsonResponse($response, Response::HTTP_CREATED); + } + + private function getClient($authenticated = false) + { + $params = array(); + if ($authenticated) { + $params = array_merge($params, array( + 'PHP_AUTH_USER' => 'restapi', + 'PHP_AUTH_PW' => 'secretpw', + )); + } + + return static::createClient(array(), $params); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/VideoControllerTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/VideoControllerTest.php new file mode 100644 index 00000000..483d0b4c --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Controller/VideoControllerTest.php @@ -0,0 +1,64 @@ +connection = $this->getClient()->getContainer()->get('database_connection'); + $this->connection->query("TRUNCATE video"); + } + + public function testPostVideo() + { + $client = $this->getClient(true); + + $client->request('POST', '/videos.json', [ + 'title' => 'Arquitectura hexagonal, solid y tdd', + 'url' => 'https://pro.codely.tv/library/testing-frontend', + 'course_id' => 5 + ]); + $response = $client->getResponse(); + + $this->assertJsonResponse($response); + $expectedId = "1"; + $expectedTitle = "Arquitectura Hexagonal, SOLID y TDD"; + $expectedUrl = "https://pro.codely.tv/library/testing-frontend"; + $expectedCourseId = 5; + $expectedResponse = [ + "id" => $expectedId, + "title" => $expectedTitle, + "url" => $expectedUrl, + "course_id" => $expectedCourseId + ]; + + $this->assertEquals(json_encode($expectedResponse), $response->getContent()); + + $stmt = $this->connection->prepare("SELECT * FROM video WHERE id = 1"); + $stmt->execute(); + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + $this->assertEquals($expectedTitle, $result['title']); + $this->assertEquals($expectedUrl, $result['url']); + $this->assertEquals($expectedCourseId, $result['course_id']); + } + + private function getClient($authenticated = false) + { + $params = array(); + if ($authenticated) { + $params = array_merge($params, array( + 'PHP_AUTH_USER' => 'restapi', + 'PHP_AUTH_PW' => 'secretpw', + )); + } + + return static::createClient(array(), $params); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/CourseTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/CourseTest.php new file mode 100644 index 00000000..dcae1aff --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/CourseTest.php @@ -0,0 +1,18 @@ +assertEquals(Course::DEFAULT_TITLE, $course->getTitle()); + $this->assertEquals(Course::DEFAULT_LEVEL, $course->getLevel()); + $this->assertEquals(Course::DEFAULT_TYPE, $course->getType()); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/EventTest.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/EventTest.php new file mode 100644 index 00000000..b6fbd4bd --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Tests/Model/EventTest.php @@ -0,0 +1,24 @@ +setName('New name'); + $this->assertEquals('New name', $event->getName()); + } + + public function testItShouldSetADate() + { + $event = new Event('Some name ', new \DateTime()); + $newDate = new \DateTime(); + $event->setDate($newDate); + $this->assertEquals($newDate, $event->getDate()); + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Twig/Extension/DemoExtension.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Twig/Extension/DemoExtension.php new file mode 100644 index 00000000..f1751d49 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Twig/Extension/DemoExtension.php @@ -0,0 +1,81 @@ +loader = $loader; + } + + public function setController($controller) + { + $this->controller = $controller; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return array( + 'code' => new \Twig_Function_Method($this, 'getCode', array('is_safe' => array('html'))), + ); + } + + public function getCode($template) + { + // highlight_string highlights php code only if 'getControllerCode(), true); + $controller = str_replace('<?php    ', '    ', $controller); + + $template = htmlspecialchars($this->getTemplateCode($template), ENT_QUOTES, 'UTF-8'); + + // remove the code block + $template = str_replace('{% set code = code(_self) %}', '', $template); + + return <<Controller Code

+
$controller
+ +

Template Code

+
$template
+EOF; + } + + protected function getControllerCode() + { + $class = get_class($this->controller[0]); + if (class_exists('CG\Core\ClassUtils')) { + $class = ClassUtils::getUserClass($class); + } + + $r = new \ReflectionClass($class); + $m = $r->getMethod($this->controller[1]); + + $code = file($r->getFilename()); + + return ' '.$m->getDocComment()."\n".implode('', array_slice($code, $m->getStartline() - 1, $m->getEndLine() - $m->getStartline() + 1)); + } + + protected function getTemplateCode($template) + { + return $this->loader->getSource($template->getTemplateName()); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'demo'; + } +} diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Util/Cache.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Util/Cache.php new file mode 100644 index 00000000..f5d901fb --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/src/AppBundle/Util/Cache.php @@ -0,0 +1,23 @@ + + RewriteEngine On + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/app.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the startpage because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) + RewriteCond %{ENV:REDIRECT_STATUS} ^$ + RewriteRule ^app\.php(/(.*)|$) %{CONTEXT_PREFIX}/$2 [R=301,L] + + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule .? - [L] + + # The following rewrites all other queries to the front controller. The + # condition ensures that if you are using Apache aliases to do mass virtual + # hosting, the base path will be prepended to allow proper resolution of the + # app.php file; it will work in non-aliased environments as well, providing + # a safe, one-size fits all solution. + RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ + RewriteRule ^(.*) - [E=BASE:%1] + RewriteRule .? %{ENV:BASE}app.php [L] + + + + + # When mod_rewrite is not available, we instruct a temporary redirect of + # the startpage to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 302 ^/$ /app.php/ + # RedirectTemp cannot be used instead + + diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app.php new file mode 100644 index 00000000..33408737 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app.php @@ -0,0 +1,25 @@ +register(true); +*/ + +require_once __DIR__.'/../app/AppKernel.php'; +//require_once __DIR__.'/../app/AppCache.php'; + +$kernel = new AppKernel('prod', false); +//$kernel = new AppCache($kernel); +Request::enableHttpMethodParameterOverride(); +$request = Request::createFromGlobals(); +$response = $kernel->handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app_dev.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app_dev.php new file mode 100644 index 00000000..0d64e4f5 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/app_dev.php @@ -0,0 +1,27 @@ +handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/apple-touch-icon.png b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/apple-touch-icon.png new file mode 100644 index 00000000..11f17e6d Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/apple-touch-icon.png differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/config.php b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/config.php new file mode 100644 index 00000000..74d052ac --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/config.php @@ -0,0 +1,128 @@ +getFailedRequirements(); +$minorProblems = $symfonyRequirements->getFailedRecommendations(); + +?> + + + + + + Symfony Configuration + + + + + +
+
+ + + +
+ +
+
+
+

Welcome!

+

Welcome to your new Symfony project.

+

+ This script will guide you through the basic configuration of your project. + You can also do the same by editing the ‘app/config/parameters.yml’ file directly. +

+ + +

Major problems

+

Major problems have been detected and must be fixed before continuing:

+
    + +
  1. getTestMessage() ?> +

    getHelpHtml() ?>

    +
  2. + +
+ + + +

Recommendations

+

+ Additionally, toTo enhance your Symfony experience, + it’s recommended that you fix the following: +

+
    + +
  1. getTestMessage() ?> +

    getHelpHtml() ?>

    +
  2. + +
+ + + hasPhpIniConfigIssue()): ?> +

* + getPhpIniConfigPath()): ?> + Changes to the php.ini file must be done in "getPhpIniConfigPath() ?>". + + To change settings, create a "php.ini". + +

+ + + +

Your configuration looks good to run Symfony.

+ + + +
+
+
+
Symfony Standard Edition
+
+ + diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/favicon.ico b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/favicon.ico new file mode 100644 index 00000000..86480361 Binary files /dev/null and b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/favicon.ico differ diff --git a/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/robots.txt b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/robots.txt new file mode 100644 index 00000000..214e4119 --- /dev/null +++ b/exercises/legacy_create_video/solutions/codely_php-symfony_golden-master/web/robots.txt @@ -0,0 +1,4 @@ +# www.robotstxt.org/ +# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 + +User-agent: *