From bf479ac4c5b48ecfa7915f246bf774d7ac3d6321 Mon Sep 17 00:00:00 2001
From: pbarroca <pbarroca@afi-sa.fr>
Date: Thu, 24 Jul 2014 19:43:28 +0200
Subject: [PATCH] rel #12993 : User group adding use generic
 ZendAfi_Controlle_Action and ZendAfi_Form mechanics with custom fields

---
 .../admin/controllers/UsergroupController.php | 38 ++++---
 .../admin/views/scripts/usergroup/add.phtml   |  1 +
 library/ZendAfi/Controller/Action.php         | 60 +++++++++---
 library/ZendAfi/Form.php                      | 37 +++++++
 library/ZendAfi/Form/Admin/UserGroup.php      | 98 +++++++++++++++++++
 .../UsergroupControllerMultimediaTest.php     | 14 +--
 6 files changed, 213 insertions(+), 35 deletions(-)
 create mode 100644 application/modules/admin/views/scripts/usergroup/add.phtml
 create mode 100644 library/ZendAfi/Form/Admin/UserGroup.php

diff --git a/application/modules/admin/controllers/UsergroupController.php b/application/modules/admin/controllers/UsergroupController.php
index 54c9391677f..2cc6664490c 100644
--- a/application/modules/admin/controllers/UsergroupController.php
+++ b/application/modules/admin/controllers/UsergroupController.php
@@ -18,9 +18,27 @@
  * along with AFI-OPAC 2.0; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
  */
-class Admin_UsergroupController extends Zend_Controller_Action {
+class Admin_UsergroupController extends ZendAfi_Controller_Action {
 	use Trait_Translator;
 
+	public function getRessourceDefinitions() {
+		return [
+			'model' => [
+				'class' => 'Class_UserGroup', 
+				'name' => 'user_group',
+				'order' => 'id'],
+
+			'messages' => [
+				'successful_save' => $this->_('Groupe "%s" sauvegardé'),
+				'successful_add' => $this->_('Groupe "%s" ajouté')],
+
+			'actions' => [
+				'add' => ['title' => $this->_("Ajouter un groupe d'utilisateurs")],
+				'edit' => ['title' => $this->_("Modifier le groupe d'utilisateurs: %s")]],
+
+			'form_class_name' => 'ZendAfi_Form_Admin_UserGroup'];
+	}
+
 	public function indexAction() {
 		$this->view->titre = "Gestion des groupes d'utilisateurs";
 		$bib= Class_Bib::getPortail();
@@ -49,11 +67,9 @@ class Admin_UsergroupController extends Zend_Controller_Action {
 	}
 
 
-	public function addAction() {
-		$categorie = Class_UserGroupCategorie::find((int)$this->_getParam('id_cat'));
-		$this->view->titre = "Ajouter un groupe d'utilisateurs";
-		$new_group = Class_UserGroup::getLoader()->newInstance()->setCategorie($categorie);
-		$this->_setupGroupFormAndSave('add', $new_group);
+	public function _updateNewModel($model) {
+		$model->setCategorie(Class_UserGroupCategorie::find((int)$this->_getParam('id_cat')));
+		return $this;
 	}
 
 
@@ -148,16 +164,6 @@ class Admin_UsergroupController extends Zend_Controller_Action {
 	}
 
 
-	protected function _getCustomFieldModelValues($model) {
-		return Class_CustomField_Model::getModel('UserGroup')->find($model->getId());
-	}
-
-
-	protected function _getCustomFieldForm($model_values) {
-		return new ZendAfi_Form_Admin_CustomFields_ModelValues(['model_values' => $model_values]);
-	}
-
-
 	protected function _groupForm($action, $group, $custom_form) {
 		$form = $this->view
 			->newForm(['id' => 'usergroupform'])
diff --git a/application/modules/admin/views/scripts/usergroup/add.phtml b/application/modules/admin/views/scripts/usergroup/add.phtml
new file mode 100644
index 00000000000..c52ca489f90
--- /dev/null
+++ b/application/modules/admin/views/scripts/usergroup/add.phtml
@@ -0,0 +1 @@
+<?php echo $this->renderForm($this->form); ?>
diff --git a/library/ZendAfi/Controller/Action.php b/library/ZendAfi/Controller/Action.php
index 5e5bd3b167a..df5da84ae26 100644
--- a/library/ZendAfi/Controller/Action.php
+++ b/library/ZendAfi/Controller/Action.php
@@ -123,6 +123,7 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 	public function addAction() {
 		$this->view->titre = $this->_definitions->addActionTitle();
 		$model = $this->_definitions->newModel();
+		$this->_updateNewModel($model);
 
 		if ($this->_setupFormAndSave($model)) {
 			$this->_helper->notify($this->_definitions->successfulAddMessage($model));
@@ -132,6 +133,23 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 	}
 
 
+	protected function _updateNewModel($model) {
+		return $this;
+	}
+
+
+
+	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 _redirectToIndex() {
 		$url = '/admin/'.$this->_request->getControllerName().'/index';
 		if (($scope_field = $this->_definitions->getScope()) 
@@ -169,9 +187,24 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 		$this->view->form = $form;
 
 		if ($this->_request->isPost()) {
-			$model->updateAttributes($this->_request->getPost());
-			if ($form->isValid($model))
-				return $model->save();
+			$post = $this->_request->getPost();
+			$custom_values = [];
+			foreach ($post as $k=>$v)
+				if ('field_' == substr($k, 0, 6)) {
+					$custom_values[$k] = $v;
+					unset($post[$k]);
+				}
+
+			$model->updateAttributes($post);
+			if ((!$form->isValid($model)) || (!$model->save()))
+				return false;
+
+			$model_values = $this->_getCustomFieldModelValues($model);
+			$custom_form = $this->_getCustomFieldForm($model_values);
+			$custom_form->populate($custom_values);
+			$custom_form->updateModelValues();
+			$model_values->save();
+			return true;
 		}
 		return false;
   }
@@ -182,13 +215,14 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 	 * @return Zend_Form
 	 */
 	protected function _getForm($model) {
-		
-		if($this->_definitions->getFormClassName())
-			return $this->_getFormWith($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 = new ZendAfi_Form( ['id' => $this->_definitions->getModelName()] );	
 			$form->populateFormFromGroupsDefinitions($this->_definitions->getDisplayGroups());
 		}
 
@@ -198,10 +232,12 @@ class ZendAfi_Controller_Action extends Zend_Controller_Action {
 	}
 
 
-	protected function _getFormWith($model) {
-		if($form = call_user_func_array([$this->_definitions->getFormClassName(),'newWith'],	[array_merge($model->toArray(), $this->_request->getParams())]))
-			return $form;
-		
+	protected function _getFormWith($model, $custom_form) {
+		$formClass = $this->_definitions->getFormClassName();
+		return $formClass::newWith(
+			array_merge($model->toArray(), $this->_request->getParams()), 
+			$custom_form
+		);
 	}
 
 
diff --git a/library/ZendAfi/Form.php b/library/ZendAfi/Form.php
index f19ea2d349b..fabecef5d34 100644
--- a/library/ZendAfi/Form.php
+++ b/library/ZendAfi/Form.php
@@ -31,6 +31,13 @@ class ZendAfi_Form extends Zend_Form {
 	}
 
 
+	public static function newWith($datas = [], $custom_form) {
+		return (new static())
+			->populate($datas)
+			->setCustomForm($custom_form);
+	}
+
+
 	public function init() {
 		parent::init();
 		$this
@@ -44,6 +51,36 @@ class ZendAfi_Form extends Zend_Form {
 	}
 
 
+	public function setCustomForm($custom_form) {
+		if (!$custom_form)
+			return $this;
+
+		$custom_elements = $custom_form->getElements();
+		$this->addElements($custom_elements);
+
+		$groups = $this->getDisplayGroups();
+		if (empty($groups))
+			return $this;
+
+		$first_group = reset($groups);
+		$this->removeDisplayGroup($first_group->getName());
+		$element_names = [];
+		foreach($first_group->getElements() as $element)
+			$element_names[] = $element->getName();
+		foreach($custom_elements as $element)
+			$element_names[] = $element->getName();
+
+		$this->addDisplayGroup(
+			$element_names, 
+			$first_group->getName(), 
+			[
+				'legend' => $first_group->getLegend(),
+				'order' => -1]);
+
+		return $this;
+	}
+
+
 	/**
 	 * @param $name string
 	 * @return Zend_Form_Element
diff --git a/library/ZendAfi/Form/Admin/UserGroup.php b/library/ZendAfi/Form/Admin/UserGroup.php
new file mode 100644
index 00000000000..c8d94be3627
--- /dev/null
+++ b/library/ZendAfi/Form/Admin/UserGroup.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * AFI-OPAC 2.0 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).
+ *
+ * AFI-OPAC 2.0 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 AFI-OPAC 2.0; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ */
+
+
+class ZendAfi_Form_Admin_UserGroup extends ZendAfi_Form {
+	public function init() {
+		parent::init();
+
+		$this
+			->setAttrib('id', 'usergroupform')
+			->addRequiredTextNamed('libelle')
+			->setLabel('Libellé *');
+
+		$this
+			->addElement('radio',
+									 'group_type',
+									 ['label' => $this->_('Mode de sélection des utilisateurs'),
+										'multiOptions' => [Class_UserGroup::TYPE_MANUAL =>  $this->_(Class_UserGroup::TYPE_MANUAL_TEXT),
+																			 Class_UserGroup::TYPE_DYNAMIC => $this->_(Class_UserGroup::TYPE_DYNAMIC_TEXT)] ] )
+			->addElement('select',
+									 'role_level',
+									 ['label' => $this->_('Rôle'),
+										'multiOptions' => ZendAfi_Acl_AdminControllerRoles::getListeRolesWithoutSuperAdmin()] )
+
+			->addDisplayGroup(['libelle', 'group_type'], 
+												'usergroup', 
+												['legend' => $this->_('Groupe')])
+
+			->addDisplayGroup(['role_level'], 
+												'dynamic_filter', 
+												['legend' => $this->_('Filtre')]);		
+
+		$this->displayGroupFiltreVisibleOnlyOnDynamicGroup();
+
+		$rights = Class_UserGroup::getActivatedRightDefinitionList();
+
+		asort($rights);
+
+		$this
+			->addElement('multiCheckbox', 'rights', ['label' => '', 'multiOptions' => $rights])
+			->addDisplayGroup(['rights'], 'rights_group', ['legend' => $this->_('Droits')]);
+
+
+		if (Class_AdminVar::isMultimediaEnabled()) {
+			$this->addRequiredTextNamed('max_day')
+				->setLabel('Par jour *')
+				->setValue(0)
+				->setValidators(['Digits']);
+			
+			$this->addRequiredTextNamed('max_week')
+				->setLabel('Par semaine *')
+				->setValue(0)
+				->setValidators([
+					'Digits', 
+					new ZendAfi_Validate_FieldsGreater(['max_day' => 'Par jour'], true)]);
+
+			$this->addRequiredTextNamed('max_month')
+				->setLabel('Par mois *')
+				->setValue(0)
+				->setValidators([
+					'Digits',
+					new ZendAfi_Validate_FieldsGreater([
+						'max_day' => 'Par jour',
+						'max_week' => 'Par semaine'],
+					true)]);
+
+			$this->addDisplayGroup(
+				['max_day', 'max_week', 'max_month'],
+				'multimedia',
+				['legend' => 'Quota de réservation multimédia (mn)']);
+		}
+	}
+
+
+	public function displayGroupFiltreVisibleOnlyOnDynamicGroup() {
+		Class_ScriptLoader::getInstance()
+			->addInlineScript('formSelectToggleVisibilityForElement("input[name=\'group_type\']", "#fieldset-dynamic_filter", ["1"]);');
+	}
+}
+?>
\ No newline at end of file
diff --git a/tests/application/modules/admin/controllers/UsergroupControllerMultimediaTest.php b/tests/application/modules/admin/controllers/UsergroupControllerMultimediaTest.php
index 9de4f709278..984bc5eaecd 100644
--- a/tests/application/modules/admin/controllers/UsergroupControllerMultimediaTest.php
+++ b/tests/application/modules/admin/controllers/UsergroupControllerMultimediaTest.php
@@ -30,7 +30,7 @@ abstract class Admin_UsergroupControllerMultimediaTestCase extends Admin_Abstrac
 		Class_AdminVar::getLoader()
 			->newInstanceWithId('MULTIMEDIA_KEY')
 			->setValeur('5018f5e08f14a');
-		
+
 		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_UserGroup')
 			->whenCalled('save')->answers(true)
 			->whenCalled('delete')->answers(true)
@@ -88,11 +88,11 @@ class Admin_UsergroupControllerMultimediaAddTest extends Admin_UsergroupControll
 class Admin_UsergroupControllerMultimediaAddValidPostTest extends Admin_UsergroupControllerMultimediaTestCase {
 	public function setUp() {
 		parent::setUp();
-		$this->postDispatch('admin/usergroup/add',
-			array('libelle' => 'Vilains',
-				    'max_day' => '120',
-				    'max_week' => '120',
-				    'max_month' => '360'));
+		$this->postDispatch('admin/usergroup/add', [
+			'libelle' => 'Vilains',
+			'max_day' => '120',
+			'max_week' => '120',
+			'max_month' => '360']);
 	}
 
 
@@ -121,7 +121,7 @@ class Admin_UsergroupControllerMultimediaAddValidPostTest extends Admin_Usergrou
 
 	/** @test */
 	public function responseShouldRedirectToDefaultAction() {
-		$this->assertRedirectTo('/admin/usergroup');
+		$this->assertRedirect();
 	}
 }
 
-- 
GitLab