dolibarr  18.0.6
myobject.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2023 Frédéric France <frederic.france@netlogic.fr>
4  * Copyright (C) ---Put here your own copyright and developer email---
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 // Put here all includes required by your class file
27 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
28 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
29 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
30 
34 class MyObject extends CommonObject
35 {
39  public $module = 'mymodule';
40 
44  public $element = 'myobject';
45 
49  public $table_element = 'mymodule_myobject';
50 
55  public $ismultientitymanaged = 0;
56 
60  public $isextrafieldmanaged = 1;
61 
65  public $picto = 'fa-file';
66 
67 
68  const STATUS_DRAFT = 0;
69  const STATUS_VALIDATED = 1;
70  const STATUS_CANCELED = 9;
71 
72 
112  // BEGIN MODULEBUILDER PROPERTIES
116  public $fields = array(
117  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'),
118  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>10),
119  'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object', 'validate'=>1),
120  'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2, 'validate'=>1, 'alwayseditable'=>1),
121  'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1),
122  'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1),
123  'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>'isModEnabled("societe")', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
124  'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'isModEnabled("project")', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
125  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1),
126  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'),
127  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1, 'cssview'=>'wordbreak'),
128  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500),
129  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501),
130  //'date_validation ' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502),
131  'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>510, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax150'),
132  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511, 'csslist'=>'tdoverflowmax150'),
133  //'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512),
134  'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'notnull'=>0, 'position'=>600),
135  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000),
136  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'notnull'=>-1, 'position'=>1010),
137  'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>2000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled'), 'validate'=>1),
138  );
139 
143  public $rowid;
144 
148  public $ref;
149 
153  public $entity;
154 
158  public $label;
159 
163  public $amount;
164 
168  public $socid; // both socid and fk_soc are used
169  public $fk_soc; // both socid and fk_soc are used
170 
174  public $status;
175 
179  public $date_creation;
180 
184  public $tms;
185 
189  public $fk_user_creat;
190 
194  public $fk_user_modif;
195 
199  public $last_main_doc;
200 
204  public $import_key;
205  // END MODULEBUILDER PROPERTIES
206 
207 
208  // If this object has a subtable with lines
209 
210  // /**
211  // * @var string Name of subtable line
212  // */
213  // public $table_element_line = 'mymodule_myobjectline';
214 
215  // /**
216  // * @var string Field with ID of parent key if this object has a parent
217  // */
218  // public $fk_element = 'fk_myobject';
219 
220  // /**
221  // * @var string Name of subtable class that manage subtable lines
222  // */
223  // public $class_element_line = 'MyObjectline';
224 
225  // /**
226  // * @var array List of child tables. To test if we can delete object.
227  // */
228  // protected $childtables = array('mychildtable' => array('name'=>'MyObject', 'fk_element'=>'fk_myobject'));
229 
230  // /**
231  // * @var array List of child tables. To know object to delete on cascade.
232  // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
233  // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
234  // */
235  // protected $childtablesoncascade = array('mymodule_myobjectdet');
236 
237  // /**
238  // * @var MyObjectLine[] Array of subtable lines
239  // */
240  // public $lines = array();
241 
242 
243 
249  public function __construct(DoliDB $db)
250  {
251  global $conf, $langs;
252 
253  $this->db = $db;
254 
255  if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
256  $this->fields['rowid']['visible'] = 0;
257  }
258  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
259  $this->fields['entity']['enabled'] = 0;
260  }
261 
262  // Example to show how to set values of fields definition dynamically
263  /*if ($user->hasRight('mymodule', 'myobject', 'read')) {
264  $this->fields['myfield']['visible'] = 1;
265  $this->fields['myfield']['noteditable'] = 0;
266  }*/
267 
268  // Unset fields that are disabled
269  foreach ($this->fields as $key => $val) {
270  if (isset($val['enabled']) && empty($val['enabled'])) {
271  unset($this->fields[$key]);
272  }
273  }
274 
275  // Translate some data of arrayofkeyval
276  if (is_object($langs)) {
277  foreach ($this->fields as $key => $val) {
278  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
279  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
280  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
281  }
282  }
283  }
284  }
285  }
286 
294  public function create(User $user, $notrigger = false)
295  {
296  $resultcreate = $this->createCommon($user, $notrigger);
297 
298  //$resultvalidate = $this->validate($user, $notrigger);
299 
300  return $resultcreate;
301  }
302 
310  public function createFromClone(User $user, $fromid)
311  {
312  global $langs, $extrafields;
313  $error = 0;
314 
315  dol_syslog(__METHOD__, LOG_DEBUG);
316 
317  $object = new self($this->db);
318 
319  $this->db->begin();
320 
321  // Load source object
322  $result = $object->fetchCommon($fromid);
323  if ($result > 0 && !empty($object->table_element_line)) {
324  $object->fetchLines();
325  }
326 
327  // get lines so they will be clone
328  //foreach($this->lines as $line)
329  // $line->fetch_optionals();
330 
331  // Reset some properties
332  unset($object->id);
333  unset($object->fk_user_creat);
334  unset($object->import_key);
335 
336  // Clear fields
337  if (property_exists($object, 'ref')) {
338  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
339  }
340  if (property_exists($object, 'label')) {
341  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
342  }
343  if (property_exists($object, 'status')) {
344  $object->status = self::STATUS_DRAFT;
345  }
346  if (property_exists($object, 'date_creation')) {
347  $object->date_creation = dol_now();
348  }
349  if (property_exists($object, 'date_modification')) {
350  $object->date_modification = null;
351  }
352  // ...
353  // Clear extrafields that are unique
354  if (is_array($object->array_options) && count($object->array_options) > 0) {
355  $extrafields->fetch_name_optionals_label($this->table_element);
356  foreach ($object->array_options as $key => $option) {
357  $shortkey = preg_replace('/options_/', '', $key);
358  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
359  //var_dump($key);
360  //var_dump($clonedObj->array_options[$key]); exit;
361  unset($object->array_options[$key]);
362  }
363  }
364  }
365 
366  // Create clone
367  $object->context['createfromclone'] = 'createfromclone';
368  $result = $object->createCommon($user);
369  if ($result < 0) {
370  $error++;
371  $this->setErrorsFromObject($object);
372  }
373 
374  if (!$error) {
375  // copy internal contacts
376  if ($this->copy_linked_contact($object, 'internal') < 0) {
377  $error++;
378  }
379  }
380 
381  if (!$error) {
382  // copy external contacts if same company
383  if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
384  if ($this->copy_linked_contact($object, 'external') < 0) {
385  $error++;
386  }
387  }
388  }
389 
390  unset($object->context['createfromclone']);
391 
392  // End
393  if (!$error) {
394  $this->db->commit();
395  return $object;
396  } else {
397  $this->db->rollback();
398  return -1;
399  }
400  }
401 
409  public function fetch($id, $ref = null)
410  {
411  $result = $this->fetchCommon($id, $ref);
412  if ($result > 0 && !empty($this->table_element_line)) {
413  $this->fetchLines();
414  }
415  return $result;
416  }
417 
423  public function fetchLines()
424  {
425  $this->lines = array();
426 
427  $result = $this->fetchLinesCommon();
428  return $result;
429  }
430 
431 
443  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
444  {
445  dol_syslog(__METHOD__, LOG_DEBUG);
446 
447  $records = array();
448 
449  $sql = "SELECT ";
450  $sql .= $this->getFieldList('t');
451  $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
452  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
453  $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
454  } else {
455  $sql .= " WHERE 1 = 1";
456  }
457  // Manage filter
458  $sqlwhere = array();
459  if (count($filter) > 0) {
460  foreach ($filter as $key => $value) {
461  if ($key == 't.rowid') {
462  $sqlwhere[] = $key." = ".((int) $value);
463  } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
464  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
465  } elseif ($key == 'customsql') {
466  $sqlwhere[] = $value;
467  } elseif (strpos($value, '%') === false) {
468  $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
469  } else {
470  $sqlwhere[] = $key." LIKE '%".$this->db->escapeforlike($this->db->escape($value))."%'";
471  }
472  }
473  }
474  if (count($sqlwhere) > 0) {
475  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
476  }
477 
478  if (!empty($sortfield)) {
479  $sql .= $this->db->order($sortfield, $sortorder);
480  }
481  if (!empty($limit)) {
482  $sql .= $this->db->plimit($limit, $offset);
483  }
484 
485  $resql = $this->db->query($sql);
486  if ($resql) {
487  $num = $this->db->num_rows($resql);
488  $i = 0;
489  while ($i < ($limit ? min($limit, $num) : $num)) {
490  $obj = $this->db->fetch_object($resql);
491 
492  $record = new self($this->db);
493  $record->setVarsFromFetchObj($obj);
494 
495  $records[$record->id] = $record;
496 
497  $i++;
498  }
499  $this->db->free($resql);
500 
501  return $records;
502  } else {
503  $this->errors[] = 'Error '.$this->db->lasterror();
504  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
505 
506  return -1;
507  }
508  }
509 
517  public function update(User $user, $notrigger = false)
518  {
519  return $this->updateCommon($user, $notrigger);
520  }
521 
529  public function delete(User $user, $notrigger = false)
530  {
531  return $this->deleteCommon($user, $notrigger);
532  //return $this->deleteCommon($user, $notrigger, 1);
533  }
534 
543  public function deleteLine(User $user, $idline, $notrigger = false)
544  {
545  if ($this->status < 0) {
546  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
547  return -2;
548  }
549 
550  return $this->deleteLineCommon($user, $idline, $notrigger);
551  }
552 
553 
561  public function validate($user, $notrigger = 0)
562  {
563  global $conf, $langs;
564 
565  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
566 
567  $error = 0;
568 
569  // Protection
570  if ($this->status == self::STATUS_VALIDATED) {
571  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
572  return 0;
573  }
574 
575  /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','write'))
576  || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && !empty($user->rights->mymodule->myobject->myobject_advance->validate))))
577  {
578  $this->error='NotEnoughPermissions';
579  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
580  return -1;
581  }*/
582 
583  $now = dol_now();
584 
585  $this->db->begin();
586 
587  // Define new ref
588  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
589  $num = $this->getNextNumRef();
590  } else {
591  $num = $this->ref;
592  }
593  $this->newref = $num;
594 
595  if (!empty($num)) {
596  // Validate
597  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
598  $sql .= " SET ref = '".$this->db->escape($num)."',";
599  $sql .= " status = ".self::STATUS_VALIDATED;
600  if (!empty($this->fields['date_validation'])) {
601  $sql .= ", date_validation = '".$this->db->idate($now)."'";
602  }
603  if (!empty($this->fields['fk_user_valid'])) {
604  $sql .= ", fk_user_valid = ".((int) $user->id);
605  }
606  $sql .= " WHERE rowid = ".((int) $this->id);
607 
608  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
609  $resql = $this->db->query($sql);
610  if (!$resql) {
611  dol_print_error($this->db);
612  $this->error = $this->db->lasterror();
613  $error++;
614  }
615 
616  if (!$error && !$notrigger) {
617  // Call trigger
618  $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
619  if ($result < 0) {
620  $error++;
621  }
622  // End call triggers
623  }
624  }
625 
626  if (!$error) {
627  $this->oldref = $this->ref;
628 
629  // Rename directory if dir was a temporary ref
630  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
631  // Now we rename also files into index
632  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'myobject/".$this->db->escape($this->newref)."'";
633  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
634  $resql = $this->db->query($sql);
635  if (!$resql) {
636  $error++; $this->error = $this->db->lasterror();
637  }
638  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'myobject/".$this->db->escape($this->newref)."'";
639  $sql .= " WHERE filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
640  $resql = $this->db->query($sql);
641  if (!$resql) {
642  $error++; $this->error = $this->db->lasterror();
643  }
644 
645  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
646  $oldref = dol_sanitizeFileName($this->ref);
647  $newref = dol_sanitizeFileName($num);
648  $dirsource = $conf->mymodule->dir_output.'/myobject/'.$oldref;
649  $dirdest = $conf->mymodule->dir_output.'/myobject/'.$newref;
650  if (!$error && file_exists($dirsource)) {
651  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
652 
653  if (@rename($dirsource, $dirdest)) {
654  dol_syslog("Rename ok");
655  // Rename docs starting with $oldref with $newref
656  $listoffiles = dol_dir_list($conf->mymodule->dir_output.'/myobject/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
657  foreach ($listoffiles as $fileentry) {
658  $dirsource = $fileentry['name'];
659  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
660  $dirsource = $fileentry['path'].'/'.$dirsource;
661  $dirdest = $fileentry['path'].'/'.$dirdest;
662  @rename($dirsource, $dirdest);
663  }
664  }
665  }
666  }
667  }
668 
669  // Set new ref and current status
670  if (!$error) {
671  $this->ref = $num;
672  $this->status = self::STATUS_VALIDATED;
673  }
674 
675  if (!$error) {
676  $this->db->commit();
677  return 1;
678  } else {
679  $this->db->rollback();
680  return -1;
681  }
682  }
683 
684 
692  public function setDraft($user, $notrigger = 0)
693  {
694  // Protection
695  if ($this->status <= self::STATUS_DRAFT) {
696  return 0;
697  }
698 
699  /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','write'))
700  || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','mymodule_advance','validate'))))
701  {
702  $this->error='Permission denied';
703  return -1;
704  }*/
705 
706  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYMODULE_MYOBJECT_UNVALIDATE');
707  }
708 
716  public function cancel($user, $notrigger = 0)
717  {
718  // Protection
719  if ($this->status != self::STATUS_VALIDATED) {
720  return 0;
721  }
722 
723  /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','write'))
724  || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','mymodule_advance','validate'))))
725  {
726  $this->error='Permission denied';
727  return -1;
728  }*/
729 
730  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYMODULE_MYOBJECT_CANCEL');
731  }
732 
740  public function reopen($user, $notrigger = 0)
741  {
742  // Protection
743  if ($this->status == self::STATUS_VALIDATED) {
744  return 0;
745  }
746 
747  /*if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','write'))
748  || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('mymodule','mymodule_advance','validate'))))
749  {
750  $this->error='Permission denied';
751  return -1;
752  }*/
753 
754  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYMODULE_MYOBJECT_REOPEN');
755  }
756 
764  public function getTooltipContentArray($params)
765  {
766  global $conf, $langs;
767 
768  $datas = [];
769 
770  if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
771  return ['optimize' => $langs->trans("ShowMyObject")];
772  }
773  $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans("MyObject").'</u>';
774  if (isset($this->status)) {
775  $datas['picto'] .= ' '.$this->getLibStatut(5);
776  }
777  $datas['ref'] .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
778 
779  return $datas;
780  }
781 
792  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
793  {
794  global $conf, $langs, $hookmanager;
795 
796  if (!empty($conf->dol_no_mouse_hover)) {
797  $notooltip = 1; // Force disable tooltips
798  }
799 
800  $result = '';
801  $params = [
802  'id' => $this->id,
803  'objecttype' => $this->element.($this->module ? '@'.$this->module : ''),
804  'option' => $option,
805  ];
806  $classfortooltip = 'classfortooltip';
807  $dataparams = '';
808  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
809  $classfortooltip = 'classforajaxtooltip';
810  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
811  $label = '';
812  } else {
813  $label = implode($this->getTooltipContentArray($params));
814  }
815 
816  $url = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$this->id;
817 
818  if ($option !== 'nolink') {
819  // Add param to save lastsearch_values or not
820  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
821  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
822  $add_save_lastsearch_values = 1;
823  }
824  if ($url && $add_save_lastsearch_values) {
825  $url .= '&save_lastsearch_values=1';
826  }
827  }
828 
829  $linkclose = '';
830  if (empty($notooltip)) {
831  if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
832  $label = $langs->trans("ShowMyObject");
833  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
834  }
835  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
836  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
837  } else {
838  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
839  }
840 
841  if ($option == 'nolink' || empty($url)) {
842  $linkstart = '<span';
843  } else {
844  $linkstart = '<a href="'.$url.'"';
845  }
846  $linkstart .= $linkclose.'>';
847  if ($option == 'nolink' || empty($url)) {
848  $linkend = '</span>';
849  } else {
850  $linkend = '</a>';
851  }
852 
853  $result .= $linkstart;
854 
855  if (empty($this->showphoto_on_popup)) {
856  if ($withpicto) {
857  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
858  }
859  } else {
860  if ($withpicto) {
861  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
862 
863  list($class, $module) = explode('@', $this->picto);
864  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
865  $filearray = dol_dir_list($upload_dir, "files");
866  $filename = $filearray[0]['name'];
867  if (!empty($filename)) {
868  $pospoint = strpos($filearray[0]['name'], '.');
869 
870  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
871  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
872  $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
873  } else {
874  $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
875  }
876 
877  $result .= '</div>';
878  } else {
879  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
880  }
881  }
882  }
883 
884  if ($withpicto != 2) {
885  $result .= $this->ref;
886  }
887 
888  $result .= $linkend;
889  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
890 
891  global $action, $hookmanager;
892  $hookmanager->initHooks(array($this->element.'dao'));
893  $parameters = array('id' => $this->id, 'getnomurl' => &$result);
894  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
895  if ($reshook > 0) {
896  $result = $hookmanager->resPrint;
897  } else {
898  $result .= $hookmanager->resPrint;
899  }
900 
901  return $result;
902  }
903 
911  public function getKanbanView($option = '', $arraydata = null)
912  {
913  global $conf, $langs;
914 
915  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
916 
917  $return = '<div class="box-flex-item box-flex-grow-zero">';
918  $return .= '<div class="info-box info-box-sm">';
919  $return .= '<span class="info-box-icon bg-infobox-action">';
920  $return .= img_picto('', $this->picto);
921  $return .= '</span>';
922  $return .= '<div class="info-box-content">';
923  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
924  if ($selected >= 0) {
925  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
926  }
927  if (property_exists($this, 'label')) {
928  $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
929  }
930  if (property_exists($this, 'thirdparty') && is_object($this->thirdparty)) {
931  $return .= '<br><div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).'</div>';
932  }
933  if (property_exists($this, 'amount')) {
934  $return .= '<br>';
935  $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
936  }
937  if (method_exists($this, 'getLibStatut')) {
938  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
939  }
940  $return .= '</div>';
941  $return .= '</div>';
942  $return .= '</div>';
943 
944  return $return;
945  }
946 
953  public function getLabelStatus($mode = 0)
954  {
955  return $this->LibStatut($this->status, $mode);
956  }
957 
964  public function getLibStatut($mode = 0)
965  {
966  return $this->LibStatut($this->status, $mode);
967  }
968 
969  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
977  public function LibStatut($status, $mode = 0)
978  {
979  // phpcs:enable
980  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
981  global $langs;
982  //$langs->load("mymodule@mymodule");
983  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
984  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
985  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
986  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
987  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
988  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
989  }
990 
991  $statusType = 'status'.$status;
992  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
993  if ($status == self::STATUS_CANCELED) {
994  $statusType = 'status6';
995  }
996 
997  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
998  }
999 
1006  public function info($id)
1007  {
1008  $sql = "SELECT rowid,";
1009  $sql .= " date_creation as datec, tms as datem,";
1010  $sql .= " fk_user_creat, fk_user_modif";
1011  $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
1012  $sql .= " WHERE t.rowid = ".((int) $id);
1013 
1014  $result = $this->db->query($sql);
1015  if ($result) {
1016  if ($this->db->num_rows($result)) {
1017  $obj = $this->db->fetch_object($result);
1018 
1019  $this->id = $obj->rowid;
1020 
1021  $this->user_creation_id = $obj->fk_user_creat;
1022  $this->user_modification_id = $obj->fk_user_modif;
1023  if (!empty($obj->fk_user_valid)) {
1024  $this->user_validation_id = $obj->fk_user_valid;
1025  }
1026  $this->date_creation = $this->db->jdate($obj->datec);
1027  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1028  if (!empty($obj->datev)) {
1029  $this->date_validation = empty($obj->datev) ? '' : $this->db->jdate($obj->datev);
1030  }
1031  }
1032 
1033  $this->db->free($result);
1034  } else {
1035  dol_print_error($this->db);
1036  }
1037  }
1038 
1045  public function initAsSpecimen()
1046  {
1047  // Set here init that are not commonf fields
1048  // $this->property1 = ...
1049  // $this->property2 = ...
1050 
1051  $this->initAsSpecimenCommon();
1052  }
1053 
1059  public function getLinesArray()
1060  {
1061  $this->lines = array();
1062 
1063  $objectline = new MyObjectLine($this->db);
1064  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.((int) $this->id)));
1065 
1066  if (is_numeric($result)) {
1067  $this->setErrorsFromObject($objectline);
1068  return $result;
1069  } else {
1070  $this->lines = $result;
1071  return $this->lines;
1072  }
1073  }
1074 
1080  public function getNextNumRef()
1081  {
1082  global $langs, $conf;
1083  $langs->load("mymodule@mymodule");
1084 
1085  if (!getDolGlobalString('MYMODULE_MYOBJECT_ADDON')) {
1086  $conf->global->MYMODULE_MYOBJECT_ADDON = 'mod_myobject_standard';
1087  }
1088 
1089  if (getDolGlobalString('MYMODULE_MYOBJECT_ADDON')) {
1090  $mybool = false;
1091 
1092  $file = getDolGlobalString('MYMODULE_MYOBJECT_ADDON').".php";
1093  $classname = getDolGlobalString('MYMODULE_MYOBJECT_ADDON');
1094 
1095  // Include file with class
1096  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1097  foreach ($dirmodels as $reldir) {
1098  $dir = dol_buildpath($reldir."core/modules/mymodule/");
1099 
1100  // Load file with numbering class (if found)
1101  $mybool |= @include_once $dir.$file;
1102  }
1103 
1104  if ($mybool === false) {
1105  dol_print_error('', "Failed to include file ".$file);
1106  return '';
1107  }
1108 
1109  if (class_exists($classname)) {
1110  $obj = new $classname();
1111  $numref = $obj->getNextValue($this);
1112 
1113  if ($numref != '' && $numref != '-1') {
1114  return $numref;
1115  } else {
1116  $this->error = $obj->error;
1117  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1118  return "";
1119  }
1120  } else {
1121  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1122  return "";
1123  }
1124  } else {
1125  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1126  return "";
1127  }
1128  }
1129 
1141  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1142  {
1143  global $conf, $langs;
1144 
1145  $result = 0;
1146  $includedocgeneration = 0;
1147 
1148  $langs->load("mymodule@mymodule");
1149 
1150  if (!dol_strlen($modele)) {
1151  $modele = 'standard_myobject';
1152 
1153  if (!empty($this->model_pdf)) {
1154  $modele = $this->model_pdf;
1155  } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) {
1156  $modele = getDolGlobalString('MYOBJECT_ADDON_PDF');
1157  }
1158  }
1159 
1160  $modelpath = "core/modules/mymodule/doc/";
1161 
1162  if ($includedocgeneration && !empty($modele)) {
1163  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1164  }
1165 
1166  return $result;
1167  }
1168 
1176  public function doScheduledJob()
1177  {
1178  //global $conf, $langs;
1179 
1180  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1181 
1182  $error = 0;
1183  $this->output = '';
1184  $this->error = '';
1185 
1186  dol_syslog(__METHOD__, LOG_DEBUG);
1187 
1188  $now = dol_now();
1189 
1190  $this->db->begin();
1191 
1192  // ...
1193 
1194  $this->db->commit();
1195 
1196  return $error;
1197  }
1198 }
1199 
1200 
1201 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1202 
1207 {
1208  // To complete with content of an object MyObjectLine
1209  // We should have a field rowid, fk_myobject and position
1210 
1214  public $isextrafieldmanaged = 0;
1215 
1221  public function __construct(DoliDB $db)
1222  {
1223  $this->db = $db;
1224  }
1225 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
setErrorsFromObject($object)
setErrorsFromObject
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
Load object in memory from the database.
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 for MyObject.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
createFromClone(User $user, $fromid)
Clone an object into another one.
getKanbanView($option='', $arraydata=null)
Return a thumb for kanban views.
getLibStatut($mode=0)
Return the label of the status.
fetch($id, $ref=null)
Load object in memory from the database.
getTooltipContentArray($params)
getTooltipContentArray
reopen($user, $notrigger=0)
Set back to validated status.
setDraft($user, $notrigger=0)
Set draft status.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
LibStatut($status, $mode=0)
Return the label of a given status.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
__construct(DoliDB $db)
Constructor.
cancel($user, $notrigger=0)
Set cancel status.
fetchLines()
Load object lines in memory from the database.
update(User $user, $notrigger=false)
Update object into database.
info($id)
Load the info information in the object.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
getLabelStatus($mode=0)
Return the label of the status.
create(User $user, $notrigger=false)
Create object into database.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
validate($user, $notrigger=0)
Validate object.
getLinesArray()
Create an array of lines.
Class MyObjectLine.
__construct(DoliDB $db)
Constructor.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.