diff --git a/app/AppKernel.php b/app/AppKernel.php
index 3789b32..2c9daeb 100644
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -8,6 +8,7 @@ class AppKernel extends Kernel
public function registerBundles()
{
$bundles = [
+ // symfony
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
@@ -15,6 +16,13 @@ class AppKernel extends Kernel
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
+
+ // dependencies
+ new FOS\RestBundle\FOSRestBundle(),
+ new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
+ new JMS\SerializerBundle\JMSSerializerBundle(),
+
+ // app
new AppBundle\AppBundle(),
];
@@ -23,6 +31,7 @@ class AppKernel extends Kernel
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
+ $bundles[] = new Nelmio\ApiDocBundle\NelmioApiDocBundle();
}
return $bundles;
diff --git a/app/config/config.yml b/app/config/config.yml
index 3292445..675bc9a 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -2,6 +2,7 @@ imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
+ - { resource: rest.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
diff --git a/app/config/config_dev.yml b/app/config/config_dev.yml
index 7eb4739..e4a8ec7 100644
--- a/app/config/config_dev.yml
+++ b/app/config/config_dev.yml
@@ -11,6 +11,8 @@ web_profiler:
toolbar: true
intercept_redirects: false
+nelmio_api_doc: ~
+
monolog:
handlers:
main:
diff --git a/app/config/rest.yml b/app/config/rest.yml
new file mode 100644
index 0000000..3d0c0dd
--- /dev/null
+++ b/app/config/rest.yml
@@ -0,0 +1,22 @@
+fos_js_routing:
+ routes_to_expose:
+
+fos_rest:
+ serializer:
+ serialize_null: true
+ param_fetcher_listener: true
+ body_listener: true
+ format_listener: true
+ view:
+ view_response_listener: true
+ formats:
+ xml: true
+ json : true
+ templating_formats:
+ html: false
+ force_redirects:
+ html: true
+ failed_validation: HTTP_BAD_REQUEST
+ default_engine: twig
+ routing_loader:
+ default_format: json
diff --git a/app/config/routing.yml b/app/config/routing.yml
index 8eadc31..53af805 100644
--- a/app/config/routing.yml
+++ b/app/config/routing.yml
@@ -1,3 +1,16 @@
app:
resource: "@AppBundle/Controller/"
type: annotation
+
+api_book:
+ resource: AppBundle\Controller\Api\BookController
+ type: rest
+ prefix: api
+
+api_category:
+ resource: AppBundle\Controller\Api\CategoryController
+ type: rest
+ prefix: api
+
+fos_js_routing:
+ resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
diff --git a/app/config/routing_dev.yml b/app/config/routing_dev.yml
index 404f6a3..33dab2c 100644
--- a/app/config/routing_dev.yml
+++ b/app/config/routing_dev.yml
@@ -10,5 +10,9 @@ _errors:
resource: "@TwigBundle/Resources/config/routing/errors.xml"
prefix: /_error
+_api_doc:
+ resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
+ prefix: /api/doc
+
_main:
resource: routing.yml
diff --git a/bin/symfony_requirements b/bin/symfony_requirements
index 8825a96..a7bf65a 100755
--- a/bin/symfony_requirements
+++ b/bin/symfony_requirements
@@ -22,7 +22,6 @@ 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;
@@ -121,10 +120,14 @@ function echo_block($style, $title, $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);
+ echo_style($style, str_repeat(' ', $width));
+ echo PHP_EOL;
+ echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT));
+ echo PHP_EOL;
+ echo_style($style, $message);
+ echo PHP_EOL;
+ echo_style($style, str_repeat(' ', $width));
+ echo PHP_EOL;
}
function has_color_support()
diff --git a/composer.json b/composer.json
index 200acf4..1da6977 100644
--- a/composer.json
+++ b/composer.json
@@ -26,7 +26,11 @@
"symfony/monolog-bundle": "^2.8",
"sensio/distribution-bundle": "^5.0",
"sensio/framework-extra-bundle": "^3.0.2",
- "incenteev/composer-parameter-handler": "^2.0"
+ "incenteev/composer-parameter-handler": "^2.0",
+ "jms/serializer-bundle": "~1.1",
+ "friendsofsymfony/rest-bundle": "^1.7",
+ "friendsofsymfony/jsrouting-bundle": "1.*",
+ "nelmio/api-doc-bundle": "2.*"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
diff --git a/var/SymfonyRequirements.php b/var/SymfonyRequirements.php
index 841338f..7e7723a 100644
--- a/var/SymfonyRequirements.php
+++ b/var/SymfonyRequirements.php
@@ -168,6 +168,9 @@ class PhpIniRequirement extends Requirement
*/
class RequirementCollection implements IteratorAggregate
{
+ /**
+ * @var Requirement[]
+ */
private $requirements = array();
/**
@@ -265,7 +268,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns both requirements and recommendations.
*
- * @return array Array of Requirement instances
+ * @return Requirement[]
*/
public function all()
{
@@ -275,7 +278,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns all mandatory requirements.
*
- * @return array Array of Requirement instances
+ * @return Requirement[]
*/
public function getRequirements()
{
@@ -292,7 +295,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns the mandatory requirements that were not met.
*
- * @return array Array of Requirement instances
+ * @return Requirement[]
*/
public function getFailedRequirements()
{
@@ -309,7 +312,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns all optional recommendations.
*
- * @return array Array of Requirement instances
+ * @return Requirement[]
*/
public function getRecommendations()
{
@@ -326,7 +329,7 @@ class RequirementCollection implements IteratorAggregate
/**
* Returns the recommendations that were not met.
*
- * @return array Array of Requirement instances
+ * @return Requirement[]
*/
public function getFailedRecommendations()
{
@@ -376,7 +379,8 @@ class RequirementCollection implements IteratorAggregate
*/
class SymfonyRequirements extends RequirementCollection
{
- const REQUIRED_PHP_VERSION = '5.3.3';
+ const LEGACY_REQUIRED_PHP_VERSION = '5.3.3';
+ const REQUIRED_PHP_VERSION = '5.5.9';
/**
* Constructor that initializes the requirements.
@@ -386,16 +390,26 @@ class SymfonyRequirements extends RequirementCollection
/* mandatory requirements follow */
$installedPhpVersion = phpversion();
+ $requiredPhpVersion = $this->getPhpRequiredVersion();
- $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->addRecommendation(
+ $requiredPhpVersion,
+ 'Vendors should be installed in order to check all requirements.',
+ 'Run the composer install
command.',
+ 'Run the "composer install" command.'
);
+ if (false !== $requiredPhpVersion) {
+ $this->addRequirement(
+ version_compare($installedPhpVersion, $requiredPhpVersion, '>='),
+ sprintf('PHP version must be at least %s (%s installed)', $requiredPhpVersion, $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, $requiredPhpVersion),
+ sprintf('Install PHP %s or newer (installed version is %s)', $requiredPhpVersion, $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',
@@ -433,7 +447,7 @@ class SymfonyRequirements extends RequirementCollection
);
}
- if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
+ if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) {
$timezones = array();
foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
foreach ($abbreviations as $abbreviation) {
@@ -681,10 +695,17 @@ class SymfonyRequirements extends RequirementCollection
if (class_exists('Symfony\Component\Intl\Intl')) {
$this->addRecommendation(
- \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(),
- sprintf('intl ICU version installed on your system (%s) should match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()),
- 'In most cases you should be fine, but please verify there is no inconsistencies between data provided by Symfony and the intl extension. See https://github.com/symfony/symfony/issues/15007 for an example of inconsistencies you might run into.'
+ \Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion(),
+ sprintf('intl ICU version installed on your system is outdated (%s) and does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()),
+ 'To get the latest internationalization data upgrade the ICU system package and the intl PHP extension.'
);
+ if (\Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion()) {
+ $this->addRecommendation(
+ \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(),
+ sprintf('intl ICU version installed on your system (%s) does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()),
+ 'To avoid internationalization data inconsistencies upgrade the symfony/intl component.'
+ );
+ }
}
$this->addPhpIniRecommendation(
@@ -718,9 +739,9 @@ class SymfonyRequirements extends RequirementCollection
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->getRealpathCacheSize() >= 5 * 1024 * 1024,
+ 'realpath_cache_size should be at least 5M in php.ini',
+ 'Setting "realpath_cache_size" to e.g. "5242880" or "5M" in php.ini* may improve performance on Windows significantly in some cases.'
);
}
@@ -771,4 +792,28 @@ class SymfonyRequirements extends RequirementCollection
return (int) $size;
}
}
+
+ /**
+ * Defines PHP required version from Symfony version.
+ *
+ * @return string|false The PHP required version or false if it could not be guessed
+ */
+ protected function getPhpRequiredVersion()
+ {
+ if (!file_exists($path = __DIR__.'/../composer.lock')) {
+ return false;
+ }
+
+ $composerLock = json_decode(file_get_contents($path), true);
+ foreach ($composerLock['packages'] as $package) {
+ $name = $package['name'];
+ if ('symfony/symfony' !== $name && 'symfony/http-kernel' !== $name) {
+ continue;
+ }
+
+ return (int) $package['version'][1] > 2 ? self::REQUIRED_PHP_VERSION : self::LEGACY_REQUIRED_PHP_VERSION;
+ }
+
+ return false;
+ }
}
diff --git a/web/config.php b/web/config.php
index 5e36d79..a031a3a 100644
--- a/web/config.php
+++ b/web/config.php
@@ -28,6 +28,8 @@ $symfonyRequirements = new SymfonyRequirements();
$majorProblems = $symfonyRequirements->getFailedRequirements();
$minorProblems = $symfonyRequirements->getFailedRecommendations();
+$hasMajorProblems = (bool) count($majorProblems);
+$hasMinorProblems = (bool) count($minorProblems);
?>
@@ -36,9 +38,216 @@ $minorProblems = $symfonyRequirements->getFailedRecommendations();