ecmfiles.class.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  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 Frédéric France <frederic.france@netlogic.fr>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  21. */
  22. /**
  23. * \file htdocs/ecm/class/ecmfiles.class.php
  24. * \ingroup ecm
  25. * \brief Class to manage ECM Files (Create/Read/Update/Delete)
  26. */
  27. // Put here all includes required by your class file
  28. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  29. /**
  30. * Class to manage ECM files
  31. */
  32. class EcmFiles extends CommonObject
  33. {
  34. /**
  35. * @var string Id to identify managed objects
  36. */
  37. public $element = 'ecmfiles';
  38. /**
  39. * @var string Name of table without prefix where object is stored
  40. */
  41. public $table_element = 'ecm_files';
  42. /**
  43. * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
  44. */
  45. public $picto = 'folder-open';
  46. /**
  47. * @var string Ref hash of file path
  48. */
  49. public $ref;
  50. /**
  51. * hash of file content (md5_file(dol_osencode($destfull))
  52. * @var string Ecm Files label
  53. */
  54. public $label;
  55. /**
  56. * @var string hash for file sharing, empty by default (example: getRandomPassword(true))
  57. */
  58. public $share;
  59. /**
  60. * @var int Entity
  61. */
  62. public $entity;
  63. /**
  64. * @var string filename, Note: Into ecm database record, the entry $filename never ends with .noexe
  65. */
  66. public $filename;
  67. /**
  68. * @var string filepath
  69. */
  70. public $filepath;
  71. /**
  72. * @var string fullpath origin
  73. */
  74. public $fullpath_orig;
  75. /**
  76. * @var string description
  77. */
  78. public $description;
  79. /**
  80. * @var string keywords
  81. */
  82. public $keywords;
  83. /**
  84. * @var string cover
  85. */
  86. public $cover;
  87. /**
  88. * @var int position
  89. */
  90. public $position;
  91. /**
  92. * @var string can be 'generated', 'uploaded', 'unknown'
  93. */
  94. public $gen_or_uploaded;
  95. /**
  96. * @var string extraparams
  97. */
  98. public $extraparams;
  99. /**
  100. * @var int|string date create
  101. */
  102. public $date_c = '';
  103. /**
  104. * @var int|string date modify
  105. */
  106. public $date_m = '';
  107. /**
  108. * @var int ID
  109. */
  110. public $fk_user_c;
  111. /**
  112. * @var int ID
  113. */
  114. public $fk_user_m;
  115. /**
  116. * @var string acl
  117. */
  118. public $acl;
  119. /**
  120. * @var string src object type
  121. */
  122. public $src_object_type;
  123. /**
  124. * @var int src object id
  125. */
  126. public $src_object_id;
  127. /**
  128. * @var int section_id ID of section = ID of EcmDirectory, directory of manual ECM (not stored into database)
  129. */
  130. public $section_id;
  131. /**
  132. * Constructor
  133. *
  134. * @param DoliDb $db Database handler
  135. */
  136. public function __construct(DoliDB $db)
  137. {
  138. $this->db = $db;
  139. }
  140. /**
  141. * Create object into database
  142. *
  143. * @param User $user User that creates
  144. * @param bool $notrigger false=launch triggers after, true=disable triggers
  145. * @return int <0 if KO, Id of created object if OK
  146. */
  147. public function create(User $user, $notrigger = false)
  148. {
  149. global $conf;
  150. dol_syslog(__METHOD__, LOG_DEBUG);
  151. $error = 0;
  152. // Clean parameters
  153. if (isset($this->ref)) {
  154. $this->ref = trim($this->ref);
  155. }
  156. if (isset($this->label)) {
  157. $this->label = trim($this->label);
  158. }
  159. if (isset($this->share)) {
  160. $this->share = trim($this->share);
  161. }
  162. if (isset($this->entity)) {
  163. $this->entity = (int) $this->entity;
  164. }
  165. if (isset($this->filename)) {
  166. $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
  167. }
  168. if (isset($this->filepath)) {
  169. $this->filepath = trim($this->filepath);
  170. $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
  171. }
  172. if (isset($this->fullpath_orig)) {
  173. $this->fullpath_orig = trim($this->fullpath_orig);
  174. }
  175. if (isset($this->description)) {
  176. $this->description = trim($this->description);
  177. }
  178. if (isset($this->keywords)) {
  179. $this->keywords = trim($this->keywords);
  180. }
  181. if (isset($this->cover)) {
  182. $this->cover = trim($this->cover);
  183. }
  184. if (isset($this->gen_or_uploaded)) {
  185. $this->gen_or_uploaded = trim($this->gen_or_uploaded);
  186. }
  187. if (isset($this->extraparams)) {
  188. $this->extraparams = trim($this->extraparams);
  189. }
  190. if (isset($this->fk_user_c)) {
  191. $this->fk_user_c = (int) $this->fk_user_c;
  192. }
  193. if (isset($this->fk_user_m)) {
  194. $this->fk_user_m = (int) $this->fk_user_m;
  195. }
  196. if (isset($this->acl)) {
  197. $this->acl = trim($this->acl);
  198. }
  199. if (isset($this->src_object_type)) {
  200. $this->src_object_type = trim($this->src_object_type);
  201. }
  202. if (empty($this->date_c)) {
  203. $this->date_c = dol_now();
  204. }
  205. if (empty($this->date_m)) {
  206. $this->date_m = dol_now();
  207. }
  208. // If ref not defined
  209. $ref = '';
  210. if (!empty($this->ref)) {
  211. $ref = $this->ref;
  212. } else {
  213. include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
  214. $ref = dol_hash($this->filepath.'/'.$this->filename, 3);
  215. }
  216. $maxposition = 0;
  217. if (empty($this->position)) {
  218. // Get max used
  219. $sql = "SELECT MAX(position) as maxposition FROM ".MAIN_DB_PREFIX.$this->table_element;
  220. $sql .= " WHERE filepath ='".$this->db->escape($this->filepath)."'";
  221. $resql = $this->db->query($sql);
  222. if ($resql) {
  223. $obj = $this->db->fetch_object($resql);
  224. $maxposition = (int) $obj->maxposition;
  225. } else {
  226. $this->errors[] = 'Error '.$this->db->lasterror();
  227. return --$error;
  228. }
  229. $maxposition = $maxposition + 1;
  230. } else {
  231. $maxposition = $this->position;
  232. }
  233. // Check parameters
  234. if (empty($this->filename) || empty($this->filepath)) {
  235. $this->errors[] = 'Bad property filename or filepath';
  236. return --$error;
  237. }
  238. if (!isset($this->entity)) {
  239. $this->entity = $conf->entity;
  240. }
  241. // Put here code to add control on parameters values
  242. // Insert request
  243. $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
  244. $sql .= 'ref,';
  245. $sql .= 'label,';
  246. $sql .= 'share,';
  247. $sql .= 'entity,';
  248. $sql .= 'filename,';
  249. $sql .= 'filepath,';
  250. $sql .= 'fullpath_orig,';
  251. $sql .= 'description,';
  252. $sql .= 'keywords,';
  253. $sql .= 'cover,';
  254. $sql .= 'position,';
  255. $sql .= 'gen_or_uploaded,';
  256. $sql .= 'extraparams,';
  257. $sql .= 'date_c,';
  258. $sql .= 'tms,';
  259. $sql .= 'fk_user_c,';
  260. $sql .= 'fk_user_m,';
  261. $sql .= 'acl,';
  262. $sql .= 'src_object_type,';
  263. $sql .= 'src_object_id';
  264. $sql .= ') VALUES (';
  265. $sql .= " '".$this->db->escape($ref)."', ";
  266. $sql .= ' '.(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").',';
  267. $sql .= ' '.(!isset($this->share) ? 'NULL' : "'".$this->db->escape($this->share)."'").',';
  268. $sql .= ' '.((int) $this->entity).',';
  269. $sql .= ' '.(!isset($this->filename) ? 'NULL' : "'".$this->db->escape($this->filename)."'").',';
  270. $sql .= ' '.(!isset($this->filepath) ? 'NULL' : "'".$this->db->escape($this->filepath)."'").',';
  271. $sql .= ' '.(!isset($this->fullpath_orig) ? 'NULL' : "'".$this->db->escape($this->fullpath_orig)."'").',';
  272. $sql .= ' '.(!isset($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").',';
  273. $sql .= ' '.(!isset($this->keywords) ? 'NULL' : "'".$this->db->escape($this->keywords)."'").',';
  274. $sql .= ' '.(!isset($this->cover) ? 'NULL' : "'".$this->db->escape($this->cover)."'").',';
  275. $sql .= ' '.((int) $maxposition).',';
  276. $sql .= ' '.(!isset($this->gen_or_uploaded) ? 'NULL' : "'".$this->db->escape($this->gen_or_uploaded)."'").',';
  277. $sql .= ' '.(!isset($this->extraparams) ? 'NULL' : "'".$this->db->escape($this->extraparams)."'").',';
  278. $sql .= " '".$this->db->idate($this->date_c)."',";
  279. $sql .= ' '.(!isset($this->date_m) || dol_strlen($this->date_m) == 0 ? 'NULL' : "'".$this->db->idate($this->date_m)."'").',';
  280. $sql .= ' '.(!isset($this->fk_user_c) ? $user->id : $this->fk_user_c).',';
  281. $sql .= ' '.(!isset($this->fk_user_m) ? 'NULL' : $this->fk_user_m).',';
  282. $sql .= ' '.(!isset($this->acl) ? 'NULL' : "'".$this->db->escape($this->acl)."'").',';
  283. $sql .= ' '.(!isset($this->src_object_type) ? 'NULL' : "'".$this->db->escape($this->src_object_type)."'").',';
  284. $sql .= ' '.(!isset($this->src_object_id) ? 'NULL' : $this->src_object_id);
  285. $sql .= ')';
  286. $this->db->begin();
  287. $resql = $this->db->query($sql);
  288. if (!$resql) {
  289. $error++;
  290. $this->errors[] = 'Error '.$this->db->lasterror();
  291. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  292. }
  293. if (!$error) {
  294. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
  295. $this->position = $maxposition;
  296. // Triggers
  297. if (!$notrigger) {
  298. // Call triggers
  299. $result = $this->call_trigger(strtoupper(get_class($this)).'_CREATE', $user);
  300. if ($result < 0) {
  301. $error++;
  302. }
  303. // End call triggers
  304. }
  305. }
  306. // Commit or rollback
  307. if ($error) {
  308. $this->db->rollback();
  309. return -1 * $error;
  310. } else {
  311. $this->db->commit();
  312. return $this->id;
  313. }
  314. }
  315. /**
  316. * Load object in memory from the database
  317. *
  318. * @param int $id Id object
  319. * @param string $ref Hash of file name (filename+filepath). Not always defined on some version.
  320. * @param string $relativepath Relative path of file from document directory. Example: 'path/path2/file' or 'path/path2/*'
  321. * @param string $hashoffile Hash of file content. Take the first one found if same file is at different places. This hash will also change if file content is changed.
  322. * @param string $hashforshare Hash of file sharing.
  323. * @param string $src_object_type src_object_type to search (value of object->table_element)
  324. * @param string $src_object_id src_object_id to search
  325. * @return int <0 if KO, 0 if not found, >0 if OK
  326. */
  327. public function fetch($id, $ref = '', $relativepath = '', $hashoffile = '', $hashforshare = '', $src_object_type = '', $src_object_id = 0)
  328. {
  329. global $conf;
  330. dol_syslog(__METHOD__, LOG_DEBUG);
  331. $sql = 'SELECT';
  332. $sql .= ' t.rowid,';
  333. $sql .= " t.ref,";
  334. $sql .= " t.label,";
  335. $sql .= " t.share,";
  336. $sql .= " t.entity,";
  337. $sql .= " t.filename,";
  338. $sql .= " t.filepath,";
  339. $sql .= " t.fullpath_orig,";
  340. $sql .= " t.description,";
  341. $sql .= " t.keywords,";
  342. $sql .= " t.cover,";
  343. $sql .= " t.position,";
  344. $sql .= " t.gen_or_uploaded,";
  345. $sql .= " t.extraparams,";
  346. $sql .= " t.date_c,";
  347. $sql .= " t.tms as date_m,";
  348. $sql .= " t.fk_user_c,";
  349. $sql .= " t.fk_user_m,";
  350. $sql .= ' t.note_private,';
  351. $sql .= ' t.note_public,';
  352. $sql .= " t.acl,";
  353. $sql .= " t.src_object_type,";
  354. $sql .= " t.src_object_id";
  355. $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
  356. $sql .= ' WHERE 1 = 1';
  357. /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
  358. if (! empty($conf->multicompany->enabled)) {
  359. $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
  360. }*/
  361. if ($relativepath) {
  362. $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
  363. $sql .= " AND t.filepath = '".$this->db->escape(dirname($relativepath))."'";
  364. $filename = basename($relativepathwithnoexe);
  365. if ($filename != '*') {
  366. $sql .= " AND t.filename = '".$this->db->escape($filename)."'";
  367. }
  368. $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
  369. } elseif (!empty($ref)) { // hash of file path
  370. $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
  371. $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
  372. } elseif (!empty($hashoffile)) { // hash of content
  373. $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'";
  374. $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
  375. } elseif (!empty($hashforshare)) {
  376. $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'";
  377. //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique
  378. } elseif ($src_object_type && $src_object_id) {
  379. // Warning: May return several record, and only first one is returned !
  380. $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id);
  381. $sql .= " AND t.entity = ".$conf->entity;
  382. } else {
  383. $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique
  384. }
  385. $this->db->plimit(1); // When we search on src or on hash of content (hashforfile) to solve hash conflict when several files has same content, we take first one only
  386. $this->db->order('t.rowid', 'ASC');
  387. $resql = $this->db->query($sql);
  388. if ($resql) {
  389. $numrows = $this->db->num_rows($resql);
  390. if ($numrows) {
  391. $obj = $this->db->fetch_object($resql);
  392. $this->id = $obj->rowid;
  393. $this->ref = $obj->ref;
  394. $this->label = $obj->label;
  395. $this->share = $obj->share;
  396. $this->entity = $obj->entity;
  397. $this->filename = $obj->filename;
  398. $this->filepath = $obj->filepath;
  399. $this->fullpath_orig = $obj->fullpath_orig;
  400. $this->description = $obj->description;
  401. $this->keywords = $obj->keywords;
  402. $this->cover = $obj->cover;
  403. $this->position = $obj->position;
  404. $this->gen_or_uploaded = $obj->gen_or_uploaded;
  405. $this->extraparams = $obj->extraparams;
  406. $this->date_c = $this->db->jdate($obj->date_c);
  407. $this->date_m = $this->db->jdate($obj->date_m);
  408. $this->fk_user_c = $obj->fk_user_c;
  409. $this->fk_user_m = $obj->fk_user_m;
  410. $this->note_private = $obj->note_private;
  411. $this->note_public = $obj->note_public;
  412. $this->acl = $obj->acl;
  413. $this->src_object_type = $obj->src_object_type;
  414. $this->src_object_id = $obj->src_object_id;
  415. }
  416. // Retrieve all extrafields for ecm_files
  417. // fetch optionals attributes and labels
  418. $this->fetch_optionals();
  419. // $this->fetch_lines();
  420. $this->db->free($resql);
  421. if ($numrows) {
  422. return 1;
  423. } else {
  424. return 0;
  425. }
  426. } else {
  427. $this->errors[] = 'Error '.$this->db->lasterror();
  428. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  429. return -1;
  430. }
  431. }
  432. /**
  433. * Load object in memory from the database
  434. *
  435. * @param string $sortorder Sort Order
  436. * @param string $sortfield Sort field
  437. * @param int $limit offset limit
  438. * @param int $offset offset limit
  439. * @param array $filter filter array
  440. * @param string $filtermode filter mode (AND or OR)
  441. *
  442. * @return int <0 if KO, >0 if OK
  443. */
  444. public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
  445. {
  446. dol_syslog(__METHOD__, LOG_DEBUG);
  447. $sql = 'SELECT';
  448. $sql .= ' t.rowid,';
  449. $sql .= " t.label,";
  450. $sql .= " t.share,";
  451. $sql .= " t.entity,";
  452. $sql .= " t.filename,";
  453. $sql .= " t.filepath,";
  454. $sql .= " t.fullpath_orig,";
  455. $sql .= " t.description,";
  456. $sql .= " t.keywords,";
  457. $sql .= " t.cover,";
  458. $sql .= " t.position,";
  459. $sql .= " t.gen_or_uploaded,";
  460. $sql .= " t.extraparams,";
  461. $sql .= " t.date_c,";
  462. $sql .= " t.tms as date_m,";
  463. $sql .= " t.fk_user_c,";
  464. $sql .= " t.fk_user_m,";
  465. $sql .= " t.acl,";
  466. $sql .= " t.src_object_type,";
  467. $sql .= " t.src_object_id";
  468. $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
  469. // Manage filter
  470. $sqlwhere = array();
  471. if (count($filter) > 0) {
  472. foreach ($filter as $key => $value) {
  473. if ($key == 't.src_object_id') {
  474. $sqlwhere[] = $key." = ".((int) $value);
  475. } else {
  476. $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
  477. }
  478. }
  479. }
  480. $sql .= ' WHERE 1 = 1';
  481. /* Fetching this table depends on filepath+filename, it must not depends on entity
  482. if (! empty($conf->multicompany->enabled)) {
  483. $sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
  484. }*/
  485. if (count($sqlwhere) > 0) {
  486. $sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere);
  487. }
  488. if (!empty($sortfield)) {
  489. $sql .= $this->db->order($sortfield, $sortorder);
  490. }
  491. if (!empty($limit)) {
  492. $sql .= $this->db->plimit($limit, $offset);
  493. }
  494. $this->lines = array();
  495. $resql = $this->db->query($sql);
  496. if ($resql) {
  497. $num = $this->db->num_rows($resql);
  498. while ($obj = $this->db->fetch_object($resql)) {
  499. $line = new EcmfilesLine();
  500. $line->id = $obj->rowid;
  501. $line->ref = $obj->ref;
  502. $line->label = $obj->label;
  503. $line->share = $obj->share;
  504. $line->entity = $obj->entity;
  505. $line->filename = $obj->filename;
  506. $line->filepath = $obj->filepath;
  507. $line->fullpath_orig = $obj->fullpath_orig;
  508. $line->description = $obj->description;
  509. $line->keywords = $obj->keywords;
  510. $line->cover = $obj->cover;
  511. $line->position = $obj->position;
  512. $line->gen_or_uploaded = $obj->gen_or_uploaded;
  513. $line->extraparams = $obj->extraparams;
  514. $line->date_c = $this->db->jdate($obj->date_c);
  515. $line->date_m = $this->db->jdate($obj->date_m);
  516. $line->fk_user_c = $obj->fk_user_c;
  517. $line->fk_user_m = $obj->fk_user_m;
  518. $line->acl = $obj->acl;
  519. $line->src_object_type = $obj->src_object_type;
  520. $line->src_object_id = $obj->src_object_id;
  521. $this->lines[] = $line;
  522. }
  523. $this->db->free($resql);
  524. return $num;
  525. } else {
  526. $this->errors[] = 'Error '.$this->db->lasterror();
  527. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  528. return -1;
  529. }
  530. }
  531. /**
  532. * Update object into database
  533. *
  534. * @param User $user User that modifies
  535. * @param bool $notrigger false=launch triggers after, true=disable triggers
  536. *
  537. * @return int <0 if KO, >0 if OK
  538. */
  539. public function update(User $user, $notrigger = false)
  540. {
  541. global $conf;
  542. $error = 0;
  543. dol_syslog(__METHOD__, LOG_DEBUG);
  544. // Clean parameters
  545. if (isset($this->ref)) {
  546. $this->ref = trim($this->ref);
  547. }
  548. if (isset($this->label)) {
  549. $this->label = trim($this->label);
  550. }
  551. if (isset($this->share)) {
  552. $this->share = trim($this->share);
  553. }
  554. if (isset($this->entity)) {
  555. $this->entity = trim($this->entity);
  556. }
  557. if (isset($this->filename)) {
  558. $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
  559. }
  560. if (isset($this->filepath)) {
  561. $this->filepath = trim($this->filepath);
  562. $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
  563. }
  564. if (isset($this->fullpath_orig)) {
  565. $this->fullpath_orig = trim($this->fullpath_orig);
  566. }
  567. if (isset($this->description)) {
  568. $this->description = trim($this->description);
  569. }
  570. if (isset($this->keywords)) {
  571. $this->keywords = trim($this->keywords);
  572. }
  573. if (isset($this->cover)) {
  574. $this->cover = trim($this->cover);
  575. }
  576. if (isset($this->gen_or_uploaded)) {
  577. $this->gen_or_uploaded = trim($this->gen_or_uploaded);
  578. }
  579. if (isset($this->extraparams)) {
  580. $this->extraparams = trim($this->extraparams);
  581. }
  582. if (isset($this->fk_user_m)) {
  583. $this->fk_user_m = trim($this->fk_user_m);
  584. }
  585. if (isset($this->acl)) {
  586. $this->acl = trim($this->acl);
  587. }
  588. if (isset($this->src_object_type)) {
  589. $this->src_object_type = trim($this->src_object_type);
  590. }
  591. // Check parameters
  592. // Put here code to add a control on parameters values
  593. // Update request
  594. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
  595. $sql .= " ref = '".$this->db->escape(dol_hash($this->filepath."/".$this->filename, 3))."',";
  596. $sql .= ' label = '.(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").',';
  597. $sql .= ' share = '.(!empty($this->share) ? "'".$this->db->escape($this->share)."'" : "null").',';
  598. $sql .= ' entity = '.(isset($this->entity) ? $this->entity : $conf->entity).',';
  599. $sql .= ' filename = '.(isset($this->filename) ? "'".$this->db->escape($this->filename)."'" : "null").',';
  600. $sql .= ' filepath = '.(isset($this->filepath) ? "'".$this->db->escape($this->filepath)."'" : "null").',';
  601. $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig) ? "'".$this->db->escape($this->fullpath_orig)."'" : "null").',';
  602. $sql .= ' description = '.(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").',';
  603. $sql .= ' keywords = '.(isset($this->keywords) ? "'".$this->db->escape($this->keywords)."'" : "null").',';
  604. $sql .= ' cover = '.(isset($this->cover) ? "'".$this->db->escape($this->cover)."'" : "null").',';
  605. $sql .= ' position = '.(isset($this->position) ? $this->db->escape($this->position) : "0").',';
  606. $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded) ? "'".$this->db->escape($this->gen_or_uploaded)."'" : "null").',';
  607. $sql .= ' extraparams = '.(isset($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").',';
  608. $sql .= ' date_c = '.(!isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').',';
  609. //$sql .= ' tms = '.(! isset($this->date_m) || dol_strlen($this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated
  610. $sql .= ' fk_user_m = '.($this->fk_user_m > 0 ? $this->fk_user_m : $user->id).',';
  611. $sql .= ' acl = '.(isset($this->acl) ? "'".$this->db->escape($this->acl)."'" : "null").',';
  612. $sql .= ' src_object_id = '.($this->src_object_id > 0 ? $this->src_object_id : "null").',';
  613. $sql .= ' src_object_type = '.(isset($this->src_object_type) ? "'".$this->db->escape($this->src_object_type)."'" : "null");
  614. $sql .= ' WHERE rowid='.((int) $this->id);
  615. $this->db->begin();
  616. $resql = $this->db->query($sql);
  617. if (!$resql) {
  618. $error++;
  619. $this->errors[] = 'Error '.$this->db->lasterror();
  620. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  621. }
  622. // Triggers
  623. if (!$error && !$notrigger) {
  624. // Call triggers
  625. $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user);
  626. if ($result < 0) {
  627. $error++;
  628. } //Do also here what you must do to rollback action if trigger fail
  629. // End call triggers
  630. }
  631. // Commit or rollback
  632. if ($error) {
  633. $this->db->rollback();
  634. return -1 * $error;
  635. } else {
  636. $this->db->commit();
  637. return 1;
  638. }
  639. }
  640. /**
  641. * Delete object in database
  642. *
  643. * @param User $user User that deletes
  644. * @param bool $notrigger false=launch triggers after, true=disable triggers
  645. *
  646. * @return int <0 if KO, >0 if OK
  647. */
  648. public function delete(User $user, $notrigger = false)
  649. {
  650. dol_syslog(__METHOD__, LOG_DEBUG);
  651. $error = 0;
  652. $this->db->begin();
  653. // Triggers
  654. if (!$notrigger) {
  655. // Call triggers
  656. $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user);
  657. if ($result < 0) {
  658. $error++;
  659. } //Do also here what you must do to rollback action if trigger fail
  660. // End call triggers
  661. }
  662. // If you need to delete child tables to, you can insert them here
  663. if (!$error) {
  664. $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
  665. $sql .= ' WHERE rowid='.((int) $this->id);
  666. $resql = $this->db->query($sql);
  667. if (!$resql) {
  668. $error++;
  669. $this->errors[] = 'Error '.$this->db->lasterror();
  670. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  671. }
  672. }
  673. // Commit or rollback
  674. if ($error) {
  675. $this->db->rollback();
  676. return -1 * $error;
  677. } else {
  678. $this->db->commit();
  679. return 1;
  680. }
  681. }
  682. /**
  683. * Load an object from its id and create a new one in database
  684. *
  685. * @param User $user User making the clone
  686. * @param int $fromid Id of object to clone
  687. * @return int New id of clone
  688. */
  689. public function createFromClone(User $user, $fromid)
  690. {
  691. dol_syslog(__METHOD__, LOG_DEBUG);
  692. $error = 0;
  693. $object = new Ecmfiles($this->db);
  694. $this->db->begin();
  695. // Load source object
  696. $object->fetch($fromid);
  697. // Reset object
  698. $object->id = 0;
  699. // Clear fields
  700. // ...
  701. // Create clone
  702. $object->context['createfromclone'] = 'createfromclone';
  703. $result = $object->create($user);
  704. // Other options
  705. if ($result < 0) {
  706. $error++;
  707. $this->errors = $object->errors;
  708. dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
  709. }
  710. unset($object->context['createfromclone']);
  711. // End
  712. if (!$error) {
  713. $this->db->commit();
  714. return $object->id;
  715. } else {
  716. $this->db->rollback();
  717. return -1;
  718. }
  719. }
  720. /**
  721. * Return a link to the object card (with optionaly the picto)
  722. *
  723. * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
  724. * @param string $option On what the link point to
  725. * @param int $notooltip 1=Disable tooltip
  726. * @param int $maxlen Max length of visible user name
  727. * @param string $morecss Add more css on link
  728. * @return string String with URL
  729. */
  730. public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $maxlen = 24, $morecss = '')
  731. {
  732. global $db, $conf, $langs;
  733. global $dolibarr_main_authentication, $dolibarr_main_demo;
  734. global $menumanager;
  735. if (!empty($conf->dol_no_mouse_hover)) {
  736. $notooltip = 1; // Force disable tooltips
  737. }
  738. $result = '';
  739. $label = '<u>'.$langs->trans("MyModule").'</u>';
  740. $label .= '<br>';
  741. $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
  742. $url = DOL_URL_ROOT.'/ecm/'.$this->table_name.'_card.php?id='.$this->id;
  743. $linkclose = '';
  744. if (empty($notooltip)) {
  745. if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
  746. $label = $langs->trans("ShowProject");
  747. $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
  748. }
  749. $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
  750. $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
  751. } else {
  752. $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
  753. }
  754. $linkstart = '<a href="'.$url.'"';
  755. $linkstart .= $linkclose.'>';
  756. $linkend = '</a>';
  757. if ($withpicto) {
  758. $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="classfortooltip"')).$linkend);
  759. if ($withpicto != 2) {
  760. $result .= ' ';
  761. }
  762. }
  763. $result .= $linkstart.$this->ref.$linkend;
  764. return $result;
  765. }
  766. /**
  767. * Retourne le libelle du status d'un user (actif, inactif)
  768. *
  769. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  770. * @return string Label of status
  771. */
  772. public function getLibStatut($mode = 0)
  773. {
  774. return $this->LibStatut($this->status, $mode);
  775. }
  776. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  777. /**
  778. * Return the status
  779. *
  780. * @param int $status Id status
  781. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto
  782. * @return string Label of status
  783. */
  784. public static function LibStatut($status, $mode = 0)
  785. {
  786. // phpcs:enable
  787. global $langs;
  788. return '';
  789. }
  790. /**
  791. * Initialise object with example values
  792. * Id must be 0 if object instance is a specimen
  793. *
  794. * @return void
  795. */
  796. public function initAsSpecimen()
  797. {
  798. global $conf, $user;
  799. $this->id = 0;
  800. $this->specimen = 1;
  801. $this->label = '0a1b2c3e4f59999999';
  802. $this->entity = 1;
  803. $this->filename = 'myspecimenfilefile.pdf';
  804. $this->filepath = '/aaa/bbb';
  805. $this->fullpath_orig = 'c:/file on my disk.pdf';
  806. $this->description = 'This is a long description of file';
  807. $this->keywords = 'key1,key2';
  808. $this->cover = '1';
  809. $this->position = 5;
  810. $this->gen_or_uploaded = 'uploaded';
  811. $this->extraparams = '';
  812. $this->date_c = (dol_now() - 3600 * 24 * 10);
  813. $this->date_m = '';
  814. $this->fk_user_c = $user->id;
  815. $this->fk_user_m = '';
  816. $this->acl = '';
  817. $this->src_object_type = 'product';
  818. $this->src_object_id = 1;
  819. }
  820. }
  821. /**
  822. * Class of an index line of a document
  823. */
  824. class EcmfilesLine
  825. {
  826. /**
  827. * @var string ECM files line label
  828. */
  829. public $label;
  830. /**
  831. * @var int Entity
  832. */
  833. public $entity;
  834. public $filename;
  835. public $filepath;
  836. public $fullpath_orig;
  837. /**
  838. * @var string description
  839. */
  840. public $description;
  841. public $keywords;
  842. public $cover;
  843. public $position;
  844. public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown'
  845. public $extraparams;
  846. public $date_c = '';
  847. public $date_m = '';
  848. /**
  849. * @var int ID
  850. */
  851. public $fk_user_c;
  852. /**
  853. * @var int ID
  854. */
  855. public $fk_user_m;
  856. public $acl;
  857. public $src_object_type;
  858. public $src_object_id;
  859. }