dolibarr 22.0.5
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-2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2025 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
57 public $ref;
58
63 public $label;
64
68 public $share;
69
73 public $entity;
74
78 public $filename;
79
83 public $filepath;
84
88 public $fullpath_orig;
89
93 public $description;
94
98 public $keywords;
99
103 public $content;
104
108 public $cover;
109
113 public $position;
114
118 public $gen_or_uploaded;
119
123 public $extraparams;
124
128 public $date_c = '';
129
133 public $date_m = '';
134
138 public $fk_user_c;
139
143 public $fk_user_m;
144
148 public $acl;
149
153 public $src_object_type;
154
158 public $src_object_id;
159
163 public $agenda_id;
164
168 public $section_id;
169
170 public $fields = array(
171 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
172 '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"),
173 '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"),
174 '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"),
175 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 50, 'index' => 1),
176 '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"),
177 '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"),
178 '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', ...)"),
179 'src_object_id' => array('type' => 'integer', 'label' => 'SourceID', 'default' => '1', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'position' => 90, 'index' => 1, 'comment' => "Source object id"),
180 '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"),
181 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'visible' => 0, 'position' => 110),
182 '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."),
183 '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."),
184 'cover' => array('type' => 'text', 'label' => 'Cover', 'enabled' => 1, 'visible' => 0, 'position' => 130, 'comment' => "is this file a file to use for a cover"),
185 'position' => array('type' => 'integer', 'label' => 'Position', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 140, 'index' => 1, 'comment' => "position of file among others"),
186 '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'"),
187 '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"),
188 'date_c' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
189 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
190 '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',),
191 'fk_user_m' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
192 'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
193 'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
194 'acl' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160, 'comment' => "for future permission 'per file'"),
195 'agenda_id' => array('type' => 'integer', 'label' => 'IdAgenda', 'enabled' => 1, 'visible' => 0, 'position' => 180, 'comment' => "Link to an actioncomm"),
196 );
197
198
204 public function __construct(DoliDB $db)
205 {
206 $this->db = $db;
207 }
208
216 public function create(User $user, $notrigger = 0)
217 {
218 global $conf;
219
220 dol_syslog(__METHOD__, LOG_DEBUG);
221
222 $error = 0;
223
224 // Clean parameters
225 if (isset($this->ref)) {
226 $this->ref = trim($this->ref);
227 }
228 if (isset($this->label)) {
229 $this->label = trim($this->label);
230 }
231 if (isset($this->share)) {
232 $this->share = trim($this->share);
233 }
234 if (isset($this->entity)) {
235 $this->entity = (int) $this->entity;
236 }
237 if (isset($this->filename)) {
238 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
239 }
240 if (isset($this->filepath)) {
241 $this->filepath = trim($this->filepath);
242 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
243 }
244 if (isset($this->fullpath_orig)) {
245 $this->fullpath_orig = trim($this->fullpath_orig);
246 }
247 if (isset($this->description)) {
248 $this->description = trim($this->description);
249 }
250 if (isset($this->keywords)) {
251 $this->keywords = trim($this->keywords);
252 }
253 if (isset($this->cover)) {
254 $this->cover = trim($this->cover);
255 }
256 if (isset($this->gen_or_uploaded)) {
257 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
258 }
259 if (isset($this->fk_user_c)) {
260 $this->fk_user_c = (int) $this->fk_user_c;
261 }
262 if (isset($this->fk_user_m)) {
263 $this->fk_user_m = (int) $this->fk_user_m;
264 }
265 if (isset($this->acl)) {
266 $this->acl = trim($this->acl);
267 }
268 if (isset($this->src_object_type)) {
269 $this->src_object_type = trim($this->src_object_type);
270 }
271 if (empty($this->date_c)) {
272 $this->date_c = dol_now();
273 }
274 if (empty($this->date_m)) {
275 $this->date_m = dol_now();
276 }
277
278 // If ref not defined
279 if (empty($this->ref)) {
280 include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
281 $this->ref = dol_hash($this->filepath.'/'.$this->filename, '3');
282 }
283
284 $maxposition = 0;
285 if (empty($this->position)) {
286 // Get max used
287 $sql = "SELECT MAX(position) as maxposition FROM ".MAIN_DB_PREFIX.$this->table_element;
288 $sql .= " WHERE filepath ='".$this->db->escape($this->filepath)."'";
289
290 $resql = $this->db->query($sql);
291 if ($resql) {
292 $obj = $this->db->fetch_object($resql);
293 $maxposition = (int) $obj->maxposition;
294 } else {
295 $this->errors[] = 'Error '.$this->db->lasterror();
296 return --$error;
297 }
298 $maxposition += 1;
299 } else {
300 $maxposition = $this->position;
301 }
302
303 // Check parameters
304 if (empty($this->filename) || empty($this->filepath)) {
305 $this->errors[] = 'Bad property filename or filepath';
306 return --$error;
307 }
308 if (!isset($this->entity)) {
309 $this->entity = $conf->entity;
310 }
311
312 $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null);
313 $extraparams = dol_trunc($extraparams, 250);
314
315 // Put here code to add control on parameters values
316 if (!empty($this->agenda_id)) {
317 $this->agenda_id = (int) $this->agenda_id;
318 }
319
320 // Insert request
321 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
322 $sql .= 'ref,';
323 $sql .= 'label,';
324 $sql .= 'share,';
325 $sql .= 'entity,';
326 $sql .= 'filename,';
327 $sql .= 'filepath,';
328 $sql .= 'fullpath_orig,';
329 $sql .= 'description,';
330 $sql .= 'keywords,';
331 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
332 $sql .= 'content,';
333 }
334 $sql .= 'cover,';
335 $sql .= 'position,';
336 $sql .= 'gen_or_uploaded,';
337 $sql .= 'extraparams,';
338 $sql .= 'date_c,';
339 $sql .= 'tms,';
340 $sql .= 'fk_user_c,';
341 $sql .= 'fk_user_m,';
342 $sql .= 'acl,';
343 $sql .= 'src_object_type,';
344 $sql .= 'src_object_id,';
345 $sql .= 'agenda_id';
346 $sql .= ') VALUES (';
347 $sql .= " '".$this->db->escape($this->ref)."', ";
348 $sql .= ' '.(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").',';
349 $sql .= ' '.(!isset($this->share) ? 'NULL' : "'".$this->db->escape($this->share)."'").',';
350 $sql .= ' '.((int) $this->entity).',';
351 $sql .= ' '.(!isset($this->filename) ? 'NULL' : "'".$this->db->escape($this->filename)."'").',';
352 $sql .= ' '.(!isset($this->filepath) ? 'NULL' : "'".$this->db->escape($this->filepath)."'").',';
353 $sql .= ' '.(!isset($this->fullpath_orig) ? 'NULL' : "'".$this->db->escape($this->fullpath_orig)."'").',';
354 $sql .= ' '.(!isset($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").',';
355 $sql .= ' '.(!isset($this->keywords) ? 'NULL' : "'".$this->db->escape($this->keywords)."'").',';
356 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
357 $sql .= ' '.(!isset($this->content) ? 'NULL' : "'".$this->db->escape($this->content)."'").',';
358 }
359 $sql .= ' '.(!isset($this->cover) ? 'NULL' : "'".$this->db->escape($this->cover)."'").',';
360 $sql .= ' '.((int) $maxposition).',';
361 $sql .= ' '.(!isset($this->gen_or_uploaded) ? 'NULL' : "'".$this->db->escape($this->gen_or_uploaded)."'").',';
362 $sql .= ' '.(!isset($extraparams) ? 'NULL' : "'".$this->db->escape($extraparams)."'").',';
363 $sql .= " '".$this->db->idate($this->date_c)."',";
364 $sql .= ' '.(!isset($this->date_m) || dol_strlen((string) $this->date_m) == 0 ? 'NULL' : "'".$this->db->idate($this->date_m)."'").',';
365 $sql .= ' '.(!isset($this->fk_user_c) ? $user->id : $this->fk_user_c).',';
366 $sql .= ' '.(!isset($this->fk_user_m) ? 'NULL' : $this->fk_user_m).',';
367 $sql .= ' '.(!isset($this->acl) ? 'NULL' : "'".$this->db->escape($this->acl)."'").',';
368 $sql .= ' '.(!isset($this->src_object_type) ? 'NULL' : "'".$this->db->escape($this->src_object_type)."'").',';
369 $sql .= ' '.(!isset($this->src_object_id) ? 'NULL' : $this->src_object_id).',';
370 $sql .= ' '.(empty($this->agenda_id) ? 'NULL' : (int) $this->agenda_id);
371 $sql .= ')';
372
373 $this->db->begin();
374
375 $resql = $this->db->query($sql);
376 if (!$resql) {
377 $error++;
378 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
379 $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror();
380 } else {
381 $this->errors[] = 'Error '.$this->db->lasterror();
382 }
383 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
384 }
385
386 if (!$error) {
387 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
388 $this->position = $maxposition;
389
390 // Triggers
391 if (!$notrigger) {
392 // Call triggers
393 $result = $this->call_trigger(strtoupper(get_class($this)).'_CREATE', $user);
394 if ($result < 0) {
395 $error++;
396 }
397 // End call triggers
398 }
399 }
400
401 // Commit or rollback
402 if ($error) {
403 $this->db->rollback();
404
405 return -1 * $error;
406 } else {
407 $this->db->commit();
408
409 return $this->id;
410 }
411 }
412
426 public function fetch($id, $ref = '', $relativepath = '', $hashoffile = '', $hashforshare = '', $src_object_type = '', $src_object_id = 0, $entity = 0)
427 {
428 global $conf;
429
430 dol_syslog(__METHOD__, LOG_DEBUG);
431
432 $sql = 'SELECT';
433 $sql .= ' t.rowid,';
434 $sql .= " t.ref,";
435 $sql .= " t.label,";
436 $sql .= " t.share,";
437 $sql .= " t.entity,";
438 $sql .= " t.filename,";
439 $sql .= " t.filepath,";
440 $sql .= " t.fullpath_orig,";
441 $sql .= " t.description,";
442 $sql .= " t.keywords,";
443 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
444 $sql .= " t.content,";
445 }
446 $sql .= " t.cover,";
447 $sql .= " t.position,";
448 $sql .= " t.gen_or_uploaded,";
449 $sql .= " t.extraparams,";
450 $sql .= " t.date_c,";
451 $sql .= " t.tms as date_m,";
452 $sql .= " t.fk_user_c,";
453 $sql .= " t.fk_user_m,";
454 $sql .= ' t.note_private,';
455 $sql .= ' t.note_public,';
456 $sql .= " t.acl,";
457 $sql .= " t.src_object_type,";
458 $sql .= " t.src_object_id,";
459 $sql .= " t.agenda_id";
460 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
461 $sql .= ' WHERE 1 = 1';
462 /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
463 if (isModEnabled('multicompany')) {
464 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
465 }*/
466 $filterfound = 0;
467 if ($relativepath) {
468 $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
469 $sql .= " AND t.filepath = '".$this->db->escape(dirname($relativepath))."'";
470 $filename = basename($relativepathwithnoexe);
471 if ($filename != '*') {
472 $sql .= " AND t.filename = '".$this->db->escape($filename)."'";
473 }
474 if (! empty($entity)) {
475 $sql .= " AND t.entity = " . (int) $entity;
476 } else {
477 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
478 }
479 $filterfound++;
480 }
481 if (!empty($ref)) { // hash of file path
482 $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
483 if (! empty($entity)) {
484 $sql .= " AND t.entity = " . (int) $entity;
485 } else {
486 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
487 }
488 $filterfound++;
489 }
490 if (!empty($hashoffile)) { // hash of content
491 $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'";
492 if (! empty($entity)) {
493 $sql .= " AND t.entity = " . (int) $entity;
494 } else {
495 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
496 }
497 $filterfound++;
498 }
499 if (!empty($hashforshare)) {
500 if ($hashforshare != 'shared') {
501 $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'";
502 } else {
503 $sql .= " AND t.share IS NOT NULL AND t.share <> ''";
504 }
505 //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique
506 $filterfound++;
507 }
508 if ($src_object_type && $src_object_id) {
509 $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id);
510 if (! empty($entity)) {
511 $sql .= " AND t.entity = " . (int) $entity;
512 } else {
513 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
514 }
515 $filterfound++;
516 }
517 if ($id > 0 || empty($filterfound)) {
518 $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique
519 }
520
521 // Warning: May return several record, and only first one is returned !
522 $this->db->plimit(1); // When we search on src, or on hash of content (hashforfile), we take first one only
523 $this->db->order('t.rowid', 'ASC');
524
525 $resql = $this->db->query($sql);
526 if ($resql) {
527 $numrows = $this->db->num_rows($resql);
528 if ($numrows) {
529 $obj = $this->db->fetch_object($resql);
530
531 $this->id = $obj->rowid;
532 $this->ref = $obj->ref;
533 $this->label = $obj->label;
534 $this->share = $obj->share;
535 $this->entity = $obj->entity;
536 $this->filename = $obj->filename;
537 $this->filepath = $obj->filepath;
538 $this->fullpath_orig = $obj->fullpath_orig;
539 $this->description = $obj->description;
540 $this->keywords = $obj->keywords;
541 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
542 $this->content = $obj->content;
543 }
544 $this->cover = $obj->cover;
545 $this->position = $obj->position;
546 $this->gen_or_uploaded = $obj->gen_or_uploaded;
547 $this->date_c = $this->db->jdate($obj->date_c);
548 $this->date_m = $this->db->jdate($obj->date_m);
549 $this->fk_user_c = $obj->fk_user_c;
550 $this->fk_user_m = $obj->fk_user_m;
551 $this->note_private = $obj->note_private;
552 $this->note_public = $obj->note_public;
553 $this->acl = $obj->acl;
554 $this->src_object_type = $obj->src_object_type;
555 $this->src_object_id = $obj->src_object_id;
556 $this->agenda_id = $obj->agenda_id;
557 $this->extraparams = (isset($obj->extraparams) ? (array) json_decode($obj->extraparams, true) : null);
558 }
559
560 // Retrieve all extrafields for ecm_files
561 // fetch optionals attributes and labels
562 $this->fetch_optionals();
563
564 // $this->fetch_lines();
565
566 $this->db->free($resql);
567
568 if ($numrows) {
569 return 1;
570 } else {
571 return 0;
572 }
573 } else {
574 $this->errors[] = 'Error '.$this->db->lasterror();
575 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
576
577 return -1;
578 }
579 }
580
592 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
593 {
594 dol_syslog(__METHOD__, LOG_DEBUG);
595
596 $sql = 'SELECT';
597 $sql .= ' t.rowid,';
598 $sql .= " t.label,";
599 $sql .= " t.share,";
600 $sql .= " t.entity,";
601 $sql .= " t.filename,";
602 $sql .= " t.filepath,";
603 $sql .= " t.fullpath_orig,";
604 $sql .= " t.description,";
605 $sql .= " t.keywords,";
606 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
607 $sql .= " t.content,";
608 }
609 $sql .= " t.cover,";
610 $sql .= " t.position,";
611 $sql .= " t.gen_or_uploaded,";
612 $sql .= " t.extraparams,";
613 $sql .= " t.date_c,";
614 $sql .= " t.tms as date_m,";
615 $sql .= " t.fk_user_c,";
616 $sql .= " t.fk_user_m,";
617 $sql .= " t.acl,";
618 $sql .= " t.src_object_type,";
619 $sql .= " t.src_object_id,";
620 $sql .= " t.agenda_id";
621 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
622 $sql .= ' WHERE 1 = 1';
623
624 // Manage filter
625 if (is_array($filter)) {
626 $sqlwhere = array();
627 if (count($filter) > 0) {
628 foreach ($filter as $key => $value) {
629 if ($key == 't.src_object_id') {
630 $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value);
631 } else {
632 $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
633 }
634 }
635 }
636 if (count($sqlwhere) > 0) {
637 $sql .= ' AND '.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere);
638 }
639
640 $filter = '';
641 }
642
643 // Manage filter
644 $errormessage = '';
645 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
646 if ($errormessage) {
647 $this->errors[] = $errormessage;
648 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
649 return -1;
650 }
651
652 /* Fetching this table depends on filepath+filename, it must not depends on entity
653 if (isModEnabled('multicompany')) {
654 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
655 }*/
656 if (!empty($sortfield)) {
657 $sql .= $this->db->order($sortfield, $sortorder);
658 }
659 if (!empty($limit)) {
660 $sql .= $this->db->plimit($limit, $offset);
661 }
662
663 $this->lines = array();
664
665 $resql = $this->db->query($sql);
666 if ($resql) {
667 $num = $this->db->num_rows($resql);
668
669 while ($obj = $this->db->fetch_object($resql)) {
670 $line = new EcmFilesLine($this->db);
671
672 $line->id = $obj->rowid;
673 $line->ref = $obj->rowid;
674 $line->label = $obj->label;
675 $line->share = $obj->share;
676 $line->entity = $obj->entity;
677 $line->filename = $obj->filename;
678 $line->filepath = $obj->filepath;
679 $line->fullpath_orig = $obj->fullpath_orig;
680 $line->description = $obj->description;
681 $line->keywords = $obj->keywords;
682 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
683 $line->content = $obj->content;
684 }
685 $line->cover = $obj->cover;
686 $line->position = $obj->position;
687 $line->gen_or_uploaded = $obj->gen_or_uploaded;
688 $line->extraparams = $obj->extraparams;
689 $line->date_c = $this->db->jdate($obj->date_c);
690 $line->date_m = $this->db->jdate($obj->date_m);
691 $line->fk_user_c = $obj->fk_user_c;
692 $line->fk_user_m = $obj->fk_user_m;
693 $line->acl = $obj->acl;
694 $line->src_object_type = $obj->src_object_type;
695 $line->src_object_id = $obj->src_object_id;
696 $line->agenda_id = $obj->agenda_id;
697 $this->lines[] = $line;
698 }
699 $this->db->free($resql);
700
701 return $num;
702 } else {
703 $this->errors[] = 'Error '.$this->db->lasterror();
704 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
705
706 return -1;
707 }
708 }
709
717 public function update(User $user, $notrigger = 0)
718 {
719 global $conf;
720
721 $error = 0;
722
723 dol_syslog(__METHOD__, LOG_DEBUG);
724
725 // Clean parameters
726
727 if (isset($this->ref)) {
728 $this->ref = trim($this->ref);
729 }
730 if (isset($this->label)) {
731 $this->label = trim($this->label);
732 }
733 if (isset($this->share)) {
734 $this->share = trim($this->share);
735 }
736 if (isset($this->entity)) {
737 $this->entity = (int) $this->entity;
738 }
739 if (isset($this->filename)) {
740 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
741 }
742 if (isset($this->filepath)) {
743 $this->filepath = trim($this->filepath);
744 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
745 }
746 if (isset($this->fullpath_orig)) {
747 $this->fullpath_orig = trim($this->fullpath_orig);
748 }
749 if (isset($this->description)) {
750 $this->description = trim($this->description);
751 }
752 if (isset($this->keywords)) {
753 $this->keywords = trim($this->keywords);
754 }
755 if (isset($this->cover)) {
756 $this->cover = trim($this->cover);
757 }
758 if (isset($this->gen_or_uploaded)) {
759 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
760 }
761 if (isset($this->fk_user_m)) {
762 $this->fk_user_m = (int) $this->fk_user_m;
763 }
764 if (isset($this->acl)) {
765 $this->acl = trim($this->acl);
766 }
767 if (isset($this->src_object_type)) {
768 $this->src_object_type = trim($this->src_object_type);
769 }
770 if (!empty($this->agenda_id)) {
771 $this->agenda_id = (int) $this->agenda_id;
772 }
773 $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null);
774 $extraparams = dol_trunc($extraparams, 250);
775
776 // Update request
777 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
778 $sql .= " ref = '".$this->db->escape(dol_hash($this->filepath."/".$this->filename, '3'))."',";
779 $sql .= ' label = '.(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").',';
780 $sql .= ' share = '.(!empty($this->share) ? "'".$this->db->escape($this->share)."'" : "null").',';
781 $sql .= ' entity = '.(isset($this->entity) ? $this->entity : $conf->entity).',';
782 $sql .= ' filename = '.(isset($this->filename) ? "'".$this->db->escape($this->filename)."'" : "null").',';
783 $sql .= ' filepath = '.(isset($this->filepath) ? "'".$this->db->escape($this->filepath)."'" : "null").',';
784 $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig) ? "'".$this->db->escape($this->fullpath_orig)."'" : "null").',';
785 $sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
786 $sql .= ' keywords = '.(isset($this->keywords) ? "'".$this->db->escape($this->keywords)."'" : "null").',';
787 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
788 $sql .= ' content = '.(isset($this->content) ? "'".$this->db->escape($this->content)."'" : "null").',';
789 }
790 $sql .= ' cover = '.(isset($this->cover) ? "'".$this->db->escape($this->cover)."'" : "null").',';
791 $sql .= ' position = '.(isset($this->position) ? $this->db->escape((string) $this->position) : "0").',';
792 $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded) ? "'".$this->db->escape($this->gen_or_uploaded)."'" : "null").',';
793 $sql .= ' extraparams = '.(isset($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null").',';
794 $sql .= ' date_c = '.(!isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').',';
795 //$sql .= ' tms = '.(! isset($this->date_m) || dol_strlen((string) $this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated
796 $sql .= ' fk_user_m = '.($this->fk_user_m > 0 ? $this->fk_user_m : $user->id).',';
797 $sql .= ' acl = '.(isset($this->acl) ? "'".$this->db->escape($this->acl)."'" : "null").',';
798 $sql .= ' src_object_id = '.($this->src_object_id > 0 ? $this->src_object_id : "null").',';
799 $sql .= ' src_object_type = '.(isset($this->src_object_type) ? "'".$this->db->escape($this->src_object_type)."'" : "null").',';
800 $sql .= ' agenda_id = '.($this->agenda_id > 0 ? (int) $this->agenda_id : "null");
801 $sql .= ' WHERE rowid='.((int) $this->id);
802 $this->db->begin();
803
804 $resql = $this->db->query($sql);
805 if (!$resql) {
806 $error++;
807 $this->errors[] = 'Error '.$this->db->lasterror();
808 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
809 }
810
811 if (!$error) {
812 // Update extrafields
813 $result = $this->insertExtraFields();
814 if ($result < 0) {
815 $error++;
816 }
817 }
818
819 // Triggers
820 if (!$error && !$notrigger) {
821 // Call triggers
822 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user);
823 if ($result < 0) {
824 $error++;
825 } //Do also here what you must do to rollback action if trigger fail
826 // End call triggers
827 }
828
829 // Commit or rollback
830 if ($error) {
831 $this->db->rollback();
832
833 return -1 * $error;
834 } else {
835 $this->db->commit();
836
837 return 1;
838 }
839 }
840
848 public function delete(User $user, $notrigger = 0)
849 {
850 dol_syslog(__METHOD__, LOG_DEBUG);
851
852 $error = 0;
853
854 $this->db->begin();
855
856 // Triggers
857 if (!$notrigger) {
858 // Call triggers
859 $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user);
860 if ($result < 0) {
861 $error++;
862 } //Do also here what you must do to rollback action if trigger fail
863 // End call triggers
864 }
865
866 // If you need to delete child tables to, you can insert them here
867 if (!$error) {
868 $result = $this->deleteExtraFields();
869 if (!$result) {
870 dol_syslog(get_class($this)."::delete error ".$this->error, LOG_ERR);
871 $error++;
872 }
873 }
874 if (!$error) {
875 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
876 $sql .= ' WHERE rowid='.((int) $this->id);
877
878 $resql = $this->db->query($sql);
879 if (!$resql) {
880 $error++;
881 $this->errors[] = 'Error '.$this->db->lasterror();
882 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
883 }
884 }
885
886 // Commit or rollback
887 if ($error) {
888 $this->db->rollback();
889
890 return -1 * $error;
891 } else {
892 $this->db->commit();
893
894 return 1;
895 }
896 }
897
905 public function createFromClone(User $user, $fromid)
906 {
907 dol_syslog(__METHOD__, LOG_DEBUG);
908
909 $error = 0;
910 $object = new EcmFiles($this->db);
911
912 $this->db->begin();
913
914 // Load source object
915 $object->fetch($fromid);
916 // Reset object
917 $object->id = 0;
918
919 // Clear fields
920 // ...
921
922 // Create clone
923 $object->context['createfromclone'] = 'createfromclone';
924 $result = $object->create($user);
925
926 // Other options
927 if ($result < 0) {
928 $error++;
929 $this->errors = $object->errors;
930 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
931 }
932
933 unset($object->context['createfromclone']);
934
935 // End
936 if (!$error) {
937 $this->db->commit();
938
939 return $object->id;
940 } else {
941 $this->db->rollback();
942
943 return -1;
944 }
945 }
946
954 public function updateAfterRename($olddir, $newdir)
955 {
956 $sql = 'UPDATE '.MAIN_DB_PREFIX.'ecm_files SET';
957 $sql .= ' filepath = "'.$this->db->escape($newdir).'"';
958 //$sql .= ', fullpath_orig = "'.$dbs->escape($newdir)."'";
959 $sql .= ' WHERE ';
960 $sql .= ' filepath = "'.$this->db->escape($olddir).'"';
961 // $sql .= ' AND fullpath_orig = "'.$dbs->escape($olddir).'"';
962
963 $this->db->query($sql);
964 }
965
973 public function getTooltipContentArray($params)
974 {
975 global $langs;
976
977 $langs->load('ecm');
978 $datas = [];
979 $nofetch = !empty($params['nofetch']);
980
981 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
982 return ['optimize' => $langs->trans("ShowFile")];
983 }
984 $datas['picto'] = img_picto('', $this->picto, '', 0, 0, 0, '', 'paddingrightonly') . '<u>' . $langs->trans("File") . '</u>';
985 if (!empty($this->filename)) {
986 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.basename($this->filename);
987 }
988 if (!empty($this->ref)) {
989 $datas['ref'] = '<br><b>'.$langs->trans('HashOfFileContent').':</b> '.$this->ref;
990 }
991 if (!empty($this->share)) {
992 $datas['share'] = '<br>'.$langs->trans("FileSharedViaALink");
993 } else {
994 $datas['share'] = '<br>'.$langs->trans("FileNotShared");
995 }
996 if (!empty($this->gen_or_uploaded)) {
997 $datas['gen_or_upload'] = '<br><b>'.$langs->trans('GenOrUpload').':</b> '.$this->gen_or_uploaded;
998 }
999 if (!empty($this->content)) {
1000 $datas['content'] = '<br>'.$langs->trans('FileHasAnIndexedTextContent');
1001 }
1002
1003 return $datas;
1004 }
1005
1016 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
1017 {
1018 global $conf, $hookmanager, $langs;
1019
1020 if (!empty($conf->dol_no_mouse_hover)) {
1021 $notooltip = 1; // Force disable tooltips
1022 }
1023
1024 $result = '';
1025
1026 $params = [
1027 'id' => $this->id,
1028 'objecttype' => $this->element,
1029 'option' => $option,
1030 'nofetch' => 1,
1031 ];
1032 $classfortooltip = 'classfortooltip';
1033 $dataparams = '';
1034 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1035 $classfortooltip = 'classforajaxtooltip';
1036 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1037 $label = '';
1038 } else {
1039 $label = implode($this->getTooltipContentArray($params));
1040 }
1041
1042 if ($option) {
1043 if ($option == 'facture_fournisseur') {
1044 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/facture\//', '', $this->filepath);
1045 } elseif ($option == 'commande_fournisseur') {
1046 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/commande\//', '', $this->filepath);
1047 } elseif ($option == 'tax-vat') { // Remove part "tax/vat/"
1048 $tmppath = preg_replace('/^(\d+\/)?tax\/vat\//', '', $this->filepath);
1049 } elseif ($option == 'remisecheque') { // Remove part "tax/vat/"
1050 $tmppath = preg_replace('/^bank\/checkdeposits\//', '', $this->filepath);
1051 } else {
1052 if ((int) $this->entity > 1) {
1053 // Remove the part "entityid/commande/" into "entityid/commande/REFXXX" to get only the ref
1054 $tmppath = preg_replace('/^\d+\/[^\/]+\//', '', $this->filepath);
1055 } else {
1056 // Remove the part "commande/" into "commande/REFXXX" to get only the ref
1057 $tmppath = preg_replace('/^[^\/]+\//', '', $this->filepath);
1058 }
1059 }
1060 $url = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($option).'&file='.urlencode($tmppath.'/'.$this->filename).'&entity='.((int) $this->entity);
1061 } else {
1062 $url = DOL_URL_ROOT.'/ecm/file_card.php?id='.$this->id;
1063 }
1064
1065 $linkclose = '';
1066 if (empty($notooltip)) {
1067 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1068 $label = $langs->trans("ShowFile");
1069 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1070 }
1071 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1072 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.($morecss ? ' '.$morecss : '').'"';
1073 } else {
1074 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1075 }
1076
1077 $linkstart = '<a href="'.$url.'"';
1078 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1079 $linkstart .= 'target="_blank" ';
1080 }
1081 $linkstart .= $linkclose.'>';
1082 $linkend = '</a>';
1083
1084 if ($withpicto) {
1085 if (empty($this->filename)) {
1086 $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="paddingright"')).$linkend);
1087 } else {
1088 $result .= ($linkstart.img_mime($this->filename, ($notooltip ? '' : dol_escape_htmltag($label, 1)), ($notooltip ? '' : ' paddingright')).$linkend);
1089 }
1090 }
1091 $result .= $linkstart.$this->filename.$linkend;
1092
1093 global $action;
1094 $hookmanager->initHooks(array($this->element . 'dao'));
1095 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1096 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1097 if ($reshook > 0) {
1098 $result = $hookmanager->resPrint;
1099 } else {
1100 $result .= $hookmanager->resPrint;
1101 }
1102
1103 return $result;
1104 }
1105
1112 public function getLibStatut($mode = 0)
1113 {
1114 return $this->LibStatut($this->status, $mode);
1115 }
1116
1117 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1125 public static function LibStatut($status, $mode = 0)
1126 {
1127 // phpcs:enable
1128 global $langs;
1129 return '';
1130 }
1131
1132
1139 public function initAsSpecimen()
1140 {
1141 global $conf, $user;
1142
1143 $this->id = 0;
1144 $this->specimen = 1;
1145 $this->label = '0a1b2c3e4f59999999';
1146 $this->entity = 1;
1147 $this->filename = 'myspecimenfilefile.pdf';
1148 $this->filepath = '/aaa/bbb';
1149 $this->fullpath_orig = 'c:/file on my disk.pdf';
1150 $this->description = 'This is a description of the file';
1151 $this->keywords = 'key1,key2';
1152 $this->content = 'This is the text content of the file';
1153 $this->cover = '1';
1154 $this->position = 5;
1155 $this->gen_or_uploaded = 'uploaded';
1156 $this->extraparams = '';
1157 $this->date_c = (dol_now() - 3600 * 24 * 10);
1158 $this->date_m = '';
1159 $this->fk_user_c = $user->id;
1160 $this->fk_user_m = $user->id;
1161 $this->acl = '';
1162 $this->src_object_type = 'product';
1163 $this->src_object_id = 1;
1164
1165 return 1;
1166 }
1167}
1168
1169
1174{
1178 public $label;
1179
1183 public $entity;
1184
1188 public $filename;
1192 public $filepath;
1196 public $fullpath_orig;
1197
1201 public $description;
1202
1206 public $keywords;
1207
1211 public $content;
1212
1216 public $cover;
1220 public $position;
1224 public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown'
1228 public $extraparams;
1232 public $date_c = '';
1236 public $date_m = '';
1237
1241 public $fk_user_c;
1242
1246 public $fk_user_m;
1247
1251 public $acl;
1255 public $src_object_type;
1259 public $src_object_id;
1260}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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.
call_trigger($triggerName, $user)
Call trigger based on this instance.
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.
fetch($id, $ref='', $relativepath='', $hashoffile='', $hashforshare='', $src_object_type='', $src_object_id=0, $entity=0)
Load object in memory from the database.
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)
__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:171
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.
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
dol_now($mode='auto')
Return date for now.
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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.