dolibarr 25.0.0-alpha
ecmfiles.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es>
4 * Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
6 * Copyright (C) 2018 Francis Appels <francis.appels@yahoo.com>
7 * Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
33
38{
42 public $element = 'ecmfiles';
43
47 public $table_element = 'ecm_files';
48
52 public $picto = 'folder-open';
53
58 public $label;
59
63 public $share;
64
68 public $lines = array();
69
73 public $filename;
74
78 public $filepath;
79
83 public $fullpath_orig;
84
88 public $description;
89
93 public $keywords;
94
98 public $content;
99
103 public $cover;
104
108 public $position;
109
113 public $gen_or_uploaded;
114
118 public $extraparams;
119
123 public $date_c = '';
124
128 public $date_m = '';
129
133 public $fk_user_c;
134
138 public $fk_user_m;
139
143 public $acl;
144
148 public $src_object_type;
149
153 public $src_object_id;
154
158 public $agenda_id;
159
163 public $section_id;
164
165 public $fields = array(
166 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
167 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => -1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1, 'comment' => "contains hash from filename+filepath"),
168 'label' => array('type' => 'varchar(128)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => -1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1, 'comment' => "contains hash of file content"),
169 'share' => array('type' => 'varchar(128)', 'label' => 'Share', 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => -1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1, 'comment' => "contains hash for file sharing"),
170 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 50, 'index' => 1),
171 'filepath' => array('type' => 'varchar(255)', 'label' => 'FilePath', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 0, 'searchall' => 0, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "relative to dolibarr document dir. Example module/def"),
172 'filename' => array('type' => 'varchar(255)', 'label' => 'FileName', 'enabled' => 1, 'position' => 70, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "file name only without any directory"),
173 'src_object_type' => array('type' => 'varchar(64)', 'label' => 'SourceType', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'visible' => 0, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "Source object type ('proposal', 'invoice', ...)"),
174 'src_object_id' => array('type' => 'integer', 'label' => 'SourceID', 'default' => '1', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'position' => 90, 'index' => 1, 'comment' => "Source object id"),
175 'fullpath_orig' => array('type' => 'varchar(750)', 'label' => 'FullPathOrig', 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => 0, 'searchall' => 0, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "full path of original filename, when file is uploaded from a local computer"),
176 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'visible' => 0, 'position' => 110),
177 'keywords' => array('type' => 'varchar(750)', 'label' => 'Keywords', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "list of keywords, separated with comma. Must be limited to most important keywords."),
178 'content' => array('type' => 'html', 'label' => 'Content', 'enabled' => 'getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")', 'position' => 120, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'csslist' => 'tdoverflowmax200', 'help' => "Text content of file", 'showoncombobox' => 2, 'validate' => 1,'comment' => "Text content if option to store txt content was set."),
179 'cover' => array('type' => 'text', 'label' => 'Cover', 'enabled' => 1, 'visible' => 0, 'position' => 130, 'comment' => "is this file a file to use for a cover"),
180 'position' => array('type' => 'integer', 'label' => 'Position', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 140, 'index' => 1, 'comment' => "position of file among others"),
181 'gen_or_uploaded' => array('type' => 'varchar(12)', 'label' => 'GenOrUpload', 'enabled' => 1, 'position' => 150, 'notnull' => 0, 'visible' => -1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1,'comment' => "'generated' or 'uploaded'"),
182 'extraparams' => array('type' => 'varchar(255)', 'label' => 'ExtraParams', 'enabled' => 1, 'position' => 160, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'showoncombobox' => 2, 'validate' => 1, 'comment' => "for stocking other parameters with json format"),
183 'date_c' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
184 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
185 'fk_user_c' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid',),
186 'fk_user_m' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
187 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
188 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
189 'acl' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160, 'comment' => "for future permission 'per file'"),
190 'agenda_id' => array('type' => 'integer', 'label' => 'IdAgenda', 'enabled' => 1, 'visible' => 0, 'position' => 180, 'comment' => "Link to an actioncomm"),
191 );
192
193
199 public function __construct(DoliDB $db)
200 {
201 $this->db = $db;
202 }
203
211 public function create(User $user, $notrigger = 0)
212 {
213 global $conf;
214
215 dol_syslog(__METHOD__, LOG_DEBUG);
216
217 $error = 0;
218
219 // Clean parameters
220 if (isset($this->ref)) {
221 $this->ref = trim($this->ref);
222 }
223 if (isset($this->label)) {
224 $this->label = trim($this->label);
225 }
226 if (isset($this->share)) {
227 $this->share = trim($this->share);
228 }
229 if (isset($this->entity)) {
230 $this->entity = (int) $this->entity;
231 }
232 if (isset($this->filename)) {
233 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
234 }
235 if (isset($this->filepath)) {
236 $this->filepath = trim($this->filepath);
237 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
238 }
239 if (isset($this->fullpath_orig)) {
240 $this->fullpath_orig = trim($this->fullpath_orig);
241 }
242 if (isset($this->description)) {
243 $this->description = trim($this->description);
244 }
245 if (isset($this->keywords)) {
246 $this->keywords = trim($this->keywords);
247 }
248 if (isset($this->cover)) {
249 $this->cover = trim($this->cover);
250 }
251 if (isset($this->gen_or_uploaded)) {
252 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
253 }
254 if (isset($this->fk_user_c)) {
255 $this->fk_user_c = (int) $this->fk_user_c;
256 }
257 if (isset($this->fk_user_m)) {
258 $this->fk_user_m = (int) $this->fk_user_m;
259 }
260 if (isset($this->acl)) {
261 $this->acl = trim($this->acl);
262 }
263 if (isset($this->src_object_type)) {
264 $this->src_object_type = trim($this->src_object_type);
265 }
266 if (empty($this->date_c)) {
267 $this->date_c = dol_now();
268 }
269 if (empty($this->date_m)) {
270 $this->date_m = dol_now();
271 }
272
273 // If ref not defined
274 if (empty($this->ref)) {
275 include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
276 $this->ref = dol_hash($this->filepath.'/'.$this->filename, '3');
277 }
278
279 $maxposition = 0;
280 if (empty($this->position)) {
281 // Get max used
282 $sql = "SELECT MAX(position) as maxposition FROM ".MAIN_DB_PREFIX.$this->table_element;
283 $sql .= " WHERE filepath ='".$this->db->escape($this->filepath)."'";
284
285 $resql = $this->db->query($sql);
286 if ($resql) {
287 $obj = $this->db->fetch_object($resql);
288 $maxposition = (int) $obj->maxposition;
289 } else {
290 $this->errors[] = 'Error '.$this->db->lasterror();
291 return --$error;
292 }
293 $maxposition += 1;
294 } else {
295 $maxposition = $this->position;
296 }
297
298 // Check parameters
299 if (empty($this->filename) || empty($this->filepath)) {
300 $this->errors[] = 'Bad property filename or filepath';
301 return --$error;
302 }
303 if (!isset($this->entity)) {
304 $this->entity = $conf->entity;
305 }
306
307 $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null);
308 $extraparams = dol_trunc($extraparams, 250);
309
310 // Put here code to add control on parameters values
311 if (!empty($this->agenda_id)) {
312 $this->agenda_id = (int) $this->agenda_id;
313 }
314
315 // Insert request
316 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
317 $sql .= 'ref,';
318 $sql .= 'label,';
319 $sql .= 'share,';
320 $sql .= 'entity,';
321 $sql .= 'filename,';
322 $sql .= 'filepath,';
323 $sql .= 'fullpath_orig,';
324 $sql .= 'description,';
325 $sql .= 'keywords,';
326 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
327 $sql .= 'content,';
328 }
329 $sql .= 'cover,';
330 $sql .= 'position,';
331 $sql .= 'gen_or_uploaded,';
332 $sql .= 'extraparams,';
333 $sql .= 'date_c,';
334 $sql .= 'tms,';
335 $sql .= 'fk_user_c,';
336 $sql .= 'fk_user_m,';
337 $sql .= 'acl,';
338 $sql .= 'src_object_type,';
339 $sql .= 'src_object_id,';
340 $sql .= 'agenda_id';
341 $sql .= ') VALUES (';
342 $sql .= " '".$this->db->escape($this->ref)."', ";
343 $sql .= ' '.(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").',';
344 $sql .= ' '.(!isset($this->share) ? 'NULL' : "'".$this->db->escape($this->share)."'").',';
345 $sql .= ' '.((int) $this->entity).',';
346 $sql .= ' '.(!isset($this->filename) ? 'NULL' : "'".$this->db->escape($this->filename)."'").',';
347 $sql .= ' '.(!isset($this->filepath) ? 'NULL' : "'".$this->db->escape($this->filepath)."'").',';
348 $sql .= ' '.(!isset($this->fullpath_orig) ? 'NULL' : "'".$this->db->escape($this->fullpath_orig)."'").',';
349 $sql .= ' '.(!isset($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").',';
350 $sql .= ' '.(!isset($this->keywords) ? 'NULL' : "'".$this->db->escape($this->keywords)."'").',';
351 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
352 $sql .= ' '.(!isset($this->content) ? 'NULL' : "'".$this->db->escape($this->content)."'").',';
353 }
354 $sql .= ' '.(!isset($this->cover) ? 'NULL' : "'".$this->db->escape($this->cover)."'").',';
355 $sql .= ' '.((int) $maxposition).',';
356 $sql .= ' '.(!isset($this->gen_or_uploaded) ? 'NULL' : "'".$this->db->escape($this->gen_or_uploaded)."'").',';
357 $sql .= ' '.(!isset($extraparams) ? 'NULL' : "'".$this->db->escape($extraparams)."'").',';
358 $sql .= " '".$this->db->idate($this->date_c)."',";
359 $sql .= ' '.(!isset($this->date_m) || dol_strlen((string) $this->date_m) == 0 ? 'NULL' : "'".$this->db->idate($this->date_m)."'").',';
360 $sql .= ' '.(!isset($this->fk_user_c) ? ((int) $user->id) : ((int) $this->fk_user_c)).',';
361 $sql .= ' '.(!isset($this->fk_user_m) ? 'NULL' : ((int) $this->fk_user_m)).',';
362 $sql .= ' '.(!isset($this->acl) ? 'NULL' : "'".$this->db->escape($this->acl)."'").',';
363 $sql .= ' '.(!isset($this->src_object_type) ? 'NULL' : "'".$this->db->escape($this->src_object_type)."'").',';
364 $sql .= ' '.(!isset($this->src_object_id) ? 'NULL' : ((int) $this->src_object_id)).',';
365 $sql .= ' '.(empty($this->agenda_id) ? 'NULL' : ((int) $this->agenda_id));
366 $sql .= ')';
367
368 $this->db->begin();
369
370 $resql = $this->db->query($sql);
371 if (!$resql) {
372 $error++;
373 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
374 $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror();
375 } else {
376 $this->errors[] = 'Error '.$this->db->lasterror();
377 }
378 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
379 }
380
381 if (!$error) {
382 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
383 $this->position = $maxposition;
384
385 // Triggers
386 if (!$notrigger) {
387 // Call triggers
388 $result = $this->call_trigger(strtoupper(get_class($this)).'_CREATE', $user);
389 if ($result < 0) {
390 $error++;
391 }
392 // End call triggers
393 }
394 }
395
396 // Commit or rollback
397 if ($error) {
398 $this->db->rollback();
399
400 return -1 * $error;
401 } else {
402 $this->db->commit();
403
404 return $this->id;
405 }
406 }
407
421 public function fetch($id, $ref = '', $relativepath = '', $hashoffile = '', $hashforshare = '', $src_object_type = '', $src_object_id = 0, $entity = null)
422 {
423 global $conf;
424
425 dol_syslog(__METHOD__, LOG_DEBUG);
426
427 $sql = 'SELECT';
428 $sql .= ' t.rowid,';
429 $sql .= " t.ref,";
430 $sql .= " t.label,";
431 $sql .= " t.share,";
432 $sql .= " t.entity,";
433 $sql .= " t.filename,";
434 $sql .= " t.filepath,";
435 $sql .= " t.fullpath_orig,";
436 $sql .= " t.description,";
437 $sql .= " t.keywords,";
438 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
439 $sql .= " t.content,";
440 }
441 $sql .= " t.cover,";
442 $sql .= " t.position,";
443 $sql .= " t.gen_or_uploaded,";
444 $sql .= " t.extraparams,";
445 $sql .= " t.date_c,";
446 $sql .= " t.tms as date_m,";
447 $sql .= " t.fk_user_c,";
448 $sql .= " t.fk_user_m,";
449 $sql .= ' t.note_private,';
450 $sql .= ' t.note_public,';
451 $sql .= " t.acl,";
452 $sql .= " t.src_object_type,";
453 $sql .= " t.src_object_id,";
454 $sql .= " t.agenda_id";
455 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
456 $sql .= ' WHERE 1 = 1';
457 /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
458 if (isModEnabled('multicompany')) {
459 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
460 }*/
461 $filterfound = 0;
462 if ($relativepath) {
463 $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
464 $sql .= " AND t.filepath = '".$this->db->escape(dirname($relativepath))."'";
465 $filename = basename($relativepathwithnoexe);
466 if ($filename != '*') {
467 $sql .= " AND t.filename = '".$this->db->escape($filename)."'";
468 }
469 if (isset($entity)) {
470 $sql .= " AND t.entity = " . (int) $entity;
471 } else {
472 $sql .= " AND t.entity = " . ((int) $conf->entity); // unique key include the entity so each company has its own index
473 }
474 $filterfound++;
475 }
476 if (!empty($ref)) { // hash of file path
477 $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
478 if (isset($entity)) {
479 $sql .= " AND t.entity = " . (int) $entity;
480 } else {
481 $sql .= " AND t.entity = " . ((int) $conf->entity); // unique key include the entity so each company has its own index
482 }
483 $filterfound++;
484 }
485 if (!empty($hashoffile)) { // hash of content
486 $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'";
487 if (isset($entity)) {
488 $sql .= " AND t.entity = " . (int) $entity;
489 } else {
490 $sql .= " AND t.entity = " . ((int) $conf->entity); // unique key include the entity so each company has its own index
491 }
492 $filterfound++;
493 }
494 if (!empty($hashforshare)) {
495 if ($hashforshare != 'shared') {
496 $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'";
497 } else {
498 $sql .= " AND t.share IS NOT NULL AND t.share <> ''";
499 }
500 //$sql .= " AND t.entity = ".((int) $conf->entity); // hashforshare already unique
501 $filterfound++;
502 }
503 if ($src_object_type && $src_object_id) {
504 $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id);
505 if (isset($entity)) {
506 $sql .= " AND t.entity = " . (int) $entity;
507 } else {
508 $sql .= " AND t.entity = " . ((int) $conf->entity); // unique key include the entity so each company has its own index
509 }
510 $filterfound++;
511 }
512 if ($id > 0 || empty($filterfound)) {
513 $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique
514 }
515
516 // Warning: May return several record, and only first one is returned !
517 $this->db->plimit(1); // When we search on src, or on hash of content (hashforfile), we take first one only
518 $this->db->order('t.rowid', 'ASC');
519
520 $resql = $this->db->query($sql);
521 if ($resql) {
522 $numrows = $this->db->num_rows($resql);
523 if ($numrows) {
524 $obj = $this->db->fetch_object($resql);
525
526 $this->id = $obj->rowid;
527 $this->ref = $obj->ref;
528 $this->label = $obj->label;
529 $this->share = $obj->share;
530 $this->entity = $obj->entity;
531 $this->filename = $obj->filename;
532 $this->filepath = $obj->filepath;
533 $this->fullpath_orig = $obj->fullpath_orig;
534 $this->description = $obj->description;
535 $this->keywords = $obj->keywords;
536 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
537 $this->content = $obj->content;
538 }
539 $this->cover = $obj->cover;
540 $this->position = $obj->position;
541 $this->gen_or_uploaded = $obj->gen_or_uploaded;
542 $this->date_c = $this->db->jdate($obj->date_c);
543 $this->date_m = $this->db->jdate($obj->date_m);
544 $this->fk_user_c = $obj->fk_user_c;
545 $this->fk_user_m = $obj->fk_user_m;
546 $this->note_private = $obj->note_private;
547 $this->note_public = $obj->note_public;
548 $this->acl = $obj->acl;
549 $this->src_object_type = $obj->src_object_type;
550 $this->src_object_id = $obj->src_object_id;
551 $this->agenda_id = $obj->agenda_id;
552 $this->extraparams = (isset($obj->extraparams) ? (array) json_decode($obj->extraparams, true) : null);
553 }
554
555 // Retrieve all extrafields for ecm_files
556 // fetch optionals attributes and labels
557 $this->fetch_optionals();
558
559 // $this->fetch_lines();
560
561 $this->db->free($resql);
562
563 if ($numrows) {
564 return 1;
565 } else {
566 return 0;
567 }
568 } else {
569 $this->errors[] = 'Error '.$this->db->lasterror();
570 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
571
572 return -1;
573 }
574 }
575
587 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
588 {
589 dol_syslog(__METHOD__, LOG_DEBUG);
590
591 $sql = 'SELECT';
592 $sql .= ' t.rowid,';
593 $sql .= " t.label,";
594 $sql .= " t.share,";
595 $sql .= " t.entity,";
596 $sql .= " t.filename,";
597 $sql .= " t.filepath,";
598 $sql .= " t.fullpath_orig,";
599 $sql .= " t.description,";
600 $sql .= " t.keywords,";
601 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
602 $sql .= " t.content,";
603 }
604 $sql .= " t.cover,";
605 $sql .= " t.position,";
606 $sql .= " t.gen_or_uploaded,";
607 $sql .= " t.extraparams,";
608 $sql .= " t.date_c,";
609 $sql .= " t.tms as date_m,";
610 $sql .= " t.fk_user_c,";
611 $sql .= " t.fk_user_m,";
612 $sql .= " t.acl,";
613 $sql .= " t.src_object_type,";
614 $sql .= " t.src_object_id,";
615 $sql .= " t.agenda_id";
616 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
617 $sql .= ' WHERE 1 = 1';
618
619 // Manage filter
620 if (is_array($filter)) {
621 $sqlwhere = array();
622 if (count($filter) > 0) {
623 foreach ($filter as $key => $value) {
624 if ($key == 't.src_object_id') {
625 $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value);
626 } else {
627 $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
628 }
629 }
630 }
631 if (count($sqlwhere) > 0) {
632 $sql .= ' AND '.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere);
633 }
634
635 $filter = '';
636 }
637
638 // Manage filter
639 $errormessage = '';
640 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
641 if ($errormessage) {
642 $this->errors[] = $errormessage;
643 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
644 return -1;
645 }
646
647 /* Fetching this table depends on filepath+filename, it must not depends on entity
648 if (isModEnabled('multicompany')) {
649 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
650 }*/
651 if (!empty($sortfield)) {
652 $sql .= $this->db->order($sortfield, $sortorder);
653 }
654 if (!empty($limit)) {
655 $sql .= $this->db->plimit($limit, $offset);
656 }
657
658 $this->lines = array();
659
660 $resql = $this->db->query($sql);
661 if ($resql) {
662 $num = $this->db->num_rows($resql);
663
664 while ($obj = $this->db->fetch_object($resql)) {
665 $line = new EcmFilesLine($this->db);
666
667 $line->id = $obj->rowid;
668 $line->ref = $obj->rowid;
669 $line->label = $obj->label;
670 $line->share = $obj->share;
671 $line->entity = $obj->entity;
672 $line->filename = $obj->filename;
673 $line->filepath = $obj->filepath;
674 $line->fullpath_orig = $obj->fullpath_orig;
675 $line->description = $obj->description;
676 $line->keywords = $obj->keywords;
677 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
678 $line->content = $obj->content;
679 }
680 $line->cover = $obj->cover;
681 $line->position = $obj->position;
682 $line->gen_or_uploaded = $obj->gen_or_uploaded;
683 $line->extraparams = $obj->extraparams;
684 $line->date_c = $this->db->jdate($obj->date_c);
685 $line->date_m = $this->db->jdate($obj->date_m);
686 $line->fk_user_c = $obj->fk_user_c;
687 $line->fk_user_m = $obj->fk_user_m;
688 $line->acl = $obj->acl;
689 $line->src_object_type = $obj->src_object_type;
690 $line->src_object_id = $obj->src_object_id;
691 $line->agenda_id = $obj->agenda_id;
692
693 $line->fetch_optionals();
694
695 $this->lines[] = $line;
696 }
697 $this->db->free($resql);
698
699 return $num;
700 } else {
701 $this->errors[] = 'Error '.$this->db->lasterror();
702 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
703
704 return -1;
705 }
706 }
707
715 public function update(User $user, $notrigger = 0)
716 {
717 global $conf;
718
719 $error = 0;
720
721 dol_syslog(__METHOD__, LOG_DEBUG);
722
723 // Clean parameters
724
725 if (isset($this->ref)) {
726 $this->ref = trim($this->ref);
727 }
728 if (isset($this->label)) {
729 $this->label = trim($this->label);
730 }
731 if (isset($this->share)) {
732 $this->share = trim($this->share);
733 }
734 if (isset($this->entity)) {
735 $this->entity = (int) $this->entity;
736 }
737 if (isset($this->filename)) {
738 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
739 }
740 if (isset($this->filepath)) {
741 $this->filepath = trim($this->filepath);
742 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
743 }
744 if (isset($this->fullpath_orig)) {
745 $this->fullpath_orig = trim($this->fullpath_orig);
746 }
747 if (isset($this->description)) {
748 $this->description = trim($this->description);
749 }
750 if (isset($this->keywords)) {
751 $this->keywords = trim($this->keywords);
752 }
753 if (isset($this->cover)) {
754 $this->cover = trim($this->cover);
755 }
756 if (isset($this->gen_or_uploaded)) {
757 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
758 }
759 if (isset($this->fk_user_m)) {
760 $this->fk_user_m = (int) $this->fk_user_m;
761 }
762 if (isset($this->acl)) {
763 $this->acl = trim($this->acl);
764 }
765 if (isset($this->src_object_type)) {
766 $this->src_object_type = trim($this->src_object_type);
767 }
768 if (!empty($this->agenda_id)) {
769 $this->agenda_id = (int) $this->agenda_id;
770 }
771 $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null);
772 $extraparams = dol_trunc($extraparams, 250);
773
774 // Update request
775 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
776 $sql .= " ref = '".$this->db->escape(dol_hash($this->filepath."/".$this->filename, '3'))."',";
777 $sql .= ' label = '.(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").',';
778 $sql .= ' share = '.(!empty($this->share) ? "'".$this->db->escape($this->share)."'" : "null").',';
779 $sql .= ' entity = '.(isset($this->entity) ? ((int) $this->entity) : ((int) $conf->entity)).',';
780 $sql .= ' filename = '.(isset($this->filename) ? "'".$this->db->escape($this->filename)."'" : "null").',';
781 $sql .= ' filepath = '.(isset($this->filepath) ? "'".$this->db->escape($this->filepath)."'" : "null").',';
782 $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig) ? "'".$this->db->escape($this->fullpath_orig)."'" : "null").',';
783 $sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
784 $sql .= ' keywords = '.(isset($this->keywords) ? "'".$this->db->escape($this->keywords)."'" : "null").',';
785 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
786 $sql .= ' content = '.(isset($this->content) ? "'".$this->db->escape($this->content)."'" : "null").',';
787 }
788 $sql .= ' cover = '.(isset($this->cover) ? "'".$this->db->escape($this->cover)."'" : "null").',';
789 $sql .= ' position = '.(isset($this->position) ? $this->db->escape((string) $this->position) : "0").',';
790 $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded) ? "'".$this->db->escape($this->gen_or_uploaded)."'" : "null").',';
791 $sql .= ' extraparams = '.(isset($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null").',';
792 $sql .= ' date_c = '.(!isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').',';
793 //$sql .= ' tms = '.(! isset($this->date_m) || dol_strlen((string) $this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated
794 $sql .= ' fk_user_m = '.($this->fk_user_m > 0 ? ((int) $this->fk_user_m) : ((int) $user->id)).',';
795 $sql .= ' acl = '.(isset($this->acl) ? "'".$this->db->escape($this->acl)."'" : "null").',';
796 $sql .= ' src_object_id = '.($this->src_object_id > 0 ? ((int) $this->src_object_id) : "null").',';
797 $sql .= ' src_object_type = '.(isset($this->src_object_type) ? "'".$this->db->escape($this->src_object_type)."'" : "null").',';
798 $sql .= ' agenda_id = '.($this->agenda_id > 0 ? ((int) $this->agenda_id) : "null");
799 $sql .= ' WHERE rowid='.((int) $this->id);
800 $this->db->begin();
801
802 $resql = $this->db->query($sql);
803 if (!$resql) {
804 $error++;
805 $this->errors[] = 'Error '.$this->db->lasterror();
806 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
807 }
808
809 if (!$error) {
810 // Update extrafields
811 $result = $this->insertExtraFields();
812 if ($result < 0) {
813 $error++;
814 }
815 }
816
817 // Triggers
818 if (!$error && !$notrigger) {
819 // Call triggers
820 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user);
821 if ($result < 0) {
822 $error++;
823 } //Do also here what you must do to rollback action if trigger fail
824 // End call triggers
825 }
826
827 // Commit or rollback
828 if ($error) {
829 $this->db->rollback();
830
831 return -1 * $error;
832 } else {
833 $this->db->commit();
834
835 return 1;
836 }
837 }
838
846 public function delete(User $user, $notrigger = 0)
847 {
848 dol_syslog(__METHOD__, LOG_DEBUG);
849
850 $error = 0;
851
852 $this->db->begin();
853
854 // Triggers
855 if (!$notrigger) {
856 // Call triggers
857 $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user);
858 if ($result < 0) {
859 $error++;
860 } //Do also here what you must do to rollback action if trigger fail
861 // End call triggers
862 }
863
864 // If you need to delete child tables to, you can insert them here
865 if (!$error) {
866 $result = $this->deleteExtraFields();
867 if (!$result) {
868 dol_syslog(get_class($this)."::delete error ".$this->error, LOG_ERR);
869 $error++;
870 }
871 }
872 if (!$error) {
873 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
874 $sql .= ' WHERE rowid='.((int) $this->id);
875
876 $resql = $this->db->query($sql);
877 if (!$resql) {
878 $error++;
879 $this->errors[] = 'Error '.$this->db->lasterror();
880 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
881 }
882 }
883
884 // Commit or rollback
885 if ($error) {
886 $this->db->rollback();
887
888 return -1 * $error;
889 } else {
890 $this->db->commit();
891
892 return 1;
893 }
894 }
895
903 public function createFromClone(User $user, $fromid)
904 {
905 dol_syslog(__METHOD__, LOG_DEBUG);
906
907 $error = 0;
908 $object = new EcmFiles($this->db);
909
910 $this->db->begin();
911
912 // Load source object
913 $object->fetch($fromid);
914 // Reset object
915 $object->id = 0;
916
917 // Clear fields
918 // ...
919
920 // Create clone
921 $object->context['createfromclone'] = 'createfromclone';
922 $result = $object->create($user);
923
924 // Other options
925 if ($result < 0) {
926 $error++;
927 $this->errors = $object->errors;
928 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
929 }
930
931 unset($object->context['createfromclone']);
932
933 // End
934 if (!$error) {
935 $this->db->commit();
936
937 return $object->id;
938 } else {
939 $this->db->rollback();
940
941 return -1;
942 }
943 }
944
952 public function updateAfterRename($olddir, $newdir)
953 {
954 $sql = 'UPDATE '.MAIN_DB_PREFIX.'ecm_files SET';
955 $sql .= ' filepath = "'.$this->db->escape($newdir).'"';
956 //$sql .= ', fullpath_orig = "'.$dbs->escape($newdir)."'";
957 $sql .= ' WHERE ';
958 $sql .= ' filepath = "'.$this->db->escape($olddir).'"';
959 // $sql .= ' AND fullpath_orig = "'.$dbs->escape($olddir).'"';
960
961 $this->db->query($sql);
962 }
963
971 public function getTooltipContentArray($params)
972 {
973 global $langs;
974
975 $langs->load('ecm');
976 $datas = [];
977 $nofetch = !empty($params['nofetch']);
978
979 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
980 return ['optimize' => $langs->trans("ShowFile")];
981 }
982 $datas['picto'] = img_picto('', $this->picto, '', 0, 0, 0, '', 'paddingrightonly') . '<u>' . $langs->trans("File") . '</u>';
983 if (!empty($this->filename)) {
984 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.basename($this->filename);
985 }
986 if (!empty($this->ref)) {
987 $datas['ref'] = '<br><b>'.$langs->trans('HashOfFileContent').':</b> '.$this->ref;
988 }
989 if (!empty($this->share)) {
990 $datas['share'] = '<br>'.$langs->trans("FileSharedViaALink");
991 } else {
992 $datas['share'] = '<br>'.$langs->trans("FileNotShared");
993 }
994 if (!empty($this->gen_or_uploaded)) {
995 $datas['gen_or_upload'] = '<br><b>'.$langs->trans('GenOrUpload').':</b> '.$this->gen_or_uploaded;
996 }
997 if (!empty($this->content)) {
998 $datas['content'] = '<br>'.$langs->trans('FileHasAnIndexedTextContent');
999 }
1000
1001 return $datas;
1002 }
1003
1014 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
1015 {
1016 global $conf, $hookmanager, $langs;
1017
1018 if (!empty($conf->dol_no_mouse_hover)) {
1019 $notooltip = 1; // Force disable tooltips
1020 }
1021
1022 $result = '';
1023
1024 $params = [
1025 'id' => $this->id,
1026 'objecttype' => $this->element,
1027 'option' => $option,
1028 'nofetch' => 1,
1029 ];
1030 $classfortooltip = 'classfortooltip';
1031 $dataparams = '';
1032 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1033 $classfortooltip = 'classforajaxtooltip';
1034 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1035 $label = '';
1036 } else {
1037 $label = implode($this->getTooltipContentArray($params));
1038 }
1039
1040 if ($option) {
1041 if ($option == 'facture_fournisseur') {
1042 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/facture\//', '', $this->filepath);
1043 } elseif ($option == 'commande_fournisseur') {
1044 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/commande\//', '', $this->filepath);
1045 } elseif ($option == 'tax-vat') { // Remove part "tax/vat/"
1046 $tmppath = preg_replace('/^(\d+\/)?tax\/vat\//', '', $this->filepath);
1047 } elseif ($option == 'remisecheque') { // Remove part "tax/vat/"
1048 $tmppath = preg_replace('/^bank\/checkdeposits\//', '', $this->filepath);
1049 } else {
1050 if ((int) $this->entity > 1) {
1051 // Remove the part "entityid/commande/" into "entityid/commande/REFXXX" to get only the ref
1052 $tmppath = preg_replace('/^\d+\/[^\/]+\//', '', $this->filepath);
1053 } else {
1054 // Remove the part "commande/" into "commande/REFXXX" to get only the ref
1055 $tmppath = preg_replace('/^[^\/]+\//', '', $this->filepath);
1056 }
1057 }
1058 $url = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($option).'&file='.urlencode($tmppath.'/'.$this->filename).'&entity='.((int) $this->entity);
1059 } else {
1060 $url = DOL_URL_ROOT.'/ecm/file_card.php?id='.$this->id;
1061 }
1062
1063 $linkclose = '';
1064 if (empty($notooltip)) {
1065 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1066 $label = $langs->trans("ShowFile");
1067 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1068 }
1069 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1070 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.($morecss ? ' '.$morecss : '').'"';
1071 } else {
1072 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1073 }
1074
1075 $linkstart = '<a href="'.$url.'"';
1076 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1077 $linkstart .= 'target="_blank" ';
1078 }
1079 $linkstart .= $linkclose.'>';
1080 $linkend = '</a>';
1081
1082 if ($withpicto) {
1083 if (empty($this->filename)) {
1084 $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="paddingright"')).$linkend);
1085 } else {
1086 $result .= ($linkstart.img_mime($this->filename, ($notooltip ? '' : dol_escape_htmltag($label, 1)), ($notooltip ? '' : ' paddingright')).$linkend);
1087 }
1088 }
1089 $result .= $linkstart.$this->filename.$linkend;
1090
1091 global $action;
1092 $hookmanager->initHooks(array($this->element . 'dao'));
1093 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1094 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1095 if ($reshook > 0) {
1096 $result = $hookmanager->resPrint;
1097 } else {
1098 $result .= $hookmanager->resPrint;
1099 }
1100
1101 return $result;
1102 }
1103
1110 public function getLibStatut($mode = 0)
1111 {
1112 return $this->LibStatut($this->status, $mode);
1113 }
1114
1115 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1123 public static function LibStatut($status, $mode = 0)
1124 {
1125 // phpcs:enable
1126 global $langs;
1127 return '';
1128 }
1129
1130
1137 public function initAsSpecimen()
1138 {
1139 global $conf, $user;
1140
1141 $this->id = 0;
1142 $this->specimen = 1;
1143 $this->label = '0a1b2c3e4f59999999';
1144 $this->entity = 1;
1145 $this->filename = 'myspecimenfilefile.pdf';
1146 $this->filepath = '/aaa/bbb';
1147 $this->fullpath_orig = 'c:/file on my disk.pdf';
1148 $this->description = 'This is a description of the file';
1149 $this->keywords = 'key1,key2';
1150 $this->content = 'This is the text content of the file';
1151 $this->cover = '1';
1152 $this->position = 5;
1153 $this->gen_or_uploaded = 'uploaded';
1154 $this->extraparams = '';
1155 $this->date_c = (dol_now() - 3600 * 24 * 10);
1156 $this->date_m = '';
1157 $this->fk_user_c = $user->id;
1158 $this->fk_user_m = $user->id;
1159 $this->acl = '';
1160 $this->src_object_type = 'product';
1161 $this->src_object_id = 1;
1162
1163 return 1;
1164 }
1165}
1166
1167
1172{
1176 public $label;
1177
1181 public $entity;
1182
1186 public $table_element = 'ecm_files';
1187
1191 public $filename;
1195 public $filepath;
1199 public $fullpath_orig;
1200
1204 public $description;
1205
1209 public $keywords;
1210
1214 public $content;
1215
1219 public $cover;
1223 public $position;
1227 public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown'
1231 public $extraparams;
1235 public $date_c = '';
1239 public $date_m = '';
1240
1244 public $fk_user_c;
1245
1249 public $fk_user_m;
1250
1254 public $acl;
1258 public $src_object_type;
1262 public $src_object_id;
1266 public $agenda_id;
1270 public $share;
1271}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
print $object position
Definition edit.php:206
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage ECM files.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
getTooltipContentArray($params)
getTooltipContentArray
getLibStatut($mode=0)
Return the label of the status.
createFromClone(User $user, $fromid)
Load an object from its id and create a new one in database.
update(User $user, $notrigger=0)
Update object into database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='')
Return a link to the object card (with optionally the picto)
fetch($id, $ref='', $relativepath='', $hashoffile='', $hashforshare='', $src_object_type='', $src_object_id=0, $entity=null)
Load object in memory from the database.
__construct(DoliDB $db)
Constructor.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load object in memory from the database.
static LibStatut($status, $mode=0)
Return the status.
updateAfterRename($olddir, $newdir)
updateAfterRename update entries in ecmfiles if exist to avoid losing info
create(User $user, $notrigger=0)
Create object into database.
Class of an index line of a document.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.