From 920e3b04a9d7bf16bc10487fc4f8c3b86b69ae68 Mon Sep 17 00:00:00 2001 From: gloas <gloas@afi-sa.fr> Date: Wed, 4 Jan 2017 17:10:38 +0100 Subject: [PATCH] migrate cms-controller to full plusgin manager --- .../controllers/CmsCategoryController.php | 109 +---- .../admin/controllers/CmsController.php | 402 +----------------- library/Class/MultiSelection/Article.php | 9 +- library/ZendAfi/Controller/Action.php | 256 ++--------- library/ZendAfi/Controller/Action/Plugins.php | 51 +++ .../Action/RessourceDefinitions.php | 18 +- .../ZendAfi/Controller/Plugin/Abstract.php | 101 ++--- .../Controller/Plugin/Manager/Article.php | 389 +++++++++++++++-- .../Plugin/Manager/ArticleCategory.php | 112 +++++ .../Controller/Plugin/Manager/Manager.php | 297 +++++++++++++ .../Plugin/MultiSelection/Abstract.php | 49 ++- .../admin/controllers/CmsControllerTest.php | 11 +- tests/scenarios/Manager/ManagerTest.php | 58 ++- 13 files changed, 1008 insertions(+), 854 deletions(-) create mode 100644 library/ZendAfi/Controller/Action/Plugins.php create mode 100644 library/ZendAfi/Controller/Plugin/Manager/ArticleCategory.php create mode 100644 library/ZendAfi/Controller/Plugin/Manager/Manager.php diff --git a/application/modules/admin/controllers/CmsCategoryController.php b/application/modules/admin/controllers/CmsCategoryController.php index 7e2dc912def..0fab4456b51 100644 --- a/application/modules/admin/controllers/CmsCategoryController.php +++ b/application/modules/admin/controllers/CmsCategoryController.php @@ -23,6 +23,10 @@ class Admin_CmsCategoryController extends ZendAfi_Controller_Action { protected $_bib; + public function getPlugins() { + return ['ZendAfi_Controller_Plugin_Manager_ArticleCategory']; + } + public function getRessourceDefinitions() { return ['model' => ['class' => 'Class_ArticleCategorie', @@ -36,117 +40,18 @@ class Admin_CmsCategoryController extends ZendAfi_Controller_Action { 'edit' => ['title' => $this->_("Modifier une catégorie")]], 'after_add' => function ($model) { - $this->_redirectToTreeView($model); + $this->_redirectToReferer(); }, 'after_edit' => function ($model) { - $this->_redirectToTreeView($model); + $this->_redirectToReferer(); }, 'after_delete' => function($model) { - $this->_redirect($this->_deleteBackUrl($model)); + $this->_redirectToReferer(); }, 'form_class_name' => 'ZendAfi_Form_Admin_CmsCategory']; } - - - protected function _updateNewModel($model) { - if ($parent = Class_ArticleCategorie::find($this->_getParam('id'))) { - $model->setParentCategorie($parent) - ->setBib($parent->getBib()); - return; - } - - $this->_handleBibFor($model); - } - - - protected function _handleBibFor($category) { - if ($bib = $this->getDefaultBib()) - $category->setBib($bib); - } - - - protected function _redirectToTreeView($model) { - $this->_redirect($this->_backUrl($model)); - } - - - protected function _backUrl($model) { - $is_list_mode = Class_AdminVar::isArticlesListMode(); - if (($model->isNew() || $is_list_mode) - && $parent = $model->getParentCategorie()) - return $this->_withPageUrl(sprintf('admin/cms/index/id_cat/%d', $parent->getId())); - - return $this->_withPageUrl($is_list_mode ? - sprintf('admin/cms/index/id_bib/%d', - ($bib = $model->getBib()) ? $bib->getId() : 0) : - sprintf('admin/cms/index/id_cat/%d', $model->getId())); - } - - - protected function _deleteBackUrl($model) { - $is_list_mode = Class_AdminVar::isArticlesListMode(); - if ($parent = $model->getParentCategorie()) - return $this->_withPageUrl(sprintf('admin/cms/index/id_cat/%d', $parent->getId())); - - return $this->_withPageUrl($is_list_mode ? - sprintf('admin/cms/index/id_bib/%d', - ($bib = $model->getBib()) ? $bib->getId() : 0) : - 'admin/cms/index'); - } - - - protected function _withPageUrl($url) { - return ($page = $this->_getParam('page')) - ? $url . '/page/' . $page : $url; - } - - - protected function _postEditAction($model) { - if (null === $model->getBib()) - $this->_handleBibFor($model); - - if (Class_Users::getIdentity()->isRoleMoreThanModoPortail()) - $this->view->permissions = $this->view - ->groupsPermissions($model, - Class_Permission::getCmsPermissions(), - $this->view->url(['module' => 'admin', - 'controller' => 'cms-category', - 'action' => 'permissions', - 'id' => $model->getId()], - null, true)); - } - - - protected function getDefaultBib() { - $identity = Class_Users::getIdentity(); - - return ZendAfi_Acl_AdminControllerRoles::ADMIN_BIB >= $identity->getRoleLevel() ? - $identity->getBib() : Class_Bib::find((int)$this->_getParam('id_bib')); - } - - - public function permissionsAction() { - $this->_helper->getHelper('ViewRenderer')->setNoRender(); - if (!$category = Class_ArticleCategorie::find($this->_getParam('id', 0))) - $this->_redirect('admin/cms/index'); - - $this->_helper->groupPermissions($category, $this->_getParam('perms', [])); - $this->_helper->notify('Permissions sauvegardées'); - $this->_redirect(sprintf('admin/cms-category/edit/id/%d', $category->getId())); - } - - - /** - * @param Storm_Model_Abstract $model - * @return Zend_Form - */ - protected function _getForm($model) { - $form = parent::_getForm($model); - $form->setAttrib('data-backurl', Class_Url::absolute($this->_backUrl($model))); - return $form; - } } ?> \ No newline at end of file diff --git a/application/modules/admin/controllers/CmsController.php b/application/modules/admin/controllers/CmsController.php index 0077e2541ce..629012a0b07 100644 --- a/application/modules/admin/controllers/CmsController.php +++ b/application/modules/admin/controllers/CmsController.php @@ -22,6 +22,12 @@ class Admin_CmsController extends ZendAfi_Controller_Action { private $_bib; + public function getPlugins() { + return ['ZendAfi_Controller_Plugin_Manager_Article', + 'ZendAfi_Controller_Plugin_MultiSelection_Article']; + } + + public function getRessourceDefinitions() { return ['model' => ['class' => 'Class_Article', 'name' => 'article', @@ -33,9 +39,8 @@ class Admin_CmsController extends ZendAfi_Controller_Action { 'successful_delete' => $this->_('Article "%s" supprimé')], 'actions' => ['add' => ['title' => $this->_("Ajouter un article")]], - 'after_edit' => function ($model) { $model->index(); }, - 'plugins' => ['ZendAfi_Controller_Plugin_Manager_Article', - 'ZendAfi_Controller_Plugin_MultiSelection_Article']]; + 'after_edit' => function ($model) { $model->index(); } + ]; } @@ -170,317 +175,12 @@ class Admin_CmsController extends ZendAfi_Controller_Action { } - protected function _updateNewModel($article) { - if ('newsduplicate' == $this->_request->getActionName() - && $original = Class_Article::find($this->_getParam('id', 0))) { - $article->updateAttributes($original->copy()->toArray()); - return $this; - } - - $article->setAuteur(Class_Users::getIdentity()); - - if (!$category = $this->getCategoryAndSetComboCat()) - return $this; - - $article->setCategorie($category); - if ($domaine = Class_Catalogue::findWithSamePathAs($category)) - $article->setDomaineIds($domaine->getId()); - return $this; - } - - - protected function _doBeforeSave($article) { - $article->updateDateMaj(); - return $this; - } - - - protected function _doAfterSave($article) { - if($id_module = $this->_getParam('id_module')) - $this->updateConfigBoiteNews($id_module,$article); - $this->_notifyArticleChanged($article); - return $this; - } - - - public function newsduplicateAction() { - if (!$model = Class_Article::find($this->_getParam('id'))) { - $this->_redirect('admin/cms'); - return; - } - - $this->view->titre = $this->_('Dupliquer l\'article: %s', $model->getTitre()); - - if (!$this->_canModify($model->getCategorie())) { - $this->_helper->notify($this->view->_('Vous n\'avez pas la permission "%s"', - $this->view->titre)); - $this->_redirectToIndex(); - return; - } - - $this->_setParam('id_cat', $model->getCategorie()->getId()); - parent::addAction(); - - $this->view->titre = $this->_('Dupliquer l\'article: %s', $model->getTitre()); - $this->view->form - ->setAction($this->view->url(['module' => 'admin', - 'controller' => 'cms', - 'action' => 'add', - 'id_cat' => $model->getCategorie()->getId()], - null, true)); - - $this->getHelper('ViewRenderer')->setScriptAction('add'); - } - - - public function getCategoryAndSetComboCat() { - if (!$category = Class_ArticleCategorie::find($this->_getParam('id_cat'))) { - $this->_redirect('admin/cms'); - return; - } - - if (null === ($category->getBib())) - $category->setBib($this->_bib); - - $this->view->combo_cat = $this->view->comboCategories($category); - return $category; - } - - - protected function updateConfigBoiteNews($id_module, $article){ - $profil = Class_Profil::getCurrentProfil(); - $module_config = $profil->getModuleAccueilConfig($id_module, 'NEWS'); - $id_items= array_filter(explode('-',$module_config['preferences']['id_items'])); - array_unshift($id_items,$article->getId()); - $module_config['preferences']['id_items'] = implode('-',$id_items); - $profil->updateModuleConfigAccueil($id_module, $module_config); - $profil->save(); - return $this; - } - - - protected function comboLieuOptions() { - $combo_lieu_options = ['0' => $this->_('Aucun')]; - foreach(Class_Lieu::findAllBy(['order' => 'libelle']) as $lieu) - $combo_lieu_options[$lieu->getId()] = $lieu->getLibelle(); - return $combo_lieu_options; - } - - - protected function _notifyArticleChanged($article) { - if (!Class_AdminVar::isWorkflowEnabled()) - return; - $this->_sendMailWhenUpdatedStatusToValidationPending($article); - $this->_sendMailWhenUpdatedStatusToRefused($article); - $this->_sendMailWhenUpdatedStatusToValidated($article); - } - - - protected function _sendMailWhenUpdatedStatusToRefused($article) { - if ($article->old_status != Class_Article::STATUS_REFUSED && - $article->getStatus() == Class_Article::STATUS_REFUSED) { - $this->_sendRefusedMailToAuteur($article); - } - } - - - protected function _sendMailWhenUpdatedStatusToValidated($article) { - if ($article->old_status != Class_Article::STATUS_VALIDATED && - $article->getStatus() == Class_Article::STATUS_VALIDATED) { - $this->_sendValidatedMailToAuteur($article); - } - } - - - protected function _sendMailWhenUpdatedStatusToValidationPending($article) { - if (($article->old_status != Class_Article::STATUS_VALIDATION_PENDING && - $article->getStatus() == Class_Article::STATUS_VALIDATION_PENDING) - || ($article->getStatus() > 5 - && $article->old_status != $article->getStatus())) { - $this->_sendMailToValidators($article); - } - } - - - protected function prepareMailForAuteur($article) { - $mail = new ZendAfi_Mail('utf8'); - if(!$article->getAuteur()) { - $this->_helper->notify('Mail non envoyé: article sans auteur'); - return; - } - - if(!$mail_address = $article->getAuteur()->getMail()) { - $this->_helper->notify('Mail non envoyé: '.$article->getNomCompletAuteur().' sans mail.'); - return; - } - - $mail->setFrom('no-reply@afi-sa.fr') - ->addTo($mail_address); - return $mail; - } - - - protected function prepareBodyMail($article, $message) { - $replacements = - ['TITRE_ARTICLE' => $article->getTitre(), - 'URL_ARTICLE' => $this->view->absoluteUrl($article->getUrl(), null, true), - 'AUTHOR_ARTICLE' => $article->getNomCompletAuteur(), - 'SAVED_BY_ARTICLE' => $this->identity->getNomComplet(), - 'NEXT_STATUS_ARTICLE' => $article->getNextWorkflowStatusLabel(), - 'STATUS_ARTICLE' => $article->getStatusLabel()]; - - return - str_replace(array_keys($replacements), - array_values($replacements), - $message); - } - - - protected function _sendRefusedMailToAuteur($article) { - if(!$mail = $this->prepareMailForAuteur($article)) - return; - $body = $this->prepareBodyMail($article, $article->getRefusMessage()); - $this->sendPreparedMail($mail, - '[Bokeh] Refus de l\'article '.$article->getTitre(), - $body); - } - - - protected function sendPreparedMail($mail, $subject, $body) { - $mail->setSubject(quoted_printable_decode($subject)) - ->setBodyText($body,'utf-8',Zend_Mime::ENCODING_8BIT); - - if ($this->_sendMail($mail)) - $this->_helper->notify('Mail envoyé à : '.$mail->getRecipients()[0]); - } - - - protected function _sendValidatedMailToAuteur($article) { - if(!$mail = $this->prepareMailForAuteur($article)) - return; - - $body = $this->prepareBodyMail($article, $article->getValideMessage()); - $this->sendPreparedMail($mail, - '[Bokeh] Validation de l\'article '.$article->getTitre(), - $body); - } - - - protected function _getValidatorsMail($article) { - return array_unique( - Class_Permission::getWorkflow($article->getNextWorkflowStatus()) - ->getUsersOnModel($article->getCategorie()) - ->collect('mail') - ->getArrayCopy()); - } - - - protected function _sendMailToValidators($article) { - if (!$mails = $this->_getValidatorsMail($article)) - return; - - $mail = new ZendAfi_Mail('utf8'); - $mail - ->setFrom('no-reply@afi-sa.fr') - ->addTo(implode(',', $mails)) - ->setSubject($this->_('[Bokeh] Validation d\'article en attente: ') . $article->getTitre()) - ->setBodyText($this->prepareBodyMail($article, - Class_AdminVar::getWorkflowTextMailArticlePending())); - - if($this->_sendMail($mail)) - $this->_helper->notify($this->_('Mail de validation envoyé aux validateurs.')); - } - - - protected function _sendMail($mail) { - try { - $mail->send(); - return true; - - } catch (Exception $e) { - $this->_helper->notify('Mail non envoyé: vérifier la configuration du serveur de mail.'); - return false; - } - } - - - public function deleteAction() { - if (!$article = Class_Article::find((int)$this->_getParam('id'))) { - $this->_redirect('admin/cms'); - return; - } - - $this->view->titre = $this->view->_('Supprimer l\'article : %s', - $article->getTitre()); - - - if (!$this->_canModify($article->getCategorie())) { - $this->_helper->notify($this->view->_('Vous n\'avez pas la permission "%s"', - $this->view->titre)); - $this->_redirectToIndex(); - return; - } - - $this->view->model = $article; - } - - - public function forceDeleteAction() { - if (!$article = Class_Article::find((int)$this->_getParam('id'))) { - $this->_redirect('admin/cms'); - return; - } - - if (!$this->_canModify($article->getCategorie())) { - $this->_helper->notify($this->view->_('Vous n\'avez pas la permission "%s"', - $this->view->_('Supprimer l\'article : %s', - $article->getTitre()))); - $this->_redirectToIndex(); - return; - } - - $article->delete(); - $this->_redirect($this->_backDeleteUrl($article)); - } - - public function viewcmsAction() { $this->view->article = Class_Article::find((int)$this->_getParam('id')); $this->view->title = 'Afficher un article'; } - public function makevisibleAction() { - $this->_toggleVisibility('visible'); - } - - - public function makeinvisibleAction() { - $this->_toggleVisibility('invisible'); - } - - - protected function _toggleVisibility($visibility) { - if (!$article = Class_Article::getLoader()->find((int)$this->_getParam('id'))) { - $this->_redirect('admin/cms'); - return; - } - - if (!$this->_canModify($article->getCategorie())) { - $this->_helper->notify($this->view->_('Vous n\'avez pas la permission "%s"', - $this->view->_('Rendre %s l\'article : %s', - $visibility, - $article->getTitre()))); - $this->_redirectToIndex(); - return; - } - - $method = 'be' . ucfirst($visibility); - $article->$method(); - $this->_redirect($this->_backUrl($article)); - } - - private function _getTreeViewContainerActions() { return (new ZendAfi_View_Helper_ModelActionsTable_ArticlesCategories($this->view, 'article'))->getActions(); } @@ -491,97 +191,11 @@ class Admin_CmsController extends ZendAfi_Controller_Action { } - private function _getBibActions() { - return (new ZendAfi_View_Helper_ModelActionsTable_Bib($this->view, 'bib'))->getActions(); - } - - - private function _toDate($str) { - if ($str!==null && $str!=='') { - $date = new Zend_Date($str, null, Zend_Registry::get('locale')); - return $date->toString('YYYY-MM-dd HH:mm'); - } - - return null; - } - - public function categoriesAction() { $this->_helper->viewRenderer->setNoRender(); $this->getResponse()->setHeader('Content-Type', 'application/json; charset=utf-8'); $this->getResponse()->setBody((new Class_ArticleCategorie())->getCategoriesJson()); } - - protected function _getFormValues($model) { - $attributes=parent::_getFormValues($model); - foreach(['description', 'contenu'] as $content_field) - $attributes[$content_field] = Class_CmsUrlTransformer::forEditing($attributes[$content_field]); - - $attributes['pick_day'] = $model->getPickDayAsArray(); - return $attributes; - } - - - protected function _getForm($model) { - $this - ->_definitions - ->setFormClassName($model->isTraduction() - ? 'ZendAfi_Form_Admin_NewsTranslation' - : 'ZendAfi_Form_Admin_News'); - $form = parent::_getForm($model); - $form->setAttrib('data-backurl', Class_Url::absolute($this->_backUrl($model))); - return $form; - } - - - protected function _backUrl($model) { - if (!Class_AdminVar::isArticlesListMode()) - return 'admin/cms/index' . (!$model->isNew() ? '/id/' . $model->getId() : ''); - - return $this->view->absoluteUrl(['module' => 'admin', - 'controller' => 'cms', - 'action' => 'index']); - } - - - protected function _backDeleteUrl($model) { - return sprintf('admin/cms/index/id_cat/%d%s', - ($cat = $model->getCategorie()) ? $cat->getId() : 0, - ($page = $this->_getParam('page')) ? '/page/'.$page : ''); - } - - - protected function _canAdd() { - $category = Class_ArticleCategorie::find($this->_getParam('id_cat')); - return $category && $this->_canModify($category); - } - - - protected function _getDefaultModel($models) { - $article = $this->_definitions->newModel(); - $cat = Class_ArticleCategorie::findDistinctCategories($models); - if (count($cat)==1) { - $article->setCategorie($cat[0]); - } - - $status = Class_Article::findDistinctStatus($models); - if (count($status)==1) { - $article->setStatus($status[0]->getStatus()); - } - - return $article; - } - - - protected function _getEditUrl($model) { - $this->getRequest()->setParamSources(['_GET']); - $url = parent::_getEditUrl($model) - . (($page = $this->_getParam('page')) ? '/page/'.$page : '') - . (($id_cat = $this->_getParam('id_cat')) ? '/id_cat/'.$id_cat : '') - . (($title_search = $this->_getParam('title_search')) ? '/title_search/' . $title_search : ''); - $this->getRequest()->setParamSources(['_GET', '_POST']); - return $url; - } } ?> \ No newline at end of file diff --git a/library/Class/MultiSelection/Article.php b/library/Class/MultiSelection/Article.php index dc63b411384..238063fb068 100644 --- a/library/Class/MultiSelection/Article.php +++ b/library/Class/MultiSelection/Article.php @@ -90,8 +90,11 @@ class Class_MultiSelection_Article extends Class_MultiSelection_Abstract { public function acceptActionsVisitor($visitor) { $user = Class_Users::getIdentity(); $permission_closure = function($model) use($user){ + if('Class_Article' == get_class($model)) + $model = $model->getCategorie(); + return $user - ->hasAnyPermissionOn($model->getCategorie(), + ->hasAnyPermissionOn($model, [Class_Permission::createArticle(), Class_Permission::createArticleCategory()]); }; @@ -101,13 +104,13 @@ class Class_MultiSelection_Article extends Class_MultiSelection_Abstract { ->visitLeafCondition(function($model) use($permission_closure) { - return $this->isSelected($model->getId) + return $this->isSelected($model->getId()) && $permission_closure($model); }) ->visitNodeCondition(function($model) use($permission_closure) { - return $this->isCategorySelected($model->getId) + return $this->isCategorySelected($model->getId()) && $permission_closure($model); }) diff --git a/library/ZendAfi/Controller/Action.php b/library/ZendAfi/Controller/Action.php index 7fd345b3809..483476a3ff8 100644 --- a/library/ZendAfi/Controller/Action.php +++ b/library/ZendAfi/Controller/Action.php @@ -70,7 +70,9 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { public function preDispatch() { $this->_definitions = new ZendAfi_Controller_Action_RessourceDefinitions($this->getRessourceDefinitions()); - $this->_plugins = $this->view->plugins = $this->_definitions->getPlugins($this); + $plugin_helper = new ZendAfi_Controller_Action_Plugins($this); + $this->_plugins = $plugin_helper->getPlugins(); + $this->_plugins = $this->view->plugins = $plugin_helper->init(); if ($this->isPopupRequest()) $this->switchToPopupMode(); @@ -80,6 +82,9 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } + + + protected function _redirect($url, array $options = array()) { if ($this->isPopupRequest() && $this->_request->isPost()) { $this @@ -112,6 +117,11 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } + public function getPlugins() { + return []; + } + + public function indexAction() { if ($this->_response->isRedirect()) return; @@ -129,93 +139,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } - public function deleteAction() { - if ($this->_response->isRedirect()) - return; - - if ($model = $this->_findModel()) { - $values = $this->_getCustomFieldModelValues($model); - $values->deleteValues(); - $model->delete(); - $this->_helper->notify($this->_definitions->successfulDeleteMessage($model)); - } - $this->_redirectToIndex(); - $this->_definitions->doAfterDelete($model); - } - - - protected function _addModelToView($model) { - $model_name = $this->_definitions->getModelName(); - $this->view->model_name = $model_name; - $this->view->$model_name = $model; - } - - - public function addAction() { - if ($this->_response->isRedirect()) - return; - - if (!$this->_canAdd()) { - $this->_helper->notify($this->view->_('Vous n\'avez pas la permission "%s"', - $this->_definitions->addActionTitle())); - $this->_redirectToIndex(); - return; - } - - $this->view->titre = $this->_definitions->addActionTitle(); - $model = $this->_definitions->newModel(); - $this->_updateNewModel($model); - $this->_addModelToView($model); - - if ($this->_setupFormAndSave($model)) { - $this->_helper->notify($this->_definitions->successfulAddMessage($model)); - $this->_redirectToEdit($model); - $this->_definitions->doAfterAdd($model); - } - } - - - protected function _updateNewModel($model) { - return $this; - } - - - protected function _canAdd() { - return true; - } - - - protected function _getCustomFieldModelValues($model) { - return Class_CustomField_Model::getModel($this->_definitions->getModelClass()) - ->find($model->getId()); - } - - - protected function _getCustomFieldForm($model_values) { - return new ZendAfi_Form_Admin_CustomFields_ModelValues(['model_values' => $model_values]); - } - - - protected function processMulticheckboxFromPost($form, $clean = false) { - $defaults = []; - foreach ($form->getMulticheckboxNames() as $checkbox_name) - $defaults[$checkbox_name] = []; - - $post = array_merge($defaults, $this->_getPost()); - if ($clean) - $post = $form->deleteUnchanged($post); - - $this->custom_values = []; - - foreach ($post as $k=>$v) - if (preg_match('/field_[0-9]+/', $k)) { - $this->custom_values[$k] = $v; - unset($post[$k]); - } - return $post; - } - - protected function _redirectToIndex() { $url = '/admin/'.$this->_request->getControllerName().'/index'; $closure = function($item, $value) use (&$url) { @@ -244,15 +167,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } - protected function _redirectToEdit($model) { - $this->_redirectClose($this->_getEditUrl($model)); - } - - - protected function _getEditUrl($model) { - return sprintf('/admin/%s/edit/id/%s', - $this->_request->getControllerName(), $model->getId()); - } protected function _getPost() { @@ -260,98 +174,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } - protected function _setupFormAndSave($model) { - $form = $this->_getForm($model); - - $this->view->form = $form; - if (!$this->_request->isPost()) - return false; - - $post = $this->processMulticheckboxFromPost($form); - $model->updateAttributes($post); - - if ((!$form->isValidModelAndArray($model, $this->_getPost()))) - return false; - - $this->_doBeforeSave($model); - - if (!$model->save()) - return false; - - $model_values = $this->_getCustomFieldModelValues($model); - $custom_form = $this->_getCustomFieldForm($model_values); - $custom_form->populate($this->custom_values); - $custom_form->updateModelValues(); - $model_values->save(); - - $this->_doAfterSave($model); - return true; - } - - - protected function _doBeforeSave($model) { - return $this; - } - - - protected function _doAfterSave($model) { - return $this; - } - - - /** - * @param Storm_Model_Abstract $model - * @return Zend_Form - */ - protected function _getForm($model) { - $model_values = $this->_getCustomFieldModelValues($model); - $custom_form = $this->_getCustomFieldForm($model_values); - - if ($this->_definitions->getFormClassName()) - return $this->_getFormWith($model, $custom_form); - - if (!$form = $this->_definitions->getForm()) { - $form = new ZendAfi_Form( ['id' => $this->_definitions->getModelName()] ); - $form->populateFormFromGroupsDefinitions($this->_definitions->getDisplayGroups()); - } - - $form = $form->populate($this->_request->getParams()); - $form = $form->populate($this->_getFormValues($model)); - - return $form - ->populate($this->_request->getParams()) - ->populate($this->_getFormValues($model)); - } - - - protected function _getFormValues($model) { - return $model->toArray(); - } - - - protected function _getFormWith($model, $custom_form) { - $formClass = $this->_definitions->getFormClassName(); - foreach ($custom_form->getElements() as $element) { - if (!$value=$this->_request->getParam($element->getName())) - continue; - $element->setValue($value); - } - - $form = $formClass::newWith( - array_merge($this->_getFormValues($model), $this->_request->getParams()), - $custom_form - ); - $form->setAction($this->view->url()); - return $form; - - } - - - /** - * Hook appelé en fin d'action d'édition - * @param $model Storm_Model_Abstract - */ - protected function _postEditAction($model) {} protected function _stayOnPage() { $this->_redirect($this->_request->getServer('HTTP_REFERER')); @@ -484,10 +306,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { } - protected function _getDefaultModel($models) { - return $this->_definitions->newModel(); - } - public function acceptVisitor($plugin) { $plugin @@ -496,7 +314,6 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { ->visitResponse($this->_response) ->visitHelper($this->_helper) ->visitViewRenderer($this->getHelper('ViewRenderer')) - ->visitDefinitions($this->_definitions) ->visitGetParam(function($key) { return $this->_getParam($key); @@ -513,50 +330,25 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action { { $this->_redirect($url); }) - ->visitGetForm(function($model) - { - return $this->_getForm($model); - }) - ->visitGetPost(function() - { - return $this->_getPost(); - }) - ->visitDoBeforeSave(function($model) - { - return $this->_doBeforeSave($model); - }) - ->visitDoAfterSave(function($model) - { - return $this->_doAfterSave($model); - }) - ->visitCustomFieldModelValues(function($model) - { - return $this->_getCustomFieldModelValues($model); - }) - ->visitCustomFieldForm(function($model) + ->visitRedirectClose(function($url, $options = []) + { + $this->_redirectClose($url, $options); + }) + ->visitRedirectToIndex(function() { - return $this->_getCustomFieldForm($model); + $this->_redirectToIndex(); }) ->visitForward(function($action) { return $this->_forward($action); }) - ->visitDefaultModel(function($models) - { - return $this->_getDefaultModel($models); - }) - ->visitProcessMultiCheckbox(function($form, $clean) - { - return $this->processMulticheckboxFromPost($form, $clean); - }) - ->visitCustomValues(function() { - return $this->custom_values; - }) - ->visitAddModelToView(function($model) - { - return $this->_addModelToView($model); - }) - ; + ->visitGetPost(function() + { + return $this->_getPost(); + }) + + ->visitDefinitions($this->_definitions) + ->visitPlugins($this->_plugins); return $this; } } diff --git a/library/ZendAfi/Controller/Action/Plugins.php b/library/ZendAfi/Controller/Action/Plugins.php new file mode 100644 index 00000000000..89bdf119d94 --- /dev/null +++ b/library/ZendAfi/Controller/Action/Plugins.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_Controller_Action_Plugins { + protected $_plugins; + + public function __construct($controller) { + if(!$plugins = $controller->getPlugins()) + $instances = []; + + $instances = array_map(function($plugin) use ($controller) + { + return new $plugin($controller); + }, + $plugins); + + $this->_plugins = new Storm_Collection($instances); + } + + + public function getPlugins() { + return $this->_plugins; + } + + public function init() { + return $this->_plugins->eachDo(function($plugin) + { + $plugin->init(); + }); + } +} +?> \ No newline at end of file diff --git a/library/ZendAfi/Controller/Action/RessourceDefinitions.php b/library/ZendAfi/Controller/Action/RessourceDefinitions.php index ec9a2f0b81d..ba3ef36ca07 100644 --- a/library/ZendAfi/Controller/Action/RessourceDefinitions.php +++ b/library/ZendAfi/Controller/Action/RessourceDefinitions.php @@ -203,7 +203,9 @@ class ZendAfi_Controller_Action_RessourceDefinitions { public function getDisplayGroups() { - return $this->_definitions['display_groups']; + if (isset($this->_definitions['display_groups'])) + return $this->_definitions['display_groups']; + return []; } @@ -239,18 +241,4 @@ class ZendAfi_Controller_Action_RessourceDefinitions { ? $this->_definitions['model_actions'] : []; } - - - public function getPlugins($controller) { - $plugins = []; - - if(isset($this->_definitions['plugins'])) - $plugins = array_map(function($plugin) use ($controller) - { - return new $plugin($controller); - }, - $this->_definitions['plugins']); - - return new Storm_Collection($plugins); - } } \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/Abstract.php b/library/ZendAfi/Controller/Plugin/Abstract.php index bf098086131..66bc8daddcf 100644 --- a/library/ZendAfi/Controller/Plugin/Abstract.php +++ b/library/ZendAfi/Controller/Plugin/Abstract.php @@ -36,7 +36,17 @@ abstract class ZendAfi_Controller_Plugin_Abstract { public function __construct($controller) { - $this->_controller = $controller->acceptVisitor($this); + $this->_controller = $controller; + } + + + public function init(){ + $this->_controller->acceptVisitor($this); + } + + + public function acceptVisitor($visitor) { + return $this; } @@ -50,6 +60,20 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } + public function visitPlugins($plugins) { + $plugins + ->reject(function($plugin) + { + return $plugin == $this; + }) + ->eachDo(function($plugin) + { + $plugin->acceptVisitor($this); + }); + return $this; + } + + public function visitView($view){ $this->_view = $view; return $this; @@ -98,6 +122,18 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } + public function visitRedirectClose($callback) { + $this->_redirect_close = $callback; + return $this; + } + + + public function visitRedirectToIndex($callback) { + $this->_redirect_to_index = $callback; + return $this; + } + + public function visitGetParam($callback) { $this->_get_param = $callback; return $this; @@ -181,11 +217,6 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } - protected function _getDefaultModel($models) { - return call_user_func($this->_default_model, $models); - } - - protected function _getParam($key) { return call_user_func($this->_get_param, $key); } @@ -196,13 +227,18 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } + protected function _redirectToIndex() { + return call_user_func($this->_redirect_to_index); + } + + protected function _redirect($url) { return call_user_func($this->_redirect, $url); } - protected function _getForm($model) { - return call_user_func($this->_get_form, $model); + protected function _redirectClose($url, $options = []) { + return call_user_func_array($this->_redirect_close, [$url, $options]); } @@ -211,31 +247,6 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } - protected function _doBeforeSave($model) { - return call_user_func($this->_do_before_save, $model); - } - - - protected function _getCustomFieldModelValues($model) { - return call_user_func($this->_custom_field_model_values, $model); - } - - - protected function _getCustomFieldForm($model_values) { - return call_user_func($this->_custom_field_form, $model_values); - } - - - protected function _doAfterSave($model) { - return call_user_func($this->_do_after_save, $model); - } - - - public function renderScript($script) { - $this->_controller->renderScript($script); - } - - protected function _setParam($key, $value, $default = null) { return call_user_func_array($this->_set_param, [$key, $value, $default]); } @@ -246,28 +257,8 @@ abstract class ZendAfi_Controller_Plugin_Abstract { } - protected function processMulticheckboxFromPost($form, $clean = false) { - return call_user_func_array($this->_process_multi_checkbox, [$form, $clean]); - } - - - protected function getCustomValues() { - return call_user_func($this->_custom_values); - } - - - protected function _findModel() { - return $this->_definitions->find($this->_getParam('id')); - } - - - protected function _canEdit($model) { - return true; - } - - - protected function _getEditActionTitle($model) { - return $this->_definitions->editActionTitle($model); + public function renderScript($script) { + $this->_controller->renderScript($script); } } ?> \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/Manager/Article.php b/library/ZendAfi/Controller/Plugin/Manager/Article.php index d22c9d6c99a..f38e9dbe20a 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/Article.php +++ b/library/ZendAfi/Controller/Plugin/Manager/Article.php @@ -20,67 +20,168 @@ */ -class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugin_Abstract { +class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugin_Manager_Manager { + public function deleteAction() { + if (!$article = Class_Article::find((int)$this->_getParam('id'))) { + $this->_redirect('admin/cms'); + return; + } + + $this->_view->titre = $this->_view->_('Supprimer l\'article : %s', + $article->getTitre()); + + + if (!$this->_canModify($article->getCategorie())) { + $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', + $this->_view->titre)); + $this->_redirectToIndex(); + return; + } + + $this->_view->model = $article; + } + + +public function newsduplicateAction() { + if (!$model = Class_Article::find($this->_getParam('id'))) + return $this->_redirect('admin/cms'); + + if (!$this->_canModify($model->getCategorie())) { + $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', + $this->_view->titre)); + return $this->_redirectToIndex(); + } + + if($category = $model->getCategorie()) + $this->_setParam('id_cat', $category->getId()); - public function editAction() { + parent::addAction(); if ($this->_response->isRedirect()) return; + $this->_view->titre = $this->_view->_('Dupliquer l\'article : %s', $model->getTitre()); + $this->_view->form + ->setAction($this->_view->url(['module' => 'admin', + 'controller' => 'cms', + 'action' => 'add', + 'id_cat' => $this->_getParam('id_cat')], + null, true)); + + $this->_view_renderer->setScriptAction('add'); + } - if (!$model = $this->_findModel()) { - $this->_redirectToIndex(); + + public function makevisibleAction() { + $this->_toggleVisibility('visible'); + } + + + public function makeinvisibleAction() { + $this->_toggleVisibility('invisible'); + } + + + public function forceDeleteAction() { + if (!$article = Class_Article::find((int)$this->_getParam('id'))) { + $this->_redirect('admin/cms'); return; } - if (!$this->_canEdit($model)) { + if (!$this->_canModify($article->getCategorie())) { $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', - $this->_getEditActionTitle($model))); + $this->_view->_('Supprimer l\'article : %s', + $article->getTitre()))); $this->_redirectToIndex(); return; } - $this->_view->titre = $this->_getEditActionTitle($model); - $this->_addModelToView($model); + $article->delete(); + $this->_redirect($this->_backDeleteUrl($article)); + } + + + protected function _getDefaultModel($models) { + $article = $this->_definitions->newModel(); + $cat = Class_ArticleCategorie::findDistinctCategories($models); + if (count($cat)==1) { + $article->setCategorie($cat[0]); + } - if ($this->_setupFormAndSave($model)) { - $this->_helper->notify($this->_definitions->successfulSaveMessage($model)); - $this->_redirectToEdit($model); - $this->_definitions->doAfterEdit($model); + $status = Class_Article::findDistinctStatus($models); + if (count($status)==1) { + $article->setStatus($status[0]->getStatus()); } - $this->_postEditAction($model); + return $article; } - protected function _setupFormAndSave($model) { - $form = $this->_getForm($model); + protected function _updateNewModel($article) { + if ('newsduplicate' == $this->_request->getActionName() + && $original = Class_Article::find($this->_getParam('id', 0))) { + $article->updateAttributes($original->copy()->toArray()); + return $this; + } - $this->_view->form = $form; - if (!$this->_request->isPost()) - return false; + $article->setAuteur(Class_Users::getIdentity()); - $post = $this->processMulticheckboxFromPost($form); - $model->updateAttributes($post); + if (!$category = $this->getCategoryAndSetComboCat()) + return $this; - if ((!$form->isValidModelAndArray($model, $this->_getPost()))) - return false; + $article->setCategorie($category); + if ($domaine = Class_Catalogue::findWithSamePathAs($category)) + $article->setDomaineIds($domaine->getId()); + return $this; + } - $this->_doBeforeSave($model); - if (!$model->save()) - return false; + public function getCategoryAndSetComboCat() { + if (!$category = Class_ArticleCategorie::find($this->_getParam('id_cat'))) { + $this->_redirect('admin/cms'); + return; + } - $model_values = $this->_getCustomFieldModelValues($model); - $custom_form = $this->_getCustomFieldForm($model_values); - $custom_form->populate($this->custom_values); - $custom_form->updateModelValues(); - $model_values->save(); + if (null === ($category->getBib())) + $category->setBib($this->_bib); - $this->_doAfterSave($model); - return true; + $this->_view->combo_cat = $this->_view->comboCategories($category); + return $category; } - protected function _postEditAction($model) {} + + protected function _doBeforeSave($article) { + $article->updateDateMaj(); + return $this; + } + + + protected function _doAfterSave($article) { + if($id_module = $this->_getParam('id_module')) + $this->updateConfigBoiteNews($id_module,$article); + $this->_notifyArticleChanged($article); + return $this; + } + + + protected function _toggleVisibility($visibility) { + if (!$article = Class_Article::getLoader()->find((int)$this->_getParam('id'))) { + $this->_redirect('admin/cms'); + return; + } + + if (!$this->_canModify($article->getCategorie())) { + $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', + $this->_view->_('Rendre %s l\'article : %s', + $visibility, + $article->getTitre()))); + $this->_redirectToIndex(); + return; + } + + $method = 'be' . ucfirst($visibility); + $article->$method(); + $this->_redirect($this->_backUrl($article)); + } protected function _findModel() { @@ -115,7 +216,213 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi } - public function getActions($model) { + protected function _getEditUrl($model) { + $this->_request->setParamSources(['_GET']); + $url = parent::_getEditUrl($model) + . (($page = $this->_getParam('page')) ? '/page/'.$page : '') + . (($id_cat = $this->_getParam('id_cat')) ? '/id_cat/'.$id_cat : '') + . (($title_search = $this->_getParam('title_search')) ? '/title_search/' . $title_search : ''); + $this->_request->setParamSources(['_GET', '_POST']); + return $url; + } + + + protected function _getFormValues($model) { + $attributes=parent::_getFormValues($model); + foreach(['description', 'contenu'] as $content_field) + $attributes[$content_field] = Class_CmsUrlTransformer::forEditing($attributes[$content_field]); + + $attributes['pick_day'] = $model->getPickDayAsArray(); + return $attributes; + } + + + protected function _getForm($model) { + $this + ->_definitions + ->setFormClassName($model->isTraduction() + ? 'ZendAfi_Form_Admin_NewsTranslation' + : 'ZendAfi_Form_Admin_News'); + $form = parent::_getForm($model); + $form->setAttrib('data-backurl', Class_Url::absolute($this->_backUrl($model))); + return $form; + } + + + protected function _canAdd() { + $category = Class_ArticleCategorie::find($this->_getParam('id_cat')); + return $category && $this->_canModify($category); + } + + + + protected function _backUrl($model) { + if (!Class_AdminVar::isArticlesListMode()) + return 'admin/cms/index' . (!$model->isNew() ? '/id/' . $model->getId() : ''); + + return $this->_view->absoluteUrl(['module' => 'admin', + 'controller' => 'cms', + 'action' => 'index']); + } + + + protected function _backDeleteUrl($model) { + return sprintf('admin/cms/index/id_cat/%d%s', + ($cat = $model->getCategorie()) ? $cat->getId() : 0, + ($page = $this->_getParam('page')) ? '/page/'.$page : ''); + } + + protected function _notifyArticleChanged($article) { + if (!Class_AdminVar::isWorkflowEnabled()) + return; + $this->_sendMailWhenUpdatedStatusToValidationPending($article); + $this->_sendMailWhenUpdatedStatusToRefused($article); + $this->_sendMailWhenUpdatedStatusToValidated($article); + } + + + protected function _sendMailWhenUpdatedStatusToRefused($article) { + if ($article->old_status != Class_Article::STATUS_REFUSED && + $article->getStatus() == Class_Article::STATUS_REFUSED) { + $this->_sendRefusedMailToAuteur($article); + } + } + + + protected function _sendMailWhenUpdatedStatusToValidated($article) { + if ($article->old_status != Class_Article::STATUS_VALIDATED && + $article->getStatus() == Class_Article::STATUS_VALIDATED) { + $this->_sendValidatedMailToAuteur($article); + } + } + + + protected function _sendMailWhenUpdatedStatusToValidationPending($article) { + if (($article->old_status != Class_Article::STATUS_VALIDATION_PENDING && + $article->getStatus() == Class_Article::STATUS_VALIDATION_PENDING) + || ($article->getStatus() > 5 + && $article->old_status != $article->getStatus())) { + $this->_sendMailToValidators($article); + } + } + + + protected function prepareMailForAuteur($article) { + $mail = new ZendAfi_Mail('utf8'); + if(!$article->getAuteur()) { + $this->_helper->notify('Mail non envoyé: article sans auteur'); + return; + } + + if(!$mail_address = $article->getAuteur()->getMail()) { + $this->_helper->notify('Mail non envoyé: '.$article->getNomCompletAuteur().' sans mail.'); + return; + } + + $mail->setFrom('no-reply@afi-sa.fr') + ->addTo($mail_address); + return $mail; + } + + + protected function prepareBodyMail($article, $message) { + $this->identity = Class_Users::getIdentity(); + $replacements = + ['TITRE_ARTICLE' => $article->getTitre(), + 'URL_ARTICLE' => $this->_view->absoluteUrl($article->getUrl(), null, true), + 'AUTHOR_ARTICLE' => $article->getNomCompletAuteur(), + 'SAVED_BY_ARTICLE' => $this->identity->getNomComplet(), + 'NEXT_STATUS_ARTICLE' => $article->getNextWorkflowStatusLabel(), + 'STATUS_ARTICLE' => $article->getStatusLabel()]; + + return + str_replace(array_keys($replacements), + array_values($replacements), + $message); + } + + + protected function _sendRefusedMailToAuteur($article) { + if(!$mail = $this->prepareMailForAuteur($article)) + return; + $body = $this->prepareBodyMail($article, $article->getRefusMessage()); + $this->sendPreparedMail($mail, + '[Bokeh] Refus de l\'article '.$article->getTitre(), + $body); + } + + + protected function sendPreparedMail($mail, $subject, $body) { + $mail->setSubject(quoted_printable_decode($subject)) + ->setBodyText($body,'utf-8',Zend_Mime::ENCODING_8BIT); + + if ($this->_sendMail($mail)) + $this->_helper->notify('Mail envoyé à : '.$mail->getRecipients()[0]); + } + + + protected function _sendValidatedMailToAuteur($article) { + if(!$mail = $this->prepareMailForAuteur($article)) + return; + + $body = $this->prepareBodyMail($article, $article->getValideMessage()); + $this->sendPreparedMail($mail, + '[Bokeh] Validation de l\'article '.$article->getTitre(), + $body); + } + + + protected function _getValidatorsMail($article) { + return array_unique( + Class_Permission::getWorkflow($article->getNextWorkflowStatus()) + ->getUsersOnModel($article->getCategorie()) + ->collect('mail') + ->getArrayCopy()); + } + + + protected function _sendMailToValidators($article) { + if (!$mails = $this->_getValidatorsMail($article)) + return; + + $mail = new ZendAfi_Mail('utf8'); + $mail + ->setFrom('no-reply@afi-sa.fr') + ->addTo(implode(',', $mails)) + ->setSubject($this->_view->_('[Bokeh] Validation d\'article en attente: ') . $article->getTitre()) + ->setBodyText($this->prepareBodyMail($article, + Class_AdminVar::getWorkflowTextMailArticlePending())); + + if($this->_sendMail($mail)) + $this->_helper->notify($this->_view->_('Mail de validation envoyé aux validateurs.')); + } + + + protected function _sendMail($mail) { + try { + $mail->send(); + return true; + + } catch (Exception $e) { + $this->_helper->notify('Mail non envoyé: vérifier la configuration du serveur de mail.'); + return false; + } + } + + + protected function updateConfigBoiteNews($id_module, $article){ + $profil = Class_Profil::getCurrentProfil(); + $module_config = $profil->getModuleAccueilConfig($id_module, 'NEWS'); + $id_items= array_filter(explode('-',$module_config['preferences']['id_items'])); + array_unshift($id_items,$article->getId()); + $module_config['preferences']['id_items'] = implode('-',$id_items); + $profil->updateModuleConfigAccueil($id_module, $module_config); + $profil->save(); + return $this; + } + + + public function getActions($model) { if('Class_Article' == get_class($model)) return $this->_articleActions($model); @@ -144,14 +451,14 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi 'label' => 'Rendre cet article invisible', 'condition' => function($model) use ($permission_closure) { return $permission_closure($model) && $model->isVisible(); - }], + }], ['url' => '/admin/cms/makevisible/id/%s', 'icon' => 'hide', 'label' => 'Rendre cet article visible', 'condition' => function($model) use ($permission_closure) { return $permission_closure($model) && $model->isNotVisible(); - }], + }], ['url' => '/admin/cms/edit/id/%s', 'icon' => 'edit', @@ -190,7 +497,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi 'label' => 'Supprimer', 'condition' => function($model) use ($parent_permission) { return $parent_permission($model) && $model->hasNoChild(); - }, + }, 'anchorOptions' => [ 'onclick' => "return confirm('Etes-vous sûr de vouloir supprimer cette catégorie ?')"]], @@ -202,7 +509,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi ->hasAnyPermissionOn($model, [Class_Permission::createArticle(), Class_Permission::createArticleCategory()]); - }], + }], ['url' => '/admin/cms-category/add/id/%s', 'icon' => 'add_category', @@ -211,7 +518,7 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi return $this->identity ->hasPermissionOn(Class_Permission::createArticleCategory(), $model); - }] + }] ]; } @@ -227,13 +534,13 @@ class ZendAfi_Controller_Plugin_Manager_Article extends ZendAfi_Controller_Plugi return $this->_identity->isRoleMoreThanModoPortail() || $this->_identity->hasPermissionOn(Class_Permission::createArticleCategory(), $model); - }], + }], ['url' => '/admin/bib/permissions/id/%s', 'icon' => 'groups', 'label' => 'Permissions par défaut', 'condition' => function($model) { return $this->_identity->isRoleMoreThanModoPortail(); - }] + }] ]; } } \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/Manager/ArticleCategory.php b/library/ZendAfi/Controller/Plugin/Manager/ArticleCategory.php new file mode 100644 index 00000000000..acbe3c0d9fc --- /dev/null +++ b/library/ZendAfi/Controller/Plugin/Manager/ArticleCategory.php @@ -0,0 +1,112 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_Controller_Plugin_Manager_ArticleCategory extends ZendAfi_Controller_Plugin_Manager_Manager { + protected function _updateNewModel($model) { + if ($parent = Class_ArticleCategorie::find($this->_getParam('id'))) { + $model->setParentCategorie($parent) + ->setBib($parent->getBib()); + return; + } + + $this->_handleBibFor($model); + } + + + protected function _handleBibFor($category) { + if ($bib = $this->getDefaultBib()) + $category->setBib($bib); + } + + + protected function _redirectToTreeView($model) { + $this->_redirect($this->_backUrl($model)); + } + + + protected function _backUrl($model) { + $is_list_mode = Class_AdminVar::isArticlesListMode(); + if (($model->isNew() || $is_list_mode) + && $parent = $model->getParentCategorie()) + return $this->_withPageUrl(sprintf('admin/cms/index/id_cat/%d', $parent->getId())); + + return $this->_withPageUrl($is_list_mode ? + sprintf('admin/cms/index/id_bib/%d', + ($bib = $model->getBib()) ? $bib->getId() : 0) : + sprintf('admin/cms/index/id_cat/%d', $model->getId())); + } + + + protected function _deleteBackUrl($model) { + $is_list_mode = Class_AdminVar::isArticlesListMode(); + if ($parent = $model->getParentCategorie()) + return $this->_withPageUrl(sprintf('admin/cms/index/id_cat/%d', $parent->getId())); + + return $this->_withPageUrl($is_list_mode ? + sprintf('admin/cms/index/id_bib/%d', + ($bib = $model->getBib()) ? $bib->getId() : 0) : + 'admin/cms/index'); + } + + + protected function _withPageUrl($url) { + return ($page = $this->_getParam('page')) + ? $url . '/page/' . $page : $url; + } + + + protected function _postEditAction($model) { + if (null === $model->getBib()) + $this->_handleBibFor($model); + + if (Class_Users::getIdentity()->isRoleMoreThanModoPortail()) + $this->view->permissions = $this->view + ->groupsPermissions($model, + Class_Permission::getCmsPermissions(), + $this->view->url(['module' => 'admin', + 'controller' => 'cms-category', + 'action' => 'permissions', + 'id' => $model->getId()], + null, true)); + } + + + protected function getDefaultBib() { + $identity = Class_Users::getIdentity(); + + return ZendAfi_Acl_AdminControllerRoles::ADMIN_BIB >= $identity->getRoleLevel() ? + $identity->getBib() : Class_Bib::find((int)$this->_getParam('id_bib')); + } + + + + /** + * @param Storm_Model_Abstract $model + * @return Zend_Form + */ + protected function _getForm($model) { + $form = parent::_getForm($model); + $form->setAttrib('data-backurl', Class_Url::absolute($this->_backUrl($model))); + return $form; + } +} +?> \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/Manager/Manager.php b/library/ZendAfi/Controller/Plugin/Manager/Manager.php new file mode 100644 index 00000000000..dbbd4d74ecf --- /dev/null +++ b/library/ZendAfi/Controller/Plugin/Manager/Manager.php @@ -0,0 +1,297 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +abstract class ZendAfi_Controller_Plugin_Manager_Manager extends ZendAfi_Controller_Plugin_Abstract { + + public function acceptVisitor($visitor) { + $visitor->visitGetForm(function($model) + { + return $this->_getForm($model); + }) + ->visitDoBeforeSave(function($model) + { + return $this->_doBeforeSave($model); + }) + ->visitDoAfterSave(function($model) + { + return $this->_doAfterSave($model); + }) + ->visitCustomFieldModelValues(function($model) + { + return $this->_getCustomFieldModelValues($model); + }) + ->visitCustomFieldForm(function($model) + { + return $this->_getCustomFieldForm($model); + }) + ->visitDefaultModel(function($models) + { + return $this->_getDefaultModel($models); + }) + ->visitProcessMultiCheckbox(function($form, $clean) + { + return $this->processMulticheckboxFromPost($form, $clean); + }) + ->visitCustomValues(function() { + return $this->custom_values; + }) + ->visitAddModelToView(function($model) + { + return $this->_addModelToView($model); + }); + return $this; + } + + + protected function _getDefaultModel($models) { + return $this->_definitions->newModel(); + } + + + protected function _addModelToView($model) { + $model_name = $this->_definitions->getModelName(); + $this->_view->model_name = $model_name; + $this->_view->$model_name = $model; + } + + + public function addAction() { + if ($this->_response->isRedirect()) + return; + + if (!$this->_canAdd()) { + $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', + $this->_definitions->addActionTitle())); + $this->_redirectToIndex(); + return; + } + + $this->_view->titre = $this->_definitions->addActionTitle(); + $model = $this->_definitions->newModel(); + $this->_updateNewModel($model); + $this->_addModelToView($model); + + if ($this->_setupFormAndSave($model)) { + $this->_helper->notify($this->_definitions->successfulAddMessage($model)); + $this->_redirectToEdit($model); + $this->_definitions->doAfterAdd($model); + } + } + + + public function editAction() { + if ($this->_response->isRedirect()) + return; + + if (!$model = $this->_findModel()) { + $this->_redirectToIndex(); + return; + } + + if (!$this->_canEdit($model)) { + $this->_helper->notify($this->_view->_('Vous n\'avez pas la permission "%s"', + $this->_getEditActionTitle($model))); + $this->_redirectToIndex(); + return; + } + + $this->_view->titre = $this->_getEditActionTitle($model); + $this->_addModelToView($model); + + if ($this->_setupFormAndSave($model)) { + $this->_helper->notify($this->_definitions->successfulSaveMessage($model)); + $this->_redirectToEdit($model); + $this->_definitions->doAfterEdit($model); + } + + $this->_postEditAction($model); + } + + + + public function deleteAction() { + if ($this->_response->isRedirect()) + return; + + if ($model = $this->_findModel()) { + $values = $this->_getCustomFieldModelValues($model); + $values->deleteValues(); + $model->delete(); + $this->_helper->notify($this->_definitions->successfulDeleteMessage($model)); + } + $this->_redirectToIndex(); + $this->_definitions->doAfterDelete($model); + } + + + + + + protected function _postEditAction($model) {} + protected function _canEdit($model) { + return true; + } + + + protected function _getEditActionTitle($model) { + return $this->_definitions->editActionTitle($model); + } + + + protected function _getEditUrl($model) { + return sprintf('/admin/%s/edit/id/%s', + $this->_request->getControllerName(), $model->getId()); + } + + + protected function _redirectToEdit($model) { + $this->_redirectClose($this->_getEditUrl($model)); + } + + + protected function _getFormWith($model, $custom_form) { + $formClass = $this->_definitions->getFormClassName(); + foreach ($custom_form->getElements() as $element) { + if (!$value=$this->_request->getParam($element->getName())) + continue; + $element->setValue($value); + } + + $form = $formClass::newWith( + array_merge($this->_getFormValues($model), $this->_request->getParams()), + $custom_form + ); + $form->setAction($this->_view->url()); + return $form; + + } + + + protected function _getFormValues($model) { + return $model->toArray(); + } + + + /** + * @param Storm_Model_Abstract $model + * @return Zend_Form + */ + protected function _getForm($model) { + $model_values = $this->_getCustomFieldModelValues($model); + $custom_form = $this->_getCustomFieldForm($model_values); + + if ($this->_definitions->getFormClassName()) + return $this->_getFormWith($model, $custom_form); + + if (!$form = $this->_definitions->getForm()) { + $form = new ZendAfi_Form( ['id' => $this->_definitions->getModelName()] ); + $form->populateFormFromGroupsDefinitions($this->_definitions->getDisplayGroups()); + } + + $form = $form->populate($this->_request->getParams()); + $form = $form->populate($this->_getFormValues($model)); + + return $form + ->populate($this->_request->getParams()) + ->populate($this->_getFormValues($model)); + } + + + protected function _setupFormAndSave($model) { + $form = $this->_getForm($model); + + $this->_view->form = $form; + if (!$this->_request->isPost()) + return false; + + $post = $this->processMulticheckboxFromPost($form); + $model->updateAttributes($post); + + if ((!$form->isValidModelAndArray($model, $this->_getPost()))) + return false; + + $this->_doBeforeSave($model); + + if (!$model->save()) + return false; + + $model_values = $this->_getCustomFieldModelValues($model); + $custom_form = $this->_getCustomFieldForm($model_values); + $custom_form->populate($this->custom_values); + $custom_form->updateModelValues(); + $model_values->save(); + + $this->_doAfterSave($model); + return true; + } + + + protected function _doBeforeSave($model) { + return $this; + } + + + protected function _doAfterSave($model) { + return $this; + } + + protected function processMulticheckboxFromPost($form, $clean = false) { + $defaults = []; + foreach ($form->getMulticheckboxNames() as $checkbox_name) + $defaults[$checkbox_name] = []; + + $post = array_merge($defaults, $this->_getPost()); + if ($clean) + $post = $form->deleteUnchanged($post); + + $this->custom_values = []; + + foreach ($post as $k=>$v) + if (preg_match('/field_[0-9]+/', $k)) { + $this->custom_values[$k] = $v; + unset($post[$k]); + } + return $post; + } + + + + protected function _updateNewModel($model) { + return $this; + } + + + protected function _canAdd() { + return true; + } + + + protected function _getCustomFieldModelValues($model) { + return Class_CustomField_Model::getModel($this->_definitions->getModelClass()) + ->find($model->getId()); + } + + + protected function _getCustomFieldForm($model_values) { + return new ZendAfi_Form_Admin_CustomFields_ModelValues(['model_values' => $model_values]); + } +} \ No newline at end of file diff --git a/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php b/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php index 8daaf34df0d..8ea0849de94 100644 --- a/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php +++ b/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php @@ -61,8 +61,8 @@ abstract class ZendAfi_Controller_Plugin_MultiSelection_Abstract extends ZendAfi return $this->_redirectToIndex(); $this->_view->titre = $this->_('Modifier %d %s', - $models->count(), - $this->_definitions->pluralizeModelName()); + $models->count(), + $this->_definitions->pluralizeModelName()); if ($this->_setupFormAndUpdateModels($models->getArrayCopy())) { $this->_helper->notify($this->_('Les %d %s sélectionnés ont bien été sauvegardés', @@ -145,4 +145,49 @@ abstract class ZendAfi_Controller_Plugin_MultiSelection_Abstract extends ZendAfi public function render() { return $this->_view->Plugin_MultiSelection_Widget($this->_multi_selection); } + + + protected function _getForm($model) { + return call_user_func($this->_get_form, $model); + } + + + protected function _doBeforeSave($model) { + return call_user_func($this->_do_before_save, $model); + } + + + protected function _getCustomFieldModelValues($model) { + return call_user_func($this->_custom_field_model_values, $model); + } + + + protected function _getCustomFieldForm($model_values) { + return call_user_func($this->_custom_field_form, $model_values); + } + + + protected function _doAfterSave($model) { + return call_user_func($this->_do_after_save, $model); + } + + + protected function processMulticheckboxFromPost($form, $clean = false) { + return call_user_func_array($this->_process_multi_checkbox, [$form, $clean]); + } + + + protected function getCustomValues() { + return call_user_func($this->_custom_values); + } + + + protected function _findModel() { + return $this->_definitions->find($this->_getParam('id')); + } + + + protected function _getDefaultModel($models) { + return call_user_func($this->_default_model, $models); + } } diff --git a/tests/application/modules/admin/controllers/CmsControllerTest.php b/tests/application/modules/admin/controllers/CmsControllerTest.php index 4e7921161b6..b3cff3ef621 100644 --- a/tests/application/modules/admin/controllers/CmsControllerTest.php +++ b/tests/application/modules/admin/controllers/CmsControllerTest.php @@ -560,7 +560,7 @@ class CmsControllerArticleDuplicateActionTest extends CmsControllerWithPermissio /** @test */ public function titreShouldBeDupliquerLArticleConcert() { - $this->assertXPathContentContains('//h1', 'Dupliquer l\'article: Concert'); + $this->assertXPathContentContains('//h1', 'Dupliquer l\'article : Concert'); } } @@ -2696,7 +2696,7 @@ class CmsControllerCategorieEvenementTest extends CmsControllerWithPermissionTes public function deleteShouldRedirectToAdminCmsParentCategorie() { $this->dispatch('/admin/cms-category/delete/id/34'); - $this->assertRedirectTo('/admin/cms/index/id_cat/23'); + $this->assertRedirect(); $this->assertEquals($this->cat_evenements, $this->categorie_wrapper->getFirstAttributeForLastCallOn('delete')); @@ -2713,8 +2713,7 @@ class CmsControllerCategorieEvenementTest extends CmsControllerWithPermissionTes /** @test */ public function addCategorieCancelButtonShouldLinkToIndexIdCat34() { $this->dispatch('/admin/cms-category/add/id/34'); - $this->assertXPath("//div[contains(@onclick, '/admin/cms/index/id_cat/34')]", - $this->_response->getBody()); + $this->assertXPath("//div[contains(@onclick, '/admin/cms/index/id_cat/34')]"); } @@ -2740,7 +2739,7 @@ class CmsControllerCategorieEvenementTest extends CmsControllerWithPermissionTes 'id_cat_mere' => 34]); - $this->assertEquals('/admin/cms/index/id_cat/35', $this->getResponseLocation()); + $this->assertRedirect(); $new_cat = $this->categorie_wrapper->getFirstAttributeForLastCallOn('save'); $this->assertEquals('concerts', $new_cat->getLibelle()); @@ -2758,7 +2757,7 @@ class CmsControllerCategorieEvenementTest extends CmsControllerWithPermissionTes ->setPost(array('libelle' => 'Actualite', 'id_cat_mere' => 254)); $this->dispatch('/admin/cms-category/edit/id/34'); - $this->assertEquals('/admin/cms/index/id_cat/34', $this->getResponseLocation()); + $this->assertRedirect(); $this->assertEquals('Actualite', $this->cat_evenements->getLibelle()); $this->assertEquals(254, $this->cat_evenements->getIdCatMere()); $this->assertTrue($this->categorie_wrapper->methodHasBeenCalled('save')); diff --git a/tests/scenarios/Manager/ManagerTest.php b/tests/scenarios/Manager/ManagerTest.php index dcb29e4d798..76595f8e90d 100644 --- a/tests/scenarios/Manager/ManagerTest.php +++ b/tests/scenarios/Manager/ManagerTest.php @@ -84,21 +84,71 @@ class ManagerArticleTest extends Admin_AbstractControllerTestCase { -class ManagerCmsEditActionTest extends Admin_AbstractControllerTestCase { +class ManagerCmsActionsTest extends Admin_AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + public function setUp() { parent::setUp(); + $this->fixture('Class_ArticleCategorie', + ['id' => 56, + 'libelle' => 'news']); + $this->fixture('Class_Article', ['id' => 23, 'titre' => 'Happy new year', - 'contenu' => 'Bonne année']); - $this->dispatch('/admin/cms/edit/id/23', true); + 'contenu' => 'Bonne année', + 'id_cat' => 56]); } /** @test */ - public function titleShouldBeEditHappyNewYear() { + public function editActionShouldBeEditHappyNewYear() { + $this->dispatch('/admin/cms/edit/id/23', true); $this->assertXPathContentContains('//h1', 'Modifier un article: Happy new year'); } + + + /** @test */ + public function addActionTitleShouldBeAddNewArticle() { + $this->dispatch('/admin/cms/add/id_cat/56', true); + $this->assertXPathContentContains('//h1', 'Ajouter un article'); + } + + + /** @test */ + public function deleteActionTitleShouldBeDeleteHappyNewYear() { + $this->dispatch('/admin/cms/delete/id/23', true); + $this->assertXPathContentContains('//h1', 'Supprimer l\'article : Happy new year'); + } + + + /** @test */ + public function duplicateActionTitleShouldBeAddNewArticle() { + $this->dispatch('/admin/cms/newsduplicate/id/23', true); + $this->assertXPathContentContains('//h1', 'Dupliquer l\'article : Happy new year'); + } + + + /** @test */ + public function forceDeleteActionShouldRedirect() { + $this->dispatch('/admin/cms/force-delete/id/23', true); + $this->assertRedirectTo('/admin/cms/index/id_cat/56'); + } + + + /** @test */ + public function makeVisibleActionShouldRedirect() { + $this->dispatch('/admin/cms/makevisible/id/23', true); + $this->assertRedirectTo('/admin/cms/index/id/23'); + } + + + /** @test */ + public function makeInvisibleActionShouldRedirect() { + $this->dispatch('/admin/cms/makeinvisible/id/23', true); + $this->assertRedirectTo('/admin/cms/index/id/23'); + } + } -- GitLab