diff --git a/app/AppKernel.php b/app/AppKernel.php
index 3cd5f25..a46b78b 100644
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -19,12 +19,19 @@ class AppKernel extends Kernel
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\UserBundle\FOSUserBundle(),
new FOS\RestBundle\FOSRestBundle(),
+ new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
new JMS\DiExtraBundle\JMSDiExtraBundle($this),
new JMS\AopBundle\JMSAopBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
+ new Sonata\CoreBundle\SonataCoreBundle(),
+ new Sonata\BlockBundle\SonataBlockBundle(),
+ new Sonata\AdminBundle\SonataAdminBundle(),
+ new Sonata\DoctrineMongoDBAdminBundle\SonataDoctrineMongoDBAdminBundle(),
+ new \Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Wallabag\Bundle\CoreBundle\WallabagCoreBundle(),
new Wallabag\Bundle\ApiBundle\WallabagApiBundle(),
new Wallabag\Bundle\CliBundle\WallabagCliBundle(),
+ new Wallabag\Bundle\FullTextRssBundle\WallabagFullTextRssBundle(),
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
diff --git a/app/config/config.yml b/app/config/config.yml
index e8b625e..b1bd089 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -88,13 +88,13 @@ fos_rest:
rules:
# setting fallback_format to json means that instead of considering the next rule in case of a priority mismatch, json will be used
- { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
+ - { path: ^/, priorities: ['html', '*/*'], fallback_format: html, prefer_extension: true }
-# FOS User Configuration
fos_user:
db_driver: mongodb # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
- user_class: Wallabag\CoreBundle\Document\User
+ user_class: Wallabag\Bundle\CoreBundle\Document\User
jms_di_extra:
locations:
@@ -103,4 +103,15 @@ jms_di_extra:
directories: ["%kernel.root_dir%/../src"]
sensio_framework_extra:
- view: { annotations: false }
\ No newline at end of file
+ view: { annotations: false }
+
+nelmio_api_doc:
+ name: 'Wallabag API Documentation'
+
+sonata_block:
+ default_contexts: [cms]
+ blocks:
+ # Enable the SonataAdminBundle block
+ sonata.admin.block.admin_list:
+ contexts: [admin]
+ # Your other blocks
\ No newline at end of file
diff --git a/app/config/routing.yml b/app/config/routing.yml
index 365ddee..1ed3c6c 100644
--- a/app/config/routing.yml
+++ b/app/config/routing.yml
@@ -1,8 +1,3 @@
-wallabag_readability:
- resource: "@WallabagReadabilityBundle/Controller/"
- type: annotation
- prefix: /
-
wallabag_cli:
resource: "@WallabagCliBundle/Controller/"
type: annotation
@@ -18,6 +13,10 @@ wallabag_core:
type: annotation
prefix: /
+NelmioApiDocBundle:
+ resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
+ prefix: /api/doc
+
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
@@ -35,4 +34,13 @@ fos_user_resetting:
fos_user_change_password:
resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
- prefix: /profile
\ No newline at end of file
+ prefix: /profile
+
+admin:
+ resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
+ prefix: /admin
+
+_sonata_admin:
+ resource: .
+ type: sonata_admin
+ prefix: /admin
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 810cdb5..8a26669 100644
--- a/composer.json
+++ b/composer.json
@@ -35,6 +35,7 @@
"fivefilters/php-readability": "v1.0",
"friendsofsymfony/user-bundle": "2.0.x-dev",
"friendsofsymfony/rest-bundle": "1.5.*@dev",
+ "nelmio/api-doc-bundle": "@stable",
"simplepie/simplepie": "1.3.1",
"ezyang/htmlpurifier": "v4.6.0",
"exercise/htmlpurifier-bundle": "1.0.x-dev",
@@ -43,7 +44,9 @@
"doctrine/mongodb-odm": "1.0.*@dev",
"jms/di-extra-bundle": "1.4.*@dev",
"jms/serializer-bundle": "0.13.*@dev",
- "fivefilters/full-text-rss": "dev-master"
+ "fivefilters/full-text-rss": "dev-master",
+ "sonata-project/doctrine-mongodb-admin-bundle": "2.3.*@dev",
+ "knplabs/knp-menu": "2.0.*@dev"
},
"require-dev": {
"sensio/generator-bundle": "~2.3"
diff --git a/composer.lock b/composer.lock
index 0d2c5cd..3004a54 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": "8daa2d4e793b6ddb5bde55f2fda04668",
+ "hash": "6b6d6e40dcc042ac296d385285ff447f",
"packages": [
{
"name": "doctrine/annotations",
@@ -626,12 +626,12 @@
"source": {
"type": "git",
"url": "https://github.com/doctrine/mongodb-odm.git",
- "reference": "6f812184f3fe645da4902fc20148eccf0a9539bf"
+ "reference": "10e7e22a200b6d1e1565651486534b12267dd9f0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/mongodb-odm/zipball/6f812184f3fe645da4902fc20148eccf0a9539bf",
- "reference": "6f812184f3fe645da4902fc20148eccf0a9539bf",
+ "url": "https://api.github.com/repos/doctrine/mongodb-odm/zipball/10e7e22a200b6d1e1565651486534b12267dd9f0",
+ "reference": "10e7e22a200b6d1e1565651486534b12267dd9f0",
"shasum": ""
},
"require": {
@@ -691,7 +691,7 @@
"odm",
"persistence"
],
- "time": "2014-08-28 19:25:37"
+ "time": "2014-09-04 19:16:50"
},
{
"name": "doctrine/mongodb-odm-bundle",
@@ -997,12 +997,12 @@
"source": {
"type": "git",
"url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git",
- "reference": "23fa377b27552cbce0adf5aa67d73bc94ec305a8"
+ "reference": "03e3663f447b4432a088a7dab27a1ff9e3722d75"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/23fa377b27552cbce0adf5aa67d73bc94ec305a8",
- "reference": "23fa377b27552cbce0adf5aa67d73bc94ec305a8",
+ "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/03e3663f447b4432a088a7dab27a1ff9e3722d75",
+ "reference": "03e3663f447b4432a088a7dab27a1ff9e3722d75",
"shasum": ""
},
"require": {
@@ -1066,7 +1066,7 @@
"keywords": [
"rest"
],
- "time": "2014-09-01 23:14:17"
+ "time": "2014-09-08 14:32:15"
},
{
"name": "friendsofsymfony/user-bundle",
@@ -1075,12 +1075,12 @@
"source": {
"type": "git",
"url": "https://github.com/FriendsOfSymfony/FOSUserBundle.git",
- "reference": "094bea6f318fbb067db3ddf6d26a62af0bf13442"
+ "reference": "e009ce7e3d42ed0578544ad65ece869e2a7c9734"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/094bea6f318fbb067db3ddf6d26a62af0bf13442",
- "reference": "094bea6f318fbb067db3ddf6d26a62af0bf13442",
+ "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/e009ce7e3d42ed0578544ad65ece869e2a7c9734",
+ "reference": "e009ce7e3d42ed0578544ad65ece869e2a7c9734",
"shasum": ""
},
"require": {
@@ -1134,7 +1134,7 @@
"keywords": [
"User management"
],
- "time": "2014-08-23 11:32:38"
+ "time": "2014-09-08 21:45:10"
},
{
"name": "incenteev/composer-parameter-handler",
@@ -1620,6 +1620,124 @@
],
"time": "2014-08-07 13:20:59"
},
+ {
+ "name": "knplabs/knp-menu",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/KnpLabs/KnpMenu.git",
+ "reference": "08b8052ddebf96ac0a2cba4fc33dfda724248c74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/KnpLabs/KnpMenu/zipball/08b8052ddebf96ac0a2cba4fc33dfda724248c74",
+ "reference": "08b8052ddebf96ac0a2cba4fc33dfda724248c74",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "pimple/pimple": "1.0.*",
+ "silex/silex": "1.0.*",
+ "twig/twig": ">=1.2,<2.0-dev"
+ },
+ "suggest": {
+ "pimple/pimple": "for the built-in implementations of the menu provider and renderer provider",
+ "silex/silex": "for the integration with your silex application",
+ "twig/twig": "for the TwigRenderer and the integration with your templates"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Knp\\Menu\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christophe Coevoet",
+ "email": "stof@notk.org"
+ },
+ {
+ "name": "KnpLabs",
+ "homepage": "http://knplabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://github.com/KnpLabs/KnpMenu/contributors"
+ }
+ ],
+ "description": "An object oriented menu library",
+ "homepage": "http://knplabs.com",
+ "keywords": [
+ "menu",
+ "tree"
+ ],
+ "time": "2014-09-08 08:34:57"
+ },
+ {
+ "name": "knplabs/knp-menu-bundle",
+ "version": "v2.0.0",
+ "target-dir": "Knp/Bundle/MenuBundle",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/KnpLabs/KnpMenuBundle.git",
+ "reference": "bdfc95da5ff7e4e67f948aaa9ea5da835a3a9088"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/KnpLabs/KnpMenuBundle/zipball/bdfc95da5ff7e4e67f948aaa9ea5da835a3a9088",
+ "reference": "bdfc95da5ff7e4e67f948aaa9ea5da835a3a9088",
+ "shasum": ""
+ },
+ "require": {
+ "knplabs/knp-menu": "~2.0",
+ "symfony/framework-bundle": "~2.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Knp\\Bundle\\MenuBundle": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christophe Coevoet",
+ "email": "stof@notk.org"
+ },
+ {
+ "name": "KnpLabs",
+ "homepage": "http://knplabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://github.com/KnpLabs/KnpMenuBundle/contributors"
+ }
+ ],
+ "description": "This bundle provides an integration of the KnpMenu library",
+ "keywords": [
+ "menu"
+ ],
+ "time": "2014-08-01 09:57:23"
+ },
{
"name": "kriswallsmith/assetic",
"version": "v1.1.2",
@@ -1697,12 +1815,12 @@
"source": {
"type": "git",
"url": "https://github.com/mibe/FeedWriter.git",
- "reference": "ccf2279b54b7833969b98c192689f92e8fa42c7c"
+ "reference": "9a65ed2117153b5b12f29f0cac92e9ecae3cb9ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mibe/FeedWriter/zipball/ccf2279b54b7833969b98c192689f92e8fa42c7c",
- "reference": "ccf2279b54b7833969b98c192689f92e8fa42c7c",
+ "url": "https://api.github.com/repos/mibe/FeedWriter/zipball/9a65ed2117153b5b12f29f0cac92e9ecae3cb9ea",
+ "reference": "9a65ed2117153b5b12f29f0cac92e9ecae3cb9ea",
"shasum": ""
},
"type": "library",
@@ -1720,12 +1838,6 @@
"GPL-3.0"
],
"authors": [
- {
- "name": "Michael Robinson",
- "email": "mike@pagesofinterest.net",
- "homepage": "http://pagesofinterest.net/",
- "role": "Developer"
- },
{
"name": "Anis uddin Ahmad"
},
@@ -1741,6 +1853,22 @@
},
{
"name": "Brennen Bearnes"
+ },
+ {
+ "name": "Michael Robinson",
+ "email": "mike@pagesofinterest.net"
+ },
+ {
+ "name": "Baptiste Fontaine"
+ },
+ {
+ "name": "Kristián Valentín"
+ },
+ {
+ "name": "Brandtley McMinn"
+ },
+ {
+ "name": "Julian Bogdani"
}
],
"description": "Generate feeds in either RSS 1.0, RSS 2.0 or ATOM formats",
@@ -1748,7 +1876,58 @@
"keywords": [
"rss"
],
- "time": "2014-06-23 06:38:26"
+ "time": "2014-09-10 22:29:51"
+ },
+ {
+ "name": "michelf/php-markdown",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/michelf/php-markdown.git",
+ "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/michelf/php-markdown/zipball/de9a19c7bf352d41cc99ed86c3c0ef17e87394b6",
+ "reference": "de9a19c7bf352d41cc99ed86c3c0ef17e87394b6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-lib": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Michelf": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Michel Fortin",
+ "email": "michel.fortin@michelf.ca",
+ "homepage": "http://michelf.ca/",
+ "role": "Developer"
+ },
+ {
+ "name": "John Gruber",
+ "homepage": "http://daringfireball.net/"
+ }
+ ],
+ "description": "PHP Markdown",
+ "homepage": "http://michelf.ca/projects/php-markdown/",
+ "keywords": [
+ "markdown"
+ ],
+ "time": "2014-05-05 02:43:50"
},
{
"name": "monolog/monolog",
@@ -1818,6 +1997,81 @@
],
"time": "2014-06-04 16:30:04"
},
+ {
+ "name": "nelmio/api-doc-bundle",
+ "version": "2.7.0",
+ "target-dir": "Nelmio/ApiDocBundle",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nelmio/NelmioApiDocBundle.git",
+ "reference": "3fdb2d4a819d1f71bff0c45880af705a8b124955"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/3fdb2d4a819d1f71bff0c45880af705a8b124955",
+ "reference": "3fdb2d4a819d1f71bff0c45880af705a8b124955",
+ "shasum": ""
+ },
+ "require": {
+ "michelf/php-markdown": "~1.4",
+ "symfony/console": "~2.1",
+ "symfony/framework-bundle": "~2.1",
+ "symfony/twig-bundle": "~2.1"
+ },
+ "conflict": {
+ "jms/serializer": "<0.12",
+ "jms/serializer-bundle": "<0.11"
+ },
+ "require-dev": {
+ "friendsofsymfony/rest-bundle": "~1.0",
+ "jms/serializer-bundle": ">=0.11",
+ "sensio/framework-extra-bundle": "~2.1",
+ "symfony/browser-kit": "~2.1",
+ "symfony/css-selector": "~2.1",
+ "symfony/form": "~2.1",
+ "symfony/validator": "~2.1",
+ "symfony/yaml": "~2.1"
+ },
+ "suggest": {
+ "friendsofsymfony/rest-bundle": "For making use of REST information in the doc.",
+ "jms/serializer": "For making use of serializer information in the doc.",
+ "symfony/form": "For using form definitions as input.",
+ "symfony/validator": "For making use of validator information in the doc."
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Nelmio\\ApiDocBundle": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nelmio",
+ "homepage": "http://nelm.io"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors"
+ }
+ ],
+ "description": "Generates documentation for your REST API from annotations",
+ "keywords": [
+ "api",
+ "doc",
+ "documentation",
+ "rest"
+ ],
+ "time": "2014-07-30 09:11:08"
+ },
{
"name": "phpcollection/phpcollection",
"version": "0.4.0",
@@ -2063,6 +2317,56 @@
],
"time": "2014-09-02 07:11:30"
},
+ {
+ "name": "sensio/generator-bundle",
+ "version": "v2.3.5",
+ "target-dir": "Sensio/Bundle/GeneratorBundle",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git",
+ "reference": "8b7a33aa3d22388443b6de0b0cf184122e9f60d2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/8b7a33aa3d22388443b6de0b0cf184122e9f60d2",
+ "reference": "8b7a33aa3d22388443b6de0b0cf184122e9f60d2",
+ "shasum": ""
+ },
+ "require": {
+ "symfony/console": "~2.0",
+ "symfony/framework-bundle": "~2.2"
+ },
+ "require-dev": {
+ "doctrine/orm": "~2.2,>=2.2.3",
+ "symfony/doctrine-bridge": "~2.2",
+ "twig/twig": "~1.11"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Sensio\\Bundle\\GeneratorBundle": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "This bundle generates code for you",
+ "time": "2014-04-28 14:01:06"
+ },
{
"name": "sensiolabs/security-checker",
"version": "v2.0.0",
@@ -2162,6 +2466,401 @@
],
"time": "2012-10-30 17:54:03"
},
+ {
+ "name": "sonata-project/admin-bundle",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/SonataAdminBundle.git",
+ "reference": "68a836e5dbcb89a9bec36586186d4fdf3fedf6f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/SonataAdminBundle/zipball/68a836e5dbcb89a9bec36586186d4fdf3fedf6f5",
+ "reference": "68a836e5dbcb89a9bec36586186d4fdf3fedf6f5",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/common": "~2.2",
+ "knplabs/knp-menu": ">=1.1.0,<3.0.0",
+ "knplabs/knp-menu-bundle": ">=1.1.0,<3.0.0",
+ "sensio/generator-bundle": "~2.3",
+ "sonata-project/block-bundle": "~2.2,>=2.2.7",
+ "sonata-project/core-bundle": "~2.2",
+ "sonata-project/exporter": "~1.0",
+ "symfony/class-loader": "~2.3",
+ "symfony/config": "~2.3",
+ "symfony/console": "~2.3",
+ "symfony/form": "~2.3",
+ "symfony/http-foundation": "~2.3",
+ "symfony/routing": "~2.3",
+ "symfony/security-bundle": "~2.3",
+ "symfony/twig-bridge": "~2.3",
+ "symfony/validator": "~2.3",
+ "twig/extensions": "~1.0",
+ "twig/twig": "~1.15"
+ },
+ "require-dev": {
+ "jms/translation-bundle": "~1.1",
+ "sonata-project/intl-bundle": "~2.1",
+ "symfony/yaml": "~2.3"
+ },
+ "suggest": {
+ "jms/translation-bundle": "Extract message keys from Admins",
+ "sonata-project/intl-bundle": "Add localized date and number into the list"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sonata\\AdminBundle\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Thomas Rabaix",
+ "email": "thomas.rabaix@sonata-project.org",
+ "homepage": "http://sonata-project.org"
+ },
+ {
+ "name": "Sonata Community",
+ "homepage": "https://github.com/sonata-project/SonataAdminBundle/contributors"
+ }
+ ],
+ "description": "Symfony SonataAdminBundle",
+ "homepage": "http://sonata-project.org/bundles/admin",
+ "keywords": [
+ "Admin Generator",
+ "admin",
+ "bootstrap",
+ "sonata"
+ ],
+ "time": "2014-09-09 13:52:07"
+ },
+ {
+ "name": "sonata-project/block-bundle",
+ "version": "2.2.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/SonataBlockBundle.git",
+ "reference": "ba4888c69745416da8ab0f7e7a64e04401cd2fbe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/SonataBlockBundle/zipball/ba4888c69745416da8ab0f7e7a64e04401cd2fbe",
+ "reference": "ba4888c69745416da8ab0f7e7a64e04401cd2fbe",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/common": "~2.3",
+ "sonata-project/cache": "~1.0",
+ "sonata-project/core-bundle": "~2.2",
+ "symfony/form": "~2.2",
+ "symfony/http-kernel": "~2.2"
+ },
+ "require-dev": {
+ "knplabs/knp-menu-bundle": "~1.1",
+ "sonata-project/admin-bundle": "~2.2"
+ },
+ "suggest": {
+ "knplabs/knp-menu-bundle": "~1.1",
+ "sonata-project/admin-bundle": "~2.2",
+ "sonata-project/cache-bundle": "~2.1"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sonata\\BlockBundle\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Thomas Rabaix",
+ "email": "thomas.rabaix@sonata-project.org",
+ "homepage": "http://sonata-project.org"
+ },
+ {
+ "name": "Sonata Community",
+ "homepage": "https://github.com/sonata-project/SonataBlockBundle/contributors"
+ }
+ ],
+ "description": "Symfony SonataBlockBundle",
+ "homepage": "http://sonata-project.org/bundles/block",
+ "keywords": [
+ "block",
+ "sonata"
+ ],
+ "time": "2014-06-13 10:26:57"
+ },
+ {
+ "name": "sonata-project/cache",
+ "version": "1.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/cache.git",
+ "reference": "548b14c49474ed006543336d8f0be093089a3797"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/cache/zipball/548b14c49474ed006543336d8f0be093089a3797",
+ "reference": "548b14c49474ed006543336d8f0be093089a3797",
+ "shasum": ""
+ },
+ "require-dev": {
+ "doctrine/orm": "~2.2",
+ "doctrine/phpcr-odm": "~1.0",
+ "jackalope/jackalope-doctrine-dbal": "~1.0",
+ "predis/predis": "~0.8,<1.0",
+ "psr/log": "~1.0"
+ },
+ "suggest": {
+ "doctrine/orm": "ORM support",
+ "doctrine/phpcr-odm": "PHPCR ODM support",
+ "ext-apc": "Caching with ext/apc",
+ "ext-memcached": "Caching with ext/memcached",
+ "predis/predis": "Install redis php"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sonata\\Cache\\Tests\\": "test/",
+ "Sonata\\Cache\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Thomas Rabaix",
+ "email": "thomas.rabaix@gmail.com",
+ "homepage": "http://sonata-project.org/"
+ }
+ ],
+ "description": "Cache library",
+ "homepage": "https://github.com/sonata-project/cache",
+ "keywords": [
+ "cache",
+ "memcached",
+ "mongodb",
+ "redis"
+ ],
+ "time": "2014-07-02 20:57:41"
+ },
+ {
+ "name": "sonata-project/core-bundle",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/SonataCoreBundle.git",
+ "reference": "60bfa806faa332642a63215e3b6e3607c1e1b13e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/SonataCoreBundle/zipball/60bfa806faa332642a63215e3b6e3607c1e1b13e",
+ "reference": "60bfa806faa332642a63215e3b6e3607c1e1b13e",
+ "shasum": ""
+ },
+ "require": {
+ "symfony/config": "~2.3",
+ "symfony/form": "~2.3",
+ "symfony/http-foundation": "~2.3",
+ "symfony/translation": "~2.3",
+ "twig/twig": "~1.16"
+ },
+ "require-dev": {
+ "doctrine/orm": "~2.4",
+ "doctrine/phpcr-odm": "~1.0",
+ "friendsofsymfony/rest-bundle": "~1.1",
+ "jackalope/jackalope-doctrine-dbal": "~1.0",
+ "jms/serializer-bundle": "~0.11",
+ "sensio/framework-extra-bundle": "~2.3",
+ "sonata-project/exporter": "~1.3"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sonata\\CoreBundle\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Sonata Community",
+ "homepage": "https://github.com/sonata-project/SonataCoreBundle/contributors"
+ },
+ {
+ "name": "Thomas Rabaix",
+ "email": "thomas.rabaix@sonata-project.org"
+ }
+ ],
+ "description": "Symfony SonataCoreBundle",
+ "homepage": "http://sonata-project.org/bundles/core",
+ "keywords": [
+ "sonata"
+ ],
+ "time": "2014-09-09 23:58:27"
+ },
+ {
+ "name": "sonata-project/doctrine-mongodb-admin-bundle",
+ "version": "dev-master",
+ "target-dir": "Sonata/DoctrineMongoDBAdminBundle",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/SonataDoctrineMongoDBAdminBundle.git",
+ "reference": "a34ee530191b3ae4a00df251823c09e0dbca2031"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/SonataDoctrineMongoDBAdminBundle/zipball/a34ee530191b3ae4a00df251823c09e0dbca2031",
+ "reference": "a34ee530191b3ae4a00df251823c09e0dbca2031",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/mongodb-odm": "1.0.*@dev",
+ "doctrine/mongodb-odm-bundle": "3.0.*@dev",
+ "sonata-project/admin-bundle": "~2.3@dev"
+ },
+ "provide": {
+ "sonata-project/admin-bundle-persistency-layer": "1.0.0"
+ },
+ "require-dev": {
+ "jmikola/geojson": "~1.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-2.0": "2.0.x-dev",
+ "dev-2.1": "2.1.x-dev",
+ "dev-2.2": "2.2.x-dev",
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Sonata\\DoctrineMongoDBAdminBundle": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kévin Dunglas",
+ "email": "dunglas@gmail.com",
+ "homepage": "http://dunglas.fr"
+ },
+ {
+ "name": "Sonata Community",
+ "homepage": "https://github.com/sonata-project/SonataDoctrineMongoDBAdminBundle/contributors"
+ }
+ ],
+ "description": "Symfony Sonata / Integrate Doctrine MongoDB ODM into the SonataAdminBundle",
+ "homepage": "http://sonata-project.org/bundles/admin",
+ "keywords": [
+ "Admin Generator",
+ "admin",
+ "bootstrap",
+ "generator",
+ "mongo",
+ "mongodb",
+ "sonata"
+ ],
+ "time": "2014-08-05 11:33:30"
+ },
+ {
+ "name": "sonata-project/exporter",
+ "version": "1.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sonata-project/exporter.git",
+ "reference": "8a88328ccdd1ca1471dd14483a4396350fbda91c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sonata-project/exporter/zipball/8a88328ccdd1ca1471dd14483a4396350fbda91c",
+ "reference": "8a88328ccdd1ca1471dd14483a4396350fbda91c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "propel/propel1": "~1.6",
+ "symfony/property-access": "~2.2",
+ "symfony/routing": "*"
+ },
+ "suggest": {
+ "ext-curl": "*",
+ "propel/propel1": "~1.6",
+ "symfony/property-access": "~2.2",
+ "symfony/routing": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Exporter": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Thomas Rabaix",
+ "email": "thomas.rabaix@gmail.com",
+ "homepage": "http://sonata-project.org/"
+ }
+ ],
+ "description": "Lightweight Exporter library",
+ "homepage": "https://github.com/sonata-project/Exporter",
+ "keywords": [
+ "client",
+ "csv",
+ "data",
+ "export",
+ "xls"
+ ],
+ "time": "2014-09-11 09:05:40"
+ },
{
"name": "swiftmailer/swiftmailer",
"version": "v5.2.1",
@@ -2753,56 +3452,7 @@
}
],
"packages-dev": [
- {
- "name": "sensio/generator-bundle",
- "version": "v2.3.5",
- "target-dir": "Sensio/Bundle/GeneratorBundle",
- "source": {
- "type": "git",
- "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git",
- "reference": "8b7a33aa3d22388443b6de0b0cf184122e9f60d2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/8b7a33aa3d22388443b6de0b0cf184122e9f60d2",
- "reference": "8b7a33aa3d22388443b6de0b0cf184122e9f60d2",
- "shasum": ""
- },
- "require": {
- "symfony/console": "~2.0",
- "symfony/framework-bundle": "~2.2"
- },
- "require-dev": {
- "doctrine/orm": "~2.2,>=2.2.3",
- "symfony/doctrine-bridge": "~2.2",
- "twig/twig": "~1.11"
- },
- "type": "symfony-bundle",
- "extra": {
- "branch-alias": {
- "dev-master": "2.3.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Sensio\\Bundle\\GeneratorBundle": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- }
- ],
- "description": "This bundle generates code for you",
- "time": "2014-04-28 14:01:06"
- }
+
],
"aliases": [
@@ -2811,13 +3461,16 @@
"stability-flags": {
"friendsofsymfony/user-bundle": 20,
"friendsofsymfony/rest-bundle": 20,
+ "nelmio/api-doc-bundle": 0,
"exercise/htmlpurifier-bundle": 20,
"mibe/feedwriter": 20,
"doctrine/mongodb-odm-bundle": 20,
"doctrine/mongodb-odm": 20,
"jms/di-extra-bundle": 20,
"jms/serializer-bundle": 20,
- "fivefilters/full-text-rss": 20
+ "fivefilters/full-text-rss": 20,
+ "sonata-project/doctrine-mongodb-admin-bundle": 20,
+ "knplabs/knp-menu": 20
},
"prefer-stable": false,
"platform": {
diff --git a/src/Wallabag/Bundle/ApiBundle/Controller/EntriesController.php b/src/Wallabag/Bundle/ApiBundle/Controller/EntriesController.php
index 3c8c614..b1746d2 100644
--- a/src/Wallabag/Bundle/ApiBundle/Controller/EntriesController.php
+++ b/src/Wallabag/Bundle/ApiBundle/Controller/EntriesController.php
@@ -6,6 +6,7 @@ use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\View;
use JMS\DiExtraBundle\Annotation\Inject;
+use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\Request;
@@ -17,7 +18,7 @@ class EntriesController
{
/**
* @var EntryService
- * @Inject("wallabag_core.entry")
+ * @Inject("wallabag_core.services.entry")
*/
private $entryService;
@@ -28,15 +29,27 @@ class EntriesController
private $router;
/**
+ * Save a new entry for the given user
+ *
* @Post("/u/{user}/entries")
* @ParamConverter("user",options={"mapping": {"user": "username"}})
* @View(statusCode=201)
+ * @ApiDoc(
+ * requirements={
+ * {"name"="user", "dataType"="string", "requirement"="\w+", "description"="The username"}
+ * },
+ * parameters={
+ * {"name"="url", "dataType"="string", "required"=true, "description"="The URL to save"},
+ * {"name"="tags", "dataType"="string[]", "required"=false, "description"="The tags for this entry"}
+ * })
*/
public function postAction(Request $request, User $user)
{
$url = $request->request->get("url");
- $tags = $request->request->get("tags");
+ $tags = $request->request->get("tags", array());
+
$entry = $this->entryService->save($user, $url, $tags);
+
$view = \FOS\RestBundle\View\View::create();
$view->setData($entry);
$view->setStatusCode(Response::HTTP_CREATED);
@@ -48,10 +61,19 @@ class EntriesController
}
/**
+ * List unread entries for the given user
+ *
* @Get("/u/{user}/entries", methods={"GET"})
* @Get("/u/{user}", methods={"GET"})
* @ParamConverter("user", options={"mapping": {"user": "username"}})
* @View(statusCode=200, serializerGroups={"entries"})
+ * @ApiDoc(
+ * requirements={
+ * {"name"="user", "dataType"="string", "requirement"="\w+", "description"="The username"}
+ * }
+ * )
+ *
+ * @param User $user the username
*/
public function getAction(User $user) {
return array_values($this->entryService->listForUser($user));
diff --git a/src/Wallabag/Bundle/ApiBundle/Controller/EntryController.php b/src/Wallabag/Bundle/ApiBundle/Controller/EntryController.php
index 37c4a20..83d9a07 100644
--- a/src/Wallabag/Bundle/ApiBundle/Controller/EntryController.php
+++ b/src/Wallabag/Bundle/ApiBundle/Controller/EntryController.php
@@ -5,9 +5,14 @@ namespace Wallabag\Bundle\ApiBundle\Controller;
use FOS\RestBundle\Controller\Annotations\Get;
+use FOS\RestBundle\Controller\Annotations\Patch;
use FOS\RestBundle\Controller\Annotations\View;
use JMS\DiExtraBundle\Annotation\Inject;
+use Nelmio\ApiDocBundle\Annotation\ApiDoc;
+use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Wallabag\Bundle\CoreBundle\Document\Entry;
use Wallabag\Bundle\CoreBundle\Document\User;
use Wallabag\Bundle\CoreBundle\Service\EntryService;
@@ -15,17 +20,67 @@ use Wallabag\Bundle\CoreBundle\Service\EntryService;
class EntryController {
/**
* @var EntryService
- * @Inject("wallabag_core.entry")
+ * @Inject("wallabag_core.services.entry")
*/
private $entryService;
/**
- * @Get("/u/{user}/entry/{entry}", methods={"GET"})
+ * @var LoggerInterface
+ * @Inject("logger")
+ */
+ private $logger;
+
+ /**
+ * @var Router
+ * @Inject("router")
+ */
+ private $router;
+
+ /**
+ * Fetch an entry, regardless the status flags
+ *
+ * @Get("/u/{user}/entry/{entry}")
* @ParamConverter("user", options={"mapping": {"user": "username"}})
* @ParamConverter("entry", options={"id"="entry"})
* @View(statusCode=200, serializerGroups={"entries"})
+ * @ApiDoc(
+ * requirements={
+ * {"name"="user", "dataType"="string", "requirement"="\w+", "description"="The username"},
+ * {"name"="entry", "dataType"="string", "requirement"="\w+", "description"="The entry ID"}
+ * }
+ * )
*/
public function getAction(User $user, Entry $entry) {
+ $this->logger->info("User {username} wants to show entry {url}",
+ array("username" => $user->getUsername(), "url" => $entry->getUrl()));
return $entry;
}
+
+ /**
+ * Change several properties of an entry. I.E tags, archived, starred and deleted status
+ *
+ * @Patch("/u/{user}/entry/{entry}")
+ * @ParamConverter("user", options={"mapping": {"user": "username"}})
+ * @ParamConverter("entry", options={"id"="entry"})
+ * @View(statusCode=204)
+ * @ApiDoc(
+ * requirements={
+ * {"name"="user", "dataType"="string", "requirement"="\w+", "description"="The username"}
+ * }
+ * )
+ */
+ public function patchAction(User $user, Entry $entry, Request $request) {
+ $request->request->get("tags", array());
+ $request->request->get("archived");
+ $request->request->get("deleted");
+ $request->request->get("starred");
+
+ $view = \FOS\RestBundle\View\View::create();
+ $view->setStatusCode(Response::HTTP_NO_CONTENT);
+ $view->setLocation($this->router->generate("wallabag_api_entry_get", array(
+ "user" => $user->getUsername(),
+ "entry" => $entry->getId()
+ )));
+ return $view;
+ }
}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/CoreBundle/Admin/EntryAdmin.php b/src/Wallabag/Bundle/CoreBundle/Admin/EntryAdmin.php
new file mode 100644
index 0000000..99b0a50
--- /dev/null
+++ b/src/Wallabag/Bundle/CoreBundle/Admin/EntryAdmin.php
@@ -0,0 +1,58 @@
+add('id')
+ ->add('url')
+ ->add('title')
+ ;
+ }
+
+ /**
+ * @param ListMapper $listMapper
+ */
+ protected function configureListFields(ListMapper $listMapper)
+ {
+ $listMapper
+ ->add('id')
+ ->add('url')
+ ->add('title')
+ ->add('user')
+ ->add('_action', 'actions', array(
+ 'actions' => array(
+ 'show' => array(),
+ 'edit' => array(),
+ 'delete' => array(),
+ )
+ ))
+ ;
+ }
+
+ /**
+ * @param ShowMapper $showMapper
+ */
+ protected function configureShowFields(ShowMapper $showMapper)
+ {
+ $showMapper
+ ->add('id')
+ ->add('url')
+ ->add('title')
+ ->add('content')
+ ;
+ }
+}
diff --git a/src/Wallabag/Bundle/CoreBundle/Admin/UserAdmin.php b/src/Wallabag/Bundle/CoreBundle/Admin/UserAdmin.php
new file mode 100644
index 0000000..77cd321
--- /dev/null
+++ b/src/Wallabag/Bundle/CoreBundle/Admin/UserAdmin.php
@@ -0,0 +1,26 @@
+add("username")
+ ->add("email");
+ }
+
+ protected function configureListFields(ListMapper $list)
+ {
+ $list->addIdentifier("id")
+ ->add("username")
+ ->add("email");
+ }
+
+}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/CoreBundle/Configurator/HTMLPurifierConfigurator.php b/src/Wallabag/Bundle/CoreBundle/Configurator/HTMLPurifierConfigurator.php
new file mode 100644
index 0000000..7f88d4c
--- /dev/null
+++ b/src/Wallabag/Bundle/CoreBundle/Configurator/HTMLPurifierConfigurator.php
@@ -0,0 +1,39 @@
+cacheDir = $cacheDir;
+ }
+
+
+ public function configure(\HTMLPurifier_Config $config) {
+ $config->set('Cache.SerializerPath', $this->cacheDir);
+ $config->set('HTML.SafeIframe', true);
+
+ //allow YouTube, Vimeo and dailymotion videos
+ $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/|www\.dailymotion\.com/embed/video/)%');
+ }
+}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/CoreBundle/Document/Entry.php b/src/Wallabag/Bundle/CoreBundle/Document/Entry.php
index b130fd4..a654fbd 100644
--- a/src/Wallabag/Bundle/CoreBundle/Document/Entry.php
+++ b/src/Wallabag/Bundle/CoreBundle/Document/Entry.php
@@ -12,7 +12,10 @@ use JMS\Serializer\Annotation\Groups;
/**
* Entry
*
- * @MongoDB\Document(repositoryClass="Wallabag\Bundle\CoreBundle\Repository\EntryRepository")
+ * @MongoDB\Document(repositoryClass="Wallabag\Bundle\CoreBundle\Repository\EntryRepository",
+ * indexes={
+ * @MongoDB\Index(keys={"user" = "asc", "url" = "asc"}, options={"unique"="true"})
+ * })
*/
class Entry
{
@@ -66,7 +69,7 @@ class Entry
private $createdAt;
/**
- * @var Tag[]
+ * @var ArrayCollection
* @MongoDB\EmbedMany(targetDocument="Wallabag\Bundle\CoreBundle\Document\Tag")
* @Expose
* @Groups({"entries"})
@@ -77,19 +80,19 @@ class Entry
* @var boolean
* @MongoDB\Boolean
*/
- private $archived;
+ private $archived = false;
/**
* @var boolean
* @MongoDB\Boolean
*/
- private $deleted;
+ private $deleted = false;
/**
* @var boolean
* @MongoDB\Boolean
*/
- private $starred;
+ private $starred = false;
public function __construct()
{
@@ -216,6 +219,10 @@ class Entry
$this->tags->removeElement($tag);
}
+ public function flushTags() {
+ $this->tags->clear();
+ }
+
/**
* Get tags
*
diff --git a/src/Wallabag/Bundle/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/Bundle/CoreBundle/Repository/EntryRepository.php
index 8d025b0..e7d9b62 100644
--- a/src/Wallabag/Bundle/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/Bundle/CoreBundle/Repository/EntryRepository.php
@@ -3,6 +3,7 @@
namespace Wallabag\Bundle\CoreBundle\Repository;
use Doctrine\ODM\MongoDB\DocumentRepository;
+use JMS\DiExtraBundle\Annotation\Service;
use Wallabag\Bundle\CoreBundle\Document\Entry;
/**
@@ -14,7 +15,7 @@ class EntryRepository extends DocumentRepository
* Find all unread bookmarks for a given user
*
* @param string $userId the user ID
- * @return Bookmark[]
+ * @return Entry[]
*/
public function findUnreadByUser($userId) {
return $this->createQueryBuilder('Wallabag\Bundle\CoreBundle\Document\Entry')
diff --git a/src/Wallabag/Bundle/CoreBundle/Resources/config/services.xml b/src/Wallabag/Bundle/CoreBundle/Resources/config/services.xml
index 1413551..15e4948 100644
--- a/src/Wallabag/Bundle/CoreBundle/Resources/config/services.xml
+++ b/src/Wallabag/Bundle/CoreBundle/Resources/config/services.xml
@@ -9,5 +9,40 @@
+
+
+
+ WallabagCoreBundle:Entry
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wallabag\Bundle\CoreBundle\Document\User
+
+
+ WallabagCoreBundle
+
+
+
+
+
+ Wallabag\Bundle\CoreBundle\Document\Entry
+
+
+ WallabagCoreBundle
+
+
diff --git a/src/Wallabag/Bundle/CoreBundle/Service/EntryService.php b/src/Wallabag/Bundle/CoreBundle/Service/EntryService.php
index f383eee..ee99cb9 100644
--- a/src/Wallabag/Bundle/CoreBundle/Service/EntryService.php
+++ b/src/Wallabag/Bundle/CoreBundle/Service/EntryService.php
@@ -7,15 +7,19 @@ use Doctrine\ODM\MongoDB\DocumentManager;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Inject;
use JMS\DiExtraBundle\Annotation\Service;
+use Psr\Log\LoggerInterface;
use Wallabag\Bundle\CoreBundle\Document\Bookmark;
use Wallabag\Bundle\CoreBundle\Document\Entry;
use Wallabag\Bundle\CoreBundle\Document\Tag;
use Wallabag\Bundle\CoreBundle\Document\User;
+use Wallabag\Bundle\CoreBundle\Repository\EntryRepository;
+use Wallabag\Bundle\CoreBundle\Url\Url;
+use Wallabag\Bundle\CoreBundle\Url\UrlFetcher;
/**
* Class BookmarkService
* @package Wallabag\Bundle\CoreBundle\Service
- * @Service(id="wallabag_core.entry")
+ * @Service(id="wallabag_core.services.entry")
*/
class EntryService {
/**
@@ -23,32 +27,68 @@ class EntryService {
*/
private $dm;
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
+ /**
+ * @var UrlFetcher
+ */
+ private $urlFetcher;
+
+ /**
+ * @var \HTMLPurifier
+ */
+ private $htmlPurifier;
+
+ /**
+ * @var EntryRepository
+ */
+ private $entryRepository;
+
/**
* @InjectParams({
- * "dm" = @Inject("doctrine_mongodb.odm.document_manager")
+ * "dm" = @Inject("doctrine_mongodb.odm.document_manager"),
+ * "logger" = @Inject("logger"),
+ * "urlFetcher" = @Inject("full_text_rss_url_fetcher"),
+ * "htmlPurifier" = @Inject("wallabag_core.html_purifier"),
+ * "entryRepository" = @Inject("wallabag_core.repository.entry")
* })
* @param DocumentManager $dm
+ * @param UrlFetcher $urlFetcher
*/
- public function __construct(DocumentManager $dm) {
+ public function __construct(DocumentManager $dm, LoggerInterface $logger, UrlFetcher $urlFetcher,
+ \HTMLPurifier $htmlPurifier, EntryRepository $entryRepository) {
$this->dm = $dm;
+ $this->logger = $logger;
+ $this->urlFetcher = $urlFetcher;
+ $this->htmlPurifier = $htmlPurifier;
+ $this->entryRepository = $entryRepository;
}
/**
+ * Fetch and save an entry and assign it to a user
+ *
* @param User $user
* @param string $url
* @param string[] $tags
* @return Entry the created entry
*/
public function save(User $user, $url, $tags = array()) {
- $entry = new Entry();
- $entry->setUser($user);
- $entry->setUrl($url);
- $entry->setCreatedAt(new \DateTime());
- $entry->setContent("Fixture content");
- $entry->setTitle("Fixture title");
+ $content = $this->urlFetcher->fetch($url);
+ $this->purifyUrl($content);
+
+ $entry = $this->entryRepository->findOneByUserAndUrl($user->getId(), $content->getUrl());
+ if($entry === null) {
+ $entry = new Entry();
+ $entry->setUser($user);
+ $entry->setUrl($content->getUrl());
+ $entry->setCreatedAt(new \DateTime());
+ }
+ $entry->setContent($content->getContent());
+ $entry->setTitle($content->getTitle());
$entry->setArchived(false);
- $entry->setDeleted(false);
- $entry->setStarred(false);
foreach($tags as $tag) {
$entry->addTag(new Tag($tag));
@@ -60,8 +100,54 @@ class EntryService {
return $entry;
}
+ /**
+ * List all non-archived entries for a given user
+ *
+ * @param User $user the user
+ * @return \Wallabag\Bundle\CoreBundle\Document\Entry[]
+ */
public function listForUser(User $user) {
- $bookmarkRepository = $this->dm->getRepository('\Wallabag\Bundle\CoreBundle\Document\Entry');
- return $bookmarkRepository->findUnreadByUser($user->getId());
+ return $this->entryRepository->findUnreadByUser($user->getId());
+ }
+
+ /**
+ * Purify HTML contents of an URL : title and content fields
+ *
+ * @param Url $url the URL Object to purify
+ */
+ private function purifyUrl(Url $url) {
+ $url->setTitle($this->htmlPurifier->purify($url->getTitle()));
+ $url->setContent($this->htmlPurifier->purify($url->getContent()));
+ }
+
+ /**
+ * Change updatable fields of an entry an persists it
+ *
+ * @param Entry $entry the entry
+ * @param string[] $tags the new tags
+ * @param boolean $archived the new archived status
+ * @param boolean $starred the new starred status
+ * @param boolean $deleted the new deleted status
+ */
+ public function updateEntry(Entry $entry, $tags, $archived, $starred, $deleted) {
+ $managed = $this->dm->merge($entry);
+
+ if(is_array($tags)) {
+ $managed->flushTags();
+ foreach ($tags as $tag) {
+ $managed->addTag(new Tag($tag));
+ }
+ }
+ if($archived != null) {
+ $entry->setArchived($archived);
+ }
+ if($starred != null) {
+ $entry->setStarred($starred);
+ }
+ if($deleted != null) {
+ $entry->setDeleted($deleted);
+ }
+
+ $this->dm->flush();
}
}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/CoreBundle/Url/Url.php b/src/Wallabag/Bundle/CoreBundle/Url/Url.php
new file mode 100644
index 0000000..587f9a1
--- /dev/null
+++ b/src/Wallabag/Bundle/CoreBundle/Url/Url.php
@@ -0,0 +1,67 @@
+content = $content;
+ $this->title = $title;
+ $this->url = $url;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ /**
+ * @param mixed $content
+ */
+ public function setContent($content)
+ {
+ $this->content = $content;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ /**
+ * @param mixed $title
+ */
+ public function setTitle($title)
+ {
+ $this->title = $title;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getUrl()
+ {
+ return $this->url;
+ }
+
+ /**
+ * @param mixed $url
+ */
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/CoreBundle/Url/UrlFetcher.php b/src/Wallabag/Bundle/CoreBundle/Url/UrlFetcher.php
index 6d5beee..48a8b88 100644
--- a/src/Wallabag/Bundle/CoreBundle/Url/UrlFetcher.php
+++ b/src/Wallabag/Bundle/CoreBundle/Url/UrlFetcher.php
@@ -5,5 +5,9 @@ namespace Wallabag\Bundle\CoreBundle\Url;
interface UrlFetcher {
- public function fetch($url, $max, $links);
+ /**
+ * @param string $url the url to fetch
+ * @return Url extracted content
+ */
+ public function fetch($url);
}
\ No newline at end of file
diff --git a/src/Wallabag/Bundle/FullTextRssBundle/UrlFetcher/FullTextRssUrlFetcher.php b/src/Wallabag/Bundle/FullTextRssBundle/UrlFetcher/FullTextRssUrlFetcher.php
new file mode 100644
index 0000000..7f50e87
--- /dev/null
+++ b/src/Wallabag/Bundle/FullTextRssBundle/UrlFetcher/FullTextRssUrlFetcher.php
@@ -0,0 +1,119 @@
+logger = $logger;
+ $this->rootDir = $rootDir;
+ }
+
+ public function fetch($url)
+ {
+ // Saving and clearing context
+ $REAL = array();
+ foreach( $GLOBALS as $key => $value ) {
+ if( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
+ $GLOBALS[$key] = array();
+ $REAL[$key] = $value;
+ }
+ }
+ // Saving and clearing session
+ if (isset($_SESSION)) {
+ $REAL_SESSION = array();
+ foreach( $_SESSION as $key => $value ) {
+ $REAL_SESSION[$key] = $value;
+ unset($_SESSION[$key]);
+ }
+ }
+
+ // Running code in different context
+ $scope = function() {
+ global $extractor, $http;
+ extract( func_get_arg(1) );
+ $_GET = $_REQUEST = array(
+ "url" => $url,
+ "max" => FullTextRssUrlFetcher::DEFAULT_MAX,
+ "links" => FullTextRssUrlFetcher::DEFAULT_LINK_STRATEGY,
+ "exc" => "",
+ "format" => FullTextRssUrlFetcher::DEFAULT_FORMAT,
+ "submit" => FullTextRssUrlFetcher::DEFAULT_SUBMIT
+ );
+ ob_start();
+ set_error_handler(function($errno, $errstr) {$this->logger->info("Full Text RSS - {errno} : {errstr}", array("errno" => $errno, "errstr" => $errstr));});
+ require func_get_arg(0);
+ $json = ob_get_contents();
+ ob_end_clean();
+ restore_error_handler();
+ return $json;
+ };
+
+ $json = $scope($this->rootDir."/../vendor/fivefilters/full-text-rss/makefulltextfeed.php", array("url" => $url));
+
+ // Clearing and restoring context
+ foreach ($GLOBALS as $key => $value) {
+ if($key != "GLOBALS" && $key != "_SESSION" ) {
+ unset($GLOBALS[$key]);
+ }
+ }
+ foreach ($REAL as $key => $value) {
+ $GLOBALS[$key] = $value;
+ }
+
+ // Clearing and restoring session
+ if (isset($REAL_SESSION)) {
+ foreach($_SESSION as $key => $value) {
+ unset($_SESSION[$key]);
+ }
+
+ foreach($REAL_SESSION as $key => $value) {
+ $_SESSION[$key] = $value;
+ }
+ }
+
+ $content = json_decode($json, true);
+ $content = $content['rss']['channel']['item'];
+ return new Url($content['description'], $content['title'], $url);
+ }
+}
\ No newline at end of file
diff --git a/web/app_dev.php b/web/app_dev.php
index e0279c2..63ba507 100644
--- a/web/app_dev.php
+++ b/web/app_dev.php
@@ -11,7 +11,7 @@ use Symfony\Component\Debug\Debug;
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
- || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
+ || !(in_array(@$_SERVER['REMOTE_ADDR'], array('10.0.3.1','127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');