diff --git a/VERSIONS_WIP/74174 b/VERSIONS_WIP/74174 new file mode 100644 index 0000000000000000000000000000000000000000..b552202a27f0def7a1f4b64c1acd5186ef6a82a5 --- /dev/null +++ b/VERSIONS_WIP/74174 @@ -0,0 +1,2 @@ + - ticket #74174 : Administration : correction de l'affichage de la popup des nouvelles fonctionnalités + \ No newline at end of file diff --git a/application/modules/admin/controllers/FeatureController.php b/application/modules/admin/controllers/FeatureController.php index 8b841623ce0c7ad512d9cd47236fe04381742661..5891608432815610278863b66ca83fe13ca0613d 100644 --- a/application/modules/admin/controllers/FeatureController.php +++ b/application/modules/admin/controllers/FeatureController.php @@ -23,8 +23,8 @@ class Admin_FeatureController extends ZendAfi_Controller_Action { public function indexAction() { $this->view->titre = $this->_('Les fonctionnalités du logiciel Bokeh'); - (new Class_Feature())->stopTracking(); $user = Class_Users::getIdentity(); + (new Class_Feature())->stopPopup($user); $this->view->new_features = (new Class_Feature)->findNewFor($user); $this->view->checked_features = (new Class_Feature)->findCheckedBy($user); } @@ -74,10 +74,8 @@ class Admin_FeatureController extends ZendAfi_Controller_Action { } - public function stopTrackingAction() { - if((new Class_Feature())->stopTracking()) - $this->_helper->notify($this->_('Vous ne serez plus notifié des nouvelles fonctionnalités jusqu\'à la prochaine mise à jour du logicel.')); - - $this->_redirectToReferer(); + public function stopPopupAction() { + (new Class_Feature())->stopPopup(Class_Users::getIdentity()); + $this->_redirectToIndex(); } } \ No newline at end of file diff --git a/library/Class/Feature.php b/library/Class/Feature.php index c8006ab89afa1a1ce629a36aedd8fd73d8333eab..d8b156d0229788d1cda2ec9ca6d40110eba5ecc2 100644 --- a/library/Class/Feature.php +++ b/library/Class/Feature.php @@ -20,11 +20,7 @@ */ class Class_Feature { - - use - Trait_StaticFileSystem, - Trait_TimeSource, - Trait_Translator; + use Trait_Translator; protected static @@ -127,53 +123,54 @@ class Class_Feature { } - public function trackFeatures() { - if(!$this->_isTrackingFeaturesReady()) + public function popupFeatures($user) { + if(!$this->isPopupReady($user)) return; - if(!$features = $this->findNewFor(Class_Users::getIdentity())) + if(!$features = $this->findNewFor($user)) return; - if (isset($_COOKIE[$this->_getCookieJar()->getKey()])) + if($this->getUserPopupKey($user)) return; - $session = new Zend_Session_Namespace($this->_getCookieJar()->getKey()); + $session = new Zend_Session_Namespace(Class_User_Settings::POPUP_FEATURES); if ($session->features_seen) return; $session->features_seen = true; + Class_ScriptLoader::getInstance() ->notify($this->_renderContent($features), false, 10, 'new_features'); } - protected function _isTrackingFeaturesReady() { - if (!Class_AdminVar::get('FEATURES_TRACKING_ENABLE')) - return false; - - if(!$user = Class_Users::getIdentity()) + public function isPopupReady($user) { + if(!$user) return false; if(!$user->isAdmin()) return false; - return true; + return Class_AdminVar::get('FEATURES_TRACKING_ENABLE'); } protected function _renderContent($features) { + $stop_popup_onclick = sprintf('closeNotificationAndOpen(\'%s\');', + Class_Url::absolute(['module' => 'admin', + 'controller' => 'feature', + 'action' => 'stop-popup'], null, true)); + $buttons = [sprintf('<button class="admin-button" onclick="window.open(\'%s\', \'_top\');">%s</button>', Class_Url::absolute(['module' => 'admin', 'controller' => 'feature', 'action' => 'index'], null, true), $this->_('En savoir plus')), - sprintf('<button class="admin-button" onclick="window.open(\'%s\', \'_top\')">%s</button>', - Class_Url::absolute(['module' => 'admin', - 'controller' => 'feature', - 'action' => 'stop-tracking'], null, true), + sprintf('<button class="admin-button" onclick="%s">%s</button>', + $stop_popup_onclick, $this->_('Ne plus m\'avertir'))]; $html_features = []; @@ -191,26 +188,25 @@ class Class_Feature { } - public function stopTracking() { - if(!$this->_isTrackingFeaturesReady()) + public function stopPopup($user) { + if(!$user) return; - return $this->_getCookieJar() - ->setcookie($this->_getCookieJar()->getKey(), - '1', - $this->getTimeSource()->time() + (3600 * 24 * 30 * 3)); - } -} + if(!$this->isPopupReady($user)) + return; + return $this->setUserPopupKey($user); + } -class Class_Feature_CookieJar { - public function setcookie() { - call_user_func_array('setcookie', func_get_args()); + public function getUserPopupKey($user) { + return (new Class_User_Settings($user))->getPopupFeatures(); } - public function getKey() { - return 'tracking_features_' . str_replace('.', '_', BOKEH_RELEASE_NUMBER); + public function setUserPopupKey($user) { + (new Class_User_Settings($user))->setPopupFeatures(1); + $user->save(); + return $this; } } \ No newline at end of file diff --git a/library/Class/User/Settings.php b/library/Class/User/Settings.php index 7ce4c009a9bb8278a9009783560fd3f070ca5fb6..97cbc249dc6ecee376f50990f9c761dbb8ea7b38 100644 --- a/library/Class/User/Settings.php +++ b/library/Class/User/Settings.php @@ -27,7 +27,8 @@ class Class_User_Settings { ADMIN_SKIN = 'admin_skin', ADMIN_SKIN_COLOR = 'admin_skin_color', CHECKED_FEATURE = 'checked_features', - BOOKMARKED_SEARCHES = 'bookmarked_searches'; + BOOKMARKED_SEARCHES = 'bookmarked_searches', + POPUP_FEATURES = 'popup_features'; protected $_user, $_user_settings; @@ -209,6 +210,17 @@ class Class_User_Settings { } + public function getPopupFeatures() { + return $this->get(Class_User_Settings::POPUP_FEATURES); + } + + + public function setPopupFeatures($boolean) { + $this->set(Class_User_Settings::POPUP_FEATURES, $boolean); + return $this; + } + + protected function _getCheckedFeatures($id) { $checked_features = explode('-', $this->get(static::CHECKED_FEATURE)); return array_values(array_unique(array_merge($checked_features, @@ -261,4 +273,20 @@ class Class_User_Settings { $this->set(self::BOOKMARKED_LIBRARIES, $id); $this->_user->save(); } + + + public function updateAttributes($datas) { + if(array_key_exists(static::POPUP_FEATURES, $datas)) { + $value = $datas[static::POPUP_FEATURES]; + unset($datas[static::POPUP_FEATURES]); + $this->set(static::POPUP_FEATURES, $value); + } + return $datas; + } + + + public function injectAttributesIn($datas) { + $datas[static::POPUP_FEATURES] = $this->get(static::POPUP_FEATURES); + return $datas; + } } \ No newline at end of file diff --git a/library/Class/Users.php b/library/Class/Users.php index 9e74dc1b8c9e6bf3bfdc0e94378c996f9541b17b..35c1b1eeef1db8087a0c89a9057256d0925b72d5 100644 --- a/library/Class/Users.php +++ b/library/Class/Users.php @@ -1887,4 +1887,9 @@ class Class_Users extends Storm_Model_Abstract { public function verifyPassword($value) { return (new Class_User_Password($this))->verify($value); } + + + public function updateAttributes(Array $datas) { + return parent::updateAttributes((new Class_User_Settings($this))->updateAttributes($datas)); + } } diff --git a/library/ZendAfi/Controller/Plugin/FeaturesTracking.php b/library/ZendAfi/Controller/Plugin/FeaturesTracking.php index 79b33e82db3bb748041c4a9501effe8868440d10..c8653dc3f1937c8abf202621fd8a112a74ecc20d 100644 --- a/library/ZendAfi/Controller/Plugin/FeaturesTracking.php +++ b/library/ZendAfi/Controller/Plugin/FeaturesTracking.php @@ -22,6 +22,6 @@ class ZendAfi_Controller_Plugin_FeaturesTracking extends Zend_Controller_Plugin_Abstract { function preDispatch(Zend_Controller_Request_Abstract $request) { - (new Class_Feature())->trackFeatures(); + (new Class_Feature())->popupFeatures(Class_Users::getIdentity()); } } diff --git a/library/ZendAfi/Controller/Plugin/Manager/User.php b/library/ZendAfi/Controller/Plugin/Manager/User.php index f7ffaa8e1380207eebaae48df23cedaaba3b5fde..c6aaa2c6ada407ff595079676d9404dc9c4742b9 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/User.php +++ b/library/ZendAfi/Controller/Plugin/Manager/User.php @@ -72,44 +72,45 @@ class ZendAfi_Controller_Plugin_Manager_User extends ZendAfi_Controller_Plugin_M 'icon' => 'users', 'condition' => function() { return Class_Users::getIdentity()->isSuperAdmin();}, 'label' => $this->_('Se connecter avec l\'identité')] - ]; -} + ]; + } -protected function _getPost() { - $post = $this->_request->getPost(); - $post['user_groups'] = array_filter( - array_map(function($id) { return Class_UserGroup::find((int)$id);}, - explode('-', $this->_getParam('user_group_ids',''))) - ); + protected function _getPost() { + $post = $this->_request->getPost(); + $post['user_groups'] = array_filter( + array_map(function($id) { return Class_UserGroup::find((int)$id);}, + explode('-', $this->_getParam('user_group_ids',''))) + ); - unset($post['id_categories']); + unset($post['id_categories']); - return $post; -} + return $post; + } -protected function _getFormValues($model) { - $array_model=parent::_getFormValues($model); - $array_model['user_group_ids']=implode('-',array_map(function($group) { return $group->getId();},$model->getUserGroups())); + protected function _getFormValues($model) { + $array_model = parent::_getFormValues($model); + $array_model['user_group_ids'] = implode('-',array_map(function($group) { return $group->getId();},$model->getUserGroups())); + $array_model = (new Class_User_Settings(Class_Users::getIdentity()))->injectAttributesIn($array_model); - return $array_model; -} + return $array_model; + } -protected function _setupFormAndSave($model) { - if ($this->_request->isPost()) - $model->updateSIGBOnSave(); + protected function _setupFormAndSave($model) { + if ($this->_request->isPost()) + $model->updateSIGBOnSave(); - try { - return parent::_setupFormAndSave($model); - } catch (Exception $e) { - $this->_helper->notify($e->getMessage()); + try { + return parent::_setupFormAndSave($model); + } catch (Exception $e) { + $this->_helper->notify($e->getMessage()); + } } -} -protected function _canEdit($model) { - return $model->getRoleLevel() <= Class_Users::getIdentity()->getRoleLevel(); -} + protected function _canEdit($model) { + return $model->getRoleLevel() <= Class_Users::getIdentity()->getRoleLevel(); + } } \ No newline at end of file diff --git a/library/ZendAfi/Form/Admin/User.php b/library/ZendAfi/Form/Admin/User.php index f4479ee3ad0b8fbe8bb159ced329da72ee2497cb..ac332f61c5c7f2289504ad71dfe0534fa2afb718 100644 --- a/library/ZendAfi/Form/Admin/User.php +++ b/library/ZendAfi/Form/Admin/User.php @@ -50,7 +50,8 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { ->addAdminUserInfo() ->addRedmine() ->addSIGB() - ->addMoreUserInfo(); + ->addMoreUserInfo() + ->addPreferences(); return $this; } @@ -198,6 +199,20 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { } + protected function addPreferences() { + if(!Class_Feature::isPopupReady(Class_Users::getIdentity())) + return $this; + + $this->addElement('checkbox', + Class_User_Settings::POPUP_FEATURES, + ['label' => $this->_('Masquer la popup des nouvelles fonctionnalités')]) + ->addDisplayGroup([Class_User_Settings::POPUP_FEATURES], + 'preferences_group', + ['legend' => $this->_('Préférences')]); + return $this; + } + + protected function addValidity( $start, $end) { $event_range = $this->getElement('subscription_range_date'); diff --git a/public/admin/js/notification/js/jquery_notification_v.1.js b/public/admin/js/notification/js/jquery_notification_v.1.js index 4f84c5f3dbc8581e80dd306df0ef44fe0cb0d176..701c601a13c67b198a9134146fd2b8d329b2dd22 100755 --- a/public/admin/js/notification/js/jquery_notification_v.1.js +++ b/public/admin/js/notification/js/jquery_notification_v.1.js @@ -101,5 +101,7 @@ function slideDownNotification(startAfter, autoClose, duration){ } - - +function closeNotificationAndOpen(url, duration = 1) { + closeNotification(duration); + $.ajax(url); +} diff --git a/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php b/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php index 9cc11c5878a254749b97cbf02e5db368ee4bec90..617168086baf54843f2a3c3bfda9672a092c52d0 100644 --- a/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php +++ b/tests/application/modules/admin/controllers/IndexControllerFeaturesTrackingTest.php @@ -22,39 +22,21 @@ abstract class IndexControllerFeaturesTrackingTestCase extends Admin_AbstractControllerTestCase { protected $_storm_default_to_volatile = true; - protected $_expected_message = 'Nouvelles fonctionnalit\u00e9s depuis votre derni\u00e8re connexion :'; - protected $_cookie_jar; + protected + $_expected_message = 'Nouvelles fonctionnalit\u00e9s depuis votre derni\u00e8re connexion :', + $_user; public function setUp() { parent::setUp(); - - $this->fixture('Class_AdminVar', ['id' => 'FEATURES_TRACKING_ENABLE', - 'valeur' => true]); - - Class_Feature::setTimeSource($this->mock() - ->whenCalled('time') - ->answers(strtotime('2018-02-21 11:51:54'))); - - Class_Feature::setCookieJar($this->_cookie_jar = - $this->mock() - ->whenCalled('setcookie') - ->answers(true) - - ->whenCalled('getKey') - ->answers('tracking_features_7_11_20')); - } - - - public function tearDown() { - Class_Feature::setCookieJar(null); - $_COOKIE = []; - parent::tearDown(); + $this->_user = Class_Users::getIdentity(); + Class_AdminVar::set('FEATURES_TRACKING_ENABLE', 1); } } + class IndexControllerFeaturesTrackingFirstVisitTest extends IndexControllerFeaturesTrackingTestCase { @@ -79,7 +61,6 @@ class IndexControllerFeaturesTrackingTrackingFirstVisitWithAdminVarDisabledTest public function setUp() { parent::setUp(); - $this->fixture('Class_AdminVar', ['id' => 'FEATURES_TRACKING_ENABLE', 'valeur' => false]); $this->dispatch('/', true); @@ -98,6 +79,7 @@ class IndexControllerFeaturesTrackingTrackingFirstVisitWithAdminVarDisabledTest class IndexControllerFeaturesTrackingSecondVisitTest extends IndexControllerFeaturesTrackingTestCase { + public function setUp() { parent::setUp(); $this->dispatch('/', true); @@ -114,8 +96,8 @@ class IndexControllerFeaturesTrackingSecondVisitTest /** @test */ - public function shouldNotSetCookieFor6Months() { - $this->assertFalse($this->_cookie_jar->methodHasBeenCalled('setcookie')); + public function adminShouldNotHavePopupKey() { + $this->assertNull((new Class_User_Settings($this->_user))->get(Class_User_Settings::POPUP_FEATURES)); } } @@ -128,7 +110,7 @@ class IndexControllerFeaturesTrackingExistingCookieVisitTest public function setUp() { parent::setUp(); - $_COOKIE['tracking_features_7_11_20'] = 1; + (new Class_Feature)->stopPopup($this->_user); $this->dispatch('/', true); } @@ -147,28 +129,69 @@ class IndexControllerFeaturesTrackingUntrackTest public function setUp() { parent::setUp(); - Class_Feature::setCookieJar($this->_cookie_jar = $this->mock() - ->whenCalled('setcookie') - ->with('tracking_features_7_11_20', - 1, - 1526986314) - ->answers(true) - - ->whenCalled('getKey') - ->answers('tracking_features_7_11_20')); } /** @test */ - public function stopTrackingActionshouldSetCookie() { - $this->dispatch('/admin/feature/stop-tracking', true); - $this->assertTrue($this->_cookie_jar->methodHasBeenCalled('setcookie')); + public function stopPopupActionshouldSetCookie() { + $this->dispatch('/admin/feature/stop-popup', true); + $this->assertEquals('1', (new Class_Feature)->getUserPopupKey($this->_user)); } /** @test */ - public function indexActionSetCookie() { + public function dispatchIndexActionShouldStopPopup() { $this->dispatch('/admin/feature/index', true); - $this->assertTrue($this->_cookie_jar->methodHasBeenCalled('setcookie')); + $this->assertEquals('1', (new Class_Feature)->getUserPopupKey($this->_user)); } -} \ No newline at end of file +} + + + + +class IndexControllerFeaturesTrackingUserFormTest extends IndexControllerFeaturesTrackingTestCase { + public function setUp() { + parent::setUp(); + $this->dispatch('/admin/users/edit/id/' . $this->_user->getId(), true); + } + + + /** @test */ + public function checkboxHideFeaturesPopupShouldBePresent() { + $this->assertXPath('//form//input[@type="checkbox"][@name="popup_features"]'); + } +} + + + + +class IndexControllerFeaturesTrackingUserPostFormTest extends IndexControllerFeaturesTrackingTestCase { + public function setUp() { + parent::setUp(); + $this->postDispatch('/admin/users/edit/id/' . $this->_user->getId(), + ['popup_features' => 1]); + } + + + /** @test */ + public function userPopupFeatureSettingShouldHaveBeenSaved() { + $this->assertEquals('1', (new Class_Feature)->getUserPopupKey($this->_user)); + } +} + + + + +class IndexControllerFeaturesTrackingUserFormWithSettingsTest extends IndexControllerFeaturesTrackingTestCase { + public function setUp() { + parent::setUp(); + (new Class_Feature)->setUserPopupKey($this->_user); + $this->dispatch('/admin/users/edit/id/' . $this->_user->getId(), true); + } + + + /** @test */ + public function checkboxHideFeaturesPopupShouldBePresent() { + $this->assertXPath('//form//input[@type="checkbox"][@name="popup_features"][@checked]'); + } +}