, 2025
8 | # Edison Jaçe, 2025
9 | #
10 | #, fuzzy
11 | msgid ""
12 | msgstr ""
13 | "Project-Id-Version: GLPI - AutoExportSearches plugin\n"
14 | "Report-Msgid-Bugs-To: \n"
15 | "POT-Creation-Date: 2025-03-17 15:03+0000\n"
16 | "PO-Revision-Date: 2025-02-21 16:08+0000\n"
17 | "Last-Translator: Edison Jaçe, 2025\n"
18 | "Language-Team: French (France) (https://app.transifex.com/infotelGLPI/teams/205440/fr_FR/)\n"
19 | "MIME-Version: 1.0\n"
20 | "Content-Type: text/plain; charset=UTF-8\n"
21 | "Content-Transfer-Encoding: 8bit\n"
22 | "Language: fr_FR\n"
23 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
24 |
25 | #: setup.php:80
26 | msgid "Auto export searches"
27 | msgid_plural "Auto exports searches"
28 | msgstr[0] "Export automatique de recherches"
29 | msgstr[1] "Exports automatiques de recherches"
30 | msgstr[2] "Exports automatiques de recherches"
31 |
32 | #: ajax/customsearchcriterias.php:78
33 | msgid "Customise the export of"
34 | msgstr "Personnaliser l'export de"
35 |
36 | #: ajax/customsearchcriterias.php:86
37 | msgid "Value"
38 | msgstr "Valeur"
39 |
40 | #: ajax/customsearchcriterias.php:87
41 | msgid "Customise"
42 | msgstr "Personnaliser"
43 |
44 | #: ajax/periodicityfields.php:48
45 | msgid "Periodicity (in minutes)"
46 | msgstr "Périodicité (en minutes)"
47 |
48 | #: ajax/periodicityfields.php:64
49 | msgid "Periodicity (in hours)"
50 | msgstr "Périodicité (en heures)"
51 |
52 | #: ajax/periodicityfields.php:78
53 | msgid "Periodicity (in days)"
54 | msgstr "Périodicité ( en jours)"
55 |
56 | #: ajax/periodicityfields.php:89 ajax/periodicityfields.php:171
57 | msgid "Work day only"
58 | msgstr "Seulement les jours ouvrés"
59 |
60 | #: ajax/periodicityfields.php:92
61 | msgid "If this option is checked, the export will be done only on worked day"
62 | msgstr "Si cette option est coché, l'export ne sera fait que les jours ouvrés"
63 |
64 | #: ajax/periodicityfields.php:140
65 | msgid "Weekday"
66 | msgstr "Jour de la semaine"
67 |
68 | #: ajax/periodicityfields.php:155
69 | msgid "Day of the month"
70 | msgstr "Jour du mois"
71 |
72 | #: ajax/periodicityfields.php:167
73 | msgid ""
74 | "For months having less days than the selected day, the export will be done "
75 | "on the last day of the month."
76 | msgstr ""
77 | "Pour les mois plus court que le jour sélectionné, l'export sera fait le "
78 | "dernier jour du mois."
79 |
80 | #: ajax/periodicityfields.php:174
81 | msgid ""
82 | "If this option is checked, the export will be done the first work day from "
83 | "the selected day"
84 | msgstr ""
85 | "Si cette option est cochée, l'export sera fait le jour premier ouvré à "
86 | "partir du jour sélectionné"
87 |
88 | #: front/config.form.php:56
89 | msgid "Please activate the plugin"
90 | msgstr "Veuillez activer le plugin"
91 |
92 | #: front/files.php:66
93 | msgid "File successfully deleted"
94 | msgstr "Fichier supprimé avec succès"
95 |
96 | #: front/files.php:68
97 | msgid "No file selected"
98 | msgstr "Pas de fichier sélectionné"
99 |
100 | #: inc/config.class.php:58
101 | msgid "Number of months before purge files"
102 | msgstr "Nombre de mois avant la purge des fichiers"
103 |
104 | #: inc/exportconfig.class.php:59 inc/profile.class.php:187
105 | msgid "Auto export config"
106 | msgstr "Configuration de l'export automatique"
107 |
108 | #: inc/exportconfig.class.php:86 inc/exportconfig.class.php:140
109 | msgid "User who owns the saved search"
110 | msgstr "Utilisateur ayant la vue à exporter"
111 |
112 | #: inc/exportconfig.class.php:94 inc/exportconfig.class.php:156
113 | msgid "Saved search to export"
114 | msgstr "Recherche sauvegardée à exporter"
115 |
116 | #: inc/exportconfig.class.php:111
117 | msgid "Last export"
118 | msgstr "Dernier export"
119 |
120 | #: inc/exportconfig.class.php:135
121 | msgid "Search to export"
122 | msgstr "Recherche sauvegardée à exporter"
123 |
124 | #: inc/exportconfig.class.php:187
125 | msgid "Periodicity type"
126 | msgstr "Type de périodicité"
127 |
128 | #: inc/exportconfig.class.php:195
129 | msgid "Every x days"
130 | msgstr "Tout les x jours"
131 |
132 | #: inc/exportconfig.class.php:198
133 | msgid "Every x minutes"
134 | msgstr "Toutes les x minutes"
135 |
136 | #: inc/exportconfig.class.php:199
137 | msgid "Every x hours"
138 | msgstr "Toutes les x heures"
139 |
140 | #: inc/exportconfig.class.php:228
141 | msgid "Options"
142 | msgstr "Options"
143 |
144 | #: inc/exportconfig.class.php:232
145 | msgid "Send mail to"
146 | msgstr "Envoyé par mail à l'adresse"
147 |
148 | #: inc/exportconfig.class.php:559
149 | msgid "Export saved searches"
150 | msgstr "Recherches sauvegardées exportées"
151 |
152 | #: inc/files.class.php:43
153 | msgid "Download files"
154 | msgstr "Téléchargements des fichiers"
155 |
156 | #: inc/files.class.php:104
157 | msgid "No export files available"
158 | msgstr "Pas de fichiers exportés disponibles"
159 |
160 | #: inc/files.class.php:138
161 | msgid "Files"
162 | msgstr "Fichiers"
163 |
164 | #: inc/files.class.php:204
165 | msgid "File name"
166 | msgstr "Nom du fichier"
167 |
168 | #: inc/files.class.php:208
169 | msgid "Generation date"
170 | msgstr "Date de génération"
171 |
172 | #: inc/files.class.php:286
173 | msgid "No file to download in the directory"
174 | msgstr "Pas de fichier à télécharger dans le dossier"
175 |
176 | #: inc/files.class.php:291
177 | msgid "The folder doesn't exist"
178 | msgstr "Le dossier n'existe pas"
179 |
180 | #: inc/files.class.php:405
181 | msgid "Delete export files"
182 | msgstr "Supprimer les fichiers exportés"
183 |
184 | #: inc/menu.class.php:41
185 | msgid "Auto export"
186 | msgid_plural "Auto exports"
187 | msgstr[0] "Export automatique"
188 | msgstr[1] "Exports automatiques"
189 | msgstr[2] "Exports automatiques"
190 |
191 | #: inc/menu.class.php:94
192 | msgid "Menu"
193 | msgstr "Menu"
194 |
195 | #: inc/menu.class.php:101
196 | msgid "Export config list to export"
197 | msgstr "Liste des configurations d'export à exporter"
198 |
199 | #: inc/menu.class.php:108
200 | msgid "List of export files"
201 | msgstr "Liste des fichiers exportés"
202 |
203 | #: inc/profile.class.php:152
204 | msgid "Access to download files"
205 | msgstr "Téléchargements des fichiers"
206 |
207 | #: inc/profile.class.php:194
208 | msgid "Access export files"
209 | msgstr "Accès aux fichiers exportés"
210 |
211 | #: inc/profile.class.php:199
212 | msgid "Configuration"
213 | msgstr "Configuration"
214 |
--------------------------------------------------------------------------------
/ajax/customsearchcriterias.php:
--------------------------------------------------------------------------------
1 | .
26 | --------------------------------------------------------------------------
27 | */
28 |
29 | use Glpi\Exception\Http\AccessDeniedHttpException;
30 | use GlpiPlugin\Autoexportsearches\Customsearchcriteria;
31 |
32 | header("Content-Type: text/html; charset=UTF-8");
33 | Html::header_nocache();
34 | Session::checkRight('plugin_autoexportsearches_exportconfigs', UPDATE);
35 |
36 | Session::checkLoginUser();
37 |
38 | $savedSearchId = null;
39 | if (isset($_POST['savedsearches_id']) && $_POST['savedsearches_id']) {
40 | $savedSearchId = $_POST['savedsearches_id'];
41 | }
42 | if (Session::haveRight("plugin_autoexportsearches_exportconfigs", READ)) {
43 | if ($savedSearchId) {
44 | $translations = [
45 | 'equals' => __('is'),
46 | 'notequals' => __('is not'),
47 | 'lessthan' => __('before'),
48 | 'morethan' => __('after'),
49 | 'contains' => __('contains'),
50 | 'notcontains' => __('not contains')
51 | ];
52 |
53 | echo "";
54 | $search = new SavedSearch();
55 | if ($search->getFromDB($savedSearchId)) {
56 | $url = "?" . $search->fields["query"];
57 | $url_components = parse_url($url);
58 | parse_str($url_components['query'], $p);
59 | if (isset($p['itemtype'])) {
60 | $item = getItemForItemtype($p['itemtype']);
61 | if ($item instanceof CommonITILObject) {
62 | $fields = $item->getSearchOptionsMain();
63 | $dateFields = array_filter($fields, function ($f) {
64 | if (array_key_exists('datatype', $f)) {
65 | return $f['datatype'] === 'datetime';
66 | }
67 | return false;
68 | });
69 | $dateFieldsIds = array_map(function ($f) {
70 | return $f['id'];
71 | }, $dateFields);
72 | $headerAdded = false;
73 | foreach ($p['criteria'] as $index => $criteria) {
74 | if (in_array($criteria['field'], $dateFieldsIds)) {
75 | $value = $criteria['value'];
76 | if (str_starts_with($value, '-')
77 | && (str_contains($value, 'MONTH') || str_contains($value, 'WEEK'))) {
78 | if (!$headerAdded) {
79 | echo "";
80 | echo "" . __(
81 | 'Customise the export of',
82 | 'autoexportsearches'
83 | ) . __(
84 | $p['itemtype']
85 | ) . " | ";
86 | echo "
";
87 | echo "";
88 | echo "" . __('Criterion') . " | ";
89 | echo "" . __('Value', 'autoexportsearches') . " | ";
90 | echo "" . __('Customise', 'autoexportsearches') . " | ";
91 | echo "
";
92 | $headerAdded = true;
93 | }
94 |
95 | $customValue = null;
96 | $customCriteria = new Customsearchcriteria();
97 | if ($customCriteria->getFromDBByCrit([
98 | 'savedsearches_id' => $savedSearchId,
99 | 'exportconfigs_id' => $_POST['exportconfigs_id'],
100 | 'criteria_field' => $criteria['field'],
101 | 'criteria_searchtype' => $criteria['searchtype']
102 | ])) {
103 | $customValue = $customCriteria->fields['criteria_value'];
104 | }
105 |
106 | $field = array_filter($dateFields, function ($f) use ($criteria) {
107 | return $f['id'] == $criteria['field'];
108 | });
109 | $field = reset($field);
110 |
111 | $timeValue = str_contains($value, 'MONTH') ? 'month' : 'week';
112 | $searchValue = $translations[$criteria['searchtype']] . ' : -' . sprintf(
113 | _n("%d $timeValue", "%d $timeValue" . 's', $value[1]),
114 | $value[1]
115 | );
116 | $label = $timeValue === 'month' ? __('Beginning of the month') : __('Monday');
117 | $inputValue = $timeValue === 'month' ? Customsearchcriteria::CRITERIA_FIRST_DAY_OF_MONTH : Customsearchcriteria::CRITERIA_FIRST_DAY_OF_WEEK;
118 | $checked = $customValue === $inputValue ? 'checked' : '';
119 | echo "
120 |
121 | |
122 |
123 | |
124 |
125 | $searchValue
126 | |
127 |
128 |
129 |
130 |
131 |
132 |
133 | |
134 |
135 | ";
136 | }
137 | }
138 | }
139 | }
140 | }
141 | }
142 | echo "
";
143 | }
144 | } else {
145 | throw new AccessDeniedHttpException();
146 | }
147 |
148 |
--------------------------------------------------------------------------------
/ajax/periodicityfields.php:
--------------------------------------------------------------------------------
1 | .
26 | --------------------------------------------------------------------------
27 | */
28 |
29 | use Glpi\Exception\Http\AccessDeniedHttpException;
30 | use GlpiPlugin\Autoexportsearches\Exportconfig;
31 |
32 | header("Content-Type: text/html; charset=UTF-8");
33 | Html::header_nocache();
34 |
35 | Session::checkLoginUser();
36 | Session::checkRight('plugin_autoexportsearches_exportconfigs', UPDATE);
37 |
38 | $id = 0;
39 | if (isset($_POST['id']) && $_POST['id']) {
40 | $id = $_POST['id'];
41 | }
42 | if (Session::haveRight("plugin_autoexportsearches_exportconfigs", READ)
43 | && Session::haveRight("plugin_autoexportsearches_exportconfigs", UPDATE)) {
44 | $exportConfig = null;
45 | if ($id > 0) {
46 | $exportConfig = new Exportconfig();
47 | $exportConfig->getFromDB($id);
48 | }
49 | switch ($_POST['periodicity_type']) {
50 | case Exportconfig::PERIODICITY_MINUTES:
51 | echo "" . __('Periodicity (in minutes)', 'autoexportsearches') . " | ";
52 |
53 | $rand = mt_rand();
54 |
55 | Dropdown::showNumber(
56 | 'periodicity',
57 | [
58 | 'value' => $exportConfig ? $exportConfig->fields['periodicity'] : 1,
59 | 'rand' => $rand,
60 | 'min' => 30,
61 | 'max' => 59
62 | ]
63 | );
64 | echo " | ";
65 | break;
66 | case Exportconfig::PERIODICITY_HOURS:
67 | echo "" . __('Periodicity (in hours)', 'autoexportsearches') . " | ";
68 | $rand = mt_rand();
69 | Dropdown::showNumber(
70 | 'periodicity',
71 | [
72 | 'value' => $exportConfig ? $exportConfig->fields['periodicity'] : 1,
73 | 'rand' => $rand,
74 | 'min' => 1,
75 | 'max' => 23
76 | ]
77 | );
78 | echo " | ";
79 | break;
80 | case Exportconfig::PERIODICITY_DAYS:
81 | echo "" . __('Periodicity (in days)', 'autoexportsearches') . " | ";
82 | echo "";
83 | $rand = mt_rand();
84 | Dropdown::showNumber(
85 | 'periodicity',
86 | [
87 | 'value' => $exportConfig ? $exportConfig->fields['periodicity'] : 1,
88 | 'rand' => $rand,
89 | 'min' => 1
90 | ]
91 | );
92 | $openDaysLabel = __('Work day only', 'autoexportsearches');
93 | $checked = $exportConfig ? $exportConfig->fields['periodicity_open_days'] == 1 ? 'checked' : '' : '';
94 | $openDaysExplanation = __(
95 | 'If this option is checked, the export will be done only on worked day',
96 | 'autoexportsearches'
97 | );
98 | echo "
99 |
100 |
101 |
102 |
106 |
107 |
108 |
109 |
123 | ";
124 | echo "
125 |
138 | ";
139 | echo " | ";
140 | break;
141 |
142 | case Exportconfig::PERIODICITY_WEEKLY:
143 | echo "" . __('Weekday', 'autoexportsearches') . " | ";
144 |
145 | $rand = mt_rand();
146 | Dropdown::showFromArray(
147 | 'periodicity',
148 | Toolbox::getDaysOfWeekArray(),
149 | [
150 | 'value' => $exportConfig ? $exportConfig->fields['periodicity'] : 1,
151 | 'rand' => $rand
152 | ]
153 | );
154 | echo " | ";
155 | break;
156 |
157 | case Exportconfig::PERIODICITY_MONTHLY:
158 | echo "" . __('Day of the month', 'autoexportsearches') . " | ";
159 | $rand = mt_rand();
160 | Dropdown::showNumber(
161 | 'periodicity',
162 | [
163 | 'value' => $exportConfig ? $exportConfig->fields['periodicity'] : 1,
164 | 'rand' => $rand,
165 | 'min' => 1,
166 | 'max' => 31
167 | ]
168 | );
169 | echo '' . __(
170 | 'For months having less days than the selected day, the export will be done on the last day of the month.',
171 | 'autoexportsearches'
172 | ) . '';
173 | echo ' ';
174 | $openDaysLabel = __('Work day only', 'autoexportsearches');
175 | $checked = $exportConfig ? $exportConfig->fields['periodicity_open_days'] == 1 ? 'checked' : '' : '';
176 | $openDaysExplanation = __(
177 | 'If this option is checked, the export will be done the first work day from the selected day',
178 | 'autoexportsearches'
179 | );
180 | echo "
181 |
182 |
183 |
184 |
188 |
189 |
190 |
191 |
205 | ";
206 | echo " | ";
207 | break;
208 | }
209 | } else {
210 | throw new AccessDeniedHttpException();
211 | }
212 |
213 |
214 |
--------------------------------------------------------------------------------
/src/Profile.php:
--------------------------------------------------------------------------------
1 | .
26 | --------------------------------------------------------------------------
27 | */
28 |
29 | namespace GlpiPlugin\Autoexportsearches;
30 |
31 | use CommonGLPI;
32 | use DbUtils;
33 | use Html;
34 | use ProfileRight;
35 | use Session;
36 |
37 | if (!defined('GLPI_ROOT')) {
38 | die("Sorry. You can't access directly to this file");
39 | }
40 |
41 | /**
42 | * Class Profile
43 | */
44 | class Profile extends \Profile
45 | {
46 |
47 | static $rightname = "profile";
48 |
49 | /**
50 | * @param CommonGLPI $item
51 | * @param int $withtemplate
52 | *
53 | * @return string
54 | */
55 | public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0)
56 | {
57 |
58 | if ($item->getType() == 'Profile') {
59 | if ($item->getField('interface') == 'central') {
60 | return self::createTabEntry(Menu::getMenuName(2));
61 | }
62 | }
63 | return '';
64 | }
65 |
66 | static function getIcon()
67 | {
68 | return Menu::getIcon();
69 | }
70 | /**
71 | * @param CommonGLPI $item
72 | * @param int $tabnum
73 | * @param int $withtemplate
74 | *
75 | * @return bool
76 | */
77 | public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0)
78 | {
79 |
80 | if ($item->getType() == 'Profile') {
81 | $ID = $item->getID();
82 | $prof = new self();
83 |
84 | self::addDefaultProfileInfos(
85 | $ID,
86 | ['plugin_autoexportsearches_exportconfigs' => 0,
87 | 'plugin_autoexportsearches_accessfiles' => 0,
88 | 'plugin_autoexportsearches_configs' => 0]
89 | );
90 | $prof->showForm($ID);
91 | }
92 | return true;
93 | }
94 |
95 | /**
96 | * @param $ID
97 | */
98 | static function createFirstAccess($ID)
99 | {
100 | //85
101 | self::addDefaultProfileInfos(
102 | $ID,
103 | ['plugin_autoexportsearches_exportconfigs' => ALLSTANDARDRIGHT,
104 | 'plugin_autoexportsearches_accessfiles' => 1,
105 | 'plugin_autoexportsearches_configs' => 1],
106 | true
107 | );
108 | }
109 |
110 | /**
111 | * @param $profiles_id
112 | * @param $rights
113 | * @param bool $drop_existing
114 | *
115 | * @internal param $profile
116 | */
117 | static function addDefaultProfileInfos($profiles_id, $rights, $drop_existing = false)
118 | {
119 |
120 | $profileRight = new ProfileRight();
121 | $dbu = new DbUtils();
122 | foreach ($rights as $right => $value) {
123 | if ($dbu->countElementsInTable(
124 | 'glpi_profilerights',
125 | ["profiles_id" => $profiles_id, "name" => $right]
126 | ) && $drop_existing) {
127 | $profileRight->deleteByCriteria(['profiles_id' => $profiles_id, 'name' => $right]);
128 | }
129 | if (!$dbu->countElementsInTable(
130 | 'glpi_profilerights',
131 | ["profiles_id" => $profiles_id, "name" => $right]
132 | )) {
133 | $myright['profiles_id'] = $profiles_id;
134 | $myright['name'] = $right;
135 | $myright['rights'] = $value;
136 | $profileRight->add($myright);
137 |
138 | //Add right to the current session
139 | $_SESSION['glpiactiveprofile'][$right] = $value;
140 | }
141 | }
142 | }
143 |
144 | /**
145 | * Show profile form
146 | *
147 | * @param int $profiles_id
148 | * @param bool $openform
149 | * @param bool $closeform
150 | *
151 | * @return true
152 | * @internal param int $items_id id of the profile
153 | * @internal param value $target url of target
154 | *
155 | */
156 | function showForm($profiles_id = 0, $openform = true, $closeform = true)
157 | {
158 |
159 | echo "";
160 | if (($canedit = Session::haveRightsOr(self::$rightname, [CREATE, UPDATE, PURGE]))
161 | && $openform) {
162 | $profile = new \Profile();
163 | echo "
";
203 |
204 | return true;
205 | }
206 |
207 | /**
208 | * @param bool $all
209 | *
210 | * @return array
211 | */
212 | static function getAllRights($all = false)
213 | {
214 | $rights = [
215 | ['itemtype' => Exportconfig::class,
216 | 'label' => __('Auto export config', 'autoexportsearches'),
217 | 'field' => 'plugin_autoexportsearches_exportconfigs'
218 | ],
219 | ];
220 |
221 | if ($all) {
222 | $rights[] = ['itemtype' => Exportconfig::class,
223 | 'label' => __('Access export files', 'autoexportsearches'),
224 | 'field' => 'plugin_autoexportsearches_accessfiles'
225 | ];
226 |
227 | $rights[] = ['itemtype' => Exportconfig::class,
228 | 'label' => __('Configuration', 'autoexportsearches'),
229 | 'field' => 'plugin_autoexportsearches_configs'
230 | ];
231 | }
232 |
233 | return $rights;
234 | }
235 |
236 | /**
237 | * Init profiles
238 | *
239 | * @param $old_right
240 | *
241 | * @return int
242 | */
243 |
244 | static function translateARight($old_right)
245 | {
246 | switch ($old_right) {
247 | case '':
248 | return 0;
249 | case 'r':
250 | return READ;
251 | case 'w':
252 | return ALLSTANDARDRIGHT + READNOTE + UPDATENOTE;
253 | case '0':
254 | case '1':
255 | return $old_right;
256 |
257 | default:
258 | return 0;
259 | }
260 | }
261 |
262 |
263 | /**
264 | * Initialize profiles, and migrate it necessary
265 | */
266 | static function initProfile()
267 | {
268 | global $DB;
269 | $profile = new self();
270 | $dbu = new DbUtils();
271 | //Add new rights in glpi_profilerights table
272 | foreach ($profile->getAllRights(true) as $data) {
273 | if ($dbu->countElementsInTable(
274 | "glpi_profilerights",
275 | ["name" => $data['field']]
276 | ) == 0) {
277 | ProfileRight::addProfileRights([$data['field']]);
278 | }
279 | }
280 | $profileId = $_SESSION['glpiactiveprofile']['id'];
281 |
282 | foreach ($DB->request([
283 | 'FROM' => 'glpi_profilerights',
284 | 'WHERE' => [
285 | 'profiles_id' => $profileId,
286 | 'name' => ['LIKE', '%plugin_autoexportsearches%']
287 | ]
288 | ]) as $prof) {
289 | $_SESSION['glpiactiveprofile'][$prof['name']] = $prof['rights'];
290 | }
291 | }
292 |
293 |
294 | static function removeRightsFromSession()
295 | {
296 | foreach (self::getAllRights(true) as $right) {
297 | if (isset($_SESSION['glpiactiveprofile'][$right['field']])) {
298 | unset($_SESSION['glpiactiveprofile'][$right['field']]);
299 | }
300 | }
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/src/Files.php:
--------------------------------------------------------------------------------
1 | .
26 | --------------------------------------------------------------------------
27 | */
28 |
29 | namespace GlpiPlugin\Autoexportsearches;
30 |
31 | use CommonDBTM;
32 | use CronTask;
33 | use Html;
34 | use Migration;
35 | use ProfileRight;
36 |
37 | if (!defined('GLPI_ROOT')) {
38 | die("Sorry. You can't access directly to this file");
39 | }
40 |
41 | /**
42 | * Class Files
43 | */
44 | class Files extends CommonDBTM
45 | {
46 |
47 | static $rightname = 'plugin_autoexportsearches_accessfiles';
48 |
49 | static function getTypeName($nb = 0)
50 | {
51 | return __('Download files', 'autoexportsearches');
52 | }
53 |
54 | public static function install(Migration $migration)
55 | {
56 | CronTask::Register(
57 | Files::class,
58 | 'DeleteFile',
59 | MONTH_TIMESTAMP,
60 | ['state' => CronTask::STATE_DISABLE]
61 | );
62 | }
63 |
64 | static function canDownload()
65 | {
66 | return ProfileRight::getProfileRights(
67 | $_SESSION['glpiactiveprofile']['id'],
68 | ['plugin_autoexportsearches_accessfiles']
69 | );
70 | }
71 |
72 | function showMenu()
73 | {
74 |
75 | echo "";
76 | echo "
";
77 | echo "";
78 | echo "| " . self::getTypeName() . " | ";
79 | echo "
";
80 | $types = self::getTypes();
81 | $max = count($types);
82 | for ($i = 0; $i < $max; $i += 3) {
83 | echo "";
84 | if (($max - $i) >= 3) {
85 | $size = 2;
86 | } elseif (($max - $i) == 2) {
87 | $size = 3;
88 | } else {
89 | $size = 6;
90 | }
91 | if (isset($types[$i])) {
92 | $type = $types[$i];
93 | echo "";
94 | echo "";
95 | echo "";
96 | echo " " . $type . "";
97 | echo " | ";
98 | }
99 |
100 | if (isset($types[$i + 1])) {
101 | $type = $types[$i + 1];
102 | echo "";
103 | echo "";
104 | echo "";
105 | echo " " . $type . "";
106 | echo " | ";
107 | }
108 |
109 | if (isset($types[$i + 2])) {
110 | $type = $types[$i + 2];
111 | echo "";
112 | echo "";
113 | echo "";
114 | echo " " . $type . "";
115 | echo " | ";
116 | }
117 |
118 |
119 | echo "
";
120 | }
121 | if ($max == 0) {
122 | echo "| ";
123 | echo __("No export files available", 'autoexportsearches');
124 | echo " |
";
125 | }
126 | echo "
";
127 | }
128 |
129 | function getTypes()
130 | {
131 | $types = [];
132 | $config = new Config();
133 | $config->getFromDB(1);
134 | $dir = GLPI_PLUGIN_DOC_DIR . $config->getField('folder');
135 | //If the dir folder exist
136 | if (is_dir($dir)) {
137 | // Get all files in an array
138 | $files = scandir($dir);
139 | foreach ($files as $file) {
140 | $type = substr($file, 0, strpos($file, '_'));
141 | if (!in_array($type, $types) && !is_dir($dir . "/" . $file)) {
142 | array_push($types, $type);
143 | }
144 | }
145 | }
146 | return $types;
147 | }
148 |
149 | /** Show All files in a HTML table
150 | * @param $dir
151 | */
152 | function showListFiles($dir, $type)
153 | {
154 | global $CFG_GLPI;
155 |
156 | echo "";
157 | echo "
" . __('Files', 'autoexportsearches') . "
";
158 | //If the dir folder exist
159 | if (is_dir($dir)) {
160 | // Get all files in an array
161 | $files = $this->processFiles("get", "", $type);
162 |
163 | // If there is files in the folder
164 | if ($files == true) {
165 | //Pagination
166 | $limitBegin = 0;
167 | $nbRows = count($files);
168 | if (isset($_GET['start'])) {
169 | $limitBegin = $_GET['start'];
170 | }
171 | if (isset($_SESSION['glpilist_limit'])) {
172 | $limitNb = $_SESSION['glpilist_limit'];
173 | } else {
174 | $limitNb = 0;
175 | }
176 | $target = PLUGINAUTOEXPORTSEARCH_WEBDIR . '/front/files.php?type=' . $type;
177 | if (isset($_GET['orderType'])) {
178 | $parameters = "orderCol=" . $_GET['orderCol'] . "&orderType=" . $_GET['orderType'];
179 | } else {
180 | $parameters = "";
181 | }
182 | Html::printPager($limitBegin, $nbRows, $target, $parameters);
183 | echo "
";
301 | } else {
302 | echo "" . __(
303 | 'No file to download in the directory',
304 | 'autoexportsearches'
305 | ) . "
";
306 | }
307 | } else {
308 | echo "" . __('The folder doesn\'t exist', 'autoexportsearches') . "
";
309 | }
310 | }
311 |
312 | function sortArrayAsc($a, $b)
313 | {
314 | $aMonth = substr($a, strpos($a, "_") + 5, 2);
315 | $bMonth = substr($b, strpos($b, "_") + 5, 2);
316 | return $aMonth > $bMonth;
317 | }
318 |
319 | function sortArrayDesc($a, $b)
320 | {
321 | $aMonth = substr($a, strpos($a, "_") + 5, 2);
322 | $bMonth = substr($b, strpos($b, "_") + 5, 2);
323 | return $aMonth < $bMonth;
324 | }
325 |
326 | /** Get date in file name
327 | * @param $file
328 | * @param string $formatOut
329 | *
330 | * @return bool|string
331 | */
332 | function getDateFile($file, $formatOut = "Ymd")
333 | {
334 | switch ($formatOut) {
335 | case "Y":
336 | $out = substr($file, strpos($file, "_") + 1, 4);
337 | break;
338 | case "m":
339 | $out = substr($file, strpos($file, "_") + 6, 2);
340 | break;
341 | case "d":
342 | $out = substr($file, strpos($file, "_") + 9, 2);
343 | break;
344 | case "Ymd":
345 | $out = substr($file, strpos($file, "_") + 1, 10);
346 | break;
347 | case "YmdHis":
348 | $out = substr($file, strpos($file, "_") + 1, 19);
349 | break;
350 | }
351 | $out = str_replace("_", "-", $out);
352 |
353 | return $out;
354 | }
355 |
356 | /** Function that makes actions around files
357 | * @param $action
358 | * @param string $file
359 | *
360 | * @return array|bool
361 | */
362 | function processFiles($action, $file = "", $type = "")
363 | {
364 | $config = new Config();
365 | $config->getFromDB(1);
366 | $dir = GLPI_PLUGIN_DOC_DIR . $config->getField('folder');
367 |
368 | switch ($action) {
369 | case "get":
370 | $res = [];
371 | // Get files in defined dir
372 | $files = scandir($dir);
373 | foreach ($files as $file) {
374 | // if the file is not a folder
375 | if ($type != "" && strpos($file, $type) > -1) {
376 | if (!is_dir($dir . "/" . $file)) {
377 | $res[] = $file;
378 | }
379 | }
380 | }
381 | break;
382 | case "delete":
383 | // delete file
384 | $res = unlink($dir . "/" . $file);
385 | break;
386 | }
387 | return $res;
388 | }
389 |
390 | /** Function for delete files after $nbMonths
391 | * @param $nbMonths
392 | */
393 | function deleteByMonths($nbMonths)
394 | {
395 | $today = date("Ymd");
396 | $files = $this->processFiles("get");
397 | if (is_array($files)) {
398 | foreach ($files as $file) {
399 | $dateFile = strtotime($this->getDateFile($file));
400 | $nbMonthsToAdd = "+" . $nbMonths . " months";
401 | $dateDiff = strtotime($nbMonthsToAdd, $dateFile);
402 | $dateToDelete = date('Ymd', $dateDiff);
403 | if ($today > $dateToDelete) {
404 | $this->processFiles("delete", $file);
405 | }
406 | }
407 | }
408 | }
409 |
410 | ////// CRON FUNCTIONS ///////
411 | //Cron action
412 | /**
413 | * @param $name
414 | *
415 | * @return array
416 | */
417 | static function cronInfo($name)
418 | {
419 | switch ($name) {
420 | case 'DeleteFile':
421 | return [
422 | 'description' => __('Delete export files', 'autoexportsearches')
423 | ]; // Optional
424 | break;
425 | }
426 | return [];
427 | }
428 |
429 | /**
430 | * Cron action
431 | *
432 | * @param $task for log
433 | * @global $CFG_GLPI
434 | *
435 | * @global $DB
436 | */
437 | static function cronDeleteFile($task = null)
438 | {
439 | $CronTask = new CronTask();
440 | if ($CronTask->getFromDBbyName(Files::class, "DeleteFile")) {
441 | if ($CronTask->fields["state"] == CronTask::STATE_DISABLE) {
442 | return 0;
443 | }
444 | } else {
445 | return 0;
446 | }
447 |
448 | $config = new Config();
449 | $config->getFromDB(1);
450 | $nbMonths = $config->getField('monthBeforePurge');
451 |
452 | $autoexportsearchesFiles = new self();
453 | $autoexportsearchesFiles->deleteByMonths($nbMonths);
454 | return 1;
455 | }
456 | }
457 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/src/Exportconfig.php:
--------------------------------------------------------------------------------
1 | .
27 | --------------------------------------------------------------------------
28 | */
29 |
30 | namespace GlpiPlugin\Autoexportsearches;
31 |
32 | use Ajax;
33 | use Auth;
34 | use CommonDBTM;
35 | use CronTask;
36 | use DBConnection;
37 | use Dropdown;
38 | use GLPIMailer;
39 | use GLPINetwork;
40 | use Html;
41 | use Migration;
42 | use Profile;
43 | use SavedSearch;
44 | use Search;
45 | use Session;
46 | use User;
47 |
48 | if (!defined('GLPI_ROOT')) {
49 | die("Sorry. You can't access directly to this file");
50 | }
51 |
52 | /**
53 | * Class Exportconfig
54 | */
55 | class Exportconfig extends CommonDBTM
56 | {
57 | public const PERIODICITY_MINUTES = 3;
58 | public const PERIODICITY_HOURS = 4;
59 | public const PERIODICITY_DAYS = 0;
60 | public const PERIODICITY_WEEKLY = 1;
61 | public const PERIODICITY_MONTHLY = 2;
62 |
63 | public static $rightname = 'plugin_autoexportsearches_exportconfigs';
64 | // static $rightname = 'ticket';
65 |
66 |
67 | /**
68 | * functions mandatory
69 | * getTypeName(), canCreate(), canView()
70 | *
71 | * @param int $nb
72 | *
73 | * @return string
74 | */
75 | public static function getTypeName($nb = 0)
76 | {
77 | return __('Auto export config', 'autoexportsearches');
78 | }
79 |
80 | public static function install(Migration $migration)
81 | {
82 | global $DB;
83 |
84 | $default_charset = DBConnection::getDefaultCharset();
85 | $default_collation = DBConnection::getDefaultCollation();
86 | $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption();
87 | $table = self::getTable();
88 |
89 | if (!$DB->tableExists($table)) {
90 | $query = "CREATE TABLE `$table` (
91 | `id` int {$default_key_sign} NOT NULL auto_increment,
92 | `users_id` int {$default_key_sign} NOT NULL DEFAULT '0' COMMENT 'RELATION to glpi_users (id)',
93 | `savedsearches_id` int {$default_key_sign} NOT NULL DEFAULT '0' COMMENT 'RELATION to glpi_savedsearches (id)',
94 | `last_export` timestamp NULL DEFAULT NULL,
95 | `periodicity_type` int NOT NULL DEFAULT '0',
96 | `periodicity` int {$default_key_sign} NOT NULL DEFAULT '1',
97 | `periodicity_open_days` tinyint NOT NULL DEFAULT '0',
98 | `is_active` tinyint NOT NULL DEFAULT '1',
99 | `is_deleted` tinyint NOT NULL DEFAULT '0',
100 | `sendto` VARCHAR(255) DEFAULT '',
101 | PRIMARY KEY (`id`),
102 | KEY `users_id` (`users_id`),
103 | KEY `savedsearches_id` (`savedsearches_id`)
104 | ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;";
105 |
106 | $DB->doQuery($query);
107 | }
108 |
109 | if (!$DB->fieldExists($table, "sendto")) {
110 | $migration->addField($table, "sendto", "VARCHAR(255) DEFAULT ''");
111 | $migration->migrationOneTable($table);
112 | }
113 | if ($DB->fieldExists($table, "searches_id")) {
114 | $migration->changeField($table, 'searches_id', 'savedsearches_id', "int {$default_key_sign} NOT NULL DEFAULT '0'");
115 | $migration->migrationOneTable($table);
116 | }
117 | if (!$DB->fieldExists($table, "periodicity_type")) {
118 | $migration->addField($table, "periodicity_type", "int NOT NULL DEFAULT '0'");
119 | $migration->migrationOneTable($table);
120 | $query = $DB->buildUpdate(
121 | $table,
122 | [
123 | 'periodicity_type' => 0,
124 | ],
125 | [1]
126 | );
127 | $DB->doQuery($query);
128 | }
129 |
130 | if (!$DB->fieldExists($table, "periodicity_open_days")) {
131 | $migration->addField($table, "periodicity_open_days", "tinyint NOT NULL DEFAULT '0'");
132 | $migration->migrationOneTable($table);
133 | $query = $DB->buildUpdate(
134 | $table,
135 | [
136 | 'periodicity_open_days' => 0,
137 | ],
138 | [1]
139 | );
140 | $DB->doQuery($query);
141 | }
142 |
143 | CronTask::Register(
144 | Exportconfig::class,
145 | 'AutoexportsearchesExportconfigExport',
146 | DAY_TIMESTAMP,
147 | ['mode' => CronTask::MODE_EXTERNAL]
148 | );
149 |
150 | //Displayprefs
151 | $prefs = [2 => 1,
152 | 3 => 2,
153 | 5 => 3,
154 | 6 => 4];
155 | foreach ($prefs as $num => $rank) {
156 | if (!countElementsInTable(
157 | "glpi_displaypreferences",
158 | ['itemtype' => Exportconfig::class,
159 | 'num' => $num,
160 | 'users_id' => 0
161 | ]
162 | )
163 | ) {
164 | $DB->insert(
165 | 'glpi_displaypreferences',
166 | ['itemtype' => Exportconfig::class,
167 | 'num' => $num,
168 | 'rank' => $rank,
169 | 'users_id' => 0,
170 | 'interface' => 'central']
171 | );
172 | }
173 | }
174 |
175 | $query = $DB->buildDelete(
176 | 'glpi_crontasks',
177 | ['itemtype' => ['LIKE', 'PluginAutoexportsearches' . '%']]
178 | );
179 | $DB->doQuery($query);
180 | }
181 |
182 | public static function uninstall()
183 | {
184 | global $DB;
185 |
186 | $DB->dropTable(self::getTable(), true);
187 |
188 | $itemtypes = ['Alert',
189 | 'DisplayPreference',
190 | 'Document_Item',
191 | 'ImpactItem',
192 | 'Item_Ticket',
193 | 'Link_Itemtype',
194 | 'Notepad',
195 | 'SavedSearch',
196 | 'DropdownTranslation',
197 | 'NotificationTemplate',
198 | 'Notification'];
199 | foreach ($itemtypes as $itemtype) {
200 | $item = new $itemtype;
201 | $item->deleteByCriteria(['itemtype' => Exportconfig::class]);
202 | }
203 | }
204 |
205 | /**
206 | * @return array
207 | */
208 | public function rawSearchOptions()
209 | {
210 | $tab = [];
211 |
212 | $tab[] = [
213 | 'id' => 'common',
214 | 'name' => self::getTypeName(2),
215 | ];
216 | $tab[] = [
217 | 'id' => '1',
218 | 'table' => self::getTable(),
219 | 'field' => 'id',
220 | 'name' => __('ID'),
221 | 'massiveaction' => false,
222 | 'datatype' => 'itemlink',
223 | ];
224 |
225 | $tab[] = [
226 | 'id' => '2',
227 | 'table' => User::getTable(),
228 | 'field' => 'name',
229 | 'name' => __('User who owns the saved search', 'autoexportsearches'),
230 | 'datatype' => 'dropdown',
231 | ];
232 |
233 | $tab[] = [
234 | 'id' => '3',
235 | 'table' => SavedSearch::getTable(),
236 | 'field' => 'name',
237 | 'name' => __('Saved search to export', 'autoexportsearches'),
238 | 'datatype' => 'dropdown',
239 | 'linkfield' => 'savedsearches_id',
240 | ];
241 |
242 | // $tab[] = [
243 | // 'id' => '4',
244 | // 'table' => self::getTable(),
245 | // 'field' => 'periodicity_type',
246 | // 'name' => __('Periodicity type', 'autoexportsearches'),
247 | // 'datatype' => 'text'
248 | // ];
249 |
250 | $tab[] = [
251 | 'id' => '5',
252 | 'table' => self::getTable(),
253 | 'field' => 'last_export',
254 | 'name' => __('Last export', 'autoexportsearches'),
255 | 'datatype' => 'datetime',
256 | ];
257 | $tab[] = [
258 | 'id' => '6',
259 | 'table' => self::getTable(),
260 | 'field' => 'is_active',
261 | 'name' => __('Active'),
262 | 'datatype' => 'bool',
263 | ];
264 |
265 |
266 | return $tab;
267 | }
268 |
269 | public function showForm($ID, $options = [])
270 | {
271 | global $CFG_GLPI;
272 |
273 |
274 | $this->initForm($ID, $options);
275 | $this->showFormHeader($options);
276 |
277 | echo "";
278 | echo "| " . __('Active') . " | ";
279 | echo "";
280 | Dropdown::showYesNo("is_active", $this->fields['is_active']);
281 | echo " | ";
282 | echo "
";
283 |
284 | echo "";
285 | echo "" . __('Search to export', 'autoexportsearches') . " | ";
286 | echo "
";
287 |
288 | echo "";
289 | echo "| " . __('User who owns the saved search', 'autoexportsearches') . " | ";
290 | echo "";
291 |
292 | $rand = mt_rand();
293 | User::dropdown([
294 | 'name' => 'users_id',
295 | 'value' => $this->fields["users_id"],
296 | // 'entity' => $this->fields["entities_id"],
297 | 'right' => 'own_ticket',
298 | 'rand' => $rand,
299 | ]);
300 | echo " | ";
301 | echo "
";
302 |
303 | echo "";
304 |
305 | echo "| " . __('Saved search to export', 'autoexportsearches') . " | ";
306 | echo "";
307 | echo " | ";
308 | echo "
";
309 | $params = [
310 | "users_id" => '__VALUE__',
311 | "current_user" => $this->fields['users_id'],
312 | 'savedsearches_id' => $this->fields["savedsearches_id"],
313 | 'exportconfigs_id' => $ID,
314 | "rand" => $rand,
315 | "action" => "loadSearches",
316 | ];
317 | $url = PLUGINAUTOEXPORTSEARCH_WEBDIR . "/ajax/dropdownsavedsearches.php";
318 | Ajax::updateItemOnSelectEvent("dropdown_users_id$rand", "savedSearches", $url, $params);
319 |
320 | echo "
321 |
326 | ";
327 |
328 | echo "| ";
329 | echo " |
";
330 |
331 | echo "";
332 | echo "" . __('Periodicity') . " | ";
333 | echo "
";
334 |
335 | echo "";
336 | echo "| " . __('Periodicity type', 'autoexportsearches') . " | ";
337 | echo "";
338 |
339 | $rand = mt_rand();
340 | Dropdown::showFromArray(
341 | 'periodicity_type',
342 | [
343 |
344 | self::PERIODICITY_DAYS => __('Every x days', 'autoexportsearches'),
345 | self::PERIODICITY_WEEKLY => _x('periodicity', 'Weekly'),
346 | self::PERIODICITY_MONTHLY => _x('periodicity', 'Monthly'),
347 | self::PERIODICITY_MINUTES => __('Every x minutes', 'autoexportsearches'),
348 | self::PERIODICITY_HOURS => __('Every x hours', 'autoexportsearches'),
349 | ],
350 | [
351 | 'value' => $this->fields['periodicity_type'],
352 | 'rand' => $rand,
353 | ]
354 | );
355 | echo " |
";
356 |
357 | echo "
";
358 | $url = PLUGINAUTOEXPORTSEARCH_WEBDIR . "/ajax/periodicityfields.php";
359 | // let ajax determine the fields shown depending on the choosen periodicity_type
360 | echo "
361 |
374 | ";
375 |
376 | echo "";
377 | echo "" . __('Options', 'autoexportsearches') . " | ";
378 | echo "
";
379 |
380 | echo "";
381 | echo "| " . __('Send mail to', 'autoexportsearches') . " | ";
382 | echo "";
383 | echo Html::input('sendto', ['type' => 'mail', 'value' => $this->fields['sendto']]);
384 | echo " | ";
385 |
386 | echo "
";
387 |
388 |
389 | $this->showFormButtons($options);
390 |
391 | return true;
392 | }
393 |
394 | /**
395 | * @return array
396 | */
397 | public static function getMenuContent()
398 | {
399 | $menu['title'] = self::getMenuName(2);
400 | $menu['page'] = self::getSearchURL(false);
401 | $menu['links']['search'] = self::getSearchURL(false);
402 |
403 | $menu['icon'] = static::getIcon();
404 | if (self::canCreate()) {
405 | $menu['links']['add'] = PLUGINAUTOEXPORTSEARCH_WEBDIR . "/front/exportconfig.form.php";
406 | }
407 |
408 |
409 | return $menu;
410 | }
411 |
412 |
413 | public static function getIcon()
414 | {
415 | return "ti ti-tags";
416 | }
417 |
418 |
419 | /**
420 | * Display datas extracted from DB
421 | *
422 | * @param array $data Array of search datas prepared to get datas
423 | *
424 | * @return false
425 | **/
426 | public static function createCSVFile(array $data, $filename)
427 | {
428 | global $CFG_GLPI;
429 |
430 | $file = fopen($filename, "w");
431 | if (!$file) {
432 | return false;
433 | }
434 |
435 | // UTF-8 BOM pour Excel
436 | fwrite($file, pack("CCC", 0xef, 0xbb, 0xbf));
437 |
438 | $headers = [];
439 | $metanames = [];
440 |
441 |
442 | foreach ($data['data']['cols'] as $col) {
443 | $name = $col['name'];
444 |
445 | // Gestion du groupname
446 | if (isset($col['groupname'])) {
447 | if (is_array($col['groupname'])) {
448 | $col['groupname'] = $col['groupname']['name'];
449 | }
450 | $name = $col['groupname'] . ' - ' . $name;
451 | }
452 |
453 |
454 | if ($data['itemtype'] != $col['itemtype']) {
455 | if (!isset($metanames[$col['itemtype']])) {
456 | if ($metaitem = getItemForItemtype($col['itemtype'])) {
457 | $metanames[$col['itemtype']] = $metaitem->getTypeName();
458 | } else {
459 | $metanames[$col['itemtype']] = $col['itemtype'];
460 | }
461 | }
462 | $name = $metanames[$col['itemtype']] . ' - ' . $name;
463 | }
464 |
465 | $headers[] = $name;
466 | }
467 |
468 |
469 | if (isset($CFG_GLPI["union_search_type"][$data['itemtype']])) {
470 | $headers[] = __('Item type');
471 | }
472 |
473 |
474 | fputcsv($file, $headers, ';');
475 |
476 |
477 | foreach ($data['data']['rows'] as $row) {
478 | $line = [];
479 |
480 | foreach ($data['data']['cols'] as $col) {
481 | $colkey = "{$col['itemtype']}_{$col['id']}";
482 | $value = $row[$colkey]['displayname'] ?? '';
483 |
484 |
485 | $value = html_entity_decode(strip_tags($value), ENT_QUOTES | ENT_HTML5, 'UTF-8');
486 | $value = preg_replace("/[\r\n]+/", ' ', $value);
487 |
488 | $line[] = trim($value);
489 | }
490 |
491 |
492 | if (isset($CFG_GLPI["union_search_type"][$data['itemtype']])) {
493 | $type = $row['TYPE'] ?? $data['itemtype'];
494 | $typename = '';
495 | if ($item = getItemForItemtype($type)) {
496 | $typename = $item->getTypeName();
497 | }
498 | $line[] = $typename;
499 | }
500 |
501 | fputcsv($file, $line, ';');
502 | }
503 |
504 | fclose($file);
505 | return true;
506 | }
507 |
508 |
509 |
510 |
511 | public static function executeExport($plugin_exportconfigs_id)
512 | {
513 | global $CFG_GLPI;
514 |
515 |
516 | $export = new self();
517 | $export->getFromDB($plugin_exportconfigs_id);
518 |
519 | $search = new SavedSearch();
520 | $customSearchCriteria = new Customsearchcriteria();
521 | if ($search->getFromDB($export->fields['savedsearches_id'])) {
522 | $url = "?" . $search->fields["query"];
523 | $url_components = parse_url($url);
524 | parse_str($url_components['query'], $p);
525 | $p["display_type"] = Search::CSV_OUTPUT;
526 | $p["export_all"] = 1;
527 | $itemtype = $search->fields["itemtype"];
528 | $weekday = date('w');
529 |
530 | $customCriterias = $customSearchCriteria->find(['exportconfigs_id' => $plugin_exportconfigs_id]);
531 | foreach ($customCriterias as $customCriteria) {
532 | $criteria = array_filter($p['criteria'], function ($c) use ($customCriteria) {
533 | return $c['field'] == $customCriteria['criteria_field'] && $c['searchtype'] == $customCriteria['criteria_searchtype'];
534 | });
535 | $criteria = reset($criteria);
536 | if (preg_match('/^-\d+MONTH$/', $criteria['value'])
537 | && $customCriteria['criteria_value'] == Customsearchcriteria::CRITERIA_FIRST_DAY_OF_MONTH) {
538 | $normalValue = strtotime($criteria['value']);
539 | $monthYearString = date('F Y', $normalValue);
540 | $newValue = strtotime(
541 | Customsearchcriteria::CRITERIA_FIRST_DAY_OF_MONTH,
542 | strtotime($monthYearString)
543 | );
544 | $criteria['value'] = date('Y-m-d', $newValue) . '00:00:00';
545 | }
546 | if (preg_match('/^-\d+WEEK$/', $criteria['value'])
547 | && $customCriteria['criteria_value'] == Customsearchcriteria::CRITERIA_FIRST_DAY_OF_WEEK) {
548 | // don't need to adjust if its already monday
549 | if ($weekday != 1) {
550 | $normalValue = strtotime($criteria['value']);
551 | $newValue = strtotime(
552 | Customsearchcriteria::CRITERIA_FIRST_DAY_OF_WEEK,
553 | $normalValue
554 | );
555 | $criteria['value'] = date('Y-m-d', $newValue) . '00:00:00';
556 | }
557 | }
558 | }
559 |
560 | $params = Search::manageParams($itemtype, $p, 1, 1);
561 | $name = Dropdown::getDropdownName('glpi_savedsearches', $export->fields['savedsearches_id']);
562 | $name .= "_" . date('Y_m_d_H_i_s') . ".csv";
563 | $titleMail = $name;
564 | $filename = GLPI_PLUGIN_DOC_DIR . "/autoexportsearches/" . $name;
565 | self::createCSVFile(Search::getDatas($itemtype, $params), $filename);
566 | if (!empty($export->fields['sendto'])) {
567 | self::sendMail($titleMail, $export->fields['sendto'], $name, $filename);
568 | }
569 | }
570 | }
571 |
572 | // Cron action
573 |
574 | /**
575 | * @param $name
576 | *
577 | * @return array
578 | */
579 | public static function cronInfo($name)
580 | {
581 | switch ($name) {
582 | case 'AutoexportsearchesExportconfigExport':
583 | return [
584 | 'description' => __('Export saved searches', 'autoexportsearches'),
585 | ]; // Optional
586 | }
587 | return [];
588 | }
589 |
590 | public static function sendMail($title, $recipient, $filename, $filepath)
591 | {
592 | global $CFG_GLPI;
593 |
594 | $mmail = new GLPIMailer();
595 |
596 | $mmail->AddCustomHeader("Auto-Submitted: auto-generated");
597 | // For exchange
598 | $mmail->AddCustomHeader("X-Auto-Response-Suppress: OOF, DR, NDR, RN, NRN");
599 | if (empty($CFG_GLPI["from_email"])) {
600 | $config = new Config();
601 | $results = $config->find(['name' => 'from_email']);
602 |
603 | foreach ($results as $result) {
604 | $mmail->SetFrom($result['value'], $CFG_GLPI["from_email_name"], false);
605 | }
606 | } else {
607 | $mmail->SetFrom($CFG_GLPI["from_email"], $CFG_GLPI["from_email_name"], false);
608 | }
609 |
610 | $text = __('Mail autoexportsearches');
611 |
612 | $mmail->AddAddress($recipient, $recipient);
613 | $mmail->Subject = "[GLPI] " . $title;
614 | $mmail->Body = $text;
615 |
616 | // $mmail->AddEmbeddedImage($filepath,
617 | // 0,
618 | // $filename,
619 | // 'base64',
620 | // 'text/csv');
621 | $mmail->addAttachment(
622 | $filepath,
623 | $filename
624 | );
625 |
626 |
627 | if (!$mmail->Send()) {
628 | Session::addMessageAfterRedirect(
629 | __('Failed to send email to ' . $recipient),
630 | false,
631 | ERROR
632 | );
633 | GLPINetwork::addErrorMessageAfterRedirect();
634 | return false;
635 | } else {
636 | Session::addMessageAfterRedirect(__('Mail send to ' . $recipient));
637 | return true;
638 | }
639 | }
640 |
641 | /**
642 | * Cron action on badges : ExpiredBadges or BadgesWhichExpire
643 | *
644 | * @param $task
645 | *
646 | *
647 | * @return int
648 | */
649 | public static function cronAutoexportsearchesExportconfigExport($task = null)
650 | {
651 | global $DB, $CFG_GLPI;
652 | if (!isset($CFG_GLPI['planning_work_days'])) {
653 | $CFG_GLPI['planning_work_days'] = importArrayFromDB($CFG_GLPI['planning_work_days']);
654 | }
655 |
656 | $cron_status = 0;
657 | $old_memory = ini_set("memory_limit", "-1");
658 | $old_execution = ini_set("max_execution_time", "0");
659 | $dateActual = strtotime(date("Y-m-d"));
660 | $day = date('j'); // 1 to 31, today
661 | $weekday = date('w'); // 0 to 6, today
662 | $month = date('m'); // 01 to 12, current month
663 | $monthLength = date('t'); // 28 to 31, length of the current month
664 | $exportConfig = new Exportconfig();
665 | $exportConfigs = $exportConfig->find([
666 | 'is_deleted' => 0,
667 | 'is_active' => 1,
668 | ]);
669 | $count = 0;
670 | $user_id_back = Session::getLoginUserID();
671 | $user = new User();
672 | foreach ($exportConfigs as $export) {
673 | // check if export has to be done
674 | if ($export['periodicity_type'] == self::PERIODICITY_MINUTES) {
675 | // Frequency in minutes
676 | $dateActual = strtotime(date("Y-m-d H:i:s"));
677 | $delay = 60 * intval($export['periodicity']); // Delay calculation in seconds
678 |
679 | if ($export['last_export'] != null) {
680 | $dateEnd = strtotime($export['last_export']) + $delay;
681 | if ($dateEnd > $dateActual) {
682 | continue;
683 | }
684 | }
685 | } elseif ($export['periodicity_type'] == self::PERIODICITY_HOURS) {
686 | // Periodicity in hours
687 | $dateActual = strtotime(date("Y-m-d H:i:s"));
688 | $delay = 3600 * intval($export['periodicity']); // Delay calculation in seconds
689 | if ($export['last_export'] != null) {
690 | $dateEnd = strtotime($export['last_export']) + $delay;
691 | if ($dateEnd > $dateActual) {
692 | continue;
693 | }
694 | }
695 | } elseif ($export['periodicity_type'] == self::PERIODICITY_DAYS) {
696 | // every worked day
697 | if ($export['periodicity'] == 1 && $export['periodicity_open_days'] == 1) {
698 | if (!in_array($weekday, $CFG_GLPI['planning_work_days'])) {
699 | continue;
700 | }
701 | }
702 | // regular every x days
703 | $delay = DAY_TIMESTAMP * intval($export['periodicity']);
704 | if ($export['last_export'] != null) {
705 | $dateEnd = strtotime($export['last_export']) + $delay;
706 | if ($dateEnd > $dateActual) {
707 | continue;
708 | }
709 | }
710 | } elseif ($export['periodicity_type'] == self::PERIODICITY_WEEKLY) {
711 | if ($weekday != $export['periodicity']) {
712 | continue;
713 | }
714 | } elseif ($export['periodicity_type'] == self::PERIODICITY_MONTHLY) {
715 | if ($export['last_export'] != null) {
716 | $exportMonth = date('m', strtotime($export['last_export']));
717 | // already done for this month
718 | if ($exportMonth == $month) {
719 | continue;
720 | }
721 | // too early in the month,
722 | // second condition for shorter months
723 | if ($day < $export['periodicity']
724 | && $export['periodicity'] <= $monthLength) {
725 | continue;
726 | }
727 | // for shorter month, do the export on the last day of the month if periodicity > duration of the current month
728 | if ($export['periodicity'] > $monthLength
729 | && $day != $monthLength) {
730 | continue;
731 | }
732 | // second condition ensure that it happens at least once a month even if the last day isn't a workday
733 | if ($export['periodicity_open_days'] == 1 && $day != $monthLength) {
734 | // today's not a work day,
735 | if (!in_array($weekday, $CFG_GLPI['planning_work_days'])) {
736 | continue;
737 | }
738 | }
739 | } else {
740 | // for the first export, only done on the exact date or the last day of the month
741 | if ($day != $export['periodicity'] && $export['periodicity'] <= $monthLength) {
742 | continue;
743 | }
744 | if ($export['periodicity'] > $monthLength && $day != $monthLength) {
745 | continue;
746 | }
747 | if ($export['periodicity_open_days'] == 1 && $day != $monthLength) {
748 | if (!in_array($weekday, $CFG_GLPI['planning_work_days'])) {
749 | continue;
750 | }
751 | }
752 | }
753 | }
754 |
755 | $_SESSION["glpicronuserrunning"] = $export['users_id'];
756 | $_SESSION['glpidefault_entity'] = 0;
757 | Session::initEntityProfiles($export['users_id']);
758 | $user = new User();
759 | $user->getFromDB($export['users_id']);
760 | $profile = new Profile();
761 | $savedProfile = $_SESSION['glpiactiveprofile'] ?? 0;
762 | if ($profile->getFromDB($user->fields['profiles_id'])) {
763 | $_SESSION['glpiactiveprofile'] = $profile->fields;
764 | }
765 | $_SESSION['glpiname'] = 'crontab';
766 | $_SESSION['glpiactiveentities'] = getSonsOf('glpi_entities', 0);
767 | $user->getFromDB($export['users_id']);
768 | $auth = new Auth();
769 | $auth->auth_succeded = true;
770 | $auth->user = $user;
771 | Session::init($auth);
772 | Session::loadGroups();
773 | $user = new User();
774 | $user->getFromDB($export['users_id']);
775 | $_SESSION["glpiID"] = $export['users_id'];
776 | $_SESSION["glpicronuserrunning"] = $export['users_id'];
777 | self::executeExport($export['id']);
778 | $_SESSION['glpiactiveprofile'] = $savedProfile;
779 |
780 | // add custom criterias for call to createCriterias
781 | $customSearchCriteria = new Customsearchcriteria();
782 | $customCriterias = $customSearchCriteria->find(['exportconfigs_id' => $export['id']]);
783 | $export['custom_criterias'] = $customCriterias;
784 | if ($export['periodicity_type'] == self::PERIODICITY_MINUTES || $export['periodicity_type'] == self::PERIODICITY_HOURS) {
785 | $export['last_export'] = date("Y-m-d H:i:s");
786 | } else {
787 | $export['last_export'] = date("Y-m-d");
788 | }
789 |
790 | $exportConfig->update($export);
791 | $count++;
792 | }
793 | $user->getFromDB($user_id_back);
794 | $auth = new Auth();
795 | $auth->auth_succeded = true;
796 | $auth->user = $user;
797 | Session::init($auth);
798 | ini_set("memory_limit", $old_memory);
799 | ini_set("max_execution_time", $old_execution);
800 | $task->addVolume($count);
801 |
802 | return true;
803 | }
804 | }
805 |
--------------------------------------------------------------------------------