From 0f00688096645606c7806a619ca27e6f30ce820c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 20 Feb 2015 11:45:38 +0100 Subject: [PATCH] first draft of hypermedia implementation --- app/AppKernel.php | 3 +- composer.json | 1 + composer.lock | 168 +++++++++++++++--- .../Controller/WallabagRestController.php | 10 +- src/Wallabag/CoreBundle/Entity/Entry.php | 6 +- src/Wallabag/CoreBundle/Entity/User.php | 4 + .../CoreBundle/Repository/EntryRepository.php | 3 +- 7 files changed, 165 insertions(+), 30 deletions(-) diff --git a/app/AppKernel.php b/app/AppKernel.php index d134de3c..601b52c3 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -22,7 +22,8 @@ class AppKernel extends Kernel new Nelmio\ApiDocBundle\NelmioApiDocBundle(), new Nelmio\CorsBundle\NelmioCorsBundle(), new Liip\ThemeBundle\LiipThemeBundle(), - new Wallabag\CoreBundle\WallabagCoreBundle() + new Wallabag\CoreBundle\WallabagCoreBundle(), + new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle() ); if (in_array($this->getEnvironment(), array('dev', 'test'))) { diff --git a/composer.json b/composer.json index 0b162c02..0793bcab 100644 --- a/composer.json +++ b/composer.json @@ -74,6 +74,7 @@ "robmorgan/phinx": "~0.4", "tecnick.com/tcpdf": "~6.2", "simplepie/simplepie": "~1.3.1", + "willdurand/hateoas-bundle": "1.0.*@dev", "htmlawed/htmlawed": "dev-master", "liip/theme-bundle": "1.1.3", "wallabag/PHP-Flash-Messages": "dev-master", diff --git a/composer.lock b/composer.lock index a6102a81..f5b23280 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "fd56c671d70f498ccc1996450479fbdc", + "hash": "a078afa674d2816ebe7f7ad333d9f3b4", "packages": [ { "name": "doctrine/annotations", @@ -1386,16 +1386,16 @@ }, { "name": "michelf/php-markdown", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6" + "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/de9a19c7bf352d41cc99ed86c3c0ef17e87394b6", - "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/e1aabe18173231ebcefc90e615565742fc1c7fd9", + "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9", "shasum": "" }, "require": { @@ -1417,36 +1417,36 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "John Gruber", + "homepage": "http://daringfireball.net/" + }, { "name": "Michel Fortin", "email": "michel.fortin@michelf.ca", - "homepage": "http://michelf.ca/", + "homepage": "https://michelf.ca/", "role": "Developer" - }, - { - "name": "John Gruber", - "homepage": "http://daringfireball.net/" } ], "description": "PHP Markdown", - "homepage": "http://michelf.ca/projects/php-markdown/", + "homepage": "https://michelf.ca/projects/php-markdown/", "keywords": [ "markdown" ], - "time": "2014-05-05 02:43:50" + "time": "2015-03-01 12:03:08" }, { "name": "monolog/monolog", - "version": "1.12.0", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f" + "reference": "c41c218e239b50446fd883acb1ecfd4b770caeae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1fbe8c2641f2b163addf49cc5e18f144bec6b19f", - "reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c41c218e239b50446fd883acb1ecfd4b770caeae", + "reference": "c41c218e239b50446fd883acb1ecfd4b770caeae", "shasum": "" }, "require": { @@ -1463,6 +1463,7 @@ "phpunit/phpunit": "~4.0", "raven/raven": "~0.5", "ruflin/elastica": "0.90.*", + "swiftmailer/swiftmailer": "~5.3", "videlalvaro/php-amqplib": "~2.4" }, "suggest": { @@ -1479,7 +1480,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12.x-dev" + "dev-master": "1.13.x-dev" } }, "autoload": { @@ -1505,7 +1506,7 @@ "logging", "psr-3" ], - "time": "2014-12-29 21:29:35" + "time": "2015-03-05 01:12:12" }, { "name": "nelmio/api-doc-bundle", @@ -2645,7 +2646,7 @@ "description": "Libraries from @fivefilters.", "homepage": "https://github.com/wallabag/Fivefilters_Libraries", "support": { - "source": "https://github.com/wallabag/Fivefilters_Libraries/tree/1.0.0", + "source": "https://github.com/wallabag/Fivefilters_Libraries/tree/master", "issues": "https://github.com/wallabag/Fivefilters_Libraries/issues" }, "time": "2015-01-19 20:19:28" @@ -2690,7 +2691,7 @@ "description": "PHP Classes for dynamically generating EPub files.", "homepage": "https://github.com/wallabag/PHPePub", "support": { - "source": "https://github.com/wallabag/PHPePub/tree/2.1.0" + "source": "https://github.com/wallabag/PHPePub/tree/master" }, "time": "2015-01-19 11:44:19" }, @@ -2727,7 +2728,7 @@ "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/1.0.0" + "source": "https://github.com/wallabag/kriss_php5/tree/master" }, "time": "2015-01-18 21:21:43" }, @@ -2764,7 +2765,7 @@ "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/1.0.0" + "source": "https://github.com/wallabag/pagination/tree/master" }, "time": "2015-01-19 09:24:39" }, @@ -2810,7 +2811,7 @@ "sessions" ], "support": { - "source": "https://github.com/wallabag/PHP-Flash-Messages/tree/1.0.0" + "source": "https://github.com/wallabag/PHP-Flash-Messages/tree/master" }, "time": "2015-01-18 19:51:55" }, @@ -2864,7 +2865,7 @@ "html" ], "support": { - "source": "https://github.com/wallabag/php-readability/tree/1.0.0", + "source": "https://github.com/wallabag/php-readability/tree/master", "issues": "https://github.com/wallabag/php-readability/issues" }, "time": "2015-01-19 12:25:38" @@ -2902,10 +2903,126 @@ "description": "An experimental Mobipocket file creator in PHP.", "homepage": "https://github.com/wallabag/phpMobi", "support": { - "source": "https://github.com/wallabag/phpMobi/tree/1.0.0" + "source": "https://github.com/wallabag/phpMobi/tree/master" }, "time": "2015-01-19 12:43:17" }, + { + "name": "willdurand/hateoas", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Hateoas.git", + "reference": "89fe19ad9ce25f15323d76ac22272282ae8a9f14" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Hateoas/zipball/89fe19ad9ce25f15323d76ac22272282ae8a9f14", + "reference": "89fe19ad9ce25f15323d76ac22272282ae8a9f14", + "shasum": "" + }, + "require": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.0", + "jms/metadata": "~1.1", + "jms/serializer": "~0.13@dev", + "symfony/expression-language": "~2.4" + }, + "require-dev": { + "atoum/atoum": "*@dev", + "hautelook/frankenstein": "~0.1", + "pagerfanta/pagerfanta": "~1.0", + "phpunit/phpunit": "~3.7", + "symfony/dependency-injection": "~2.0", + "symfony/routing": "~2.0", + "symfony/yaml": "~2.0", + "twig/twig": "~1.12" + }, + "suggest": { + "symfony/routing": "To use the SymfonyRouteFactory.", + "symfony/yaml": "To use yaml based configuration.", + "twig/twig": "To use the Twig extensions." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Hateoas": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Adrien Brault", + "email": "adrien.brault@gmail.com" + }, + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "A PHP library to support implementing representations for HATEOAS REST web services", + "time": "2015-02-24 15:28:33" + }, + { + "name": "willdurand/hateoas-bundle", + "version": "dev-master", + "target-dir": "Bazinga/Bundle/HateoasBundle", + "source": { + "type": "git", + "url": "https://github.com/willdurand/BazingaHateoasBundle.git", + "reference": "3c86e8080e8a229365a0ce91818da6fe6562376b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/3c86e8080e8a229365a0ce91818da6fe6562376b", + "reference": "3c86e8080e8a229365a0ce91818da6fe6562376b", + "shasum": "" + }, + "require": { + "jms/serializer-bundle": "~0.13", + "symfony/framework-bundle": "~2.2", + "willdurand/hateoas": "~2.0" + }, + "require-dev": { + "symfony/expression-language": "~2.4", + "twig/twig": "~1.12" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Bazinga\\Bundle\\HateoasBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "description": "Integration of Hateoas into Symfony2.", + "keywords": [ + "HATEOAS", + "rest" + ], + "time": "2015-02-19 16:27:51" + }, { "name": "willdurand/jsonp-callback-validator", "version": "v1.1.0", @@ -4068,6 +4185,7 @@ "minimum-stability": "dev", "stability-flags": { "nelmio/cors-bundle": 20, + "willdurand/hateoas-bundle": 20, "htmlawed/htmlawed": 20, "wallabag/php-flash-messages": 20, "wallabag/kriss_php5": 20, diff --git a/src/Wallabag/CoreBundle/Controller/WallabagRestController.php b/src/Wallabag/CoreBundle/Controller/WallabagRestController.php index e9cd8c93..cadd7e75 100644 --- a/src/Wallabag/CoreBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/CoreBundle/Controller/WallabagRestController.php @@ -5,10 +5,12 @@ namespace Wallabag\CoreBundle\Controller; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Service\Extractor; +use Hateoas\HateoasBuilder; class WallabagRestController extends Controller { @@ -72,6 +74,9 @@ class WallabagRestController extends Controller throw $this->createNotFoundException(); } + $hateoas = HateoasBuilder::create()->build(); + $json = $hateoas->serialize($entries, 'json'); + return $entries; } @@ -87,7 +92,10 @@ class WallabagRestController extends Controller */ public function getEntryAction(Entry $entry) { - return $entry; + $hateoas = HateoasBuilder::create()->build(); + $json = $hateoas->serialize($entry, 'json'); + + return new Response($json, 200, array('application/json')); } /** diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 937213b4..4f57eb0a 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php @@ -4,17 +4,21 @@ namespace Wallabag\CoreBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; +use Hateoas\Configuration\Annotation as Hateoas; +use JMS\Serializer\Annotation\XmlRoot; /** * Entry * + * @XmlRoot("entry") * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") * @ORM\Table(name="entry") * @ORM\HasLifecycleCallbacks() - * + * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") */ class Entry { + /** @Serializer\XmlAttribute */ /** * @var integer * diff --git a/src/Wallabag/CoreBundle/Entity/User.php b/src/Wallabag/CoreBundle/Entity/User.php index ed5cfe53..5589c039 100644 --- a/src/Wallabag/CoreBundle/Entity/User.php +++ b/src/Wallabag/CoreBundle/Entity/User.php @@ -7,6 +7,8 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\AdvancedUserInterface; use Symfony\Component\Validator\Constraints as Assert; +use JMS\Serializer\Annotation\ExclusionPolicy; +use JMS\Serializer\Annotation\Expose; /** * User @@ -14,12 +16,14 @@ use Symfony\Component\Validator\Constraints as Assert; * @ORM\Table(name="user") * @ORM\Entity * @ORM\HasLifecycleCallbacks() + * @ExclusionPolicy("all") */ class User implements AdvancedUserInterface, \Serializable { /** * @var integer * + * @Expose * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index bedc90d2..32394d2a 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -102,8 +102,7 @@ class EntryRepository extends EntityRepository public function findEntries($userId, $isArchived = null, $isStarred = null, $isDeleted = null, $sort = 'created', $order = 'ASC') { $qb = $this->createQueryBuilder('e') - ->leftJoin('e.user', 'u') - ->where('u.id =:userId')->setParameter('userId', $userId); + ->where('e.user =:userId')->setParameter('userId', $userId); if (null !== $isArchived) { $qb->andWhere('e.isArchived =:isArchived')->setParameter('isArchived', (bool) $isArchived); -- 2.41.0