dolibarr  x.y.z
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) ---Put here your own copyright and developer email---
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 // Put here all includes required by your class file
26 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
27 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
28 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
29 
33 class MyObject extends CommonObject
34 {
38  public $module = 'mymodule';
39 
43  public $element = 'myobject';
44 
48  public $table_element = 'mymodule_myobject';
49 
54  public $ismultientitymanaged = 0;
55 
59  public $isextrafieldmanaged = 1;
60 
64  public $picto = 'fa-file';
65 
66 
67  const STATUS_DRAFT = 0;
68  const STATUS_VALIDATED = 1;
69  const STATUS_CANCELED = 9;
70 
71 
111  // BEGIN MODULEBUILDER PROPERTIES
115  public $fields = array(
116  'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'),
117  'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>10),
118  '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),
119  '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),
120  '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),
121  '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),
122  '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'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
123  'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
124  'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1),
125  'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'),
126  'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1, 'cssview'=>'wordbreak'),
127  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500),
128  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501),
129  //'date_validation ' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502),
130  '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'),
131  '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'),
132  //'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512),
133  'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'notnull'=>0, 'position'=>600),
134  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000),
135  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'notnull'=>-1, 'position'=>1010),
136  '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),
137  );
138 
142  public $rowid;
143 
147  public $ref;
148 
152  public $entity;
153 
157  public $label;
158 
162  public $amount;
163 
167  public $socid; // both socid and fk_soc are used
168  public $fk_soc; // both socid and fk_soc are used
169 
173  public $status;
174 
178  public $date_creation;
179 
183  public $tms;
184 
188  public $fk_user_creat;
189 
193  public $fk_user_modif;
194 
198  public $last_main_doc;
199 
203  public $import_key;
204  // END MODULEBUILDER PROPERTIES
205 
206 
207  // If this object has a subtable with lines
208 
209  // /**
210  // * @var string Name of subtable line
211  // */
212  // public $table_element_line = 'mymodule_myobjectline';
213 
214  // /**
215  // * @var string Field with ID of parent key if this object has a parent
216  // */
217  // public $fk_element = 'fk_myobject';
218 
219  // /**
220  // * @var string Name of subtable class that manage subtable lines
221  // */
222  // public $class_element_line = 'MyObjectline';
223 
224  // /**
225  // * @var array List of child tables. To test if we can delete object.
226  // */
227  // protected $childtables = array();
228 
229  // /**
230  // * @var array List of child tables. To know object to delete on cascade.
231  // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
232  // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
233  // */
234  // protected $childtablesoncascade = array('mymodule_myobjectdet');
235 
236  // /**
237  // * @var MyObjectLine[] Array of subtable lines
238  // */
239  // public $lines = array();
240 
241 
242 
248  public function __construct(DoliDB $db)
249  {
250  global $conf, $langs;
251 
252  $this->db = $db;
253 
254  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
255  $this->fields['rowid']['visible'] = 0;
256  }
257  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
258  $this->fields['entity']['enabled'] = 0;
259  }
260 
261  // Example to show how to set values of fields definition dynamically
262  /*if ($user->rights->mymodule->myobject->read) {
263  $this->fields['myfield']['visible'] = 1;
264  $this->fields['myfield']['noteditable'] = 0;
265  }*/
266 
267  // Unset fields that are disabled
268  foreach ($this->fields as $key => $val) {
269  if (isset($val['enabled']) && empty($val['enabled'])) {
270  unset($this->fields[$key]);
271  }
272  }
273 
274  // Translate some data of arrayofkeyval
275  if (is_object($langs)) {
276  foreach ($this->fields as $key => $val) {
277  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
278  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
279  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
280  }
281  }
282  }
283  }
284  }
285 
293  public function create(User $user, $notrigger = false)
294  {
295  $resultcreate = $this->createCommon($user, $notrigger);
296 
297  //$resultvalidate = $this->validate($user, $notrigger);
298 
299  return $resultcreate;
300  }
301 
309  public function createFromClone(User $user, $fromid)
310  {
311  global $langs, $extrafields;
312  $error = 0;
313 
314  dol_syslog(__METHOD__, LOG_DEBUG);
315 
316  $object = new self($this->db);
317 
318  $this->db->begin();
319 
320  // Load source object
321  $result = $object->fetchCommon($fromid);
322  if ($result > 0 && !empty($object->table_element_line)) {
323  $object->fetchLines();
324  }
325 
326  // get lines so they will be clone
327  //foreach($this->lines as $line)
328  // $line->fetch_optionals();
329 
330  // Reset some properties
331  unset($object->id);
332  unset($object->fk_user_creat);
333  unset($object->import_key);
334 
335  // Clear fields
336  if (property_exists($object, 'ref')) {
337  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
338  }
339  if (property_exists($object, 'label')) {
340  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
341  }
342  if (property_exists($object, 'status')) {
343  $object->status = self::STATUS_DRAFT;
344  }
345  if (property_exists($object, 'date_creation')) {
346  $object->date_creation = dol_now();
347  }
348  if (property_exists($object, 'date_modification')) {
349  $object->date_modification = null;
350  }
351  // ...
352  // Clear extrafields that are unique
353  if (is_array($object->array_options) && count($object->array_options) > 0) {
354  $extrafields->fetch_name_optionals_label($this->table_element);
355  foreach ($object->array_options as $key => $option) {
356  $shortkey = preg_replace('/options_/', '', $key);
357  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
358  //var_dump($key);
359  //var_dump($clonedObj->array_options[$key]); exit;
360  unset($object->array_options[$key]);
361  }
362  }
363  }
364 
365  // Create clone
366  $object->context['createfromclone'] = 'createfromclone';
367  $result = $object->createCommon($user);
368  if ($result < 0) {
369  $error++;
370  $this->error = $object->error;
371  $this->errors = $object->errors;
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  global $conf;
446 
447  dol_syslog(__METHOD__, LOG_DEBUG);
448 
449  $records = array();
450 
451  $sql = "SELECT ";
452  $sql .= $this->getFieldList('t');
453  $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
454  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
455  $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
456  } else {
457  $sql .= " WHERE 1 = 1";
458  }
459  // Manage filter
460  $sqlwhere = array();
461  if (count($filter) > 0) {
462  foreach ($filter as $key => $value) {
463  if ($key == 't.rowid') {
464  $sqlwhere[] = $key." = ".((int) $value);
465  } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
466  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
467  } elseif ($key == 'customsql') {
468  $sqlwhere[] = $value;
469  } elseif (strpos($value, '%') === false) {
470  $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
471  } else {
472  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
473  }
474  }
475  }
476  if (count($sqlwhere) > 0) {
477  $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
478  }
479 
480  if (!empty($sortfield)) {
481  $sql .= $this->db->order($sortfield, $sortorder);
482  }
483  if (!empty($limit)) {
484  $sql .= $this->db->plimit($limit, $offset);
485  }
486 
487  $resql = $this->db->query($sql);
488  if ($resql) {
489  $num = $this->db->num_rows($resql);
490  $i = 0;
491  while ($i < ($limit ? min($limit, $num) : $num)) {
492  $obj = $this->db->fetch_object($resql);
493 
494  $record = new self($this->db);
495  $record->setVarsFromFetchObj($obj);
496 
497  $records[$record->id] = $record;
498 
499  $i++;
500  }
501  $this->db->free($resql);
502 
503  return $records;
504  } else {
505  $this->errors[] = 'Error '.$this->db->lasterror();
506  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
507 
508  return -1;
509  }
510  }
511 
519  public function update(User $user, $notrigger = false)
520  {
521  return $this->updateCommon($user, $notrigger);
522  }
523 
531  public function delete(User $user, $notrigger = false)
532  {
533  return $this->deleteCommon($user, $notrigger);
534  //return $this->deleteCommon($user, $notrigger, 1);
535  }
536 
545  public function deleteLine(User $user, $idline, $notrigger = false)
546  {
547  if ($this->status < 0) {
548  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
549  return -2;
550  }
551 
552  return $this->deleteLineCommon($user, $idline, $notrigger);
553  }
554 
555 
563  public function validate($user, $notrigger = 0)
564  {
565  global $conf, $langs;
566 
567  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
568 
569  $error = 0;
570 
571  // Protection
572  if ($this->status == self::STATUS_VALIDATED) {
573  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
574  return 0;
575  }
576 
577  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->myobject->write))
578  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->myobject->myobject_advance->validate))))
579  {
580  $this->error='NotEnoughPermissions';
581  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
582  return -1;
583  }*/
584 
585  $now = dol_now();
586 
587  $this->db->begin();
588 
589  // Define new ref
590  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
591  $num = $this->getNextNumRef();
592  } else {
593  $num = $this->ref;
594  }
595  $this->newref = $num;
596 
597  if (!empty($num)) {
598  // Validate
599  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
600  $sql .= " SET ref = '".$this->db->escape($num)."',";
601  $sql .= " status = ".self::STATUS_VALIDATED;
602  if (!empty($this->fields['date_validation'])) {
603  $sql .= ", date_validation = '".$this->db->idate($now)."'";
604  }
605  if (!empty($this->fields['fk_user_valid'])) {
606  $sql .= ", fk_user_valid = ".((int) $user->id);
607  }
608  $sql .= " WHERE rowid = ".((int) $this->id);
609 
610  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
611  $resql = $this->db->query($sql);
612  if (!$resql) {
613  dol_print_error($this->db);
614  $this->error = $this->db->lasterror();
615  $error++;
616  }
617 
618  if (!$error && !$notrigger) {
619  // Call trigger
620  $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
621  if ($result < 0) {
622  $error++;
623  }
624  // End call triggers
625  }
626  }
627 
628  if (!$error) {
629  $this->oldref = $this->ref;
630 
631  // Rename directory if dir was a temporary ref
632  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
633  // Now we rename also files into index
634  $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)."'";
635  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
636  $resql = $this->db->query($sql);
637  if (!$resql) {
638  $error++; $this->error = $this->db->lasterror();
639  }
640 
641  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
642  $oldref = dol_sanitizeFileName($this->ref);
643  $newref = dol_sanitizeFileName($num);
644  $dirsource = $conf->mymodule->dir_output.'/myobject/'.$oldref;
645  $dirdest = $conf->mymodule->dir_output.'/myobject/'.$newref;
646  if (!$error && file_exists($dirsource)) {
647  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
648 
649  if (@rename($dirsource, $dirdest)) {
650  dol_syslog("Rename ok");
651  // Rename docs starting with $oldref with $newref
652  $listoffiles = dol_dir_list($conf->mymodule->dir_output.'/myobject/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
653  foreach ($listoffiles as $fileentry) {
654  $dirsource = $fileentry['name'];
655  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
656  $dirsource = $fileentry['path'].'/'.$dirsource;
657  $dirdest = $fileentry['path'].'/'.$dirdest;
658  @rename($dirsource, $dirdest);
659  }
660  }
661  }
662  }
663  }
664 
665  // Set new ref and current status
666  if (!$error) {
667  $this->ref = $num;
668  $this->status = self::STATUS_VALIDATED;
669  }
670 
671  if (!$error) {
672  $this->db->commit();
673  return 1;
674  } else {
675  $this->db->rollback();
676  return -1;
677  }
678  }
679 
680 
688  public function setDraft($user, $notrigger = 0)
689  {
690  // Protection
691  if ($this->status <= self::STATUS_DRAFT) {
692  return 0;
693  }
694 
695  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
696  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
697  {
698  $this->error='Permission denied';
699  return -1;
700  }*/
701 
702  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
703  }
704 
712  public function cancel($user, $notrigger = 0)
713  {
714  // Protection
715  if ($this->status != self::STATUS_VALIDATED) {
716  return 0;
717  }
718 
719  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
720  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
721  {
722  $this->error='Permission denied';
723  return -1;
724  }*/
725 
726  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
727  }
728 
736  public function reopen($user, $notrigger = 0)
737  {
738  // Protection
739  if ($this->status == self::STATUS_VALIDATED) {
740  return 0;
741  }
742 
743  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
744  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
745  {
746  $this->error='Permission denied';
747  return -1;
748  }*/
749 
750  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
751  }
752 
763  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
764  {
765  global $conf, $langs, $hookmanager;
766 
767  if (!empty($conf->dol_no_mouse_hover)) {
768  $notooltip = 1; // Force disable tooltips
769  }
770 
771  $result = '';
772 
773  $label = img_picto('', $this->picto).' <u>'.$langs->trans("MyObject").'</u>';
774  if (isset($this->status)) {
775  $label .= ' '.$this->getLibStatut(5);
776  }
777  $label .= '<br>';
778  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
779 
780  $url = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$this->id;
781 
782  if ($option != 'nolink') {
783  // Add param to save lastsearch_values or not
784  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
785  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
786  $add_save_lastsearch_values = 1;
787  }
788  if ($url && $add_save_lastsearch_values) {
789  $url .= '&save_lastsearch_values=1';
790  }
791  }
792 
793  $linkclose = '';
794  if (empty($notooltip)) {
795  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
796  $label = $langs->trans("ShowMyObject");
797  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
798  }
799  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
800  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
801  } else {
802  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
803  }
804 
805  if ($option == 'nolink' || empty($url)) {
806  $linkstart = '<span';
807  } else {
808  $linkstart = '<a href="'.$url.'"';
809  }
810  $linkstart .= $linkclose.'>';
811  if ($option == 'nolink' || empty($url)) {
812  $linkend = '</span>';
813  } else {
814  $linkend = '</a>';
815  }
816 
817  $result .= $linkstart;
818 
819  if (empty($this->showphoto_on_popup)) {
820  if ($withpicto) {
821  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
822  }
823  } else {
824  if ($withpicto) {
825  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
826 
827  list($class, $module) = explode('@', $this->picto);
828  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
829  $filearray = dol_dir_list($upload_dir, "files");
830  $filename = $filearray[0]['name'];
831  if (!empty($filename)) {
832  $pospoint = strpos($filearray[0]['name'], '.');
833 
834  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
835  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
836  $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>';
837  } else {
838  $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>';
839  }
840 
841  $result .= '</div>';
842  } else {
843  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
844  }
845  }
846  }
847 
848  if ($withpicto != 2) {
849  $result .= $this->ref;
850  }
851 
852  $result .= $linkend;
853  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
854 
855  global $action, $hookmanager;
856  $hookmanager->initHooks(array($this->element.'dao'));
857  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
858  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
859  if ($reshook > 0) {
860  $result = $hookmanager->resPrint;
861  } else {
862  $result .= $hookmanager->resPrint;
863  }
864 
865  return $result;
866  }
867 
874  /*
875  public function getKanbanView($option = '')
876  {
877  $return = '<div class="box-flex-item box-flex-grow-zero">';
878  $return .= '<div class="info-box info-box-sm">';
879  $return .= '<span class="info-box-icon bg-infobox-action">';
880  $return .= img_picto('', $this->picto);
881  $return .= '</span>';
882  $return .= '<div class="info-box-content">';
883  $return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
884  if (property_exists($this, 'label')) {
885  $return .= '<br><span class="info-box-label opacitymedium">'.$this->label.'</span>';
886  }
887  if (method_exists($this, 'getLibStatut')) {
888  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(5).'</div>';
889  }
890  $return .= '</div>';
891  $return .= '</div>';
892  $return .= '</div>';
893 
894  return $return;
895  }
896  */
897 
904  public function getLabelStatus($mode = 0)
905  {
906  return $this->LibStatut($this->status, $mode);
907  }
908 
915  public function getLibStatut($mode = 0)
916  {
917  return $this->LibStatut($this->status, $mode);
918  }
919 
920  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
928  public function LibStatut($status, $mode = 0)
929  {
930  // phpcs:enable
931  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
932  global $langs;
933  //$langs->load("mymodule@mymodule");
934  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
935  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
936  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
937  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
938  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
939  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
940  }
941 
942  $statusType = 'status'.$status;
943  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
944  if ($status == self::STATUS_CANCELED) {
945  $statusType = 'status6';
946  }
947 
948  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
949  }
950 
957  public function info($id)
958  {
959  $sql = "SELECT rowid,";
960  $sql .= " date_creation as datec, tms as datem,";
961  $sql .= " fk_user_creat, fk_user_modif";
962  $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
963  $sql .= " WHERE t.rowid = ".((int) $id);
964 
965  $result = $this->db->query($sql);
966  if ($result) {
967  if ($this->db->num_rows($result)) {
968  $obj = $this->db->fetch_object($result);
969 
970  $this->id = $obj->rowid;
971 
972  $this->user_creation_id = $obj->fk_user_creat;
973  $this->user_modification_id = $obj->fk_user_modif;
974  if (!empty($obj->fk_user_valid)) {
975  $this->user_validation_id = $obj->fk_user_valid;
976  }
977  $this->date_creation = $this->db->jdate($obj->datec);
978  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
979  if (!empty($obj->datev)) {
980  $this->date_validation = empty($obj->datev) ? '' : $this->db->jdate($obj->datev);
981  }
982  }
983 
984  $this->db->free($result);
985  } else {
986  dol_print_error($this->db);
987  }
988  }
989 
996  public function initAsSpecimen()
997  {
998  // Set here init that are not commonf fields
999  // $this->property1 = ...
1000  // $this->property2 = ...
1001 
1002  $this->initAsSpecimenCommon();
1003  }
1004 
1010  public function getLinesArray()
1011  {
1012  $this->lines = array();
1013 
1014  $objectline = new MyObjectLine($this->db);
1015  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.((int) $this->id)));
1016 
1017  if (is_numeric($result)) {
1018  $this->error = $objectline->error;
1019  $this->errors = $objectline->errors;
1020  return $result;
1021  } else {
1022  $this->lines = $result;
1023  return $this->lines;
1024  }
1025  }
1026 
1032  public function getNextNumRef()
1033  {
1034  global $langs, $conf;
1035  $langs->load("mymodule@mymodule");
1036 
1037  if (empty($conf->global->MYMODULE_MYOBJECT_ADDON)) {
1038  $conf->global->MYMODULE_MYOBJECT_ADDON = 'mod_myobject_standard';
1039  }
1040 
1041  if (!empty($conf->global->MYMODULE_MYOBJECT_ADDON)) {
1042  $mybool = false;
1043 
1044  $file = $conf->global->MYMODULE_MYOBJECT_ADDON.".php";
1045  $classname = $conf->global->MYMODULE_MYOBJECT_ADDON;
1046 
1047  // Include file with class
1048  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1049  foreach ($dirmodels as $reldir) {
1050  $dir = dol_buildpath($reldir."core/modules/mymodule/");
1051 
1052  // Load file with numbering class (if found)
1053  $mybool |= @include_once $dir.$file;
1054  }
1055 
1056  if ($mybool === false) {
1057  dol_print_error('', "Failed to include file ".$file);
1058  return '';
1059  }
1060 
1061  if (class_exists($classname)) {
1062  $obj = new $classname();
1063  $numref = $obj->getNextValue($this);
1064 
1065  if ($numref != '' && $numref != '-1') {
1066  return $numref;
1067  } else {
1068  $this->error = $obj->error;
1069  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1070  return "";
1071  }
1072  } else {
1073  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1074  return "";
1075  }
1076  } else {
1077  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1078  return "";
1079  }
1080  }
1081 
1093  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1094  {
1095  global $conf, $langs;
1096 
1097  $result = 0;
1098  $includedocgeneration = 0;
1099 
1100  $langs->load("mymodule@mymodule");
1101 
1102  if (!dol_strlen($modele)) {
1103  $modele = 'standard_myobject';
1104 
1105  if (!empty($this->model_pdf)) {
1106  $modele = $this->model_pdf;
1107  } elseif (!empty($conf->global->MYOBJECT_ADDON_PDF)) {
1108  $modele = $conf->global->MYOBJECT_ADDON_PDF;
1109  }
1110  }
1111 
1112  $modelpath = "core/modules/mymodule/doc/";
1113 
1114  if ($includedocgeneration && !empty($modele)) {
1115  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1116  }
1117 
1118  return $result;
1119  }
1120 
1128  public function doScheduledJob()
1129  {
1130  global $conf, $langs;
1131 
1132  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1133 
1134  $error = 0;
1135  $this->output = '';
1136  $this->error = '';
1137 
1138  dol_syslog(__METHOD__, LOG_DEBUG);
1139 
1140  $now = dol_now();
1141 
1142  $this->db->begin();
1143 
1144  // ...
1145 
1146  $this->db->commit();
1147 
1148  return $error;
1149  }
1150 }
1151 
1152 
1153 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1154 
1159 {
1160  // To complete with content of an object MyObjectLine
1161  // We should have a field rowid, fk_myobject and position
1162 
1166  public $isextrafieldmanaged = 0;
1167 
1173  public function __construct(DoliDB $db)
1174  {
1175  $this->db = $db;
1176  }
1177 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getFieldList($alias='')
Function to concat keys of fields.
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.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
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.
getLibStatut($mode=0)
Return the label of the status.
fetch($id, $ref=null)
Load object in memory from the database.
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 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 a thumb for kanban views.
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:45
if(isModEnabled('facture') &&!empty($user->rights->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') &&!empty($user->rights->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)) $resql
Social contributions to pay.
Definition: index.php:745
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:61
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.
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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db
API class for accounts.
Definition: inc.php:41