dolibarr 21.0.0-beta
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 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 $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 );
191
192
198 public function __construct(DoliDB $db)
199 {
200 $this->db = $db;
201 }
202
210 public function create(User $user, $notrigger = 0)
211 {
212 global $conf;
213
214 dol_syslog(__METHOD__, LOG_DEBUG);
215
216 $error = 0;
217
218 // Clean parameters
219 if (isset($this->ref)) {
220 $this->ref = trim($this->ref);
221 }
222 if (isset($this->label)) {
223 $this->label = trim($this->label);
224 }
225 if (isset($this->share)) {
226 $this->share = trim($this->share);
227 }
228 if (isset($this->entity)) {
229 $this->entity = (int) $this->entity;
230 }
231 if (isset($this->filename)) {
232 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
233 }
234 if (isset($this->filepath)) {
235 $this->filepath = trim($this->filepath);
236 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
237 }
238 if (isset($this->fullpath_orig)) {
239 $this->fullpath_orig = trim($this->fullpath_orig);
240 }
241 if (isset($this->description)) {
242 $this->description = trim($this->description);
243 }
244 if (isset($this->keywords)) {
245 $this->keywords = trim($this->keywords);
246 }
247 if (isset($this->cover)) {
248 $this->cover = trim($this->cover);
249 }
250 if (isset($this->gen_or_uploaded)) {
251 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
252 }
253 if (isset($this->extraparams)) {
254 $this->extraparams = trim($this->extraparams);
255 }
256 if (isset($this->fk_user_c)) {
257 $this->fk_user_c = (int) $this->fk_user_c;
258 }
259 if (isset($this->fk_user_m)) {
260 $this->fk_user_m = (int) $this->fk_user_m;
261 }
262 if (isset($this->acl)) {
263 $this->acl = trim($this->acl);
264 }
265 if (isset($this->src_object_type)) {
266 $this->src_object_type = trim($this->src_object_type);
267 }
268 if (empty($this->date_c)) {
269 $this->date_c = dol_now();
270 }
271 if (empty($this->date_m)) {
272 $this->date_m = dol_now();
273 }
274
275 // If ref not defined
276 if (empty($this->ref)) {
277 include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
278 $this->ref = dol_hash($this->filepath.'/'.$this->filename, '3');
279 }
280
281 $maxposition = 0;
282 if (empty($this->position)) {
283 // Get max used
284 $sql = "SELECT MAX(position) as maxposition FROM ".MAIN_DB_PREFIX.$this->table_element;
285 $sql .= " WHERE filepath ='".$this->db->escape($this->filepath)."'";
286
287 $resql = $this->db->query($sql);
288 if ($resql) {
289 $obj = $this->db->fetch_object($resql);
290 $maxposition = (int) $obj->maxposition;
291 } else {
292 $this->errors[] = 'Error '.$this->db->lasterror();
293 return --$error;
294 }
295 $maxposition += 1;
296 } else {
297 $maxposition = $this->position;
298 }
299
300 // Check parameters
301 if (empty($this->filename) || empty($this->filepath)) {
302 $this->errors[] = 'Bad property filename or filepath';
303 return --$error;
304 }
305 if (!isset($this->entity)) {
306 $this->entity = $conf->entity;
307 }
308 // Put here code to add control on parameters values
309
310 // Insert request
311 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
312 $sql .= 'ref,';
313 $sql .= 'label,';
314 $sql .= 'share,';
315 $sql .= 'entity,';
316 $sql .= 'filename,';
317 $sql .= 'filepath,';
318 $sql .= 'fullpath_orig,';
319 $sql .= 'description,';
320 $sql .= 'keywords,';
321 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
322 $sql .= 'content,';
323 }
324 $sql .= 'cover,';
325 $sql .= 'position,';
326 $sql .= 'gen_or_uploaded,';
327 $sql .= 'extraparams,';
328 $sql .= 'date_c,';
329 $sql .= 'tms,';
330 $sql .= 'fk_user_c,';
331 $sql .= 'fk_user_m,';
332 $sql .= 'acl,';
333 $sql .= 'src_object_type,';
334 $sql .= 'src_object_id';
335 $sql .= ') VALUES (';
336 $sql .= " '".$this->db->escape($this->ref)."', ";
337 $sql .= ' '.(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").',';
338 $sql .= ' '.(!isset($this->share) ? 'NULL' : "'".$this->db->escape($this->share)."'").',';
339 $sql .= ' '.((int) $this->entity).',';
340 $sql .= ' '.(!isset($this->filename) ? 'NULL' : "'".$this->db->escape($this->filename)."'").',';
341 $sql .= ' '.(!isset($this->filepath) ? 'NULL' : "'".$this->db->escape($this->filepath)."'").',';
342 $sql .= ' '.(!isset($this->fullpath_orig) ? 'NULL' : "'".$this->db->escape($this->fullpath_orig)."'").',';
343 $sql .= ' '.(!isset($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").',';
344 $sql .= ' '.(!isset($this->keywords) ? 'NULL' : "'".$this->db->escape($this->keywords)."'").',';
345 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
346 $sql .= ' '.(!isset($this->content) ? 'NULL' : "'".$this->db->escape($this->content)."'").',';
347 }
348 $sql .= ' '.(!isset($this->cover) ? 'NULL' : "'".$this->db->escape($this->cover)."'").',';
349 $sql .= ' '.((int) $maxposition).',';
350 $sql .= ' '.(!isset($this->gen_or_uploaded) ? 'NULL' : "'".$this->db->escape($this->gen_or_uploaded)."'").',';
351 $sql .= ' '.(!isset($this->extraparams) ? 'NULL' : "'".$this->db->escape($this->extraparams)."'").',';
352 $sql .= " '".$this->db->idate($this->date_c)."',";
353 $sql .= ' '.(!isset($this->date_m) || dol_strlen((string) $this->date_m) == 0 ? 'NULL' : "'".$this->db->idate($this->date_m)."'").',';
354 $sql .= ' '.(!isset($this->fk_user_c) ? $user->id : $this->fk_user_c).',';
355 $sql .= ' '.(!isset($this->fk_user_m) ? 'NULL' : $this->fk_user_m).',';
356 $sql .= ' '.(!isset($this->acl) ? 'NULL' : "'".$this->db->escape($this->acl)."'").',';
357 $sql .= ' '.(!isset($this->src_object_type) ? 'NULL' : "'".$this->db->escape($this->src_object_type)."'").',';
358 $sql .= ' '.(!isset($this->src_object_id) ? 'NULL' : $this->src_object_id);
359 $sql .= ')';
360
361 $this->db->begin();
362
363 $resql = $this->db->query($sql);
364 if (!$resql) {
365 $error++;
366 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
367 $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror();
368 } else {
369 $this->errors[] = 'Error '.$this->db->lasterror();
370 }
371 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
372 }
373
374 if (!$error) {
375 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
376 $this->position = $maxposition;
377
378 // Triggers
379 if (!$notrigger) {
380 // Call triggers
381 $result = $this->call_trigger(strtoupper(get_class($this)).'_CREATE', $user);
382 if ($result < 0) {
383 $error++;
384 }
385 // End call triggers
386 }
387 }
388
389 // Commit or rollback
390 if ($error) {
391 $this->db->rollback();
392
393 return -1 * $error;
394 } else {
395 $this->db->commit();
396
397 return $this->id;
398 }
399 }
400
413 public function fetch($id, $ref = '', $relativepath = '', $hashoffile = '', $hashforshare = '', $src_object_type = '', $src_object_id = 0)
414 {
415 global $conf;
416
417 dol_syslog(__METHOD__, LOG_DEBUG);
418
419 $sql = 'SELECT';
420 $sql .= ' t.rowid,';
421 $sql .= " t.ref,";
422 $sql .= " t.label,";
423 $sql .= " t.share,";
424 $sql .= " t.entity,";
425 $sql .= " t.filename,";
426 $sql .= " t.filepath,";
427 $sql .= " t.fullpath_orig,";
428 $sql .= " t.description,";
429 $sql .= " t.keywords,";
430 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
431 $sql .= " t.content,";
432 }
433 $sql .= " t.cover,";
434 $sql .= " t.position,";
435 $sql .= " t.gen_or_uploaded,";
436 $sql .= " t.extraparams,";
437 $sql .= " t.date_c,";
438 $sql .= " t.tms as date_m,";
439 $sql .= " t.fk_user_c,";
440 $sql .= " t.fk_user_m,";
441 $sql .= ' t.note_private,';
442 $sql .= ' t.note_public,';
443 $sql .= " t.acl,";
444 $sql .= " t.src_object_type,";
445 $sql .= " t.src_object_id";
446 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
447 $sql .= ' WHERE 1 = 1';
448 /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
449 if (isModEnabled('multicompany')) {
450 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
451 }*/
452 $filterfound = 0;
453 if ($relativepath) {
454 $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
455 $sql .= " AND t.filepath = '".$this->db->escape(dirname($relativepath))."'";
456 $filename = basename($relativepathwithnoexe);
457 if ($filename != '*') {
458 $sql .= " AND t.filename = '".$this->db->escape($filename)."'";
459 }
460 $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
461 $filterfound++;
462 }
463 if (!empty($ref)) { // hash of file path
464 $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
465 $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
466 $filterfound++;
467 }
468 if (!empty($hashoffile)) { // hash of content
469 $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'";
470 $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
471 $filterfound++;
472 }
473 if (!empty($hashforshare)) {
474 if ($hashforshare != 'shared') {
475 $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'";
476 } else {
477 $sql .= " AND t.share IS NOT NULL AND t.share <> ''";
478 }
479 //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique
480 $filterfound++;
481 }
482 if ($src_object_type && $src_object_id) {
483 $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id);
484 $sql .= " AND t.entity = ".((int) $conf->entity);
485 $filterfound++;
486 }
487 if ($id > 0 || empty($filterfound)) {
488 $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique
489 }
490
491 // Warning: May return several record, and only first one is returned !
492 $this->db->plimit(1); // When we search on src, or on hash of content (hashforfile), we take first one only
493 $this->db->order('t.rowid', 'ASC');
494
495 $resql = $this->db->query($sql);
496 if ($resql) {
497 $numrows = $this->db->num_rows($resql);
498 if ($numrows) {
499 $obj = $this->db->fetch_object($resql);
500
501 $this->id = $obj->rowid;
502 $this->ref = $obj->ref;
503 $this->label = $obj->label;
504 $this->share = $obj->share;
505 $this->entity = $obj->entity;
506 $this->filename = $obj->filename;
507 $this->filepath = $obj->filepath;
508 $this->fullpath_orig = $obj->fullpath_orig;
509 $this->description = $obj->description;
510 $this->keywords = $obj->keywords;
511 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
512 $this->content = $obj->content;
513 }
514 $this->cover = $obj->cover;
515 $this->position = $obj->position;
516 $this->gen_or_uploaded = $obj->gen_or_uploaded;
517 $this->extraparams = $obj->extraparams;
518 $this->date_c = $this->db->jdate($obj->date_c);
519 $this->date_m = $this->db->jdate($obj->date_m);
520 $this->fk_user_c = $obj->fk_user_c;
521 $this->fk_user_m = $obj->fk_user_m;
522 $this->note_private = $obj->note_private;
523 $this->note_public = $obj->note_public;
524 $this->acl = $obj->acl;
525 $this->src_object_type = $obj->src_object_type;
526 $this->src_object_id = $obj->src_object_id;
527 }
528
529 // Retrieve all extrafields for ecm_files
530 // fetch optionals attributes and labels
531 $this->fetch_optionals();
532
533 // $this->fetch_lines();
534
535 $this->db->free($resql);
536
537 if ($numrows) {
538 return 1;
539 } else {
540 return 0;
541 }
542 } else {
543 $this->errors[] = 'Error '.$this->db->lasterror();
544 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
545
546 return -1;
547 }
548 }
549
561 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
562 {
563 dol_syslog(__METHOD__, LOG_DEBUG);
564
565 $sql = 'SELECT';
566 $sql .= ' t.rowid,';
567 $sql .= " t.label,";
568 $sql .= " t.share,";
569 $sql .= " t.entity,";
570 $sql .= " t.filename,";
571 $sql .= " t.filepath,";
572 $sql .= " t.fullpath_orig,";
573 $sql .= " t.description,";
574 $sql .= " t.keywords,";
575 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
576 $sql .= " t.content,";
577 }
578 $sql .= " t.cover,";
579 $sql .= " t.position,";
580 $sql .= " t.gen_or_uploaded,";
581 $sql .= " t.extraparams,";
582 $sql .= " t.date_c,";
583 $sql .= " t.tms as date_m,";
584 $sql .= " t.fk_user_c,";
585 $sql .= " t.fk_user_m,";
586 $sql .= " t.acl,";
587 $sql .= " t.src_object_type,";
588 $sql .= " t.src_object_id";
589 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
590 $sql .= ' WHERE 1 = 1';
591
592 // Manage filter
593 if (is_array($filter)) {
594 $sqlwhere = array();
595 if (count($filter) > 0) {
596 foreach ($filter as $key => $value) {
597 if ($key == 't.src_object_id') {
598 $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value);
599 } else {
600 $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
601 }
602 }
603 }
604 if (count($sqlwhere) > 0) {
605 $sql .= ' AND '.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere);
606 }
607
608 $filter = '';
609 }
610
611 // Manage filter
612 $errormessage = '';
613 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
614 if ($errormessage) {
615 $this->errors[] = $errormessage;
616 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
617 return -1;
618 }
619
620 /* Fetching this table depends on filepath+filename, it must not depends on entity
621 if (isModEnabled('multicompany')) {
622 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
623 }*/
624 if (!empty($sortfield)) {
625 $sql .= $this->db->order($sortfield, $sortorder);
626 }
627 if (!empty($limit)) {
628 $sql .= $this->db->plimit($limit, $offset);
629 }
630
631 $this->lines = array();
632
633 $resql = $this->db->query($sql);
634 if ($resql) {
635 $num = $this->db->num_rows($resql);
636
637 while ($obj = $this->db->fetch_object($resql)) {
638 $line = new EcmFilesLine($this->db);
639
640 $line->id = $obj->rowid;
641 $line->ref = $obj->rowid;
642 $line->label = $obj->label;
643 $line->share = $obj->share;
644 $line->entity = $obj->entity;
645 $line->filename = $obj->filename;
646 $line->filepath = $obj->filepath;
647 $line->fullpath_orig = $obj->fullpath_orig;
648 $line->description = $obj->description;
649 $line->keywords = $obj->keywords;
650 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
651 $line->content = $obj->content;
652 }
653 $line->cover = $obj->cover;
654 $line->position = $obj->position;
655 $line->gen_or_uploaded = $obj->gen_or_uploaded;
656 $line->extraparams = $obj->extraparams;
657 $line->date_c = $this->db->jdate($obj->date_c);
658 $line->date_m = $this->db->jdate($obj->date_m);
659 $line->fk_user_c = $obj->fk_user_c;
660 $line->fk_user_m = $obj->fk_user_m;
661 $line->acl = $obj->acl;
662 $line->src_object_type = $obj->src_object_type;
663 $line->src_object_id = $obj->src_object_id;
664 $this->lines[] = $line;
665 }
666 $this->db->free($resql);
667
668 return $num;
669 } else {
670 $this->errors[] = 'Error '.$this->db->lasterror();
671 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
672
673 return -1;
674 }
675 }
676
684 public function update(User $user, $notrigger = 0)
685 {
686 global $conf;
687
688 $error = 0;
689
690 dol_syslog(__METHOD__, LOG_DEBUG);
691
692 // Clean parameters
693
694 if (isset($this->ref)) {
695 $this->ref = trim($this->ref);
696 }
697 if (isset($this->label)) {
698 $this->label = trim($this->label);
699 }
700 if (isset($this->share)) {
701 $this->share = trim($this->share);
702 }
703 if (isset($this->entity)) {
704 $this->entity = (int) $this->entity;
705 }
706 if (isset($this->filename)) {
707 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
708 }
709 if (isset($this->filepath)) {
710 $this->filepath = trim($this->filepath);
711 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
712 }
713 if (isset($this->fullpath_orig)) {
714 $this->fullpath_orig = trim($this->fullpath_orig);
715 }
716 if (isset($this->description)) {
717 $this->description = trim($this->description);
718 }
719 if (isset($this->keywords)) {
720 $this->keywords = trim($this->keywords);
721 }
722 if (isset($this->cover)) {
723 $this->cover = trim($this->cover);
724 }
725 if (isset($this->gen_or_uploaded)) {
726 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
727 }
728 if (isset($this->extraparams)) {
729 $this->extraparams = trim($this->extraparams);
730 }
731 if (isset($this->fk_user_m)) {
732 $this->fk_user_m = (int) $this->fk_user_m;
733 }
734 if (isset($this->acl)) {
735 $this->acl = trim($this->acl);
736 }
737 if (isset($this->src_object_type)) {
738 $this->src_object_type = trim($this->src_object_type);
739 }
740
741 // Check parameters
742 // Put here code to add a control on parameters values
743
744 // Update request
745 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
746 $sql .= " ref = '".$this->db->escape(dol_hash($this->filepath."/".$this->filename, '3'))."',";
747 $sql .= ' label = '.(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").',';
748 $sql .= ' share = '.(!empty($this->share) ? "'".$this->db->escape($this->share)."'" : "null").',';
749 $sql .= ' entity = '.(isset($this->entity) ? $this->entity : $conf->entity).',';
750 $sql .= ' filename = '.(isset($this->filename) ? "'".$this->db->escape($this->filename)."'" : "null").',';
751 $sql .= ' filepath = '.(isset($this->filepath) ? "'".$this->db->escape($this->filepath)."'" : "null").',';
752 $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig) ? "'".$this->db->escape($this->fullpath_orig)."'" : "null").',';
753 $sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
754 $sql .= ' keywords = '.(isset($this->keywords) ? "'".$this->db->escape($this->keywords)."'" : "null").',';
755 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
756 $sql .= ' content = '.(isset($this->content) ? "'".$this->db->escape($this->content)."'" : "null").',';
757 }
758 $sql .= ' cover = '.(isset($this->cover) ? "'".$this->db->escape($this->cover)."'" : "null").',';
759 $sql .= ' position = '.(isset($this->position) ? $this->db->escape($this->position) : "0").',';
760 $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded) ? "'".$this->db->escape($this->gen_or_uploaded)."'" : "null").',';
761 $sql .= ' extraparams = '.(isset($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").',';
762 $sql .= ' date_c = '.(!isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').',';
763 //$sql .= ' tms = '.(! isset($this->date_m) || dol_strlen((string) $this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated
764 $sql .= ' fk_user_m = '.($this->fk_user_m > 0 ? $this->fk_user_m : $user->id).',';
765 $sql .= ' acl = '.(isset($this->acl) ? "'".$this->db->escape($this->acl)."'" : "null").',';
766 $sql .= ' src_object_id = '.($this->src_object_id > 0 ? $this->src_object_id : "null").',';
767 $sql .= ' src_object_type = '.(isset($this->src_object_type) ? "'".$this->db->escape($this->src_object_type)."'" : "null");
768 $sql .= ' WHERE rowid='.((int) $this->id);
769
770 $this->db->begin();
771
772 $resql = $this->db->query($sql);
773 if (!$resql) {
774 $error++;
775 $this->errors[] = 'Error '.$this->db->lasterror();
776 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
777 }
778
779 if (!$error) {
780 // Update extrafields
781 $result = $this->insertExtraFields();
782 if ($result < 0) {
783 $error++;
784 }
785 }
786
787 // Triggers
788 if (!$error && !$notrigger) {
789 // Call triggers
790 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user);
791 if ($result < 0) {
792 $error++;
793 } //Do also here what you must do to rollback action if trigger fail
794 // End call triggers
795 }
796
797 // Commit or rollback
798 if ($error) {
799 $this->db->rollback();
800
801 return -1 * $error;
802 } else {
803 $this->db->commit();
804
805 return 1;
806 }
807 }
808
816 public function delete(User $user, $notrigger = 0)
817 {
818 dol_syslog(__METHOD__, LOG_DEBUG);
819
820 $error = 0;
821
822 $this->db->begin();
823
824 // Triggers
825 if (!$notrigger) {
826 // Call triggers
827 $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user);
828 if ($result < 0) {
829 $error++;
830 } //Do also here what you must do to rollback action if trigger fail
831 // End call triggers
832 }
833
834 // If you need to delete child tables to, you can insert them here
835 if (!$error) {
836 $result = $this->deleteExtraFields();
837 if (!$result) {
838 dol_syslog(get_class($this)."::delete error ".$this->error, LOG_ERR);
839 $error++;
840 }
841 }
842 if (!$error) {
843 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
844 $sql .= ' WHERE rowid='.((int) $this->id);
845
846 $resql = $this->db->query($sql);
847 if (!$resql) {
848 $error++;
849 $this->errors[] = 'Error '.$this->db->lasterror();
850 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
851 }
852 }
853
854 // Commit or rollback
855 if ($error) {
856 $this->db->rollback();
857
858 return -1 * $error;
859 } else {
860 $this->db->commit();
861
862 return 1;
863 }
864 }
865
873 public function createFromClone(User $user, $fromid)
874 {
875 dol_syslog(__METHOD__, LOG_DEBUG);
876
877 $error = 0;
878 $object = new EcmFiles($this->db);
879
880 $this->db->begin();
881
882 // Load source object
883 $object->fetch($fromid);
884 // Reset object
885 $object->id = 0;
886
887 // Clear fields
888 // ...
889
890 // Create clone
891 $object->context['createfromclone'] = 'createfromclone';
892 $result = $object->create($user);
893
894 // Other options
895 if ($result < 0) {
896 $error++;
897 $this->errors = $object->errors;
898 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
899 }
900
901 unset($object->context['createfromclone']);
902
903 // End
904 if (!$error) {
905 $this->db->commit();
906
907 return $object->id;
908 } else {
909 $this->db->rollback();
910
911 return -1;
912 }
913 }
914
922 public function updateAfterRename($olddir, $newdir)
923 {
924 $sql = 'UPDATE '.MAIN_DB_PREFIX.'ecm_files SET';
925 $sql .= ' filepath = "'.$this->db->escape($newdir).'"';
926 //$sql .= ', fullpath_orig = "'.$dbs->escape($newdir)."'";
927 $sql .= ' WHERE ';
928 $sql .= ' filepath = "'.$this->db->escape($olddir).'"';
929 // $sql .= ' AND fullpath_orig = "'.$dbs->escape($olddir).'"';
930
931 $this->db->query($sql);
932 }
933
941 public function getTooltipContentArray($params)
942 {
943 global $langs;
944
945 $langs->load('ecm');
946 $datas = [];
947 $nofetch = !empty($params['nofetch']);
948
949 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
950 return ['optimize' => $langs->trans("ShowFile")];
951 }
952 $datas['picto'] = img_picto('', $this->picto, '', 0, 0, 0, '', 'paddingrightonly') . '<u>' . $langs->trans("File") . '</u>';
953 if (!empty($this->filename)) {
954 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.basename($this->filename);
955 }
956 if (!empty($this->ref)) {
957 $datas['ref'] = '<br><b>'.$langs->trans('HashOfFileContent').':</b> '.$this->ref;
958 }
959 if (!empty($this->share)) {
960 $datas['share'] = '<br>'.$langs->trans("FileSharedViaALink");
961 } else {
962 $datas['share'] = '<br>'.$langs->trans("FileNotShared");
963 }
964 if (!empty($this->gen_or_uploaded)) {
965 $datas['gen_or_upload'] = '<br><b>'.$langs->trans('GenOrUpload').':</b> '.$this->gen_or_uploaded;
966 }
967 if (!empty($this->content)) {
968 $datas['content'] = '<br>'.$langs->trans('FileHasAnIndexedTextContent');
969 }
970
971 return $datas;
972 }
973
984 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
985 {
986 global $conf, $hookmanager, $langs;
987
988 if (!empty($conf->dol_no_mouse_hover)) {
989 $notooltip = 1; // Force disable tooltips
990 }
991
992 $result = '';
993
994 $params = [
995 'id' => $this->id,
996 'objecttype' => $this->element,
997 'option' => $option,
998 'nofetch' => 1,
999 ];
1000 $classfortooltip = 'classfortooltip';
1001 $dataparams = '';
1002 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1003 $classfortooltip = 'classforajaxtooltip';
1004 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1005 $label = '';
1006 } else {
1007 $label = implode($this->getTooltipContentArray($params));
1008 }
1009
1010 if ($option) {
1011 $url = DOL_URL_ROOT.'/document.php?modulepart='.$option.'&file='.urlencode(preg_replace('/^[^\/]+\//', '', $this->filepath).'/'.$this->filename).'&entity='.$this->entity;
1012 } else {
1013 $url = DOL_URL_ROOT.'/ecm/file_card.php?id='.$this->id;
1014 }
1015
1016 $linkclose = '';
1017 if (empty($notooltip)) {
1018 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1019 $label = $langs->trans("ShowFile");
1020 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1021 }
1022 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1023 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.($morecss ? ' '.$morecss : '').'"';
1024 } else {
1025 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1026 }
1027
1028 $linkstart = '<a href="'.$url.'"';
1029 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1030 $linkstart .= 'target="_blank" ';
1031 }
1032 $linkstart .= $linkclose.'>';
1033 $linkend = '</a>';
1034
1035 if ($withpicto) {
1036 if (empty($this->filename)) {
1037 $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="paddingright"')).$linkend);
1038 } else {
1039 $result .= ($linkstart.img_mime($this->filename, ($notooltip ? '' : dol_escape_htmltag($label, 1)), ($notooltip ? '' : ' paddingright')).$linkend);
1040 }
1041 if ($withpicto != 2) {
1042 $result .= ' ';
1043 }
1044 }
1045 $result .= $linkstart.$this->filename.$linkend;
1046
1047 global $action;
1048 $hookmanager->initHooks(array($this->element . 'dao'));
1049 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1050 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1051 if ($reshook > 0) {
1052 $result = $hookmanager->resPrint;
1053 } else {
1054 $result .= $hookmanager->resPrint;
1055 }
1056
1057 return $result;
1058 }
1059
1066 public function getLibStatut($mode = 0)
1067 {
1068 return $this->LibStatut($this->status, $mode);
1069 }
1070
1071 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1079 public static function LibStatut($status, $mode = 0)
1080 {
1081 // phpcs:enable
1082 global $langs;
1083 return '';
1084 }
1085
1086
1093 public function initAsSpecimen()
1094 {
1095 global $conf, $user;
1096
1097 $this->id = 0;
1098 $this->specimen = 1;
1099 $this->label = '0a1b2c3e4f59999999';
1100 $this->entity = 1;
1101 $this->filename = 'myspecimenfilefile.pdf';
1102 $this->filepath = '/aaa/bbb';
1103 $this->fullpath_orig = 'c:/file on my disk.pdf';
1104 $this->description = 'This is a description of the file';
1105 $this->keywords = 'key1,key2';
1106 $this->content = 'This is the text content of the file';
1107 $this->cover = '1';
1108 $this->position = 5;
1109 $this->gen_or_uploaded = 'uploaded';
1110 $this->extraparams = '';
1111 $this->date_c = (dol_now() - 3600 * 24 * 10);
1112 $this->date_m = '';
1113 $this->fk_user_c = $user->id;
1114 $this->fk_user_m = $user->id;
1115 $this->acl = '';
1116 $this->src_object_type = 'product';
1117 $this->src_object_id = 1;
1118
1119 return 1;
1120 }
1121}
1122
1123
1128{
1132 public $label;
1133
1137 public $entity;
1138
1142 public $filename;
1146 public $filepath;
1150 public $fullpath_orig;
1151
1155 public $description;
1156
1160 public $keywords;
1161
1165 public $content;
1166
1170 public $cover;
1174 public $position;
1178 public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown'
1182 public $extraparams;
1186 public $date_c = '';
1190 public $date_m = '';
1191
1195 public $fk_user_c;
1196
1200 public $fk_user_m;
1201
1205 public $acl;
1209 public $src_object_type;
1213 public $src_object_id;
1214}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
print $object position
Definition edit.php:204
$object ref
Definition info.php:89
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.
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)
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: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)
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.
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)
Returns a hash (non reversible encryption) of a string.