]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #1167 from wallabag/v2-api-bundle
authorNicolas Lœuillet <nicolas@loeuillet.org>
Mon, 1 Jun 2015 13:49:49 +0000 (15:49 +0200)
committerNicolas Lœuillet <nicolas@loeuillet.org>
Mon, 1 Jun 2015 13:49:49 +0000 (15:49 +0200)
Move API stuff in ApiBundle

56 files changed:
.travis.yml
app/AppKernel.php
app/SymfonyRequirements.php
app/config/routing.yml
app/config/routing_rest.yml
composer.lock
src/Wallabag/ApiBundle/Controller/WallabagRestController.php [moved from src/Wallabag/CoreBundle/Controller/WallabagRestController.php with 75% similarity]
src/Wallabag/ApiBundle/DependencyInjection/Configuration.php [new file with mode: 0644]
src/Wallabag/ApiBundle/DependencyInjection/Security/Factory/WsseFactory.php [moved from src/Wallabag/CoreBundle/DependencyInjection/Security/Factory/WsseFactory.php with 94% similarity]
src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php [new file with mode: 0644]
src/Wallabag/ApiBundle/Resources/config/routing.yml [new file with mode: 0644]
src/Wallabag/ApiBundle/Resources/config/routing_rest.yml [new file with mode: 0644]
src/Wallabag/ApiBundle/Resources/config/services.yml [new file with mode: 0644]
src/Wallabag/ApiBundle/Security/Authentication/Provider/WsseProvider.php [moved from src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php with 82% similarity]
src/Wallabag/ApiBundle/Security/Authentication/Token/WsseUserToken.php [moved from src/Wallabag/CoreBundle/Security/Authentication/Token/WsseUserToken.php with 87% similarity]
src/Wallabag/ApiBundle/Security/Firewall/WsseListener.php [moved from src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php with 94% similarity]
src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php [new file with mode: 0644]
src/Wallabag/ApiBundle/WallabagApiBundle.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Command/InstallCommand.php
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Controller/EntryController.php
src/Wallabag/CoreBundle/Controller/RssController.php
src/Wallabag/CoreBundle/Controller/SecurityController.php
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php
src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php
src/Wallabag/CoreBundle/Entity/Config.php
src/Wallabag/CoreBundle/Entity/Entry.php
src/Wallabag/CoreBundle/Entity/Tag.php
src/Wallabag/CoreBundle/Entity/User.php
src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
src/Wallabag/CoreBundle/Form/Type/ConfigType.php
src/Wallabag/CoreBundle/Form/Type/EntryType.php
src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
src/Wallabag/CoreBundle/Form/Type/NewUserType.php
src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
src/Wallabag/CoreBundle/Form/Type/RssType.php
src/Wallabag/CoreBundle/Form/Type/UserInformationType.php
src/Wallabag/CoreBundle/Helper/Tools.php
src/Wallabag/CoreBundle/Repository/EntryRepository.php
src/Wallabag/CoreBundle/Repository/UserRepository.php
src/Wallabag/CoreBundle/Resources/config/routing_rest.yml [deleted file]
src/Wallabag/CoreBundle/Resources/config/services.yml
src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
src/Wallabag/CoreBundle/Service/Extractor.php
src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php [deleted file]
src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php [moved from src/Wallabag/CoreBundle/Tests/WallabagTestCase.php with 91% similarity]
src/Wallabag/CoreBundle/Tools/Utils.php
src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php
src/Wallabag/CoreBundle/WallabagCoreBundle.php

index 3c97a9da46d15cff826e68c4b8353608ed931d42..8d0cf8170f15a6064d079d789d73ed98892040d7 100644 (file)
@@ -30,16 +30,16 @@ install:
     - composer self-update
 
 # build coverage only on one build, to speed up results feedbacks
-before_script:
-    - if [[ "$TRAVIS_PHP_VERSION" = "5.6" ]]; then PHPUNIT_FLAGS="--coverage-clover=coverage.clover"; else PHPUNIT_FLAGS=""; fi;
+before_script:
+    - if [[ "$TRAVIS_PHP_VERSION" = "5.6" ]]; then PHPUNIT_FLAGS="--coverage-clover=coverage.clover"; else PHPUNIT_FLAGS=""; fi;
 
 script:
     - ant prepare
-    - phpunit --exclude-group command-doctrine $PHPUNIT_FLAGS
-
-after_script:
-    - |
-        if [ $TRAVIS_PHP_VERSION = '5.6' ]; then
-            wget https://scrutinizer-ci.com/ocular.phar
-            php ocular.phar code-coverage:upload --format=php-clover coverage.clover
-        fi
+    - bin/phpunit --exclude-group command-doctrine --debug $PHPUNIT_FLAGS
+
+after_script:
+    - |
+        if [ $TRAVIS_PHP_VERSION = '5.6' ]; then
+            wget https://scrutinizer-ci.com/ocular.phar
+            php ocular.phar code-coverage:upload --format=php-clover coverage.clover
+        fi
index 601b52c3f4670d90c242ca6c9769bc9a96bc7c40..9a52f3493d08b49e2ed58aa1e98249d8f4a3caf9 100644 (file)
@@ -23,7 +23,8 @@ class AppKernel extends Kernel
             new Nelmio\CorsBundle\NelmioCorsBundle(),
             new Liip\ThemeBundle\LiipThemeBundle(),
             new Wallabag\CoreBundle\WallabagCoreBundle(),
-            new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle()
+            new Wallabag\ApiBundle\WallabagApiBundle(),
+            new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
         );
 
         if (in_array($this->getEnvironment(), array('dev', 'test'))) {
index cbcf1c8e3edf5695ab87372d39bb15cf944def8f..caabe407b1c057419c2e4dae3ed0a2e23f663753 100644 (file)
@@ -77,7 +77,7 @@ class Requirement
     }
 
     /**
-     * Returns the help text for resolving the problem
+     * Returns the help text for resolving the problem.
      *
      * @return string The help text
      */
@@ -119,10 +119,10 @@ class PhpIniRequirement extends 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
+     *                                         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.
+     *                                         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)
@@ -221,10 +221,10 @@ class RequirementCollection implements IteratorAggregate
      *
      * @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
+     *                                         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.
+     *                                         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)
@@ -239,10 +239,10 @@ class RequirementCollection implements IteratorAggregate
      *
      * @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
+     *                                         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.
+     *                                         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)
@@ -542,11 +542,22 @@ class SymfonyRequirements extends RequirementCollection
 
         /* optional recommendations follow */
 
-        $this->addRecommendation(
-            file_get_contents(__FILE__) === file_get_contents(__DIR__.'/../vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/skeleton/app/SymfonyRequirements.php'),
-            'Requirements file should be up-to-date',
-            'Your requirements file is outdated. Run composer install and re-check your configuration.'
-        );
+        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', '>='),
index d681b39b7c48f3ee1158151f674014e237393c59..8710e97f97995440e1fc2e232512c5d024e61f4f 100644 (file)
@@ -1,3 +1,7 @@
+wallabag_api:
+    resource: "@WallabagApiBundle/Resources/config/routing.yml"
+    prefix:   /
+
 app:
     resource: @WallabagCoreBundle/Controller/
     type:     annotation
index 82d9e6cce0ef8af304e049d384b228db5fca4cb9..0a64ad78b61620cc2ede244d74395ef09c99792c 100644 (file)
@@ -1,3 +1,3 @@
 Rest_Wallabag:
   type : rest
-  resource: "@WallabagCoreBundle/Resources/config/routing_rest.yml"
\ No newline at end of file
+  resource: "@WallabagApiBundle/Resources/config/routing_rest.yml"
index 66f4738b2d1a07f37391fbcc538e436cf8218242..c44ffee07cd7514418eb4ee608c45d80f0be9cac 100644 (file)
@@ -8,16 +8,16 @@
     "packages": [
         {
             "name": "doctrine/annotations",
-            "version": "v1.2.3",
+            "version": "v1.2.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/annotations.git",
-                "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4"
+                "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/annotations/zipball/eeda578cbe24a170331a1cfdf78be723412df7a4",
-                "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4",
+                "url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e",
+                "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e",
                 "shasum": ""
             },
             "require": {
                 "docblock",
                 "parser"
             ],
-            "time": "2014-12-20 20:49:38"
+            "time": "2014-12-23 22:40:37"
         },
         {
             "name": "doctrine/cache",
-            "version": "v1.4.0",
+            "version": "v1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/cache.git",
-                "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8"
+                "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/cache/zipball/2346085d2b027b233ae1d5de59b07440b9f288c8",
-                "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03",
+                "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03",
                 "shasum": ""
             },
             "require": {
             },
             "require-dev": {
                 "phpunit/phpunit": ">=3.7",
-                "predis/predis": "~0.8",
+                "predis/predis": "~1.0",
                 "satooshi/php-coveralls": "~0.6"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.4.x-dev"
+                    "dev-master": "1.5.x-dev"
                 }
             },
             "autoload": {
                 "cache",
                 "caching"
             ],
-            "time": "2015-01-15 20:38:55"
+            "time": "2015-04-15 00:11:59"
         },
         {
             "name": "doctrine/collections",
-            "version": "v1.2",
+            "version": "v1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/collections.git",
-                "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2"
+                "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/collections/zipball/b99c5c46c87126201899afe88ec490a25eedd6a2",
-                "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2",
+                "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": {
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Jonathan Wage",
-                    "email": "jonwage@gmail.com",
-                    "homepage": "http://www.jwage.com/",
-                    "role": "Creator"
-                },
-                {
-                    "name": "Guilherme Blanco",
-                    "email": "guilhermeblanco@gmail.com",
-                    "homepage": "http://www.instaclick.com"
-                },
                 {
                     "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",
-                    "homepage": "https://github.com/schmittjoh",
-                    "role": "Developer of wrapped JMSSerializerBundle"
+                    "email": "schmittjoh@gmail.com"
                 }
             ],
             "description": "Collections Abstraction library",
                 "collections",
                 "iterator"
             ],
-            "time": "2014-02-03 23:07:43"
+            "time": "2015-04-14 22:21:58"
         },
         {
             "name": "doctrine/common",
-            "version": "v2.4.2",
+            "version": "v2.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/common.git",
-                "reference": "5db6ab40e4c531f14dad4ca96a394dfce5d4255b"
+                "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/common/zipball/5db6ab40e4c531f14dad4ca96a394dfce5d4255b",
-                "reference": "5db6ab40e4c531f14dad4ca96a394dfce5d4255b",
+                "url": "https://api.github.com/repos/doctrine/common/zipball/cd8daf2501e10c63dced7b8b9b905844316ae9d3",
+                "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.4.x-dev"
+                    "dev-master": "2.6.x-dev"
                 }
             },
             "autoload": {
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Jonathan Wage",
-                    "email": "jonwage@gmail.com",
-                    "homepage": "http://www.jwage.com/",
-                    "role": "Creator"
-                },
-                {
-                    "name": "Guilherme Blanco",
-                    "email": "guilhermeblanco@gmail.com",
-                    "homepage": "http://www.instaclick.com"
-                },
                 {
                     "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",
-                    "homepage": "https://github.com/schmittjoh",
-                    "role": "Developer of wrapped JMSSerializerBundle"
+                    "email": "schmittjoh@gmail.com"
                 }
             ],
             "description": "Common Library for Doctrine projects",
                 "persistence",
                 "spl"
             ],
-            "time": "2014-05-21 19:28:51"
+            "time": "2015-04-02 19:55:44"
         },
         {
             "name": "doctrine/dbal",
         },
         {
             "name": "doctrine/doctrine-bundle",
-            "version": "v1.3.0",
+            "version": "v1.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/DoctrineBundle.git",
-                "reference": "3beb3a780485ab01f86941f4892cd23ef8c39c6b"
+                "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/3beb3a780485ab01f86941f4892cd23ef8c39c6b",
-                "reference": "3beb3a780485ab01f86941f4892cd23ef8c39c6b",
+                "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0b9e27037c4fdbad515ee5ec89842e9091a6480f",
+                "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f",
                 "shasum": ""
             },
             "require": {
                 "doctrine/doctrine-cache-bundle": "~1.0",
                 "jdorn/sql-formatter": "~1.1",
                 "php": ">=5.3.2",
+                "symfony/console": "~2.3",
                 "symfony/doctrine-bridge": "~2.2",
-                "symfony/framework-bundle": "~2.2"
+                "symfony/framework-bundle": "~2.3"
             },
             "require-dev": {
                 "doctrine/orm": "~2.3",
-                "phpunit/php-code-coverage": "~1.2",
-                "phpunit/phpunit": "~3.7",
-                "phpunit/phpunit-mock-objects": "~1.2",
+                "phpunit/phpunit": "~4",
                 "satooshi/php-coveralls": "~0.6.1",
                 "symfony/validator": "~2.2",
                 "symfony/yaml": "~2.2",
-                "twig/twig": "~1"
+                "twig/twig": "~1.10"
             },
             "suggest": {
                 "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.",
             "type": "symfony-bundle",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "1.5.x-dev"
                 }
             },
             "autoload": {
                 "orm",
                 "persistence"
             ],
-            "time": "2014-11-28 08:32:03"
+            "time": "2015-05-28 12:27:15"
         },
         {
             "name": "doctrine/doctrine-cache-bundle",
             ],
             "time": "2014-12-20 21:24:13"
         },
+        {
+            "name": "doctrine/instantiator",
+            "version": "1.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/instantiator.git",
+                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
+                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
+                "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.*@ALPHA"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Doctrine\\Instantiator\\": "src"
+                }
+            },
+            "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": "2014-10-13 12:58:55"
+        },
         {
             "name": "doctrine/lexer",
             "version": "v1.0.1",
         },
         {
             "name": "doctrine/orm",
-            "version": "v2.4.7",
+            "version": "v2.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/doctrine2.git",
-                "reference": "2bc4ff3cab2ae297bcd05f2e619d42e6a7ca9e68"
+                "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/2bc4ff3cab2ae297bcd05f2e619d42e6a7ca9e68",
-                "reference": "2bc4ff3cab2ae297bcd05f2e619d42e6a7ca9e68",
+                "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe",
+                "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe",
                 "shasum": ""
             },
             "require": {
-                "doctrine/collections": "~1.1",
-                "doctrine/dbal": "~2.4",
+                "doctrine/cache": "~1.4",
+                "doctrine/collections": "~1.2",
+                "doctrine/common": ">=2.5-dev,<2.6-dev",
+                "doctrine/dbal": ">=2.5-dev,<2.6-dev",
+                "doctrine/instantiator": "~1.0.1",
                 "ext-pdo": "*",
-                "php": ">=5.3.2",
-                "symfony/console": "~2.0"
+                "php": ">=5.4",
+                "symfony/console": "~2.5"
             },
             "require-dev": {
+                "phpunit/phpunit": "~4.0",
                 "satooshi/php-coveralls": "dev-master",
                 "symfony/yaml": "~2.1"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.4.x-dev"
+                    "dev-master": "2.6.x-dev"
                 }
             },
             "autoload": {
                 "database",
                 "orm"
             ],
-            "time": "2014-12-16 13:45:01"
+            "time": "2015-04-02 20:40:18"
         },
         {
             "name": "ezyang/htmlpurifier",
         },
         {
             "name": "friendsofsymfony/rest-bundle",
-            "version": "1.5.3",
+            "version": "1.6.0",
             "target-dir": "FOS/RestBundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git",
-                "reference": "fdd21c4c0cb6222ae37efc9362c6a96bd1432412"
+                "reference": "832d08199cadf1770ec43c2cba68b42b4d5e7f9f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/fdd21c4c0cb6222ae37efc9362c6a96bd1432412",
-                "reference": "fdd21c4c0cb6222ae37efc9362c6a96bd1432412",
+                "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/832d08199cadf1770ec43c2cba68b42b4d5e7f9f",
+                "reference": "832d08199cadf1770ec43c2cba68b42b4d5e7f9f",
                 "shasum": ""
             },
             "require": {
                 "doctrine/inflector": "~1.0",
                 "php": ">=5.3.9",
                 "psr/log": "~1.0",
-                "symfony/framework-bundle": "~2.2",
+                "symfony/framework-bundle": "~2.3",
+                "symfony/http-kernel": "~2.3,>=2.3.24",
                 "willdurand/jsonp-callback-validator": "~1.0",
                 "willdurand/negotiation": "~1.2"
             },
             "conflict": {
                 "jms/serializer": "<0.12",
-                "jms/serializer-bundle": "<0.11"
+                "jms/serializer-bundle": "<0.11",
+                "symfony/validator": ">=2.5.0,<2.5.5"
             },
             "require-dev": {
+                "jms/serializer": "~0.13",
                 "jms/serializer-bundle": "~0.12",
-                "sensio/framework-extra-bundle": "~2.2",
-                "symfony/form": "~2.2",
-                "symfony/security": "~2.2",
-                "symfony/serializer": "~2.2",
-                "symfony/validator": "~2.2",
-                "symfony/yaml": "~2.2"
+                "phpoption/phpoption": "~1.1.0",
+                "sensio/framework-extra-bundle": "~3.0",
+                "symfony/browser-kit": "~2.3",
+                "symfony/dependency-injection": "~2.3",
+                "symfony/form": "~2.3",
+                "symfony/security": "~2.3",
+                "symfony/serializer": "~2.3",
+                "symfony/validator": "~2.3",
+                "symfony/yaml": "~2.3"
             },
             "suggest": {
                 "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended, requires ~0.12",
-                "sensio/framework-extra-bundle": "Add support for route annotations and the view response listener",
-                "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ~2.2",
-                "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ~2.2"
+                "sensio/framework-extra-bundle": "Add support for route annotations and the view response listener, requires ~3.0",
+                "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ~2.3",
+                "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ~2.3"
             },
             "type": "symfony-bundle",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.5-dev"
+                    "dev-master": "1.6-dev"
                 }
             },
             "autoload": {
             "keywords": [
                 "rest"
             ],
-            "time": "2015-02-16 15:26:12"
+            "time": "2015-05-22 20:17:35"
         },
         {
             "name": "htmlawed/htmlawed",
             "source": {
                 "type": "git",
                 "url": "https://github.com/kesar/HTMLawed.git",
-                "reference": "9d292af5f4c288aa68f38b87f5d88c8214f5f233"
+                "reference": "f842e793614bdf3af70a62b1e70570e824dc9ab6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/kesar/HTMLawed/zipball/9d292af5f4c288aa68f38b87f5d88c8214f5f233",
-                "reference": "9d292af5f4c288aa68f38b87f5d88c8214f5f233",
+                "url": "https://api.github.com/repos/kesar/HTMLawed/zipball/f842e793614bdf3af70a62b1e70570e824dc9ab6",
+                "reference": "f842e793614bdf3af70a62b1e70570e824dc9ab6",
                 "shasum": ""
             },
             "require": {
                 "GPL-2.0+",
                 "LGPL-3.0"
             ],
-            "description": "htmLawed - Process text with HTML markup to make it more compliant with HTML  standards and administrative policies",
+            "authors": [
+                {
+                    "name": "Santosh Patnaik",
+                    "homepage": "http://www.bioinformatics.org/people/index.php?user_hash=558b661f92d0ff7b",
+                    "role": "Developer"
+                }
+            ],
+            "description": "htmLawed - Process text with HTML markup to make it more compliant with HTML standards and administrative policies",
             "homepage": "http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/",
             "keywords": [
                 "HTMLtidy",
                 "strip",
                 "tags"
             ],
-            "time": "2014-01-05 13:06:52"
+            "time": "2015-04-12 19:37:20"
         },
         {
             "name": "incenteev/composer-parameter-handler",
         },
         {
             "name": "monolog/monolog",
-            "version": "1.13.0",
+            "version": "1.13.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "c41c218e239b50446fd883acb1ecfd4b770caeae"
+                "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c41c218e239b50446fd883acb1ecfd4b770caeae",
-                "reference": "c41c218e239b50446fd883acb1ecfd4b770caeae",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
+                "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
                 "shasum": ""
             },
             "require": {
                 "logging",
                 "psr-3"
             ],
-            "time": "2015-03-05 01:12:12"
+            "time": "2015-03-09 09:58:04"
         },
         {
             "name": "nelmio/api-doc-bundle",
-            "version": "2.7.0",
+            "version": "2.9.0",
             "target-dir": "Nelmio/ApiDocBundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nelmio/NelmioApiDocBundle.git",
-                "reference": "3fdb2d4a819d1f71bff0c45880af705a8b124955"
+                "reference": "de31760fd84a45fadbb4fe24db050b5e29ea70d1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/3fdb2d4a819d1f71bff0c45880af705a8b124955",
-                "reference": "3fdb2d4a819d1f71bff0c45880af705a8b124955",
+                "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/de31760fd84a45fadbb4fe24db050b5e29ea70d1",
+                "reference": "de31760fd84a45fadbb4fe24db050b5e29ea70d1",
                 "shasum": ""
             },
             "require": {
                 "jms/serializer-bundle": "<0.11"
             },
             "require-dev": {
+                "dunglas/api-bundle": "dev-master",
                 "friendsofsymfony/rest-bundle": "~1.0",
                 "jms/serializer-bundle": ">=0.11",
-                "sensio/framework-extra-bundle": "~2.1",
+                "sensio/framework-extra-bundle": "~3.0",
                 "symfony/browser-kit": "~2.1",
                 "symfony/css-selector": "~2.1",
                 "symfony/form": "~2.1",
+                "symfony/serializer": "~2.7@dev",
                 "symfony/validator": "~2.1",
                 "symfony/yaml": "~2.1"
             },
             "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.",
             "type": "symfony-bundle",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.7.x-dev"
+                    "dev-master": "2.9.x-dev"
                 }
             },
             "autoload": {
                 "documentation",
                 "rest"
             ],
-            "time": "2014-07-30 09:11:08"
+            "time": "2015-05-16 17:16:14"
         },
         {
             "name": "nelmio/cors-bundle",
         },
         {
             "name": "sensio/distribution-bundle",
-            "version": "v3.0.18",
+            "version": "v3.0.25",
             "target-dir": "Sensio/Bundle/DistributionBundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sensiolabs/SensioDistributionBundle.git",
-                "reference": "ac026149ffb1d3a5c893290d2d3ca8795013de08"
+                "reference": "01931139b0f067a4016d5d56e82c2b3086533b89"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/ac026149ffb1d3a5c893290d2d3ca8795013de08",
-                "reference": "ac026149ffb1d3a5c893290d2d3ca8795013de08",
+                "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/01931139b0f067a4016d5d56e82c2b3086533b89",
+                "reference": "01931139b0f067a4016d5d56e82c2b3086533b89",
                 "shasum": ""
             },
             "require": {
                 "configuration",
                 "distribution"
             ],
-            "time": "2015-02-27 12:59:18"
+            "time": "2015-05-29 22:35:41"
         },
         {
             "name": "sensio/framework-extra-bundle",
-            "version": "v3.0.4",
-            "target-dir": "Sensio/Bundle/FrameworkExtraBundle",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git",
-                "reference": "b3bc3e67c8b6b68b18d727012183520d35ee762a"
+                "reference": "a30fc18bf147bc25faf6b1d54bf55cfad4b63cba"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/b3bc3e67c8b6b68b18d727012183520d35ee762a",
-                "reference": "b3bc3e67c8b6b68b18d727012183520d35ee762a",
+                "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/a30fc18bf147bc25faf6b1d54bf55cfad4b63cba",
+                "reference": "a30fc18bf147bc25faf6b1d54bf55cfad4b63cba",
                 "shasum": ""
             },
             "require": {
             },
             "suggest": {
                 "symfony/expression-language": "",
+                "symfony/psr-http-message-bridge": "To use the PSR-7 converters",
                 "symfony/security-bundle": ""
             },
             "type": "symfony-bundle",
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "Sensio\\Bundle\\FrameworkExtraBundle": ""
+                "psr-4": {
+                    "Sensio\\Bundle\\FrameworkExtraBundle\\": ""
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
                 "annotations",
                 "controllers"
             ],
-            "time": "2014-12-02 09:52:52"
+            "time": "2015-05-29 18:27:23"
         },
         {
             "name": "sensiolabs/security-checker",
-            "version": "v2.0.1",
+            "version": "v2.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sensiolabs/security-checker.git",
-                "reference": "134cecf1c61256bd8e973e11376891a724543820"
+                "reference": "2c2a71f1c77d9765c12638c4724d9ca23658a810"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/134cecf1c61256bd8e973e11376891a724543820",
-                "reference": "134cecf1c61256bd8e973e11376891a724543820",
+                "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/2c2a71f1c77d9765c12638c4724d9ca23658a810",
+                "reference": "2c2a71f1c77d9765c12638c4724d9ca23658a810",
                 "shasum": ""
             },
             "require": {
                 }
             ],
             "description": "A security checker for your composer.lock",
-            "time": "2015-01-26 16:25:19"
+            "time": "2015-05-28 14:22:40"
         },
         {
             "name": "simplepie/simplepie",
         },
         {
             "name": "swiftmailer/swiftmailer",
-            "version": "v5.3.1",
+            "version": "v5.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/swiftmailer/swiftmailer.git",
-                "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a"
+                "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/c5f963e7f9d6f6438fda4f22d5cc2db296ec621a",
-                "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/31454f258f10329ae7c48763eb898a75c39e0a9f",
+                "reference": "31454f258f10329ae7c48763eb898a75c39e0a9f",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "5.3-dev"
+                    "dev-master": "5.4-dev"
                 }
             },
             "autoload": {
                 "mail",
                 "mailer"
             ],
-            "time": "2014-12-05 14:17:14"
+            "time": "2015-03-14 06:06:39"
         },
         {
             "name": "symfony/assetic-bundle",
         },
         {
             "name": "symfony/symfony",
-            "version": "v2.6.4",
+            "version": "v2.6.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/symfony.git",
-                "reference": "23b647f1e4eeb24a457d3c47f5f5046377d5a3bf"
+                "reference": "b06539573ccf64dd3a62852685f052553d02c5ba"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/symfony/zipball/23b647f1e4eeb24a457d3c47f5f5046377d5a3bf",
-                "reference": "23b647f1e4eeb24a457d3c47f5f5046377d5a3bf",
+                "url": "https://api.github.com/repos/symfony/symfony/zipball/b06539573ccf64dd3a62852685f052553d02c5ba",
+                "reference": "b06539573ccf64dd3a62852685f052553d02c5ba",
                 "shasum": ""
             },
             "require": {
                 "ircmaxell/password-compat": "~1.0",
                 "monolog/monolog": "~1.11",
                 "ocramius/proxy-manager": "~0.4|~1.0",
-                "propel/propel1": "~1.6"
+                "propel/propel1": "~1.6",
+                "symfony/phpunit-bridge": "~2.7"
             },
             "type": "library",
             "extra": {
                 "MIT"
             ],
             "authors": [
-                {
-                    "name": "Symfony Community",
-                    "homepage": "http://symfony.com/contributors"
-                },
                 {
                     "name": "Fabien Potencier",
                     "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
             "description": "The Symfony PHP framework",
-            "homepage": "http://symfony.com",
+            "homepage": "https://symfony.com",
             "keywords": [
                 "framework"
             ],
-            "time": "2015-02-02 18:02:30"
+            "time": "2015-05-29 22:55:07"
         },
         {
             "name": "tecnick.com/tcpdf",
-            "version": "6.2.6",
+            "version": "6.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/tecnickcom/TCPDF.git",
-                "reference": "a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb"
+                "reference": "3dee9e7f3a414875fd1d9f4f1dfc2433493a86d2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb",
-                "reference": "a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb",
+                "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/3dee9e7f3a414875fd1d9f4f1dfc2433493a86d2",
+                "reference": "3dee9e7f3a414875fd1d9f4f1dfc2433493a86d2",
                 "shasum": ""
             },
             "require": {
                 "pdf417",
                 "qrcode"
             ],
-            "time": "2015-01-28 18:51:40"
+            "time": "2015-04-29 16:13:58"
         },
         {
             "name": "twig/extensions",
         },
         {
             "name": "twig/twig",
-            "version": "v1.18.0",
+            "version": "v1.18.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf"
+                "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/4cf7464348e7f9893a93f7096a90b73722be99cf",
-                "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/9f70492f44398e276d1b81c1b43adfe6751c7b7f",
+                "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.2.4"
+                "php": ">=5.2.7"
             },
             "type": "library",
             "extra": {
             "keywords": [
                 "templating"
             ],
-            "time": "2015-01-25 17:32:08"
+            "time": "2015-04-19 08:30:27"
         },
         {
             "name": "umpirsky/twig-gettext-extractor",
             "description": "Libraries from @fivefilters.",
             "homepage": "https://github.com/wallabag/Fivefilters_Libraries",
             "support": {
-                "source": "https://github.com/wallabag/Fivefilters_Libraries/tree/master",
+                "source": "https://github.com/wallabag/Fivefilters_Libraries/tree/1.0.0",
                 "issues": "https://github.com/wallabag/Fivefilters_Libraries/issues"
             },
             "time": "2015-01-19 20:19:28"
             "description": "PHP Classes for dynamically generating EPub files.",
             "homepage": "https://github.com/wallabag/PHPePub",
             "support": {
-                "source": "https://github.com/wallabag/PHPePub/tree/master"
+                "source": "https://github.com/wallabag/PHPePub/tree/2.1.0"
             },
             "time": "2015-01-19 11:44:19"
         },
             "description": "A simple and smart (or stupid) php5 snippets repository",
             "homepage": "https://github.com/wallabag/kriss_php5",
             "support": {
-                "source": "https://github.com/wallabag/kriss_php5/tree/master"
+                "source": "https://github.com/wallabag/kriss_php5/tree/1.0.0"
             },
             "time": "2015-01-18 21:21:43"
         },
             "description": "Paginate record sets, not tied in directly to a database.",
             "homepage": "https://github.com/wallabag/pagination",
             "support": {
-                "source": "https://github.com/wallabag/pagination/tree/master"
+                "source": "https://github.com/wallabag/pagination/tree/1.0.0"
             },
             "time": "2015-01-19 09:24:39"
         },
                 "sessions"
             ],
             "support": {
-                "source": "https://github.com/wallabag/PHP-Flash-Messages/tree/master"
+                "source": "https://github.com/wallabag/PHP-Flash-Messages/tree/1.0.0"
             },
             "time": "2015-01-18 19:51:55"
         },
                 "html"
             ],
             "support": {
-                "source": "https://github.com/wallabag/php-readability/tree/master",
+                "source": "https://github.com/wallabag/php-readability/tree/1.0.0",
                 "issues": "https://github.com/wallabag/php-readability/issues"
             },
             "time": "2015-01-19 12:25:38"
             "description": "An experimental Mobipocket file creator in PHP.",
             "homepage": "https://github.com/wallabag/phpMobi",
             "support": {
-                "source": "https://github.com/wallabag/phpMobi/tree/master"
+                "source": "https://github.com/wallabag/phpMobi/tree/1.0.0"
             },
             "time": "2015-01-19 12:43:17"
         },
         {
             "name": "willdurand/hateoas",
-            "version": "v2.4.0",
+            "version": "v2.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/willdurand/Hateoas.git",
-                "reference": "89fe19ad9ce25f15323d76ac22272282ae8a9f14"
+                "reference": "fc0869381d6934e5d430084154584761297caa6c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/willdurand/Hateoas/zipball/89fe19ad9ce25f15323d76ac22272282ae8a9f14",
-                "reference": "89fe19ad9ce25f15323d76ac22272282ae8a9f14",
+                "url": "https://api.github.com/repos/willdurand/Hateoas/zipball/fc0869381d6934e5d430084154584761297caa6c",
+                "reference": "fc0869381d6934e5d430084154584761297caa6c",
                 "shasum": ""
             },
             "require": {
                 "doctrine/annotations": "~1.0",
                 "doctrine/common": "~2.0",
                 "jms/metadata": "~1.1",
-                "jms/serializer": "~0.13@dev",
+                "jms/serializer": "~0.13",
+                "php": ">=5.3",
                 "symfony/expression-language": "~2.4"
             },
             "require-dev": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.4-dev"
+                    "dev-master": "2.6-dev"
                 }
             },
             "autoload": {
                 }
             ],
             "description": "A PHP library to support implementing representations for HATEOAS REST web services",
-            "time": "2015-02-24 15:28:33"
+            "time": "2015-05-21 21:57:34"
         },
         {
             "name": "willdurand/hateoas-bundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/willdurand/BazingaHateoasBundle.git",
-                "reference": "3c86e8080e8a229365a0ce91818da6fe6562376b"
+                "reference": "a99f48ea5004a89ecf0927229d9c912fed9fa4ab"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/3c86e8080e8a229365a0ce91818da6fe6562376b",
-                "reference": "3c86e8080e8a229365a0ce91818da6fe6562376b",
+                "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/a99f48ea5004a89ecf0927229d9c912fed9fa4ab",
+                "reference": "a99f48ea5004a89ecf0927229d9c912fed9fa4ab",
                 "shasum": ""
             },
             "require": {
                 "HATEOAS",
                 "rest"
             ],
-            "time": "2015-02-19 16:27:51"
+            "time": "2015-03-12 15:49:24"
         },
         {
             "name": "willdurand/jsonp-callback-validator",
     "packages-dev": [
         {
             "name": "doctrine/data-fixtures",
-            "version": "v1.0.0",
+            "version": "v1.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/data-fixtures.git",
-                "reference": "b4a135c7db56ecc4602b54a2184368f440cac33e"
+                "reference": "bd44f6b6e40247b6530bc8abe802e4e4d914976a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/b4a135c7db56ecc4602b54a2184368f440cac33e",
-                "reference": "b4a135c7db56ecc4602b54a2184368f440cac33e",
+                "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/bd44f6b6e40247b6530bc8abe802e4e4d914976a",
+                "reference": "bd44f6b6e40247b6530bc8abe802e4e4d914976a",
                 "shasum": ""
             },
             "require": {
-                "doctrine/common": ">=2.2,<2.5-dev",
+                "doctrine/common": "~2.2",
                 "php": ">=5.3.2"
             },
+            "conflict": {
+                "doctrine/orm": "< 2.4"
+            },
             "require-dev": {
-                "doctrine/orm": ">=2.2,<2.5-dev"
+                "doctrine/orm": "~2.4"
             },
             "suggest": {
                 "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures",
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "1.1.x-dev"
                 }
             },
             "autoload": {
             "authors": [
                 {
                     "name": "Jonathan Wage",
-                    "email": "jonwage@gmail.com",
-                    "homepage": "http://www.jwage.com/",
-                    "role": "Creator"
+                    "email": "jonwage@gmail.com"
                 }
             ],
             "description": "Data Fixtures for all Doctrine Object Managers",
             "keywords": [
                 "database"
             ],
-            "time": "2013-07-10 17:04:07"
+            "time": "2015-03-30 12:14:13"
         },
         {
             "name": "doctrine/doctrine-fixtures-bundle",
             ],
             "time": "2015-01-19 02:21:37"
         },
-        {
-            "name": "doctrine/instantiator",
-            "version": "1.0.4",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/doctrine/instantiator.git",
-                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
-                "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
-                "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.*@ALPHA"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-0": {
-                    "Doctrine\\Instantiator\\": "src"
-                }
-            },
-            "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": "2014-10-13 12:58:55"
-        },
         {
             "name": "phpdocumentor/reflection-docblock",
             "version": "2.0.4",
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.3.1",
+            "version": "v1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
+                "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
-                "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
+                "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "~1.0,>=1.0.2",
-                "phpdocumentor/reflection-docblock": "~2.0"
+                "doctrine/instantiator": "^1.0.2",
+                "phpdocumentor/reflection-docblock": "~2.0",
+                "sebastian/comparator": "~1.1"
             },
             "require-dev": {
                 "phpspec/phpspec": "~2.0"
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2.x-dev"
+                    "dev-master": "1.4.x-dev"
                 }
             },
             "autoload": {
                 }
             ],
             "description": "Highly opinionated mocking framework for PHP 5.3+",
-            "homepage": "http://phpspec.org",
+            "homepage": "https://github.com/phpspec/prophecy",
             "keywords": [
                 "Double",
                 "Dummy",
                 "spy",
                 "stub"
             ],
-            "time": "2014-11-17 16:23:49"
+            "time": "2015-04-27 22:15:08"
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.0.15",
+            "version": "2.0.17",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
+                "reference": "c4e8e7725e351184a76544634855b8a9c405a6e3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c4e8e7725e351184a76544634855b8a9c405a6e3",
+                "reference": "c4e8e7725e351184a76544634855b8a9c405a6e3",
                 "shasum": ""
             },
             "require": {
                 "testing",
                 "xunit"
             ],
-            "time": "2015-01-24 10:06:35"
+            "time": "2015-05-25 05:11:59"
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.3.4",
+            "version": "1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
+                "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
-                "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb",
+                "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
             "autoload": {
                 "classmap": [
-                    "File/"
+                    "src/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
-            "include-path": [
-                ""
-            ],
             "license": [
                 "BSD-3-Clause"
             ],
                 "filesystem",
                 "iterator"
             ],
-            "time": "2013-10-10 15:34:57"
+            "time": "2015-04-02 05:19:05"
         },
         {
             "name": "phpunit/php-text-template",
         },
         {
             "name": "phpunit/php-token-stream",
-            "version": "1.4.0",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
+                "reference": "eab81d02569310739373308137284e0158424330"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
-                "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/eab81d02569310739373308137284e0158424330",
+                "reference": "eab81d02569310739373308137284e0158424330",
                 "shasum": ""
             },
             "require": {
             "keywords": [
                 "tokenizer"
             ],
-            "time": "2015-01-17 09:51:32"
+            "time": "2015-04-08 04:46:07"
         },
         {
             "name": "phpunit/phpunit",
-            "version": "4.5.0",
+            "version": "4.6.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5"
+                "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5",
-                "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/816d12536a7a032adc3b68737f82cfbbf98b79c1",
+                "reference": "816d12536a7a032adc3b68737f82cfbbf98b79c1",
                 "shasum": ""
             },
             "require": {
                 "ext-reflection": "*",
                 "ext-spl": "*",
                 "php": ">=5.3.3",
-                "phpspec/prophecy": "~1.3.1",
-                "phpunit/php-code-coverage": "~2.0",
-                "phpunit/php-file-iterator": "~1.3.2",
+                "phpspec/prophecy": "~1.3,>=1.3.1",
+                "phpunit/php-code-coverage": "~2.0,>=2.0.11",
+                "phpunit/php-file-iterator": "~1.4",
                 "phpunit/php-text-template": "~1.2",
-                "phpunit/php-timer": "~1.0.2",
+                "phpunit/php-timer": "~1.0",
                 "phpunit/phpunit-mock-objects": "~2.3",
                 "sebastian/comparator": "~1.1",
-                "sebastian/diff": "~1.1",
+                "sebastian/diff": "~1.2",
                 "sebastian/environment": "~1.2",
                 "sebastian/exporter": "~1.2",
                 "sebastian/global-state": "~1.0",
                 "sebastian/version": "~1.0",
-                "symfony/yaml": "~2.0"
+                "symfony/yaml": "~2.1|~3.0"
             },
             "suggest": {
                 "phpunit/php-invoker": "~1.1"
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.5.x-dev"
+                    "dev-master": "4.6.x-dev"
                 }
             },
             "autoload": {
                 "testing",
                 "xunit"
             ],
-            "time": "2015-02-05 15:51:19"
+            "time": "2015-05-29 06:00:03"
         },
         {
             "name": "phpunit/phpunit-mock-objects",
-            "version": "2.3.0",
+            "version": "2.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
-                "reference": "c63d2367247365f688544f0d500af90a11a44c65"
+                "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65",
-                "reference": "c63d2367247365f688544f0d500af90a11a44c65",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/253c005852591fd547fc18cd5b7b43a1ec82d8f7",
+                "reference": "253c005852591fd547fc18cd5b7b43a1ec82d8f7",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "~1.0,>=1.0.1",
+                "doctrine/instantiator": "~1.0,>=1.0.2",
                 "php": ">=5.3.3",
                 "phpunit/php-text-template": "~1.2"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.3"
+                "phpunit/phpunit": "~4.4"
             },
             "suggest": {
                 "ext-soap": "*"
                 "mock",
                 "xunit"
             ],
-            "time": "2014-10-03 05:12:11"
+            "time": "2015-05-29 05:19:18"
         },
         {
             "name": "sebastian/comparator",
         },
         {
             "name": "sebastian/diff",
-            "version": "1.2.0",
+            "version": "1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/diff.git",
-                "reference": "5843509fed39dee4b356a306401e9dd1a931fec7"
+                "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7",
-                "reference": "5843509fed39dee4b356a306401e9dd1a931fec7",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3",
+                "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
             "keywords": [
                 "diff"
             ],
-            "time": "2014-08-15 10:29:00"
+            "time": "2015-02-22 15:13:53"
         },
         {
             "name": "sebastian/environment",
-            "version": "1.2.1",
+            "version": "1.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/environment.git",
-                "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7"
+                "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7",
-                "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e",
+                "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.3"
+                "phpunit/phpunit": "~4.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2.x-dev"
+                    "dev-master": "1.3.x-dev"
                 }
             },
             "autoload": {
                 "environment",
                 "hhvm"
             ],
-            "time": "2014-10-25 08:00:45"
+            "time": "2015-01-01 10:01:08"
         },
         {
             "name": "sebastian/exporter",
         },
         {
             "name": "sebastian/version",
-            "version": "1.0.4",
+            "version": "1.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/version.git",
-                "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b"
+                "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b",
-                "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4",
+                "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4",
                 "shasum": ""
             },
             "type": "library",
             ],
             "description": "Library that helps with managing the version number of Git-hosted PHP projects",
             "homepage": "https://github.com/sebastianbergmann/version",
-            "time": "2014-12-15 14:25:24"
+            "time": "2015-02-24 06:35:25"
         },
         {
             "name": "sensio/generator-bundle",
-            "version": "v2.5.2",
+            "version": "v2.5.3",
             "target-dir": "Sensio/Bundle/GeneratorBundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git",
-                "reference": "4b09746520a826a7bf34a466ba31c7d8740fef7e"
+                "reference": "e50108c2133ee5c9c484555faed50c17a61221d3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/4b09746520a826a7bf34a466ba31c7d8740fef7e",
-                "reference": "4b09746520a826a7bf34a466ba31c7d8740fef7e",
+                "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/e50108c2133ee5c9c484555faed50c17a61221d3",
+                "reference": "e50108c2133ee5c9c484555faed50c17a61221d3",
                 "shasum": ""
             },
             "require": {
                 }
             ],
             "description": "This bundle generates code for you",
-            "time": "2015-02-11 07:21:23"
+            "time": "2015-03-17 06:36:52"
         }
     ],
     "aliases": [],
similarity index 75%
rename from src/Wallabag/CoreBundle/Controller/WallabagRestController.php
rename to src/Wallabag/ApiBundle/Controller/WallabagRestController.php
index 14f42c488bcad3f2b912aa87590ce3a171d00ad4..2f5923c8bd99b31b4293794de14103562d4b6dd8 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wallabag\CoreBundle\Controller;
+namespace Wallabag\ApiBundle\Controller;
 
 use Nelmio\ApiDocBundle\Annotation\ApiDoc;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@@ -47,6 +47,7 @@ class WallabagRestController extends Controller
      *          {"name"="username", "dataType"="string", "required"=true, "description"="username"}
      *       }
      * )
+     *
      * @return array
      */
     public function getSaltAction($username)
@@ -62,6 +63,7 @@ class WallabagRestController extends Controller
 
         return array($user->getSalt() ?: null);
     }
+
     /**
      * Retrieve all entries. It could be filtered by many options.
      *
@@ -76,6 +78,7 @@ class WallabagRestController extends Controller
      *          {"name"="tags", "dataType"="string", "required"=false, "format"="api%2Crest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
      *       }
      * )
+     *
      * @return Entry
      */
     public function getEntriesAction(Request $request)
@@ -86,17 +89,13 @@ class WallabagRestController extends Controller
         $order      = $request->query->get('order', 'desc');
         $page       = (int) $request->query->get('page', 1);
         $perPage    = (int) $request->query->get('perPage', 30);
-        $tags       = $request->query->get('tags', array());
+        $tags       = $request->query->get('tags', []);
 
         $pager = $this
             ->getDoctrine()
             ->getRepository('WallabagCoreBundle:Entry')
             ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order);
 
-        if (0 === $pager->getNbResults()) {
-            throw $this->createNotFoundException();
-        }
-
         $pager->setCurrentPage($page);
         $pager->setMaxPerPage($perPage);
 
@@ -108,32 +107,31 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Retrieve a single entry
+     * Retrieve a single entry.
      *
      * @ApiDoc(
      *      requirements={
      *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
      *      }
      * )
+     *
      * @return Entry
      */
     public function getEntryAction(Entry $entry)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Create an entry
+     * Create an entry.
      *
      * @ApiDoc(
      *       parameters={
@@ -142,6 +140,7 @@ class WallabagRestController extends Controller
      *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
      *       }
      * )
+     *
      * @return Entry
      */
     public function postEntriesAction(Request $request)
@@ -165,11 +164,11 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Change several properties of an entry
+     * Change several properties of an entry.
      *
      * @ApiDoc(
      *      requirements={
@@ -182,17 +181,16 @@ class WallabagRestController extends Controller
      *          {"name"="star", "dataType"="boolean", "required"=false, "format"="true or false", "description"="starred the entry."},
      *      }
      * )
+     *
      * @return Entry
      */
     public function patchEntriesAction(Entry $entry, Request $request)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
-        $title      = $request->request->get("title");
-        $isArchived = $request->request->get("archive");
-        $isStarred  = $request->request->get("star");
+        $title      = $request->request->get('title');
+        $isArchived = $request->request->get('archive');
+        $isStarred  = $request->request->get('star');
 
         if (!is_null($title)) {
             $entry->setTitle($title);
@@ -216,24 +214,23 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Delete **permanently** an entry
+     * Delete **permanently** an entry.
      *
      * @ApiDoc(
      *      requirements={
      *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
      *      }
      * )
+     *
      * @return Entry
      */
     public function deleteEntriesAction(Entry $entry)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
         $em = $this->getDoctrine()->getManager();
         $em->remove($entry);
@@ -241,11 +238,11 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Retrieve all tags for an entry
+     * Retrieve all tags for an entry.
      *
      * @ApiDoc(
      *      requirements={
@@ -255,17 +252,15 @@ class WallabagRestController extends Controller
      */
     public function getEntriesTagsAction(Entry $entry)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
         $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Add one or more tags to an entry
+     * Add one or more tags to an entry.
      *
      * @ApiDoc(
      *      requirements={
@@ -278,9 +273,7 @@ class WallabagRestController extends Controller
      */
     public function postEntriesTagsAction(Request $request, Entry $entry)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
         $tags = $request->request->get('tags', '');
         if (!empty($tags)) {
@@ -293,24 +286,22 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Permanently remove one tag for an entry
+     * Permanently remove one tag for an entry.
      *
      * @ApiDoc(
      *      requirements={
-     *          {"name"="tag", "dataType"="string", "requirement"="\w+", "description"="The tag"},
+     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
      *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
      *      }
      * )
      */
     public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
     {
-        if ($entry->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
 
         $entry->removeTag($tag);
         $em = $this->getDoctrine()->getManager();
@@ -319,11 +310,11 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($entry, 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Retrieve all tags
+     * Retrieve all tags.
      *
      * @ApiDoc()
      */
@@ -331,23 +322,21 @@ class WallabagRestController extends Controller
     {
         $json = $this->get('serializer')->serialize($this->getUser()->getTags(), 'json');
 
-        return new Response($json, 200, array('application/json'));
+        return $this->renderJsonResponse($json);
     }
 
     /**
-     * Permanently remove one tag from **every** entry
+     * Permanently remove one tag from **every** entry.
      *
      * @ApiDoc(
      *      requirements={
-     *          {"name"="tag", "dataType"="string", "requirement"="\w+", "description"="The tag"}
+     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
      *      }
      * )
      */
     public function deleteTagAction(Tag $tag)
     {
-        if ($tag->getUser()->getId() != $this->getUser()->getId()) {
-            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$tag->getUser()->getId().', logged user id: '.$this->getUser()->getId());
-        }
+        $this->validateUserAccess($tag->getUser()->getId(), $this->getUser()->getId());
 
         $em = $this->getDoctrine()->getManager();
         $em->remove($tag);
@@ -355,6 +344,33 @@ class WallabagRestController extends Controller
 
         $json = $this->get('serializer')->serialize($tag, 'json');
 
+        return $this->renderJsonResponse($json);
+    }
+
+    /**
+     * Validate that the first id is equal to the second one.
+     * If not, throw exception. It means a user try to access information from an other user.
+     *
+     * @param int $requestUserId User id from the requested source
+     * @param int $currentUserId User id from the retrieved source
+     */
+    private function validateUserAccess($requestUserId, $currentUserId)
+    {
+        if ($requestUserId != $currentUserId) {
+            throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$requestUserId.', logged user id: '.$currentUserId);
+        }
+    }
+
+    /**
+     * Send a JSON Response.
+     * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string.
+     *
+     * @param string $json
+     *
+     * @return Response
+     */
+    private function renderJsonResponse($json)
+    {
         return new Response($json, 200, array('application/json'));
     }
 }
diff --git a/src/Wallabag/ApiBundle/DependencyInjection/Configuration.php b/src/Wallabag/ApiBundle/DependencyInjection/Configuration.php
new file mode 100644 (file)
index 0000000..cec4541
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Wallabag\ApiBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+/**
+ * This is the class that validates and merges configuration from your app/config files.
+ *
+ * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
+ */
+class Configuration implements ConfigurationInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfigTreeBuilder()
+    {
+        $treeBuilder = new TreeBuilder();
+        $rootNode = $treeBuilder->root('wallabag_api');
+
+        // Here you should define the parameters that are allowed to
+        // configure your bundle. See the documentation linked above for
+        // more information on that topic.
+
+        return $treeBuilder;
+    }
+}
similarity index 94%
rename from src/Wallabag/CoreBundle/DependencyInjection/Security/Factory/WsseFactory.php
rename to src/Wallabag/ApiBundle/DependencyInjection/Security/Factory/WsseFactory.php
index 0b5bdb40aad21ccbd2c19356c76a22aa651994af..402eb869217a900d00d59c72b23c5e090cd6568f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wallabag\CoreBundle\DependencyInjection\Security\Factory;
+namespace Wallabag\ApiBundle\DependencyInjection\Security\Factory;
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Reference;
diff --git a/src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php b/src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php
new file mode 100644 (file)
index 0000000..c5cc204
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+
+namespace Wallabag\ApiBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use Symfony\Component\DependencyInjection\Loader;
+
+class WallabagApiExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+        $configuration = new Configuration();
+        $config = $this->processConfiguration($configuration, $configs);
+
+        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+        $loader->load('services.yml');
+    }
+
+    public function getAlias()
+    {
+        return 'wallabag_api';
+    }
+}
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing.yml b/src/Wallabag/ApiBundle/Resources/config/routing.yml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
new file mode 100644 (file)
index 0000000..5f43f97
--- /dev/null
@@ -0,0 +1,4 @@
+entries:
+  type: rest
+  resource:     "WallabagApiBundle:WallabagRest"
+  name_prefix:  api_
diff --git a/src/Wallabag/ApiBundle/Resources/config/services.yml b/src/Wallabag/ApiBundle/Resources/config/services.yml
new file mode 100644 (file)
index 0000000..6854a44
--- /dev/null
@@ -0,0 +1,12 @@
+services:
+    wsse.security.authentication.provider:
+        class: Wallabag\ApiBundle\Security\Authentication\Provider\WsseProvider
+        public: false
+        arguments: ['', '%kernel.cache_dir%/security/nonces']
+
+    wsse.security.authentication.listener:
+        class: Wallabag\ApiBundle\Security\Firewall\WsseListener
+        public: false
+        tags:
+            - { name: monolog.logger, channel: wsse }
+        arguments: ['@security.context', '@security.authentication.manager', '@logger']
similarity index 82%
rename from src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php
rename to src/Wallabag/ApiBundle/Security/Authentication/Provider/WsseProvider.php
index 7e6a5dfb3960f30f78043df38a0485cddf6b1c52..db73ae2a44093fa9c1f79848de6eaa21be3d9034 100644 (file)
@@ -1,12 +1,13 @@
 <?php
-namespace Wallabag\CoreBundle\Security\Authentication\Provider;
+
+namespace Wallabag\ApiBundle\Security\Authentication\Provider;
 
 use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
 use Symfony\Component\Security\Core\User\UserProviderInterface;
 use Symfony\Component\Security\Core\Exception\AuthenticationException;
 use Symfony\Component\Security\Core\Exception\NonceExpiredException;
 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken;
+use Wallabag\ApiBundle\Security\Authentication\Token\WsseUserToken;
 
 class WsseProvider implements AuthenticationProviderInterface
 {
@@ -29,7 +30,7 @@ class WsseProvider implements AuthenticationProviderInterface
         $user = $this->userProvider->loadUserByUsername($token->getUsername());
 
         if (!$user) {
-            throw new AuthenticationException("Bad credentials. Did you forgot your username?");
+            throw new AuthenticationException('Bad credentials. Did you forgot your username?');
         }
 
         if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) {
@@ -46,12 +47,12 @@ class WsseProvider implements AuthenticationProviderInterface
     {
         // Check created time is not in the future
         if (strtotime($created) > time()) {
-            throw new AuthenticationException("Back to the future...");
+            throw new AuthenticationException('Back to the future...');
         }
 
         // Expire timestamp after 5 minutes
         if (time() - strtotime($created) > 300) {
-            throw new AuthenticationException("Too late for this timestamp... Watch your watch.");
+            throw new AuthenticationException('Too late for this timestamp... Watch your watch.');
         }
 
         // Validate nonce is unique within 5 minutes
@@ -65,7 +66,7 @@ class WsseProvider implements AuthenticationProviderInterface
         $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true));
 
         if ($digest !== $expected) {
-            throw new AuthenticationException("Bad credentials ! Digest is not as expected.");
+            throw new AuthenticationException('Bad credentials ! Digest is not as expected.');
         }
 
         return $digest === $expected;
similarity index 87%
rename from src/Wallabag/CoreBundle/Security/Authentication/Token/WsseUserToken.php
rename to src/Wallabag/ApiBundle/Security/Authentication/Token/WsseUserToken.php
index ea6fb9bf2d1201cbac430b28b70b1793fa0e1b09..e6d30224bb96298f9259631f12b2b9590ed1a076 100644 (file)
@@ -1,5 +1,6 @@
 <?php
-namespace Wallabag\CoreBundle\Security\Authentication\Token;
+
+namespace Wallabag\ApiBundle\Security\Authentication\Token;
 
 use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
 
similarity index 94%
rename from src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php
rename to src/Wallabag/ApiBundle/Security/Firewall/WsseListener.php
index 6ffdfaf0a4e482a91749ff4081822dba74ebecfb..5058783798e4cdf1576d9c7bd098f131e0bf0b7b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-namespace Wallabag\CoreBundle\Security\Firewall;
+namespace Wallabag\ApiBundle\Security\Firewall;
 
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -8,7 +8,7 @@ use Symfony\Component\Security\Http\Firewall\ListenerInterface;
 use Symfony\Component\Security\Core\Exception\AuthenticationException;
 use Symfony\Component\Security\Core\SecurityContextInterface;
 use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
-use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken;
+use Wallabag\ApiBundle\Security\Authentication\Token\WsseUserToken;
 use Psr\Log\LoggerInterface;
 
 class WsseListener implements ListenerInterface
diff --git a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php
new file mode 100644 (file)
index 0000000..86c8de1
--- /dev/null
@@ -0,0 +1,410 @@
+<?php
+
+namespace Wallabag\ApiBundle\Tests\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class WallabagRestControllerTest extends WebTestCase
+{
+    protected static $salt;
+
+    /**
+     * Grab the salt once and store it to be available for all tests.
+     */
+    public static function setUpBeforeClass()
+    {
+        $client = self::createClient();
+
+        $user = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:User')
+            ->findOneByUsername('admin');
+
+        self::$salt = $user->getSalt();
+    }
+
+    /**
+     * Generate HTTP headers for authenticate user on API.
+     *
+     * @param string $username
+     * @param string $password
+     *
+     * @return array
+     */
+    private function generateHeaders($username, $password)
+    {
+        $encryptedPassword = sha1($password.$username.self::$salt);
+        $nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
+
+        $now = new \DateTime('now', new \DateTimeZone('UTC'));
+        $created = (string) $now->format('Y-m-d\TH:i:s\Z');
+        $digest = base64_encode(sha1(base64_decode($nonce).$created.$encryptedPassword, true));
+
+        return array(
+            'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
+            'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="'.$username.'", PasswordDigest="'.$digest.'", Nonce="'.$nonce.'", Created="'.$created.'"',
+        );
+    }
+
+    public function testGetSalt()
+    {
+        $client = $this->createClient();
+        $client->request('GET', '/api/salts/admin.json');
+
+        $user = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:User')
+            ->findOneByUsername('admin');
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey(0, $content);
+        $this->assertEquals($user->getSalt(), $content[0]);
+
+        $client->request('GET', '/api/salts/notfound.json');
+        $this->assertEquals(404, $client->getResponse()->getStatusCode());
+    }
+
+    public function testWithBadHeaders()
+    {
+        $client = $this->createClient();
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByIsArchived(false);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $badHeaders = array(
+            'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
+            'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="admin", PasswordDigest="Wr0ngDig3st", Nonce="n0Nc3", Created="2015-01-01T13:37:00Z"',
+        );
+
+        $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $badHeaders);
+        $this->assertEquals(403, $client->getResponse()->getStatusCode());
+    }
+
+    public function testGetOneEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(array('user' => 1, 'isArchived' => false));
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getTitle(), $content['title']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+        $this->assertCount(count($entry->getTags()), $content['tags']);
+
+        $this->assertTrue(
+            $client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetOneEntryWrongUser()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(array('user' => 2, 'isArchived' => false));
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
+
+        $this->assertEquals(403, $client->getResponse()->getStatusCode());
+    }
+
+    public function testGetEntries()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('GET', '/api/entries', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertTrue(
+            $client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetStarredEntries()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('GET', '/api/entries', array('archive' => 1), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertTrue(
+            $client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testDeleteEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getTitle(), $content['title']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+
+        // We'll try to delete this entry again
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
+
+        $this->assertEquals(404, $client->getResponse()->getStatusCode());
+    }
+
+    public function testPostEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('POST', '/api/entries.json', array(
+            'url' => 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html',
+            'tags' => 'google',
+        ), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $this->assertEquals('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']);
+        $this->assertEquals(false, $content['is_archived']);
+        $this->assertEquals(false, $content['is_starred']);
+        $this->assertCount(1, $content['tags']);
+    }
+
+    public function testPatchEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        // hydrate the tags relations
+        $nbTags = count($entry->getTags());
+
+        $client->request('PATCH', '/api/entries/'.$entry->getId().'.json', array(
+            'title' => 'New awesome title',
+            'tags' => 'new tag '.uniqid(),
+            'star' => true,
+            'archive' => false,
+        ), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getId(), $content['id']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+        $this->assertEquals('New awesome title', $content['title']);
+        $this->assertGreaterThan($nbTags, count($content['tags']));
+    }
+
+    public function testGetTagsEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags(1);
+
+        $entry = $entry[0];
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $tags = array();
+        foreach ($entry->getTags() as $tag) {
+            $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel());
+        }
+
+        $client->request('GET', '/api/entries/'.$entry->getId().'/tags', array(), array(), $headers);
+
+        $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $client->getResponse()->getContent());
+    }
+
+    public function testPostTagsOnEntry()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $nbTags = count($entry->getTags());
+
+        $newTags = 'tag1,tag2,tag3';
+
+        $client->request('POST', '/api/entries/'.$entry->getId().'/tags', array('tags' => $newTags), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('tags', $content);
+        $this->assertEquals($nbTags + 3, count($content['tags']));
+
+        $entryDB = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->find($entry->getId());
+
+        $tagsInDB = array();
+        foreach ($entryDB->getTags()->toArray() as $tag) {
+            $tagsInDB[$tag->getId()] = $tag->getLabel();
+        }
+
+        foreach (explode(',', $newTags) as $tag) {
+            $this->assertContains($tag, $tagsInDB);
+        }
+    }
+
+    public function testDeleteOneTagEntrie()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $entry = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        // hydrate the tags relations
+        $nbTags = count($entry->getTags());
+        $tag = $entry->getTags()[0];
+
+        $client->request('DELETE', '/api/entries/'.$entry->getId().'/tags/'.$tag->getId().'.json', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('tags', $content);
+        $this->assertEquals($nbTags - 1, count($content['tags']));
+    }
+
+    public function testGetUserTags()
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('GET', '/api/tags.json', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content);
+        $this->assertArrayHasKey('id', $content[0]);
+        $this->assertArrayHasKey('label', $content[0]);
+
+        return end($content);
+    }
+
+    /**
+     * @depends testGetUserTags
+     */
+    public function testDeleteUserTag($tag)
+    {
+        $client = $this->createClient();
+        $headers = $this->generateHeaders('admin', 'mypassword');
+
+        $client->request('DELETE', '/api/tags/'.$tag['id'].'.json', array(), array(), $headers);
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $content = json_decode($client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('label', $content);
+        $this->assertEquals($tag['label'], $content['label']);
+    }
+}
diff --git a/src/Wallabag/ApiBundle/WallabagApiBundle.php b/src/Wallabag/ApiBundle/WallabagApiBundle.php
new file mode 100644 (file)
index 0000000..2484f27
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace Wallabag\ApiBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Wallabag\ApiBundle\DependencyInjection\Security\Factory\WsseFactory;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+class WallabagApiBundle extends Bundle
+{
+    public function build(ContainerBuilder $container)
+    {
+        parent::build($container);
+
+        $extension = $container->getExtension('security');
+        $extension->addSecurityListenerFactory(new WsseFactory());
+    }
+}
index 493842f7959962818fd5127207afa77982a947c3..491c67f9fc99533c7e49ec7cd12cc6a7a883adea 100644 (file)
@@ -225,7 +225,7 @@ class InstallCommand extends ContainerAwareCommand
     }
 
     /**
-     * Run a command
+     * Run a command.
      *
      * @param string $command
      * @param array  $parameters Parameters to this command (usually 'force' => true)
@@ -266,9 +266,9 @@ class InstallCommand extends ContainerAwareCommand
     }
 
     /**
-     * Check if the database already exists
+     * Check if the database already exists.
      *
-     * @return boolean
+     * @return bool
      */
     private function isDatabasePresent()
     {
@@ -300,9 +300,9 @@ class InstallCommand extends ContainerAwareCommand
 
     /**
      * Check if the schema is already created.
-     * If we found at least oen table, it means the schema exists
+     * If we found at least oen table, it means the schema exists.
      *
-     * @return boolean
+     * @return bool
      */
     private function isSchemaPresent()
     {
index 898c291f2b5ea028cead23a7963674afcbdc13a1..62ef3eeaf4107741be3671164131a8fb785b878e 100644 (file)
@@ -133,7 +133,7 @@ class ConfigController extends Controller
             'rss' => array(
                 'username' => $user->getUsername(),
                 'token' => $config->getRssToken(),
-            )
+            ),
         ));
     }
 
index 8a8f3cd79ed76cecc5ad9dbdf6a69e6ac2158010..7fd982c903e82e66f0789125bedd62ffba616d5e 100644 (file)
@@ -50,7 +50,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Shows unread entries for current user
+     * Shows unread entries for current user.
      *
      * @Route("/unread", name="unread")
      *
@@ -70,7 +70,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Shows read entries for current user
+     * Shows read entries for current user.
      *
      * @Route("/archive", name="archive")
      *
@@ -90,7 +90,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Shows starred entries for current user
+     * Shows starred entries for current user.
      *
      * @Route("/starred", name="starred")
      *
@@ -110,7 +110,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Shows entry content
+     * Shows entry content.
      *
      * @param Entry $entry
      *
@@ -129,7 +129,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Changes read status for an entry
+     * Changes read status for an entry.
      *
      * @param Request $request
      * @param Entry   $entry
@@ -154,7 +154,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Changes favorite status for an entry
+     * Changes favorite status for an entry.
      *
      * @param Request $request
      * @param Entry   $entry
@@ -179,7 +179,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Deletes entry
+     * Deletes entry.
      *
      * @param Request $request
      * @param Entry   $entry
@@ -205,7 +205,7 @@ class EntryController extends Controller
     }
 
     /**
-     * Check if the logged user can manage the given entry
+     * Check if the logged user can manage the given entry.
      *
      * @param Entry $entry
      */
index 14f1dcb2c081fc491a6ff9f9f7ce62a1205dca55..86754e157e7b6ff0d1079b452d59209ab28d3660 100644 (file)
@@ -11,7 +11,7 @@ use Wallabag\CoreBundle\Entity\Entry;
 class RssController extends Controller
 {
     /**
-     * Shows unread entries for current user
+     * Shows unread entries for current user.
      *
      * @Route("/{username}/{token}/unread.xml", name="unread_rss", defaults={"_format"="xml"})
      * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
@@ -35,7 +35,7 @@ class RssController extends Controller
     }
 
     /**
-     * Shows read entries for current user
+     * Shows read entries for current user.
      *
      * @Route("/{username}/{token}/archive.xml", name="archive_rss")
      * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
@@ -59,7 +59,7 @@ class RssController extends Controller
     }
 
     /**
-     * Shows starred entries for current user
+     * Shows starred entries for current user.
      *
      * @Route("/{username}/{token}/starred.xml", name="starred_rss")
      * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
index fe511db5ce6100a853fb881e26c54548e4bb7782..a61a898bf1d07598fb9f54d36c5b0519db7b1dab 100644 (file)
@@ -30,9 +30,10 @@ class SecurityController extends Controller
     }
 
     /**
-     * Request forgot password: show form
+     * Request forgot password: show form.
      *
      * @Route("/forgot-password", name="forgot_password")
+     *
      * @Method({"GET", "POST"})
      */
     public function forgotPasswordAction(Request $request)
@@ -73,9 +74,10 @@ class SecurityController extends Controller
     }
 
     /**
-     * Tell the user to check his email provider
+     * Tell the user to check his email provider.
      *
      * @Route("/forgot-password/check-email", name="forgot_password_check_email")
+     *
      * @Method({"GET"})
      */
     public function checkEmailAction(Request $request)
@@ -93,9 +95,10 @@ class SecurityController extends Controller
     }
 
     /**
-     * Reset user password
+     * Reset user password.
      *
      * @Route("/forgot-password/{token}", name="forgot_password_reset")
+     *
      * @Method({"GET", "POST"})
      */
     public function resetAction(Request $request, $token)
index 54d0d6b6c24719f71b444128e5fd3474ec30f425..547d6753e179135c5e6839d69caf63f6c1319990 100644 (file)
@@ -39,9 +39,9 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
         $entry3->setContent('This is my content /o/');
 
         $tag1 = new Tag($this->getReference('bob-user'));
-        $tag1->setLabel("foo");
+        $tag1->setLabel('foo');
         $tag2 = new Tag($this->getReference('bob-user'));
-        $tag2->setLabel("bar");
+        $tag2->setLabel('bar');
 
         $entry3->addTag($tag1);
         $entry3->addTag($tag2);
@@ -56,9 +56,9 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
         $entry4->setContent('This is my content /o/');
 
         $tag1 = new Tag($this->getReference('admin-user'));
-        $tag1->setLabel("foo");
+        $tag1->setLabel('foo');
         $tag2 = new Tag($this->getReference('admin-user'));
-        $tag2->setLabel("bar");
+        $tag2->setLabel('bar');
 
         $entry4->addTag($tag1);
         $entry4->addTag($tag2);
index c6ecc99e00145afaec17737fb30cb8ea9c9258c6..7493351bd7b4bab1986843046f5f00077cbbed04 100644 (file)
@@ -3,15 +3,15 @@
 namespace Wallabag\CoreBundle\DependencyInjection;
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
-use Symfony\Component\HttpKernel\DependencyInjection\Extension;
 use Symfony\Component\Config\FileLocator;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use Symfony\Component\DependencyInjection\Loader;
 
 class WallabagCoreExtension extends Extension
 {
     public function load(array $configs, ContainerBuilder $container)
     {
-        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
         $loader->load('services.yml');
     }
 
index 861a60ea408fe137bd7d53c87f71c78e1e400ada..509348db59ce515557c28b9e2b211878a3736dce 100644 (file)
@@ -25,7 +25,7 @@ class PrefixedNamingStrategy implements NamingStrategy
      */
     public function classToTableName($className)
     {
-        return strtolower($this->prefix . substr($className, strrpos($className, '\\') + 1));
+        return strtolower($this->prefix.substr($className, strrpos($className, '\\') + 1));
     }
 
     /**
@@ -49,7 +49,7 @@ class PrefixedNamingStrategy implements NamingStrategy
      */
     public function joinColumnName($propertyName)
     {
-        return $propertyName . '_' . $this->referenceColumnName();
+        return $propertyName.'_'.$this->referenceColumnName();
     }
 
     /**
@@ -62,7 +62,7 @@ class PrefixedNamingStrategy implements NamingStrategy
         // ie: not "wallabag_entry_wallabag_tag" but "wallabag_entry_tag"
         $target = substr($targetEntity, strrpos($targetEntity, '\\') + 1);
 
-        return strtolower($this->classToTableName($sourceEntity) . '_' .$target);
+        return strtolower($this->classToTableName($sourceEntity).'_'.$target);
     }
 
     /**
@@ -70,6 +70,14 @@ class PrefixedNamingStrategy implements NamingStrategy
      */
     public function joinKeyColumnName($entityName, $referencedColumnName = null)
     {
-        return strtolower($this->classToTableName($entityName) . '_' .($referencedColumnName ?: $this->referenceColumnName()));
+        return strtolower($this->classToTableName($entityName).'_'.($referencedColumnName ?: $this->referenceColumnName()));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function embeddedFieldToColumnName($propertyName, $embeddedColumnName, $className = null, $embeddedClassName = null)
+    {
+        return $propertyName.'_'.$embeddedColumnName;
     }
 }
index 62ea637eaaa4e64debd5b99262afb92b7bee477b..025d94efb605ee9ff1be2e1f86cadacb536d2d87 100644 (file)
@@ -6,7 +6,7 @@ use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
- * Config
+ * Config.
  *
  * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ConfigRepository")
  * @ORM\Table
@@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints as Assert;
 class Config
 {
     /**
-     * @var integer
+     * @var int
      *
      * @ORM\Column(name="id", type="integer")
      * @ORM\Id
@@ -32,7 +32,7 @@ class Config
     private $theme;
 
     /**
-     * @var integer
+     * @var int
      *
      * @Assert\NotBlank()
      * @Assert\Range(
@@ -60,7 +60,7 @@ class Config
     private $rssToken;
 
     /**
-     * @var integer
+     * @var int
      *
      * @ORM\Column(name="rss_limit", type="integer", nullable=true)
      * @Assert\Range(
@@ -85,9 +85,9 @@ class Config
     }
 
     /**
-     * Get id
+     * Get id.
      *
-     * @return integer
+     * @return int
      */
     public function getId()
     {
@@ -95,9 +95,10 @@ class Config
     }
 
     /**
-     * Set theme
+     * Set theme.
+     *
+     * @param string $theme
      *
-     * @param  string $theme
      * @return Config
      */
     public function setTheme($theme)
@@ -108,7 +109,7 @@ class Config
     }
 
     /**
-     * Get theme
+     * Get theme.
      *
      * @return string
      */
@@ -118,9 +119,10 @@ class Config
     }
 
     /**
-     * Set itemsPerPage
+     * Set itemsPerPage.
+     *
+     * @param int $itemsPerPage
      *
-     * @param  integer $itemsPerPage
      * @return Config
      */
     public function setItemsPerPage($itemsPerPage)
@@ -131,9 +133,9 @@ class Config
     }
 
     /**
-     * Get itemsPerPage
+     * Get itemsPerPage.
      *
-     * @return integer
+     * @return int
      */
     public function getItemsPerPage()
     {
@@ -141,9 +143,10 @@ class Config
     }
 
     /**
-     * Set language
+     * Set language.
+     *
+     * @param string $language
      *
-     * @param  string $language
      * @return Config
      */
     public function setLanguage($language)
@@ -154,7 +157,7 @@ class Config
     }
 
     /**
-     * Get language
+     * Get language.
      *
      * @return string
      */
@@ -164,9 +167,10 @@ class Config
     }
 
     /**
-     * Set user
+     * Set user.
+     *
+     * @param \Wallabag\CoreBundle\Entity\User $user
      *
-     * @param  \Wallabag\CoreBundle\Entity\User $user
      * @return Config
      */
     public function setUser(\Wallabag\CoreBundle\Entity\User $user = null)
@@ -177,7 +181,7 @@ class Config
     }
 
     /**
-     * Get user
+     * Get user.
      *
      * @return \Wallabag\CoreBundle\Entity\User
      */
@@ -187,9 +191,10 @@ class Config
     }
 
     /**
-     * Set rssToken
+     * Set rssToken.
+     *
+     * @param string $rssToken
      *
-     * @param  string $rssToken
      * @return Config
      */
     public function setRssToken($rssToken)
@@ -200,7 +205,7 @@ class Config
     }
 
     /**
-     * Get rssToken
+     * Get rssToken.
      *
      * @return string
      */
@@ -210,9 +215,10 @@ class Config
     }
 
     /**
-     * Set rssLimit
+     * Set rssLimit.
+     *
+     * @param string $rssLimit
      *
-     * @param  string $rssLimit
      * @return Config
      */
     public function setRssLimit($rssLimit)
@@ -223,7 +229,7 @@ class Config
     }
 
     /**
-     * Get rssLimit
+     * Get rssLimit.
      *
      * @return string
      */
index 15af105d22f78c7c9f25156a9332108d1e0aef70..b1998ab64df58355ffaedcd836aaf917407d3b4e 100644 (file)
@@ -9,7 +9,7 @@ use Hateoas\Configuration\Annotation as Hateoas;
 use JMS\Serializer\Annotation\XmlRoot;
 
 /**
- * Entry
+ * Entry.
  *
  * @XmlRoot("entry")
  * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository")
@@ -21,7 +21,7 @@ class Entry
 {
     /** @Serializer\XmlAttribute */
     /**
-     * @var integer
+     * @var int
      *
      * @ORM\Column(name="id", type="integer")
      * @ORM\Id
@@ -45,14 +45,14 @@ class Entry
     private $url;
 
     /**
-     * @var boolean
+     * @var bool
      *
      * @ORM\Column(name="is_archived", type="boolean")
      */
     private $isArchived = false;
 
     /**
-     * @var boolean
+     * @var bool
      *
      * @ORM\Column(name="is_starred", type="boolean")
      */
@@ -94,7 +94,7 @@ class Entry
     private $mimetype;
 
     /**
-     * @var integer
+     * @var int
      *
      * @ORM\Column(name="reading_type", type="integer", nullable=true)
      */
@@ -108,7 +108,7 @@ class Entry
     private $domainName;
 
     /**
-     * @var boolean
+     * @var bool
      *
      * @ORM\Column(name="is_public", type="boolean", nullable=true, options={"default" = false})
      */
@@ -135,9 +135,9 @@ class Entry
     }
 
     /**
-     * Get id
+     * Get id.
      *
-     * @return integer
+     * @return int
      */
     public function getId()
     {
@@ -145,9 +145,10 @@ class Entry
     }
 
     /**
-     * Set title
+     * Set title.
+     *
+     * @param string $title
      *
-     * @param  string $title
      * @return Entry
      */
     public function setTitle($title)
@@ -158,7 +159,7 @@ class Entry
     }
 
     /**
-     * Get title
+     * Get title.
      *
      * @return string
      */
@@ -168,9 +169,10 @@ class Entry
     }
 
     /**
-     * Set url
+     * Set url.
+     *
+     * @param string $url
      *
-     * @param  string $url
      * @return Entry
      */
     public function setUrl($url)
@@ -181,7 +183,7 @@ class Entry
     }
 
     /**
-     * Get url
+     * Get url.
      *
      * @return string
      */
@@ -191,9 +193,10 @@ class Entry
     }
 
     /**
-     * Set isArchived
+     * Set isArchived.
+     *
+     * @param string $isArchived
      *
-     * @param  string $isArchived
      * @return Entry
      */
     public function setArchived($isArchived)
@@ -204,7 +207,7 @@ class Entry
     }
 
     /**
-     * Get isArchived
+     * Get isArchived.
      *
      * @return string
      */
@@ -221,9 +224,10 @@ class Entry
     }
 
     /**
-     * Set isStarred
+     * Set isStarred.
+     *
+     * @param string $isStarred
      *
-     * @param  string $isStarred
      * @return Entry
      */
     public function setStarred($isStarred)
@@ -234,7 +238,7 @@ class Entry
     }
 
     /**
-     * Get isStarred
+     * Get isStarred.
      *
      * @return string
      */
@@ -251,9 +255,10 @@ class Entry
     }
 
     /**
-     * Set content
+     * Set content.
+     *
+     * @param string $content
      *
-     * @param  string $content
      * @return Entry
      */
     public function setContent($content)
@@ -264,7 +269,7 @@ class Entry
     }
 
     /**
-     * Get content
+     * Get content.
      *
      * @return string
      */
@@ -375,7 +380,7 @@ class Entry
     }
 
     /**
-     * @return boolean
+     * @return bool
      */
     public function isPublic()
     {
@@ -383,7 +388,7 @@ class Entry
     }
 
     /**
-     * @param boolean $isPublic
+     * @param bool $isPublic
      */
     public function setPublic($isPublic)
     {
index 9d3c7a32105327cceccadecc0f74711d6d09c3ff..afe9e1b9af22a8d4263d29a9728afa641ca0c894 100644 (file)
@@ -9,7 +9,7 @@ use JMS\Serializer\Annotation\Expose;
 use Doctrine\Common\Collections\ArrayCollection;
 
 /**
- * Tag
+ * Tag.
  *
  * @XmlRoot("tag")
  * @ORM\Table
@@ -19,7 +19,7 @@ use Doctrine\Common\Collections\ArrayCollection;
 class Tag
 {
     /**
-     * @var integer
+     * @var int
      *
      * @Expose
      * @ORM\Column(name="id", type="integer")
@@ -52,9 +52,9 @@ class Tag
         $this->entries = new ArrayCollection();
     }
     /**
-     * Get id
+     * Get id.
      *
-     * @return integer
+     * @return int
      */
     public function getId()
     {
@@ -62,9 +62,10 @@ class Tag
     }
 
     /**
-     * Set label
+     * Set label.
+     *
+     * @param string $label
      *
-     * @param  string $label
      * @return Tag
      */
     public function setLabel($label)
@@ -75,7 +76,7 @@ class Tag
     }
 
     /**
-     * Get label
+     * Get label.
      *
      * @return string
      */
index ff08c8fb28019b2451d33daa9a558d6d8586ae7a..00eb808a626839c1e12d5c879f1d19d6a197878b 100644 (file)
@@ -12,7 +12,7 @@ use JMS\Serializer\Annotation\ExclusionPolicy;
 use JMS\Serializer\Annotation\Expose;
 
 /**
- * User
+ * User.
  *
  * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\UserRepository")
  * @ORM\Table
@@ -25,7 +25,7 @@ use JMS\Serializer\Annotation\Expose;
 class User implements AdvancedUserInterface, \Serializable
 {
     /**
-     * @var integer
+     * @var int
      *
      * @Expose
      * @ORM\Column(name="id", type="integer")
@@ -142,9 +142,9 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get id
+     * Get id.
      *
-     * @return integer
+     * @return int
      */
     public function getId()
     {
@@ -152,9 +152,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set username
+     * Set username.
+     *
+     * @param string $username
      *
-     * @param  string $username
      * @return User
      */
     public function setUsername($username)
@@ -165,7 +166,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get username
+     * Get username.
      *
      * @return string
      */
@@ -191,9 +192,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set password
+     * Set password.
+     *
+     * @param string $password
      *
-     * @param  string $password
      * @return User
      */
     public function setPassword($password)
@@ -208,7 +210,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get password
+     * Get password.
      *
      * @return string
      */
@@ -218,9 +220,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set name
+     * Set name.
+     *
+     * @param string $name
      *
-     * @param  string $name
      * @return User
      */
     public function setName($name)
@@ -231,7 +234,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get name
+     * Get name.
      *
      * @return string
      */
@@ -241,9 +244,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set email
+     * Set email.
+     *
+     * @param string $email
      *
-     * @param  string $email
      * @return User
      */
     public function setEmail($email)
@@ -254,7 +258,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get email
+     * Get email.
      *
      * @return string
      */
@@ -341,8 +345,7 @@ class User implements AdvancedUserInterface, \Serializable
     public function unserialize($serialized)
     {
         list(
-            $this->id,
-            ) = unserialize($serialized);
+            $this->id) = unserialize($serialized);
     }
 
     public function isEqualTo(UserInterface $user)
@@ -370,9 +373,10 @@ class User implements AdvancedUserInterface, \Serializable
         return $this->isActive;
     }
     /**
-     * Set config
+     * Set config.
+     *
+     * @param \Wallabag\CoreBundle\Entity\Config $config
      *
-     * @param  \Wallabag\CoreBundle\Entity\Config $config
      * @return User
      */
     public function setConfig(\Wallabag\CoreBundle\Entity\Config $config = null)
@@ -383,7 +387,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get config
+     * Get config.
      *
      * @return \Wallabag\CoreBundle\Entity\Config
      */
@@ -393,9 +397,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set confirmationToken
+     * Set confirmationToken.
+     *
+     * @param string $confirmationToken
      *
-     * @param  string $confirmationToken
      * @return User
      */
     public function setConfirmationToken($confirmationToken)
@@ -406,7 +411,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get confirmationToken
+     * Get confirmationToken.
      *
      * @return string
      */
@@ -416,9 +421,10 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Set passwordRequestedAt
+     * Set passwordRequestedAt.
+     *
+     * @param \DateTime $passwordRequestedAt
      *
-     * @param  \DateTime $passwordRequestedAt
      * @return User
      */
     public function setPasswordRequestedAt($passwordRequestedAt)
@@ -429,7 +435,7 @@ class User implements AdvancedUserInterface, \Serializable
     }
 
     /**
-     * Get passwordRequestedAt
+     * Get passwordRequestedAt.
      *
      * @return \DateTime
      */
index e141789f10e913fe7ad1da9085fb3d97d1b52eae..b4224e3df69df004f15e148afb10777abf8770d5 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 0fcf020add5ef5495f1a341ba52e03ca3fe17992..d5890971a976484793c13b033f24307fc1697b6a 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 9a64def5f0043d6d7a5914ef2218b0d307ecddb9..0532bf104e8523d295a098034a9c18325d53ae20 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 4cc16a501a28c4a93453b0881fb6718d9bf8cafe..9e95eb47a9613d9ed0727a889b3b3925a8fa3d11 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index b7ebe8c24d50fca2b58cab66cdf43ee1f9b4a8ef..a12fff2b9b850514a6d0296bed79877550a640f1 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 50ae800b4a6f81a5ea1eaa4f11a95fd49479150f..a5d683c46f36fc2b2943c928d640f71468e6f20f 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index a1ab990f2f45fe6c3f682c328dbd50d7f0eb3af1..e14e84e101d94a423ee424c57772f09d5c1471b3 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 3d6df51017161c84bb6e244a86cc51d5565cefb4..f0367d14f339809f781bff5b4255ad123e34187e 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace Wallabag\CoreBundle\Form\Type;
 
 use Symfony\Component\Form\AbstractType;
index 0fd5f259c42d5fd56adb2a6151f57ee8a6207dc6..be29ab994ea95c5f73429e9639d07a47268e9c46 100755 (executable)
@@ -5,15 +5,16 @@ namespace Wallabag\CoreBundle\Helper;
 final class Tools
 {
     /**
-     * Download a file (typically, for downloading pictures on web server)
+     * Download a file (typically, for downloading pictures on web server).
      *
      * @param $url
+     *
      * @return bool|mixed|string
      */
     public static function getFile($url)
     {
         $timeout = 15;
-        $useragent = "Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0";
+        $useragent = 'Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0';
 
         if (in_array('curl', get_loaded_extensions())) {
             # Fetch feed from URL
@@ -32,7 +33,7 @@ final class Tools
 
             # FeedBurner requires a proper USER-AGENT...
             curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
-            curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
+            curl_setopt($curl, CURLOPT_ENCODING, 'gzip, deflate');
             curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
 
             $data = curl_exec($curl);
@@ -45,7 +46,7 @@ final class Tools
                 array(
                     'http' => array(
                         'timeout' => $timeout,
-                        'header' => "User-Agent: ".$useragent,
+                        'header' => 'User-Agent: '.$useragent,
                         'follow_location' => true,
                     ),
                     'ssl' => array(
@@ -91,9 +92,10 @@ final class Tools
     }
 
     /**
-     * Encode a URL by using a salt
+     * Encode a URL by using a salt.
      *
      * @param $string
+     *
      * @return string
      */
     public static function encodeString($string)
index a8c138a97670b1e3f830060d58d28a50bfd2b4e7..1335e808666bc05eb63042d84b080482d7dff368 100644 (file)
@@ -10,7 +10,7 @@ use Pagerfanta\Pagerfanta;
 class EntryRepository extends EntityRepository
 {
     /**
-     * Retrieves unread entries for a user
+     * Retrieves unread entries for a user.
      *
      * @param int $userId
      * @param int $firstResult
@@ -35,7 +35,7 @@ class EntryRepository extends EntityRepository
     }
 
     /**
-     * Retrieves read entries for a user
+     * Retrieves read entries for a user.
      *
      * @param int $userId
      * @param int $firstResult
@@ -61,7 +61,7 @@ class EntryRepository extends EntityRepository
     }
 
     /**
-     * Retrieves starred entries for a user
+     * Retrieves starred entries for a user.
      *
      * @param int $userId
      * @param int $firstResult
@@ -87,7 +87,7 @@ class EntryRepository extends EntityRepository
     }
 
     /**
-     * Find Entries
+     * Find Entries.
      *
      * @param int    $userId
      * @param bool   $isArchived
index aab3dedcb66c2389fca068969a82b0fea48c6827..968d0b49791e436e5d537d7ef3d1f892d1569684 100644 (file)
@@ -7,7 +7,7 @@ use Doctrine\ORM\EntityRepository;
 class UserRepository extends EntityRepository
 {
     /**
-     * Find a user by its username and rss roken
+     * Find a user by its username and rss roken.
      *
      * @param string $username
      * @param string $rssToken
diff --git a/src/Wallabag/CoreBundle/Resources/config/routing_rest.yml b/src/Wallabag/CoreBundle/Resources/config/routing_rest.yml
deleted file mode 100644 (file)
index d3af6b7..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-entries:
-  type: rest
-  resource:     "WallabagCoreBundle:WallabagRest"
-  name_prefix:  api_
index cea6c0df1098681478686cf8a883e21e799dc79e..d8bd8d5295daa2dbd345676d65694ec47d452971 100644 (file)
@@ -4,18 +4,6 @@ services:
         tags:
             - { name: twig.extension }
 
-    wsse.security.authentication.provider:
-        class: Wallabag\CoreBundle\Security\Authentication\Provider\WsseProvider
-        public: false
-        arguments: ['', '%kernel.cache_dir%/security/nonces']
-
-    wsse.security.authentication.listener:
-        class: Wallabag\CoreBundle\Security\Firewall\WsseListener
-        public: false
-        tags:
-            - { name: monolog.logger, channel: wsse }
-        arguments: ['@security.context', '@security.authentication.manager', '@logger']
-
     wallabag_core.helper.detect_active_theme:
         class: Wallabag\CoreBundle\Helper\DetectActiveTheme
         arguments:
index fcfe418bf966d076bb4c0e24f826010527ac47c8..e7c81fc0ae08961bd9a34652abbca7042d565a7c 100644 (file)
@@ -7,8 +7,7 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
 
 /**
  * This override just add en extra variable (username) to be able to salt the password
- * the way Wallabag v1 does. It will avoid to break compatibility with Wallabag v1
- *
+ * the way Wallabag v1 does. It will avoid to break compatibility with Wallabag v1.
  */
 class WallabagPasswordEncoder extends BasePasswordEncoder
 {
index 1c7c5fae8f641f03eb8b5da918b0f291cb478018..cf3cb0511bc939b26ab42f3aa46c40792797ca6d 100644 (file)
@@ -45,7 +45,7 @@ class WallabagAuthenticationProvider extends UserAuthenticationProvider
                 throw new BadCredentialsException('The credentials were changed from another session.');
             }
         } else {
-            if ("" === ($presentedPassword = $token->getCredentials())) {
+            if ('' === ($presentedPassword = $token->getCredentials())) {
                 throw new BadCredentialsException('The presented password cannot be empty.');
             }
 
index e4ec96f6d41f4156b00772b3c077fb467dc1924a..6d43a1da5c3e522e446ade423cf315fc5092e910 100644 (file)
@@ -9,7 +9,7 @@ final class Extractor
 {
     public static function extract($url)
     {
-        $pageContent = Extractor::getPageContent(new Url(base64_encode($url)));
+        $pageContent = self::getPageContent(new Url(base64_encode($url)));
         $title = $pageContent['rss']['channel']['item']['title'] ?: 'Untitled';
         $body = $pageContent['rss']['channel']['item']['description'];
 
@@ -21,9 +21,10 @@ final class Extractor
     }
 
     /**
-     * Get the content for a given URL (by a call to FullTextFeed)
+     * Get the content for a given URL (by a call to FullTextFeed).
+     *
+     * @param Url $url
      *
-     * @param  Url   $url
      * @return mixed
      */
     public static function getPageContent(Url $url)
@@ -49,12 +50,12 @@ final class Extractor
         $scope = function () {
             extract(func_get_arg(1));
             $_GET = $_REQUEST = array(
-                "url" => $url->getUrl(),
-                "max" => 5,
-                "links" => "preserve",
-                "exc" => "",
-                "format" => "json",
-                "submit" => "Create Feed",
+                'url' => $url->getUrl(),
+                'max' => 5,
+                'links' => 'preserve',
+                'exc' => '',
+                'format' => 'json',
+                'submit' => 'Create Feed',
             );
             ob_start();
             require func_get_arg(0);
@@ -67,11 +68,11 @@ final class Extractor
         // Silence $scope function to avoid
         // issues with FTRSS when error_reporting is to high
         // FTRSS generates PHP warnings which break output
-        $json = @$scope(__DIR__."/../../../../vendor/wallabag/Fivefilters_Libraries/makefulltextfeed.php", array("url" => $url));
+        $json = @$scope(__DIR__.'/../../../../vendor/wallabag/Fivefilters_Libraries/makefulltextfeed.php', array('url' => $url));
 
         // Clearing and restoring context
         foreach ($GLOBALS as $key => $value) {
-            if ($key != "GLOBALS" && $key != "_SESSION") {
+            if ($key != 'GLOBALS' && $key != '_SESSION') {
                 unset($GLOBALS[$key]);
             }
         }
index f689b5328318f510b95030f3f2d25c708b3d2fe8..7a819953e07d08bc24caa3f2a39d3761100a2723 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace Wallabag\CoreBundle\Tests\Command;
 
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
+use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
 use Wallabag\CoreBundle\Command\InstallCommand;
 use Wallabag\CoreBundle\Tests\Mock\InstallCommandMock;
 use Symfony\Bundle\FrameworkBundle\Console\Application;
@@ -12,7 +12,7 @@ use Symfony\Component\Console\Output\NullOutput;
 use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
 use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
 
-class InstallCommandTest extends WallabagTestCase
+class InstallCommandTest extends WallabagCoreTestCase
 {
     public static function tearDownAfterClass()
     {
index 5030bcbd5f561d5c9c306e718b39086eb6857129..a01457808deb18a918143af4e4ad0737d01bb797 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace Wallabag\CoreBundle\Tests\Controller;
 
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
+use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
 
-class ConfigControllerTest extends WallabagTestCase
+class ConfigControllerTest extends WallabagCoreTestCase
 {
     public function testLogin()
     {
@@ -397,7 +397,7 @@ class ConfigControllerTest extends WallabagTestCase
         );
 
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
-        $content = json_decode($client->getResponse()->getContent(), true);;
+        $content = json_decode($client->getResponse()->getContent(), true);
         $this->assertArrayHasKey('token', $content);
     }
 
index 1a0d586c2e0b9bcd527188e9070b9bd59a0e4676..8a7fdda2e36f99ec9728fe74cedb92b02ab5077f 100644 (file)
@@ -2,10 +2,10 @@
 
 namespace Wallabag\CoreBundle\Tests\Controller;
 
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
+use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
 use Doctrine\ORM\AbstractQuery;
 
-class EntryControllerTest extends WallabagTestCase
+class EntryControllerTest extends WallabagCoreTestCase
 {
     public function testLogin()
     {
index 8f627b4b82cf2d2a93e8b9d804d8b9b6d8eff457..b7c162a77e0219b62ad1950d7d1fc3cfb5cd0ee8 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace Wallabag\CoreBundle\Tests\Controller;
 
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
+use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
 
-class RssControllerTest extends WallabagTestCase
+class RssControllerTest extends WallabagCoreTestCase
 {
     public function validateDom($xml, $nb = null)
     {
@@ -36,13 +36,13 @@ class RssControllerTest extends WallabagTestCase
     {
         return array(
             array(
-                '/admin/YZIOAUZIAO/unread.xml'
+                '/admin/YZIOAUZIAO/unread.xml',
             ),
             array(
-                '/wallace/YZIOAUZIAO/starred.xml'
+                '/wallace/YZIOAUZIAO/starred.xml',
             ),
             array(
-                '/wallace/YZIOAUZIAO/archives.xml'
+                '/wallace/YZIOAUZIAO/archives.xml',
             ),
         );
     }
index 1dd05f89ba624fa83f5f03044b73fb379293cfe3..e560ffdd3d2cdadebcf50bd80cfb5a4460af1d72 100644 (file)
@@ -2,11 +2,11 @@
 
 namespace Wallabag\CoreBundle\Tests\Controller;
 
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
 use Symfony\Component\Filesystem\Filesystem;
 use Symfony\Component\Finder\Finder;
+use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
 
-class SecurityControllerTest extends WallabagTestCase
+class SecurityControllerTest extends WallabagCoreTestCase
 {
     public function testLogin()
     {
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php
deleted file mode 100644 (file)
index c990706..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-<?php
-
-namespace Wallabag\CoreBundle\Tests\Controller;
-
-use Wallabag\CoreBundle\Tests\WallabagTestCase;
-
-class WallabagRestControllerTest extends WallabagTestCase
-{
-    /**
-     * Generate HTTP headers for authenticate user on API
-     *
-     * @param $username
-     * @param $password
-     * @param $salt
-     *
-     * @return array
-     */
-    private function generateHeaders($username, $password, $salt)
-    {
-        $encryptedPassword = sha1($password.$username.$salt);
-        $nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
-
-        $now = new \DateTime('now', new \DateTimeZone('UTC'));
-        $created = (string) $now->format('Y-m-d\TH:i:s\Z');
-        $digest = base64_encode(sha1(base64_decode($nonce).$created.$encryptedPassword, true));
-
-        return array(
-            'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
-            'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="'.$username.'", PasswordDigest="'.$digest.'", Nonce="'.$nonce.'", Created="'.$created.'"',
-        );
-    }
-
-    public function testGetSalt()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-        $this->assertNotEmpty(json_decode($client->getResponse()->getContent()));
-
-        $client->request('GET', '/api/salts/notfound.json');
-        $this->assertEquals(404, $client->getResponse()->getStatusCode());
-    }
-
-    public function testWithBadHeaders()
-    {
-        $client = $this->createClient();
-
-        $entry = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByIsArchived(false);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $badHeaders = array(
-            'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
-            'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="admin", PasswordDigest="Wr0ngDig3st", Nonce="n0Nc3", Created="2015-01-01T13:37:00Z"',
-        );
-
-        $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $badHeaders);
-        $this->assertEquals(403, $client->getResponse()->getStatusCode());
-    }
-
-    public function testGetOneEntry()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $entry = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByIsArchived(false);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
-        $this->assertContains($entry->getTitle(), $client->getResponse()->getContent());
-
-        $this->assertTrue(
-            $client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetEntries()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $client->request('GET', '/api/entries', array(), array(), $headers);
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        $this->assertGreaterThanOrEqual(1, count(json_decode($client->getResponse()->getContent())));
-
-        $this->assertContains('Google', $client->getResponse()->getContent());
-
-        $this->assertTrue(
-            $client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testDeleteEntry()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $entry = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        // We'll try to delete this entry again
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
-
-        $this->assertEquals(404, $client->getResponse()->getStatusCode());
-    }
-
-    public function testGetTagsEntry()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $entry = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneWithTags(1);
-
-        $entry = $entry[0];
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $tags = array();
-        foreach ($entry->getTags() as $tag) {
-            $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel());
-        }
-
-        $client->request('GET', '/api/entries/'.$entry->getId().'/tags', array(), array(), $headers);
-
-        $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $client->getResponse()->getContent());
-    }
-
-    public function testPostTagsOnEntry()
-    {
-        $client = $this->createClient();
-        $client->request('GET', '/api/salts/admin.json');
-        $salt = json_decode($client->getResponse()->getContent());
-        $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
-
-        $entry = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $newTags = 'tag1,tag2,tag3';
-
-        $client->request('POST', '/api/entries/'.$entry->getId().'/tags', array('tags' => $newTags), array(), $headers);
-
-        $this->assertEquals(200, $client->getResponse()->getStatusCode());
-
-        $entryDB = $client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->find($entry->getId());
-
-        $tagsInDB = array();
-        foreach ($entryDB->getTags()->toArray() as $tag) {
-            $tagsInDB[$tag->getId()] = $tag->getLabel();
-        }
-
-        foreach (explode(',', $newTags) as $tag) {
-            $this->assertContains($tag, $tagsInDB);
-        }
-    }
-}
similarity index 91%
rename from src/Wallabag/CoreBundle/Tests/WallabagTestCase.php
rename to src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php
index 22016d8edd7c04727c416a7bf8a9faa338693200..e5096528cefe39d683a07a6fb67286913dc20a97 100644 (file)
@@ -4,7 +4,7 @@ namespace Wallabag\CoreBundle\Tests;
 
 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
 
-abstract class WallabagTestCase extends WebTestCase
+abstract class WallabagCoreTestCase extends WebTestCase
 {
     private $client = null;
 
index de97c796bda9f54d2ebc104439465a5864c23f22..7e2968e77f45153fc55178fd9bac190450a7bb5a 100644 (file)
@@ -5,7 +5,7 @@ namespace Wallabag\CoreBundle\Tools;
 class Utils
 {
     /**
-     * Generate a token used for RSS
+     * Generate a token used for RSS.
      *
      * @return string
      */
@@ -22,6 +22,7 @@ class Utils
             $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
         }
 
-        return str_replace('+', '', $token);
+        // remove character which can broken the url
+        return str_replace(array('+', '/'), '', $token);
     }
 }
index 92406865fc2ac682f77b1a0e88e440843b11695e..18388948edb01ab78a48cc52b045aa888323f906 100644 (file)
@@ -13,9 +13,10 @@ class WallabagExtension extends \Twig_Extension
     }
 
     /**
-     * Returns the domain name for a URL
+     * Returns the domain name for a URL.
      *
      * @param $url
+     *
      * @return string
      */
     public static function getDomainName($url)
@@ -24,9 +25,10 @@ class WallabagExtension extends \Twig_Extension
     }
 
     /**
-     * For a given text, we calculate reading time for an article
+     * For a given text, we calculate reading time for an article.
      *
      * @param $text
+     *
      * @return float
      */
     public static function getReadingTime($text)
index 1deab03a9cf373c705b8cf6db124ff18cd1200c7..f5899e39c97a12f913f2eb23a26c8007d919ae94 100644 (file)
@@ -3,16 +3,7 @@
 namespace Wallabag\CoreBundle;
 
 use Symfony\Component\HttpKernel\Bundle\Bundle;
-use Wallabag\CoreBundle\DependencyInjection\Security\Factory\WsseFactory;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
 
 class WallabagCoreBundle extends Bundle
 {
-    public function build(ContainerBuilder $container)
-    {
-        parent::build($container);
-
-        $extension = $container->getExtension('security');
-        $extension->addSecurityListenerFactory(new WsseFactory());
-    }
 }