├── .github └── workflows │ └── release.yml ├── LICENSE ├── README.md ├── ajax ├── index.php ├── satisfaction.php ├── surveytranslation.form.php └── viewsubitem_reminder.php ├── front ├── index.php ├── survey.form.php ├── survey.php ├── surveyquestion.form.php ├── surveyreminder.form.php └── surveytranslation.form.php ├── hook.php ├── inc ├── dashboard.class.php ├── index.php ├── menu.class.php ├── notificationMailing.class.php ├── notificationtargetticket.class.php ├── profile.class.php ├── reminder.class.php ├── survey.class.php ├── surveyanswer.class.php ├── surveyquestion.class.php ├── surveyreminder.class.php ├── surveyresult.class.php ├── surveytranslation.class.php └── surveytranslation.dao.php ├── index.php ├── install └── sql │ ├── empty-1.1.0.sql │ ├── empty-1.2.2.sql │ ├── empty-1.3.0.sql │ ├── empty-1.4.1.sql │ ├── empty-1.4.3.sql │ ├── empty-1.4.5.sql │ ├── empty-1.5.0.sql │ ├── empty-1.6.0.sql │ ├── update-1.1.0.sql │ ├── update-1.2.2.sql │ ├── update-1.4.1.sql │ ├── update-1.4.3.sql │ └── update-1.4.5.sql ├── locales ├── cs_CZ.mo ├── cs_CZ.po ├── en_GB.mo ├── en_GB.po ├── fi_FI.mo ├── fi_FI.po ├── fr_FR.mo ├── fr_FR.po ├── glpi.pot ├── hr_HR.mo ├── hr_HR.po ├── pt_BR.mo ├── pt_BR.po ├── pt_PT.mo ├── pt_PT.po ├── ru_RU.mo └── ru_RU.po ├── satisfaction.js ├── satisfaction.png ├── satisfaction.xml ├── setup.php └── tools ├── extract_template.sh ├── update_mo.pl └── update_po.pl /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | 2 | on: 3 | push: 4 | # Sequence of patterns matched against refs/tags 5 | tags: 6 | - '*.*.*' # Push events to matching ex:20.15.10 7 | 8 | name: Create release with tag 9 | env: 10 | TAG_VALUE: ${GITHUB_REF/refs\/tags\//} 11 | jobs: 12 | build: 13 | name: Upload Release Asset 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v2 18 | - name: Build project # This would actually build your project, using zip for an example artifact 19 | id: build_ 20 | env: 21 | GITHUB_NAME: ${{ github.event.repository.name }} 22 | 23 | 24 | run: sudo apt-get install libxml-xpath-perl;echo $(xpath -e '/root/versions/version[num="'${GITHUB_REF/refs\/tags\//}'"]/compatibility/text()' $GITHUB_NAME.xml);echo ::set-output name=version_glpi::$(xpath -e '/root/versions/version[num="'${GITHUB_REF/refs\/tags\//}'"]/compatibility/text()' $GITHUB_NAME.xml); rm -rf $GITHUB_NAME.xml tools wiki screenshots test .git .github ISSUE_TEMPLATE.md TODO.txt $GITHUB_NAME.png;cd ..; tar jcvf glpi-$GITHUB_NAME-${GITHUB_REF/refs\/tags\//}.tar.bz2 $GITHUB_NAME;ls -al;echo ::set-output name=tag::${GITHUB_REF/refs\/tags\//};echo ${{ steps.getxml.outputs.info }}; 25 | # run: rm -rf $GITHUB_NAME.xml tools wiki screenshots test ISSUE_TEMPLATE.md TODO.txt $GITHUB_NAME.png; tar -zcvf glpi-$GITHUB_NAME-$GITHUB_TAG.tar.gz $GITHUB_NAME 26 | - name: Create Release 27 | id: create_release 28 | uses: actions/create-release@v1 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | with: 32 | tag_name: ${{ github.ref }} 33 | release_name: | 34 | GLPI ${{ steps.build_.outputs.version_glpi }} : Version ${{ github.ref }} disponible / available 35 | body : Version ${{ steps.build_.outputs.tag }} released for GLPI ${{ steps.build_.outputs.version_glpi }} 36 | draft: false 37 | prerelease: true 38 | - name: Upload Release Asset 39 | id: upload-release-asset 40 | uses: actions/upload-release-asset@v1 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | GITHUB_NAME: ${{ github.event.repository.name }} 44 | with: 45 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 46 | asset_path: /home/runner/work/${{ github.event.repository.name }}/glpi-${{ github.event.repository.name }}-${{ steps.build_.outputs.tag }}.tar.bz2 47 | asset_name: glpi-${{ github.event.repository.name }}-${{ steps.build_.outputs.tag }}.tar.bz2 48 | asset_content_type: application/zip 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | This plugin extends the satisfaction survey of GLPI. 5 | 6 | Satisfaction is a plugin which allows you to add questions to the satisfaction survey. 7 | 8 | Features 9 | -------- 10 | 11 | * Different surveys (one for each entity) 12 | 13 | * Multiple questions with three types: 14 | - Yes / No dropdown list 15 | - Text box - Text box 16 | - Note: It will be possible to configure the total number of stars. 17 | 18 | * This plugin will allow you to add all the questions configured in the plugin with the two questions of the GLPI core in the satisfaction survey. 19 | 20 | * This plugin will add two new tags to the notifications for "Satisfaction survey" and "Satisfaction survey answer" events. 21 | - The tag "##satisfaction. question##" will allow you to add the list of questions of the plugin. 22 | - The tag "##satisfaction. answer##" will allow you to add the list of questions and answers of the plugin. 23 | 24 | Translations 25 | ------------ 26 | 27 | Join us on [Transifex](https://www.transifex.com/InfotelGLPI/GLPI_satisfaction) 28 | 29 | ------------------------------------------------------------------------------------------------------------------------ 30 | 31 | Introduction 32 | ============ 33 | 34 | Ce plugin étend l'enquête de satisfaction de GLPI. 35 | 36 | Satisfaction est un plugin qui vous permet d'ajouter des questions à l'enquête de satisfaction. 37 | 38 | Fonctionnalités 39 | -------- 40 | 41 | * Différents questionnaires (un pour chaque entité) 42 | 43 | * Questions multiples avec trois types de questions : 44 | - Liste déroulante Oui / Non 45 | - Zone de texte 46 | - Note : Il sera possible de configurer la nombre total d’étoiles. 47 | 48 | * Ce plugin va permettre d’ajouter l’ensemble des questions configurés dans le plugin avec les deux questions du cœur de GLPI. 49 | 50 | * Ce plugin va ajouter deux nouvelles balises dans les notifications concernant les événements « Enquête de satisfaction » et « Réponse à l’enquête de satisfaction ». 51 | - La balise « ##satisfaction.question## » va permettre d’ajouter la liste des questions du plugin. 52 | - La balise « ##satisfaction.answer## » va permettre d’ajouter la liste des questions et réponses du plugin. 53 | -------------------------------------------------------------------------------- /ajax/index.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | -------------------------------------------------------------------------------- /ajax/satisfaction.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include ('../../../inc/includes.php'); 32 | 33 | if (isset($_POST['action_default_value'])) { 34 | Dropdown::showNumber('default_value', ['max' => $_POST['default_value'], 35 | 'min' => 1, 36 | 'value' => $_POST['value']]); 37 | } 38 | -------------------------------------------------------------------------------- /ajax/surveytranslation.form.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include ('../../../inc/includes.php'); 32 | 33 | if (!isset($_POST['survey_id']) || !isset($_POST['action'])) { 34 | exit(); 35 | } 36 | 37 | global $CFG_GLPI; 38 | $redirection = Plugin::getWebDir('satisfaction')."/front/survey.form.php?id="; 39 | 40 | $translation = new PluginSatisfactionSurveyTranslation(); 41 | 42 | switch($_POST['action']){ 43 | case 'GET': 44 | header("Content-Type: text/html; charset=UTF-8"); 45 | Html::header_nocache(); 46 | Session::checkLoginUser(); 47 | $translation->showSurveyTranslationForm($_POST); 48 | Html::ajaxFooter(); 49 | break; 50 | case 'NEW': 51 | $translation->newSurveyTranslation($_POST); 52 | Html::redirect($redirection.$_POST['survey_id']); 53 | break; 54 | case 'EDIT': 55 | $translation->editSurveyTranslation($_POST); 56 | Html::redirect($redirection.$_POST['survey_id']); 57 | break; 58 | } 59 | -------------------------------------------------------------------------------- /ajax/viewsubitem_reminder.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include('../../../inc/includes.php'); 32 | header("Content-Type: text/html; charset=UTF-8"); 33 | Html::header_nocache(); 34 | 35 | Session::checkLoginUser(); 36 | 37 | if (!isset($_POST['type'])) { 38 | exit(); 39 | } 40 | if (!isset($_POST['parenttype'])) { 41 | exit(); 42 | } 43 | 44 | if (($item = getItemForItemtype($_POST['type'])) 45 | && ($parent = getItemForItemtype($_POST['parenttype']))) { 46 | if (isset($_POST[$parent->getForeignKeyField()]) 47 | && isset($_POST["id"]) 48 | && $parent->getFromDB($_POST[$parent->getForeignKeyField()])) { 49 | 50 | $reminderName = PluginSatisfactionSurveyReminder::PREDEFINED_REMINDER_OPTION_NAME; 51 | 52 | $options = [ 53 | 'parent' => $parent 54 | ]; 55 | 56 | if(isset( $_POST[$reminderName])){ 57 | $options[$reminderName] = intval($_POST[$reminderName]); 58 | } 59 | 60 | $item->showForm($_POST["id"], $options); 61 | 62 | } else { 63 | echo __('Access denied'); 64 | } 65 | } 66 | 67 | Html::ajaxFooter(); 68 | -------------------------------------------------------------------------------- /front/index.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | -------------------------------------------------------------------------------- /front/survey.form.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include('../../../inc/includes.php'); 32 | 33 | Session::checkLoginUser(); 34 | 35 | if (!isset($_GET["id"])) { 36 | $_GET["id"] = ""; 37 | } 38 | 39 | $survey = new PluginSatisfactionSurvey(); 40 | 41 | if (isset($_POST["add"])) { 42 | $survey->check(-1, CREATE, $_POST); 43 | $survey->add($_POST); 44 | Html::back(); 45 | 46 | } else if (isset($_POST["purge"])) { 47 | $survey->check($_POST['id'], PURGE); 48 | $survey->delete($_POST); 49 | $survey->redirectToList(); 50 | 51 | } else if (isset($_POST["update"])) { 52 | $survey->check($_POST['id'], UPDATE); 53 | $survey->update($_POST); 54 | Html::back(); 55 | 56 | } else { 57 | 58 | $survey->checkGlobal(READ); 59 | 60 | Html::header(PluginSatisfactionSurvey::getTypeName(2), '', "admin", "pluginsatisfactionmenu", "survey"); 61 | 62 | $survey->display(['id' => $_GET['id']]); 63 | 64 | Html::footer(); 65 | } 66 | -------------------------------------------------------------------------------- /front/survey.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include('../../../inc/includes.php'); 32 | 33 | Html::header(PluginSatisfactionSurvey::getTypeName(2), '', "admin", "pluginsatisfactionmenu"); 34 | 35 | $satisfaction = new PluginSatisfactionSurvey(); 36 | $satisfaction->checkGlobal(READ); 37 | 38 | if ($satisfaction->canView()) { 39 | Search::show('PluginSatisfactionSurvey'); 40 | 41 | } else { 42 | Html::displayRightError(); 43 | } 44 | 45 | Html::footer(); 46 | -------------------------------------------------------------------------------- /front/surveyquestion.form.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include('../../../inc/includes.php'); 32 | 33 | Session::checkLoginUser(); 34 | 35 | $question = new PluginSatisfactionSurveyQuestion(); 36 | 37 | if (isset($_POST["add"])) { 38 | $question->check(-1, CREATE, $_POST); 39 | $question->add($_POST); 40 | Html::back(); 41 | 42 | } else if (isset($_POST["update"])) { 43 | $question->check($_POST['id'], UPDATE); 44 | $question->update($_POST); 45 | Html::back(); 46 | 47 | } else if (isset($_POST["delete"])) { 48 | $question->check($_POST['id'], PURGE); 49 | $question->delete($_POST); 50 | Html::back(); 51 | 52 | } 53 | 54 | Html::displayErrorAndDie('Lost'); 55 | -------------------------------------------------------------------------------- /front/surveyreminder.form.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | 31 | include('../../../inc/includes.php'); 32 | 33 | Session::checkLoginUser(); 34 | 35 | $reminder = new PluginSatisfactionSurveyReminder(); 36 | 37 | if (isset($_POST["add"])) { 38 | 39 | $input = $_POST; 40 | 41 | if(isset($input[$reminder::PREDEFINED_REMINDER_OPTION_NAME])){ 42 | $input = $reminder->generatePredefinedReminderForAdd($input); 43 | } 44 | 45 | $reminder->check(-1, CREATE, $input); 46 | $reminder->add($input); 47 | Html::back(); 48 | 49 | } else if (isset($_POST["update"])) { 50 | $reminder->check($_POST['id'], UPDATE); 51 | $reminder->update($_POST); 52 | Html::back(); 53 | 54 | } else if (isset($_POST["delete"])) { 55 | $reminder->check($_POST['id'], PURGE); 56 | $reminder->delete($_POST); 57 | Html::back(); 58 | 59 | } 60 | 61 | Html::displayErrorAndDie('Lost'); 62 | -------------------------------------------------------------------------------- /front/surveytranslation.form.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | include('../../../inc/includes.php'); 31 | 32 | if (!isset($_POST['survey_id']) || !isset($_POST['action'])) { 33 | exit(); 34 | } 35 | 36 | $redirection = Plugin::getWebDir('satisfaction')."/front/survey.form.php?id="; 37 | $translation = new PluginSatisfactionSurveyTranslation(); 38 | switch($_POST['action']){ 39 | case 'NEW': 40 | $translation->newSurveyTranslation($_POST); 41 | Html::redirect($redirection.$_POST['survey_id']); 42 | break; 43 | 44 | case 'EDIT': 45 | $translation->editSurveyTranslation($_POST); 46 | Html::redirect($redirection.$_POST['survey_id']); 47 | break; 48 | } 49 | -------------------------------------------------------------------------------- /hook.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | /** 31 | * @return bool 32 | */ 33 | function plugin_satisfaction_install() { 34 | global $DB; 35 | 36 | include_once(Plugin::getPhpDir('satisfaction')."/inc/profile.class.php"); 37 | include_once(Plugin::getPhpDir('satisfaction')."/inc/notificationtargetticket.class.php"); 38 | 39 | if (!$DB->tableExists("glpi_plugin_satisfaction_surveys")) { 40 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/empty-1.6.0.sql"); 41 | 42 | } else { 43 | if (!$DB->fieldExists("glpi_plugin_satisfaction_surveyquestions", "type")) { 44 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/update-1.1.0.sql"); 45 | } 46 | //version 1.2.1 47 | if (!$DB->fieldExists("glpi_plugin_satisfaction_surveyquestions", "default_value")) { 48 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/update-1.2.2.sql"); 49 | } 50 | //version 1.4.1 51 | if (!$DB->tableExists("glpi_plugin_satisfaction_surveytranslations")) { 52 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/update-1.4.1.sql"); 53 | } 54 | 55 | //version 1.4.3 56 | if (!$DB->tableExists("glpi_plugin_satisfaction_surveyreminders")) { 57 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/update-1.4.3.sql"); 58 | } 59 | 60 | //version 1.4.5 61 | if (!$DB->fieldExists("glpi_plugin_satisfaction_surveys", "reminders_days")) { 62 | $DB->runFile(Plugin::getPhpDir('satisfaction')."/install/sql/update-1.4.5.sql"); 63 | } 64 | } 65 | 66 | PluginSatisfactionNotificationTargetTicket::install(); 67 | PluginSatisfactionProfile::initProfile(); 68 | PluginSatisfactionProfile::createFirstAccess($_SESSION['glpiactiveprofile']['id']); 69 | 70 | CronTask::Register(PluginSatisfactionReminder::class, PluginSatisfactionReminder::CRON_TASK_NAME, DAY_TIMESTAMP); 71 | return true; 72 | } 73 | 74 | /** 75 | * @return bool 76 | */ 77 | function plugin_satisfaction_uninstall() { 78 | global $DB; 79 | 80 | include_once(Plugin::getPhpDir('satisfaction')."/inc/profile.class.php"); 81 | include_once(Plugin::getPhpDir('satisfaction')."/inc/menu.class.php"); 82 | include_once(Plugin::getPhpDir('satisfaction')."/inc/notificationtargetticket.class.php"); 83 | 84 | $tables = [ 85 | "glpi_plugin_satisfaction_surveys", 86 | "glpi_plugin_satisfaction_surveyquestions", 87 | "glpi_plugin_satisfaction_surveyanswers", 88 | "glpi_plugin_satisfaction_surveyreminders", 89 | "glpi_plugin_satisfaction_surveytranslations", 90 | "glpi_plugin_satisfaction_reminders" 91 | ]; 92 | 93 | foreach ($tables as $table) { 94 | $DB->dropTable($table); 95 | } 96 | 97 | $tables_glpi = ["glpi_logs"]; 98 | 99 | foreach ($tables_glpi as $table_glpi) { 100 | $DB->delete($table_glpi, ['itemtype' => ['LIKE' => 'PluginSatisfaction%']]); 101 | } 102 | 103 | //Delete rights associated with the plugin 104 | $profileRight = new ProfileRight(); 105 | foreach (PluginSatisfactionProfile::getAllRights() as $right) { 106 | $profileRight->deleteByCriteria(['name' => $right['field']]); 107 | } 108 | PluginSatisfactionProfile::removeRightsFromSession(); 109 | 110 | PluginSatisfactionMenu::removeRightsFromSession(); 111 | 112 | PluginSatisfactionNotificationTargetTicket::uninstall(); 113 | 114 | CronTask::Register(PluginSatisfactionReminder::class, PluginSatisfactionReminder::CRON_TASK_NAME, DAY_TIMESTAMP); 115 | 116 | return true; 117 | } 118 | -------------------------------------------------------------------------------- /inc/dashboard.class.php: -------------------------------------------------------------------------------- 1 | . 27 | -------------------------------------------------------------------------- 28 | */ 29 | 30 | /** 31 | * Class PluginResourcesDashboard 32 | */ 33 | #[AllowDynamicProperties] 34 | class PluginSatisfactionDashboard extends CommonGLPI 35 | { 36 | // Widget identifiers 37 | const SATISFACTION_SURVEY = 1; 38 | 39 | // Icons 40 | const ICON_CIRCLE = 0; 41 | 42 | // Periods 43 | const EMPTY_PERIOD = 0; 44 | const FIRST_TRIMESTER_PERIOD = 1; 45 | const SECOND_TRIMESTER_PERIOD = 2; 46 | const THIRD_TRIMESTER_PERIOD = 3; 47 | const FOURTH_TRIMESTER_PERIOD = 4; 48 | const YEAR_PERIOD = 5; 49 | 50 | const PERIOD_SELECTOR_HTML_ID = "period-selector"; 51 | 52 | /** 53 | * PluginResourcesDashboard constructor. 54 | * 55 | * @param array $options 56 | */ 57 | public function __construct($options = []) 58 | { 59 | $this->options = $options; 60 | $this->interfaces = ["central"]; 61 | } 62 | 63 | /** 64 | * @return array 65 | */ 66 | public function getWidgetsForItem() 67 | { 68 | 69 | $widgets = [ 70 | PluginMydashboardMenu::$HELPDESK => [ 71 | 72 | $this->getType().self::SATISFACTION_SURVEY => ["title" => __('Summary of satisfaction surveys', 'satisfaction'), 73 | "type" => PluginMydashboardWidget::$KPI, 74 | "comment" => ""], 75 | ], 76 | ]; 77 | 78 | return $widgets; 79 | } 80 | 81 | 82 | public function getWidgetTitle($widgetId) 83 | { 84 | $result = ""; 85 | switch ($widgetId) { 86 | case $this->getType().self::SATISFACTION_SURVEY: 87 | $result = __('Satisfaction survey', 'satisfaction'); 88 | break; 89 | } 90 | return $result; 91 | } 92 | 93 | /** 94 | * Give name of period by id 95 | * Or give all list if id is null 96 | * 97 | * @param null $idPeriod 98 | * @return array|mixed|null 99 | */ 100 | public function getPeriodNames($idPeriod = null) 101 | { 102 | $titles = [ 103 | self::EMPTY_PERIOD => "--", 104 | self::FIRST_TRIMESTER_PERIOD => __('First Trimester', 'satisfaction'), 105 | self::SECOND_TRIMESTER_PERIOD => __('Second Trimester', 'satisfaction'), 106 | self::THIRD_TRIMESTER_PERIOD => __('Third Trimester', 'satisfaction'), 107 | self::FOURTH_TRIMESTER_PERIOD => __('Fourth Trimester', 'satisfaction'), 108 | self::YEAR_PERIOD => __('Year', 'satisfaction'), 109 | ]; 110 | 111 | if (is_null($idPeriod)) { 112 | return $titles; 113 | } else { 114 | return $titles[$idPeriod]; 115 | } 116 | } 117 | 118 | /** 119 | * Give the period interval of date 120 | * 121 | * @param $idPeriod 122 | * @param null $year 123 | * @return array 124 | */ 125 | public function getDateIntervalForPeriod($idPeriod, $year) 126 | { 127 | $interval = []; 128 | 129 | switch($idPeriod) { 130 | case self::FIRST_TRIMESTER_PERIOD: 131 | $interval['begin'] = $year.'-01-01 00:00:00'; 132 | $interval['end'] = $year.'-03-31 00:00:00'; 133 | break; 134 | case self::SECOND_TRIMESTER_PERIOD: 135 | $interval['begin'] = $year.'-04-01 00:00:00'; 136 | $interval['end'] = $year.'-06-30 00:00:00'; 137 | break; 138 | case self::THIRD_TRIMESTER_PERIOD: 139 | $interval['begin'] = $year.'-07-01 00:00:00'; 140 | $interval['end'] = $year.'-09-30 00:00:00'; 141 | break; 142 | case self::FOURTH_TRIMESTER_PERIOD: 143 | $interval['begin'] = $year.'-10-01 00:00:00'; 144 | $interval['end'] = $year.'-12-31 00:00:00'; 145 | break; 146 | case self::YEAR_PERIOD: 147 | case null: 148 | $interval['begin'] = $year.'-01-01 00:00:00'; 149 | $interval['end'] = $year.'-12-31 00:00:00'; 150 | } 151 | return $interval; 152 | } 153 | 154 | /** 155 | * @param $widgetId 156 | * 157 | * @return \PluginMydashboardDatatable 158 | */ 159 | public function getWidgetContentForItem($widgetId, $opt = []) 160 | { 161 | switch ($widgetId) { 162 | case $this->getType().self::SATISFACTION_SURVEY: 163 | return self::satisfactionSurvey($widgetId, $opt); 164 | break; 165 | } 166 | } 167 | 168 | public function satisfactionSurvey($widgetId, $opt = []) 169 | { 170 | global $DB; 171 | 172 | $criterias = ['begin', 'end', 'year', self::PERIOD_SELECTOR_HTML_ID]; 173 | $params = ["criterias" => $criterias, "opt"=> $opt]; 174 | $options = PluginMydashboardHelper::manageCriterias($params); 175 | 176 | $period = isset($opt[self::PERIOD_SELECTOR_HTML_ID]) ? $opt[self::PERIOD_SELECTOR_HTML_ID] : null ; 177 | $year = isset($options['opt']['year']) ? $options['opt']['year'] : date("Y"); 178 | 179 | // When period is chosen we set the interval of date with the year 180 | if (is_null($period) || intval($period) !== self::EMPTY_PERIOD) { 181 | $interval = self::getDateIntervalForPeriod($period, $year); 182 | 183 | $options['opt']['begin'] = $interval['begin']; 184 | $options['opt']['end'] = $interval['end']; 185 | 186 | $options['opt'][self::PERIOD_SELECTOR_HTML_ID] = self::EMPTY_PERIOD; 187 | } 188 | 189 | $opt = $options['opt']; 190 | 191 | $widget = new PluginMydashboardHtml(); 192 | $widget->setWidgetTitle(self::getWidgetTitle($widgetId)); 193 | 194 | $content = ""; 195 | 196 | // Recover survey associed to current entity 197 | $pluginSatisfactionSurvey = new PluginSatisfactionSurvey(); 198 | if (!$pluginSatisfactionSurvey->getFromDBByCrit([ 199 | 'entities_id' => $_SESSION['glpiactive_entity'], 200 | 'is_active' => 1 201 | ])) { 202 | $content.= '
'; 203 | $content.= '

'; 204 | $content.= '

'.__("There are no survey for current entity", "satisfaction").'

'; 205 | $content.= '
'; 206 | } else { 207 | // Values 208 | $numberOfSurveys = 0; 209 | $numberOfImpactedTickets = 0; 210 | $numberSurveyNotAnswered = 0; 211 | $numberSurveyAnswered = 0; 212 | $globalSatisfaction = 0; 213 | 214 | // Datetime to date conversion 215 | function addDateCriteria(&$query, $dateBegin, $dateEnd) 216 | { 217 | if (!empty($dateBegin)) { 218 | $query.= " AND date(date_begin) >= '".$dateBegin."'"; 219 | } 220 | if (!empty($dateEnd)) { 221 | $query.= " AND date(date_begin) < '".$dateEnd."'"; 222 | } 223 | } 224 | 225 | // Number of satisfaction survey 226 | $query = "SELECT count(*) as nb FROM " . TicketSatisfaction::getTable(); 227 | $query .= " WHERE 1=1"; 228 | addDateCriteria($query, $opt['begin'], $opt['end']); 229 | 230 | $result = $DB->query($query); 231 | 232 | if ($DB->numrows($result)) { 233 | while ($data = $DB->fetchAssoc($result)) { 234 | $numberOfSurveys = $data['nb']; 235 | } 236 | } 237 | 238 | // Number of concerned tickets 239 | $query = "SELECT count(DISTINCT tickets_id) as nb FROM " . TicketSatisfaction::getTable(); 240 | $query .= " WHERE 1=1"; 241 | addDateCriteria($query, $opt['begin'], $opt['end']); 242 | 243 | $result = $DB->query($query); 244 | 245 | if ($DB->numrows($result)) { 246 | while ($data = $DB->fetchAssoc($result)) { 247 | $numberOfImpactedTickets = $data['nb']; 248 | } 249 | } 250 | 251 | // Survey not answered 252 | $query = "SELECT count(*) as nb FROM " . TicketSatisfaction::getTable(); 253 | $query .= " WHERE date_answered IS NULL"; 254 | addDateCriteria($query, $opt['begin'], $opt['end']); 255 | 256 | $result = $DB->query($query); 257 | 258 | if ($DB->numrows($result)) { 259 | while ($data = $DB->fetchAssoc($result)) { 260 | $numberSurveyNotAnswered = $data['nb']; 261 | } 262 | } 263 | 264 | // Survey answered 265 | $query = "SELECT count(DISTINCT tickets_id) as nb FROM " . TicketSatisfaction::getTable(); 266 | $query .= " WHERE date_answered IS NOT NULL"; 267 | addDateCriteria($query, $opt['begin'], $opt['end']); 268 | 269 | $result = $DB->query($query); 270 | 271 | if ($DB->numrows($result)) { 272 | while ($data = $DB->fetchAssoc($result)) { 273 | $numberSurveyAnswered = $data['nb']; 274 | } 275 | } 276 | 277 | // Global satisfaction 278 | $query = "SELECT AVG(satisfaction) as nb FROM " . TicketSatisfaction::getTable(); 279 | $query .= " WHERE date_answered IS NOT NULL"; 280 | addDateCriteria($query, $opt['begin'], $opt['end']); 281 | 282 | $result = $DB->query($query); 283 | 284 | if ($DB->numrows($result)) { 285 | while ($data = $DB->fetchAssoc($result)) { 286 | $globalSatisfaction = $data['nb']; 287 | } 288 | } 289 | 290 | $globalSatisfaction = round($globalSatisfaction, 1); 291 | 292 | function displayElement($color, $icon, $title, $value) 293 | { 294 | $elem = '
'; 295 | //$elem.= ''; 296 | $elem.= ''; 297 | $elem.= '

'; 298 | $elem.= ''.$value.''; 299 | $elem.= '

'; 300 | $elem.= '

'.$title.'

'; 301 | //$elem.= '
'; 302 | $elem.= '
'; 303 | 304 | return $elem; 305 | } 306 | 307 | // Add css and javascript to display stars with rateit 308 | $content = Html::css('public/lib/jquery.rateit.css'); 309 | Html::requireJs('rateit'); 310 | 311 | $content.= '
'; 312 | $content.= displayElement( 313 | "grey", 314 | "fa-exclamation-circle", 315 | __("Number of surveys", "satisfaction"), 316 | $numberOfSurveys 317 | ); 318 | $content.= displayElement( 319 | "grey", 320 | "fa-id-card", 321 | __("Number of concerned tickets", "satisfaction"), 322 | $numberOfImpactedTickets 323 | ); 324 | $content.= displayElement( 325 | "indianred", 326 | "fa-times", 327 | __("Survey not answered", "satisfaction"), 328 | $numberSurveyNotAnswered 329 | ); 330 | $content.= displayElement( 331 | "green", 332 | "fa-check", 333 | __("Survey answered", "satisfaction"), 334 | $numberSurveyAnswered 335 | ); 336 | 337 | $content.= '
'; 338 | $content.= '

'; 339 | $content.= ''.__("Global satisfaction", "satisfaction").''; 340 | $content.= '

'; 341 | $content.= '

'.$globalSatisfaction.'

'; 342 | $content.= '
'; 343 | $content.= "
"; 344 | $content.= "
"; 345 | 346 | $params = ["widgetId" => $widgetId, 347 | "name" => str_replace(' ', '', self::getWidgetTitle($widgetId)), 348 | "onsubmit" => true, 349 | "opt" => $opt, 350 | "criterias" => $criterias, 351 | "export" => false, 352 | "canvas" => false, 353 | "nb" => 1]; 354 | 355 | $graphHeader = PluginMydashboardHelper::getGraphHeader($params); 356 | 357 | self::addPeriodCriteriaToGraphHeader($graphHeader); 358 | 359 | $widget->setWidgetHeader($graphHeader); 360 | } 361 | 362 | $widget->setWidgetHtmlContent($content); 363 | $widget->toggleWidgetRefresh(); 364 | return $widget; 365 | } 366 | 367 | /** 368 | * Only works with submit button in $graphHeader 369 | * 370 | * @param $graphHeader 371 | */ 372 | public function addPeriodCriteriaToGraphHeader(&$graphHeader) 373 | { 374 | $submitPos = strpos($graphHeader, "