From 6aa59e577561ad03f7dfe4ba8e368fc1f2ce810f Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Tue, 10 Jan 2017 15:39:11 +0100
Subject: [PATCH] migrate header actions to plugin

---
 .../modules/admin/views/scripts/module.phtml  | 10 +----
 .../views/scripts/newsletter/index.phtml      |  5 ++-
 .../ZendAfi/Controller/Plugin/Abstract.php    |  5 +++
 .../Controller/Plugin/Manager/Manager.php     | 17 ++++++-
 .../Controller/Plugin/Manager/Newsletter.php  | 42 +++++++++++++++++
 .../Plugin/ResourceDefinition/Newsletter.php  | 32 +------------
 .../ZendAfi/View/Helper/PluginRenderer.php    | 39 ++++++++++++++++
 .../View/Helper/RenderModelActions.php        | 44 +++++++++++++-----
 library/ZendAfi/View/Helper/RenderPlugins.php | 15 +------
 .../View/Helper/RenderPluginsActions.php      |  1 +
 .../Helper/RenderPluginsHeaderActions.php     | 28 ++++++++++++
 library/ZendAfi/View/Helper/TagModelTable.php |  1 +
 tests/scenarios/Manager/ManagerTest.php       | 45 +++++++++++++++++++
 13 files changed, 219 insertions(+), 65 deletions(-)
 create mode 100644 library/ZendAfi/View/Helper/PluginRenderer.php
 create mode 100644 library/ZendAfi/View/Helper/RenderPluginsHeaderActions.php

diff --git a/application/modules/admin/views/scripts/module.phtml b/application/modules/admin/views/scripts/module.phtml
index bce123d4b06..92f539c91b2 100644
--- a/application/modules/admin/views/scripts/module.phtml
+++ b/application/modules/admin/views/scripts/module.phtml
@@ -6,13 +6,7 @@
       <div class="menu barre_nav"><?php echo $this->menuHorizontalAdmin() ?></div>
       <div class="left"><?php echo $this->menuGaucheAdmin() ?></div>
       <div class="modules">
-        <?php
-        if (($model_name = $this->model_name)
-            && ($model = $this->$model_name)
-            && $this->model_actions) {
-          echo $this->tag('div', $this->tagModelTable([$model], [], [], $this->model_actions, $model_name . '_actions'),
-                          ['class' => 'header_actions']);
-        } ?>
+      <?php $this->renderPluginsHeaderActions(); ?>
         <h1>
           <?php
           echo $this->titre;
@@ -21,7 +15,7 @@
           ?>
         </h1>
                   <?php
-          echo $this->renderPlugins();
+          $this->renderPlugins();
           echo $this->render($this->actionScript); ?>
       </div>
       <div class="clear"></div>
diff --git a/application/modules/admin/views/scripts/newsletter/index.phtml b/application/modules/admin/views/scripts/newsletter/index.phtml
index cfb7cc73d7b..a55903e190e 100644
--- a/application/modules/admin/views/scripts/newsletter/index.phtml
+++ b/application/modules/admin/views/scripts/newsletter/index.phtml
@@ -7,7 +7,10 @@ echo $this->bouton('id=_create_newsletter',
 echo $this->tagModelTable($this->newsletters,
                           [$this->_('Titre'), $this->_('Dernière distribution')],
                           ['titre', 'progress'],
-                          $this->model_actions,
+                          [function($model)
+                           {
+                             return $this->renderPluginsActions($model);
+                           }],
                           'newsletters',
                           null,
                           ['progress' => function($model) { return $this->tagProgressBarForNewsletter($model); }]);
diff --git a/library/ZendAfi/Controller/Plugin/Abstract.php b/library/ZendAfi/Controller/Plugin/Abstract.php
index b55426b0425..1df6bc6f830 100644
--- a/library/ZendAfi/Controller/Plugin/Abstract.php
+++ b/library/ZendAfi/Controller/Plugin/Abstract.php
@@ -67,6 +67,11 @@ abstract class ZendAfi_Controller_Plugin_Abstract {
   }
 
 
+  public function renderHeaderActions() {
+    return '';
+  }
+
+
   public function getActions($model) {
     return [];
   }
diff --git a/library/ZendAfi/Controller/Plugin/Manager/Manager.php b/library/ZendAfi/Controller/Plugin/Manager/Manager.php
index 370bc48eaa1..224e454a02c 100644
--- a/library/ZendAfi/Controller/Plugin/Manager/Manager.php
+++ b/library/ZendAfi/Controller/Plugin/Manager/Manager.php
@@ -25,8 +25,21 @@ class ZendAfi_Controller_Plugin_Manager_Manager extends ZendAfi_Controller_Plugi
   public function init() {
     parent::init();
 
-    if ('add' != $this->_request->getActionName())
-      $this->_view->model_actions = $this->_getModelActions();
+    if (('add' != $this->_request->getActionName())
+        && ('index' != $this->_request->getActionName())
+        && ($model = $this->_findModel()))
+      $this->_addModelToView($model);
+  }
+
+
+  public function renderHeaderActions() {
+    if (($model_name = $this->_view->model_name)
+        && ($model = $this->_view->$model_name))
+      return $this->_view
+        ->tag('div',
+              $this->_view->renderPluginsActions($model),
+              ['class' => 'header_actions']);
+    return '';
   }
 
 
diff --git a/library/ZendAfi/Controller/Plugin/Manager/Newsletter.php b/library/ZendAfi/Controller/Plugin/Manager/Newsletter.php
index 6337c37081a..db228a346b7 100644
--- a/library/ZendAfi/Controller/Plugin/Manager/Newsletter.php
+++ b/library/ZendAfi/Controller/Plugin/Manager/Newsletter.php
@@ -21,6 +21,48 @@
 
 
 class ZendAfi_Controller_Plugin_Manager_Newsletter extends ZendAfi_Controller_Plugin_Manager_Manager {
+  public function getActions($model) {
+    return [
+            ['url' => '/admin/newsletter/edit/id/%s',
+             'icon' => 'edit',
+             'label' => 'Modifier la newsletter'],
+            ['url' => '/admin/newsletter/preview/id/%s',
+             'icon' => 'show',
+             'label' => 'Visualiser la newsletter'],
+            ['url' => '/admin/newsletter/edit-subscribers/id/%s',
+             'icon' => 'users',
+             'caption' => 'getNumberOfUsers',
+             'label' => 'Modifier les inscrits'],
+            ['url' => '/admin/newsletter/sendtest/id/%s',
+             'icon' => 'test',
+             'label' => 'Effectuer un test d\'envoi'],
+            ['url' => '/admin/newsletter/send/id/%s',
+             'icon' => 'mail',
+             'caption' => function($model)
+              {
+                Class_ScriptLoader::getInstance()->addJQueryReady("
+function sendNewsletterClick(event) {
+  var target = $(event.target).closest('a');
+  var answer = confirm(\"".$this->_("Envoyer la lettre d'information ?")."\");
+  if (answer == false) {
+    event.preventDefault();
+    return;
+  }
+}
+
+  $(\"a[rel='send']\").click(sendNewsletterClick);
+");},
+             'label' => 'Envoyer la lettre d\'information'],
+            ['url' => '/admin/newsletter/duplicate/id/%s',
+             'icon' => 'copy',
+             'label' => 'Dupliquer la lettre d\'information'],
+            ['url' => '/admin/newsletter/delete/id/%s',
+             'icon' => 'delete',
+             'label' => 'Supprimer la lettre d\'information']
+    ];
+  }
+
+
     public function previewAction() {
     if (!$newsletter = Class_Newsletter::find((int)$this->_getParam('id'))) {
       $this->_redirectToIndex();
diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Newsletter.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Newsletter.php
index fbf840f664c..f3cefe4ba1b 100644
--- a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Newsletter.php
+++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Newsletter.php
@@ -33,37 +33,7 @@ class ZendAfi_Controller_Plugin_ResourceDefinition_Newsletter extends ZendAfi_Co
             'messages' => ['successful_save' => $this->_('Lettre d\'information "%s" enregistrée'),
                            'successful_delete' => $this->_('Lettre d\'information supprimée')],
 
-            'form_class_name' => 'ZendAfi_Form_Admin_Newsletter',
-
-            'model_actions' => [
-                                ['action' => 'edit', 'content' => $this->_view->boutonIco('type=edit')],
-                                ['action' => 'preview', 'content' => $this->_view->boutonIco('type=show')],
-                                ['action' => 'edit-subscribers',
-                                 'content' => function($model) {
-                                    return $this->_view->tag('span', $this->_view->boutonIco("picto=users", "bulle=" . $this->_('Inscrits')) . $model->getNumberOfUsers(), ['style' => 'white-space:nowrap']);
-                                  }],
-                                ['action' => 'sendtest', 'content' => $this->_view->boutonIco('type=test')],
-                                ['action' => 'send',
-                                 'content' => function($model) {
-                                    Class_ScriptLoader::getInstance()->addJQueryReady("
-function sendNewsletterClick(event) {
-  var target = $(event.target).closest('a');
-  var answer = confirm(\"".$this->_("Envoyer la lettre d'information ?")."\");
-  if (answer == false) {
-    event.preventDefault();
-    return;
-  }
-}
-
-  $(\"a[rel='send']\").click(sendNewsletterClick);
-");
-
-
-                                    return $this->_view->boutonIco('type=mail');}],
-                                ['action' => 'duplicate', 'content' => $this->_view->boutonIco('type=duplicate')],
-                                ['action' => 'delete', 'content' => $this->_view->boutonIco('type=del')],
-            ],
-    ];
+            'form_class_name' => 'ZendAfi_Form_Admin_Newsletter'];
   }
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/PluginRenderer.php b/library/ZendAfi/View/Helper/PluginRenderer.php
new file mode 100644
index 00000000000..80f9ea1d7ea
--- /dev/null
+++ b/library/ZendAfi/View/Helper/PluginRenderer.php
@@ -0,0 +1,39 @@
+<?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
+ */
+
+
+abstract class ZendAfi_View_Helper_PluginRenderer extends Zendafi_View_Helper_Basehelper {
+  public function render($method) {
+    if(!isset($this->view->plugins))
+      return '';
+
+    $plugins = $this->view->plugins;
+
+    if($plugins->isEmpty())
+      return '';
+
+    $plugins->eachDo(function($plugin) use ($method)
+                     {
+                       echo call_user_func([$plugin, $method]);
+                     });
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/RenderModelActions.php b/library/ZendAfi/View/Helper/RenderModelActions.php
index da75b2919b2..6a8d74861b4 100644
--- a/library/ZendAfi/View/Helper/RenderModelActions.php
+++ b/library/ZendAfi/View/Helper/RenderModelActions.php
@@ -64,13 +64,12 @@ class ZendAfi_View_Helper_RenderModelAction {
     if (!$this->_meetsRequirements($model))
       return '';
 
-    $caption = array_key_exists(self::CAPTION, $this->_conf)
-      ? $model->{$this->_conf[self::CAPTION]}()
-      : '';
-
+    $caption = $this->_initCaption($model);
     $url = $this->_initUrl($model);
     $icon = $this->_initIcon($model);
-    $anchorOptions = $this->_initAnchorOptions($model->getId());
+
+    $anchorOptions = $this->_initAnchorOptions($model->getId(), $url);
+
     $title = $this->_initTitle($model);
 
     $content = $this->_current_skin->renderActionIconOn($icon, $this->_view,
@@ -99,8 +98,19 @@ class ZendAfi_View_Helper_RenderModelAction {
     if (!array_key_exists(self::ICON, $this->_conf))
       return null;
 
-    return is_a($this->_conf[self::ICON], 'Closure') ?
-      $this->_conf[self::ICON]($model) : $this->_conf[self::ICON];
+    return is_a($this->_conf[self::ICON], 'Closure')
+      ? $this->_conf[self::ICON]($model)
+      : $this->_conf[self::ICON];
+  }
+
+
+  public function _initCaption($model) {
+    if (!array_key_exists(self::CAPTION, $this->_conf))
+      return null;
+
+    return is_a($this->_conf[self::CAPTION], 'Closure')
+      ? $this->_conf[self::CAPTION]($model)
+      : $model->{$this->_conf[self::CAPTION]}();
   }
 
 
@@ -111,9 +121,23 @@ class ZendAfi_View_Helper_RenderModelAction {
   }
 
 
-  protected function _initAnchorOptions($model_id) {
-    return array_key_exists(self::ANCHOR_OPTIONS, $this->_conf) ?
-      $this->_injectIdIn($model_id, $this->_conf[self::ANCHOR_OPTIONS]) : [];
+  protected function _initAnchorOptions($model_id, $url) {
+    $attribs = array_key_exists(self::ANCHOR_OPTIONS, $this->_conf)
+      ? $this->_injectIdIn($model_id, $this->_conf[self::ANCHOR_OPTIONS])
+      : [];
+
+    if(!isset($_SERVER['REQUEST_URI']))
+      return $attribs;
+
+    if ((false === strpos($_SERVER['REQUEST_URI'], $url))
+        && (false === strpos($url, $_SERVER['REQUEST_URI'])))
+      return $attribs;
+
+    isset($attribs['class'])
+      ? ($attribs['class'] .= ' selected')
+      : ($attribs['class'] = 'selected');
+
+    return $attribs;
   }
 
 
diff --git a/library/ZendAfi/View/Helper/RenderPlugins.php b/library/ZendAfi/View/Helper/RenderPlugins.php
index 9744f9a208b..dbeea838c2f 100644
--- a/library/ZendAfi/View/Helper/RenderPlugins.php
+++ b/library/ZendAfi/View/Helper/RenderPlugins.php
@@ -20,20 +20,9 @@
  */
 
 
-class ZendAfi_View_Helper_RenderPlugins extends ZendAfi_View_Helper_BaseHelper {
+class ZendAfi_View_Helper_RenderPlugins extends ZendAfi_View_Helper_PluginRenderer {
   public function renderPlugins() {
-    if(!isset($this->view->plugins))
-      return '';
-
-    $plugins = $this->view->plugins;
-
-    if($plugins->isEmpty())
-      return '';
-
-    $plugins->eachDo(function($plugin)
-                           {
-                             echo $plugin->render();
-                           });
+    return $this->render('render');
   }
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/RenderPluginsActions.php b/library/ZendAfi/View/Helper/RenderPluginsActions.php
index 426ca61e087..cd4a9fb5eaf 100644
--- a/library/ZendAfi/View/Helper/RenderPluginsActions.php
+++ b/library/ZendAfi/View/Helper/RenderPluginsActions.php
@@ -29,6 +29,7 @@ class ZendAfi_View_Helper_RenderPluginsActions extends ZendAfi_View_Helper_BaseH
 
     if($plugins->isEmpty())
       return '';
+
     return $this->view->renderModelActions($model,
                                            $plugins->injectInto([],function($actions, $plugin) use($model)
                                                                 {
diff --git a/library/ZendAfi/View/Helper/RenderPluginsHeaderActions.php b/library/ZendAfi/View/Helper/RenderPluginsHeaderActions.php
new file mode 100644
index 00000000000..18cd7dce7a4
--- /dev/null
+++ b/library/ZendAfi/View/Helper/RenderPluginsHeaderActions.php
@@ -0,0 +1,28 @@
+<?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_View_Helper_RenderPluginsHeaderActions extends ZendAfi_View_Helper_PluginRenderer {
+  public function renderPluginsHeaderActions() {
+    return $this->render('renderHeaderActions');
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/TagModelTable.php b/library/ZendAfi/View/Helper/TagModelTable.php
index dff917e01e6..5402ad9c0db 100644
--- a/library/ZendAfi/View/Helper/TagModelTable.php
+++ b/library/ZendAfi/View/Helper/TagModelTable.php
@@ -201,6 +201,7 @@ class ZendAfi_View_Helper_TagModelTable extends ZendAfi_View_Helper_BaseHelper {
     $content = $action['content'];
     $url = $this->view->url(['action' => $action['action'], 'id' => $model->getId()]);
     $attribs = ['href' => $url, 'rel' => $action['action']];
+
     if (isset($_SERVER['REQUEST_URI'])
         && false !== strpos($_SERVER['REQUEST_URI'], $url))
       $attribs['class'] = 'selected';
diff --git a/tests/scenarios/Manager/ManagerTest.php b/tests/scenarios/Manager/ManagerTest.php
index 76595f8e90d..7641ac2588f 100644
--- a/tests/scenarios/Manager/ManagerTest.php
+++ b/tests/scenarios/Manager/ManagerTest.php
@@ -356,4 +356,49 @@ class ManagerUserGroupTest extends Admin_AbstractControllerTestCase {
   public function deleteAnnecyLibraryShouldBePresent() {
     $this->assertXPath('//a[contains(@href, "/admin/usergroup/delete/id/15")]');
   }
+}
+
+
+
+
+class ManagerHeaderActionsTest extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+
+  public function tearDown() {
+    $_SERVER["REQUEST_URI"] = null;
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function editNewsletterShouldContainsEditActionSelected() {
+    $_SERVER["REQUEST_URI"] = '/admin/newsletter/edit/id/3';
+
+    Storm_Test_ObjectWrapper::onLoaderOfModel('Class_PanierNotice')
+      ->whenCalled('findAllBelongsToAdmin')->answers([]);
+
+    $this->fixture('Class_Newsletter',
+                   ['id' => 3,
+                    'titre' => 'Framasoft']);
+
+    $this->dispatch('/admin/newsletter/edit/id/3', true);
+
+    $this->assertXPath('//div[@class="header_actions"]//a[contains(@href, "/admin/newsletter/edit/id/3")][@class="selected"]');
+  }
+
+
+  /** @test */
+  public function editAlbumShouldContainsEditActionSelected() {
+    $_SERVER["REQUEST_URI"] = '/admin/album/edit_album/id/3';
+
+    $this->fixture('Class_Album',
+                   ['id' => 32,
+                    'libelle' => 'Tokyo ghoul']);
+
+
+    $this->dispatch('/admin/album/edit_album/id/32', true);
+
+    $this->assertXPath('//div[@class="header_actions"]//a[contains(@href, "/admin/album/edit_album/id/32")][@class="selected"]');
+  }
 }
\ No newline at end of file
-- 
GitLab