From e41fb98d5fb967670e85eff1851ee2bfffabaf0a Mon Sep 17 00:00:00 2001
From: Ghislain Loas <ghislo@sandbox.afi-sa.local>
Date: Thu, 30 Jun 2016 12:44:27 +0200
Subject: [PATCH] dev #41588 implement auto generate + add edit link + add
 preview

---
 .../admin/controllers/BibController.php       | 16 +++-
 .../admin/controllers/LieuController.php      | 74 ++---------------
 library/Class/Lieu.php                        | 15 ++++
 library/ZendAfi/Form/Admin/Library.php        |  5 +-
 library/ZendAfi/Form/Admin/Location.php       | 83 +++++++++++++++++++
 .../Form/Decorator/LocationPreview.php        | 40 +++++++++
 library/ZendAfi/View/Helper/RenderLieu.php    | 31 +++----
 .../ZendAfi/View/Helper/TagEditLocation.php   | 36 ++++++++
 public/admin/skins/bokeh74/global.css         | 17 ++++
 .../admin/controllers/BibControllerTest.php   | 18 +++-
 .../admin/controllers/LieuControllerTest.php  | 14 ++--
 11 files changed, 251 insertions(+), 98 deletions(-)
 create mode 100644 library/ZendAfi/Form/Admin/Location.php
 create mode 100644 library/ZendAfi/Form/Decorator/LocationPreview.php
 create mode 100644 library/ZendAfi/View/Helper/TagEditLocation.php

diff --git a/application/modules/admin/controllers/BibController.php b/application/modules/admin/controllers/BibController.php
index 6daf4ef0917..b4a889712a9 100644
--- a/application/modules/admin/controllers/BibController.php
+++ b/application/modules/admin/controllers/BibController.php
@@ -412,6 +412,18 @@ class Admin_BibController extends ZendAfi_Controller_Action {
                                             'id' => $model->getId()],
                                            null, true));
   }
-}
 
-?>
\ No newline at end of file
+
+  protected function _doBeforeSave($model) {
+    if(Class_Lieu::GENERATE != $this->_getParam('id_lieu'))
+      return $this;
+
+    $location = Class_Lieu::newWith($model);
+
+    if(!$location->save())
+      return $this;
+
+    $model->setIdLieu($location->getId());
+    return $this;
+  }
+}
diff --git a/application/modules/admin/controllers/LieuController.php b/application/modules/admin/controllers/LieuController.php
index ed75bb23890..d8f6b2cb058 100644
--- a/application/modules/admin/controllers/LieuController.php
+++ b/application/modules/admin/controllers/LieuController.php
@@ -16,9 +16,9 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-class Admin_LieuController extends Zend_Controller_Action {
+class Admin_LieuController extends ZendAfi_Controller_Action {
   public function indexAction() {
     $this->view->titre = $this->view->_('Lieux');
     $this->view->lieux = Class_Lieu::getLoader()->findAllBy(array('order' => 'libelle'));
@@ -40,10 +40,10 @@ class Admin_LieuController extends Zend_Controller_Action {
 
   public function editAction() {
     if (!$lieu = Class_Lieu::getLoader()->find($this->_getParam('id'))) {
-      $this->_redirect('admin/lieu/index'); 
+      $this->_redirect('admin/lieu/index');
       return;
     }
-      
+
     $this->view->titre = $this->view->_('Modifier le lieu: "%s"', $lieu->getLibelle());
     $this->_setupLieuFormAndSave($lieu, 'edit');
     $this->renderScript('lieu/edit.phtml');
@@ -55,7 +55,7 @@ class Admin_LieuController extends Zend_Controller_Action {
       $lieu->delete();
       $this->_helper->notify(sprintf('Lieu "%s" supprimé',  $lieu->getLibelle()));
     }
-    $this->_redirect('admin/lieu/index'); 
+    $this->_redirect('admin/lieu/index');
   }
 
 
@@ -78,66 +78,6 @@ class Admin_LieuController extends Zend_Controller_Action {
 
 
   public function _formLieu($lieu, $action) {
-    return $this->view
-      ->newForm(['id' => 'formLieu'])
-      ->setMethod('post')
-      ->setAction($this->view->url(['action' => $action]))
-      ->addElement('text', 'libelle', ['label' => 'Libellé *',
-                                       'size' => 50,
-                                       'maxlength' => 100,
-                                       'required' => true,
-                                       'allowEmpty' => false ])
-
-      ->addElement('url', 'url', ['label' => 'Site web',
-                                  'size'  => 50,
-                                  'maxlength' => 255])
-
-      ->addElement('text', 'telephone', ['label' => 'Téléphone',
-                                         'size' => 25,
-                                         'maxlength' => 25])
-
-      ->addElement('text', 'mail', ['label' => 'E-Mail',
-                                    'size'  => 50,
-                                    'maxlength' => 50,
-                                    'validators' => ['EmailAddress']])
-
-      ->addElement('textarea', 'adresse', ['label' => 'Adresse',
-                                           'rows' => 10,
-                                           'cols' => 50])
-
-      ->addElement('text', 'code_postal', ['label' => 'Code postal',
-                                           'size' => 10,
-                                           'maxlength' => 10])
-
-      ->addElement('text', 'ville', ['label' => 'Ville',
-                                     'size' => 50,
-                                     'maxlength' => 50])
-
-      ->addElement('text', 'pays', ['label' => 'Pays',
-                                    'size' => 50,
-                                    'maxlength' => 50])
-
-      ->addElement('text', 'latitude', ['label' => 'Latitude',
-                                        'size'  => 25,
-                                        'maxlength' => 25])
-
-      ->addElement('text', 'longitude', ['label' => 'Longitude',
-                                         'size' => 25,
-                                         'maxlength' => 25])
-      ->addDisplayGroup(['libelle', 
-                         'url',
-                         'telephone',
-                         'mail',
-                         'adresse',
-                         'code_postal',
-                         'ville',
-                         'pays',
-                         'latitude',
-                         'longitude'],
-                        'lieu',
-                        ['legend' => $this->view->_('Lieu')])
-      ->populate($lieu->toArray());
+    return ZendAfi_Form_Admin_Location::newWith($lieu->toArray());
   }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/library/Class/Lieu.php b/library/Class/Lieu.php
index b96d3b68151..460cc3ddc28 100644
--- a/library/Class/Lieu.php
+++ b/library/Class/Lieu.php
@@ -20,6 +20,19 @@
  */
 
 class Class_LieuLoader extends Storm_Model_Loader {
+  public function newWith($library) {
+    $location = Class_Lieu::newInstance();
+    $location->updateAttributes(['libelle' => $library->getLibelle(),
+                                 'adresse' => $library->getAdresse(),
+                                 'ville' => $library->getVille(),
+                                 'code_postal' => $library->getCp(),
+                                 'pays' => 'FRANCE',
+                                 'telephone' => $library->getTelephone(),
+                                 'mail' => $library->getMail()]);
+    return $location;
+  }
+
+
   public function getAllLibelles() {
     $labels = [];
     foreach(Class_Lieu::findAllBy(['order' => 'libelle']) as $location)
@@ -32,6 +45,8 @@ class Class_LieuLoader extends Storm_Model_Loader {
 class Class_Lieu extends Storm_Model_Abstract {
   use Trait_Translator;
 
+  const GENERATE = 'GENERATE';
+
   protected $_table_name = 'lieux';
   protected $_loader_class = 'Class_LieuLoader';
 
diff --git a/library/ZendAfi/Form/Admin/Library.php b/library/ZendAfi/Form/Admin/Library.php
index 12df599b188..3dbfc5f59ac 100644
--- a/library/ZendAfi/Form/Admin/Library.php
+++ b/library/ZendAfi/Form/Admin/Library.php
@@ -86,7 +86,8 @@ class ZendAfi_Form_Admin_Library extends ZendAfi_Form {
 
       ->addElement('select', 'id_lieu',
                    ['label' => $this->_('Sélectionnez un lieu'),
-                    'multiOptions' => $this->_getLocationOptions()])
+                    'multiOptions' => $this->_getLocationOptions(),
+                    'onchange' =>     'this.form.submit();return false;'])
 
       ->addElement('select', 'id_zone',
                    ['label' => $this->_('Territoire'),
@@ -180,8 +181,10 @@ class ZendAfi_Form_Admin_Library extends ZendAfi_Form {
       ->displayPNB()
       ->displayRedmine();
 
+    $this->getElement('id_lieu')->addDecorator('LocationPreview');
   }
 
+
   protected function displayPNB() {
     if (!Class_AdminVar::isDilicomPNBEnabled())
       return $this;
diff --git a/library/ZendAfi/Form/Admin/Location.php b/library/ZendAfi/Form/Admin/Location.php
new file mode 100644
index 00000000000..c8ba731ea54
--- /dev/null
+++ b/library/ZendAfi/Form/Admin/Location.php
@@ -0,0 +1,83 @@
+<?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_Form_Admin_Location extends ZendAfi_Form {
+  public function init() {
+    parent::init();
+    $this
+      ->setMethod('post')
+      ->addElement('text', 'libelle', ['label' => $this->_('Libellé'),
+                                       'size' => 50,
+                                       'maxlength' => 100,
+                                       'required' => true,
+                                       'allowEmpty' => false ])
+
+      ->addElement('url', 'url', ['label' => $this->_('Site web'),
+                                  'size'  => 50,
+                                  'maxlength' => 255])
+
+      ->addElement('text', 'telephone', ['label' => $this->_('Téléphone'),
+                                         'size' => 25,
+                                         'maxlength' => 25])
+
+      ->addElement('text', 'mail', ['label' => $this->_('E-Mail'),
+                                    'size'  => 50,
+                                    'maxlength' => 50,
+                                    'validators' => ['EmailAddress']])
+
+      ->addElement('textarea', 'adresse', ['label' => $this->_('Adresse'),
+                                           'rows' => 10,
+                                           'cols' => 50])
+
+      ->addElement('text', 'code_postal', ['label' => $this->_('Code postal'),
+                                           'size' => 10,
+                                           'maxlength' => 10])
+
+      ->addElement('text', 'ville', ['label' => $this->_('Ville'),
+                                     'size' => 50,
+                                     'maxlength' => 50])
+
+      ->addElement('text', 'pays', ['label' => $this->_('Pays'),
+                                    'size' => 50,
+                                    'maxlength' => 50])
+
+      ->addElement('text', 'latitude', ['label' => $this->_('Latitude'),
+                                        'size'  => 25,
+                                        'maxlength' => 25])
+
+      ->addElement('text', 'longitude', ['label' => $this->_('Longitude'),
+                                         'size' => 25,
+                                         'maxlength' => 25])
+      ->addDisplayGroup(['libelle',
+                         'url',
+                         'telephone',
+                         'mail',
+                         'adresse',
+                         'code_postal',
+                         'ville',
+                         'pays',
+                         'latitude',
+                         'longitude'],
+                        'lieu',
+                        ['legend' => $this->_('Lieu')]);
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Decorator/LocationPreview.php b/library/ZendAfi/Form/Decorator/LocationPreview.php
new file mode 100644
index 00000000000..b306cccfd2c
--- /dev/null
+++ b/library/ZendAfi/Form/Decorator/LocationPreview.php
@@ -0,0 +1,40 @@
+<?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_Form_Decorator_LocationPreview extends Zend_Form_Decorator_Abstract {
+  public function render($content) {
+    $view = $this->_element->getView();
+
+    if(!$location = Class_Lieu::find($this->_element->getValue()))
+      return $content;
+
+    $javascript =
+      '$("#id_lieu").closest("td").append("'
+      . str_replace('"',"'", $view->tagEditLocation($location) . $view->renderLieu($location))
+      . '");';
+
+    Class_ScriptLoader::getInstance()
+      ->addJQueryReady($javascript);
+
+    return $content;
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/RenderLieu.php b/library/ZendAfi/View/Helper/RenderLieu.php
index 625fb441a97..e1fc5186e46 100644
--- a/library/ZendAfi/View/Helper/RenderLieu.php
+++ b/library/ZendAfi/View/Helper/RenderLieu.php
@@ -19,32 +19,23 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-class ZendAfi_View_Helper_RenderLieu extends Zend_View_Helper_HtmlElement {
+class ZendAfi_View_Helper_RenderLieu extends ZendAfi_View_Helper_BaseHelper {
   public function renderLieu($lieu, $map_options = null) {
     if (!$lieu)
       return '';
 
+    $adresse = [nl2br($lieu->getAdresse()),
+                $lieu->getCodePostal() . ' ' . $lieu->getVille(),
+                $lieu->getTelephone(),
+                $lieu->getMail()];
 
-    $adresse = array();
+    $adresse_str = implode('<br/>', array_filter($adresse));
 
-    if (nl2br($lieu->getAdresse()))
-      $adresse[] = nl2br($lieu->getAdresse());
-
-    if ($lieu->getCodePostal() || $lieu->getVille())
-      $adresse[] = $lieu->getCodePostal() . ' ' . $lieu->getVille();
-
-    if ($lieu->getTelephone())
-      $adresse[] = $lieu->getTelephone();
-
-    if ($lieu->getMail())
-      $adresse[] = $lieu->getMail();
-
-    $adresse_str = implode('<br />', $adresse);
-
-    return sprintf('<div class="lieu">%s %s <p>%s</p></div>',
-                   $this->view->mapForLieu($lieu, $map_options),
-                   $lieu->getLibelle(),
-                   $adresse_str);
+    return $this->_tag('div',
+                       $this->view->mapForLieu($lieu, $map_options)
+                       . $this->_tag('h3', $lieu->getLibelle())
+                       . $adresse_str,
+                       ['class' => 'lieu']);
   }
 }
 
diff --git a/library/ZendAfi/View/Helper/TagEditLocation.php b/library/ZendAfi/View/Helper/TagEditLocation.php
new file mode 100644
index 00000000000..a0ed63bb7fa
--- /dev/null
+++ b/library/ZendAfi/View/Helper/TagEditLocation.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright (c) 2012, 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_View_Helper_TagEditLocation extends Zend_View_Helper_HtmlElement {
+  public function tagEditLocation($location) {
+    return $this->view->tagAnchor($this->view->url(['module' => 'admin',
+                                                    'controller' => 'lieu',
+                                                    'action' => 'edit',
+                                                    'id' => $location->getId()], null, true),
+                                  Class_Admin_Skin::current()
+                                  ->renderActionIconOn('edit', $this->view,
+                                                       ['class' => 'location_edit',
+                                                        'alt' => $this->view->_('Modifier le lieu'),
+                                                        'title' => $this->view->_('Modifier le lieu')]),
+                                  ['class' => 'edit_location']);
+  }
+}
+?>
\ No newline at end of file
diff --git a/public/admin/skins/bokeh74/global.css b/public/admin/skins/bokeh74/global.css
index c83cb688aec..a275a7d88d9 100755
--- a/public/admin/skins/bokeh74/global.css
+++ b/public/admin/skins/bokeh74/global.css
@@ -624,4 +624,21 @@ td[id*="menu_item"] {
 
 .ouvertures_index .modules ul > li > table th:last-child {
     width: 60px;
+}
+
+form td .lieu {
+    display: inline-block;
+}
+
+form #fieldset-location td:first-child {
+    float: left;
+}
+
+form #fieldset-location .lieu,
+form #fieldset-location .edit_location {
+    float: right;
+}
+
+a[class^="edit_"] {
+    margin: 0 3px;
 }
\ No newline at end of file
diff --git a/tests/application/modules/admin/controllers/BibControllerTest.php b/tests/application/modules/admin/controllers/BibControllerTest.php
index 509da604846..28cfb6eddb5 100644
--- a/tests/application/modules/admin/controllers/BibControllerTest.php
+++ b/tests/application/modules/admin/controllers/BibControllerTest.php
@@ -53,7 +53,8 @@ abstract class BibControllerTestCase extends AbstractControllerTestCase {
                                         'annexe' => 'lac',
                                         'horaire' => '10-12',
                                         'fond' => 'documentaires',
-                                        'photo' => ''
+                                        'photo' => '',
+                                        'id_lieu' => 78
                                        ]);
 
     $this->bib_cran = $this->fixture('Class_Bib', ['id' => 3,
@@ -424,9 +425,11 @@ class BibControllerWithAdminBibEditAnnecyWithDilicomEnabledTest extends BibContr
 class BibControllerWithAdminBibEditAnnecyPostTest extends BibControllerWithAdminBibTestCase {
   public function setUp() {
     parent::setUp();
+
     $this->postDispatch('admin/bib/edit/id/2',
                         ['libelle' => 'Bonlieu',
                          'responsable' => 'Géraldine',
+                         'id_lieu' => 'GENERATE',
                          'ville' => 'C2A',
                          'url_web' => 'http://www.bibliofil.fr',
                          'mail' => 'bib@c2a.fr',
@@ -468,6 +471,19 @@ class BibControllerWithAdminBibEditAnnecyPostTest extends BibControllerWithAdmin
     Class_IntBib::clearCache();
     $this->assertEquals('C2A', Class_IntBib::find(2)->getNomCourt());
   }
+
+
+  /** @test */
+  public function locationBonlieuShouldHaveBeenCreated() {
+    $this->assertNotNull(Class_Lieu::findFirstBy(['libelle' => 'Bonlieu']));
+  }
+
+
+  /** @test */
+  public function libraryBonlieuIdLieuShouldBeOne() {
+    $this->assertEquals(Class_Bib::find(2)->getIdLieu(),
+                        Class_Lieu::findFirstBy(['libelle' => 'Bonlieu'])->getId());
+  }
 }
 
 
diff --git a/tests/application/modules/admin/controllers/LieuControllerTest.php b/tests/application/modules/admin/controllers/LieuControllerTest.php
index b0401a5c963..988e9a55dd3 100644
--- a/tests/application/modules/admin/controllers/LieuControllerTest.php
+++ b/tests/application/modules/admin/controllers/LieuControllerTest.php
@@ -128,37 +128,37 @@ class LieuControllerAddTest extends LieuControllerTestCase {
 
   /** @test */
   public function formShouldContainsInputForLibelle() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="libelle"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="libelle"]');
   }
 
 
   /** @test */
   public function formShouldContainsInputForMail() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="mail"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="mail"]');
   }
 
 
   /** @test */
   public function formShouldContainsInputForTelephone() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="telephone"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="telephone"]');
   }
 
 
   /** @test */
   public function formShouldContainsInputForLatitude() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="latitude"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="latitude"]');
   }
 
 
   /** @test */
   public function formShouldContainsInputForLongitude() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="longitude"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="longitude"]');
   }
 
 
   /** @test */
   public function formShouldContainsInputForUrl() {
-    $this->assertXPath('//form[contains(@action, "add")][@method="post"]//input[@name="url"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="url"]');
   }
 
 
@@ -252,7 +252,7 @@ class LieuControllerEditAnnecyTest extends LieuControllerTestCase {
 
   /** @test */
   public function formInputLibelleShouldContainsAnnecy() {
-    $this->assertXPath('//form[contains(@action, "edit")][@method="post"]//input[@name="libelle"][@value="AFI Annecy"]');
+    $this->assertXPath('//form[@method="post"]//input[@name="libelle"][@value="AFI Annecy"]');
   }
 
 
-- 
GitLab