Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions app/SymfonyRequirements.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <strong>PCRE</strong> extension (8.0+).'
null !== $pcreVersion,
'PCRE extension must be available',
'Install the <strong>PCRE</strong> extension (version 8.0+).'
);

/* optional recommendations follow */
Expand Down Expand Up @@ -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),
'<strong>PCRE 8.0+</strong> 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',
Expand Down
38 changes: 30 additions & 8 deletions src/ServerGrove/KbBundle/Controller/Admin/CategoriesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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.
*
Expand Down Expand Up @@ -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');
Expand All @@ -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);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/ServerGrove/KbBundle/Document/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -401,4 +401,12 @@ public function getVisibility()
{
return $this->visibility;
}

/**
* @return bool
*/
public function hasCategoriesOrArticles()
{
return 0 < $this->getArticles()->count() || 0 < $this->getChildren()->count();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
};
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<div class="well">
<button class="btn" type="button" data-toggle="collapse"
data-target="#article_edit_{{ locale }}">{% trans with { '%locale%': locale } %}Edit "%locale%" Version{% endtrans %}
{% if translation_form.isActive.vars.checked|default(false) %}
{% if translation_form.isActive.getVars().checked|default(false) %}
<span class="label label-success">{% trans %}Active{% endtrans %}</span>
{% else %}
<span class="label label-important">{% trans %}Disabled{% endtrans %}</span>
Expand All @@ -100,7 +100,7 @@
</translation>
<script type="text/javascript">
/* <![CDATA[ */
var {{ locale }}TranslationCtrl = getTranslationController('{{ translation_form.content.vars.value|escape('js') }}', '{{ translation_form.vars.contentType|escape('js') }}', '{{ locale }}');
var {{ locale }}TranslationCtrl = getTranslationController('{{ translation_form.content.getVars().value|escape('js') }}', '{{ translation_form.getVars().contentType|escape('js') }}', '{{ locale }}');
/* ]]> */
</script>
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% extends "ServerGroveKbBundle:Admin:layout.html.twig" %}

{% macro displayCategoryTree(category) %}
<ul>
{% for subcategory in category.getChildren() %}
<li>{{ subcategory.getName() }}
{% if subcategory.getChildren()|length > 0 %}
<br>
{{ _self.displayCategoryTree(subcategory) }}
{% endif %}
</li>
{% endfor %}
{% for article in category.getArticles() %}
{% if article.getCategories()|length == 1 %}
<li>
<a target="_blank" href="{{ path('sgkb_articles_view', {'path': article.getDefaultCategory().getPath(), 'slug': article.slug}) }}">
{{ article.title }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endmacro %}

{% import _self as mymacros %}

{% block content %}
<h1>{% trans with {'%category%': category} %}Deleting category "%category%"{% endtrans %}</h1>

<div>The following categories are going to be removed</div>
<form action="{{ path('sgkb_admin_categories_delete_confirmed', {'path': category.path()}) }}" method="post" class="form-horizontal">
{{ mymacros.displayCategoryTree(category) }}
{{ form_widget(form) }}
<div class="form-actions">
<button type="submit" class="btn btn-danger">{% trans %}Delete{% endtrans %}</button>
<a class="btn" href="{{ path('sgkb_admin_categories_index') }}">{% trans %}Cancel{% endtrans %}</a>
</div>
</form>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
{% endif %}

{% if is_granted("ROLE_ADMIN") %}
<delete-form action="{{ path('sgkb_admin_categories_delete', { 'path': document.getPath() }) }}" method="post" button="{% trans %}Delete{% endtrans %}" confirmation="{% trans %}Are you sure you want to delete this category?{% endtrans %}">
<delete-form action="{{ path('sgkb_admin_categories_delete', { 'path': document.getPath() }) }}" method="post" button="{% trans %}Delete{% endtrans %}" {% if not document.hasCategoriesOrArticles() %}confirmation="{% trans %}Are you sure you want to delete this category?{% endtrans %}"{% endif %}>
{{ form_widget(delete_form) }}
</delete-form>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down