<?php
namespace Cms\ModuleBundle\Controller\Dashboard;
use Cms\ContainerBundle\Entity\Container;
use Cms\ContainerBundle\Entity\Containers\PersonalContainer;
use Cms\CoreBundle\Model\Scenes\DashboardScenes\AjaxScene;
use Cms\CoreBundle\Util\DateTimeUtils;
use Cms\CoreBundle\Util\ModalsController;
use Cms\ModuleBundle\Doctrine\ProxyRepository;
use Cms\ModuleBundle\Entity\History;
use Cms\ModuleBundle\Entity\Proxy;
use Cms\ModuleBundle\Service\ModuleManager;
use Cms\WorkflowsBundle\Service\WorkflowsManager;
use Doctrine\Common\Util\ClassUtils;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Class ModalController
* @package Cms\ModuleBundle\Controller\Dashboard
*/
final class ModalController extends ModalsController
{
const ROUTES__START = 'campussuite.cms.module.dashboard.modal.start';
const ROUTES__CONTAINER = 'campussuite.cms.module.dashboard.modal.container';
const ROUTES__MODULE = 'campussuite.cms.module.dashboard.modal.module';
const ROUTES__CREATE = 'campussuite.cms.module.dashboard.modal.create';
const SESSION__LAST_LOCATION = 'campussuite.cms.content.modal.last_location';
/**
* @return array|string[]
*/
private function validModules()
{
return array(
'page' => 'Pages',
);
}
/**
* @return AjaxScene|RedirectResponse
* @throws \Exception
*
* @Route(
* "/",
* name = ModalController::ROUTES__START
* )
*/
public function startAction()
{
// get params
$last = null;
// attempt to get container
$container = null;
if ( ! empty($this->getModalParam('containerId'))) {
$container = $this->getEntityManager()
->getRepository(Container::class)
->find($this->getModalParam('containerId'));
}
// attempt to determine if there is a last location thing set
$lastId = $this->getSession()->get(self::SESSION__LAST_LOCATION);
if ( ! empty($lastId)) {
$lastContainer = $this->getEntityManager()->getRepository(Container::class)->find($lastId);
if ( ! empty($lastContainer)) {
$container = $lastContainer;
}
}
// generate redirect based on information
if ($last instanceof Container && ! empty($container) && $last->getRoot() === $container->getRoot()) {
// redirect to the root view of the container
return $this->redirectToRoute(
self::ROUTES__CONTAINER,
array(
'containerId' => $last->getId(),
)
);
} else if ( ! empty($container)) {
// redirect to the root view of the container
return $this->redirectToRoute(
self::ROUTES__CONTAINER,
array(
'containerId' => $container->getId(),
)
);
}
// get all the containers in a hierarchy
$containers = $this->getEntityManager()->getRepository(Container::class)->findAllHierarchy();
// show view
return $this->viewAjax(
array(
'containers' => $containers,
)
);
}
/**
* @param string $containerId
* @return RedirectResponse
* @throws \Exception
*
* @Route(
* "/{containerId}",
* name = ModalController::ROUTES__CONTAINER,
* requirements = {
* "containerId" = "[1-9]\d*"
* }
* )
*/
public function containerAction($containerId)
{
// grab container
$container = $this->getEntityManager()->getRepository(Container::class)->findExact($containerId);
// get modules
$modules = $this->validModules();
// get default module to jump to
if (count($modules) === 1) {
reset($modules);
$moduleKey = key($modules);
} else {
$moduleKey = 'page';
}
// set the last location
$this->getSession()->set(self::SESSION__LAST_LOCATION, $container->getId());
// get module info
$module = $this->getModuleManager()->getModuleConfiguration($moduleKey);
// done, redirect to page of content listing
return $this->redirectToRoute(
self::ROUTES__MODULE,
array(
'containerId' => $container->getId(),
'moduleKey' => $module->key(),
'dataType' => $module->types()[0],
)
);
}
/**
* @param string $containerId
* @param string $moduleKey
* @param string $dataType
* @return AjaxScene
* @throws \Exception
*
* @Route(
* "/{containerId}/{moduleKey}/{dataType}",
* name = ModalController::ROUTES__MODULE,
* requirements = {
* "containerId" = "[1-9]\d*",
* "moduleKey" = "[a-zA-Z]+",
* "dataType" = "[a-zA-Z]+"
* }
* )
*/
public function moduleAction($containerId, $moduleKey, $dataType)
{
// get the container we are relative to
$relative = $this->getEntityManager()->getRepository(Container::class)->findExact(
( ! empty($this->getModalParam('containerId'))) ? $this->getModalParam('containerId') : $containerId
);
// get all the containers in a hierarchy
$containers = $this->assembleDepartments($relative);
// grab container
$container = $this->getEntityManager()->getRepository(Container::class)->findExact($containerId);
// make sure it is a valid module
if ( ! in_array($moduleKey, array_keys($this->validModules()))) {
throw new \Exception();
}
// get the module config for the given module
$module = $this->getModuleManager()->getModuleConfiguration($moduleKey);
// get the proxy type
$type = $module->classesProxy($dataType);
// use proxy class to get repository
/** @var ProxyRepository $repo */
$repo = $this->getRepository($type);
// get the items for our container
$items = $repo->findAllForContainer($container);
// we should have all that we need
return $this->viewAjax(
array(
'containers' => $containers,
'ancestors' => $this->getEntityManager()->getRepository(Container::class)->findAncestors($container),
'container' => $container,
'relative' => $relative,
'module' => $module,
'items' => $items,
'workflowSkipper' => (
( ! $this->getWorkflowsManager()->hasWorkflow($container))
||
( ! $this->getWorkflowsManager()->needsApproval(
$this->getGlobalContext()->getEffectiveAccount(),
$container
))
),
)
);
}
/**
* @param Request $request
* @param string $containerId
* @param string $moduleKey
* @param string $dataType
* @return AjaxScene|RedirectResponse
* @throws \Exception
*
* @Route(
* "/{containerId}/{moduleKey}/{dataType}/create",
* name = ModalController::ROUTES__CREATE,
* requirements = {
* "containerId" = "[1-9]\d*",
* "moduleKey" = "[a-zA-Z]+",
* "dataType" = "[a-zA-Z]+"
* }
* )
*/
public function createAction(Request $request, $containerId, $moduleKey, $dataType)
{
// grab container
$container = $this->getEntityManager()->getRepository(Container::class)->findExact($containerId);
$containers = $this->assembleDepartments($container);
// make sure it is a valid module
if ( ! in_array($moduleKey, array_keys($this->validModules()))) {
throw new \Exception();
}
// get the module config for the given module
$module = $this->getModuleManager()->getModuleConfiguration($moduleKey);
// AUDIT
$this->denyAccessUnlessGranted(
array_filter(array(
sprintf(
'campussuite.cms.container.%s.manage',
$container->getType()
),
'campussuite.cms.module.manage',
sprintf(
'campussuite.cms.modules.%s.manage',
$module->key()
),
)),
array(null, $container)
);
// get the proxy type
$type = $module->classesProxy($dataType);
// create an object of this type
/** @var Proxy $proxy */
$proxy = new $type();
$data = $proxy->getData();
// generate form
$form = $this->createForm($module->formClass($data), $data, array(
'minimal' => true,
'create' => true,
'container' => $container,
));
// handle submission
if ($this->handleForm($form, $request)) {
// generate the history item
$history = $module->classesHistory($dataType);
/** @var History $history */
$history = new $history();
$history
->setData($proxy->getData())
->setProxy($proxy)
->setTimestamp(DateTimeUtils::now());
// set things on proxy that are needed
$proxy
->setContainer($container)
->setHistory($history);
// save them
$this->getEntityManager()->saveAll(array(
$proxy,
$history,
));
// record log
$this->getActivityLogger()->createLog($proxy);
// done
return $this->redirectToRoute(
self::ROUTES__MODULE,
array(
'containerId' => $container->getId(),
'moduleKey' => $module->key(),
'dataType' => $proxy->type(),
)
);
}
// show form
return $this->viewAjax(
array(
'containers' => $containers,
'container' => $container,
'ancestors' => $this->getEntityManager()->getRepository(Container::class)->findAncestors($container),
'module' => $module,
'form' => $form->createView(),
)
);
}
/**
* @param Container $current
* @return array|Container[]
*/
private function assembleDepartments(Container $current)
{
// query based on class
// get only ones in same root
// and order by the left values
/** @var array|Container[] $containers */
$containers = $this->getEntityManager()->getRepository(ClassUtils::getClass($current))->findBy(
array(
'rt' => $current->getRoot(),
),
array(
'lft' => 'ASC',
)
);
// TODO: do we need to do the processing for hidden stuff???
return $containers;
/*
// loop over them to process whether they are hidden
$showable = [];
$root = null;
$left = null;
$right = null;
foreach ($containers as $container) {
// if we have tracked a hidden node, we need to do some other checks
if ($root !== null) {
// if the current is not outside our tracked node, we need to clear tracking and re-check for hidden stuff
// otherwise, we know this is a child node, can assume that this node is hidden, and can skip to the next entry
if ($container->getRoot() !== $root || $container->getRight() < $left || $container->getLeft() > $right) {
$root = null;
$left = null;
$right = null;
} else {
continue;
}
}
// if we are here, we should not be tracking anything yet
// check whether the node is hidden
// if it is, start tracking and move to the next entry
// otherwise, we should have a visible node
if ($container->isHidden()) {
$root = $container->getRoot();
$left = $container->getLeft();
$right = $container->getRight();
} else {
$showable[] = $container;
}
}
// send back an array of things that we have determined should be visible
return $showable;
*/
}
/**
* @return ModuleManager|object
*/
private function getModuleManager(): ModuleManager
{
return $this->get(__METHOD__);
}
/**
* @return WorkflowsManager|object
*/
private function getWorkflowsManager(): WorkflowsManager
{
return $this->get(__METHOD__);
}
}