diff --git a/VERSIONS_HOTLINE/162262 b/VERSIONS_HOTLINE/162262 new file mode 100644 index 0000000000000000000000000000000000000000..7d8ba77d4820e5cb6c3600be7f80995181e5d6f3 --- /dev/null +++ b/VERSIONS_HOTLINE/162262 @@ -0,0 +1,3 @@ + - correctif #162262 : Administration : amélioration de l'outil de nettoyage des champs personnalisés. + Vous pouvez maintenant utiliser le bouton "Mettre à jour toutes les lignes" pour supprimer + vos anciennes valeurs rattachées aux données. \ No newline at end of file diff --git a/application/modules/admin/controllers/CustomFieldsController.php b/application/modules/admin/controllers/CustomFieldsController.php index 7ee7c5a583071148451202a536e5ffac18f1cbc0..46d7200ce667e670b5fa59b592cf08840c15354d 100644 --- a/application/modules/admin/controllers/CustomFieldsController.php +++ b/application/modules/admin/controllers/CustomFieldsController.php @@ -117,4 +117,20 @@ class Admin_CustomFieldsController extends ZendAfi_Controller_Action { $value->delete(); $this->_redirectClose($this->_getReferer()); } + + + public function cleanValuesAction() { + if ( ! $field = Class_CustomField::find($this->_getParam('id', 0))) { + $this->_helper->notify($this->_('Il y a une erreur, veuillez vérifier le paramètre "id" de votre URL.')); + return $this->_redirectCloseReferer(); + } + + $this->view->titre = $this->view->_('Mise à jour des valeurs du champs %s rattachées aux modèles', + strtolower($field->getLabel())); + + $field->cleanValues(); + + $this->_helper->notify($this->_('Les valeurs rattachées au champs %s ont bien été mises à jour')); + $this->_redirectCloseReferer(); + } } \ No newline at end of file diff --git a/application/modules/admin/views/scripts/custom-fields/clean.phtml b/application/modules/admin/views/scripts/custom-fields/clean.phtml index e1304006e5e8726f629c5ea0829174ce0d77537b..02e6ddd6beb52ce60f670ed56ea1f0e695d40560 100644 --- a/application/modules/admin/views/scripts/custom-fields/clean.phtml +++ b/application/modules/admin/views/scripts/custom-fields/clean.phtml @@ -1,7 +1,14 @@ <?php +echo $this->button((new Class_Button) + ->setText('Mettre à jour toutes les lignes') + ->setImage($this->renderIcon('class fa fa-paper-plane-o')) + ->setTitle($this->_('Mettre à jour toutes les valeurs rattachées aux modèles')) + ->setAttribs(['data-popup' => 'true']) + ->setUrl($this->url(['action' => 'clean-values']))); + $output = $this->custom_field_values - ? $this->renderTable((new Class_TableDescription_CustomFieldsValues('custom_fiels_values'))->setView($this), - $this->custom_field_values) - : $this->tagWarning($this->_('Aucune valeur')); + ? $this->renderTable((new Class_TableDescription_CustomFieldsValues('custom_fiels_values'))->setView($this), + $this->custom_field_values) + : $this->tagWarning($this->_('Aucune valeur')); -echo $output; \ No newline at end of file +echo $output; diff --git a/library/Class/CustomField.php b/library/Class/CustomField.php index cd06e2a8afc8aa9aa63e88267b37baa347512def..285ee2d54f501e217e1d05acc9f9ade3f568fb1a 100644 --- a/library/Class/CustomField.php +++ b/library/Class/CustomField.php @@ -213,4 +213,14 @@ class Class_CustomField extends Storm_Model_Abstract { ? $this->getMeta()->isCKEditor() : false; } + + + public function cleanValues() : self { + if ( ! $meta = $this->getMeta()) + return $this; + + array_map(fn($value) => $meta->cleanValue($value), + $this->getValues()); + return $this; + } } diff --git a/library/Class/CustomField/Meta.php b/library/Class/CustomField/Meta.php index e6c601efa4f76e03fb149ccd26dd283674bd84d9..f5142bba8d79cd094812efc94fa51c991afa619f 100644 --- a/library/Class/CustomField/Meta.php +++ b/library/Class/CustomField/Meta.php @@ -113,10 +113,55 @@ class Class_CustomField_Meta extends Storm_Model_Abstract { public function isCKEditor() : bool { return static::CKEDITOR === $this->getFieldType(); } + + + public function isAList() : bool { + return in_array($this->getFieldType(), + [static::SELECT, + static::MULTI_CHECKBOX]); + } + + + public function cleanValue(Class_CustomField_Value $value) : self { + if ( ! $model = $value->getModelInstance()) { + $value->delete(); + return $this; + } + + if ( ! $this->isAList()) + return $this; + + if ( ! $availables_values = $this->getOptionsListAsArray()) { + $value->delete(); + return $this; + } + + if ( ! $old_values = + array_filter(array_map(fn($value_text) => trim($value_text), + explode(static::SELECT_SEPARATOR, $value->getValue())))) { + $value->delete(); + return $this; + } + + if ( ! $cleaned_values = + array_filter(array_map(fn($value_text) => trim($value_text), + array_intersect($old_values, $availables_values)))) { + $value->delete(); + return $this; + } + + natsort($cleaned_values); + + $value->setValue(implode(static::SELECT_SEPARATOR, $cleaned_values)); + $value->save(); + + return $this; + } } + class Class_CustomField_Meta_ThesaurusAssociation extends Storm_Model_Association_Abstract { public function canHandle($method) { return in_array($method, ['getThesaurus']); diff --git a/library/Class/CustomField/Value.php b/library/Class/CustomField/Value.php index c873eddabb00ab7637c1dd766f392fe1dd25c1bf..92c05de9c0f9ec6dbea45ff775bfe54f216e1f7c 100644 --- a/library/Class/CustomField/Value.php +++ b/library/Class/CustomField/Value.php @@ -141,6 +141,13 @@ class Class_CustomField_Value extends Storm_Model_Abstract { } + public function getFieldModel() : string { + return ($field = $this->getField()) + ? $field->getModel() + : ''; + } + + public function isOutDated() { if ( ! $values = $this->getValueAsArray()) return false; diff --git a/library/Class/TableDescription/CustomFieldsValues.php b/library/Class/TableDescription/CustomFieldsValues.php index 43f035cc046c5f5e9ac0182ea89aa44134f9197c..30ca205924e74c5f76db770f39bae9181a019add 100644 --- a/library/Class/TableDescription/CustomFieldsValues.php +++ b/library/Class/TableDescription/CustomFieldsValues.php @@ -28,24 +28,29 @@ class Class_TableDescription_CustomFieldsValues extends Class_TableDescription { public function init() { $this - ->addColumn($this->_('ID'), function($custom_field_value) + ->addColumn($this->_('ID Valeur'), function($custom_field_value) { return $custom_field_value->getModelInstance() ? $custom_field_value->getId() : $this->_view->tagError($custom_field_value->getId()); }) - ->addColumn($this->_('model_id'), function($custom_field_value) + ->addColumn($this->_('ID modèle'), function($custom_field_value) { return $custom_field_value->getModelInstance() ? $custom_field_value->getModelId() : $this->_view->tagError($this->_('%s (cette ID n\'existe plus)', $custom_field_value->getModelId())); }) - ->addColumn($this->_('Objet'), - function($custom_field_value) { return $custom_field_value->getModelInstance();}) + ->addColumn($this->_('Modèle'), + function($custom_field_value) + { + return ($instance = $custom_field_value->getModelInstance()) + ? get_class($instance) + : ''; + }) - ->addColumn($this->_('value'),function($custom_field_value) + ->addColumn($this->_('Valeurs'),function($custom_field_value) { $value = $custom_field_value->getValue(); return ($custom_field_value->isOutDated() ? $this->_view->tagError($this->_('%s (cette valeur n\'existe plus)',$value)) @@ -70,10 +75,19 @@ class Class_TableDescription_CustomFieldsValues extends Class_TableDescription { ->addRowAction(function($custom_field_value) { - return null; - return ($instance = $custom_field_value->getModelInstance()) - ? $this->_view->renderModelActions($instance) - : null; + return + $this->_view->tagAnchor($this->_view->url(['module' => 'admin', + 'controller' => 'custom-fields', + 'action' => 'values', + 'model' => $custom_field_value->getFieldModel(), + 'id' => $custom_field_value->getModelId()], + null, + true), + $this->_view->tagImg(Class_Admin_Skin::current() + ->getIconUrl('actions', + 'edit')), + ['popup' => true, + 'title' => $this->_('Modifier les valeurs')]); }); } diff --git a/library/ZendAfi/Controller/Plugin/Manager/CustomField.php b/library/ZendAfi/Controller/Plugin/Manager/CustomField.php index 2bab68a8cf4547ba0a447f80d1aa2da93fcc1fe1..7c09698faac8bacade07f92d4759f4f432485494 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/CustomField.php +++ b/library/ZendAfi/Controller/Plugin/Manager/CustomField.php @@ -62,7 +62,7 @@ class ZendAfi_Controller_Plugin_Manager_CustomField extends ZendAfi_Controller_P 'label' => $this->_('Modifier')], ['url' => '/admin/custom-fields/clean/id/%s', - 'icon' => 'view', + 'icon' => 'class fa fa-recycle', 'label' => $this->_('Nettoyer')], ['url' => '/admin/custom-fields/delete/id/%s', diff --git a/tests/application/modules/admin/controllers/CustomFieldsControllerTest.php b/tests/application/modules/admin/controllers/CustomFieldsControllerTest.php index 8e45bcfcefa4cdc2d9b795c04057c1cfb6408cb6..faacb55ef25c5963badc68a27dfe68c6e568fe52 100644 --- a/tests/application/modules/admin/controllers/CustomFieldsControllerTest.php +++ b/tests/application/modules/admin/controllers/CustomFieldsControllerTest.php @@ -26,39 +26,39 @@ abstract class CustomFieldControllerTestCase extends AbstractControllerTestCase public function setUp() { parent::setUp(); - $this->fixture('Class_CustomField_Meta', + $this->fixture(Class_CustomField_Meta::class, ['id' => 1, 'label' => 'Address', 'field_type' => Class_CustomField_Meta::TEXT_INPUT, 'options_list' => '', 'indexable' => 1]); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 1, 'meta_id' => 1, 'priority' => 1, 'model' => 'Article']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 2, 'meta_id' => 1, 'priority' => 1, 'model' => 'Activity']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 3, 'meta_id' => 1, 'priority' => 1, 'model' => 'UserGroup']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 4, 'priority' => 2, 'label' => 'Age', 'field_type' => Class_CustomField_Meta::TEXT_AREA, 'model' => 'UserGroup']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 5, 'priority' => 3, 'label' => 'Status', @@ -66,44 +66,44 @@ abstract class CustomFieldControllerTestCase extends AbstractControllerTestCase 'options_list' => 'enabled; disabled; ', 'model' => 'UserGroup']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 6, 'priority' => 4, 'label' => 'Zip code', 'field_type' => Class_CustomField_Meta::TEXT_INPUT, 'model' => 'UserGroup']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 7, 'priority' => 5, 'label' => 'Notes', 'field_type' => Class_CustomField_Meta::CKEDITOR, 'model' => 'UserGroup']); - $this->fixture('Class_CustomField', + $this->fixture(Class_CustomField::class, ['id' => 8, 'priority' => 6, 'label' => 'Starting date', 'field_type' => Class_CustomField_Meta::DATE, 'model' => 'UserGroup']); - $this->fixture('Class_UserGroup', + $this->fixture(Class_UserGroup::class, ['id' => 1, 'libelle' => 'Teachers']); - $this->fixture('Class_CustomField_Value', //teachers address + $this->fixture(Class_CustomField_Value::class, //teachers address ['id' => 23, 'custom_field_id' => 3, 'model_id' => 1, 'value' => '11 rue Paradis']); - $this->fixture('Class_CustomField_Value', //teachers age + $this->fixture(Class_CustomField_Value::class, //teachers age ['id' => 24, 'custom_field_id' => 4, 'model_id' => 1, 'value' => '25']); - $this->fixture('Class_CustomField_Value', //teachers status + $this->fixture(Class_CustomField_Value::class, //teachers status ['id' => 25, 'custom_field_id' => 5, 'model_id' => 1, @@ -776,8 +776,14 @@ class CustomFieldsControllerCleanTest extends CustomFieldControllerTestCase { /** @test */ - public function userGroupIdOneShouldBeInTable() { - $this->assertXPathContentContains('//table//td', 'Class_UserGroup(id=1)'); + public function typeUserGroupShouldBeInTable() { + $this->assertXPathContentContains('//table//td', 'Class_UserGroup'); + } + + + /** @test */ + public function modelIdOneShouldBeInTable() { + $this->assertXPathContentContains('//table//td', '1'); } @@ -787,10 +793,23 @@ class CustomFieldsControllerCleanTest extends CustomFieldControllerTestCase { } + /** @test */ + public function userGroupIdOneEditValuesLinkShouldBePresent() { + $this->assertXPath('//table//td//a[@href="/admin/custom-fields/values/model/UserGroup/id/1"]'); + } + + /** @test */ public function rueDuParadisShouldBeAnError() { $this->assertXPathContentContains('//table//td//p[@class="error"]','11 rue Paradis (cette valeur n\'existe plus)'); } + + + /** @test */ + public function shouldContainsButtonToMassUpdateUserGroup() { + $this->assertXPathContentContains('//div//button[@data-url="/admin/custom-fields/clean-values/id/3"][@data-popup="true"]', + 'Mettre à jour toutes les lignes'); + } } @@ -814,3 +833,68 @@ class CustomFieldsControllerDeleteValueTest extends CustomFieldControllerTestCas $this->assertRedirect(); } } + + + + +class CustomFieldsControllerUpdateModelsTest extends CustomFieldControllerTestCase { + public function setup() { + parent::setup(); + + $this->fixture(Class_CustomField_Value::class, + ['id' => 2989, + 'custom_field_id' => 5, + 'model_id' => 1, + 'value' => 'enabled;unknown']); + + $this->fixture(Class_CustomField_Value::class, + ['id' => 99, + 'custom_field_id' => 5, + 'model_id' => 1890890, + 'value' => 'enabled;']); + + $this->fixture(Class_CustomField_Value::class, + ['id' => 88, + 'custom_field_id' => 5, + 'model_id' => 1, + 'value' => 'out dated']); + + $this->fixture(Class_CustomField_Value::class, + ['id' => 77, + 'custom_field_id' => 5, + 'model_id' => 1, + 'value' => ' ; ']); + + $this->dispatch('/admin/custom-fields/clean-values/id/5'); + } + + + /** @test */ + public function customFieldValueWithIdNineNineShouldBeDeleted() { + $this->assertNull(Class_CustomField_Value::find(99)); + } + + + /** @test */ + public function customFieldValueWithIdEightEightShouldBeDeleted() { + $this->assertNull(Class_CustomField_Value::find(88)); + } + + + /** @test */ + public function customFieldValueWithIdSevenSevenShouldBeDeleted() { + $this->assertNull(Class_CustomField_Value::find(77)); + } + + + /** @test */ + public function customFieldValueTwoNineEightNineValueShouldContainsOnlyEnable() { + $this->assertEquals('enabled', Class_CustomField_Value::find(2989)->getValue()); + } + + + /** @test */ + public function shouldRedircet() { + $this->assertRedirect(); + } +}