From cbaea8645945b0cddea2bae42c6471579e70a912 Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Fri, 4 May 2018 15:16:25 +0200
Subject: [PATCH] dev #74865 add update string action in I18n controller

---
 .../admin/controllers/I18nController.php      | 35 ++++++++-
 .../views/scripts/i18n/update-string.phtml    |  2 +
 library/Class/I18n.php                        | 28 ++++++-
 library/Class/Profil/I18nStringUpdator.php    | 74 +++++++++++++++++++
 .../ZendAfi/Form/Admin/I18n/UpdateString.php  | 38 ++++++++++
 .../admin/controllers/I18nControllerTest.php  | 48 ++++++++++++
 6 files changed, 219 insertions(+), 6 deletions(-)
 create mode 100644 application/modules/admin/views/scripts/i18n/update-string.phtml
 create mode 100644 library/Class/Profil/I18nStringUpdator.php
 create mode 100644 library/ZendAfi/Form/Admin/I18n/UpdateString.php

diff --git a/application/modules/admin/controllers/I18nController.php b/application/modules/admin/controllers/I18nController.php
index 587745b5ff9..5f3781838e0 100644
--- a/application/modules/admin/controllers/I18nController.php
+++ b/application/modules/admin/controllers/I18nController.php
@@ -18,7 +18,7 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-class Admin_I18nController extends Zend_Controller_Action {
+class Admin_I18nController extends ZendAfi_Controller_Action {
   /**
    * @var Class_I18n
    */
@@ -192,5 +192,34 @@ class Admin_I18nController extends Zend_Controller_Action {
 
     }
   }
-}
-?>
\ No newline at end of file
+
+
+  public function updateStringAction() {
+    $this->view->titre = $this->_('Outil de mise à jour de chaînes de caratères');
+
+    if(!$from = $this->_getParam('from')) {
+      $this->_helper->notify($this->_('Vous devez fournir un paramètre "from".'));
+      $this->_redirectToReferer();
+    }
+
+    $this->view->form
+      = $form
+      = ZendAfi_Form_Admin_I18n_UpdateString::newWith($this->_request->getParams());
+
+    if(!$this->_request->isPost())
+      return;
+
+    $this->_i18n->setProfileUpdator(new Class_Profil_I18nStringUpdator);
+    $to = $this->_getParam('to', '');
+
+    if(!$this->_i18n->updateString($from, $to)) {
+      $this->_helper->notify($this->_('La modification de la "%s" par "%s" a échoué.',
+                                      $from, $to));
+      return $this->_redirectToReferer();
+    }
+
+    $this->_helper->notify($this->_('La modification de la chaîne "%s" par "%s" a été enregistrée.',
+                                    $from, $to));
+    $this->_redirectToReferer();
+  }
+}
\ No newline at end of file
diff --git a/application/modules/admin/views/scripts/i18n/update-string.phtml b/application/modules/admin/views/scripts/i18n/update-string.phtml
new file mode 100644
index 00000000000..ac736335975
--- /dev/null
+++ b/application/modules/admin/views/scripts/i18n/update-string.phtml
@@ -0,0 +1,2 @@
+<?php
+echo $this->renderForm($this->form);
diff --git a/library/Class/I18n.php b/library/Class/I18n.php
index 7e75b1e9b32..47caa70b308 100644
--- a/library/Class/I18n.php
+++ b/library/Class/I18n.php
@@ -25,7 +25,8 @@ class Class_I18n {
   const BASE_PATH = '/i18n/';
   const MASTER_NAME = 'master';
 
-  protected $_profilExtractor;
+  protected $_profilExtractor,
+    $_profile_updator;
 
   protected static $_filePaths = [];
 
@@ -77,6 +78,13 @@ class Class_I18n {
     return $this;
   }
 
+
+  public function setProfileUpdator($updator) {
+    $this->_profile_updator = $updator;
+    return $this;
+  }
+
+
   /**
    * @return array
    */
@@ -227,6 +235,20 @@ return array(
     return $this->_buildSerialized($empty);
   }
 
-}
 
-?>
\ No newline at end of file
+  public function updateString($from, $to) {
+    if(!$from)
+      return false;
+
+    if(!$this->_profile_updator)
+      return false;
+
+    $profiles = Class_Profil::findAll();
+    foreach ($profiles as $profile) {
+      $this->_profile_updator->setModel($profile);
+      $this->_profile_updator->updateString($from, $to);
+    }
+
+    return $this->_profile_updator->hasError();
+  }
+}
\ No newline at end of file
diff --git a/library/Class/Profil/I18nStringUpdator.php b/library/Class/Profil/I18nStringUpdator.php
new file mode 100644
index 00000000000..35eed66d428
--- /dev/null
+++ b/library/Class/Profil/I18nStringUpdator.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 Class_Profil_I18nStringUpdator extends Class_Profil_I18n {
+  use Trait_Translator;
+
+  protected $_errors = [];
+
+
+  public function updateString($from, $to) {
+    foreach ($this->_knownConfigurations as $configCalls)
+      $this->_updateAllStringsInModel($configCalls[self::CONFIG_GETTER_KEY], $from, $to);
+  }
+
+
+  protected function _updateAllStringsInModel($key, $from, $to) {
+    $config = $this->_model->_getRawCfgAsArrayNamed($key);
+
+    if(!$from)
+      return $this->_addError($this->_('La chaîne à remplacer est vide.'));
+
+    $config = $this->_findAndReplaceIn($config, $from, $to);
+    $profile_function = Storm_Inflector::camelize('setCfg' . $key);
+    call_user_func([$this->_model, $profile_function], $config);
+
+    if(!$this->_model->save())
+      $this->_addError($this->_('Le remplacement de la chaîne "%s" par "%s" dans le profil "%s" n\'a pas été pris en compte.',
+                                $from,
+                                $to,
+                                $this->_model->getLibelle()));
+  }
+
+
+  protected function _findAndReplaceIn($config, $from, $to) {
+    foreach($config as $key => $value) {
+      if(is_array($value))
+        $config[$key] = $this->_findAndReplaceIn($config[$key], $from, $to);
+
+      if($value == $from)
+        $config[$key] = $to;
+    }
+
+    return $config;
+  }
+
+  protected function _addError($message) {
+    $this->_errors [] = $message;
+    return $this;
+  }
+
+
+  public function hasError() {
+    return !empty($this->_errors);
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Admin/I18n/UpdateString.php b/library/ZendAfi/Form/Admin/I18n/UpdateString.php
new file mode 100644
index 00000000000..7876336bd45
--- /dev/null
+++ b/library/ZendAfi/Form/Admin/I18n/UpdateString.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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_Form_Admin_I18n_UpdateString extends ZendAfi_Form {
+  public function init() {
+    parent::init();
+
+    $this
+      ->addElement('text',
+                      'from',
+                      ['label' => $this->_('Chaîne de caratères à remplacer'),
+                       'disabled' => 'disabled'])
+      ->addElement('text',
+                   'to',
+                   ['label' => $this->_('par')])
+
+      ->addUniqDisplayGroup('update-string');
+  }
+}
\ No newline at end of file
diff --git a/tests/application/modules/admin/controllers/I18nControllerTest.php b/tests/application/modules/admin/controllers/I18nControllerTest.php
index 58d5ae565d2..da8bdb8b9f8 100644
--- a/tests/application/modules/admin/controllers/I18nControllerTest.php
+++ b/tests/application/modules/admin/controllers/I18nControllerTest.php
@@ -143,4 +143,52 @@ class Admin_I18nControllerUpdateActionTest extends Admin_AbstractControllerTestC
 
     $this->dispatch('/admin/i18n/update');
   }
+}
+
+
+
+
+class I18nControllerUpdateStringTest extends Admin_AbstractControllerTestCase {
+
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $profil_8 = $this->fixture('Class_Profil',
+                   ['id' => 8]);
+
+    $profil_9 = $this->fixture('Class_Profil',
+                               ['id' => 9]);
+
+    $simple_widgets = ['modules' => ['6' => ['division' => 1,
+                                             'id_module' => '6',
+                                             'type_module' => 'KIOSQUE',
+                                             'preferences' => ['titre' => 'Bienvenue']]]];
+
+    $profil_8->setCfgAccueil($simple_widgets)->save();
+    $profil_9->setCfgAccueil($simple_widgets)->save();
+
+
+  }
+
+
+  /** @test */
+  public function dispatchShouldRenderForm() {
+    $this->dispatch('/admin/I18n/update-string/from/Bienvenue', true);
+    $this->assertXPath('//form//input[@name="from"]');
+  }
+
+
+  /** @test */
+  public function afterPostDipatchkiosqueInProfile8TitreShouldBeBienvenido() {
+    $this->postDispatch('/admin/I18n/update-string/from/Bienvenue',
+                        ['to' => 'Bienvenido']);
+    $widget = (new Class_Systeme_Widget_Widget())
+      ->setId(6)
+      ->setProfileId(8)
+      ->load();
+    $this->assertEquals('Bienvenido', $widget->gettitre());
+  }
 }
\ No newline at end of file
-- 
GitLab