dolibarr 21.0.4
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
414 public function fetch($id, $ref = '', $relativepath = '', $hashoffile = '', $hashforshare = '', $src_object_type = '', $src_object_id = 0, $entity = 0)
415 {
416 global $conf;
417
418 dol_syslog(__METHOD__, LOG_DEBUG);
419
420 $sql = 'SELECT';
421 $sql .= ' t.rowid,';
422 $sql .= " t.ref,";
423 $sql .= " t.label,";
424 $sql .= " t.share,";
425 $sql .= " t.entity,";
426 $sql .= " t.filename,";
427 $sql .= " t.filepath,";
428 $sql .= " t.fullpath_orig,";
429 $sql .= " t.description,";
430 $sql .= " t.keywords,";
431 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
432 $sql .= " t.content,";
433 }
434 $sql .= " t.cover,";
435 $sql .= " t.position,";
436 $sql .= " t.gen_or_uploaded,";
437 $sql .= " t.extraparams,";
438 $sql .= " t.date_c,";
439 $sql .= " t.tms as date_m,";
440 $sql .= " t.fk_user_c,";
441 $sql .= " t.fk_user_m,";
442 $sql .= ' t.note_private,';
443 $sql .= ' t.note_public,';
444 $sql .= " t.acl,";
445 $sql .= " t.src_object_type,";
446 $sql .= " t.src_object_id";
447 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
448 $sql .= ' WHERE 1 = 1';
449 /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
450 if (isModEnabled('multicompany')) {
451 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
452 }*/
453 $filterfound = 0;
454 if ($relativepath) {
455 $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
456 $sql .= " AND t.filepath = '".$this->db->escape(dirname($relativepath))."'";
457 $filename = basename($relativepathwithnoexe);
458 if ($filename != '*') {
459 $sql .= " AND t.filename = '".$this->db->escape($filename)."'";
460 }
461 if (! empty($entity)) {
462 $sql .= " AND t.entity = " . (int) $entity;
463 } else {
464 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
465 }
466 $filterfound++;
467 }
468 if (!empty($ref)) { // hash of file path
469 $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
470 if (! empty($entity)) {
471 $sql .= " AND t.entity = " . (int) $entity;
472 } else {
473 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
474 }
475 $filterfound++;
476 }
477 if (!empty($hashoffile)) { // hash of content
478 $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'";
479 if (! empty($entity)) {
480 $sql .= " AND t.entity = " . (int) $entity;
481 } else {
482 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
483 }
484 $filterfound++;
485 }
486 if (!empty($hashforshare)) {
487 if ($hashforshare != 'shared') {
488 $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'";
489 } else {
490 $sql .= " AND t.share IS NOT NULL AND t.share <> ''";
491 }
492 //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique
493 $filterfound++;
494 }
495 if ($src_object_type && $src_object_id) {
496 $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id);
497 if (! empty($entity)) {
498 $sql .= " AND t.entity = " . (int) $entity;
499 } else {
500 $sql .= " AND t.entity = " . $conf->entity; // unique key include the entity so each company has its own index
501 }
502 $filterfound++;
503 }
504 if ($id > 0 || empty($filterfound)) {
505 $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique
506 }
507
508 // Warning: May return several record, and only first one is returned !
509 $this->db->plimit(1); // When we search on src, or on hash of content (hashforfile), we take first one only
510 $this->db->order('t.rowid', 'ASC');
511
512 $resql = $this->db->query($sql);
513 if ($resql) {
514 $numrows = $this->db->num_rows($resql);
515 if ($numrows) {
516 $obj = $this->db->fetch_object($resql);
517
518 $this->id = $obj->rowid;
519 $this->ref = $obj->ref;
520 $this->label = $obj->label;
521 $this->share = $obj->share;
522 $this->entity = $obj->entity;
523 $this->filename = $obj->filename;
524 $this->filepath = $obj->filepath;
525 $this->fullpath_orig = $obj->fullpath_orig;
526 $this->description = $obj->description;
527 $this->keywords = $obj->keywords;
528 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
529 $this->content = $obj->content;
530 }
531 $this->cover = $obj->cover;
532 $this->position = $obj->position;
533 $this->gen_or_uploaded = $obj->gen_or_uploaded;
534 $this->extraparams = $obj->extraparams;
535 $this->date_c = $this->db->jdate($obj->date_c);
536 $this->date_m = $this->db->jdate($obj->date_m);
537 $this->fk_user_c = $obj->fk_user_c;
538 $this->fk_user_m = $obj->fk_user_m;
539 $this->note_private = $obj->note_private;
540 $this->note_public = $obj->note_public;
541 $this->acl = $obj->acl;
542 $this->src_object_type = $obj->src_object_type;
543 $this->src_object_id = $obj->src_object_id;
544 }
545
546 // Retrieve all extrafields for ecm_files
547 // fetch optionals attributes and labels
548 $this->fetch_optionals();
549
550 // $this->fetch_lines();
551
552 $this->db->free($resql);
553
554 if ($numrows) {
555 return 1;
556 } else {
557 return 0;
558 }
559 } else {
560 $this->errors[] = 'Error '.$this->db->lasterror();
561 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
562
563 return -1;
564 }
565 }
566
578 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
579 {
580 dol_syslog(__METHOD__, LOG_DEBUG);
581
582 $sql = 'SELECT';
583 $sql .= ' t.rowid,';
584 $sql .= " t.label,";
585 $sql .= " t.share,";
586 $sql .= " t.entity,";
587 $sql .= " t.filename,";
588 $sql .= " t.filepath,";
589 $sql .= " t.fullpath_orig,";
590 $sql .= " t.description,";
591 $sql .= " t.keywords,";
592 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
593 $sql .= " t.content,";
594 }
595 $sql .= " t.cover,";
596 $sql .= " t.position,";
597 $sql .= " t.gen_or_uploaded,";
598 $sql .= " t.extraparams,";
599 $sql .= " t.date_c,";
600 $sql .= " t.tms as date_m,";
601 $sql .= " t.fk_user_c,";
602 $sql .= " t.fk_user_m,";
603 $sql .= " t.acl,";
604 $sql .= " t.src_object_type,";
605 $sql .= " t.src_object_id";
606 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
607 $sql .= ' WHERE 1 = 1';
608
609 // Manage filter
610 if (is_array($filter)) {
611 $sqlwhere = array();
612 if (count($filter) > 0) {
613 foreach ($filter as $key => $value) {
614 if ($key == 't.src_object_id') {
615 $sqlwhere[] = $this->db->sanitize($key)." = ".((int) $value);
616 } else {
617 $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($this->db->escapeforlike($value))."%'";
618 }
619 }
620 }
621 if (count($sqlwhere) > 0) {
622 $sql .= ' AND '.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere);
623 }
624
625 $filter = '';
626 }
627
628 // Manage filter
629 $errormessage = '';
630 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
631 if ($errormessage) {
632 $this->errors[] = $errormessage;
633 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
634 return -1;
635 }
636
637 /* Fetching this table depends on filepath+filename, it must not depends on entity
638 if (isModEnabled('multicompany')) {
639 $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
640 }*/
641 if (!empty($sortfield)) {
642 $sql .= $this->db->order($sortfield, $sortorder);
643 }
644 if (!empty($limit)) {
645 $sql .= $this->db->plimit($limit, $offset);
646 }
647
648 $this->lines = array();
649
650 $resql = $this->db->query($sql);
651 if ($resql) {
652 $num = $this->db->num_rows($resql);
653
654 while ($obj = $this->db->fetch_object($resql)) {
655 $line = new EcmFilesLine($this->db);
656
657 $line->id = $obj->rowid;
658 $line->ref = $obj->rowid;
659 $line->label = $obj->label;
660 $line->share = $obj->share;
661 $line->entity = $obj->entity;
662 $line->filename = $obj->filename;
663 $line->filepath = $obj->filepath;
664 $line->fullpath_orig = $obj->fullpath_orig;
665 $line->description = $obj->description;
666 $line->keywords = $obj->keywords;
667 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
668 $line->content = $obj->content;
669 }
670 $line->cover = $obj->cover;
671 $line->position = $obj->position;
672 $line->gen_or_uploaded = $obj->gen_or_uploaded;
673 $line->extraparams = $obj->extraparams;
674 $line->date_c = $this->db->jdate($obj->date_c);
675 $line->date_m = $this->db->jdate($obj->date_m);
676 $line->fk_user_c = $obj->fk_user_c;
677 $line->fk_user_m = $obj->fk_user_m;
678 $line->acl = $obj->acl;
679 $line->src_object_type = $obj->src_object_type;
680 $line->src_object_id = $obj->src_object_id;
681 $this->lines[] = $line;
682 }
683 $this->db->free($resql);
684
685 return $num;
686 } else {
687 $this->errors[] = 'Error '.$this->db->lasterror();
688 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
689
690 return -1;
691 }
692 }
693
701 public function update(User $user, $notrigger = 0)
702 {
703 global $conf;
704
705 $error = 0;
706
707 dol_syslog(__METHOD__, LOG_DEBUG);
708
709 // Clean parameters
710
711 if (isset($this->ref)) {
712 $this->ref = trim($this->ref);
713 }
714 if (isset($this->label)) {
715 $this->label = trim($this->label);
716 }
717 if (isset($this->share)) {
718 $this->share = trim($this->share);
719 }
720 if (isset($this->entity)) {
721 $this->entity = (int) $this->entity;
722 }
723 if (isset($this->filename)) {
724 $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
725 }
726 if (isset($this->filepath)) {
727 $this->filepath = trim($this->filepath);
728 $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
729 }
730 if (isset($this->fullpath_orig)) {
731 $this->fullpath_orig = trim($this->fullpath_orig);
732 }
733 if (isset($this->description)) {
734 $this->description = trim($this->description);
735 }
736 if (isset($this->keywords)) {
737 $this->keywords = trim($this->keywords);
738 }
739 if (isset($this->cover)) {
740 $this->cover = trim($this->cover);
741 }
742 if (isset($this->gen_or_uploaded)) {
743 $this->gen_or_uploaded = trim($this->gen_or_uploaded);
744 }
745 if (isset($this->extraparams)) {
746 $this->extraparams = trim($this->extraparams);
747 }
748 if (isset($this->fk_user_m)) {
749 $this->fk_user_m = (int) $this->fk_user_m;
750 }
751 if (isset($this->acl)) {
752 $this->acl = trim($this->acl);
753 }
754 if (isset($this->src_object_type)) {
755 $this->src_object_type = trim($this->src_object_type);
756 }
757
758 // Check parameters
759 // Put here code to add a control on parameters values
760
761 // Update request
762 $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
763 $sql .= " ref = '".$this->db->escape(dol_hash($this->filepath."/".$this->filename, '3'))."',";
764 $sql .= ' label = '.(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").',';
765 $sql .= ' share = '.(!empty($this->share) ? "'".$this->db->escape($this->share)."'" : "null").',';
766 $sql .= ' entity = '.(isset($this->entity) ? $this->entity : $conf->entity).',';
767 $sql .= ' filename = '.(isset($this->filename) ? "'".$this->db->escape($this->filename)."'" : "null").',';
768 $sql .= ' filepath = '.(isset($this->filepath) ? "'".$this->db->escape($this->filepath)."'" : "null").',';
769 $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig) ? "'".$this->db->escape($this->fullpath_orig)."'" : "null").',';
770 $sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
771 $sql .= ' keywords = '.(isset($this->keywords) ? "'".$this->db->escape($this->keywords)."'" : "null").',';
772 if (getDolGlobalString("MAIN_SAVE_FILE_CONTENT_AS_TEXT")) {
773 $sql .= ' content = '.(isset($this->content) ? "'".$this->db->escape($this->content)."'" : "null").',';
774 }
775 $sql .= ' cover = '.(isset($this->cover) ? "'".$this->db->escape($this->cover)."'" : "null").',';
776 $sql .= ' position = '.(isset($this->position) ? $this->db->escape($this->position) : "0").',';
777 $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded) ? "'".$this->db->escape($this->gen_or_uploaded)."'" : "null").',';
778 $sql .= ' extraparams = '.(isset($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").',';
779 $sql .= ' date_c = '.(!isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').',';
780 //$sql .= ' tms = '.(! isset($this->date_m) || dol_strlen((string) $this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated
781 $sql .= ' fk_user_m = '.($this->fk_user_m > 0 ? $this->fk_user_m : $user->id).',';
782 $sql .= ' acl = '.(isset($this->acl) ? "'".$this->db->escape($this->acl)."'" : "null").',';
783 $sql .= ' src_object_id = '.($this->src_object_id > 0 ? $this->src_object_id : "null").',';
784 $sql .= ' src_object_type = '.(isset($this->src_object_type) ? "'".$this->db->escape($this->src_object_type)."'" : "null");
785 $sql .= ' WHERE rowid='.((int) $this->id);
786 $this->db->begin();
787
788 $resql = $this->db->query($sql);
789 if (!$resql) {
790 $error++;
791 $this->errors[] = 'Error '.$this->db->lasterror();
792 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
793 }
794
795 if (!$error) {
796 // Update extrafields
797 $result = $this->insertExtraFields();
798 if ($result < 0) {
799 $error++;
800 }
801 }
802
803 // Triggers
804 if (!$error && !$notrigger) {
805 // Call triggers
806 $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user);
807 if ($result < 0) {
808 $error++;
809 } //Do also here what you must do to rollback action if trigger fail
810 // End call triggers
811 }
812
813 // Commit or rollback
814 if ($error) {
815 $this->db->rollback();
816
817 return -1 * $error;
818 } else {
819 $this->db->commit();
820
821 return 1;
822 }
823 }
824
832 public function delete(User $user, $notrigger = 0)
833 {
834 dol_syslog(__METHOD__, LOG_DEBUG);
835
836 $error = 0;
837
838 $this->db->begin();
839
840 // Triggers
841 if (!$notrigger) {
842 // Call triggers
843 $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user);
844 if ($result < 0) {
845 $error++;
846 } //Do also here what you must do to rollback action if trigger fail
847 // End call triggers
848 }
849
850 // If you need to delete child tables to, you can insert them here
851 if (!$error) {
852 $result = $this->deleteExtraFields();
853 if (!$result) {
854 dol_syslog(get_class($this)."::delete error ".$this->error, LOG_ERR);
855 $error++;
856 }
857 }
858 if (!$error) {
859 $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
860 $sql .= ' WHERE rowid='.((int) $this->id);
861
862 $resql = $this->db->query($sql);
863 if (!$resql) {
864 $error++;
865 $this->errors[] = 'Error '.$this->db->lasterror();
866 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
867 }
868 }
869
870 // Commit or rollback
871 if ($error) {
872 $this->db->rollback();
873
874 return -1 * $error;
875 } else {
876 $this->db->commit();
877
878 return 1;
879 }
880 }
881
889 public function createFromClone(User $user, $fromid)
890 {
891 dol_syslog(__METHOD__, LOG_DEBUG);
892
893 $error = 0;
894 $object = new EcmFiles($this->db);
895
896 $this->db->begin();
897
898 // Load source object
899 $object->fetch($fromid);
900 // Reset object
901 $object->id = 0;
902
903 // Clear fields
904 // ...
905
906 // Create clone
907 $object->context['createfromclone'] = 'createfromclone';
908 $result = $object->create($user);
909
910 // Other options
911 if ($result < 0) {
912 $error++;
913 $this->errors = $object->errors;
914 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
915 }
916
917 unset($object->context['createfromclone']);
918
919 // End
920 if (!$error) {
921 $this->db->commit();
922
923 return $object->id;
924 } else {
925 $this->db->rollback();
926
927 return -1;
928 }
929 }
930
938 public function updateAfterRename($olddir, $newdir)
939 {
940 $sql = 'UPDATE '.MAIN_DB_PREFIX.'ecm_files SET';
941 $sql .= ' filepath = "'.$this->db->escape($newdir).'"';
942 //$sql .= ', fullpath_orig = "'.$dbs->escape($newdir)."'";
943 $sql .= ' WHERE ';
944 $sql .= ' filepath = "'.$this->db->escape($olddir).'"';
945 // $sql .= ' AND fullpath_orig = "'.$dbs->escape($olddir).'"';
946
947 $this->db->query($sql);
948 }
949
957 public function getTooltipContentArray($params)
958 {
959 global $langs;
960
961 $langs->load('ecm');
962 $datas = [];
963 $nofetch = !empty($params['nofetch']);
964
965 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
966 return ['optimize' => $langs->trans("ShowFile")];
967 }
968 $datas['picto'] = img_picto('', $this->picto, '', 0, 0, 0, '', 'paddingrightonly') . '<u>' . $langs->trans("File") . '</u>';
969 if (!empty($this->filename)) {
970 $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.basename($this->filename);
971 }
972 if (!empty($this->ref)) {
973 $datas['ref'] = '<br><b>'.$langs->trans('HashOfFileContent').':</b> '.$this->ref;
974 }
975 if (!empty($this->share)) {
976 $datas['share'] = '<br>'.$langs->trans("FileSharedViaALink");
977 } else {
978 $datas['share'] = '<br>'.$langs->trans("FileNotShared");
979 }
980 if (!empty($this->gen_or_uploaded)) {
981 $datas['gen_or_upload'] = '<br><b>'.$langs->trans('GenOrUpload').':</b> '.$this->gen_or_uploaded;
982 }
983 if (!empty($this->content)) {
984 $datas['content'] = '<br>'.$langs->trans('FileHasAnIndexedTextContent');
985 }
986
987 return $datas;
988 }
989
1000 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
1001 {
1002 global $conf, $hookmanager, $langs;
1003
1004 if (!empty($conf->dol_no_mouse_hover)) {
1005 $notooltip = 1; // Force disable tooltips
1006 }
1007
1008 $result = '';
1009
1010 $params = [
1011 'id' => $this->id,
1012 'objecttype' => $this->element,
1013 'option' => $option,
1014 'nofetch' => 1,
1015 ];
1016 $classfortooltip = 'classfortooltip';
1017 $dataparams = '';
1018 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1019 $classfortooltip = 'classforajaxtooltip';
1020 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1021 $label = '';
1022 } else {
1023 $label = implode($this->getTooltipContentArray($params));
1024 }
1025
1026 if ($option) {
1027 if ($option == 'facture_fournisseur') {
1028 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/facture\//', '', $this->filepath);
1029 } elseif ($option == 'commande_fournisseur') {
1030 $tmppath = preg_replace('/^(\d+\/)?fournisseur\/commande\//', '', $this->filepath);
1031 } elseif ($option == 'tax-vat') { // Remove part "tax/vat/"
1032 $tmppath = preg_replace('/^(\d+\/)?tax\/vat\//', '', $this->filepath);
1033 } elseif ($option == 'remisecheque') { // Remove part "tax/vat/"
1034 $tmppath = preg_replace('/^bank\/checkdeposits\//', '', $this->filepath);
1035 } else {
1036 if ((int) $this->entity > 1) {
1037 // Remove the part "entityid/commande/" into "entityid/commande/REFXXX" to get only the ref
1038 $tmppath = preg_replace('/^\d+\/[^\/]+\//', '', $this->filepath);
1039 } else {
1040 // Remove the part "commande/" into "commande/REFXXX" to get only the ref
1041 $tmppath = preg_replace('/^[^\/]+\//', '', $this->filepath);
1042 }
1043 }
1044 $url = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($option).'&file='.urlencode($tmppath.'/'.$this->filename).'&entity='.((int) $this->entity);
1045 } else {
1046 $url = DOL_URL_ROOT.'/ecm/file_card.php?id='.$this->id;
1047 }
1048
1049 $linkclose = '';
1050 if (empty($notooltip)) {
1051 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1052 $label = $langs->trans("ShowFile");
1053 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1054 }
1055 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1056 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.($morecss ? ' '.$morecss : '').'"';
1057 } else {
1058 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1059 }
1060
1061 $linkstart = '<a href="'.$url.'"';
1062 if (getDolGlobalInt('MAIN_DISABLE_FORCE_SAVEAS') == 2) {
1063 $linkstart .= 'target="_blank" ';
1064 }
1065 $linkstart .= $linkclose.'>';
1066 $linkend = '</a>';
1067
1068 if ($withpicto) {
1069 if (empty($this->filename)) {
1070 $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="paddingright"')).$linkend);
1071 } else {
1072 $result .= ($linkstart.img_mime($this->filename, ($notooltip ? '' : dol_escape_htmltag($label, 1)), ($notooltip ? '' : ' paddingright')).$linkend);
1073 }
1074 if ($withpicto != 2) {
1075 $result .= ' ';
1076 }
1077 }
1078 $result .= $linkstart.$this->filename.$linkend;
1079
1080 global $action;
1081 $hookmanager->initHooks(array($this->element . 'dao'));
1082 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1083 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1084 if ($reshook > 0) {
1085 $result = $hookmanager->resPrint;
1086 } else {
1087 $result .= $hookmanager->resPrint;
1088 }
1089
1090 return $result;
1091 }
1092
1099 public function getLibStatut($mode = 0)
1100 {
1101 return $this->LibStatut($this->status, $mode);
1102 }
1103
1104 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1112 public static function LibStatut($status, $mode = 0)
1113 {
1114 // phpcs:enable
1115 global $langs;
1116 return '';
1117 }
1118
1119
1126 public function initAsSpecimen()
1127 {
1128 global $conf, $user;
1129
1130 $this->id = 0;
1131 $this->specimen = 1;
1132 $this->label = '0a1b2c3e4f59999999';
1133 $this->entity = 1;
1134 $this->filename = 'myspecimenfilefile.pdf';
1135 $this->filepath = '/aaa/bbb';
1136 $this->fullpath_orig = 'c:/file on my disk.pdf';
1137 $this->description = 'This is a description of the file';
1138 $this->keywords = 'key1,key2';
1139 $this->content = 'This is the text content of the file';
1140 $this->cover = '1';
1141 $this->position = 5;
1142 $this->gen_or_uploaded = 'uploaded';
1143 $this->extraparams = '';
1144 $this->date_c = (dol_now() - 3600 * 24 * 10);
1145 $this->date_m = '';
1146 $this->fk_user_c = $user->id;
1147 $this->fk_user_m = $user->id;
1148 $this->acl = '';
1149 $this->src_object_type = 'product';
1150 $this->src_object_id = 1;
1151
1152 return 1;
1153 }
1154}
1155
1156
1161{
1165 public $label;
1166
1170 public $entity;
1171
1175 public $filename;
1179 public $filepath;
1183 public $fullpath_orig;
1184
1188 public $description;
1189
1193 public $keywords;
1194
1198 public $content;
1199
1203 public $cover;
1207 public $position;
1211 public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown'
1215 public $extraparams;
1219 public $date_c = '';
1223 public $date_m = '';
1224
1228 public $fk_user_c;
1229
1233 public $fk_user_m;
1234
1238 public $acl;
1242 public $src_object_type;
1246 public $src_object_id;
1247}
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.
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.
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.