diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php index 4df46d1..0e416b8 100644 --- a/app/SymfonyRequirements.php +++ b/app/SymfonyRequirements.php @@ -500,9 +500,9 @@ function_exists('simplexml_import_dom'), $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; $this->addRequirement( - null !== $pcreVersion && $pcreVersion > 8.0, - sprintf('PCRE extension must be available and at least 8.0 (%s installed)', $pcreVersion ? $pcreVersion : 'not'), - 'Upgrade your PCRE extension (8.0+).' + null !== $pcreVersion, + 'PCRE extension must be available', + 'Install the PCRE extension (version 8.0+).' ); /* optional recommendations follow */ @@ -531,6 +531,14 @@ function_exists('simplexml_import_dom'), 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' ); + if (null !== $pcreVersion) { + $this->addRecommendation( + $pcreVersion >= 8.0, + sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), + 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' + ); + } + $this->addRecommendation( class_exists('DomDocument'), 'PHP-XML module should be installed', diff --git a/src/ServerGrove/KbBundle/Controller/Admin/CategoriesController.php b/src/ServerGrove/KbBundle/Controller/Admin/CategoriesController.php index f9ec60b..08c9c2d 100644 --- a/src/ServerGrove/KbBundle/Controller/Admin/CategoriesController.php +++ b/src/ServerGrove/KbBundle/Controller/Admin/CategoriesController.php @@ -6,6 +6,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use ServerGrove\KbBundle\Document\Article; use ServerGrove\KbBundle\Document\Category; @@ -222,14 +223,19 @@ public function updateAction(Category $category) * Deletes a Category document. * * @Route("/{path}/delete", name="sgkb_admin_categories_delete", requirements={"path":".+"}) + * @Route("/{path}/delete/confirmed", name="sgkb_admin_categories_delete_confirmed", requirements={"path":".+"}) * @Method("post") * @ParamConverter("category", class="ServerGroveKbBundle:Category") * */ public function deleteAction(Category $category) { - $form = $this->createDeleteForm($category); $request = $this->getRequest(); + if ('sgkb_admin_categories_delete_confirmed' != $request->get('_route')) { + return $this->forward('ServerGroveKbBundle:Admin/Categories:deleteConfirmation', array('category' => $category)); + } + + $form = $this->createDeleteForm($category); $form->bind($request); @@ -241,11 +247,30 @@ public function deleteAction(Category $category) $dm->remove($category); $dm->flush(); + } else { + var_dump($form->getErrorsAsString()); + exit; } return $this->redirect($this->generateUrl('sgkb_admin_categories_index')); } + /** + * Confirmation action for category removal + * + * @Template + * + * @param Category $category + * + * @return array + */ + public function deleteConfirmationAction(Category $category) + { + $form = $this->createDeleteForm($category); + + return array('category' => $category, 'form' => $form->createView()); + } + /** * Lists all Article documents. * @@ -274,6 +299,7 @@ public function removeArticlesFromCategory() { /** @var $category Category */ $category = func_get_arg(1 == func_num_args() ? 0 : 1); + $this->get('logger')->info(sprintf('Removing articles from category "%s"', $category->getName())); if (!($category instanceof Category)) { throw new \RuntimeException('Expected instance of Category'); @@ -294,14 +320,10 @@ public function removeArticlesFromCategory() public function removeChildrenFromCategory(Category $category) { - $controller = $this; - + $this->get('logger')->info(sprintf('Removing children from category "%s"', $category->getName())); foreach ($category->getChildren() as $child) { - call_user_func(array($controller, 'removeArticlesFromCategory'), $child); - call_user_func(array($controller, 'removeChildrenFromCategory'), $child); - - /** @var $category Category */ - $category->getChildren()->removeElement($child); + call_user_func(array($this, 'removeArticlesFromCategory'), $child); + call_user_func(array($this, 'removeChildrenFromCategory'), $child); } } diff --git a/src/ServerGrove/KbBundle/Document/Category.php b/src/ServerGrove/KbBundle/Document/Category.php index 848d5aa..0a3aa3c 100644 --- a/src/ServerGrove/KbBundle/Document/Category.php +++ b/src/ServerGrove/KbBundle/Document/Category.php @@ -401,4 +401,12 @@ public function getVisibility() { return $this->visibility; } + + /** + * @return bool + */ + public function hasCategoriesOrArticles() + { + return 0 < $this->getArticles()->count() || 0 < $this->getChildren()->count(); + } } diff --git a/src/ServerGrove/KbBundle/Resources/public/js/backend/admin-angular.js b/src/ServerGrove/KbBundle/Resources/public/js/backend/admin-angular.js index 68419ec..1029af7 100644 --- a/src/ServerGrove/KbBundle/Resources/public/js/backend/admin-angular.js +++ b/src/ServerGrove/KbBundle/Resources/public/js/backend/admin-angular.js @@ -53,9 +53,11 @@ method: '@method', confirmation: '@confirmation' }, - link: function (scope, element, attrs) { + link: function (scope, element) { scope.doDelete = function () { - if (window.confirm(scope.confirmation)) { + if (angular.isUndefined(scope.confirmation) || !angular.isString(scope.confirmation)) { + element.find('form').submit(); + } else if (window.confirm(scope.confirmation)) { element.find('form').submit(); } }; @@ -307,11 +309,11 @@ var timeout = null, state, nextCall; - $scope.$watch('categories.values', function (newValue, oldValue) { + $scope.$watch('categories.values', function () { $scope.categories.invalid = 0 === $scope.categories.values.length; }); - $scope.$watch('title.value', function (newValue, oldValue) { + $scope.$watch('title.value', function (newValue) { if ('' === newValue || null === newValue) { window.clearTimeout(timeout); diff --git a/src/ServerGrove/KbBundle/Resources/views/Admin/Articles/edit.html.twig b/src/ServerGrove/KbBundle/Resources/views/Admin/Articles/edit.html.twig index 2f315ac..9ca3cbd 100644 --- a/src/ServerGrove/KbBundle/Resources/views/Admin/Articles/edit.html.twig +++ b/src/ServerGrove/KbBundle/Resources/views/Admin/Articles/edit.html.twig @@ -73,7 +73,7 @@
+ {% trans %}Cancel{% endtrans %} +
+ +{% endblock %} diff --git a/src/ServerGrove/KbBundle/Resources/views/Admin/Categories/edit.html.twig b/src/ServerGrove/KbBundle/Resources/views/Admin/Categories/edit.html.twig index a8ea646..9a12e27 100644 --- a/src/ServerGrove/KbBundle/Resources/views/Admin/Categories/edit.html.twig +++ b/src/ServerGrove/KbBundle/Resources/views/Admin/Categories/edit.html.twig @@ -26,7 +26,7 @@ {% endif %} {% if is_granted("ROLE_ADMIN") %} - + {{ form_widget(delete_form) }} {% endif %} diff --git a/src/ServerGrove/KbBundle/Tests/Controller/Admin/ArticlesControllerTest.php b/src/ServerGrove/KbBundle/Tests/Controller/Admin/ArticlesControllerTest.php index c161f8f..0ba735e 100644 --- a/src/ServerGrove/KbBundle/Tests/Controller/Admin/ArticlesControllerTest.php +++ b/src/ServerGrove/KbBundle/Tests/Controller/Admin/ArticlesControllerTest.php @@ -82,7 +82,7 @@ public function testEditAction() $this->assertEquals(200, $client->getResponse()->getStatusCode(), $this->getErrorMessage($client)); $form = $crawler->selectButton('Save')->form(); - $form['article[categories]']->select(array('/categories/mysql', '/categories/billing')); + $form['article[categories]']->select(array('/categories/category-a', '/categories/category-b')); $client->submit($form); $this->assertEquals(302, $client->getResponse()->getStatusCode(), $this->getErrorMessage($client)); @@ -96,7 +96,7 @@ public function testEditAction() /** @var $category \ServerGrove\KbBundle\Document\Category */ foreach ($article->getCategories() as $category) { $this->assertInstanceOf('ServerGrove\KbBundle\Document\Category', $category); - $this->assertTrue(in_array($category->getName(), array('MySQL', 'Billing'))); + $this->assertTrue(in_array($category->getName(), array('Category A', 'Category B'))); } $crawler = $client->request('GET', $url = $this->generateUrl('sgkb_admin_articles_edit', array('slug' => $slug = Sluggable::urlize($this->title)))); diff --git a/src/ServerGrove/KbBundle/Tests/Controller/ArticlesControllerTest.php b/src/ServerGrove/KbBundle/Tests/Controller/ArticlesControllerTest.php index 74b942d..00f8bc3 100644 --- a/src/ServerGrove/KbBundle/Tests/Controller/ArticlesControllerTest.php +++ b/src/ServerGrove/KbBundle/Tests/Controller/ArticlesControllerTest.php @@ -35,8 +35,8 @@ public function testArticleViewWithLocale($locale, $title) $client = $this->getClient(); $crawler = $client->request('GET', '/'.$locale.'/categories/test/articles/the-title-of-my-article.html'); $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $this->assertGreaterThan(0, $crawler->filter('#doccontent h2.article-title')->count()); - $this->assertEquals($title, $crawler->filter('#doccontent h2.article-title')->first()->text(), $crawler->filter('#doccontent h2.article-title')->first()->text()); + $this->assertGreaterThan(0, $crawler->filter('h2.article-title')->count()); + $this->assertEquals($title, $crawler->filter('h2.article-title')->first()->text()); } public function getTestData() diff --git a/src/ServerGrove/KbBundle/Tests/Controller/CategoryControllerTest.php b/src/ServerGrove/KbBundle/Tests/Controller/CategoryControllerTest.php index eea7fdf..2f44486 100644 --- a/src/ServerGrove/KbBundle/Tests/Controller/CategoryControllerTest.php +++ b/src/ServerGrove/KbBundle/Tests/Controller/CategoryControllerTest.php @@ -10,9 +10,9 @@ public function testCategories() /* @var $crawler \Symfony\Component\DomCrawler\Crawler */ $crawler = $this->getClient()->request('GET', '/'); $this->assertGreaterThan(0, $crawler->filter('h1:contains("Knowledge Base")')->count(), 'There is no header for KB'); - $this->assertGreaterThan(0, $crawler->filter('.left-nav ul li a:contains("Test")')->count()); + $this->assertGreaterThan(0, $crawler->filter('ul.nav li a:contains("Test")')->count()); - $link = $crawler->filter('.left-nav ul li a:contains("Test")')->first()->link(); + $link = $crawler->filter('ul.nav li a:contains("Test")')->first()->link(); $crawler = $this->getClient()->click($link); $this->assertGreaterThan(0, $crawler->filter('h1:contains("Knowledge Base")')->count(), 'There is no header for KB'); $this->assertGreaterThan(0, $crawler->filter('.breadcrumb a:contains("Test")')->count(), 'There is no breadcrumb for Test category');