<?php
namespace Cms\WorkflowsBundle\Controller\Dashboard;
use Cms\CoreBundle\Model\Scenes\DashboardScenes\AjaxScene;
use Cms\CoreBundle\Model\Scenes\DashboardScenes\DocumentScene;
use Cms\CoreBundle\Model\Search\Search;
use Cms\ModuleBundle\Controller\ContentController;
use Cms\ModuleBundle\Entity\Draft;
use Cms\ModuleBundle\Form\Type\Actions\PublishActionType;
use Cms\ModuleBundle\Service\ModuleManager;
use Cms\WorkflowsBundle\Controller\AbstractWorkflowsController;
use Cms\WorkflowsBundle\Entity\Publication\ScheduledPublication;
use Cms\WorkflowsBundle\Entity\Workflow;
use Cms\WorkflowsBundle\Entity\WorkflowSubmission;
use Cms\WorkflowsBundle\Form\Type\PublicationCancelType;
use Cms\WorkflowsBundle\Service\Search\DraftsSearcher;
use Cms\WorkflowsBundle\Service\Search\ScheduledPublicationSearcher;
use Cms\WorkflowsBundle\Service\Search\WorkflowSubmissionSearcher;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Class DraftsController
* @package Cms\WorkflowsBundle\Controller\Dashboard
*
* @Route(
* "/drafts"
* )
*/
final class DraftsController extends AbstractWorkflowsController
{
const ROUTES__INDEX = 'cms.workflows.dashboard.drafts.index';
const ROUTES__DRAFTS = 'cms.workflows.dashboard.drafts.drafts';
const ROUTES__DRAFTS_LAZY = 'cms.workflows.dashboard.drafts.drafts_lazy';
const ROUTES__MY_DRAFTS = 'cms.workflows.dashboard.drafts.my_drafts';
const ROUTES__MY_DRAFTS_LAZY = 'cms.workflows.dashboard.drafts.my_drafts_lazy';
const ROUTES__SUBMISSIONS = 'cms.workflows.dashboard.drafts.submissions';
const ROUTES__SUBMISSIONS_LAZY = 'cms.workflows.dashboard.drafts.submissions_lazy';
const ROUTES__MY_SUBMISSIONS = 'cms.workflows.dashboard.drafts.my_submissions';
const ROUTES__MY_SUBMISSIONS_LAZY = 'cms.workflows.dashboard.drafts.my_submissions_lazy';
const ROUTES__PUBLICATIONS = 'cms.workflows.dashboard.drafts.publications';
const ROUTES__PUBLICATIONS_LAZY = 'cms.workflows.dashboard.drafts.publications_lazy';
const ROUTES__PUBLICATION_CANCEL = 'cms.workflows.dashboard.drafts.publication_cancel';
const ROUTES__PUBLICATION_RESCHEDULE = 'cms.workflows.dashboard.drafts.publication_reschedule';
/**
* @return DraftsSearcher|object
*/
private function getDraftsSearcher(): DraftsSearcher
{
return $this->get(__METHOD__);
}
/**
* @return ModuleManager|object
*/
private function getModuleManager(): ModuleManager
{
return $this->get(__METHOD__);
}
/**
* @return WorkflowSubmissionSearcher|object
*/
private function getWorkflowSubmissionSearcher(): WorkflowSubmissionSearcher
{
return $this->get(__METHOD__);
}
/**
* @return ScheduledPublicationSearcher|object
*/
private function getScheduledPublicationSearcher(): ScheduledPublicationSearcher
{
return $this->get(__METHOD__);
}
/**
* @return RedirectResponse
*
* @Route(
* "",
* name = DraftsController::ROUTES__INDEX
* )
*/
public function indexAction()
{
return $this->redirectToRoute(self::ROUTES__MY_DRAFTS);
}
/**
* @param Request $request
* @return AjaxScene|DocumentScene
* @throws \Exception
*
* @Route(
* "/drafts",
* name = DraftsController::ROUTES__DRAFTS
* )
* @Route(
* "/drafts/lazyload",
* name = DraftsController::ROUTES__DRAFTS_LAZY
* )
*/
public function draftsAction(Request $request)
{
// do search logic to find applicable workflows
$search = $this->getDraftsSearcher()->handleRequest($request);
if ($search instanceof RedirectResponse) {
return $search;
}
// query for drafts
$drafts = $this->getDraftsSearcher()->search(
$search,
null
);
// function for linking the edit buttons
$editCallback = function($draft) {
switch (true) {
case $draft instanceof Draft:
return $this->generateUrl(
ContentController::ROUTES__MODIFY_CONFLICTS,
array(
'container' => $draft->getProxy()->getContainer()->getId(),
'module' => $this->getModuleManager()->getModuleConfigurationForEntity($draft)->key(),
'proxy' => $draft->getProxy()->getId(),
//'draft' => $draft->getId(),
'redirectTo' => $this->getRequest()->getRequestUri(),
)
);
}
throw new \Exception();
};
// handle lazyloading
if ($request->isXmlHttpRequest()) {
return $this->viewAjax(
'@CmsWorkflows/Dashboard/Drafts/includes/drafts.html.twig',
array(
'search' => $search,
'drafts' => $drafts,
'editCallback' => $editCallback,
)
);
}
return $this->view(
array(
'search' => $search,
'drafts' => $drafts,
'editCallback' => $editCallback,
)
);
}
/**
* @param Request $request
* @return AjaxScene|DocumentScene
* @throws \Exception
*
* @Route(
* "/my-drafts",
* name = DraftsController::ROUTES__MY_DRAFTS
* )
* @Route(
* "/my-drafts/lazyload",
* name = DraftsController::ROUTES__MY_DRAFTS_LAZY
* )
*/
public function myDraftsAction(Request $request)
{
// do search logic to find applicable workflows
$search = $this->getDraftsSearcher()->handleRequest($request);
if ($search instanceof RedirectResponse) {
return $search;
}
// query for drafts
$drafts = $this->getDraftsSearcher()->search(
$search,
$this->getGlobalContext()->getEffectiveAccount()
);
// function for linking the edit buttons
$editCallback = function($draft) {
switch (true) {
case $draft instanceof Draft:
return $this->generateUrl(
ContentController::ROUTES__MODIFY_CONFLICTS,
array(
'container' => $draft->getProxy()->getContainer()->getId(),
'module' => $this->getModuleManager()->getModuleConfigurationForEntity($draft)->key(),
'proxy' => $draft->getProxy()->getId(),
//'draft' => $draft->getId(),
'redirectTo' => $this->getRequest()->getRequestUri(),
)
);
}
throw new \Exception();
};
// handle lazyloading
if ($request->isXmlHttpRequest()) {
return $this->viewAjax(
'@CmsWorkflows/Dashboard/Drafts/includes/drafts.html.twig',
array(
'search' => $search,
'drafts' => $drafts,
'editCallback' => $editCallback,
)
);
}
return $this->view(
'@CmsWorkflows/Dashboard/Drafts/drafts.html.twig',
array(
'search' => $search,
'drafts' => $drafts,
'editCallback' => $editCallback,
)
);
}
/**
* @param Request $request
* @return AjaxScene|DocumentScene
* @throws \Exception
*
* @Route(
* "/submissions",
* name = DraftsController::ROUTES__SUBMISSIONS
* )
* @Route(
* "/submissions/lazyload",
* name = DraftsController::ROUTES__SUBMISSIONS_LAZY
* )
*/
public function submissionsAction(Request $request)
{
// do search logic to find applicable workflows
$search = $this->getWorkflowSubmissionSearcher()->handleRequest($request);
if ($search instanceof RedirectResponse) {
return $search;
}
// use groups for user to limit the search space to the ones tied to a workflow they are a reviewer for
$search->registerPreFilter(
function (QueryBuilder $qb, Search $search)
{
// get the workflows that have these groups set as reviewers
$workflows = $this->getEntityManager()->getRepository(Workflow::class)
->findByReviewedByAccount(
$this->getGlobalContext()->getEffectiveAccount()
);
// add a restriction on the query builder where the submission is tied to a workflow they are a reviewer of
$qb
->andWhere(sprintf(
'%s.workflow IN (:workflows)',
$qb->getRootAliases()[0]
))
->setParameter('workflows', $workflows);
}
);
// get the submissions
$submissions = $this->getEntityManager()->getRepository(WorkflowSubmission::class)->search($search);
// handle lazyloading
if ($request->isXmlHttpRequest()) {
return $this->viewAjax(
'@CmsWorkflows/Dashboard/Drafts/includes/submissions.html.twig',
array(
'search' => $search,
'submissions' => $submissions,
)
);
}
return $this->view(
array(
'search' => $search,
'submissions' => $submissions,
)
);
}
/**
* @param Request $request
* @return AjaxScene|DocumentScene
* @throws \Exception
*
* @Route(
* "/my-submissions",
* name = DraftsController::ROUTES__MY_SUBMISSIONS
* )
* @Route(
* "/my-submissions/lazyload",
* name = DraftsController::ROUTES__MY_SUBMISSIONS_LAZY
* )
*/
public function mySubmissionsAction(Request $request)
{
// do search logic to find applicable workflows
$search = $this->getWorkflowSubmissionSearcher()->handleRequest($request);
if ($search instanceof RedirectResponse) {
return $search;
}
// only get the submissions created by us
$search->registerPreFilter(
function (QueryBuilder $qb, Search $search)
{
// add a restriction on the query builder where the submission is tied to a workflow they are a reviewer of
$qb
->andWhere(sprintf(
'%s.createdBy = :account',
$qb->getRootAliases()[0]
))
->setParameter(
'account',
$this->getGlobalContext()->getEffectiveAccount()
);
}
);
// get the submissions
$submissions = $this->getEntityManager()->getRepository(WorkflowSubmission::class)->search($search);
// handle lazyloading
if ($request->isXmlHttpRequest()) {
return $this->viewAjax(
'@CmsWorkflows/Dashboard/Drafts/includes/submissions.html.twig',
array(
'search' => $search,
'submissions' => $submissions,
)
);
}
return $this->view(
'@CmsWorkflows/Dashboard/Drafts/submissions.html.twig',
array(
'search' => $search,
'submissions' => $submissions,
)
);
}
/**
* @param Request $request
* @return AjaxScene|DocumentScene
* @throws \Exception
*
* @Route(
* "/publications",
* name = DraftsController::ROUTES__PUBLICATIONS
* )
* @Route(
* "/publications/lazyload",
* name = DraftsController::ROUTES__PUBLICATIONS_LAZY
* )
*/
public function publicationsAction(Request $request)
{
// do search logic to find applicable workflows
$search = $this->getScheduledPublicationSearcher()->handleRequest($request);
if ($search instanceof RedirectResponse) {
return $search;
}
// get the scheduled publications
$publications = $this->getEntityManager()->getRepository(ScheduledPublication::class)->search($search);
// handle lazyloading
if ($request->isXmlHttpRequest()) {
return $this->viewAjax(
'@CmsWorkflows/Dashboard/Drafts/includes/publications.html.twig',
array(
'search' => $search,
'publications' => $publications,
)
);
}
return $this->view(
array(
'search' => $search,
'publications' => $publications,
)
);
}
/**
* @param string $id
* @return DocumentScene|RedirectResponse
* @throws \Exception
*
* @Route(
* "/publication/{id}/cancel",
* name = DraftsController::ROUTES__PUBLICATION_CANCEL,
* requirements = {
* "id" = "[1-9]\d*"
* }
* )
*/
public function publicationCancelAction($id)
{
// TODO: AUDIT
//$this->denyAccessUnlessGranted('campussuite.cms.workflows.publication_manage');
// load up the publication
$publication = $this->getEntityManager()->getRepository(ScheduledPublication::class)->findExact($id);
// generate the form
$form = $this->createForm(PublicationCancelType::class, [], []);
// process the form
if ($this->handleForm($form)) {
try {
$this->getPublisher()->cancel($publication);
// go back to the main listing page
return $this->redirectToRoute(self::ROUTES__PUBLICATIONS);
} catch (\Exception $e) {
$form->addError(new FormError($e->getMessage()));
}
}
return $this->view(array(
'publication' => $publication,
'form' => $form->createView(),
));
}
/**
* @param string $id
* @return DocumentScene|RedirectResponse
* @throws \Exception
*
* @Route(
* "/publication/{id}/reschedule",
* name = DraftsController::ROUTES__PUBLICATION_RESCHEDULE,
* requirements = {
* "id" = "[1-9]\d*"
* }
* )
*/
public function publicationRescheduleAction($id)
{
// load up the publication
$publication = $this->getEntityManager()->getRepository(ScheduledPublication::class)->findExact($id);
// generate the form
$form = $this->createForm(
PublishActionType::class,
$publication
);
// process the form
if ($this->handleForm($form)) {
try {
$this->getPublisher()->reschedule(
$publication,
$form->getData()->getPublishAt()
);
// go back to the main listing page
return $this->redirectToRoute(self::ROUTES__PUBLICATIONS);
} catch (\Exception $e) {
$form->addError(new FormError($e->getMessage()));
}
}
return $this->view(array(
'publication' => $publication,
'form' => $form->createView(),
));
}
}