From 7bd43298da6062df103e13eaac2b9f2c6c80582a Mon Sep 17 00:00:00 2001 From: Mathieu Templier Date: Mon, 22 Jul 2019 13:46:38 +0200 Subject: [PATCH 1/6] FEATURE : Reminders for satisfaction --- ajax/viewsubitem_reminder.php | 70 ++++ front/surveyreminder.form.php | 33 ++ hook.php | 29 +- inc/notification.class.php | 197 ++++++++++ inc/notificationtargetticket.class.php | 135 +++++++ inc/reminder.class.php | 115 ++++++ inc/survey.class.php | 11 +- inc/surveyreminder.class.php | 484 +++++++++++++++++++++++++ install/sql/empty-1.4.3.sql | 66 ++++ install/sql/update-1.4.3.sql | 17 + setup.php | 10 +- 11 files changed, 1154 insertions(+), 13 deletions(-) create mode 100644 ajax/viewsubitem_reminder.php create mode 100644 front/surveyreminder.form.php create mode 100644 inc/notification.class.php create mode 100644 inc/notificationtargetticket.class.php create mode 100644 inc/reminder.class.php create mode 100644 inc/surveyreminder.class.php create mode 100644 install/sql/empty-1.4.3.sql create mode 100644 install/sql/update-1.4.3.sql diff --git a/ajax/viewsubitem_reminder.php b/ajax/viewsubitem_reminder.php new file mode 100644 index 0000000..a25e8a0 --- /dev/null +++ b/ajax/viewsubitem_reminder.php @@ -0,0 +1,70 @@ +. + * --------------------------------------------------------------------- + */ + +include('../../../inc/includes.php'); +header("Content-Type: text/html; charset=UTF-8"); +Html::header_nocache(); + +Session::checkLoginUser(); + +if (!isset($_POST['type'])) { + exit(); +} +if (!isset($_POST['parenttype'])) { + exit(); +} + +if (($item = getItemForItemtype($_POST['type'])) + && ($parent = getItemForItemtype($_POST['parenttype']))) { + if (isset($_POST[$parent->getForeignKeyField()]) + && isset($_POST["id"]) + && $parent->getFromDB($_POST[$parent->getForeignKeyField()])) { + + $reminderName = PluginSatisfactionSurveyReminder::PREDEFINED_REMINDER_OPTION_NAME; + + $options = [ + 'parent' => $parent + ]; + + if(isset( $_POST[$reminderName])){ + $options[$reminderName] = intval($_POST[$reminderName]); + } + + $item->showForm($_POST["id"], $options); + + } else { + echo __('Access denied'); + } +} + +Html::ajaxFooter(); diff --git a/front/surveyreminder.form.php b/front/surveyreminder.form.php new file mode 100644 index 0000000..74d0d03 --- /dev/null +++ b/front/surveyreminder.form.php @@ -0,0 +1,33 @@ +generatePredefinedReminderForAdd($input); + } + + $reminder->check(-1, CREATE, $input); + $reminder->add($input); + Html::back(); + +} else if (isset($_POST["update"])) { + $reminder->check($_POST['id'], UPDATE); + $reminder->update($_POST); + Html::back(); + +} else if (isset($_POST["delete"])) { + $reminder->check($_POST['id'], PURGE); + $reminder->delete($_POST); + Html::back(); + +} + +Html::displayErrorAndDie('Lost'); diff --git a/hook.php b/hook.php index 6bf4728..dff80ba 100644 --- a/hook.php +++ b/hook.php @@ -7,9 +7,13 @@ function plugin_satisfaction_install() { global $DB; include_once(GLPI_ROOT . "/plugins/satisfaction/inc/profile.class.php"); + include_once(GLPI_ROOT . "/plugins/satisfaction/inc/notificationtargetticket.class.php"); if (!$DB->tableExists("glpi_plugin_satisfaction_surveys")) { - $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/empty-1.4.1.sql"); + $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/empty-1.4.3.sql"); + + PluginSatisfactionNotificationTargetTicket::install(); + } else { if (!$DB->fieldExists("glpi_plugin_satisfaction_surveyquestions", "type")) { $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/update-1.1.0.sql"); @@ -22,10 +26,16 @@ function plugin_satisfaction_install() { if (!$DB->tableExists("glpi_plugin_satisfaction_surveytranslations")) { $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/update-1.4.1.sql"); } + + //version 1.4.3 + if (!$DB->tableExists("glpi_plugin_satisfaction_surveyreminders")) { + $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/update-1.4.3.sql"); + } } PluginSatisfactionProfile::initProfile(); PluginSatisfactionProfile::createFirstAccess($_SESSION['glpiactiveprofile']['id']); + return true; } @@ -37,10 +47,13 @@ function plugin_satisfaction_uninstall() { include_once(GLPI_ROOT . "/plugins/satisfaction/inc/profile.class.php"); include_once(GLPI_ROOT . "/plugins/satisfaction/inc/menu.class.php"); + include_once(GLPI_ROOT . "/plugins/satisfaction/inc/notificationtargetticket.class.php"); - $tables = ["glpi_plugin_satisfaction_surveys", - "glpi_plugin_satisfaction_surveyquestions", - "glpi_plugin_satisfaction_surveyanswers"]; + $tables = [ + "glpi_plugin_satisfaction_surveys", + "glpi_plugin_satisfaction_surveyquestions", + "glpi_plugin_satisfaction_surveyanswers" + ]; foreach ($tables as $table) { $DB->query("DROP TABLE IF EXISTS `$table`;"); @@ -62,5 +75,13 @@ function plugin_satisfaction_uninstall() { PluginSatisfactionMenu::removeRightsFromSession(); + PluginSatisfactionNotificationTargetTicket::uninstall(); + + CronTask::Register(PluginSatisfactionReminder::class, PluginSatisfactionReminder::CRON_TASK_NAME, DAY_TIMESTAMP); + return true; +} + +function plugin_satisfaction_get_events(NotificationTargetTicket $target) { + $target->events['survey_reminder'] = __("Ticket Satisfaction Reminder", 'satisfaction'); } \ No newline at end of file diff --git a/inc/notification.class.php b/inc/notification.class.php new file mode 100644 index 0000000..9c7cea5 --- /dev/null +++ b/inc/notification.class.php @@ -0,0 +1,197 @@ +. + -------------------------------------------------------------------------- + */ + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access directly to this file"); +} + +/** + * Class PluginResourcesNotification + */ +class PluginSatisfactionNotification extends CommonDBTM { + + static $rightname = 'plugin_satisfaction'; + + /** + * Return the localized name of the current Type + * Should be overloaded in each new class + * + * @param integer $nb Number of items + * + * @return string + **/ + static function getTypeName($nb = 0) { + + return __('Notification satisfaction reminder', 'satisfaction'); + } + + /** + * Have I the global right to "create" the Object + * May be overloaded if needed (ex KnowbaseItem) + * + * @return booleen + **/ + static function canCreate() { + return Session::haveRight(self::$rightname, [CREATE, UPDATE, DELETE]); + } + + /** + * Have I the global right to "view" the Object + * + * Default is true and check entity if the objet is entity assign + * + * May be overloaded if needed + * + * @return booleen + **/ + static function canView() { + return Session::haveRight(self::$rightname, READ); + } + + /** + * Function list items + * + * @param type $ID + */ + public function listItems($ID) { + + $rand = mt_rand(); + + // Start + $start = 0; + if (isset($_REQUEST["start"])) { + $start = $_REQUEST["start"]; + } + + // Get data + $data = $this->getItems($ID, $start); + if (!empty($data)) { + echo "
"; + $dbu = new DbUtils(); + Html::printAjaxPager(self::getTypeName(2), $start, $dbu->countElementsInTable($this->getTable())); + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + $dbu = new DbUtils(); + + foreach ($data as $field) { + echo ""; +// // User +// echo ""; +// echo ""; +// echo ""; +// echo ""; + // Ticket + // TODO + } + echo "
".self::getTypeName(1)."
".__('User')."".__('Date')."".__('Type')."
".$dbu->formatUserName($field['users_id'], $field['name'], $field['realname'], $field['firstname'])."".Html::convDateTime($field['date_mod'])."".self::getStatus($field['type'])."
"; + echo "
"; + } + } + + /** + * Function get items for resource + * + * @global type $DB + * @param type $recordmodels_id + * @param type $start + * @return type + */ + function getItems($resources_id, $start = 0) { + global $DB; + + $output = []; + + $query = "SELECT `".$this->getTable()."`.`id`, + `glpi_users`.`realname`, + `glpi_users`.`firstname`, + `glpi_users`.`name`, + `".$this->getTable()."`.`type`, + `".$this->getTable()."`.`users_id`, + `".$this->getTable()."`.`date_mod`, + `".$this->getTable()."`.`plugin_resources_resources_id` + FROM ".$this->getTable()." + LEFT JOIN `glpi_users` ON (`".$this->getTable()."`.`users_id` = `glpi_users`.`id`) + WHERE `".$this->getTable()."`.`plugin_resources_resources_id` = ".Toolbox::cleanInteger($resources_id)." + ORDER BY `".$this->getTable()."`.`date_mod` DESC + LIMIT ".intval($start).",".intval($_SESSION['glpilist_limit']); + + $result = $DB->query($query); + if ($DB->numrows($result)) { + while ($data = $DB->fetch_assoc($result)) { + $output[$data['id']] = $data; + } + } + + return $output; + } + + /** + * Function get the Status + * + * @return an array + */ + static function getStatus($value) { + $data = self::getAllStatusArray(); + return $data[$value]; + } + + /** + * Get the SNMP Status list + * + * @return an array + */ + static function getAllStatusArray() { + + // To be overridden by class + $tab = ['report' => __('Resource creation', 'resources'), + 'other' => __('Other', 'resources')]; + + return $tab; + } + + /** + * if profile deleted + * + * @param \Ticket $resource + */ + static function purgeNotification(Ticket $ticket) { + $temp = new self(); + $temp->deleteByCriteria(['tickets_id' => $ticket->getField("id")]); + } + +} + diff --git a/inc/notificationtargetticket.class.php b/inc/notificationtargetticket.class.php new file mode 100644 index 0000000..31585c5 --- /dev/null +++ b/inc/notificationtargetticket.class.php @@ -0,0 +1,135 @@ +. + -------------------------------------------------------------------------- + */ +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access directly to this file"); +} + +/** + * Class PluginSatisfactionNotificationTargetTicket + */ +class PluginSatisfactionNotificationTargetTicket extends NotificationTarget { + + function getEvents(){ + return ['survey_reminder' => __('Survey Reminder', 'satisfaction')]; + } + + function getDatasForTemplate($event, $options = []) { + } + + function getSpecificTargets($data, $options) { + + } + + public static function sendReminder($item){ + NotificationEvent::raiseEvent('survey_reminder', $item, []); + } + + function getTags() { + $notification_target_ticket = new NotificationTargetTicket(); + $notification_target_ticket->getTags(); + $this->tag_descriptions = $notification_target_ticket->tag_descriptions; + } + + function getDatasForObject(CommonDBTM $item, array $options, $simple=false) { + $notification_target_ticket = new NotificationTargetTicket(); + $data = $notification_target_ticket->getDataForObject($item, $options, $simple); + return $data; + } + + static function install(){ + + $notificationTemplateDBTM = new NotificationTemplate(); + if(!$notificationTemplateDBTM->getFromDBByCrit(['name' => 'Ticket Satisfaction Reminder'])) { + $notificationTemplateId = $notificationTemplateDBTM->add([ + 'name' => "Ticket Satisfaction Reminder", + 'itemtype' => 'Ticket', + 'comment' => "Created by the plugin satisfaction" + ]); + } + + $notificationDBTM = new Notification(); + if(!$notificationDBTM->getFromDBByCrit(['name' => 'Ticket Satisfaction Reminder'])){ + $notifications_id = $notificationDBTM->add([ + 'name' => "Ticket Satisfaction Reminder", + 'entities_id' => 0, + 'is_recursive' => 1, + 'is_active' => 1, + 'itemtype' => 'Ticket', + 'event' => "survey_reminder", + 'comment' => "Created by the plugin Satisfaction" + ]); + } + +// $notificationtargets = new NotificationTarget(); +// +// $requester_group_id = 999999; +// +// $crit = [ +// 'items_id' => $requester_group_id, +// "notifications_id" => $notificationDBTM->getField('id') +// ]; +// +// if(!$notificationtargets->getFromDBByCrit($crit)){ +// +// $input = [ +// 'items_id' => $requester_group_id, +// 'type' => Notification::REQUESTER_GROUP, +// 'notifications_id' =>$notificationDBTM->getField('id') +// ]; +// +// $notificationtargets->add($input); +// } + } + + static function uninstall(){ + global $DB; + + $notificationDBTM = new Notification(); + $notificationDBTM->getFromDBByCrit(['event'=>'survey-reminder']); + + $notification_notificationTemplate = new Notification_NotificationTemplate(); + + if($notification_notificationTemplate->find(['notifications_id' => $notificationDBTM->getID()])){ + $DB->query("DELETE FROM glpi_notificationtemplatetranslations + WHERE notificationtemplates_id = " . $notification_notificationTemplate->getField('notificationtemplates_id')); + + $DB->query("DELETE FROM glpi_notificationtargets + WHERE notifications_id = " . $notificationDBTM->getID()); + + $DB->query("DELETE FROM glpi_notifications_notificationtemplates + WHERE id = " . $notification_notificationTemplate->getField('notificationtemplates_id')); + + $DB->query("DELETE FROM glpi_notificationtemplates + WHERE id = " . $notification_notificationTemplate->getField('notificationtemplates_id')); + + $DB->query("DELETE FROM glpi_notifications + WHERE id = " . $notificationDBTM->getID()); + } + } +} \ No newline at end of file diff --git a/inc/reminder.class.php b/inc/reminder.class.php new file mode 100644 index 0000000..c8bb7c2 --- /dev/null +++ b/inc/reminder.class.php @@ -0,0 +1,115 @@ + __('Send automaticaly survey reminders and delete old', 'resources')]; // Optional + break; + } + return []; + } + + /** + * Cron action + * + * @param $task for log + * @global $CFG_GLPI + * + * @global $DB + */ + static function cronSatisfactionReminder($task = NULL) { + + $CronTask = new CronTask(); + if ($CronTask->getFromDBbyName(PluginSatisfactionReminder::class, PluginSatisfactionReminder::CRON_TASK_NAME)) { + if ($CronTask->fields["state"] == CronTask::STATE_DISABLE) { + return 0; + } + } else { + return 0; + } + + // Delete reminders of answered survey + self::deleteObsoleteReminders(); + + // Send reminder survey when date == today + self::createNotificationsFromReminders(); + } + + static function deleteObsoleteReminders(){ + global $DB; + + $selectQuery = "SELECT re.id"; + $selectQuery.= " FROM ".self::getTable() . " as re"; + $selectQuery.= " INNER JOIN ".TicketSatisfaction::getTable() . " as sa"; + $selectQuery.= " ON sa.id = re.".self::$items_id; + $selectQuery.= " WHERE sa.date_answered IS NOT NULL"; + + $deleteQuery = "DELETE FROM ".self::getTable(); + $deleteQuery.= " WHERE id = "; + + $result = $DB->query($selectQuery); + + if ($DB->numrows($result)) { + while ($data = $DB->fetch_assoc($result)) { + $DB->query($deleteQuery.$data['id']); + } + } + } + + static function createNotificationsFromReminders(){ + global $DB; + + $selectQuery = "SELECT sa.*"; + $selectQuery.= " FROM ".self::getTable() . " as re"; + $selectQuery.= " INNER JOIN ".TicketSatisfaction::getTable() . " as sa"; + $selectQuery.= " ON sa.id = re.".self::$items_id; + $selectQuery.= " WHERE sa.date_answered IS NULL"; + $selectQuery.= " AND DATEDIFF(re.date, CURDATE()) < 0"; + + $result = $DB->query($selectQuery); + + if ($DB->numrows($result)) { + while ($data = $DB->fetch_assoc($result)) { + PluginSatisfactionNotificationTargetTicket::sendReminder($data); + } + } + + } +} \ No newline at end of file diff --git a/inc/survey.class.php b/inc/survey.class.php index 1ff5ba3..b03b33c 100644 --- a/inc/survey.class.php +++ b/inc/survey.class.php @@ -38,12 +38,13 @@ function defineTabs($options = []) { $ong = []; $this->addDefaultFormTab($ong); - $this->addStandardTab('PluginSatisfactionSurveyQuestion', $ong, $options); - $this->addStandardTab('PluginSatisfactionSurveyAnswer', $ong, $options); - $this->addStandardTab('PluginSatisfactionSurveyResult', $ong, $options); - $this->addStandardTab('PluginSatisfactionSurveyTranslation', $ong, $options); + $this->addStandardTab(PluginSatisfactionSurveyQuestion::class, $ong, $options); + $this->addStandardTab(PluginSatisfactionSurveyAnswer::class, $ong, $options); + $this->addStandardTab(PluginSatisfactionSurveyResult::class, $ong, $options); + $this->addStandardTab(PluginSatisfactionSurveyTranslation::class, $ong, $options); + $this->addStandardTab(PluginSatisfactionSurveyReminder::class, $ong, $options); - $this->addStandardTab('Log', $ong, $options); + $this->addStandardTab(Log::class, $ong, $options); return $ong; } diff --git a/inc/surveyreminder.class.php b/inc/surveyreminder.class.php new file mode 100644 index 0000000..9b319b4 --- /dev/null +++ b/inc/surveyreminder.class.php @@ -0,0 +1,484 @@ +getType() == PluginSatisfactionSurvey::class) { + return _n('Reminder', 'Reminders', 2, 'satisfaction'); + } + + return ''; + } + + /** + * show Tab content + * + * @since version 0.83 + * + * @param $item CommonGLPI object for which the tab need to be displayed + * @param $tabnum integer tab number (default 1) + * @param $withtemplate boolean is a template object ? (default 0) + * + * @return true + **/ + static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { + if ($item->getType() == PluginSatisfactionSurvey::class) { + self::showSurvey($item, true); + } + return true; + } + + /** + * Print survey + * + * @param \CommonGLPI $item + * @param bool $preview + * + * @return bool + */ + static function showSurvey(PluginSatisfactionSurvey $survey, $preview = false) { + + global $CFG_GLPI; + + $surveyReminder = new self(); + $sID = $survey->fields['id']; + $rand_survey = mt_rand(); + + $canadd = Session::haveRight(self::$rightname, CREATE); + $canedit = Session::haveRight(self::$rightname, UPDATE); + $canpurge = Session::haveRight(self::$rightname, PURGE); + + echo "
\n"; + if ($canadd) { + echo "\n"; + echo "
"; + // Add a reminder + echo ""; + echo __('Add a reminder', 'satisfaction') . "\n"; + echo "
"; + // Add a preset reminder + echo ""; + echo __('Add a predefined reminder', 'satisfaction') . "\n"; + echo "

"; + } + + // Display existing questions + $remminders = $surveyReminder->find([self::$items_id => $sID], 'id'); + if (count($remminders) == 0) { + echo ""; + echo ""; + echo "
" . __('No reminders for this survey', 'satisfaction') . "
"; + } else { + + $rand = mt_rand(); + if ($canpurge) { + //TODO : Detect delete to update history + Html::openMassiveActionsForm('mass' . __CLASS__ . $rand); + $massiveactionparams = ['item' => __CLASS__, 'container' => 'mass' . __CLASS__ . $rand]; + Html::showMassiveActions($massiveactionparams); + } + + echo ""; + echo ""; + if ($canpurge) { + echo ""; + } + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + + foreach ($remminders as $reminder) { + if ($surveyReminder->getFromDB($reminder['id'])) { + $surveyReminder->showOne($canedit, $canpurge, $rand_survey); + } + } + echo "
" . Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand) . "" . $surveyReminder->getColumnTitles(self::COLUMN_NAME) . "" . $surveyReminder->getColumnTitles(self::COLUMN_DURATION_TYPE) . "" . $surveyReminder->getColumnTitles(self::COLUMN_DURATION) . "" . $surveyReminder->getColumnTitles(self::COLUMN_IS_ACTIVE) . "
"; + + if ($canpurge) { + $paramsma['ontop'] = false; + Html::showMassiveActions($paramsma); + Html::closeForm(); + } + } + + } + + /** + * @param $ID + * @param array $options + * + * @return bool + */ + function showForm($ID, $options = []) { + if (isset($options['parent']) && !empty($options['parent'])) { + $survey = $options['parent']; + } + + $surveyReminder = new self(); + if ($ID <= 0) { + $surveyReminder->getEmpty(); + } else { + $surveyReminder->getFromDB($ID); + } + + if (!$surveyReminder->canView()) { + return false; + } + + $displayPresetReminderForm = isset($options[self::PREDEFINED_REMINDER_OPTION_NAME]) + && $options[self::PREDEFINED_REMINDER_OPTION_NAME]; + + echo "
"; + + echo "
"; + + echo ""; + if($displayPresetReminderForm){ + echo ""; + } + else{ + echo ""; + } + + echo ""; + + if($displayPresetReminderForm){ + + echo ""; + + echo ""; + echo ""; + echo ""; + + }else{ + echo ""; + + // Name line 1 + echo ""; + echo ""; + + echo ""; + + // Comment line 1 + echo ""; + echo ""; + + echo ""; + + // Duration type line 2 + echo ""; + echo ""; + echo ""; + echo ""; + + // Duration line 3 + echo ""; + echo ""; + echo ""; + echo ""; + + // Active line 4 + echo ""; + echo ""; + echo ""; + } + + echo ""; + echo ""; + echo ""; + + echo "
" . __('Choose a predefined reminder', 'satisfaction') . "" . __('Add a reminder', 'satisfaction') . "
" . __('Predefined Reminders') . "" .self::getPresetReminderDropdown(self::PREDEFINED_REMINDER_OPTION_NAME) . "
" . self::getColumnTitles(self::COLUMN_NAME) . "" . self::getColumnTitles(self::COLUMN_COMMENT) . ""; + echo ""; + echo "
" . self::getColumnTitles(self::COLUMN_DURATION_TYPE) . "" .self::getDurationDropdown(self::COLUMN_DURATION_TYPE, $surveyReminder->fields[self::COLUMN_DURATION_TYPE]) . "
" . self::getColumnTitles(self::COLUMN_DURATION) . ""; + echo ''; + echo "
" . self::getColumnTitles(self::COLUMN_IS_ACTIVE) . ""; + Dropdown::showYesNo(self::COLUMN_IS_ACTIVE, $surveyReminder->fields[self::COLUMN_IS_ACTIVE]); + echo "
"; + if ($ID <= 0) { + echo Html::hidden(self::$items_id, ['value' => $survey->getField('id')]); + echo ""; + } else { + echo Html::hidden('id', ['value' => $ID]); + echo ""; + } + echo "
"; + + Html::closeForm(); + } + + /** + * Display line with name & type + * + * @param $canedit + * @param $rand + */ + function showOne($canedit, $canpurge, $rand) { + global $CFG_GLPI; + + $style = ''; + if ($canedit) { + $style = "style='cursor:pointer' onClick=\"viewEditReminder" . + $this->fields[self::$items_id] . + $this->fields['id'] . "$rand();\"" . + " id='viewquestion" . $this->fields[self::$items_id] . $this->fields["id"] . "$rand'"; + } + echo ""; + + if ($canpurge) { + echo ""; + Html::showMassiveActionCheckBox(__CLASS__, $this->fields["id"]); + echo ""; + } + + if ($canedit) { + echo "\n\n"; + } + + echo "" . nl2br($this->fields[self::COLUMN_NAME]) . ""; + echo "" . nl2br($this->getDurationTitles($this->fields[self::COLUMN_DURATION_TYPE])) . ""; + echo "" . nl2br($this->fields[self::COLUMN_DURATION]) . ""; + echo "" . nl2br($this->getActiveTitles($this->fields[self::COLUMN_IS_ACTIVE])) . ""; + echo ""; + } + + /** + * Get the standard massive actions which are forbidden + * + * @since version 0.84 + * + * @return an array of massive actions + **/ + public function getForbiddenStandardMassiveAction() { + + $forbidden = parent::getForbiddenStandardMassiveAction(); + $forbidden[] = 'update'; + return $forbidden; + } + + public function getActiveTitles($id){ + $titles = [ + self::ACTIVE_OFF => __('No'), + self::ACTIVE_ON => __('Yes'), + ]; + return $titles[$id]; + } + + public function getDurationTitles($id = null){ + + $titles = [ + self::DURATION_DAY => __('Day'), + self::DURATION_MONTH => __('Month', 'satisfaction') + ]; + + if(is_null($id)){ + return $titles; + } + else{ + return $titles[$id]; + } + } + + public function getPresetReminderTitles($id = null){ + $yolo = 2; + + $titles = [ + self::PREDEFINED_1_WEEK => __('One Week', 'satisfaction'), + self::PREDEFINED_2_WEEK => __('Two Week', 'satisfaction'), + self::PREDEFINED_1_MONTH => __('One Month', 'satisfaction'), + ]; + + if(is_null($id)){ + return $titles; + } + else{ + return $titles[$id]; + } + } + + public function getColumnTitles($id){ + $titles = [ + self::COLUMN_NAME => __('Name'), + self::COLUMN_DURATION_TYPE => __("Duration Type", "satisfaction"), + self::COLUMN_DURATION => __("Duration", "satisfaction"), + self::COLUMN_COMMENT => __("Comments"), + self::COLUMN_IS_ACTIVE => __("Active"), + ]; + + return $titles[$id]; + } + + public function getDurationDropdown($name, $defaultValue){ + + $params = [ + 'display' => false, + 'value' => $defaultValue + ]; + + return Dropdown::showFromArray($name, self::getDurationTitles(), $params); + } + + public function getPresetReminderDropdown($name){ + $params = [ + 'display' => false + ]; + + return Dropdown::showFromArray($name, self::getPresetReminderTitles(), $params); + } + + public function generatePredefinedReminderForAdd($postValues){ + + $namePrefix = __('Reminder', 'satisfaction'); + $comment = __('Preset Reminder'); + + switch(intval($postValues[self::PREDEFINED_REMINDER_OPTION_NAME])){ + case self::PREDEFINED_1_WEEK: + $postValues[self::COLUMN_NAME] = $namePrefix." ".self::getPresetReminderTitles(self::PREDEFINED_1_WEEK); + $postValues[self::COLUMN_COMMENT] = $comment; + $postValues[self::COLUMN_DURATION_TYPE] = self::DURATION_DAY; + $postValues[self::COLUMN_DURATION] = 7; + break; + case self::PREDEFINED_2_WEEK: + $postValues[self::COLUMN_NAME] = $namePrefix." ".self::getPresetReminderTitles(self::PREDEFINED_2_WEEK); + $postValues[self::COLUMN_COMMENT] = $comment; + $postValues[self::COLUMN_DURATION_TYPE] = self::DURATION_DAY; + $postValues[self::COLUMN_DURATION] = 14; + break; + case self::PREDEFINED_1_MONTH: + $postValues[self::COLUMN_NAME] = $namePrefix." ".self::getPresetReminderTitles(self::PREDEFINED_1_MONTH); + $postValues[self::COLUMN_COMMENT] = $comment; + $postValues[self::COLUMN_DURATION_TYPE] = self::DURATION_MONTH; + $postValues[self::COLUMN_DURATION] = 1; + break; + } + return $postValues; + } + + /** + * Verify this survey does not have a reminder with exact same duration type and duration + * + * @param $input + * @return array|bool + */ + function prepareInputForAdd($input) { + $crit = [ + self::COLUMN_DURATION_TYPE => $input[self::COLUMN_DURATION_TYPE], + self::COLUMN_DURATION => $input[self::COLUMN_DURATION], + ]; + + $items = $this->find($crit); + + if(count($items)){ + + $item = array_pop($items); + + $errorMessage = __('You already have a reminder with the same duration type and duration named : %s', 'satisfaction'); + + Session::addMessageAfterRedirect(sprintf($errorMessage, $item['name']), false, ERROR); + return false; + } + return $input; + } + + function prepareInputForUpdate($input){ + return $this->prepareInputForAdd($input); + } +} diff --git a/install/sql/empty-1.4.3.sql b/install/sql/empty-1.4.3.sql new file mode 100644 index 0000000..044a367 --- /dev/null +++ b/install/sql/empty-1.4.3.sql @@ -0,0 +1,66 @@ +CREATE TABLE `glpi_plugin_satisfaction_surveys` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `entities_id` int(11) NOT NULL DEFAULT 0, + `is_recursive` tinyint(1) NOT NULL default '0', + `is_active` tinyint(1) NOT NULL default '0', + `name` varchar(255) collate utf8_unicode_ci default NULL, + `comment` text collate utf8_unicode_ci default NULL, + `date_creation` date default NULL, + `date_mod` datetime default NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE `glpi_plugin_satisfaction_surveyquestions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `plugin_satisfaction_surveys_id` int(11) NOT NULL, + `name` text collate utf8_unicode_ci default NULL, + `type` varchar(255) collate utf8_unicode_ci default NULL, + `comment` text collate utf8_unicode_ci default NULL, + `number` int(11) NOT NULL DEFAULT 0, + `default_value` int(11) NOT NULL DEFAULT 1, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE `glpi_plugin_satisfaction_surveyanswers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `answer` text collate utf8_unicode_ci default NULL, + `comment` text collate utf8_unicode_ci default NULL, + `plugin_satisfaction_surveys_id` int(11) NOT NULL, + `ticketsatisfactions_id` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +### Dump table glpi_plugin_satisfaction_surveytranslations + +DROP TABLE IF EXISTS `glpi_plugin_satisfaction_surveytranslations`; +CREATE TABLE `glpi_plugin_satisfaction_surveytranslations` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `plugin_satisfaction_surveys_id` int(11) NOT NULL DEFAULT '0', + `glpi_plugin_satisfaction_surveyquestions_id` int(11) NOT NULL DEFAULT '0', + `language` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL, + `value` text COLLATE utf8_unicode_ci, + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`plugin_satisfaction_surveys_id`,`glpi_plugin_satisfaction_surveyquestions_id`,`language`), + KEY `typeid` (`plugin_satisfaction_surveys_id`,`glpi_plugin_satisfaction_surveyquestions_id`), + KEY `language` (`language`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +DROP TABLE IF EXISTS `glpi_plugin_satisfaction_surveyreminders`; +CREATE TABLE `glpi_plugin_satisfaction_surveyreminders` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `plugin_satisfaction_surveys_id` int(11) NOT NULL, + `name` text collate utf8_unicode_ci default NULL, + `duration_type` int(11) NOT NULL, + `duration` int(11) NOT NULL, + `is_active` tinyint(1) NOT NULL default '0', + `comment` text collate utf8_unicode_ci default NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +DROP TABLE IF EXISTS `glpi_plugin_satisfaction_reminders`; +CREATE TABLE `glpi_plugin_satisfaction_reminders` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ticketsatisfactions_id` int(11) NOT NULL, + `date` date default NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/install/sql/update-1.4.3.sql b/install/sql/update-1.4.3.sql new file mode 100644 index 0000000..abfa37b --- /dev/null +++ b/install/sql/update-1.4.3.sql @@ -0,0 +1,17 @@ +CREATE TABLE `glpi_plugin_satisfaction_surveyreminders` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `plugin_satisfaction_surveys_id` int(11) NOT NULL, + `name` text collate utf8_unicode_ci default NULL, + `duration_type` int(11) NOT NULL, + `duration` int(11) NOT NULL, + `is_active` tinyint(1) NOT NULL default '0', + `comment` text collate utf8_unicode_ci default NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE `glpi_plugin_satisfaction_reminders` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ticketsatisfactions_id` int(11) NOT NULL, + `date` date default NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/setup.php b/setup.php index f432331..5736b5b 100644 --- a/setup.php +++ b/setup.php @@ -4,7 +4,7 @@ * Init the hooks of the plugins -Needed */ -define('PLUGIN_SATISFACTION_VERSION', '1.4.2'); +define('PLUGIN_SATISFACTION_VERSION', '1.4.3'); function plugin_init_satisfaction() { global $PLUGIN_HOOKS; @@ -15,9 +15,6 @@ function plugin_init_satisfaction() { $plugin = new Plugin(); if ($plugin->isInstalled('satisfaction') && $plugin->isActivated('satisfaction')) { - $PLUGIN_HOOKS['item_get_datas']['satisfaction'] = [NotificationTargetTicket::class => [PluginSatisfactionSurveyAnswer::class, - 'addNotificationDatas']]; - //if glpi is loaded if (Session::getLoginUserID()) { @@ -29,6 +26,8 @@ function plugin_init_satisfaction() { $PLUGIN_HOOKS['pre_item_update']['satisfaction'][TicketSatisfaction::class] = [PluginSatisfactionSurveyAnswer::class, 'preUpdateSatisfaction']; + $PLUGIN_HOOKS['item_get_events']['satisfaction'] = [NotificationTargetTicket::class => 'plugin_satisfaction_get_events']; + //current user must have config rights if (Session::haveRight('plugin_satisfaction', READ)) { $config_page = 'front/survey.php'; @@ -43,6 +42,9 @@ function plugin_init_satisfaction() { $PLUGIN_HOOKS['mydashboard']['satisfaction'] = [PluginSatisfactionDashboard::class]; } } + + $PLUGIN_HOOKS['item_get_datas']['satisfaction'] = [NotificationTargetTicket::class => [PluginSatisfactionSurveyAnswer::class, + 'addNotificationDatas']]; } } From 0745c8f00ce6ba5b029ad37d21834f7e925b9005 Mon Sep 17 00:00:00 2001 From: Mathieu Templier Date: Wed, 24 Jul 2019 11:02:19 +0200 Subject: [PATCH 2/6] FEATURE : Create mail notification when cron satisfaction reminder is executed --- ...lass.php => notificationMailing.class.php} | 3 +-- inc/notificationtargetticket.class.php | 26 +++---------------- inc/reminder.class.php | 10 ++++--- 3 files changed, 12 insertions(+), 27 deletions(-) rename inc/{notification.class.php => notificationMailing.class.php} (98%) diff --git a/inc/notification.class.php b/inc/notificationMailing.class.php similarity index 98% rename from inc/notification.class.php rename to inc/notificationMailing.class.php index 9c7cea5..b1c5378 100644 --- a/inc/notification.class.php +++ b/inc/notificationMailing.class.php @@ -34,7 +34,7 @@ /** * Class PluginResourcesNotification */ -class PluginSatisfactionNotification extends CommonDBTM { +class PluginSatisfactionNotificationMailing extends CommonDBTM { static $rightname = 'plugin_satisfaction'; @@ -192,6 +192,5 @@ static function purgeNotification(Ticket $ticket) { $temp = new self(); $temp->deleteByCriteria(['tickets_id' => $ticket->getField("id")]); } - } diff --git a/inc/notificationtargetticket.class.php b/inc/notificationtargetticket.class.php index 31585c5..a967e11 100644 --- a/inc/notificationtargetticket.class.php +++ b/inc/notificationtargetticket.class.php @@ -35,8 +35,10 @@ */ class PluginSatisfactionNotificationTargetTicket extends NotificationTarget { + const SURVEY_REMINDER_NOTIFICATION = "survey_reminder"; + function getEvents(){ - return ['survey_reminder' => __('Survey Reminder', 'satisfaction')]; + return [self::SURVEY_REMINDER_NOTIFICATION => __('Survey Reminder', 'satisfaction')]; } function getDatasForTemplate($event, $options = []) { @@ -47,7 +49,7 @@ function getSpecificTargets($data, $options) { } public static function sendReminder($item){ - NotificationEvent::raiseEvent('survey_reminder', $item, []); + NotificationEvent::raiseEvent(self::SURVEY_REMINDER_NOTIFICATION, $item); } function getTags() { @@ -85,26 +87,6 @@ static function install(){ 'comment' => "Created by the plugin Satisfaction" ]); } - -// $notificationtargets = new NotificationTarget(); -// -// $requester_group_id = 999999; -// -// $crit = [ -// 'items_id' => $requester_group_id, -// "notifications_id" => $notificationDBTM->getField('id') -// ]; -// -// if(!$notificationtargets->getFromDBByCrit($crit)){ -// -// $input = [ -// 'items_id' => $requester_group_id, -// 'type' => Notification::REQUESTER_GROUP, -// 'notifications_id' =>$notificationDBTM->getField('id') -// ]; -// -// $notificationtargets->add($input); -// } } static function uninstall(){ diff --git a/inc/reminder.class.php b/inc/reminder.class.php index c8bb7c2..012fc85 100644 --- a/inc/reminder.class.php +++ b/inc/reminder.class.php @@ -69,7 +69,7 @@ static function cronSatisfactionReminder($task = NULL) { self::deleteObsoleteReminders(); // Send reminder survey when date == today - self::createNotificationsFromReminders(); + self::sendRemindersNotifications(); } static function deleteObsoleteReminders(){ @@ -93,7 +93,7 @@ static function deleteObsoleteReminders(){ } } - static function createNotificationsFromReminders(){ + static function sendRemindersNotifications(){ global $DB; $selectQuery = "SELECT sa.*"; @@ -107,7 +107,11 @@ static function createNotificationsFromReminders(){ if ($DB->numrows($result)) { while ($data = $DB->fetch_assoc($result)) { - PluginSatisfactionNotificationTargetTicket::sendReminder($data); + + $t = new Ticket(); + $t->getFromDB($data['tickets_id']); + + PluginSatisfactionNotificationTargetTicket::sendReminder($t); } } From e97e03a6dad1d576d3bf2508da9ea937164fd686 Mon Sep 17 00:00:00 2001 From: Mathieu Templier Date: Thu, 25 Jul 2019 16:30:49 +0200 Subject: [PATCH 3/6] FEATURE : create notification with reminder cron --- inc/notificationtargetticket.class.php | 10 +- inc/reminder.class.php | 169 +++++++++++++++++++------ install/sql/empty-1.4.3.sql | 10 +- install/sql/update-1.4.3.sql | 3 +- 4 files changed, 146 insertions(+), 46 deletions(-) diff --git a/inc/notificationtargetticket.class.php b/inc/notificationtargetticket.class.php index a967e11..58afb3e 100644 --- a/inc/notificationtargetticket.class.php +++ b/inc/notificationtargetticket.class.php @@ -48,8 +48,12 @@ function getSpecificTargets($data, $options) { } - public static function sendReminder($item){ - NotificationEvent::raiseEvent(self::SURVEY_REMINDER_NOTIFICATION, $item); + public static function sendReminder($tickets_id){ + + $ticketDBTM = new Ticket(); + if($ticketDBTM->getFromDB($tickets_id)){ + NotificationEvent::raiseEvent(self::SURVEY_REMINDER_NOTIFICATION, $ticketDBTM); + } } function getTags() { @@ -83,7 +87,7 @@ static function install(){ 'is_recursive' => 1, 'is_active' => 1, 'itemtype' => 'Ticket', - 'event' => "survey_reminder", + 'event' => self::SURVEY_REMINDER_NOTIFICATION, 'comment' => "Created by the plugin Satisfaction" ]); } diff --git a/inc/reminder.class.php b/inc/reminder.class.php index 012fc85..983f351 100644 --- a/inc/reminder.class.php +++ b/inc/reminder.class.php @@ -65,55 +65,148 @@ static function cronSatisfactionReminder($task = NULL) { return 0; } - // Delete reminders of answered survey - self::deleteObsoleteReminders(); - - // Send reminder survey when date == today - self::sendRemindersNotifications(); + self::sendReminders(); } - static function deleteObsoleteReminders(){ - global $DB; - - $selectQuery = "SELECT re.id"; - $selectQuery.= " FROM ".self::getTable() . " as re"; - $selectQuery.= " INNER JOIN ".TicketSatisfaction::getTable() . " as sa"; - $selectQuery.= " ON sa.id = re.".self::$items_id; - $selectQuery.= " WHERE sa.date_answered IS NOT NULL"; - - $deleteQuery = "DELETE FROM ".self::getTable(); - $deleteQuery.= " WHERE id = "; + static function sendReminders(){ - $result = $DB->query($selectQuery); - - if ($DB->numrows($result)) { - while ($data = $DB->fetch_assoc($result)) { - $DB->query($deleteQuery.$data['id']); - } - } - } + $entityDBTM = new Entity(); + $ticketSatisfactionDBTM = new TicketSatisfaction(); - static function sendRemindersNotifications(){ - global $DB; + $pluginSatisfactionSurveyDBTM = new PluginSatisfactionSurvey(); + $pluginSatisfactionSurveyReminderDBTM = new PluginSatisfactionSurveyReminder(); + $pluginSatisfactionReminderDBTM = new PluginSatisfactionReminder(); - $selectQuery = "SELECT sa.*"; - $selectQuery.= " FROM ".self::getTable() . " as re"; - $selectQuery.= " INNER JOIN ".TicketSatisfaction::getTable() . " as sa"; - $selectQuery.= " ON sa.id = re.".self::$items_id; - $selectQuery.= " WHERE sa.date_answered IS NULL"; - $selectQuery.= " AND DATEDIFF(re.date, CURDATE()) < 0"; + $surveys = $pluginSatisfactionSurveyDBTM->find(['is_active' => true]); - $result = $DB->query($selectQuery); + foreach($surveys as $survey){ - if ($DB->numrows($result)) { - while ($data = $DB->fetch_assoc($result)) { + // Entity + $entityDBTM->getFromDB($survey['entities_id']); - $t = new Ticket(); - $t->getFromDB($data['tickets_id']); + // Don't get tickets satisfaction with date older than max_close_date + $max_close_date = date('Y-m-d', strtotime($entityDBTM->getField('max_closedate'))); - PluginSatisfactionNotificationTargetTicket::sendReminder($t); + // Ticket Satisfaction + $crit = [ + 'date_begin' => ['>', $max_close_date], + 'date_answered' => null, + 'type' => $survey['entities_id'] + ]; + $ticketSatisfactions = $ticketSatisfactionDBTM->find($crit); + + foreach($ticketSatisfactions as $ticketSatisfaction){ + + $reminders = $pluginSatisfactionReminderDBTM->find(['tickets_id' => $ticketSatisfaction['tickets_id']]); + + // Date when glpi satisfaction was sended for the first time + $lastSurveySendDate = date('Y-m-d', strtotime($ticketSatisfaction['date_begin'])); + + $reminder = null; + + // Update lastSurvey with last sended reminder date + if(count($reminders)){ + $reminder = array_pop($reminders); + $lastSurveySendDate = date('Y-m-d', strtotime($reminder['date'])); + } + + // Survey Reminders + $surveyReminderCrit = [ + 'plugin_satisfaction_surveys_id' => $survey['id'] + ]; + $surveyReminders = $pluginSatisfactionSurveyReminderDBTM->find($surveyReminderCrit); + + $potentialReminderToSendDates = []; + $potentialReminderTypes = []; + $potentialReminderIndexes = []; + + // Calculate the next date of next reminders + foreach($surveyReminders as $surveyReminder){ + + // Don't get the last reminder used + if(isset($reminder['type']) && $surveyReminder['id'] === $reminder['type']){ + continue; + } + + $date = null; + + switch($surveyReminder[PluginSatisfactionSurveyReminder::COLUMN_DURATION_TYPE]){ + + case PluginSatisfactionSurveyReminder::DURATION_DAY: + $add = " +".$surveyReminder[PluginSatisfactionSurveyReminder::COLUMN_DURATION]." day"; + $date = strtotime(date("Y-m-d", strtotime($lastSurveySendDate)).$add); + $date = date('Y-m-d', $date); + break; + + case PluginSatisfactionSurveyReminder::DURATION_MONTH: + $add = " +".$surveyReminder[PluginSatisfactionSurveyReminder::COLUMN_DURATION]." month"; + $date = strtotime(date("Y-m-d", strtotime($lastSurveySendDate)).$add); + $date = date('Y-m-d', $date); + break; + default: + $date = null; + } + + if(!is_null($date)){ + $potentialReminderToSendDates[] = $date; + $potentialReminderTypes[$date] = $reminder['type']; + $potentialReminderIndexes[$date] = $reminder['id']; + } + } + + function date_sort($a, $b) { + return strtotime($a) - strtotime($b); + } + + // Order dates + usort($potentialReminderToSendDates, "date_sort"); + + $dateNow = date("Y/m/d"); + + foreach($potentialReminderToSendDates as $potentialReminderToSendDate){ + + $potentialTimestamp = strtotime($potentialReminderToSendDate); + $nowTimestamp = strtotime($dateNow); + + if($potentialTimestamp <= $nowTimestamp){ + + // Send notification + PluginSatisfactionNotificationTargetTicket::sendReminder($ticketSatisfaction['tickets_id']); + + // Create new raw in reminder table or update : 1 ROW => 1 ticket + if(count($reminders)){ + self::updateReminderForTicket([ + 'id' => $potentialReminderIndexes['id'], + 'type' => $potentialReminderTypes[$potentialReminderToSendDate], + 'tickets_id' => $ticketSatisfaction['tickets_id'], + 'date' => $potentialReminderToSendDate + ]); + }else{ + self::addReminderForTicket([ + 'type' => $potentialReminderTypes[$potentialReminderToSendDate], + 'tickets_id' => $ticketSatisfaction['tickets_id'], + 'date' => $potentialReminderToSendDate + ]); + } + break; + } + } } } + } + + static function addReminderForTicket($params = []){ + $s = new self(); + $s->add($params); + } + + static function updateReminderForTicket($params = []){ + $s = new self(); + $s->update($params); + } + static function deleteReminderForTicket($tickets_id){ + $s = new self(); + $s->deleteByCriteria(['tickets_id' => $tickets_id]); } } \ No newline at end of file diff --git a/install/sql/empty-1.4.3.sql b/install/sql/empty-1.4.3.sql index 044a367..2a2c671 100644 --- a/install/sql/empty-1.4.3.sql +++ b/install/sql/empty-1.4.3.sql @@ -1,3 +1,5 @@ +# noinspection SqlNoDataSourceInspectionForFile + CREATE TABLE `glpi_plugin_satisfaction_surveys` ( `id` int(11) NOT NULL AUTO_INCREMENT, `entities_id` int(11) NOT NULL DEFAULT 0, @@ -30,8 +32,6 @@ CREATE TABLE `glpi_plugin_satisfaction_surveyanswers` ( PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -### Dump table glpi_plugin_satisfaction_surveytranslations - DROP TABLE IF EXISTS `glpi_plugin_satisfaction_surveytranslations`; CREATE TABLE `glpi_plugin_satisfaction_surveytranslations` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -60,7 +60,9 @@ CREATE TABLE `glpi_plugin_satisfaction_surveyreminders` ( DROP TABLE IF EXISTS `glpi_plugin_satisfaction_reminders`; CREATE TABLE `glpi_plugin_satisfaction_reminders` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `ticketsatisfactions_id` int(11) NOT NULL, + `type` int(11) NOT NULL DEFAULT '0', + `tickets_id` int(11) NOT NULL, `date` date default NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`tickets_id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file diff --git a/install/sql/update-1.4.3.sql b/install/sql/update-1.4.3.sql index abfa37b..f1f72d8 100644 --- a/install/sql/update-1.4.3.sql +++ b/install/sql/update-1.4.3.sql @@ -11,7 +11,8 @@ CREATE TABLE `glpi_plugin_satisfaction_surveyreminders` ( CREATE TABLE `glpi_plugin_satisfaction_reminders` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `ticketsatisfactions_id` int(11) NOT NULL, + 'type' int(11) NOT NULL DEFAULT '0', + `tickets_id` int(11) NOT NULL, `date` date default NULL, PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file From 6f3c7fd1ce6fe4ee51fdee9567dc56266fc66250 Mon Sep 17 00:00:00 2001 From: keha35 Date: Wed, 31 Jul 2019 09:44:29 +0200 Subject: [PATCH 4/6] Update : - Delete ticket => Delete associated reminder - Delete survey => Delete reminderSurvey - Unistall plugin drop all tables --- hook.php | 7 ++++--- inc/reminder.class.php | 21 +++++++++++++++------ inc/survey.class.php | 3 +++ setup.php | 2 ++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/hook.php b/hook.php index dff80ba..2847892 100644 --- a/hook.php +++ b/hook.php @@ -12,8 +12,6 @@ function plugin_satisfaction_install() { if (!$DB->tableExists("glpi_plugin_satisfaction_surveys")) { $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/empty-1.4.3.sql"); - PluginSatisfactionNotificationTargetTicket::install(); - } else { if (!$DB->fieldExists("glpi_plugin_satisfaction_surveyquestions", "type")) { $DB->runFile(GLPI_ROOT . "/plugins/satisfaction/install/sql/update-1.1.0.sql"); @@ -33,6 +31,7 @@ function plugin_satisfaction_install() { } } + PluginSatisfactionNotificationTargetTicket::install(); PluginSatisfactionProfile::initProfile(); PluginSatisfactionProfile::createFirstAccess($_SESSION['glpiactiveprofile']['id']); @@ -52,7 +51,9 @@ function plugin_satisfaction_uninstall() { $tables = [ "glpi_plugin_satisfaction_surveys", "glpi_plugin_satisfaction_surveyquestions", - "glpi_plugin_satisfaction_surveyanswers" + "glpi_plugin_satisfaction_surveyanswers", + "glpi_plugin_satisfaction_surveyreminders", + "glpi_plugin_satisfaction_surveytranslations" ]; foreach ($tables as $table) { diff --git a/inc/reminder.class.php b/inc/reminder.class.php index 983f351..c462e58 100644 --- a/inc/reminder.class.php +++ b/inc/reminder.class.php @@ -46,6 +46,13 @@ static function cronInfo($name) { return []; } + public function deleteItem(Ticket $ticket){ + $reminder = new Self; + if($reminder->getFromDBByCrit(['tickets_id'=>$ticket->fields['id']])){ + $reminder->delete(['id' => $reminder->fields["id"]]); + } + } + /** * Cron action * @@ -69,7 +76,7 @@ static function cronSatisfactionReminder($task = NULL) { } static function sendReminders(){ - + //TODO ENTITIES_id $entityDBTM = new Entity(); $ticketSatisfactionDBTM = new TicketSatisfaction(); @@ -90,8 +97,7 @@ static function sendReminders(){ // Ticket Satisfaction $crit = [ 'date_begin' => ['>', $max_close_date], - 'date_answered' => null, - 'type' => $survey['entities_id'] + 'date_answered' => null ]; $ticketSatisfactions = $ticketSatisfactionDBTM->find($crit); @@ -152,10 +158,13 @@ static function sendReminders(){ $potentialReminderTypes[$date] = $reminder['type']; $potentialReminderIndexes[$date] = $reminder['id']; } + $types = $surveyReminder['id']; } - function date_sort($a, $b) { - return strtotime($a) - strtotime($b); + if(!function_exists("date_sort")){ + function date_sort($a, $b) { + return strtotime($a) - strtotime($b); + } } // Order dates @@ -183,7 +192,7 @@ function date_sort($a, $b) { ]); }else{ self::addReminderForTicket([ - 'type' => $potentialReminderTypes[$potentialReminderToSendDate], + 'type' => $types, 'tickets_id' => $ticketSatisfaction['tickets_id'], 'date' => $potentialReminderToSendDate ]); diff --git a/inc/survey.class.php b/inc/survey.class.php index b03b33c..577e7e3 100644 --- a/inc/survey.class.php +++ b/inc/survey.class.php @@ -269,6 +269,9 @@ function pre_deleteItem() { $answer = new PluginSatisfactionSurveyAnswer; $answer->deleteByCriteria([PluginSatisfactionSurveyAnswer::$items_id => $this->getID()]); + $reminder = new PluginSatisfactionSurveyReminder(); + $reminder->deleteByCriteria([PluginSatisfactionSurveyReminder::$items_id => $this->getID()]); + return true; } diff --git a/setup.php b/setup.php index 5736b5b..fb9e5a4 100644 --- a/setup.php +++ b/setup.php @@ -28,6 +28,8 @@ function plugin_init_satisfaction() { $PLUGIN_HOOKS['item_get_events']['satisfaction'] = [NotificationTargetTicket::class => 'plugin_satisfaction_get_events']; + $PLUGIN_HOOKS['item_delete']['satisfaction'] = ['Ticket' => ['PluginSatisfactionReminder', 'deleteItem']]; + //current user must have config rights if (Session::haveRight('plugin_satisfaction', READ)) { $config_page = 'front/survey.php'; From b61a3f062f2be3d7fe06de282a69be5ef1638213 Mon Sep 17 00:00:00 2001 From: Mathieu Templier Date: Thu, 1 Aug 2019 13:43:29 +0200 Subject: [PATCH 5/6] FEATURE : use textbox for survey translation value --- inc/surveyreminder.class.php | 29 +++++++++++++++++++++++++++-- inc/surveytranslation.class.php | 16 ++++++++++------ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/inc/surveyreminder.class.php b/inc/surveyreminder.class.php index 9b319b4..9b58782 100644 --- a/inc/surveyreminder.class.php +++ b/inc/surveyreminder.class.php @@ -266,7 +266,7 @@ function showForm($ID, $options = []) { // Duration line 3 echo ""; echo "" . self::getColumnTitles(self::COLUMN_DURATION) . ""; - echo ""; + echo ""; echo ''; echo ""; echo ""; @@ -478,7 +478,32 @@ function prepareInputForAdd($input) { return $input; } + /** + * Verify survey remindr can be updated only if a column is different + * + * @param $input + * @return array|bool + */ function prepareInputForUpdate($input){ - return $this->prepareInputForAdd($input); + $crit = [ + self::COLUMN_DURATION_TYPE => $input[self::COLUMN_DURATION_TYPE], + self::COLUMN_DURATION => $input[self::COLUMN_DURATION], + self::COLUMN_IS_ACTIVE => $input[self::COLUMN_IS_ACTIVE], + self::COLUMN_NAME => $input[self::COLUMN_NAME], + self::COLUMN_COMMENT => $input[self::COLUMN_COMMENT] + ]; + + $items = $this->find($crit); + + if(count($items)){ + + $item = array_pop($items); + + $errorMessage = __('There are nothing to save', 'satisfaction'); + + Session::addMessageAfterRedirect(sprintf($errorMessage, $item['name']), false, ERROR); + return false; + } + return $input; } } diff --git a/inc/surveytranslation.class.php b/inc/surveytranslation.class.php index d60a6ed..d5432ac 100644 --- a/inc/surveytranslation.class.php +++ b/inc/surveytranslation.class.php @@ -272,7 +272,7 @@ function showForm($options){ $surveyQuestion->getFromDB($surveyTranslationData['glpi_plugin_satisfaction_surveyquestions_id']); // Language - echo ""; + echo ""; echo ""; echo ""; echo ""; @@ -280,9 +280,10 @@ function showForm($options){ echo Dropdown::getLanguageName($surveyTranslationData['language']); echo ""; // Question - echo "".$surveyQuestion->getName().""; + echo "".$surveyQuestion->getName().""; // Value - echo ""; + echo ""; echo ""; // Save button @@ -295,7 +296,7 @@ function showForm($options){ echo ""; // Language - echo ""; + echo ""; $rand = Dropdown::showLanguages( "language", ['display_none' => true, 'value' => $_SESSION['glpilanguage']]); @@ -314,10 +315,13 @@ function showForm($options){ echo ""; // Question - echo "".$this->getQuestionDropdown($surveyId).""; + echo "".$this->getQuestionDropdown($surveyId).""; // Value - echo ""; + + echo ""; + echo ""; // Add button From 188dea361dfd4ac7ce5de5929aa300d041472e14 Mon Sep 17 00:00:00 2001 From: Mathieu Templier Date: Thu, 1 Aug 2019 14:18:25 +0200 Subject: [PATCH 6/6] FEATURE : Find ticket satisfaction by entity. BUGFIX : Create reminder with date now --- inc/reminder.class.php | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/inc/reminder.class.php b/inc/reminder.class.php index c462e58..d3511f3 100644 --- a/inc/reminder.class.php +++ b/inc/reminder.class.php @@ -75,10 +75,32 @@ static function cronSatisfactionReminder($task = NULL) { self::sendReminders(); } + static function getTicketSatisfaction($date_begin, $date_answered, $entities_id){ + + $ticketSatisfactions = []; + + global $DB; + + $query = "SELECT ts.* FROM ".TicketSatisfaction::getTable() . " as ts"; + $query .= " INNER JOIN ".Ticket::getTable() . " as t"; + $query .= " ON ts.tickets_id = t.id"; + $query .= " WHERE t.entities_id = ".$entities_id; + $query .= " AND ts.date_begin > DATE('".$date_begin."')"; + $query .= " AND ts.date_answered ".(($date_answered == null)? " IS NULL" : " = DATE('".$date_answered."')"); + + $result = $DB->query($query); + + if ($DB->numrows($result)) { + while ($data = $DB->fetch_assoc($result)) { + $ticketSatisfactions[] = $data; + } + } + return $ticketSatisfactions; + } + static function sendReminders(){ //TODO ENTITIES_id $entityDBTM = new Entity(); - $ticketSatisfactionDBTM = new TicketSatisfaction(); $pluginSatisfactionSurveyDBTM = new PluginSatisfactionSurvey(); $pluginSatisfactionSurveyReminderDBTM = new PluginSatisfactionSurveyReminder(); @@ -95,11 +117,7 @@ static function sendReminders(){ $max_close_date = date('Y-m-d', strtotime($entityDBTM->getField('max_closedate'))); // Ticket Satisfaction - $crit = [ - 'date_begin' => ['>', $max_close_date], - 'date_answered' => null - ]; - $ticketSatisfactions = $ticketSatisfactionDBTM->find($crit); + $ticketSatisfactions = self::getTicketSatisfaction($max_close_date, null, $survey['entities_id']); foreach($ticketSatisfactions as $ticketSatisfaction){ @@ -188,13 +206,13 @@ function date_sort($a, $b) { 'id' => $potentialReminderIndexes['id'], 'type' => $potentialReminderTypes[$potentialReminderToSendDate], 'tickets_id' => $ticketSatisfaction['tickets_id'], - 'date' => $potentialReminderToSendDate + 'date' => $dateNow ]); }else{ self::addReminderForTicket([ 'type' => $types, 'tickets_id' => $ticketSatisfaction['tickets_id'], - 'date' => $potentialReminderToSendDate + 'date' => $dateNow ]); } break;