Skip to content

Commit

Permalink
Modification of delete Item, create service and add method to delete …
Browse files Browse the repository at this point in the history
…Item by strategy (#20)
  • Loading branch information
AlexBDev authored and benjamin-hubert committed Jun 30, 2016
1 parent a05ccfa commit 7a68f4b
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 1 deletion.
184 changes: 184 additions & 0 deletions Controller/ItemCRUDController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<?php

namespace Alpixel\Bundle\MenuBundle\Controller;

use Alpixel\Bundle\MenuBundle\Entity\Item;
use Alpixel\Bundle\MenuBundle\Entity\Menu;
use Pix\SortableBehaviorBundle\Controller\SortableAdminController as Controller;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Exception\ModelManagerException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

/**
* @author Alexis BUSSIERES <[email protected]>
*/
class ItemCRUDController extends Controller
{
private function deleteItems($items)
{
$menu = $this->get('alpixel_menu.menu.menu');
$menu->deleteItems($items);
}

public function batchActionDelete(ProxyQueryInterface $query)
{
$this->admin->checkAccess('batchDelete');

try {
$this->deleteItems($query->execute());
$this->addFlash('sonata_flash_success', 'flash_batch_delete_success');
} catch (ModelManagerException $e) {
$this->handleModelManagerException($e);
$this->addFlash('sonata_flash_error', 'flash_batch_delete_error');
}

return new RedirectResponse($this->admin->generateUrl(
'list',
array('filter' => $this->admin->getFilterParameters())
));
}

public function deleteAction($id)
{
$request = $this->getRequest();
$object = $this->admin->getObject($id);

if (!$object) {
throw $this->createNotFoundException(sprintf('unable to find the object with id : %s', $id));
}

$this->admin->checkAccess('delete', $object);

$preResponse = $this->preDelete($request, $object);
if ($preResponse !== null) {
return $preResponse;
}

if ($this->getRestMethod() == 'DELETE') {
// check the csrf token
$this->validateCsrfToken('sonata.delete');

$objectName = $this->admin->toString($object);

try {
$this->deleteItems([$object]);

if ($this->isXmlHttpRequest()) {
return $this->renderJson(array('result' => 'ok'), 200, array());
}

$this->addFlash(
'sonata_flash_success',
$this->admin->trans(
'flash_delete_success',
array('%name%' => $this->escapeHtml($objectName)),
'SonataAdminBundle'
)
);
} catch (ModelManagerException $e) {
$this->handleModelManagerException($e);

if ($this->isXmlHttpRequest()) {
return $this->renderJson(array('result' => 'error'), 200, array());
}

$this->addFlash(
'sonata_flash_error',
$this->admin->trans(
'flash_delete_error',
array('%name%' => $this->escapeHtml($objectName)),
'SonataAdminBundle'
)
);
}

return $this->redirectTo($object);
}

return $this->render($this->admin->getTemplate('delete'), array(
'object' => $object,
'action' => 'delete',
'csrf_token' => $this->getCsrfToken('sonata.delete'),
), null);
}

protected function redirectTo($object)
{
$request = $this->getRequest();

$url = false;
$params = [];

if ($object instanceof Item) {
if ($object->getParent() !== null) {
$itemId = $object->getParent()->getId();
$params['list']['item'] = $itemId;
$params['create']['create-item'] = $itemId;
}
$menuId = $object->getMenu()->getId();
$params['list']['menu'] = $menuId;
$params['create']['create-menu'] = $menuId;
} elseif ($object instanceof Menu) {
$menuId = $object->getId();
$params['list']['menu'] = $menuId;
$params['create']['create-menu'] = $menuId;
}

if (null !== $request->get('btn_update_and_list')) {
$url = $this->admin->generateUrl('list', $params['list']);
} elseif (null !== $request->get('btn_create_and_list')) {
$url = $this->admin->generateUrl('list', $params['list']);
}

if (null !== $request->get('btn_create_and_create')) {
if ($this->admin->hasActiveSubClass()) {
$params['create']['subclass'] = $request->get('subclass');
}
$url = $this->admin->generateUrl('create', $params['create']);
}

if ($this->getRestMethod() === 'DELETE') {
if ($object instanceof Item) {
$url = $this->admin->generateUrl('list', $params['list']);
} else {
$router = $this->get('router');
$url = $router->generate('admin_alpixel_menu_menu_list');
}
}

if (!$url) {
foreach (['edit', 'show'] as $route) {
if ($this->admin->hasRoute($route) && $this->admin->isGranted(strtoupper($route), $object)) {
$url = $this->admin->generateObjectUrl($route, $object);
break;
}
}
}

if (!$url) {
$router = $this->get('router');
$url = $router->generate('admin_alpixel_menu_menu_list');
}

return new RedirectResponse($url);
}

public function itemAction()
{
$object = $this->admin->getSubject();
$router = $this->container->get('router');
$parameters = [];

if ($object instanceof Menu) {
$parameters['menu'] = $object->getId();
} elseif ($object instanceof Item) {
$parameters['menu'] = $object->getMenu()->getId();
$parameters['item'] = $object->getId();
}

$url = $router->generate('admin_alpixel_menu_item_list', $parameters, UrlGeneratorInterface::ABSOLUTE_PATH);

return new RedirectResponse($url);
}
}
109 changes: 109 additions & 0 deletions Menu/Menu.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace Alpixel\Bundle\MenuBundle\Menu;

use Alpixel\Bundle\MenuBundle\Entity\Item;
use Doctrine\ORM\EntityManager;

/**
* @author Alexis BUSSIERES <[email protected]>
*/
class Menu
{
const DELETE_STRATEGY_MOVE_CHILDREN = 'delete.strategy.move_children';

protected $entityManager;

/**
* Menu constructor.
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}

/**
* @param array $item An array of object Item
* @param string $strategy Strategy to use
*/
public function deleteItem($item, $strategy)
{
$this->deleteItems([$item], $strategy);
}

/**
* This method delete an array of Item by different strategy.
*
* Strategies available:
* self::DELETE_STRATEGY_MOVE_CHILDREN Remove Item and set children to the same level of the deleted Item
*
* @param $items
* @param string $strategy Strategy to use
*/
public function deleteItems($items, $strategy = self::DELETE_STRATEGY_MOVE_CHILDREN)
{
if (!is_array($items)) {
throw new \InvalidArgumentException('The "$items" parameters is not an array.');
}

if (empty($items)) {
return;
}

switch ($strategy) {
case self::DELETE_STRATEGY_MOVE_CHILDREN:
$this->deleteItemsMoveChildren($items);
break;
default:
throw new \InvalidArgumentException('The "$stategy" parameter must be a non empty string.');
}

$this->entityManager->flush();
}

/**
* This method delete Item object and manage his children by self::DELETE_STRATEGY_MOVE_CHILDREN strategy
*
* @param array $items An array of object Item
*/
private function deleteItemsMoveChildren($items)
{

foreach ($items as $item) {
if (!is_object($item) || !$item instanceof Item) {
throw new \InvalidArgumentException(sprintf(
'An error occurred during the operation,
the value must be an instance object of %s'
), Item::class);
}

$this->entityManager->remove($item);

$children = $item->getChildren();
$itemParent = $item->getParent();

if (empty($children) || empty($itemParent)) {
continue;
}

$itemParentChildren = $itemParent->getChildren();
foreach ($children as $child) {
$child->setParent($itemParent);
$itemParentChildren->add($child);
}

$this->entityManager->persist($itemParent);
}
}

/**
* @return array An array of available delete strategies
*/
public static function getDeleteStrategiesAvailable()
{
return [
self::DELETE_STRATEGY_MOVE_CHILDREN,
];
}
}
6 changes: 5 additions & 1 deletion Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ services:
- "@doctrine.orm.entity_manager"
- "@knp_menu.factory"

alpixel_menu.menu.menu:
class: Alpixel\Bundle\MenuBundle\Menu\Menu
arguments: ["@doctrine.orm.entity_manager"]

# SonataAdmin
alpixel_menu.admin.menu:
class: Alpixel\Bundle\MenuBundle\Controller\Admin\CRUD\MenuAdmin
Expand All @@ -24,7 +28,7 @@ services:
arguments:
- ~
- Alpixel\Bundle\MenuBundle\Entity\Item
- AlpixelMenuBundle:CRUD
- AlpixelMenuBundle:ItemCRUD
calls:
- [ setTemplate, [edit, AlpixelMenuBundle:CRUD:edit__item.html.twig]]
- [ setTemplate, [list, AlpixelMenuBundle:CRUD:list_item.html.twig]]
Expand Down

0 comments on commit 7a68f4b

Please sign in to comment.