From 6666e4be183afc5da00fa910b661b01b77b5300f Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 30 Nov 2014 12:36:24 -0500 Subject: [PATCH 01/20] update composer.json dep versions --- composer.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 626f69e..387ec94 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "symfony-cmf/blog-bundle", + "name": "briancappello/blog-bundle", "type": "symfony-bundle", "description": "Symfony CMF Blog Bundle", "keywords": ["Symfony CMF"], @@ -11,19 +11,19 @@ "homepage": "https://github.com/symfony-cmf/BlogBundle/contributors" } ], - "minimum-stability": "dev", + "minimum-stability": "stable", "require": { "php": ">=5.3.3", - "symfony/framework-bundle": "~2.2", - "symfony-cmf/core-bundle": "1.0.*", + "symfony/framework-bundle": "~2.3", + "symfony-cmf/core-bundle": "1.2.*", "symfony-cmf/routing-auto-bundle": "1.0.*", - "doctrine/phpcr-bundle": "1.0.*", - "doctrine/phpcr-odm": "1.0.*" + "doctrine/phpcr-bundle": "~1.1", + "doctrine/phpcr-odm": "~1.1" }, "require-dev": { - "symfony-cmf/testing": "1.1.*", - "sonata-project/doctrine-phpcr-admin-bundle": "1.0.*", - "symfony-cmf/core-bundle": "1.0.*" + "symfony-cmf/testing": "1.2.*", + "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", + "symfony-cmf/core-bundle": "1.2.*" }, "suggest": { "sonata-project/doctrine-phpcr-admin-bundle": "For sonata administration" From 0dd64f5d9ccde5bcf970666dcb4038595bd489d4 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 4 Dec 2014 09:14:46 -0500 Subject: [PATCH 02/20] cleanups --- Admin/BlogAdmin.php | 51 +++++++++++-------- Admin/PostAdmin.php | 22 ++++---- CmfBlogBundle.php | 19 +++++++ Controller/BlogController.php | 26 ++++------ DependencyInjection/CmfBlogExtension.php | 12 ++--- DependencyInjection/Configuration.php | 27 ++++++---- Document/Blog.php | 22 ++++++++ README.md | 2 +- .../config/{blog-admin.xml => admin.xml} | 40 ++++++--------- Resources/config/cmf_routing_auto.yml | 11 ++++ Resources/config/controllers.xml | 21 -------- .../Blog.phpcr.xml | 15 ++++-- .../Post.phpcr.xml | 16 ++++-- .../TagRoute.phpcr.xml | 3 +- Resources/config/initializer-phpcr.xml | 18 +++++++ Resources/config/menu.xml | 4 +- .../config/routing/autoroute_default.yml | 30 ----------- Resources/config/services.xml | 35 +++++++++++++ Resources/doc/building-a-blog.rst | 6 +-- Resources/translations/CmfBlogBundle.en.xliff | 4 +- Resources/translations/CmfBlogBundle.fr.xliff | 4 +- Resources/translations/CmfBlogBundle.pl.xliff | 4 +- Resources/translations/CmfBlogBundle.ru.xliff | 4 +- Resources/translations/CmfBlogBundle.sk.xliff | 4 +- Resources/translations/CmfBlogBundle.sl.xliff | 4 +- composer.json | 2 +- 26 files changed, 235 insertions(+), 171 deletions(-) rename Resources/config/{blog-admin.xml => admin.xml} (51%) create mode 100644 Resources/config/cmf_routing_auto.yml delete mode 100644 Resources/config/controllers.xml rename Resources/config/{doctrine => doctrine-phpcr}/Blog.phpcr.xml (83%) rename Resources/config/{doctrine => doctrine-phpcr}/Post.phpcr.xml (89%) rename Resources/config/{doctrine => doctrine-phpcr}/TagRoute.phpcr.xml (94%) create mode 100644 Resources/config/initializer-phpcr.xml delete mode 100644 Resources/config/routing/autoroute_default.yml create mode 100644 Resources/config/services.xml diff --git a/Admin/BlogAdmin.php b/Admin/BlogAdmin.php index fb7a11b..4b228bb 100644 --- a/Admin/BlogAdmin.php +++ b/Admin/BlogAdmin.php @@ -14,11 +14,8 @@ use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; -use Sonata\AdminBundle\Validator\ErrorElement; use Sonata\AdminBundle\Form\FormMapper; use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin; -use Symfony\Cmf\Bundle\BlogBundle\Form\PostType; -use Symfony\Cmf\Bundle\BlogBundle\Routing\BlogRouteManager; /** * Blog Admin @@ -30,33 +27,45 @@ class BlogAdmin extends Admin protected $translationDomain = 'CmfBlogBundle'; protected $blogRoot; - protected function configureFormFields(FormMapper $mapper) + /** + * Constructor + * + * @param string $code + * @param string $class + * @param string $baseControllerName + * @param string $blogRoot + */ + public function __construct($code, $class, $baseControllerName, $blogRoot) { - $mapper->add('name', 'text'); - $mapper->add('parent', 'doctrine_phpcr_odm_tree', array( - 'root_node' => $this->blogRoot, - 'choice_list' => array(), - 'select_root_node' => true) - ); - } - - protected function configureDatagridFilters(DatagridMapper $dm) - { - $dm->add('name', 'doctrine_phpcr_string'); + parent::__construct($code, $class, $baseControllerName); + $this->blogRoot = $blogRoot; } - protected function configureListFields(ListMapper $dm) + protected function configureFormFields(FormMapper $formMapper) { - $dm->addIdentifier('name'); + $formMapper + ->with('dashboard.label_blog') + ->add('name', 'text') + ->add('parentDocument', 'doctrine_phpcr_odm_tree', array( + 'root_node' => $this->blogRoot, + 'choice_list' => array(), + 'select_root_node' => true, + )) + ->end() + ; } - public function setBlogRoot($blogRoot) + protected function configureDatagridFilters(DatagridMapper $filterMapper) { - $this->blogRoot = $blogRoot; + $filterMapper + ->add('name', 'doctrine_phpcr_string') + ; } - public function validate(ErrorElement $ee, $obj) + protected function configureListFields(ListMapper $listMapper) { - $ee->with('name')->assertNotBlank()->end(); + $listMapper + ->addIdentifier('name') + ; } } diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index df1fa90..4f87a89 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -17,7 +17,6 @@ use Sonata\AdminBundle\Validator\ErrorElement; use Sonata\AdminBundle\Form\FormMapper; use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin; -use Symfony\Cmf\Bundle\BlogBundle\Form\PostType; use Symfony\Cmf\Bundle\BlogBundle\Form\DataTransformer\CsvToArrayTransformer; /** @@ -38,15 +37,18 @@ protected function configureFormFields(FormMapper $mapper) // $csvToArrayTransformer = new CsvToArrayTransformer; - $mapper->add('title'); - $mapper->add('date', 'datetime', array( - 'widget' => 'single_text', - )); - - $mapper->add('body', 'textarea'); - $mapper->add('blog', 'phpcr_document', array( - 'class' => 'Symfony\Cmf\Bundle\BlogBundle\Document\Blog', - )); + $mapper + ->with('dashboard.label_post') + ->add('title') + ->add('date', 'datetime', array( + 'widget' => 'single_text', + )) + ->add('body', 'textarea') + ->add('blog', 'phpcr_document', array( + 'class' => 'Symfony\Cmf\Bundle\BlogBundle\Document\Blog', + )) + ->end() + ; //$tags = $mapper->create('tags', 'text') // ->addModelTransformer($csvToArrayTransformer); diff --git a/CmfBlogBundle.php b/CmfBlogBundle.php index 802bdaa..45a9f9c 100644 --- a/CmfBlogBundle.php +++ b/CmfBlogBundle.php @@ -12,8 +12,27 @@ namespace Symfony\Cmf\Bundle\BlogBundle; +use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class CmfBlogBundle extends Bundle { + public function build(ContainerBuilder $container) + { + parent::build($container); + + if (class_exists('Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass')) { + $container->addCompilerPass( + DoctrinePhpcrMappingsPass::createXmlMappingDriver( + array( + realpath(__DIR__ . '/Resources/config/doctrine-phpcr') => 'Symfony\Cmf\Bundle\BlogBundle\Document', + ), + array('cmf_blog.persistence.phpcr.manager_name'), + false, + array('CmfBlogBundle' => 'Symfony\Cmf\Bundle\BlogBundle\Document') + ) + ); + } + } } diff --git a/Controller/BlogController.php b/Controller/BlogController.php index fb77135..3f49805 100644 --- a/Controller/BlogController.php +++ b/Controller/BlogController.php @@ -12,13 +12,13 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Controller; -use Doctrine\ODM\PHPCR\DocumentManager; use Symfony\Cmf\Bundle\BlogBundle\Document\Post; +use Symfony\Cmf\Bundle\BlogBundle\Repository\PostRepository; use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishWorkflowChecker; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Security\Core\SecurityContextInterface; -use Symfony\Component\Templating\EngineInterface; +use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; use FOS\RestBundle\View\ViewHandlerInterface; use FOS\RestBundle\View\View; @@ -40,14 +40,14 @@ class BlogController protected $viewHandler; /** - * @var DocumentManager + * @var SecurityContextInterface */ - protected $dm; + protected $securityContext; /** - * @var SecurityContextInterface + * @var PostRepository */ - protected $securityContext; + protected $postRepository; /** * The permission to check for when doing the publish workflow check. @@ -56,17 +56,16 @@ class BlogController */ private $publishWorkflowPermission = PublishWorkflowChecker::VIEW_ATTRIBUTE; - public function __construct( EngineInterface $templating, ViewHandlerInterface $viewHandler = null, - DocumentManager $dm, - SecurityContextInterface $securityContext + SecurityContextInterface $securityContext, + PostRepository $postRepository ) { $this->templating = $templating; $this->viewHandler = $viewHandler; - $this->dm = $dm; $this->securityContext = $securityContext; + $this->postRepository = $postRepository; } /** @@ -91,11 +90,6 @@ protected function renderResponse($contentTemplate, $params) return $this->templating->renderResponse($contentTemplate, $params); } - protected function getPostRepo() - { - return $this->dm->getRepository('Symfony\Cmf\Bundle\BlogBundle\Document\Post'); - } - public function viewPostAction(Post $contentDocument, $contentTemplate = null) { $post = $contentDocument; @@ -119,7 +113,7 @@ public function listAction(Request $request, $contentDocument, $contentTemplate $tag = $request->get('tag', null); // @todo: Pagination - $posts = $this->getPostRepo()->search(array( + $posts = $this->postRepository->search(array( 'tag' => $tag, 'blog_id' => $blog->getId(), )); diff --git a/DependencyInjection/CmfBlogExtension.php b/DependencyInjection/CmfBlogExtension.php index a5dd1b7..9dbd3bb 100644 --- a/DependencyInjection/CmfBlogExtension.php +++ b/DependencyInjection/CmfBlogExtension.php @@ -35,7 +35,8 @@ public function load(array $configs, ContainerBuilder $container) $config = $this->processConfiguration($configuration, $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('controllers.xml'); + $loader->load('services.xml'); + $loader->load('initializer-phpcr.xml'); if ($config['use_sonata_admin']) { $this->loadSonataAdmin($config, $loader, $container); @@ -44,13 +45,6 @@ public function load(array $configs, ContainerBuilder $container) $this->loadMenuIntegration($config, $loader, $container); } - $config['class'] = array_merge(array( - 'blog_admin' => 'Symfony\Cmf\Bundle\BlogBundle\Admin\BlogAdmin', - 'post_admin' => 'Symfony\Cmf\Bundle\BlogBundle\Admin\PostAdmin', - 'blog' => 'Symfony\Cmf\Bundle\BlogBundle\Document\Blog', - 'post' => 'Symfony\Cmf\Bundle\BlogBundle\Document\Post', - ), isset($config['class']) ? $config['class'] : array()); - foreach ($config['class'] as $type => $classFqn) { $container->setParameter( $param = sprintf('cmf_blog.%s_class', $type), @@ -66,7 +60,7 @@ private function loadSonataAdmin($config, XmlFileLoader $loader, ContainerBuilde return; } - $loader->load('blog-admin.xml'); + $loader->load('admin.xml'); $container->setParameter($this->getAlias() . '.blog_basepath', $config['blog_basepath']); } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 9c94521..50c852b 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -52,26 +52,35 @@ public function getConfigTreeBuilder() ->end() ->scalarNode('blog_basepath') ->isRequired() + ->defaultValue('/cms/blog') ->end() - ->scalarNode('routing_post_controller') + ->scalarNode('routing_post_controller') # unused ->defaultValue('cmf_blog.blog_controller:viewPostAction') ->end() - ->scalarNode('routing_post_prefix') + ->scalarNode('routing_post_prefix') # unused ->defaultValue('posts') ->end() - ->scalarNode('routing_tag_controller') + ->scalarNode('routing_tag_controller') # unused ->defaultValue('cmf_blog.blog_controller:listAction') ->end() - ->scalarNode('routing_tag_prefix') + ->scalarNode('routing_tag_prefix') # unused ->defaultValue('tag') ->end() ->arrayNode('class') + ->addDefaultsIfNotSet() ->children() - # defaults defined in CmfBlogExtension - ->scalarNode('blog_admin')->end() - ->scalarNode('post_admin')->end() - ->scalarNode('blog')->end() - ->scalarNode('post')->end() + ->scalarNode('blog_admin') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\BlogAdmin') + ->end() + ->scalarNode('post_admin') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\PostAdmin') + ->end() + ->scalarNode('blog') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Document\Blog') + ->end() + ->scalarNode('post') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Document\Post') + ->end() ->end() ->end() ->end() diff --git a/Document/Blog.php b/Document/Blog.php index 5d235c1..9e3b38e 100644 --- a/Document/Blog.php +++ b/Document/Blog.php @@ -54,6 +54,11 @@ public function getId() return $this->id; } + public function setId($id) + { + $this->id = $id; + } + public function getName() { return $this->name; @@ -64,16 +69,32 @@ public function setName($name) $this->name = $name; } + /** + * @deprecated Use getParentDocument instead + */ public function getParent() { return $this->parent; } + public function getParentDocument() + { + return $this->parent; + } + + /** + * @deprecated Use setParentDocument instead + */ public function setParent($parent) { $this->parent = $parent; } + public function setParentDocument($parent) + { + $this->parent = $parent; + } + public function getPosts() { return $this->posts; @@ -82,6 +103,7 @@ public function getPosts() public function setPosts($posts) { $this->posts = array(); + foreach ($posts as $post) { $this->addPost($post); } diff --git a/README.md b/README.md index 459126f..356a8c8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Pending features: ## Requirements -* Symfony 2.2.x +* Symfony 2.3+ * [CoreBundle](https://github.com/symfony-cmf/CoreBundle) * [RoutingAutoBundle](https://github.com/symfony-cmf/RoutingAutoBundle) diff --git a/Resources/config/blog-admin.xml b/Resources/config/admin.xml similarity index 51% rename from Resources/config/blog-admin.xml rename to Resources/config/admin.xml index 1e1c518..1f4f1c2 100644 --- a/Resources/config/blog-admin.xml +++ b/Resources/config/admin.xml @@ -4,43 +4,33 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - - - - - + %cmf_blog.blog_class% SonataAdminBundle:CRUD + %cmf_blog.blog_basepath% - - - %cmf_blog.blog_basepath% - - - + %cmf_blog.post_class% diff --git a/Resources/config/cmf_routing_auto.yml b/Resources/config/cmf_routing_auto.yml new file mode 100644 index 0000000..71c46fd --- /dev/null +++ b/Resources/config/cmf_routing_auto.yml @@ -0,0 +1,11 @@ +Symfony\Cmf\Bundle\BlogBundle\Document\Blog: + uri_schema: /blogs/{blog} + token_providers: + blog: [content_method, { method: getName }] + +Symfony\Cmf\Bundle\BlogBundle\Document\Post: + uri_schema: /blogs/{blog}/{date}/{title} + token_providers: + blog: [content_method, { method: getBlog }] + date: [content_datetime, { method: getDate }] + title: [content_method, { method: getTitle }] diff --git a/Resources/config/controllers.xml b/Resources/config/controllers.xml deleted file mode 100644 index 846eab2..0000000 --- a/Resources/config/controllers.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - Symfony\Cmf\Bundle\BlogBundle\Controller\BlogController - - - - - - - - - - - - - - - diff --git a/Resources/config/doctrine/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml similarity index 83% rename from Resources/config/doctrine/Blog.phpcr.xml rename to Resources/config/doctrine-phpcr/Blog.phpcr.xml index ddfe29b..43c8de9 100644 --- a/Resources/config/doctrine/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -2,23 +2,28 @@ xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping - https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd" -> + https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> + > + + - + - + + + + + diff --git a/Resources/config/doctrine/Post.phpcr.xml b/Resources/config/doctrine-phpcr/Post.phpcr.xml similarity index 89% rename from Resources/config/doctrine/Post.phpcr.xml rename to Resources/config/doctrine-phpcr/Post.phpcr.xml index daed590..deba37c 100644 --- a/Resources/config/doctrine/Post.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Post.phpcr.xml @@ -2,8 +2,7 @@ xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping - https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd" -> + https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> + + + + @@ -21,11 +24,14 @@ - - + - + + + + + diff --git a/Resources/config/doctrine/TagRoute.phpcr.xml b/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml similarity index 94% rename from Resources/config/doctrine/TagRoute.phpcr.xml rename to Resources/config/doctrine-phpcr/TagRoute.phpcr.xml index 423400e..4064dd7 100644 --- a/Resources/config/doctrine/TagRoute.phpcr.xml +++ b/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml @@ -2,8 +2,7 @@ xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping - https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd" -> + https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> + + + + + + + CmfBlogBundle + + %cmf_blog.blog_basepath% + + + + + + diff --git a/Resources/config/menu.xml b/Resources/config/menu.xml index 02c70dc..c5a309a 100644 --- a/Resources/config/menu.xml +++ b/Resources/config/menu.xml @@ -12,7 +12,9 @@ %cmf_blog.content_key% %cmf_blog.post_class% - + + + diff --git a/Resources/config/routing/autoroute_default.yml b/Resources/config/routing/autoroute_default.yml deleted file mode 100644 index 688ab72..0000000 --- a/Resources/config/routing/autoroute_default.yml +++ /dev/null @@ -1,30 +0,0 @@ -cmf_routing_auto: - mappings: - Symfony\Cmf\Bundle\BlogBundle\Document\Blog: - content_path: - routing_path: - provider: [specified, { path: cms/routes }] - exists_action: use - not_exists_action: throw_exception - namespace: - provider: [specified, { path: blog }] - exists_action: use - not_exists_action: create - content_name: - provider: [content_method,{ method: getName }] - exists_action: auto_increment - not_exists_action: create - Symfony\Cmf\Bundle\BlogBundle\Document\Post: - content_path: - routing_path: - provider: [content_object, { method: getBlog }] - exists_action: use - not_exists_action: throw_exception - date: - provider: [content_datetime, {method: getDate}] - exists_action: use - not_exists_action: create - content_name: - provider: [content_method, {method: getTitle}] - exists_action: auto_increment - not_exists_action: create diff --git a/Resources/config/services.xml b/Resources/config/services.xml new file mode 100644 index 0000000..83f0f17 --- /dev/null +++ b/Resources/config/services.xml @@ -0,0 +1,35 @@ + + + + Symfony\Cmf\Bundle\BlogBundle\Controller\BlogController + + + + + + + + + + + + + %cmf_blog.blog_class% + + + + %cmf_blog.post_class% + + + + + + diff --git a/Resources/doc/building-a-blog.rst b/Resources/doc/building-a-blog.rst index 62f15dc..a71ab89 100644 --- a/Resources/doc/building-a-blog.rst +++ b/Resources/doc/building-a-blog.rst @@ -15,6 +15,6 @@ Register the routes in config.yml dynamic: ... controllers_by_class: - Symfony\Cmf\Bundle\BlogBundle\Document\Blog: cmf_blog.blog_controller:list - Symfony\Cmf\Bundle\BlogBundle\Document\Post: cmf_blog.blog_controller:viewPost - Symfony\Cmf\Bundle\BlogBundle\Document\Tag: cmf_blog.blog_controller:list + Symfony\Cmf\Bundle\BlogBundle\Document\Blog: cmf_blog.blog_controller:listAction + Symfony\Cmf\Bundle\BlogBundle\Document\Post: cmf_blog.blog_controller:viewPostAction + Symfony\Cmf\Bundle\BlogBundle\Document\Tag: cmf_blog.blog_controller:listAction diff --git a/Resources/translations/CmfBlogBundle.en.xliff b/Resources/translations/CmfBlogBundle.en.xliff index 6a5122e..225b183 100644 --- a/Resources/translations/CmfBlogBundle.en.xliff +++ b/Resources/translations/CmfBlogBundle.en.xliff @@ -107,8 +107,8 @@ Name - - form.label_parent + + form.label_parent_document Parent diff --git a/Resources/translations/CmfBlogBundle.fr.xliff b/Resources/translations/CmfBlogBundle.fr.xliff index 5e3437e..3b83108 100644 --- a/Resources/translations/CmfBlogBundle.fr.xliff +++ b/Resources/translations/CmfBlogBundle.fr.xliff @@ -107,8 +107,8 @@ Nom - - form.label_parent + + form.label_parent_document Parent diff --git a/Resources/translations/CmfBlogBundle.pl.xliff b/Resources/translations/CmfBlogBundle.pl.xliff index 8af6ef1..d837f91 100644 --- a/Resources/translations/CmfBlogBundle.pl.xliff +++ b/Resources/translations/CmfBlogBundle.pl.xliff @@ -107,8 +107,8 @@ Nazwa - - form.label_parent + + form.label_parent_document Nadrzędny diff --git a/Resources/translations/CmfBlogBundle.ru.xliff b/Resources/translations/CmfBlogBundle.ru.xliff index 2ea6e83..ba018bd 100644 --- a/Resources/translations/CmfBlogBundle.ru.xliff +++ b/Resources/translations/CmfBlogBundle.ru.xliff @@ -107,8 +107,8 @@ Имя - - form.label_parent + + form.label_parent_document Родитель diff --git a/Resources/translations/CmfBlogBundle.sk.xliff b/Resources/translations/CmfBlogBundle.sk.xliff index a089db6..b5b68a2 100644 --- a/Resources/translations/CmfBlogBundle.sk.xliff +++ b/Resources/translations/CmfBlogBundle.sk.xliff @@ -107,8 +107,8 @@ Názov - - form.label_parent + + form.label_parent_document Rodič diff --git a/Resources/translations/CmfBlogBundle.sl.xliff b/Resources/translations/CmfBlogBundle.sl.xliff index 2a9d863..2be0ffd 100644 --- a/Resources/translations/CmfBlogBundle.sl.xliff +++ b/Resources/translations/CmfBlogBundle.sl.xliff @@ -107,8 +107,8 @@ Ime - - form.label_parent + + form.label_parent_document Vrhnji diff --git a/composer.json b/composer.json index 387ec94..ef17776 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "briancappello/blog-bundle", + "name": "symfony-cmf/blog-bundle", "type": "symfony-bundle", "description": "Symfony CMF Blog Bundle", "keywords": ["Symfony CMF"], From 18747ee6403d3d6f7d71531da18465999f204b73 Mon Sep 17 00:00:00 2001 From: Brian Cappello Date: Fri, 5 Dec 2014 20:09:11 -0500 Subject: [PATCH 03/20] refactor Blog and Post into Models and move the document entities into Doctrine/Phpcr --- Admin/PostAdmin.php | 25 +- CmfBlogBundle.php | 4 +- Controller/BlogController.php | 2 +- DependencyInjection/Configuration.php | 6 +- {Document => Doctrine/Phpcr}/Blog.php | 95 +++---- Doctrine/Phpcr/Post.php | 146 +++++++++++ {Document => Doctrine/Phpcr}/TagRoute.php | 2 +- Document/Post.php | 218 ---------------- Model/Blog.php | 131 ++++++++++ Model/Post.php | 235 ++++++++++++++++++ Repository/PostRepository.php | 10 +- Resources/config/admin.xml | 1 + Resources/config/cmf_routing_auto.yml | 9 +- .../config/doctrine-phpcr/Blog.phpcr.xml | 15 +- .../config/doctrine-phpcr/Post.phpcr.xml | 19 +- .../config/doctrine-phpcr/TagRoute.phpcr.xml | 2 +- Resources/config/validation.xml | 33 +++ Resources/doc/building-a-blog.rst | 6 +- Resources/translations/CmfBlogBundle.en.xliff | 12 +- Resources/translations/CmfBlogBundle.fr.xliff | 12 +- Resources/translations/CmfBlogBundle.pl.xliff | 12 +- Resources/translations/CmfBlogBundle.ru.xliff | 12 +- Resources/translations/CmfBlogBundle.sk.xliff | 12 +- Resources/translations/CmfBlogBundle.sl.xliff | 12 +- Tagging/Tag.php | 2 +- Tests/Unit/Tagging/TagTest.php | 2 +- 26 files changed, 670 insertions(+), 365 deletions(-) rename {Document => Doctrine/Phpcr}/Blog.php (60%) create mode 100644 Doctrine/Phpcr/Post.php rename {Document => Doctrine/Phpcr}/TagRoute.php (89%) delete mode 100644 Document/Post.php create mode 100644 Model/Blog.php create mode 100644 Model/Post.php create mode 100644 Resources/config/validation.xml diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index 4f87a89..a7c3ca1 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -27,6 +27,21 @@ class PostAdmin extends Admin { protected $translationDomain = 'CmfBlogBundle'; + protected $blogClass; + + /** + * Constructor + * + * @param string $code + * @param string $class + * @param string $baseControllerName + * @param string $blogClass + */ + public function __construct($code, $class, $baseControllerName, $blogClass) + { + parent::__construct($code, $class, $baseControllerName); + $this->blogClass = $blogClass; + } protected function configureFormFields(FormMapper $mapper) { @@ -40,12 +55,12 @@ protected function configureFormFields(FormMapper $mapper) $mapper ->with('dashboard.label_post') ->add('title') - ->add('date', 'datetime', array( + ->add('publicationDate', 'datetime', array( 'widget' => 'single_text', )) - ->add('body', 'textarea') + ->add('content', 'textarea') ->add('blog', 'phpcr_document', array( - 'class' => 'Symfony\Cmf\Bundle\BlogBundle\Document\Blog', + 'class' => $this->blogClass, )) ->end() ; @@ -68,8 +83,4 @@ protected function configureListFields(ListMapper $dm) $dm->addIdentifier('title'); } - public function validate(ErrorElement $ee, $obj) - { - $ee->with('title')->assertNotBlank()->end(); - } } diff --git a/CmfBlogBundle.php b/CmfBlogBundle.php index 45a9f9c..a399649 100644 --- a/CmfBlogBundle.php +++ b/CmfBlogBundle.php @@ -26,11 +26,11 @@ public function build(ContainerBuilder $container) $container->addCompilerPass( DoctrinePhpcrMappingsPass::createXmlMappingDriver( array( - realpath(__DIR__ . '/Resources/config/doctrine-phpcr') => 'Symfony\Cmf\Bundle\BlogBundle\Document', + realpath(__DIR__ . '/Resources/config/doctrine-phpcr') => 'Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr', ), array('cmf_blog.persistence.phpcr.manager_name'), false, - array('CmfBlogBundle' => 'Symfony\Cmf\Bundle\BlogBundle\Document') + array('CmfBlogBundle' => 'Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr') ) ); } diff --git a/Controller/BlogController.php b/Controller/BlogController.php index 3f49805..eff8927 100644 --- a/Controller/BlogController.php +++ b/Controller/BlogController.php @@ -12,7 +12,7 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Controller; -use Symfony\Cmf\Bundle\BlogBundle\Document\Post; +use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post; use Symfony\Cmf\Bundle\BlogBundle\Repository\PostRepository; use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishWorkflowChecker; use Symfony\Component\HttpFoundation\Request; diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 50c852b..2dd1436 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -51,8 +51,8 @@ public function getConfigTreeBuilder() ->end() ->end() ->scalarNode('blog_basepath') - ->isRequired() ->defaultValue('/cms/blog') + ->cannotBeEmpty() ->end() ->scalarNode('routing_post_controller') # unused ->defaultValue('cmf_blog.blog_controller:viewPostAction') @@ -76,10 +76,10 @@ public function getConfigTreeBuilder() ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\PostAdmin') ->end() ->scalarNode('blog') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Document\Blog') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog') ->end() ->scalarNode('post') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Document\Post') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post') ->end() ->end() ->end() diff --git a/Document/Blog.php b/Doctrine/Phpcr/Blog.php similarity index 60% rename from Document/Blog.php rename to Doctrine/Phpcr/Blog.php index 9e3b38e..82d31b7 100644 --- a/Document/Blog.php +++ b/Doctrine/Phpcr/Blog.php @@ -10,108 +10,66 @@ */ -namespace Symfony\Cmf\Bundle\BlogBundle\Document; +namespace Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr; -use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR; +use Symfony\Cmf\Bundle\BlogBundle\Model\Blog as BlogModel; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; -use Symfony\Component\Routing\Route; /** * Blog Document * * @author Daniel Leech */ -class Blog implements RouteReferrersReadInterface +class Blog extends BlogModel implements RouteReferrersReadInterface, RouteObjectInterface { /** - * Identifier + * @var string */ protected $id; - /** - * Node Name / Blog Title - */ - protected $name; - /** * Parent Document */ protected $parent; - /** - * Posts (mapped as children) - */ - protected $posts; - /** * Routes (mapped from Route::content) + * + * @var \Symfony\Component\Routing\Route[] */ protected $routes; + /** + * Get id + * + * @return string + */ public function getId() { return $this->id; } - public function setId($id) - { - $this->id = $id; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - } - /** - * @deprecated Use getParentDocument instead + * Get parent document */ - public function getParent() - { - return $this->parent; - } - public function getParentDocument() { return $this->parent; } /** - * @deprecated Use setParentDocument instead + * Set parent document + * + * @param $parent + * @return Blog */ - public function setParent($parent) - { - $this->parent = $parent; - } - public function setParentDocument($parent) { $this->parent = $parent; - } - public function getPosts() - { - return $this->posts; - } - - public function setPosts($posts) - { - $this->posts = array(); - - foreach ($posts as $post) { - $this->addPost($post); - } - } - - public function addPost(Post $post) - { - $this->posts[] = $post; + return $this; } /** @@ -122,14 +80,16 @@ public function getRoutes() return $this->routes; } + // FIXME: these getRoutes functions should probably go into a repository so classes aren't hard coded + public function getPostsRoutes() { - return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Document\PostRoute'); + return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\PostRoute'); } public function getTagRoutes() { - return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Document\TagRoute'); + return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\TagRoute'); } public function getSubRoutes($routeClass) @@ -140,7 +100,7 @@ public function getSubRoutes($routeClass) foreach ($route->getRouteChildren() as $routeChild) if ($routeChild instanceof $routeClass) { $subRoutes[] = $routeChild; - } + } } if (empty($subRoutes)) { @@ -154,8 +114,13 @@ public function getSubRoutes($routeClass) return $subRoutes; } - public function __toString() + public function getContent() + { + return $this; + } + + public function getRouteKey() { - return (string) $this->name; + return null; } } diff --git a/Doctrine/Phpcr/Post.php b/Doctrine/Phpcr/Post.php new file mode 100644 index 0000000..1b1615f --- /dev/null +++ b/Doctrine/Phpcr/Post.php @@ -0,0 +1,146 @@ + + */ +class Post extends PostModel implements RouteReferrersReadInterface +{ + /** + * ID / Path to to this object + * + * @var string + */ + protected $id; + + /** + * Node name (same as slug) + * + * @var string + */ + protected $name; + + // FIXME what is this cannot query shit + /** + * READ ONLY: Post slug (cannot query directly on name field) + * + * @var string + */ + protected $slug; + + /** + * List of referring routes + * + * @var \Symfony\Component\Routing\Route[] + */ + protected $routes; + + + /** + * Get id + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Get name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritDoc} + */ + public function setTitle($title) + { + parent::setTitle($title); + + $this->name = PostUtils::slugify($title); // FIXME does gedmo work with phpcr? + $this->slug = $this->name; + + return $this; + } + + /** + * Get slug + * + * @return string + */ + public function getSlug() + { + return $this->slug; + } + + /** + * Get parent document + * + * @return BlogModel + */ + public function getParentDocument() + { + return $this->blog; + } + + /** + * Set parent document + * + * @param BlogModel $blog + * @return Post + */ + public function setParentDocument(BlogModel $blog) + { + $this->blog = $blog; + $this->parent = $blog; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function setBlog(BlogModel $blog) + { + parent::setBlog($blog); + + $this->parent = $blog; + + return $this; + } + + /** + * Get routes + * + * @return \Symfony\Component\Routing\Route[] + */ + public function getRoutes() + { + return $this->routes; + } + +} diff --git a/Document/TagRoute.php b/Doctrine/Phpcr/TagRoute.php similarity index 89% rename from Document/TagRoute.php rename to Doctrine/Phpcr/TagRoute.php index 9989e53..409f262 100644 --- a/Document/TagRoute.php +++ b/Doctrine/Phpcr/TagRoute.php @@ -10,7 +10,7 @@ */ -namespace Symfony\Cmf\Bundle\BlogBundle\Document; +namespace Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr; use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route; use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR; diff --git a/Document/Post.php b/Document/Post.php deleted file mode 100644 index ed5fa93..0000000 --- a/Document/Post.php +++ /dev/null @@ -1,218 +0,0 @@ - - */ -class Post implements RouteReferrersReadInterface, PublishTimePeriodInterface, PublishableInterface -{ - /** - * ID / Path to to this object - * @var string - */ - protected $id; - - /** - * Node name (same as slug) - * @var string - */ - protected $name; - - /** - * READ ONLY: Post slug (cannot query directly on name field) - */ - protected $slug; - - /** - * Blog - this is the parent document. - * @var Blog - */ - protected $blog; - - /** - * Post title (name is generated from this) - * @var string - */ - protected $title; - - /** - * Post body text - * @var string - */ - protected $body; - - /** - * Date of publication - * @var \DateTime - */ - protected $date; - - /** - * List of referring routes - */ - protected $routes; - - /** - * Date to start publishing from - * @var \DateTime - */ - protected $publishStartDate; - - /** - * Date to stop publishing from - * @var \DateTime - */ - protected $publishEndDate; - - /** - * If the document should be publishable - * @var Boolean - */ - protected $isPublishable = true; - - public function __construct() - { - $this->date = new \DateTime(); - } - - public function getId() - { - return $this->id; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - } - - public function getTitle() - { - return $this->title; - } - - public function setTitle($title) - { - $this->title = $title; - $this->name = PostUtils::slugify($title); - $this->slug = $this->name; - } - - public function getSlug() - { - return $this->slug; - } - - public function getBody() - { - return $this->body; - } - - public function setBody($body) - { - $this->body = $body; - } - - public function getDate() - { - return $this->date; - } - - public function setDate($date) - { - $this->date = $date; - } - - public function getParent() - { - return $this->getBlog(); - } - - public function getBlog() - { - return $this->blog; - } - - public function setBlog(Blog $blog) - { - $this->blog = $blog; - - // The user can create a post from Admin, so - // we let them choose and automatically make - // this Post a child of selected blog. - $this->parent = $blog; - } - - public function getBodyPreview($length = 255) - { - $suffix = strlen($this->body) > $length ? ' ...' : ''; - - return substr($this->body, 0, 255).$suffix; - } - - public function getRoutes() - { - return $this->routes; - } - - public function isPublishable() - { - return $this->isPublishable; - } - - public function setPublishable($publishable) - { - $this->isPublishable = $publishable; - } - - public function getPublishStartDate() - { - return $this->publishStartDate; - } - - public function setPublishStartDate(\DateTime $publishStartDate = null) - { - $this->publishStartDate = $publishStartDate; - } - - public function getPublishEndDate() - { - return $this->publishEndDate; - } - - public function setPublishEndDate(\DateTime $publishEndDate = null) - { - $this->publishEndDate = $publishEndDate; - } - - public function __toString() - { - return (string) $this->name; - } -} diff --git a/Model/Blog.php b/Model/Blog.php new file mode 100644 index 0000000..e81ddad --- /dev/null +++ b/Model/Blog.php @@ -0,0 +1,131 @@ + + */ +class Blog +{ + /** + * Blog name + * + * @var string + */ + protected $name; + + /** + * Posts + * + * @var ArrayCollection + */ + protected $posts; + + + /** + * Constructor + */ + public function __construct() + { + $this->posts = new ArrayCollection(); + } + + /** + * Get name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Set name + * + * @param string $name + * @return Blog + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + /** + * Add post + * + * @param Post $post + * @return Blog + */ + public function addPost(Post $post) + { + if (!$this->posts->contains($post)) { + $this->posts->add($post); + } + + return $this; + } + + /** + * Remove post + * + * @param Post $post + * @return Blog + */ + public function removePost(Post $post) + { + if ($this->posts->contains($post)) { + $this->posts->remove($post); + } + + return $this; + } + + /** + * Get posts + * + * @return ArrayCollection + */ + public function getPosts() + { + return $this->posts; + } + + /** + * Set posts + * + * @param $posts + * @return $this + */ + public function setPosts($posts) + { + $this->posts = new ArrayCollection(); + + foreach ($posts as $post) { + $this->posts->add($post); + } + + return $this; + } + + public function __toString() + { + return (string) $this->name; + } +} diff --git a/Model/Post.php b/Model/Post.php new file mode 100644 index 0000000..b929fa6 --- /dev/null +++ b/Model/Post.php @@ -0,0 +1,235 @@ + + */ +class Post implements PublishTimePeriodInterface, PublishableInterface +{ + /** + * @var Blog + */ + protected $blog; + + /** + * @var string + */ + protected $title; + + /** + * @var string + */ + protected $content; + + /** + * @var \DateTime + */ + protected $publicationDate; + + /** + * @var \DateTime + */ + protected $publishStartDate; + + /** + * @var \DateTime + */ + protected $publishEndDate; + + /** + * @var boolean + */ + protected $isPublishable = true; + + + /** + * Constructor + */ + public function __construct() + { + $this->publicationDate = new \DateTime(); + } + + /** + * Get blog + * + * @return Blog + */ + public function getBlog() + { + return $this->blog; + } + + /** + * Set blog + * + * @param Blog $blog + * @return Post + */ + public function setBlog(Blog $blog) + { + $this->blog = $blog; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set title + * + * @param string $title + * @return Post + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get the post's content + * + * @return string + */ + public function getContent() + { + return $this->content; + } + + /** + * Set the post's content + * + * @param string $content + * @return Post + */ + public function setContent($content) + { + $this->content = $content; + + return $this; + } + + /** + * Get publication date + * + * @return \DateTime + */ + public function getPublicationDate() + { + return $this->publicationDate; + } + + /** + * Set publication date + * + * @param \DateTime $publicationDate + * @return Post + */ + public function setPublicationDate($publicationDate) + { + $this->publicationDate = $publicationDate; + + return $this; + } + + /** + * Is publishable + * + * @return bool + */ + public function isPublishable() + { + return $this->isPublishable; + } + + /** + * Set publishable + * + * @param bool $publishable + * @return Post + */ + public function setPublishable($publishable) + { + $this->isPublishable = $publishable; + + return $this; + } + + /** + * Get publish start date + * + * @return \DateTime + */ + public function getPublishStartDate() + { + return $this->publishStartDate; + } + + /** + * Set publish start date + * + * @param \DateTime $publishStartDate + * @return Post + */ + public function setPublishStartDate(\DateTime $publishStartDate = null) + { + $this->publishStartDate = $publishStartDate; + + return $this; + } + + /** + * Get publish end date + * + * @return \DateTime + */ + public function getPublishEndDate() + { + return $this->publishEndDate; + } + + /** + * Set publish end date + * + * @param \DateTime $publishEndDate + * @return Post + */ + public function setPublishEndDate(\DateTime $publishEndDate = null) + { + $this->publishEndDate = $publishEndDate; + + return $this; + } + + public function __toString() + { + return (string) $this->title; + } +} diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index dcfe065..b6e2e39 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -12,7 +12,7 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Repository; use Doctrine\ODM\PHPCR\DocumentRepository; -use Symfony\Cmf\Bundle\BlogBundle\Document\Post; +use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post; class PostRepository extends DocumentRepository { @@ -21,13 +21,15 @@ public function searchQuery($options) $options = array_merge(array( 'blog_uuid' => null, ), $options); - $qb = $this->createQueryBuilder('a'); + + $qb = $this->createQueryBuilder('p'); if ($options['blog_id']) { - $qb->where()->descendant($options['blog_id'], 'a'); + $qb->where()->descendant($options['blog_id'], 'p'); } - $qb->orderBy()->desc()->field('a.date'); + $qb->orderBy()->desc()->field('p.publicationDate'); + return $qb->getQuery(); } diff --git a/Resources/config/admin.xml b/Resources/config/admin.xml index 1f4f1c2..9d04f94 100644 --- a/Resources/config/admin.xml +++ b/Resources/config/admin.xml @@ -35,6 +35,7 @@ %cmf_blog.post_class% SonataAdminBundle:CRUD + %cmf_blog.blog_class% diff --git a/Resources/config/cmf_routing_auto.yml b/Resources/config/cmf_routing_auto.yml index 71c46fd..046eff1 100644 --- a/Resources/config/cmf_routing_auto.yml +++ b/Resources/config/cmf_routing_auto.yml @@ -1,11 +1,14 @@ -Symfony\Cmf\Bundle\BlogBundle\Document\Blog: +Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: uri_schema: /blogs/{blog} +# attributes: +# defaults: +# _template: '::blog.html.twig' token_providers: blog: [content_method, { method: getName }] -Symfony\Cmf\Bundle\BlogBundle\Document\Post: +Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: uri_schema: /blogs/{blog}/{date}/{title} token_providers: blog: [content_method, { method: getBlog }] - date: [content_datetime, { method: getDate }] + date: [content_datetime, { method: getPublicationDate }] title: [content_method, { method: getTitle }] diff --git a/Resources/config/doctrine-phpcr/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml index 43c8de9..04d0a44 100644 --- a/Resources/config/doctrine-phpcr/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -4,18 +4,16 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> - + - + - - - + + + + @@ -27,4 +25,3 @@ - diff --git a/Resources/config/doctrine-phpcr/Post.phpcr.xml b/Resources/config/doctrine-phpcr/Post.phpcr.xml index deba37c..e7abe15 100644 --- a/Resources/config/doctrine-phpcr/Post.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Post.phpcr.xml @@ -5,25 +5,25 @@ https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> - + - - - - - - - + + + + + + + @@ -35,4 +35,3 @@ - diff --git a/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml b/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml index 4064dd7..4e43ffe 100644 --- a/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml +++ b/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml @@ -5,7 +5,7 @@ https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> diff --git a/Resources/config/validation.xml b/Resources/config/validation.xml new file mode 100644 index 0000000..34faa18 --- /dev/null +++ b/Resources/config/validation.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/doc/building-a-blog.rst b/Resources/doc/building-a-blog.rst index a71ab89..92a853e 100644 --- a/Resources/doc/building-a-blog.rst +++ b/Resources/doc/building-a-blog.rst @@ -15,6 +15,6 @@ Register the routes in config.yml dynamic: ... controllers_by_class: - Symfony\Cmf\Bundle\BlogBundle\Document\Blog: cmf_blog.blog_controller:listAction - Symfony\Cmf\Bundle\BlogBundle\Document\Post: cmf_blog.blog_controller:viewPostAction - Symfony\Cmf\Bundle\BlogBundle\Document\Tag: cmf_blog.blog_controller:listAction + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: cmf_blog.blog_controller:listAction + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: cmf_blog.blog_controller:viewPostAction + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Tag: cmf_blog.blog_controller:listAction diff --git a/Resources/translations/CmfBlogBundle.en.xliff b/Resources/translations/CmfBlogBundle.en.xliff index 225b183..71af840 100644 --- a/Resources/translations/CmfBlogBundle.en.xliff +++ b/Resources/translations/CmfBlogBundle.en.xliff @@ -47,8 +47,8 @@ Blog - - list.label_date + + list.label_publication_date Date @@ -87,13 +87,13 @@ Blog - - form.label_body + + form.label_content Content - - form.label_date + + form.label_publication_date Date diff --git a/Resources/translations/CmfBlogBundle.fr.xliff b/Resources/translations/CmfBlogBundle.fr.xliff index 3b83108..14ac515 100644 --- a/Resources/translations/CmfBlogBundle.fr.xliff +++ b/Resources/translations/CmfBlogBundle.fr.xliff @@ -47,8 +47,8 @@ Blog - - list.label_date + + list.label_publication_date Date @@ -87,13 +87,13 @@ Blog - - form.label_body + + form.label_content Contenu - - form.label_date + + form.label_publication_date Date diff --git a/Resources/translations/CmfBlogBundle.pl.xliff b/Resources/translations/CmfBlogBundle.pl.xliff index d837f91..ffc315d 100644 --- a/Resources/translations/CmfBlogBundle.pl.xliff +++ b/Resources/translations/CmfBlogBundle.pl.xliff @@ -47,8 +47,8 @@ Blog - - list.label_date + + list.label_publication_date Data @@ -87,13 +87,13 @@ Wydarzenia - - form.label_body + + form.label_content Zawartość - - form.label_date + + form.label_publication_date Data diff --git a/Resources/translations/CmfBlogBundle.ru.xliff b/Resources/translations/CmfBlogBundle.ru.xliff index ba018bd..6d60475 100644 --- a/Resources/translations/CmfBlogBundle.ru.xliff +++ b/Resources/translations/CmfBlogBundle.ru.xliff @@ -47,8 +47,8 @@ Блог - - list.label_date + + list.label_publication_date Дата @@ -87,13 +87,13 @@ Блог - - form.label_body + + form.label_content Содержание - - form.label_date + + form.label_publication_date Дата diff --git a/Resources/translations/CmfBlogBundle.sk.xliff b/Resources/translations/CmfBlogBundle.sk.xliff index b5b68a2..03d4a8c 100644 --- a/Resources/translations/CmfBlogBundle.sk.xliff +++ b/Resources/translations/CmfBlogBundle.sk.xliff @@ -47,8 +47,8 @@ Blog - - list.label_date + + list.label_publication_date Dátum @@ -87,13 +87,13 @@ Blog - - form.label_body + + form.label_content Obsah - - form.label_date + + form.label_publication_date Dátum diff --git a/Resources/translations/CmfBlogBundle.sl.xliff b/Resources/translations/CmfBlogBundle.sl.xliff index 2be0ffd..89c90dd 100644 --- a/Resources/translations/CmfBlogBundle.sl.xliff +++ b/Resources/translations/CmfBlogBundle.sl.xliff @@ -47,8 +47,8 @@ Blog - - list.label_date + + list.label_publication_date Datum @@ -87,13 +87,13 @@ Blog - - form.label_body + + form.label_content Vsebina - - form.label_date + + form.label_publication_date Datum diff --git a/Tagging/Tag.php b/Tagging/Tag.php index f5ebc41..d97a5d6 100644 --- a/Tagging/Tag.php +++ b/Tagging/Tag.php @@ -13,7 +13,7 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Tagging; use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; -use Symfony\Cmf\Bundle\BlogBundle\Document\Blog; +use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog; class Tag implements RouteReferrersReadInterface { diff --git a/Tests/Unit/Tagging/TagTest.php b/Tests/Unit/Tagging/TagTest.php index 4e12d4b..c8dea7d 100644 --- a/Tests/Unit/Tagging/TagTest.php +++ b/Tests/Unit/Tagging/TagTest.php @@ -20,7 +20,7 @@ class TagTest extends \PHPUnit_Framework_TestCase public function setUp() { - $blog = $this->getMock('Symfony\Cmf\Bundle\BlogBundle\Document\Blog'); + $blog = $this->getMock('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog'); $this->tag = new Tag($blog, 'foo'); } From 899e53e5efeeb13fab335da6806c5ca4663dd589 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 8 Dec 2014 12:52:04 -0500 Subject: [PATCH 04/20] front end refactoring - repositories, controllers and templates --- Admin/BlogAdmin.php | 1 + Admin/PostAdmin.php | 5 +- Controller/BaseController.php | 85 +++++++++ Controller/BlogController.php | 124 +++++-------- Controller/PostController.php | 65 +++++++ DataFixtures/PHPCR/LoadBlogData.php | 79 ++++++++ DependencyInjection/CmfBlogExtension.php | 11 +- DependencyInjection/Configuration.php | 9 +- Doctrine/Phpcr/Blog.php | 72 +++----- Doctrine/Phpcr/Post.php | 14 +- Model/Blog.php | 34 +++- Model/Post.php | 65 +++++-- Repository/BlogRepository.php | 128 +++++++++++++ Repository/PostRepository.php | 174 ++++++++++++++++-- Resources/config/admin.xml | 10 +- Resources/config/cmf_routing_auto.yml | 2 +- .../config/doctrine-phpcr/Blog.phpcr.xml | 7 +- .../config/doctrine-phpcr/Post.phpcr.xml | 13 +- Resources/config/menu.xml | 3 +- Resources/config/routing/blog_controller.xml | 11 ++ Resources/config/services.xml | 22 ++- Resources/translations/CmfBlogBundle.en.xliff | 19 +- Resources/translations/CmfBlogBundle.fr.xliff | 12 +- Resources/translations/CmfBlogBundle.pl.xliff | 12 +- Resources/translations/CmfBlogBundle.ru.xliff | 12 +- Resources/translations/CmfBlogBundle.sk.xliff | 12 +- Resources/translations/CmfBlogBundle.sl.xliff | 12 +- Resources/views/Blog/detail.html.twig | 37 ++++ .../views/Blog/detailPaginated.html.twig | 11 ++ Resources/views/Blog/list.html.twig | 42 +++-- Resources/views/Blog/list_post.html.twig | 24 --- Resources/views/Blog/tags_inline.html.twig | 4 - Resources/views/Blog/view_post.html.twig | 33 ---- Resources/views/Post/detail.html.twig | 34 ++++ ...ault_layout.html.twig => layout.html.twig} | 12 +- composer.json | 9 +- 36 files changed, 913 insertions(+), 306 deletions(-) create mode 100644 Controller/BaseController.php create mode 100644 Controller/PostController.php create mode 100644 DataFixtures/PHPCR/LoadBlogData.php create mode 100644 Repository/BlogRepository.php create mode 100644 Resources/config/routing/blog_controller.xml create mode 100644 Resources/views/Blog/detail.html.twig create mode 100644 Resources/views/Blog/detailPaginated.html.twig delete mode 100644 Resources/views/Blog/list_post.html.twig delete mode 100644 Resources/views/Blog/tags_inline.html.twig delete mode 100644 Resources/views/Blog/view_post.html.twig create mode 100644 Resources/views/Post/detail.html.twig rename Resources/views/{default_layout.html.twig => layout.html.twig} (61%) diff --git a/Admin/BlogAdmin.php b/Admin/BlogAdmin.php index 4b228bb..89acfb6 100644 --- a/Admin/BlogAdmin.php +++ b/Admin/BlogAdmin.php @@ -46,6 +46,7 @@ protected function configureFormFields(FormMapper $formMapper) $formMapper ->with('dashboard.label_blog') ->add('name', 'text') + ->add('description', 'textarea') ->add('parentDocument', 'doctrine_phpcr_odm_tree', array( 'root_node' => $this->blogRoot, 'choice_list' => array(), diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index a7c3ca1..1220046 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -55,10 +55,11 @@ protected function configureFormFields(FormMapper $mapper) $mapper ->with('dashboard.label_post') ->add('title') - ->add('publicationDate', 'datetime', array( + ->add('date', 'datetime', array( 'widget' => 'single_text', )) - ->add('content', 'textarea') + ->add('bodyPreview', 'textarea') + ->add('body', 'textarea') ->add('blog', 'phpcr_document', array( 'class' => $this->blogClass, )) diff --git a/Controller/BaseController.php b/Controller/BaseController.php new file mode 100644 index 0000000..cebdaa8 --- /dev/null +++ b/Controller/BaseController.php @@ -0,0 +1,85 @@ + + */ +abstract class BaseController +{ + /** + * @var EngineInterface + */ + protected $templating; + + /** + * @var SecurityContextInterface + */ + protected $securityContext; + + /** + * @var ViewHandlerInterface + */ + protected $viewHandler; + + /** + * Constructor + * + * @param EngineInterface $templating + * @param SecurityContextInterface $securityContext + * @param ViewHandlerInterface $viewHandler + */ + public function __construct( + EngineInterface $templating, + SecurityContextInterface $securityContext, + ViewHandlerInterface $viewHandler = null + ) { + $this->templating = $templating; + $this->securityContext = $securityContext; + $this->viewHandler = $viewHandler; + } + + protected function renderResponse($contentTemplate, $params) + { + if ($this->viewHandler) { + $view = new View($params); + $view->setTemplate($contentTemplate); + return $this->viewHandler->handle($view); + } + + return $this->templating->renderResponse($contentTemplate, $params); + } + + protected function getTemplateForResponse(Request $request, $contentTemplate) + { + return str_replace( + array('{_format}', '{_locale}'), + array($request->getRequestFormat(), $request->getLocale()), + $contentTemplate + ); + } +} diff --git a/Controller/BlogController.php b/Controller/BlogController.php index eff8927..a9dd3f2 100644 --- a/Controller/BlogController.php +++ b/Controller/BlogController.php @@ -12,127 +12,97 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Controller; -use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post; +use Symfony\Cmf\Bundle\BlogBundle\Model\Blog; +use Symfony\Cmf\Bundle\BlogBundle\Repository\BlogRepository; use Symfony\Cmf\Bundle\BlogBundle\Repository\PostRepository; -use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishWorkflowChecker; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; use FOS\RestBundle\View\ViewHandlerInterface; -use FOS\RestBundle\View\View; /** * Blog Controller * * @author Daniel Leech */ -class BlogController +class BlogController extends BaseController { /** - * @var EngineInterface + * @var BlogRepository */ - protected $templating; + protected $blogRepository; /** - * @var ViewHandlerInterface - */ - protected $viewHandler; - - /** - * @var SecurityContextInterface + * @var PostRepository */ - protected $securityContext; + protected $postRepository; /** - * @var PostRepository + * @var \Knp\Component\Pager\Paginator */ - protected $postRepository; + protected $paginator; /** - * The permission to check for when doing the publish workflow check. - * - * @var string + * @var int */ - private $publishWorkflowPermission = PublishWorkflowChecker::VIEW_ATTRIBUTE; + protected $postsPerPage; public function __construct( EngineInterface $templating, - ViewHandlerInterface $viewHandler = null, SecurityContextInterface $securityContext, - PostRepository $postRepository + ViewHandlerInterface $viewHandler = null, + BlogRepository $blogRepository, + PostRepository $postRepository, + $paginator = null, + $postsPerPage = 0 ) { - $this->templating = $templating; - $this->viewHandler = $viewHandler; - $this->securityContext = $securityContext; + parent::__construct($templating, $securityContext, $viewHandler); + $this->blogRepository = $blogRepository; $this->postRepository = $postRepository; + $this->paginator = $paginator; + $this->postsPerPage = $postsPerPage; } /** - * What attribute to use in the publish workflow check. This typically - * is VIEW or VIEW_ANONYMOUS. - * - * @param string $attribute + * List blogs */ - public function setPublishWorkflowPermission($attribute) - { - $this->publishWorkflowPermission = $attribute; - } - - protected function renderResponse($contentTemplate, $params) - { - if ($this->viewHandler) { - $view = new View($params); - $view->setTemplate($contentTemplate); - return $this->viewHandler->handle($view); - } - - return $this->templating->renderResponse($contentTemplate, $params); - } - - public function viewPostAction(Post $contentDocument, $contentTemplate = null) + public function listAction(Request $request) { - $post = $contentDocument; - - if (true !== $this->securityContext->isGranted($this->publishWorkflowPermission, $post)) { - throw new NotFoundHttpException(sprintf( - 'Post "%s" is not published' - , $post->getTitle())); - } - - $contentTemplate = $contentTemplate ? : 'CmfBlogBundle:Blog:view_post.html.twig'; - - return $this->renderResponse($contentTemplate, array( - 'post' => $post, - )); + return $this->renderResponse( + $this->getTemplateForResponse($request, 'CmfBlogBundle:Blog:list.{_format}.twig'), + array( + 'blogs' => $this->blogRepository->findAll(), + ) + ); } - public function listAction(Request $request, $contentDocument, $contentTemplate = null) + /** + * Blog detail - list posts in a blog, optionally paginated + */ + public function detailAction(Request $request, Blog $contentDocument, $contentTemplate = null) { $blog = $contentDocument; - $tag = $request->get('tag', null); - // @todo: Pagination $posts = $this->postRepository->search(array( - 'tag' => $tag, - 'blog_id' => $blog->getId(), + 'blogId' => $blog->getId(), )); - $contentTemplate = $contentTemplate ?: 'CmfBlogBundle:Blog:list.{_format}.twig'; + $pager = false; + if ($this->postsPerPage) { + $pager = $posts = $this->paginator->paginate( + $posts, + $request->query->get('page', 1), + $this->postsPerPage + ); + } - // @todo: Copy and pasted from ContentBundle::ContentController - // I wonder if we can share some code between content-like - // bundles. - $contentTemplate = str_replace( - array('{_format}', '{_locale}'), - array($request->getRequestFormat(), $request->getLocale()), - $contentTemplate + $templateFilename = $pager ? 'detailPaginated' : 'detail'; + $contentTemplate = $this->getTemplateForResponse( + $request, + $contentTemplate ?: sprintf('CmfBlogBundle:Blog:%s.{_format}.twig', $templateFilename) ); - return $this->renderResponse($contentTemplate, array( - 'blog' => $blog, - 'posts' => $posts, - 'tag' => $tag - )); + return $this->renderResponse($contentTemplate, compact('blog', 'posts', 'pager')); } + } diff --git a/Controller/PostController.php b/Controller/PostController.php new file mode 100644 index 0000000..d1618f0 --- /dev/null +++ b/Controller/PostController.php @@ -0,0 +1,65 @@ + + */ +class PostController extends BaseController +{ + /** + * @var PostRepository + */ + protected $postRepository; + + public function __construct( + EngineInterface $templating, + SecurityContextInterface $securityContext, + ViewHandlerInterface $viewHandler = null, + PostRepository $postRepository + ) { + parent::__construct($templating, $securityContext, $viewHandler); + $this->postRepository = $postRepository; + } + + public function detailAction(Request $request, Post $contentDocument, $contentTemplate = null) + { + $post = $contentDocument; + + if (true !== $this->securityContext->isGranted(PublishWorkflowChecker::VIEW_ATTRIBUTE, $post)) { + throw new NotFoundHttpException(sprintf( + 'Post "%s" is not published', + $post->getTitle() + )); + } + + $contentTemplate = $this->getTemplateForResponse( + $request, + $contentTemplate ?: 'CmfBlogBundle:Post:detail.{_format}.twig' + ); + + return $this->renderResponse($contentTemplate, compact('post')); + } + +} diff --git a/DataFixtures/PHPCR/LoadBlogData.php b/DataFixtures/PHPCR/LoadBlogData.php new file mode 100644 index 0000000..f84e8cb --- /dev/null +++ b/DataFixtures/PHPCR/LoadBlogData.php @@ -0,0 +1,79 @@ +find(null, $this->getBasePath()); + + $numBlogs = 5; + $numPostsPerBlog = (2 * $this->getPostsPerPage()) + 2; // 3 pages + + $blogIdx = 0; + while ($blogIdx++ < $numBlogs) { + $blog = new Blog( + $faker->sentence(3), // name + implode("\n\n", $faker->paragraphs(3)), // description + $rootNode // parent + ); + $manager->persist($blog); + + $postIdx = 0; + while($postIdx++ < $numPostsPerBlog) { + $paragraphs = $faker->paragraphs(5); + $post = new Post( + $blog, // blog + $faker->sentence(5), // title + $paragraphs[0], // body preview + implode("\n\n", $paragraphs) // body + ); + $manager->persist($post); + } + } + $manager->flush(); + } + + protected function getPostsPerPage() + { + $postsPerPage = $this->container->getParameter('cmf_blog.pagination.posts_per_page'); + + return $postsPerPage != 0 ? $postsPerPage : 5; + } + + protected function getBasePath() + { + return $this->container->getParameter('cmf_blog.blog_basepath'); + } + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/DependencyInjection/CmfBlogExtension.php b/DependencyInjection/CmfBlogExtension.php index 9dbd3bb..807a9d5 100644 --- a/DependencyInjection/CmfBlogExtension.php +++ b/DependencyInjection/CmfBlogExtension.php @@ -45,9 +45,18 @@ public function load(array $configs, ContainerBuilder $container) $this->loadMenuIntegration($config, $loader, $container); } + if ($config['pagination']['enabled']) { + $container->setParameter($this->getAlias().'.pagination.enabled', true); + $container->setParameter($this->getAlias().'.pagination.posts_per_page', $config['pagination']['posts_per_page']); + } else { + // this parameter is used in the cmf_blog.blog_controller service definition, so + // it must be defined until it's a viable option to use the expression language instead + $container->setParameter($this->getAlias().'.pagination.posts_per_page', 0); + } + foreach ($config['class'] as $type => $classFqn) { $container->setParameter( - $param = sprintf('cmf_blog.%s_class', $type), + $param = sprintf('cmf_blog.%s.class', $type), $classFqn ); } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 2dd1436..73d1ca8 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -50,8 +50,15 @@ public function getConfigTreeBuilder() ->scalarNode('content_key')->defaultNull()->end() ->end() ->end() + ->arrayNode('pagination') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('enabled')->defaultTrue()->end() + ->scalarNode('posts_per_page')->defaultValue(10)->end() + ->end() + ->end() ->scalarNode('blog_basepath') - ->defaultValue('/cms/blog') + ->defaultValue('/cms/blogs') ->cannotBeEmpty() ->end() ->scalarNode('routing_post_controller') # unused diff --git a/Doctrine/Phpcr/Blog.php b/Doctrine/Phpcr/Blog.php index 82d31b7..76e9709 100644 --- a/Doctrine/Phpcr/Blog.php +++ b/Doctrine/Phpcr/Blog.php @@ -13,15 +13,15 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr; use Symfony\Cmf\Bundle\BlogBundle\Model\Blog as BlogModel; -use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; +use Doctrine\ODM\PHPCR\Document\Generic; /** * Blog Document * * @author Daniel Leech */ -class Blog extends BlogModel implements RouteReferrersReadInterface, RouteObjectInterface +class Blog extends BlogModel implements RouteReferrersReadInterface { /** * @var string @@ -30,6 +30,8 @@ class Blog extends BlogModel implements RouteReferrersReadInterface, RouteObject /** * Parent Document + * + * @var Generic */ protected $parent; @@ -41,6 +43,18 @@ class Blog extends BlogModel implements RouteReferrersReadInterface, RouteObject protected $routes; + /** + * Constructor + * + * @param string $name + * @param Generic $parent + */ + public function __construct($name = null, $description = null, Generic $parent = null) + { + parent::__construct($name, $description); + $this->parent = $parent; + } + /** * Get id * @@ -53,6 +67,8 @@ public function getId() /** * Get parent document + * + * @return Generic */ public function getParentDocument() { @@ -62,10 +78,10 @@ public function getParentDocument() /** * Set parent document * - * @param $parent + * @param Generic $parent * @return Blog */ - public function setParentDocument($parent) + public function setParentDocument(Generic $parent) { $this->parent = $parent; @@ -73,54 +89,12 @@ public function setParentDocument($parent) } /** - * @return \Symfony\Component\Routing\Route[] Route instances that point to this content + * Get routes that point to this content + * + * @return \Symfony\Component\Routing\Route[] */ public function getRoutes() { return $this->routes; } - - // FIXME: these getRoutes functions should probably go into a repository so classes aren't hard coded - - public function getPostsRoutes() - { - return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\PostRoute'); - } - - public function getTagRoutes() - { - return $this->getSubRoutes('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\TagRoute'); - } - - public function getSubRoutes($routeClass) - { - $subRoutes = array(); - - foreach ($this->routes as $route) { - foreach ($route->getRouteChildren() as $routeChild) - if ($routeChild instanceof $routeClass) { - $subRoutes[] = $routeChild; - } - } - - if (empty($subRoutes)) { - throw new \Exception(sprintf( - 'Could not find route of class "%s", this special route should be a child '. - 'of the blogs route.', - $routeClass - )); - } - - return $subRoutes; - } - - public function getContent() - { - return $this; - } - - public function getRouteKey() - { - return null; - } } diff --git a/Doctrine/Phpcr/Post.php b/Doctrine/Phpcr/Post.php index 1b1615f..49834b3 100644 --- a/Doctrine/Phpcr/Post.php +++ b/Doctrine/Phpcr/Post.php @@ -12,10 +12,10 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr; -use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; use Symfony\Cmf\Bundle\BlogBundle\Util\PostUtils; use Symfony\Cmf\Bundle\BlogBundle\Model\Post as PostModel; use Symfony\Cmf\Bundle\BlogBundle\Model\Blog as BlogModel; +use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; /** * Object representing a blog post. @@ -38,7 +38,7 @@ class Post extends PostModel implements RouteReferrersReadInterface */ protected $name; - // FIXME what is this cannot query shit + // FIXME investigate this cannot query note /** * READ ONLY: Post slug (cannot query directly on name field) * @@ -54,6 +54,16 @@ class Post extends PostModel implements RouteReferrersReadInterface protected $routes; + /** + * Constructor + */ + public function __construct(BlogModel $blog = null, $title = null, $bodyPreview = null, $body = null) + { + parent::__construct($blog, $title, $bodyPreview, $body); + if ($blog) $this->setParentDocument($blog); + if ($title) $this->setTitle($title); + } + /** * Get id * diff --git a/Model/Blog.php b/Model/Blog.php index e81ddad..a504906 100644 --- a/Model/Blog.php +++ b/Model/Blog.php @@ -28,6 +28,13 @@ class Blog */ protected $name; + /** + * Description of the blog + * + * @var string + */ + protected $description; + /** * Posts * @@ -39,8 +46,10 @@ class Blog /** * Constructor */ - public function __construct() + public function __construct($name = null, $description = null) { + $this->name = $name; + $this->description = $description; $this->posts = new ArrayCollection(); } @@ -67,6 +76,29 @@ public function setName($name) return $this; } + /** + * Get description + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set description + * + * @param string $description + * @return Blog + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + /** * Add post * diff --git a/Model/Post.php b/Model/Post.php index b929fa6..879fb81 100644 --- a/Model/Post.php +++ b/Model/Post.php @@ -12,7 +12,6 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Model; -use Symfony\Cmf\Bundle\BlogBundle\Util\PostUtils; use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishTimePeriodInterface; use Symfony\Cmf\Bundle\CoreBundle\PublishWorkflow\PublishableInterface; @@ -36,12 +35,17 @@ class Post implements PublishTimePeriodInterface, PublishableInterface /** * @var string */ - protected $content; + protected $bodyPreview; + + /** + * @var string + */ + protected $body; /** * @var \DateTime */ - protected $publicationDate; + protected $date; /** * @var \DateTime @@ -62,9 +66,13 @@ class Post implements PublishTimePeriodInterface, PublishableInterface /** * Constructor */ - public function __construct() + public function __construct(Blog $blog = null, $title = null, $bodyPreview = null, $body = null) { - $this->publicationDate = new \DateTime(); + $this->blog = $blog; + $this->title = $title; + $this->bodyPreview = $bodyPreview; + $this->body = $body; + $this->date = new \DateTime(); } /** @@ -114,24 +122,47 @@ public function setTitle($title) } /** - * Get the post's content + * Get body preview + * + * @return string + */ + public function getBodyPreview() + { + return $this->bodyPreview; + } + + /** + * Set body preview + * + * @param string $bodyPreview + * @return Post + */ + public function setBodyPreview($bodyPreview) + { + $this->bodyPreview = $bodyPreview; + + return $this; + } + + /** + * Get body (the post's content) * * @return string */ - public function getContent() + public function getBody() { - return $this->content; + return $this->body; } /** - * Set the post's content + * Set body (the post's content) * - * @param string $content + * @param string $body * @return Post */ - public function setContent($content) + public function setBody($body) { - $this->content = $content; + $this->body = $body; return $this; } @@ -141,20 +172,20 @@ public function setContent($content) * * @return \DateTime */ - public function getPublicationDate() + public function getDate() { - return $this->publicationDate; + return $this->date; } /** * Set publication date * - * @param \DateTime $publicationDate + * @param \DateTime $date * @return Post */ - public function setPublicationDate($publicationDate) + public function setDate($date) { - $this->publicationDate = $publicationDate; + $this->date = $date; return $this; } diff --git a/Repository/BlogRepository.php b/Repository/BlogRepository.php new file mode 100644 index 0000000..1a680f0 --- /dev/null +++ b/Repository/BlogRepository.php @@ -0,0 +1,128 @@ +resolver = $this->setDefaultOptions(new OptionsResolver()); + } + + public function setBasepath($basepath) + { + $this->basepath = $basepath; + } + + /** + * Find post by name + * + * @param string $name + * @return null|Blog + */ + public function findByName($name) + { + return $this->search(array( + 'name' => $name, + 'limit' => 1, + )); + } + + /** + * Search for posts by an array of options + * + * @param array $options + * @return Blog[] When limit is not provided or is greater than 1 + * @return Blog|null When limit is set to 1 + */ + public function search(array $options) + { + $options = $this->resolver->resolve($options); + + $qb = $this->createQueryBuilderFromOptions($options); + + if (isset($options['limit']) && $options['limit'] === 1) { + return $qb->getQuery()->getOneOrNullResult(); + } + + return $qb->getQuery()->getResult(); + } + + protected function createQueryBuilderFromOptions(array $options) + { + $qb = $this->createQueryBuilder('b'); + + // parent node + $qb->where()->descendant($this->basepath, 'b'); + + // blog name + if (isset($options['name'])) { + $qb->andWhere()->eq()->field('b.name')->literal($options['name']); + } + + // order by + $qb->orderBy()->asc()->field('b.name'); + + // limit + if (isset($options['limit'])) { + $qb->setMaxResults($options['limit']); + } + + return $qb; + } + + protected function setDefaultOptions(OptionsResolver $resolver) + { + $resolver->setOptional(array( + 'limit', + 'name', + )); + + // null types mean don't include / search by the key term + $resolver->setAllowedTypes(array( + 'name' => 'string', + 'limit' => 'int', + )); + + $resolver->setAllowedValues(array( + 'limit' => function($value) { + return $value > 0; + }, + )); + + return $resolver; + } + +} diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index b6e2e39..3172e09 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -11,31 +11,181 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Repository; + use Doctrine\ODM\PHPCR\DocumentRepository; +use Doctrine\ODM\PHPCR\Mapping\ClassMetadata; +use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post; class PostRepository extends DocumentRepository -{ - public function searchQuery($options) +{ + /** + * @var OptionsResolver + */ + protected $resolver; + + /** + * Constructor + * + * @param \Doctrine\ODM\PHPCR\DocumentManager $dm + * @param ClassMetadata $class + */ + public function __construct($dm, ClassMetadata $class) + { + parent::__construct($dm, $class); + $this->resolver = $this->setDefaultOptions(new OptionsResolver()); + } + + /** + * Find post by title + * + * @param string $title + * @return null|Post + */ + public function findByTitle($title) + { + return $this->search(array( + 'title' => $title, + 'limit' => 1, + )); + } + + /** + * Search for posts by an array of options: + * - blogId: string (required) + * - isPublishable: boolean (optional) + * - title: string (optional) + * - limit: integer (optional) + * - orderBy: array of arrays('field' => $field, 'order' => 'ASC or DESC') (optional) + * + * @param array $options + * @return Post[] When limit is not provided or is greater than 1 + * @return Post|null When limit is set to 1 + */ + public function search(array $options) { - $options = array_merge(array( - 'blog_uuid' => null, - ), $options); + $options = $this->resolver->resolve($options); + $qb = $this->createQueryBuilderFromOptions($options); + + if (isset($options['limit']) && $options['limit'] === 1) { + return $qb->getQuery()->getOneOrNullResult(); + } + + return $qb->getQuery()->getResult(); + } + + /** + * Create query builder from search options + * + * @param array $options + * @return \Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder + */ + protected function createQueryBuilderFromOptions(array $options) + { $qb = $this->createQueryBuilder('p'); - if ($options['blog_id']) { - $qb->where()->descendant($options['blog_id'], 'p'); + // parent node (blog id) + $qb->where()->descendant($options['blogId'], 'p'); + + // is published + if (isset($options['isPublishable']) && ($options['isPublishable'] !== null)) { + $qb->andWhere()->eq()->field('p.isPublishable')->literal($options['isPublishable']); + } + + // order by + if (isset($options['orderBy']['field']) && isset($options['orderBy']['order'])) { + + $field = $options['orderBy']['field']; + $sortOrder = strtolower($options['orderBy']['order']); + + $qb->orderBy()->$sortOrder()->field('p.'.$field); } - $qb->orderBy()->desc()->field('p.publicationDate'); + // limit + if (isset($options['limit'])) { + $qb->setMaxResults($options['limit']); + } - return $qb->getQuery(); + return $qb; } - public function search($options) + /** + * Set default search options + * + * @param OptionsResolver $resolver + * @return OptionsResolver + */ + protected function setDefaultOptions(OptionsResolver $resolver) { - $q = $this->searchQuery($options); - return $q->execute(); + $resolver->setDefaults(array( + 'isPublishable' => true, + 'orderBy' => array( + array( + 'field' => 'date', + 'order' => 'DESC', + ), + ), + )); + + $resolver->setRequired(array( + 'blogId', + )); + + $resolver->setOptional(array( + 'isPublishable', + 'limit', + 'title', + )); + + $resolver->setAllowedTypes(array( + 'isPublishable' => array('null', 'bool'), + 'blogId' => 'string', + 'title' => 'string', + 'limit' => 'int', + 'orderBy' => 'array', + )); + + $resolver->setAllowedValues(array( + 'limit' => function($value) { + return $value > 0; + }, + 'orderBy' => function(array $orderBys) { + + $allowedFields = array('id', 'title', 'date', 'publishStartDate', 'publishEndDate'); + $allowedOrders = array('asc', 'desc'); + + $throwIfNotFound = function ($optionName, $value, array $allowedValues, $joinBy = ', ') { + if(!in_array($value, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf('Unrecognized orderBy %s value "%s". %s must be one of %s.', + $optionName, + $value, + $optionName, + implode($joinBy, $allowedValues) + ) + ); + } + }; + + $validOrderBys = array(); + foreach ($orderBys as $orderBy) { + + if ($fieldValid = isset($orderBy['field'])) { + $throwIfNotFound('field', $orderBy['field'], $allowedFields); + } + + if ($orderByValid = isset($orderBy['order'])) { + $throwIfNotFound('order', strtolower($orderBy['order']), $allowedOrders, ' or '); + } + + $validOrderBys[] = $fieldValid && $orderByValid; + } + + return count(array_filter($validOrderBys)) == count($orderBys); + }, + )); + + return $resolver; } } diff --git a/Resources/config/admin.xml b/Resources/config/admin.xml index 9d04f94..23fc9c3 100644 --- a/Resources/config/admin.xml +++ b/Resources/config/admin.xml @@ -6,7 +6,7 @@ - + - %cmf_blog.blog_class% + %cmf_blog.blog.class% SonataAdminBundle:CRUD %cmf_blog.blog_basepath% @@ -24,7 +24,7 @@ - + - %cmf_blog.post_class% + %cmf_blog.post.class% SonataAdminBundle:CRUD - %cmf_blog.blog_class% + %cmf_blog.blog.class% diff --git a/Resources/config/cmf_routing_auto.yml b/Resources/config/cmf_routing_auto.yml index 046eff1..1ebfbf7 100644 --- a/Resources/config/cmf_routing_auto.yml +++ b/Resources/config/cmf_routing_auto.yml @@ -10,5 +10,5 @@ Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: uri_schema: /blogs/{blog}/{date}/{title} token_providers: blog: [content_method, { method: getBlog }] - date: [content_datetime, { method: getPublicationDate }] + date: [content_datetime, { method: getDate }] title: [content_method, { method: getTitle }] diff --git a/Resources/config/doctrine-phpcr/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml index 04d0a44..fa95ab8 100644 --- a/Resources/config/doctrine-phpcr/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -4,7 +4,9 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> - + @@ -12,9 +14,10 @@ - + + diff --git a/Resources/config/doctrine-phpcr/Post.phpcr.xml b/Resources/config/doctrine-phpcr/Post.phpcr.xml index e7abe15..7b49690 100644 --- a/Resources/config/doctrine-phpcr/Post.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Post.phpcr.xml @@ -4,11 +4,9 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd"> - + @@ -19,8 +17,9 @@ - - + + + diff --git a/Resources/config/menu.xml b/Resources/config/menu.xml index c5a309a..9debd89 100644 --- a/Resources/config/menu.xml +++ b/Resources/config/menu.xml @@ -10,7 +10,7 @@ %cmf_blog.content_key% - %cmf_blog.post_class% + %cmf_blog.post.class% @@ -20,4 +20,3 @@ - diff --git a/Resources/config/routing/blog_controller.xml b/Resources/config/routing/blog_controller.xml new file mode 100644 index 0000000..b57238d --- /dev/null +++ b/Resources/config/routing/blog_controller.xml @@ -0,0 +1,11 @@ + + + + + cmf_blog.blog_controller:listAction + + + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 83f0f17..68fd65d 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -4,14 +4,25 @@ Symfony\Cmf\Bundle\BlogBundle\Controller\BlogController + Symfony\Cmf\Bundle\BlogBundle\Controller\PostController - - + + + + + + %cmf_blog.pagination.posts_per_page% + + + + + + @@ -19,14 +30,17 @@ class="Doctrine\Common\Persistence\ObjectRepository" factory-service="doctrine_phpcr" factory-method="getRepository"> - %cmf_blog.blog_class% + %cmf_blog.blog.class% + + %cmf_blog.blog_basepath% + - %cmf_blog.post_class% + %cmf_blog.post.class% diff --git a/Resources/translations/CmfBlogBundle.en.xliff b/Resources/translations/CmfBlogBundle.en.xliff index 71af840..e11e0fe 100644 --- a/Resources/translations/CmfBlogBundle.en.xliff +++ b/Resources/translations/CmfBlogBundle.en.xliff @@ -47,8 +47,8 @@ Blog - - list.label_publication_date + + list.label_date Date @@ -87,13 +87,18 @@ Blog - - form.label_content - Content + + form.label_body_preview + Body Preview - - form.label_publication_date + + form.label_body + Body Content + + + + form.label_date Date diff --git a/Resources/translations/CmfBlogBundle.fr.xliff b/Resources/translations/CmfBlogBundle.fr.xliff index 14ac515..3b83108 100644 --- a/Resources/translations/CmfBlogBundle.fr.xliff +++ b/Resources/translations/CmfBlogBundle.fr.xliff @@ -47,8 +47,8 @@ Blog - - list.label_publication_date + + list.label_date Date @@ -87,13 +87,13 @@ Blog - - form.label_content + + form.label_body Contenu - - form.label_publication_date + + form.label_date Date diff --git a/Resources/translations/CmfBlogBundle.pl.xliff b/Resources/translations/CmfBlogBundle.pl.xliff index ffc315d..d837f91 100644 --- a/Resources/translations/CmfBlogBundle.pl.xliff +++ b/Resources/translations/CmfBlogBundle.pl.xliff @@ -47,8 +47,8 @@ Blog - - list.label_publication_date + + list.label_date Data @@ -87,13 +87,13 @@ Wydarzenia - - form.label_content + + form.label_body Zawartość - - form.label_publication_date + + form.label_date Data diff --git a/Resources/translations/CmfBlogBundle.ru.xliff b/Resources/translations/CmfBlogBundle.ru.xliff index 6d60475..ba018bd 100644 --- a/Resources/translations/CmfBlogBundle.ru.xliff +++ b/Resources/translations/CmfBlogBundle.ru.xliff @@ -47,8 +47,8 @@ Блог - - list.label_publication_date + + list.label_date Дата @@ -87,13 +87,13 @@ Блог - - form.label_content + + form.label_body Содержание - - form.label_publication_date + + form.label_date Дата diff --git a/Resources/translations/CmfBlogBundle.sk.xliff b/Resources/translations/CmfBlogBundle.sk.xliff index 03d4a8c..b5b68a2 100644 --- a/Resources/translations/CmfBlogBundle.sk.xliff +++ b/Resources/translations/CmfBlogBundle.sk.xliff @@ -47,8 +47,8 @@ Blog - - list.label_publication_date + + list.label_date Dátum @@ -87,13 +87,13 @@ Blog - - form.label_content + + form.label_body Obsah - - form.label_publication_date + + form.label_date Dátum diff --git a/Resources/translations/CmfBlogBundle.sl.xliff b/Resources/translations/CmfBlogBundle.sl.xliff index 89c90dd..2be0ffd 100644 --- a/Resources/translations/CmfBlogBundle.sl.xliff +++ b/Resources/translations/CmfBlogBundle.sl.xliff @@ -47,8 +47,8 @@ Blog - - list.label_publication_date + + list.label_date Datum @@ -87,13 +87,13 @@ Blog - - form.label_content + + form.label_body Vsebina - - form.label_publication_date + + form.label_date Datum diff --git a/Resources/views/Blog/detail.html.twig b/Resources/views/Blog/detail.html.twig new file mode 100644 index 0000000..9ffa7e9 --- /dev/null +++ b/Resources/views/Blog/detail.html.twig @@ -0,0 +1,37 @@ +{# CmfBlogBundle:Blog:detail.html.twig #} + +{% extends "CmfBlogBundle::layout.html.twig" %} + +{% block content %} +
+ +

{{ blog.name }}

+ +

+ {{ blog.description|nl2br|raw }} +

+ +
+ +

Posts

+ + {% for post in posts %} + +
+

+ {{ post.title }} +

+

+ Posted on {{ post.date|date('F jS, Y') }} at {{ post.date|date('H:i') }} +

+

{{ post.bodyPreview }}

+
+ + {% else %} +

No posts found.

+ {% endfor %} + +
+ +
+{% endblock %} diff --git a/Resources/views/Blog/detailPaginated.html.twig b/Resources/views/Blog/detailPaginated.html.twig new file mode 100644 index 0000000..48b6def --- /dev/null +++ b/Resources/views/Blog/detailPaginated.html.twig @@ -0,0 +1,11 @@ +{# CmfBlogBundle:Blog:detailPaginated.html.twig #} + +{% extends "CmfBlogBundle:Blog:detail.html.twig" %} + +{% block content %} + {{ parent() }} + + {% if pager.totalItemCount %} + {{ knp_pagination_render(pager) }} + {% endif %} +{% endblock %} diff --git a/Resources/views/Blog/list.html.twig b/Resources/views/Blog/list.html.twig index 817430a..9127ada 100644 --- a/Resources/views/Blog/list.html.twig +++ b/Resources/views/Blog/list.html.twig @@ -1,22 +1,28 @@ -{% extends "CmfBlogBundle::default_layout.html.twig" %} +{# CmfBlogBundle:Blog:list.html.twig #} + +{% extends "CmfBlogBundle::layout.html.twig" %} + {% block content %} -
-
- {% if tag %} -
- {# @todo: Translation #} - Showing posts with tag "{{ tag }}" +
+ +

Blogs

+ + {% for blog in blogs %} + +
+

+ {{ blog.name }} +

+ {% if blog.description %} +

+ {{ blog.description|nl2br|raw }} +

+ {% endif %}
- {% endif %} + + {% else %} +

No blogs found.

+ {% endfor %} +
-
-
-
- {% block posts %} - {% for post in posts %} - {% include "CmfBlogBundle:Blog:list_post.html.twig" %} - {% endfor %} - {% endblock %} -
-
{% endblock %} diff --git a/Resources/views/Blog/list_post.html.twig b/Resources/views/Blog/list_post.html.twig deleted file mode 100644 index c3a5480..0000000 --- a/Resources/views/Blog/list_post.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -
-
-
- {# @todo: Post routes #} - {{ post.title }} -
-
- {{ post.date.format('d-m-Y H:i:s') }} -
-
-
-
- {{ post.bodyPreview }} -
-
-
-
-
-
- {% trans from "CmfSimpleCmsBundle" %}Tagging{% endtrans %}: -
-
-
- diff --git a/Resources/views/Blog/tags_inline.html.twig b/Resources/views/Blog/tags_inline.html.twig deleted file mode 100644 index ed54d31..0000000 --- a/Resources/views/Blog/tags_inline.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{% for tag in post.tags %} - {# @todo: Tag routes #} - {{ tag }} -{% endfor %} diff --git a/Resources/views/Blog/view_post.html.twig b/Resources/views/Blog/view_post.html.twig deleted file mode 100644 index 6cb552f..0000000 --- a/Resources/views/Blog/view_post.html.twig +++ /dev/null @@ -1,33 +0,0 @@ -{% extends "CmfBlogBundle::default_layout.html.twig" %} -{% block content %} -
-
- {% if cmf_prev(post) %} - << {{ cmf_prev(post).title }} - {% endif %} -
-
- {% if cmf_next(post) %} - {{ cmf_next(post).title }} >> - {% endif %} -
-
-
-
-

{{ post.title }}

-
-
-
-
-

Posted on: {{ post.date.format('Y-m-d H:i:s') }}

-
-
-
-
-
-
- {{ post.body|nl2br|raw }} -
-
-{% endblock %} - diff --git a/Resources/views/Post/detail.html.twig b/Resources/views/Post/detail.html.twig new file mode 100644 index 0000000..eace657 --- /dev/null +++ b/Resources/views/Post/detail.html.twig @@ -0,0 +1,34 @@ +{# CmfBlogBundle:Post:detail.html.twig #} + +{% extends "CmfBlogBundle::layout.html.twig" %} + +{% block content %} +
+ +

{{ post.title }}

+ +

Posted on {{ post.date|date('F jS, Y') }} at {{ post.date|date('H:i') }}

+ +

{{ post.body|nl2br|raw }}

+ + + + +
+{% endblock %} diff --git a/Resources/views/default_layout.html.twig b/Resources/views/layout.html.twig similarity index 61% rename from Resources/views/default_layout.html.twig rename to Resources/views/layout.html.twig index 31392a5..d278088 100644 --- a/Resources/views/default_layout.html.twig +++ b/Resources/views/layout.html.twig @@ -4,13 +4,19 @@ Default Blog Layout +

Default Blog Layout

This is the default Symfony CMF Blog layout. You probably want to - override this template to integrate the blog bundle system into + override this template to integrate the blog bundle system into your website.

- {% block content %} - {% endblock %} +
+
+ {% block content %} + {% endblock %} +
+
+
diff --git a/composer.json b/composer.json index ef17776..4721e48 100644 --- a/composer.json +++ b/composer.json @@ -17,16 +17,17 @@ "symfony/framework-bundle": "~2.3", "symfony-cmf/core-bundle": "1.2.*", "symfony-cmf/routing-auto-bundle": "1.0.*", - "doctrine/phpcr-bundle": "~1.1", - "doctrine/phpcr-odm": "~1.1" + "doctrine/phpcr-bundle": "~1.2", + "doctrine/phpcr-odm": "~1.2" }, "require-dev": { "symfony-cmf/testing": "1.2.*", "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", - "symfony-cmf/core-bundle": "1.2.*" + "nelmio/alice": "~1.7.2" }, "suggest": { - "sonata-project/doctrine-phpcr-admin-bundle": "For sonata administration" + "sonata-project/doctrine-phpcr-admin-bundle": "For sonata administration", + "knplabs/knp-paginator-bundle": "To enable pagination of posts" }, "autoload": { "psr-4": { From 5c111695107e915db75cdc9d1eff62fa09b16051 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 11 Dec 2014 17:27:00 -0500 Subject: [PATCH 05/20] refactor configuration --- DataFixtures/PHPCR/LoadBlogData.php | 2 +- DependencyInjection/Configuration.php | 82 +++++++++++++++------------ Doctrine/Phpcr/Blog.php | 1 + Repository/BlogRepository.php | 4 +- Repository/PostRepository.php | 4 +- Resources/views/Blog/detail.html.twig | 6 +- Resources/views/Post/detail.html.twig | 8 ++- 7 files changed, 61 insertions(+), 46 deletions(-) diff --git a/DataFixtures/PHPCR/LoadBlogData.php b/DataFixtures/PHPCR/LoadBlogData.php index f84e8cb..c4eed1f 100644 --- a/DataFixtures/PHPCR/LoadBlogData.php +++ b/DataFixtures/PHPCR/LoadBlogData.php @@ -46,7 +46,7 @@ public function load(ObjectManager $manager) $manager->persist($blog); $postIdx = 0; - while($postIdx++ < $numPostsPerBlog) { + while ($postIdx++ < $numPostsPerBlog) { $paragraphs = $faker->paragraphs(5); $post = new Post( $blog, // blog diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 73d1ca8..15a486a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -35,61 +35,69 @@ public function getConfigTreeBuilder() $treeBuilder = new TreeBuilder(); $treeBuilder->root('cmf_blog') ->children() - ->enumNode('use_sonata_admin') - ->values(array(true, false, 'auto')) - ->defaultValue('auto') + + // admin + ->arrayNode('sonata_admin') + ->canBeEnabled() + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('enabled')->defaultTrue()->end() + ->end() ->end() + // menu ->arrayNode('integrate_menu') ->addDefaultsIfNotSet() + ->canBeEnabled() ->children() - ->enumNode('enabled') - ->values(array(true, false, 'auto')) - ->defaultValue('auto') - ->end() + ->booleanNode('enabled')->defaultTrue()->end() ->scalarNode('content_key')->defaultNull()->end() ->end() ->end() + + // pagination ->arrayNode('pagination') ->addDefaultsIfNotSet() + ->canBeEnabled() ->children() - ->scalarNode('enabled')->defaultTrue()->end() - ->scalarNode('posts_per_page')->defaultValue(10)->end() + ->booleanNode('enabled')->defaultTrue()->end() + ->scalarNode('posts_per_page')->defaultValue(5)->end() ->end() ->end() - ->scalarNode('blog_basepath') - ->defaultValue('/cms/blogs') - ->cannotBeEmpty() - ->end() - ->scalarNode('routing_post_controller') # unused - ->defaultValue('cmf_blog.blog_controller:viewPostAction') - ->end() - ->scalarNode('routing_post_prefix') # unused - ->defaultValue('posts') - ->end() - ->scalarNode('routing_tag_controller') # unused - ->defaultValue('cmf_blog.blog_controller:listAction') - ->end() - ->scalarNode('routing_tag_prefix') # unused - ->defaultValue('tag') - ->end() - ->arrayNode('class') + + // persistence + ->arrayNode('persistence') ->addDefaultsIfNotSet() ->children() - ->scalarNode('blog_admin') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\BlogAdmin') - ->end() - ->scalarNode('post_admin') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\PostAdmin') - ->end() - ->scalarNode('blog') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog') - ->end() - ->scalarNode('post') - ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post') + ->arrayNode('phpcr') + ->addDefaultsIfNotSet() + ->canBeEnabled() + ->children() + ->scalarNode('blog_basepath') + ->defaultValue('/cms/blogs')->cannotBeEmpty() + ->end() + ->arrayNode('class') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('blog_admin') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\BlogAdmin') + ->end() + ->scalarNode('post_admin') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Admin\PostAdmin') + ->end() + ->scalarNode('blog') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog') + ->end() + ->scalarNode('post') + ->defaultValue('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post') + ->end() + ->end() + ->end() + ->end() ->end() ->end() ->end() + ->end() ->end() ; diff --git a/Doctrine/Phpcr/Blog.php b/Doctrine/Phpcr/Blog.php index 76e9709..b302526 100644 --- a/Doctrine/Phpcr/Blog.php +++ b/Doctrine/Phpcr/Blog.php @@ -47,6 +47,7 @@ class Blog extends BlogModel implements RouteReferrersReadInterface * Constructor * * @param string $name + * @param string $description * @param Generic $parent */ public function __construct($name = null, $description = null, Generic $parent = null) diff --git a/Repository/BlogRepository.php b/Repository/BlogRepository.php index 1a680f0..ce50187 100644 --- a/Repository/BlogRepository.php +++ b/Repository/BlogRepository.php @@ -47,7 +47,7 @@ public function setBasepath($basepath) } /** - * Find post by name + * Find blog by name * * @param string $name * @return null|Blog @@ -61,7 +61,7 @@ public function findByName($name) } /** - * Search for posts by an array of options + * Search for blogs by an array of options * * @param array $options * @return Blog[] When limit is not provided or is greater than 1 diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index 3172e09..7b482fb 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -40,7 +40,7 @@ public function __construct($dm, ClassMetadata $class) * Find post by title * * @param string $title - * @return null|Post + * @return Post|null */ public function findByTitle($title) { @@ -53,7 +53,7 @@ public function findByTitle($title) /** * Search for posts by an array of options: * - blogId: string (required) - * - isPublishable: boolean (optional) + * - isPublishable: boolean (optional, default true) * - title: string (optional) * - limit: integer (optional) * - orderBy: array of arrays('field' => $field, 'order' => 'ASC or DESC') (optional) diff --git a/Resources/views/Blog/detail.html.twig b/Resources/views/Blog/detail.html.twig index 9ffa7e9..9797f31 100644 --- a/Resources/views/Blog/detail.html.twig +++ b/Resources/views/Blog/detail.html.twig @@ -17,14 +17,16 @@ {% for post in posts %} -
+

{{ post.title }}

Posted on {{ post.date|date('F jS, Y') }} at {{ post.date|date('H:i') }}

-

{{ post.bodyPreview }}

+

+ {{ post.bodyPreview }} +

{% else %} diff --git a/Resources/views/Post/detail.html.twig b/Resources/views/Post/detail.html.twig index eace657..f362ab6 100644 --- a/Resources/views/Post/detail.html.twig +++ b/Resources/views/Post/detail.html.twig @@ -7,9 +7,13 @@

{{ post.title }}

-

Posted on {{ post.date|date('F jS, Y') }} at {{ post.date|date('H:i') }}

+

+ Posted on {{ post.date|date('F jS, Y') }} at {{ post.date|date('H:i') }} +

-

{{ post.body|nl2br|raw }}

+

+ {{ post.body|nl2br|raw }} +

All Blog Posts From ac7955a7a102828aa04668647e31c248f468f864 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 11 Dec 2014 19:29:22 -0500 Subject: [PATCH 06/20] it helps to update the bundle extension when you change the configuration....... --- DependencyInjection/CmfBlogExtension.php | 57 +++++++++++++++--------- Resources/config/admin.xml | 10 ++--- Resources/config/cmf_routing_auto.yml | 3 -- Resources/config/doctrine-phpcr.xml | 26 +++++++++++ Resources/config/menu.xml | 2 +- Resources/config/schema/blog-1.0.xsd | 4 +- Resources/config/services.xml | 18 -------- 7 files changed, 69 insertions(+), 51 deletions(-) create mode 100644 Resources/config/doctrine-phpcr.xml diff --git a/DependencyInjection/CmfBlogExtension.php b/DependencyInjection/CmfBlogExtension.php index 807a9d5..13cac86 100644 --- a/DependencyInjection/CmfBlogExtension.php +++ b/DependencyInjection/CmfBlogExtension.php @@ -36,55 +36,56 @@ public function load(array $configs, ContainerBuilder $container) $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $loader->load('initializer-phpcr.xml'); - if ($config['use_sonata_admin']) { + if (isset($config['persistence']['phpcr'])) { + $this->loadPhpcrPersistence($config, $loader, $container); + } + + if (isset($config['sonata_admin']) && $config['sonata_admin']['enabled']) { $this->loadSonataAdmin($config, $loader, $container); } - if ($config['integrate_menu']['enabled']) { + + if (isset($config['integrate_menu']) && $config['integrate_menu']['enabled']) { $this->loadMenuIntegration($config, $loader, $container); } - if ($config['pagination']['enabled']) { - $container->setParameter($this->getAlias().'.pagination.enabled', true); - $container->setParameter($this->getAlias().'.pagination.posts_per_page', $config['pagination']['posts_per_page']); - } else { - // this parameter is used in the cmf_blog.blog_controller service definition, so - // it must be defined until it's a viable option to use the expression language instead - $container->setParameter($this->getAlias().'.pagination.posts_per_page', 0); - } + $this->loadPaginationIntegration($config, $container); + } + + protected function loadPhpcrPersistence($config, XmlFileLoader $loader, ContainerBuilder $container) + { + $container->setParameter($this->getAlias().'.blog_basepath', $config['persistence']['phpcr']['blog_basepath']); - foreach ($config['class'] as $type => $classFqn) { + foreach ($config['persistence']['phpcr']['class'] as $type => $classFqn) { $container->setParameter( - $param = sprintf('cmf_blog.%s.class', $type), + $param = sprintf('cmf_blog.phpcr.%s.class', $type), $classFqn ); } + + $loader->load('initializer-phpcr.xml'); + $loader->load('doctrine-phpcr.xml'); } - private function loadSonataAdmin($config, XmlFileLoader $loader, ContainerBuilder $container) + protected function loadSonataAdmin(array $config, XmlFileLoader $loader, ContainerBuilder $container) { $bundles = $container->getParameter('kernel.bundles'); - if ('auto' === $config['use_sonata_admin'] && !isset($bundles['SonataDoctrinePHPCRAdminBundle'])) { + if (!isset($bundles['SonataDoctrinePHPCRAdminBundle'])) { return; } $loader->load('admin.xml'); - $container->setParameter($this->getAlias() . '.blog_basepath', $config['blog_basepath']); } - private function loadMenuIntegration($config, XmlFileLoader $loader, ContainerBuilder $container) + protected function loadMenuIntegration(array $config, XmlFileLoader $loader, ContainerBuilder $container) { $bundles = $container->getParameter('kernel.bundles'); - if ('auto' === $config['integrate_menu']['enabled'] && !isset($bundles['CmfMenuBundle'])) { + if (!isset($bundles['CmfMenuBundle'])) { return; } if (empty($config['integrate_menu']['content_key'])) { if (!class_exists('Symfony\\Cmf\\Bundle\\RoutingBundle\\Routing\\DynamicRouter')) { - if ('auto' === $config['integrate_menu']) { - return; - } throw new \RuntimeException('You need to set the content_key when not using the CmfRoutingBundle DynamicRouter'); } $contentKey = DynamicRouter::CONTENT_KEY; @@ -97,6 +98,18 @@ private function loadMenuIntegration($config, XmlFileLoader $loader, ContainerBu $loader->load('menu.xml'); } + protected function loadPaginationIntegration(array $config, ContainerBuilder $container) + { + if (isset($config['pagination']) && $config['pagination']['enabled']) { + $container->setParameter($this->getAlias().'.pagination.enabled', true); + $container->setParameter($this->getAlias().'.pagination.posts_per_page', $config['pagination']['posts_per_page']); + } else { + // this parameter is used in the cmf_blog.blog_controller service definition, so + // it must be defined until it's a viable option to use the expression language instead + $container->setParameter($this->getAlias().'.pagination.posts_per_page', 0); + } + } + /** * Returns the base path for the XSD files. * @@ -109,6 +122,6 @@ public function getXsdValidationBasePath() public function getNamespace() { - return 'http://cmf.symfony.com/schema/dic/blog'; + return 'http://cmf.symfony.com/schema/dic/cmf_blog'; } } diff --git a/Resources/config/admin.xml b/Resources/config/admin.xml index 23fc9c3..b1e79c6 100644 --- a/Resources/config/admin.xml +++ b/Resources/config/admin.xml @@ -6,7 +6,7 @@ - + - %cmf_blog.blog.class% + %cmf_blog.phpcr.blog.class% SonataAdminBundle:CRUD %cmf_blog.blog_basepath% @@ -24,7 +24,7 @@ - + - %cmf_blog.post.class% + %cmf_blog.phpcr.post.class% SonataAdminBundle:CRUD - %cmf_blog.blog.class% + %cmf_blog.phpcr.blog.class% diff --git a/Resources/config/cmf_routing_auto.yml b/Resources/config/cmf_routing_auto.yml index 1ebfbf7..2e2e23a 100644 --- a/Resources/config/cmf_routing_auto.yml +++ b/Resources/config/cmf_routing_auto.yml @@ -1,8 +1,5 @@ Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: uri_schema: /blogs/{blog} -# attributes: -# defaults: -# _template: '::blog.html.twig' token_providers: blog: [content_method, { method: getName }] diff --git a/Resources/config/doctrine-phpcr.xml b/Resources/config/doctrine-phpcr.xml new file mode 100644 index 0000000..5a4c3ed --- /dev/null +++ b/Resources/config/doctrine-phpcr.xml @@ -0,0 +1,26 @@ + + + + + + %cmf_blog.phpcr.blog.class% + + %cmf_blog.blog_basepath% + + + + + %cmf_blog.phpcr.post.class% + + + + + diff --git a/Resources/config/menu.xml b/Resources/config/menu.xml index 9debd89..5481d24 100644 --- a/Resources/config/menu.xml +++ b/Resources/config/menu.xml @@ -10,7 +10,7 @@ %cmf_blog.content_key% - %cmf_blog.post.class% + %cmf_blog.phpcr.post.class% diff --git a/Resources/config/schema/blog-1.0.xsd b/Resources/config/schema/blog-1.0.xsd index ecfc8e7..3436d04 100644 --- a/Resources/config/schema/blog-1.0.xsd +++ b/Resources/config/schema/blog-1.0.xsd @@ -1,8 +1,8 @@ - diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 68fd65d..870f8e3 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -26,24 +26,6 @@ - - %cmf_blog.blog.class% - - %cmf_blog.blog_basepath% - - - - - %cmf_blog.post.class% - - - From 948cb7c35946c1ffdb034441c9fcc568092d881a Mon Sep 17 00:00:00 2001 From: Brian Cappello Date: Fri, 12 Dec 2014 16:03:59 -0500 Subject: [PATCH 07/20] remove everything tag related --- .gitignore | 4 +- Admin/PostAdmin.php | 13 ---- Block/TagCloudBlock.php | 62 ---------------- Controller/BlogController.php | 1 - Controller/PostController.php | 1 - Doctrine/Phpcr/Post.php | 11 ++- Doctrine/Phpcr/TagRoute.php | 25 ------- .../DataTransformer/CsvToArrayTransformer.php | 71 ------------------- Repository/PostRepository.php | 30 ++------ .../config/doctrine-phpcr/TagRoute.phpcr.xml | 12 ---- Resources/views/Admin/list_tags.html.twig | 1 - Tagging/DoctrineORMStrategy.php | 36 ---------- Tagging/PHPCRStringStrategy.php | 59 --------------- Tagging/StrategyInterface.php | 60 ---------------- Tagging/Tag.php | 39 ---------- Tests/Functional/Admin/BlogAdminTest.php | 2 +- Tests/Resources/app/config/blogbundle.yml | 5 +- Tests/Resources/app/config/config.php | 2 +- .../CsvToArrayTransformerTest.php | 40 ----------- Tests/Unit/Tagging/TagTest.php | 31 -------- composer.json | 1 + 21 files changed, 25 insertions(+), 481 deletions(-) delete mode 100644 Block/TagCloudBlock.php delete mode 100644 Doctrine/Phpcr/TagRoute.php delete mode 100644 Form/DataTransformer/CsvToArrayTransformer.php delete mode 100644 Resources/config/doctrine-phpcr/TagRoute.phpcr.xml delete mode 100644 Resources/views/Admin/list_tags.html.twig delete mode 100644 Tagging/DoctrineORMStrategy.php delete mode 100644 Tagging/PHPCRStringStrategy.php delete mode 100644 Tagging/StrategyInterface.php delete mode 100644 Tagging/Tag.php delete mode 100644 Tests/Unit/Form/DataTransformer/CsvToArrayTransformerTest.php delete mode 100644 Tests/Unit/Tagging/TagTest.php diff --git a/.gitignore b/.gitignore index 26ad278..acfaf23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ Tests/Resources/app/cache Tests/Resources/app/logs +bin/ composer.lock -vendor +vendor/ + diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index 1220046..098bf91 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -17,7 +17,6 @@ use Sonata\AdminBundle\Validator\ErrorElement; use Sonata\AdminBundle\Form\FormMapper; use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin; -use Symfony\Cmf\Bundle\BlogBundle\Form\DataTransformer\CsvToArrayTransformer; /** * Post Admin @@ -45,13 +44,6 @@ public function __construct($code, $class, $baseControllerName, $blogClass) protected function configureFormFields(FormMapper $mapper) { - // @todo: I think this would be better as a service, - // but I don't know how integrate the form - // AND have all the Sonata magic from the - // FormMapper->add method. - - // $csvToArrayTransformer = new CsvToArrayTransformer; - $mapper ->with('dashboard.label_post') ->add('title') @@ -65,11 +57,6 @@ protected function configureFormFields(FormMapper $mapper) )) ->end() ; - - //$tags = $mapper->create('tags', 'text') - // ->addModelTransformer($csvToArrayTransformer); - - // $mapper->add($tags); } protected function configureDatagridFilters(DatagridMapper $dm) diff --git a/Block/TagCloudBlock.php b/Block/TagCloudBlock.php deleted file mode 100644 index 76607e8..0000000 --- a/Block/TagCloudBlock.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ -class TagCloudBlockService extends BaseBlockService -{ - protected $repo; - - public function __construct($name, EngineInterface $templating, TagRepository $repo) - { - $this->repo = $repo; - parent::__construct($name, $templating); - } - - public function getDefaultSettings() - { - return array( - 'path' => 'cmf_blog_post_index' - ); - } - - public function buildEditForm(FormMapper $fm, BlockInterface $block) - { - } - - public function validateBlock(ErrorElement $errorElement, BlockInterface $block) - { - } - - public function execute(BlockInterface $block, Response $response = null) - { - $wTags = $this->repo->getWeightedTags(); - return $this->renderResponse('CmfBlogBundle:Block:tagCloud.html.twig', array( - 'block' => $block, - 'wTags' => $wTags - )); - } -} diff --git a/Controller/BlogController.php b/Controller/BlogController.php index a9dd3f2..c2d9189 100644 --- a/Controller/BlogController.php +++ b/Controller/BlogController.php @@ -104,5 +104,4 @@ public function detailAction(Request $request, Blog $contentDocument, $contentTe return $this->renderResponse($contentTemplate, compact('blog', 'posts', 'pager')); } - } diff --git a/Controller/PostController.php b/Controller/PostController.php index d1618f0..c5c16e0 100644 --- a/Controller/PostController.php +++ b/Controller/PostController.php @@ -61,5 +61,4 @@ public function detailAction(Request $request, Post $contentDocument, $contentTe return $this->renderResponse($contentTemplate, compact('post')); } - } diff --git a/Doctrine/Phpcr/Post.php b/Doctrine/Phpcr/Post.php index 49834b3..3d1269f 100644 --- a/Doctrine/Phpcr/Post.php +++ b/Doctrine/Phpcr/Post.php @@ -53,15 +53,20 @@ class Post extends PostModel implements RouteReferrersReadInterface */ protected $routes; - /** * Constructor */ public function __construct(BlogModel $blog = null, $title = null, $bodyPreview = null, $body = null) { parent::__construct($blog, $title, $bodyPreview, $body); - if ($blog) $this->setParentDocument($blog); - if ($title) $this->setTitle($title); + + if ($blog) { + $this->setParentDocument($blog); + } + + if ($title) { + $this->setTitle($title); + } } /** diff --git a/Doctrine/Phpcr/TagRoute.php b/Doctrine/Phpcr/TagRoute.php deleted file mode 100644 index 409f262..0000000 --- a/Doctrine/Phpcr/TagRoute.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ -class TagRoute extends Route -{ -} diff --git a/Form/DataTransformer/CsvToArrayTransformer.php b/Form/DataTransformer/CsvToArrayTransformer.php deleted file mode 100644 index 9860ea6..0000000 --- a/Form/DataTransformer/CsvToArrayTransformer.php +++ /dev/null @@ -1,71 +0,0 @@ - - */ -class CsvToArrayTransformer implements DataTransformerInterface -{ - /** - * Transforms an array of values to a comma - * separated string. - * - * @param array $value - * - * @return string - */ - public function transform($value) - { - if ($value) { - - // trim all the values - $value = array_map('trim', $value); - - // join together - $string = implode(',', $value); - - return $string; - } - } - - /** - * Transforms a CSV string into an array. - * - * @param string $value - * - * @return array - */ - public function reverseTransform($value) - { - if ($value) { - - // string to array - $array = explode(',', $value); - - // trim all the values - $array = array_map('trim', $array); - - return $array; - } - } -} - - diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index 7b482fb..0d87402 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -151,35 +151,19 @@ protected function setDefaultOptions(OptionsResolver $resolver) return $value > 0; }, 'orderBy' => function(array $orderBys) { - - $allowedFields = array('id', 'title', 'date', 'publishStartDate', 'publishEndDate'); - $allowedOrders = array('asc', 'desc'); - - $throwIfNotFound = function ($optionName, $value, array $allowedValues, $joinBy = ', ') { - if(!in_array($value, $allowedValues, true)) { - throw new \InvalidArgumentException( - sprintf('Unrecognized orderBy %s value "%s". %s must be one of %s.', - $optionName, - $value, - $optionName, - implode($joinBy, $allowedValues) - ) - ); - } - }; - $validOrderBys = array(); foreach ($orderBys as $orderBy) { - if ($fieldValid = isset($orderBy['field'])) { - $throwIfNotFound('field', $orderBy['field'], $allowedFields); - } - if ($orderByValid = isset($orderBy['order'])) { - $throwIfNotFound('order', strtolower($orderBy['order']), $allowedOrders, ' or '); + if(!in_array(strtolower($orderBy['order']), array('asc', 'desc'), true)) { + throw new \InvalidArgumentException(sprintf( + 'Unrecognized orderBy order value "%s". order must be one of ASC or DESC.', + $orderBy['order'] + )); + } } - $validOrderBys[] = $fieldValid && $orderByValid; + $validOrderBys[] = isset($orderBy['field']) && $orderByValid; } return count(array_filter($validOrderBys)) == count($orderBys); diff --git a/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml b/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml deleted file mode 100644 index 4e43ffe..0000000 --- a/Resources/config/doctrine-phpcr/TagRoute.phpcr.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/Resources/views/Admin/list_tags.html.twig b/Resources/views/Admin/list_tags.html.twig deleted file mode 100644 index d96beb0..0000000 --- a/Resources/views/Admin/list_tags.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ object.tags|join(',') }} diff --git a/Tagging/DoctrineORMStrategy.php b/Tagging/DoctrineORMStrategy.php deleted file mode 100644 index 9c886aa..0000000 --- a/Tagging/DoctrineORMStrategy.php +++ /dev/null @@ -1,36 +0,0 @@ - - */ -class DoctrineORMStrategy implements StrategyInterface -{ - public function getWeightedTags($blogId) - { - // select aggregated tag counts... - // @todo. - } - - public function updateTags(Post $post) - { - foreach ($post->getTags() as $tag) { - // todo - } - } -} diff --git a/Tagging/PHPCRStringStrategy.php b/Tagging/PHPCRStringStrategy.php deleted file mode 100644 index d4bdc84..0000000 --- a/Tagging/PHPCRStringStrategy.php +++ /dev/null @@ -1,59 +0,0 @@ - - */ -class PHPCRStringStrategy implements StrategyInterface -{ - /** - * {@inheritDoc} - */ - public function getWeightedTags($blogId) - { - $qb = $this->postRep->createQueryBuilder('a'); - $qb->select('tags'); - $qb->where()->descendant($blogId, 'a'); // select only children of given blog - $q = $qb->getQuery(); - $res = $q->getPhpcrNodeResult(); - $rows = $res->getRows(); - $weightedTags = array(); - - $max = 0; - foreach ($rows as $row) { - $tag = $row->getValue('tags'); - if (!isset($weightedTags[$tag])) { - $weightedTags[$tag] = array( - 'count' => 0, - ); - } - - $weightedTags[$tag]['count']++; - - if ($weightedTags[$tag]['count'] > $max) { - $max = $weightedTags[$tag]['count']; - } - } - - foreach ($weightedTags as $name => &$tag) { - $tag['weight'] = $tag['count'] / $max; - } - - return $weightedTags; - } -} diff --git a/Tagging/StrategyInterface.php b/Tagging/StrategyInterface.php deleted file mode 100644 index 6297b26..0000000 --- a/Tagging/StrategyInterface.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ -interface StrategyInterface -{ - /** - * Return an associative array of tags as: - * - * array( - * 'symfony' => array( - * 'count' => 123 - * 'weight' => 0.6 - * ), - * 'php' => array( - * 'count' => 100 - * 'weight' => 0.4 - * ), - * // etc. - * ) - * - * The weight is a floating point number between - * 0 and 1 and represents the relative weight of the - * tag within the set. It is calculated as: - * - * (tag count sum) / (highest individual tag count sum) - * - * @param string $blogId - ID of blog, e.g. /content/blogs/my-blog - * - * @return array - */ - public function getWeightedTags($blogId); - - /** - * Give the strategy the chance to update its database - * of tags. - * - * @param Post $post - Blog post - */ - public function updateTags(Post $post); -} diff --git a/Tagging/Tag.php b/Tagging/Tag.php deleted file mode 100644 index d97a5d6..0000000 --- a/Tagging/Tag.php +++ /dev/null @@ -1,39 +0,0 @@ -name = $name; - $this->blog = $blog; - } - - public function getRoutes() - { - return array(); - } - - public function __toString() - { - return (string)$this->name; - } -} - diff --git a/Tests/Functional/Admin/BlogAdminTest.php b/Tests/Functional/Admin/BlogAdminTest.php index f01dc42..101f39d 100644 --- a/Tests/Functional/Admin/BlogAdminTest.php +++ b/Tests/Functional/Admin/BlogAdminTest.php @@ -16,7 +16,7 @@ class BlogAdminTest extends BaseTestCase { - public function testList() + public function testDashboard() { $client = $this->createClient(); diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index a5188f8..2591b93 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -1,2 +1,5 @@ cmf_blog: - blog_basepath: /cms/content + sonata_admin: ~ + persistence: + phpcr: + blog_basepath: /cms/content diff --git a/Tests/Resources/app/config/config.php b/Tests/Resources/app/config/config.php index 2b8e6cb..a6d3d98 100644 --- a/Tests/Resources/app/config/config.php +++ b/Tests/Resources/app/config/config.php @@ -1,6 +1,6 @@ setParameter('cmf_testing.bundle_fqn', 'Symfony\Cmf\Bundle\BlogBundle'); $loader->import(CMF_TEST_CONFIG_DIR.'/default.php'); $loader->import(CMF_TEST_CONFIG_DIR.'/phpcr_odm.php'); $loader->import(CMF_TEST_CONFIG_DIR.'/sonata_admin.php'); diff --git a/Tests/Unit/Form/DataTransformer/CsvToArrayTransformerTest.php b/Tests/Unit/Form/DataTransformer/CsvToArrayTransformerTest.php deleted file mode 100644 index b16ed94..0000000 --- a/Tests/Unit/Form/DataTransformer/CsvToArrayTransformerTest.php +++ /dev/null @@ -1,40 +0,0 @@ -transformer = new CsvToArrayTransformer; - } - - public function testTransform() - { - $v = array('one', 'two', 'three ', 'four five'); - $res = $this->transformer->transform($v); - - $this->assertEquals('one,two,three,four five', $res); - } - - public function testReverseTransform() - { - $v = ' one, one, two, three , four five '; - $res = $this->transformer->reverseTransform($v); - - $expected = array('one', 'one', 'two', 'three', 'four five'); - $this->assertEquals($expected, $res); - } -} diff --git a/Tests/Unit/Tagging/TagTest.php b/Tests/Unit/Tagging/TagTest.php deleted file mode 100644 index c8dea7d..0000000 --- a/Tests/Unit/Tagging/TagTest.php +++ /dev/null @@ -1,31 +0,0 @@ -getMock('Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog'); - $this->tag = new Tag($blog, 'foo'); - } - - public function testTag() - { - $this->assertEquals('foo', (string) $this->tag); - } -} diff --git a/composer.json b/composer.json index 4721e48..11ded23 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "doctrine/phpcr-odm": "~1.2" }, "require-dev": { + "phpunit/phpunit": "~3.7.28", "symfony-cmf/testing": "1.2.*", "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", "nelmio/alice": "~1.7.2" From 59aec765da408f1539833070cfd0fbd95ef36fa7 Mon Sep 17 00:00:00 2001 From: Brian Cappello Date: Fri, 12 Dec 2014 16:08:34 -0500 Subject: [PATCH 08/20] style consistency --- Admin/PostAdmin.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index 098bf91..895b076 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -42,9 +42,9 @@ public function __construct($code, $class, $baseControllerName, $blogClass) $this->blogClass = $blogClass; } - protected function configureFormFields(FormMapper $mapper) + protected function configureFormFields(FormMapper $formMapper) { - $mapper + $formMapper ->with('dashboard.label_post') ->add('title') ->add('date', 'datetime', array( @@ -59,16 +59,20 @@ protected function configureFormFields(FormMapper $mapper) ; } - protected function configureDatagridFilters(DatagridMapper $dm) + protected function configureDatagridFilters(DatagridMapper $filterMapper) { - $dm->add('title', 'doctrine_phpcr_string'); + $filterMapper + ->add('title', 'doctrine_phpcr_string') + ; } - protected function configureListFields(ListMapper $dm) + protected function configureListFields(ListMapper $listMapper) { - $dm->add('blog'); - $dm->add('date', 'datetime'); - $dm->addIdentifier('title'); + $listMapper + ->addIdentifier('title') + ->add('blog') + ->add('date', 'datetime') + ; } } From 2d125037c4e529d3aaf841af3e836a29d5662907 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 22 Dec 2014 12:09:26 -0500 Subject: [PATCH 09/20] add test for blog admin create action --- .gitignore | 3 +- Doctrine/Phpcr/Blog.php | 22 +-- Doctrine/Phpcr/Post.php | 16 --- Model/Blog.php | 5 +- Model/Post.php | 7 +- .../config/doctrine-phpcr/Blog.phpcr.xml | 2 +- Tests/Functional/Admin/BlogAdminTest.php | 24 +++- Tests/Functional/BaseTestCase.php | 129 ++++++++++++++++++ .../DataFixtures}/PHPCR/LoadBlogData.php | 24 ++-- Tests/Resources/app/AppKernel.php | 2 + Tests/Resources/app/config/blogbundle.yml | 34 ++++- Tests/Resources/app/console | 1 + composer.json | 4 + 13 files changed, 208 insertions(+), 65 deletions(-) create mode 100644 Tests/Functional/BaseTestCase.php rename {DataFixtures => Tests/Resources/DataFixtures}/PHPCR/LoadBlogData.php (74%) create mode 120000 Tests/Resources/app/console diff --git a/.gitignore b/.gitignore index acfaf23..c790d14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ Tests/Resources/app/cache Tests/Resources/app/logs +Tests/Resources/test_db.sqlite bin/ composer.lock vendor/ - +.idea diff --git a/Doctrine/Phpcr/Blog.php b/Doctrine/Phpcr/Blog.php index b302526..dd96b23 100644 --- a/Doctrine/Phpcr/Blog.php +++ b/Doctrine/Phpcr/Blog.php @@ -33,7 +33,7 @@ class Blog extends BlogModel implements RouteReferrersReadInterface * * @var Generic */ - protected $parent; + protected $parentDocument; /** * Routes (mapped from Route::content) @@ -42,20 +42,6 @@ class Blog extends BlogModel implements RouteReferrersReadInterface */ protected $routes; - - /** - * Constructor - * - * @param string $name - * @param string $description - * @param Generic $parent - */ - public function __construct($name = null, $description = null, Generic $parent = null) - { - parent::__construct($name, $description); - $this->parent = $parent; - } - /** * Get id * @@ -73,7 +59,7 @@ public function getId() */ public function getParentDocument() { - return $this->parent; + return $this->parentDocument; } /** @@ -82,9 +68,9 @@ public function getParentDocument() * @param Generic $parent * @return Blog */ - public function setParentDocument(Generic $parent) + public function setParentDocument(Generic $parentDocument) { - $this->parent = $parent; + $this->parentDocument = $parentDocument; return $this; } diff --git a/Doctrine/Phpcr/Post.php b/Doctrine/Phpcr/Post.php index 3d1269f..ef3649c 100644 --- a/Doctrine/Phpcr/Post.php +++ b/Doctrine/Phpcr/Post.php @@ -53,22 +53,6 @@ class Post extends PostModel implements RouteReferrersReadInterface */ protected $routes; - /** - * Constructor - */ - public function __construct(BlogModel $blog = null, $title = null, $bodyPreview = null, $body = null) - { - parent::__construct($blog, $title, $bodyPreview, $body); - - if ($blog) { - $this->setParentDocument($blog); - } - - if ($title) { - $this->setTitle($title); - } - } - /** * Get id * diff --git a/Model/Blog.php b/Model/Blog.php index a504906..1e61e7d 100644 --- a/Model/Blog.php +++ b/Model/Blog.php @@ -42,14 +42,11 @@ class Blog */ protected $posts; - /** * Constructor */ - public function __construct($name = null, $description = null) + public function __construct() { - $this->name = $name; - $this->description = $description; $this->posts = new ArrayCollection(); } diff --git a/Model/Post.php b/Model/Post.php index 879fb81..cda3a8d 100644 --- a/Model/Post.php +++ b/Model/Post.php @@ -62,16 +62,11 @@ class Post implements PublishTimePeriodInterface, PublishableInterface */ protected $isPublishable = true; - /** * Constructor */ - public function __construct(Blog $blog = null, $title = null, $bodyPreview = null, $body = null) + public function __construct() { - $this->blog = $blog; - $this->title = $title; - $this->bodyPreview = $bodyPreview; - $this->body = $body; $this->date = new \DateTime(); } diff --git a/Resources/config/doctrine-phpcr/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml index fa95ab8..92f9798 100644 --- a/Resources/config/doctrine-phpcr/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -13,7 +13,7 @@ - + diff --git a/Tests/Functional/Admin/BlogAdminTest.php b/Tests/Functional/Admin/BlogAdminTest.php index 101f39d..3a04b47 100644 --- a/Tests/Functional/Admin/BlogAdminTest.php +++ b/Tests/Functional/Admin/BlogAdminTest.php @@ -12,16 +12,28 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Tests\Functional\Admin; -use Symfony\Cmf\Component\Testing\Functional\BaseTestCase; +use Symfony\Cmf\Bundle\BlogBundle\Tests\Functional\BaseTestCase; class BlogAdminTest extends BaseTestCase { - public function testDashboard() + public function testCreate() { - $client = $this->createClient(); + $crawler = $this->requestRoute('GET', 'admin_cmf_blog_blog_create'); - $client->request('GET', '/admin/dashboard'); - $response = $client->getResponse(); - $this->assertEquals(200, $response->getStatusCode()); + $form = $crawler->selectButton('Create')->form(); + $formPrefix = $this->getAdminFormNamePrefix($crawler); + + $form->setValues(array( + $formPrefix.'[name]' => 'Test Blog', + $formPrefix.'[description]' => 'A blog lives here.', + $formPrefix.'[parentDocument]' => '/cms/test', + )); + + $this->client->followRedirects(); + $crawler = $this->client->submit($form); + + $this->assertCount(1, $crawler->filter("html:contains('has been successfully created')"), + 'Expected a success flash message, but none was found.' + ); } } diff --git a/Tests/Functional/BaseTestCase.php b/Tests/Functional/BaseTestCase.php new file mode 100644 index 0000000..bd76fcc --- /dev/null +++ b/Tests/Functional/BaseTestCase.php @@ -0,0 +1,129 @@ +client = $this->createClient($this->getKernelConfiguration()); + + $this->application = new Application($this->client->getKernel()); + $this->application->setAutoExit(false); + + $this->router = $this->client->getContainer()->get('router'); + + $this->runConsole('doctrine:database:drop', array('--force' => true)); + $this->runConsole('doctrine:database:create'); + + $this->runConsole('doctrine:phpcr:init:dbal'); + $this->runConsole('doctrine:phpcr:repo:init'); + $this->runConsole('doctrine:phpcr:fixtures:load', array( + '--fixtures' => __DIR__.'/../Resources/DataFixtures/PHPCR', + '--no-interaction' => true, + )); + + } + + /** + * @param string $serviceId + * @return object + */ + protected function get($serviceId) + { + return $this->client->getContainer()->get($serviceId); + } + + /** + * @param string $parameter + * @return mixed + */ + protected function getParameter($parameter) + { + return $this->client->getContainer()->getParameter($parameter); + } + + /** + * @param string $method + * @param string $url + * @return \Symfony\Component\DomCrawler\Crawler + */ + protected function request($method, $url) + { + return $this->client->request($method, $url); + } + + /** + * @param string $method + * @param string $route + * @param array $parameters + * @return \Symfony\Component\DomCrawler\Crawler + */ + protected function requestRoute($method, $route, array $parameters = array()) + { + return $this->request( + $method, + $this->router->generate($route, $parameters) + ); + } + + /** + * Returns the unique ID Sonata Admins use to prefix form fields + * + * @param \Symfony\Component\DomCrawler\Crawler $crawler + * @param string $filter + * @return string + */ + protected function getAdminFormNamePrefix(\Symfony\Component\DomCrawler\Crawler $crawler, $filter = 'input[type=text]') + { + $parts = explode('_', $crawler->filter($filter)->first()->attr('id')); + + return $parts[0]; + } + + /** + * @param string $command + * @param array $options + * @return int + */ + protected function runConsole($command, array $options = array()) + { + $options['-e'] = 'test'; // test environment +// $options['-q'] = null; // suppress the command's output + $options['command'] = $command; + + return $this->application->run(new ArrayInput($options)); + } +} diff --git a/DataFixtures/PHPCR/LoadBlogData.php b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php similarity index 74% rename from DataFixtures/PHPCR/LoadBlogData.php rename to Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php index c4eed1f..aab65e3 100644 --- a/DataFixtures/PHPCR/LoadBlogData.php +++ b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php @@ -10,7 +10,7 @@ */ -namespace Symfony\Cmf\Bundle\BlogBundle\DataFixtures\PHPCR; +namespace Symfony\Cmf\Bundle\BlogBundle\Tests\Resources\DataFixtures\PHPCR; use Doctrine\Common\DataFixtures\FixtureInterface; use Doctrine\Common\Persistence\ObjectManager; @@ -38,22 +38,22 @@ public function load(ObjectManager $manager) $blogIdx = 0; while ($blogIdx++ < $numBlogs) { - $blog = new Blog( - $faker->sentence(3), // name - implode("\n\n", $faker->paragraphs(3)), // description - $rootNode // parent - ); + $blog = new Blog(); + $blog->setName($faker->sentence(3)); + $blog->setDescription(implode("\n\n", $faker->paragraphs(3))); + $blog->setParentDocument($rootNode); + $manager->persist($blog); $postIdx = 0; while ($postIdx++ < $numPostsPerBlog) { $paragraphs = $faker->paragraphs(5); - $post = new Post( - $blog, // blog - $faker->sentence(5), // title - $paragraphs[0], // body preview - implode("\n\n", $paragraphs) // body - ); + $post = new Post(); + $post->setBlog($blog); + $post->setTitle($faker->sentence(5)); + $post->setBodyPreview($paragraphs[0]); + $post->setBody(implode("\n\n", $paragraphs)); + $manager->persist($post); } } diff --git a/Tests/Resources/app/AppKernel.php b/Tests/Resources/app/AppKernel.php index 1739c6a..a8cfe02 100644 --- a/Tests/Resources/app/AppKernel.php +++ b/Tests/Resources/app/AppKernel.php @@ -15,6 +15,8 @@ public function configure() $this->addBundles(array( new \Symfony\Cmf\Bundle\CoreBundle\CmfCoreBundle(), + new \Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(), + new \Symfony\Cmf\Bundle\RoutingAutoBundle\CmfRoutingAutoBundle(), new \Symfony\Cmf\Bundle\BlogBundle\CmfBlogBundle(), )); } diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index 2591b93..0305186 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -1,5 +1,37 @@ +parameters: + phpcr_basepath: /cms/test + +doctrine: + dbal: + driver: pdo_sqlite + path: %kernel.root_dir%/../test_db.sqlite + memory: true + types: + json: Sonata\Doctrine\Types\JsonType + +doctrine_phpcr: + odm: + auto_generate_proxy_classes: true + cmf_blog: sonata_admin: ~ persistence: phpcr: - blog_basepath: /cms/content + blog_basepath: /cms/test + +cmf_routing: + chain: + routers_by_id: + router.default: 100 + cmf_routing.dynamic_router: 20 + dynamic: + persistence: + phpcr: + admin_basepath: %phpcr_basepath% + route_basepaths: [%phpcr_basepath%] + content_basepath: %phpcr_basepath% + +cmf_routing_auto: + persistence: + phpcr: + route_basepath: /cms/routes diff --git a/Tests/Resources/app/console b/Tests/Resources/app/console new file mode 120000 index 0000000..4134a52 --- /dev/null +++ b/Tests/Resources/app/console @@ -0,0 +1 @@ +../../../vendor/symfony-cmf/testing/bin/console \ No newline at end of file diff --git a/composer.json b/composer.json index 11ded23..c6dfa1a 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "symfony/framework-bundle": "~2.3", "symfony-cmf/core-bundle": "1.2.*", "symfony-cmf/routing-auto-bundle": "1.0.*", + "sonata-project/doctrine-extensions": "~1.0.2", "doctrine/phpcr-bundle": "~1.2", "doctrine/phpcr-odm": "~1.2" }, @@ -35,6 +36,9 @@ "Symfony\\Cmf\\Bundle\\BlogBundle\\": "" } }, + "config": { + "bin-dir": "bin" + }, "extra": { "branch-alias": { "dev-master": "1.0-dev" From 623798d60d30609a74a657002d76a8c90ff506de Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 22 Dec 2014 15:27:06 -0500 Subject: [PATCH 10/20] more tests --- Admin/PostAdmin.php | 2 - Doctrine/Phpcr/Blog.php | 30 ++++++++++++- Doctrine/Phpcr/Post.php | 45 ++----------------- .../config/doctrine-phpcr/Blog.phpcr.xml | 2 +- .../config/doctrine-phpcr/Post.phpcr.xml | 5 +-- Tests/Functional/Admin/BlogAdminTest.php | 42 ++++++++++++++++- Tests/Functional/Admin/PostAdminTest.php | 30 +++++++++++++ Tests/Functional/BaseTestCase.php | 2 +- Tests/Functional/BlogControllerTest.php | 13 ++++++ .../DataFixtures/PHPCR/LoadBlogData.php | 11 +++-- Tests/Resources/app/config/blogbundle.yml | 4 +- Tests/Resources/app/config/routing.php | 4 +- Tests/Resources/app/config/routing.yml | 2 + composer.json | 3 +- 14 files changed, 137 insertions(+), 58 deletions(-) create mode 100644 Tests/Functional/Admin/PostAdminTest.php create mode 100644 Tests/Functional/BlogControllerTest.php create mode 100644 Tests/Resources/app/config/routing.yml diff --git a/Admin/PostAdmin.php b/Admin/PostAdmin.php index 895b076..64c4e26 100644 --- a/Admin/PostAdmin.php +++ b/Admin/PostAdmin.php @@ -14,7 +14,6 @@ use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; -use Sonata\AdminBundle\Validator\ErrorElement; use Sonata\AdminBundle\Form\FormMapper; use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin; @@ -74,5 +73,4 @@ protected function configureListFields(ListMapper $listMapper) ->add('date', 'datetime') ; } - } diff --git a/Doctrine/Phpcr/Blog.php b/Doctrine/Phpcr/Blog.php index dd96b23..f846c79 100644 --- a/Doctrine/Phpcr/Blog.php +++ b/Doctrine/Phpcr/Blog.php @@ -13,6 +13,7 @@ namespace Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr; use Symfony\Cmf\Bundle\BlogBundle\Model\Blog as BlogModel; +use Symfony\Cmf\Bundle\BlogBundle\Util\PostUtils; use Symfony\Cmf\Component\Routing\RouteReferrersReadInterface; use Doctrine\ODM\PHPCR\Document\Generic; @@ -28,6 +29,11 @@ class Blog extends BlogModel implements RouteReferrersReadInterface */ protected $id; + /** + * @var string + */ + protected $slug; + /** * Parent Document * @@ -52,6 +58,16 @@ public function getId() return $this->id; } + /** + * Get slug + * + * @return string + */ + public function getSlug() + { + return $this->slug; + } + /** * Get parent document * @@ -65,7 +81,7 @@ public function getParentDocument() /** * Set parent document * - * @param Generic $parent + * @param Generic $parentDocument * @return Blog */ public function setParentDocument(Generic $parentDocument) @@ -84,4 +100,16 @@ public function getRoutes() { return $this->routes; } + + /** + * {@inheritDoc} + */ + public function setName($name) + { + parent::setName($name); + + $this->slug = PostUtils::slugify($name); + + return $this; + } } diff --git a/Doctrine/Phpcr/Post.php b/Doctrine/Phpcr/Post.php index ef3649c..417d232 100644 --- a/Doctrine/Phpcr/Post.php +++ b/Doctrine/Phpcr/Post.php @@ -25,23 +25,11 @@ class Post extends PostModel implements RouteReferrersReadInterface { /** - * ID / Path to to this object - * * @var string */ protected $id; /** - * Node name (same as slug) - * - * @var string - */ - protected $name; - - // FIXME investigate this cannot query note - /** - * READ ONLY: Post slug (cannot query directly on name field) - * * @var string */ protected $slug; @@ -64,13 +52,13 @@ public function getId() } /** - * Get name + * Get slug * * @return string */ - public function getName() + public function getSlug() { - return $this->name; + return $this->slug; } /** @@ -80,22 +68,11 @@ public function setTitle($title) { parent::setTitle($title); - $this->name = PostUtils::slugify($title); // FIXME does gedmo work with phpcr? - $this->slug = $this->name; + $this->slug = PostUtils::slugify($title); return $this; } - /** - * Get slug - * - * @return string - */ - public function getSlug() - { - return $this->slug; - } - /** * Get parent document * @@ -113,22 +90,9 @@ public function getParentDocument() * @return Post */ public function setParentDocument(BlogModel $blog) - { - $this->blog = $blog; - $this->parent = $blog; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function setBlog(BlogModel $blog) { parent::setBlog($blog); - $this->parent = $blog; - return $this; } @@ -141,5 +105,4 @@ public function getRoutes() { return $this->routes; } - } diff --git a/Resources/config/doctrine-phpcr/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml index 92f9798..4093498 100644 --- a/Resources/config/doctrine-phpcr/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -12,7 +12,7 @@ - + diff --git a/Resources/config/doctrine-phpcr/Post.phpcr.xml b/Resources/config/doctrine-phpcr/Post.phpcr.xml index 7b49690..67d1eb3 100644 --- a/Resources/config/doctrine-phpcr/Post.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Post.phpcr.xml @@ -12,10 +12,9 @@ - - + + - diff --git a/Tests/Functional/Admin/BlogAdminTest.php b/Tests/Functional/Admin/BlogAdminTest.php index 3a04b47..7a0641f 100644 --- a/Tests/Functional/Admin/BlogAdminTest.php +++ b/Tests/Functional/Admin/BlogAdminTest.php @@ -26,7 +26,7 @@ public function testCreate() $form->setValues(array( $formPrefix.'[name]' => 'Test Blog', $formPrefix.'[description]' => 'A blog lives here.', - $formPrefix.'[parentDocument]' => '/cms/test', + $formPrefix.'[parentDocument]' => '/cms/blogs', )); $this->client->followRedirects(); @@ -36,4 +36,44 @@ public function testCreate() 'Expected a success flash message, but none was found.' ); } + + public function testEdit() + { + $crawler = $this->requestRoute('GET', 'admin_cmf_blog_blog_edit', array( + 'id' => '/cms/blogs/blog-one', + )); + + $form = $crawler->selectButton('Update')->form(); + $formPrefix = $this->getAdminFormNamePrefix($crawler); + + $form->setValues(array( + $formPrefix.'[name]' => 'Edited Blog', + )); + + $this->client->followRedirects(); + $crawler = $this->client->submit($form); + + $this->assertCount(1, $crawler->filter("html:contains('has been successfully updated')"), + 'Expected a success flash message, but none as found.' + ); + + $dm = $this->db('PHPCR')->getOm(); + $this->assertNotNull($blog = $dm->find(null, '/cms/blogs/edited-blog')); + } + + public function testDelete() + { + $crawler = $this->requestRoute('GET', 'admin_cmf_blog_blog_delete', array( + 'id' => '/cms/blogs/blog-one', + )); + + $form = $crawler->selectButton('Yes, delete')->form(); + + $this->client->followRedirects(); + $crawler = $this->client->submit($form); + + $this->assertCount(1, $crawler->filter("html:contains('has been deleted successfully')"), + 'Expected a success flash message, but none was found.' + ); + } } diff --git a/Tests/Functional/Admin/PostAdminTest.php b/Tests/Functional/Admin/PostAdminTest.php new file mode 100644 index 0000000..ed22dcd --- /dev/null +++ b/Tests/Functional/Admin/PostAdminTest.php @@ -0,0 +1,30 @@ +requestRoute('GET', 'admin_cmf_blog_post_create'); + + $form = $crawler->selectButton('Create')->form(); + $formPrefix = $this->getAdminFormNamePrefix($crawler); + + $form->setValues(array( + $formPrefix.'[blog]' => '/cms/blogs/blog-one', + $formPrefix.'[title]' => 'A test post.', + $formPrefix.'[body]' => 'the full post content', + $formPrefix.'[bodyPreview]' => 'the post content preview', + )); + + $this->client->followRedirects(); + $crawler = $this->client->submit($form); + + $this->assertCount(1, $crawler->filter("html:contains('has been successfully created')"), + 'Expected a success flash message, but none was found.' + ); + } +} diff --git a/Tests/Functional/BaseTestCase.php b/Tests/Functional/BaseTestCase.php index bd76fcc..6442c8b 100644 --- a/Tests/Functional/BaseTestCase.php +++ b/Tests/Functional/BaseTestCase.php @@ -121,7 +121,7 @@ protected function getAdminFormNamePrefix(\Symfony\Component\DomCrawler\Crawler protected function runConsole($command, array $options = array()) { $options['-e'] = 'test'; // test environment -// $options['-q'] = null; // suppress the command's output + $options['-q'] = null; // suppress the command's output $options['command'] = $command; return $this->application->run(new ArrayInput($options)); diff --git a/Tests/Functional/BlogControllerTest.php b/Tests/Functional/BlogControllerTest.php new file mode 100644 index 0000000..a71c9e4 --- /dev/null +++ b/Tests/Functional/BlogControllerTest.php @@ -0,0 +1,13 @@ +request('GET', '/blogs'); + + $this->assertCount(3, $crawler->filter('h2')); + } +} diff --git a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php index aab65e3..c35d96b 100644 --- a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php +++ b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php @@ -33,13 +33,16 @@ public function load(ObjectManager $manager) $rootNode = $manager->find(null, $this->getBasePath()); - $numBlogs = 5; $numPostsPerBlog = (2 * $this->getPostsPerPage()) + 2; // 3 pages + $blogNames = array( + 'Blog One', + 'Blog Two', + 'Blog Three', + ); - $blogIdx = 0; - while ($blogIdx++ < $numBlogs) { + foreach ($blogNames as $blogName) { $blog = new Blog(); - $blog->setName($faker->sentence(3)); + $blog->setName($blogName); $blog->setDescription(implode("\n\n", $faker->paragraphs(3))); $blog->setParentDocument($rootNode); diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index 0305186..5799716 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -1,5 +1,5 @@ parameters: - phpcr_basepath: /cms/test + phpcr_basepath: /cms doctrine: dbal: @@ -17,7 +17,7 @@ cmf_blog: sonata_admin: ~ persistence: phpcr: - blog_basepath: /cms/test + blog_basepath: /cms/blogs cmf_routing: chain: diff --git a/Tests/Resources/app/config/routing.php b/Tests/Resources/app/config/routing.php index 0b064f6..ceb49e8 100644 --- a/Tests/Resources/app/config/routing.php +++ b/Tests/Resources/app/config/routing.php @@ -6,5 +6,7 @@ $collection->addCollection( $loader->import(CMF_TEST_CONFIG_DIR.'/routing/sonata_routing.yml') ); - +$collection->addCollection( + $loader->import(__DIR__.'/routing.yml') +); return $collection; diff --git a/Tests/Resources/app/config/routing.yml b/Tests/Resources/app/config/routing.yml new file mode 100644 index 0000000..6a319d0 --- /dev/null +++ b/Tests/Resources/app/config/routing.yml @@ -0,0 +1,2 @@ +blog_bundle: + resource: '@CmfBlogBundle/Resources/config/routing/blog_controller.xml' diff --git a/composer.json b/composer.json index c6dfa1a..c19cbd3 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "symfony-cmf/routing-auto-bundle": "1.0.*", "sonata-project/doctrine-extensions": "~1.0.2", "doctrine/phpcr-bundle": "~1.2", - "doctrine/phpcr-odm": "~1.2" + "doctrine/phpcr-odm": "~1.2", + "friendsofsymfony/rest-bundle": "~1.4.0" }, "require-dev": { "phpunit/phpunit": "~3.7.28", From def6d545da1647449d04a8c8593419a028a1799b Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 22 Dec 2014 16:47:54 -0500 Subject: [PATCH 11/20] use cmf shell scritps to initialize database --- Tests/Functional/BaseTestCase.php | 11 ++++------- Tests/Resources/app/config/blogbundle.yml | 1 + composer.json | 1 + run_tests.sh | 5 +++++ 4 files changed, 11 insertions(+), 7 deletions(-) create mode 100755 run_tests.sh diff --git a/Tests/Functional/BaseTestCase.php b/Tests/Functional/BaseTestCase.php index 6442c8b..08ce5b4 100644 --- a/Tests/Functional/BaseTestCase.php +++ b/Tests/Functional/BaseTestCase.php @@ -37,24 +37,21 @@ class BaseTestCase extends CmfBaseTestCase public function setUp() { - $this->client = $this->createClient($this->getKernelConfiguration()); $this->application = new Application($this->client->getKernel()); $this->application->setAutoExit(false); - $this->router = $this->client->getContainer()->get('router'); + $this->router = $this->get('router'); - $this->runConsole('doctrine:database:drop', array('--force' => true)); - $this->runConsole('doctrine:database:create'); +// $this->db('PHPCR')->loadFixtures(array( +// 'Symfony\Cmf\Bundle\BlogBundle\Tests\Resources\DataFixtures\PHPCR\LoadBlogData', +// )); - $this->runConsole('doctrine:phpcr:init:dbal'); - $this->runConsole('doctrine:phpcr:repo:init'); $this->runConsole('doctrine:phpcr:fixtures:load', array( '--fixtures' => __DIR__.'/../Resources/DataFixtures/PHPCR', '--no-interaction' => true, )); - } /** diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index 5799716..a424b8e 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -2,6 +2,7 @@ parameters: phpcr_basepath: /cms doctrine: + orm: ~ dbal: driver: pdo_sqlite path: %kernel.root_dir%/../test_db.sqlite diff --git a/composer.json b/composer.json index c19cbd3..15ff54b 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "phpunit/phpunit": "~3.7.28", "symfony-cmf/testing": "1.2.*", "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", + "doctrine/orm": "~2.4.7", "nelmio/alice": "~1.7.2" }, "suggest": { diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 0000000..ca56eed --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,5 @@ +#!/bin/sh +sh vendor/symfony-cmf/testing/bin/travis/doctrine_orm.sh +sh vendor/symfony-cmf/testing/bin/travis/phpcr_odm_doctrine_dbal.sh +bin/phpunit + From 2e85bfe2b3ab18c2991d5fc8285770764848630e Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 23 Dec 2014 09:09:31 +0000 Subject: [PATCH 12/20] Fix --- Resources/config/doctrine-phpcr/Blog.phpcr.xml | 1 + composer.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Resources/config/doctrine-phpcr/Blog.phpcr.xml b/Resources/config/doctrine-phpcr/Blog.phpcr.xml index 4093498..c8943f8 100644 --- a/Resources/config/doctrine-phpcr/Blog.phpcr.xml +++ b/Resources/config/doctrine-phpcr/Blog.phpcr.xml @@ -16,6 +16,7 @@ + diff --git a/composer.json b/composer.json index 15ff54b..ee586c9 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,8 @@ "symfony-cmf/testing": "1.2.*", "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", "doctrine/orm": "~2.4.7", - "nelmio/alice": "~1.7.2" + "nelmio/alice": "~1.7.2", + "phpcr/phpcr-shell": "@alpha" }, "suggest": { "sonata-project/doctrine-phpcr-admin-bundle": "For sonata administration", From a3d97929e33c6e9531330d85d63539d106b3065b Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 08:48:17 -0500 Subject: [PATCH 13/20] add blog detail test --- DependencyInjection/Configuration.php | 6 ------ Tests/Functional/BlogControllerTest.php | 12 ++++++++++++ Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php | 3 +-- Tests/Resources/app/config/blogbundle.yml | 3 +++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 15a486a..984418a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -39,10 +39,6 @@ public function getConfigTreeBuilder() // admin ->arrayNode('sonata_admin') ->canBeEnabled() - ->addDefaultsIfNotSet() - ->children() - ->booleanNode('enabled')->defaultTrue()->end() - ->end() ->end() // menu @@ -50,7 +46,6 @@ public function getConfigTreeBuilder() ->addDefaultsIfNotSet() ->canBeEnabled() ->children() - ->booleanNode('enabled')->defaultTrue()->end() ->scalarNode('content_key')->defaultNull()->end() ->end() ->end() @@ -60,7 +55,6 @@ public function getConfigTreeBuilder() ->addDefaultsIfNotSet() ->canBeEnabled() ->children() - ->booleanNode('enabled')->defaultTrue()->end() ->scalarNode('posts_per_page')->defaultValue(5)->end() ->end() ->end() diff --git a/Tests/Functional/BlogControllerTest.php b/Tests/Functional/BlogControllerTest.php index a71c9e4..c5ded3f 100644 --- a/Tests/Functional/BlogControllerTest.php +++ b/Tests/Functional/BlogControllerTest.php @@ -10,4 +10,16 @@ public function testListAction() $this->assertCount(3, $crawler->filter('h2')); } + + /** + * Pagination disabled + */ + public function testDetailAction() + { + $crawler = $this->request('GET', '/blogs/blog-three'); + + $this->assertCount(1, $crawler->filter('h1')); + $this->assertCount(1, $crawler->filter('h2')); + $this->assertCount(12, $crawler->filter('h3')); + } } diff --git a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php index c35d96b..7ad897b 100644 --- a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php +++ b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php @@ -48,8 +48,7 @@ public function load(ObjectManager $manager) $manager->persist($blog); - $postIdx = 0; - while ($postIdx++ < $numPostsPerBlog) { + for ($i = 0; $i < $numPostsPerBlog; $i++) { $paragraphs = $faker->paragraphs(5); $post = new Post(); $post->setBlog($blog); diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index a424b8e..3875aa2 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -31,6 +31,9 @@ cmf_routing: admin_basepath: %phpcr_basepath% route_basepaths: [%phpcr_basepath%] content_basepath: %phpcr_basepath% + controllers_by_class: + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: cmf_blog.blog_controller:detailAction + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: cmf_blog.post_controller:detailAction cmf_routing_auto: persistence: From bdc0f0e212ad3ef20b71bc7579a754079b7424b4 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 09:23:50 -0500 Subject: [PATCH 14/20] greenlight tests on travis, hopefully --- .gitignore | 1 - .travis.yml | 5 +++-- Tests/Functional/Admin/BlogAdminTest.php | 2 +- Tests/Functional/Admin/PostAdminTest.php | 10 ++++++++++ Tests/Functional/BlogControllerTest.php | 11 ++++++++++- Tests/Resources/app/config/blogbundle.yml | 2 +- run_tests.sh | 1 - 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index c790d14..fcf7e3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ Tests/Resources/app/cache Tests/Resources/app/logs -Tests/Resources/test_db.sqlite bin/ composer.lock vendor/ diff --git a/.travis.yml b/.travis.yml index d0c2202..1d8e247 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ php: env: - SYMFONY_VERSION=2.5.* - + matrix: allow_failures: - env: SYMFONY_VERSION=dev-master @@ -18,13 +18,14 @@ matrix: env: SYMFONY_VERSION=2.4.* - php: 5.5 env: SYMFONY_VERSION=dev-master - + before_script: - composer self-update - echo 'memory_limit = -1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - composer require symfony/symfony:${SYMFONY_VERSION} --prefer-source + - vendor/symfony-cmf/testing/bin/travis/doctrine_orm.sh - vendor/symfony-cmf/testing/bin/travis/phpcr_odm_doctrine_dbal.sh script: phpunit --coverage-text diff --git a/Tests/Functional/Admin/BlogAdminTest.php b/Tests/Functional/Admin/BlogAdminTest.php index 7a0641f..e6c4ea7 100644 --- a/Tests/Functional/Admin/BlogAdminTest.php +++ b/Tests/Functional/Admin/BlogAdminTest.php @@ -54,7 +54,7 @@ public function testEdit() $crawler = $this->client->submit($form); $this->assertCount(1, $crawler->filter("html:contains('has been successfully updated')"), - 'Expected a success flash message, but none as found.' + 'Expected a success flash message, but none was found.' ); $dm = $this->db('PHPCR')->getOm(); diff --git a/Tests/Functional/Admin/PostAdminTest.php b/Tests/Functional/Admin/PostAdminTest.php index ed22dcd..0a84e9e 100644 --- a/Tests/Functional/Admin/PostAdminTest.php +++ b/Tests/Functional/Admin/PostAdminTest.php @@ -1,5 +1,15 @@ request('GET', '/blogs/blog-three'); - $this->assertCount(1, $crawler->filter('h1')); $this->assertCount(1, $crawler->filter('h2')); $this->assertCount(12, $crawler->filter('h3')); } diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index 3875aa2..fbacdfd 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -5,7 +5,7 @@ doctrine: orm: ~ dbal: driver: pdo_sqlite - path: %kernel.root_dir%/../test_db.sqlite + path: %kernel.root_dir%/cache/test_db.sqlite memory: true types: json: Sonata\Doctrine\Types\JsonType diff --git a/run_tests.sh b/run_tests.sh index ca56eed..277ee13 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -2,4 +2,3 @@ sh vendor/symfony-cmf/testing/bin/travis/doctrine_orm.sh sh vendor/symfony-cmf/testing/bin/travis/phpcr_odm_doctrine_dbal.sh bin/phpunit - From 8e82d64e0724cf7459d2281d47559d969f557bab Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 10:37:06 -0500 Subject: [PATCH 15/20] explicitely create node basepaths in the fixtures --- Tests/Functional/BaseTestCase.php | 9 ++----- Tests/Functional/PostControllerTest.php | 26 +++++++++++++++++++ .../DataFixtures/PHPCR/LoadBlogData.php | 8 ++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 Tests/Functional/PostControllerTest.php diff --git a/Tests/Functional/BaseTestCase.php b/Tests/Functional/BaseTestCase.php index 08ce5b4..60da308 100644 --- a/Tests/Functional/BaseTestCase.php +++ b/Tests/Functional/BaseTestCase.php @@ -44,13 +44,8 @@ public function setUp() $this->router = $this->get('router'); -// $this->db('PHPCR')->loadFixtures(array( -// 'Symfony\Cmf\Bundle\BlogBundle\Tests\Resources\DataFixtures\PHPCR\LoadBlogData', -// )); - - $this->runConsole('doctrine:phpcr:fixtures:load', array( - '--fixtures' => __DIR__.'/../Resources/DataFixtures/PHPCR', - '--no-interaction' => true, + $this->db('PHPCR')->loadFixtures(array( + 'Symfony\Cmf\Bundle\BlogBundle\Tests\Resources\DataFixtures\PHPCR\LoadBlogData', )); } diff --git a/Tests/Functional/PostControllerTest.php b/Tests/Functional/PostControllerTest.php new file mode 100644 index 0000000..376583a --- /dev/null +++ b/Tests/Functional/PostControllerTest.php @@ -0,0 +1,26 @@ +request('GET', '/blogs/blog-one/2014-01-01/first-post'); + + $this->assertCount(2, $crawler->filter('h1')); + $this->assertCount(1, $crawler->filter("html:contains('First Post')"), + 'Expected to find the Post\'s title, but it was not.' + ); + } +} diff --git a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php index 7ad897b..499a96f 100644 --- a/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php +++ b/Tests/Resources/DataFixtures/PHPCR/LoadBlogData.php @@ -15,6 +15,7 @@ use Doctrine\Common\DataFixtures\FixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Faker; +use PHPCR\Util\NodeHelper; use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog; use Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post; use Symfony\Component\DependencyInjection\ContainerAwareInterface; @@ -31,6 +32,8 @@ public function load(ObjectManager $manager) { $faker = Faker\Factory::create(); + NodeHelper::createPath($manager->getPhpcrSession(), '/cms/routes'); + NodeHelper::createPath($manager->getPhpcrSession(), $this->getBasePath()); $rootNode = $manager->find(null, $this->getBasePath()); $numPostsPerBlog = (2 * $this->getPostsPerPage()) + 2; // 3 pages @@ -56,6 +59,11 @@ public function load(ObjectManager $manager) $post->setBodyPreview($paragraphs[0]); $post->setBody(implode("\n\n", $paragraphs)); + if ($i == 0) { + $post->setTitle('First Post'); + $post->setDate(new \DateTime('2014-01-01')); + } + $manager->persist($post); } } From ab1fc9cee8f625c7cfc3368abcf4762ad317f000 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 10:53:48 -0500 Subject: [PATCH 16/20] perhaps a manual cache removal is necessary for travis? --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1d8e247..42745a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ before_script: - composer self-update - echo 'memory_limit = -1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - composer require symfony/symfony:${SYMFONY_VERSION} --prefer-source + - rm -fr Tests/Resources/app/cache - vendor/symfony-cmf/testing/bin/travis/doctrine_orm.sh - vendor/symfony-cmf/testing/bin/travis/phpcr_odm_doctrine_dbal.sh From 6425ce0f6d76979bc6c5760a873f3360ac7f51c8 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 11:37:53 -0500 Subject: [PATCH 17/20] fingers crossed --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 42745a2..d334868 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,14 +19,10 @@ matrix: - php: 5.5 env: SYMFONY_VERSION=dev-master - - before_script: - composer self-update - echo 'memory_limit = -1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - composer require symfony/symfony:${SYMFONY_VERSION} --prefer-source - - rm -fr Tests/Resources/app/cache - - vendor/symfony-cmf/testing/bin/travis/doctrine_orm.sh - vendor/symfony-cmf/testing/bin/travis/phpcr_odm_doctrine_dbal.sh script: phpunit --coverage-text From db62834606ebe80c980ada242acb8bc7cea2442c Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Dec 2014 12:16:47 -0500 Subject: [PATCH 18/20] symfony <2.6 does not support closures in setAllowedValues --- Repository/BlogRepository.php | 6 ------ Repository/PostRepository.php | 24 ------------------------ 2 files changed, 30 deletions(-) diff --git a/Repository/BlogRepository.php b/Repository/BlogRepository.php index ce50187..6734e44 100644 --- a/Repository/BlogRepository.php +++ b/Repository/BlogRepository.php @@ -116,12 +116,6 @@ protected function setDefaultOptions(OptionsResolver $resolver) 'limit' => 'int', )); - $resolver->setAllowedValues(array( - 'limit' => function($value) { - return $value > 0; - }, - )); - return $resolver; } diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index 0d87402..71799fa 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -146,30 +146,6 @@ protected function setDefaultOptions(OptionsResolver $resolver) 'orderBy' => 'array', )); - $resolver->setAllowedValues(array( - 'limit' => function($value) { - return $value > 0; - }, - 'orderBy' => function(array $orderBys) { - $validOrderBys = array(); - foreach ($orderBys as $orderBy) { - - if ($orderByValid = isset($orderBy['order'])) { - if(!in_array(strtolower($orderBy['order']), array('asc', 'desc'), true)) { - throw new \InvalidArgumentException(sprintf( - 'Unrecognized orderBy order value "%s". order must be one of ASC or DESC.', - $orderBy['order'] - )); - } - } - - $validOrderBys[] = isset($orderBy['field']) && $orderByValid; - } - - return count(array_filter($validOrderBys)) == count($orderBys); - }, - )); - return $resolver; } } From 27bb8a45f13175cb55299fb1e94e6a7ee4961f6b Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 27 Dec 2014 13:06:46 -0500 Subject: [PATCH 19/20] remove superfluous code --- Controller/PostController.php | 64 ------------------- Repository/BlogRepository.php | 14 ---- Repository/PostRepository.php | 16 +---- Resources/doc/building-a-blog.rst | 20 ------ Resources/views/Blog/detail.html.twig | 2 - .../views/Blog/detailPaginated.html.twig | 2 - Resources/views/Blog/list.html.twig | 2 - Resources/views/Post/detail.html.twig | 4 +- Tests/Resources/app/AppKernel.php | 1 + Tests/Resources/app/config/blogbundle.yml | 3 +- composer.json | 1 + 11 files changed, 7 insertions(+), 122 deletions(-) delete mode 100644 Controller/PostController.php delete mode 100644 Resources/doc/building-a-blog.rst diff --git a/Controller/PostController.php b/Controller/PostController.php deleted file mode 100644 index c5c16e0..0000000 --- a/Controller/PostController.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -class PostController extends BaseController -{ - /** - * @var PostRepository - */ - protected $postRepository; - - public function __construct( - EngineInterface $templating, - SecurityContextInterface $securityContext, - ViewHandlerInterface $viewHandler = null, - PostRepository $postRepository - ) { - parent::__construct($templating, $securityContext, $viewHandler); - $this->postRepository = $postRepository; - } - - public function detailAction(Request $request, Post $contentDocument, $contentTemplate = null) - { - $post = $contentDocument; - - if (true !== $this->securityContext->isGranted(PublishWorkflowChecker::VIEW_ATTRIBUTE, $post)) { - throw new NotFoundHttpException(sprintf( - 'Post "%s" is not published', - $post->getTitle() - )); - } - - $contentTemplate = $this->getTemplateForResponse( - $request, - $contentTemplate ?: 'CmfBlogBundle:Post:detail.{_format}.twig' - ); - - return $this->renderResponse($contentTemplate, compact('post')); - } -} diff --git a/Repository/BlogRepository.php b/Repository/BlogRepository.php index 6734e44..e3af5a8 100644 --- a/Repository/BlogRepository.php +++ b/Repository/BlogRepository.php @@ -46,20 +46,6 @@ public function setBasepath($basepath) $this->basepath = $basepath; } - /** - * Find blog by name - * - * @param string $name - * @return null|Blog - */ - public function findByName($name) - { - return $this->search(array( - 'name' => $name, - 'limit' => 1, - )); - } - /** * Search for blogs by an array of options * diff --git a/Repository/PostRepository.php b/Repository/PostRepository.php index 71799fa..2bb6a5a 100644 --- a/Repository/PostRepository.php +++ b/Repository/PostRepository.php @@ -36,24 +36,10 @@ public function __construct($dm, ClassMetadata $class) $this->resolver = $this->setDefaultOptions(new OptionsResolver()); } - /** - * Find post by title - * - * @param string $title - * @return Post|null - */ - public function findByTitle($title) - { - return $this->search(array( - 'title' => $title, - 'limit' => 1, - )); - } - /** * Search for posts by an array of options: * - blogId: string (required) - * - isPublishable: boolean (optional, default true) + * - isPublishable: boolean (optional, default true) // TODO: https://github.com/symfony-cmf/CoreBundle/issues/126 * - title: string (optional) * - limit: integer (optional) * - orderBy: array of arrays('field' => $field, 'order' => 'ASC or DESC') (optional) diff --git a/Resources/doc/building-a-blog.rst b/Resources/doc/building-a-blog.rst deleted file mode 100644 index 92a853e..0000000 --- a/Resources/doc/building-a-blog.rst +++ /dev/null @@ -1,20 +0,0 @@ -Work in progress -================ - -This document will eventually describe the process of implementing -the BlogBundle. - -Routing -------- - -Register the routes in config.yml - -.. code-block:: php - - cmf_routing: - dynamic: - ... - controllers_by_class: - Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: cmf_blog.blog_controller:listAction - Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: cmf_blog.blog_controller:viewPostAction - Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Tag: cmf_blog.blog_controller:listAction diff --git a/Resources/views/Blog/detail.html.twig b/Resources/views/Blog/detail.html.twig index 9797f31..cebf2f4 100644 --- a/Resources/views/Blog/detail.html.twig +++ b/Resources/views/Blog/detail.html.twig @@ -1,5 +1,3 @@ -{# CmfBlogBundle:Blog:detail.html.twig #} - {% extends "CmfBlogBundle::layout.html.twig" %} {% block content %} diff --git a/Resources/views/Blog/detailPaginated.html.twig b/Resources/views/Blog/detailPaginated.html.twig index 48b6def..1768847 100644 --- a/Resources/views/Blog/detailPaginated.html.twig +++ b/Resources/views/Blog/detailPaginated.html.twig @@ -1,5 +1,3 @@ -{# CmfBlogBundle:Blog:detailPaginated.html.twig #} - {% extends "CmfBlogBundle:Blog:detail.html.twig" %} {% block content %} diff --git a/Resources/views/Blog/list.html.twig b/Resources/views/Blog/list.html.twig index 9127ada..72e5b80 100644 --- a/Resources/views/Blog/list.html.twig +++ b/Resources/views/Blog/list.html.twig @@ -1,5 +1,3 @@ -{# CmfBlogBundle:Blog:list.html.twig #} - {% extends "CmfBlogBundle::layout.html.twig" %} {% block content %} diff --git a/Resources/views/Post/detail.html.twig b/Resources/views/Post/detail.html.twig index f362ab6..696c6d2 100644 --- a/Resources/views/Post/detail.html.twig +++ b/Resources/views/Post/detail.html.twig @@ -1,7 +1,7 @@ -{# CmfBlogBundle:Post:detail.html.twig #} - {% extends "CmfBlogBundle::layout.html.twig" %} +{% set post = cmfMainContent %} + {% block content %}
diff --git a/Tests/Resources/app/AppKernel.php b/Tests/Resources/app/AppKernel.php index a8cfe02..8c3a52d 100644 --- a/Tests/Resources/app/AppKernel.php +++ b/Tests/Resources/app/AppKernel.php @@ -15,6 +15,7 @@ public function configure() $this->addBundles(array( new \Symfony\Cmf\Bundle\CoreBundle\CmfCoreBundle(), + new \Symfony\Cmf\Bundle\ContentBundle\CmfContentBundle(), new \Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(), new \Symfony\Cmf\Bundle\RoutingAutoBundle\CmfRoutingAutoBundle(), new \Symfony\Cmf\Bundle\BlogBundle\CmfBlogBundle(), diff --git a/Tests/Resources/app/config/blogbundle.yml b/Tests/Resources/app/config/blogbundle.yml index fbacdfd..98b7f7a 100644 --- a/Tests/Resources/app/config/blogbundle.yml +++ b/Tests/Resources/app/config/blogbundle.yml @@ -33,7 +33,8 @@ cmf_routing: content_basepath: %phpcr_basepath% controllers_by_class: Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: cmf_blog.blog_controller:detailAction - Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: cmf_blog.post_controller:detailAction + templates_by_class: + Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: CmfBlogBundle:Post:detail.html.twig cmf_routing_auto: persistence: diff --git a/composer.json b/composer.json index ee586c9..f5d9f46 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "php": ">=5.3.3", "symfony/framework-bundle": "~2.3", "symfony-cmf/core-bundle": "1.2.*", + "symfony-cmf/content-bundle": "1.2.*", "symfony-cmf/routing-auto-bundle": "1.0.*", "sonata-project/doctrine-extensions": "~1.0.2", "doctrine/phpcr-bundle": "~1.2", From dde14b59e406529a2b075ea407524854c38de87d Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 6 Feb 2015 18:20:11 -0500 Subject: [PATCH 20/20] convert routing auto config to xml and update composer.json --- Resources/config/cmf_routing_auto.xml | 28 +++++++++++++++++++++++++++ Resources/config/cmf_routing_auto.yml | 11 ----------- composer.json | 6 +++--- 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 Resources/config/cmf_routing_auto.xml delete mode 100644 Resources/config/cmf_routing_auto.yml diff --git a/Resources/config/cmf_routing_auto.xml b/Resources/config/cmf_routing_auto.xml new file mode 100644 index 0000000..2908f6e --- /dev/null +++ b/Resources/config/cmf_routing_auto.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/config/cmf_routing_auto.yml b/Resources/config/cmf_routing_auto.yml deleted file mode 100644 index 2e2e23a..0000000 --- a/Resources/config/cmf_routing_auto.yml +++ /dev/null @@ -1,11 +0,0 @@ -Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Blog: - uri_schema: /blogs/{blog} - token_providers: - blog: [content_method, { method: getName }] - -Symfony\Cmf\Bundle\BlogBundle\Doctrine\Phpcr\Post: - uri_schema: /blogs/{blog}/{date}/{title} - token_providers: - blog: [content_method, { method: getBlog }] - date: [content_datetime, { method: getDate }] - title: [content_method, { method: getTitle }] diff --git a/composer.json b/composer.json index f5d9f46..5e7c8d1 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,17 @@ "symfony-cmf/core-bundle": "1.2.*", "symfony-cmf/content-bundle": "1.2.*", "symfony-cmf/routing-auto-bundle": "1.0.*", - "sonata-project/doctrine-extensions": "~1.0.2", + "sonata-project/doctrine-extensions": "~1.0,>=1.0.2", "doctrine/phpcr-bundle": "~1.2", "doctrine/phpcr-odm": "~1.2", - "friendsofsymfony/rest-bundle": "~1.4.0" + "friendsofsymfony/rest-bundle": "~1.4" }, "require-dev": { "phpunit/phpunit": "~3.7.28", "symfony-cmf/testing": "1.2.*", "sonata-project/doctrine-phpcr-admin-bundle": "1.2.*", "doctrine/orm": "~2.4.7", - "nelmio/alice": "~1.7.2", + "nelmio/alice": "~1.7,>=1.7.2", "phpcr/phpcr-shell": "@alpha" }, "suggest": {