dolibarr  20.0.0-alpha
calendar.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-2024 Frédéric France <frederic.france@free.fr>
4  * Copyright (C) 2023 Alice Adminson <aadminson@example.com>
5  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
27 // Put here all includes required by your class file
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29 //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
30 //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
31 
35 class Calendar extends CommonObject
36 {
40  public $module = 'bookcal';
41 
45  public $element = 'calendar';
46 
50  public $table_element = 'bookcal_calendar';
51 
56  public $ismultientitymanaged = 1;
57 
61  public $isextrafieldmanaged = 1;
62 
66  public $picto = 'fa-calendar-check';
67 
68 
69  const STATUS_DRAFT = 0;
70  const STATUS_VALIDATED = 1;
71  const STATUS_CANCELED = 9;
72 
73 
113  // BEGIN MODULEBUILDER PROPERTIES
117  public $fields = array(
118  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'right', 'comment' => "Id"),
119  'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
120  'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1, 'comment' => "Reference of object", 'css' => 'width100'),
121  'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => 1, 'alwayseditable' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'help' => "Help text", 'showoncombobox' => 2, 'validate' => 1,),
122  'visibility' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Owner', 'enabled' => 1, 'position' => 40, 'notnull' => 1, 'visible' => 1, 'picto' => 'user', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150',),
123  'type' => array('type' => 'integer', 'label' => 'Type', 'enabled' => 1, 'position' => 42, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array('0' => 'Customer', '1' => 'Supplier', '3' => 'Other'),),
124  'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label' => 'ThirdParty', 'picto' => 'company', 'enabled' => 'isModEnabled("societe")', 'position' => 50, 'notnull' => -1, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150', 'help' => "ThirdPartyBookCalHelp", 'validate' => 1,),
125  'fk_project' => array('type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'picto' => 'project', 'enabled' => 'isModEnabled("project")', 'position' => 52, 'notnull' => -1, 'visible' => -1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150', 'validate' => 1,),
126  'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 3, 'validate' => 1,),
127  'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
128  'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
129  'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
130  'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
131  'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax150',),
132  'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'picto' => 'user', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2, 'csslist' => 'tdoverflowmax150',),
133  'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
134  'status' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'position' => 2000, 'notnull' => 1, 'default' => '0', 'visible' => 1, 'index' => 1, 'arrayofkeyval' => array('0' => 'Draft', '1' => 'Validated', '9' => 'Closed'), 'validate' => 1,),
135  );
136  public $rowid;
137  public $entity;
138  public $ref;
139  public $label;
140  public $type;
141  public $visibility;
142  public $fk_soc;
143  public $fk_project;
144  public $description;
145  public $note_public;
146  public $note_private;
147  public $date_creation;
148  public $fk_user_creat;
149  public $fk_user_modif;
150  public $import_key;
151  public $status;
152  // END MODULEBUILDER PROPERTIES
153 
154 
160  public function __construct(DoliDB $db)
161  {
162  global $langs, $user;
163 
164  $this->db = $db;
165 
166  if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
167  $this->fields['rowid']['visible'] = 0;
168  }
169  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
170  $this->fields['entity']['enabled'] = 0;
171  }
172 
173  // Example to show how to set values of fields definition dynamically
174  /*if ($user->hasRight('bookcal', 'calendar', 'read')) {
175  $this->fields['myfield']['visible'] = 1;
176  $this->fields['myfield']['noteditable'] = 0;
177  }*/
178  $this->fields['visibility']['default'] = $user->id;
179 
180  // Unset fields that are disabled
181  foreach ($this->fields as $key => $val) {
182  if (isset($val['enabled']) && empty($val['enabled'])) {
183  unset($this->fields[$key]);
184  }
185  }
186 
187  // Translate some data of arrayofkeyval
188  if (is_object($langs)) {
189  foreach ($this->fields as $key => $val) {
190  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
191  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
192  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
193  }
194  }
195  }
196  }
197  }
198 
206  public function create(User $user, $notrigger = 0)
207  {
208  $resultcreate = $this->createCommon($user, $notrigger);
209 
210  //$resultvalidate = $this->validate($user, $notrigger);
211 
212  return $resultcreate;
213  }
214 
222  public function createFromClone(User $user, $fromid)
223  {
224  global $langs, $extrafields;
225  $error = 0;
226 
227  dol_syslog(__METHOD__, LOG_DEBUG);
228 
229  $object = new self($this->db);
230 
231  $this->db->begin();
232 
233  // Load source object
234  $result = $object->fetchCommon($fromid);
235  if ($result > 0 && !empty($object->table_element_line)) {
236  $object->fetchLines();
237  }
238 
239  // get lines so they will be clone
240  //foreach($this->lines as $line)
241  // $line->fetch_optionals();
242 
243  // Reset some properties
244  unset($object->id);
245  unset($object->fk_user_creat);
246  unset($object->import_key);
247 
248  // Clear fields
249  if (property_exists($object, 'ref')) {
250  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
251  }
252  if (property_exists($object, 'label')) {
253  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
254  }
255  if (property_exists($object, 'status')) {
256  $object->status = self::STATUS_DRAFT;
257  }
258  if (property_exists($object, 'date_creation')) {
259  $object->date_creation = dol_now();
260  }
261  if (property_exists($object, 'date_modification')) {
262  $object->date_modification = null;
263  }
264  // ...
265  // Clear extrafields that are unique
266  if (is_array($object->array_options) && count($object->array_options) > 0) {
267  $extrafields->fetch_name_optionals_label($this->table_element);
268  foreach ($object->array_options as $key => $option) {
269  $shortkey = preg_replace('/options_/', '', $key);
270  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
271  //var_dump($key);
272  //var_dump($clonedObj->array_options[$key]); exit;
273  unset($object->array_options[$key]);
274  }
275  }
276  }
277 
278  // Create clone
279  $object->context['createfromclone'] = 'createfromclone';
280  $result = $object->createCommon($user);
281  if ($result < 0) {
282  $error++;
284  }
285 
286  if (!$error) {
287  // copy internal contacts
288  if ($this->copy_linked_contact($object, 'internal') < 0) {
289  $error++;
290  }
291  }
292 
293  if (!$error) {
294  // copy external contacts if same company
295  if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
296  if ($this->copy_linked_contact($object, 'external') < 0) {
297  $error++;
298  }
299  }
300  }
301 
302  unset($object->context['createfromclone']);
303 
304  // End
305  if (!$error) {
306  $this->db->commit();
307  return $object;
308  } else {
309  $this->db->rollback();
310  return -1;
311  }
312  }
313 
321  public function fetch($id, $ref = null)
322  {
323  $result = $this->fetchCommon($id, $ref);
324  if ($result > 0 && !empty($this->table_element_line)) {
325  $this->fetchLines();
326  }
327  return $result;
328  }
329 
335  public function fetchLines()
336  {
337  $this->lines = array();
338 
339  $result = $this->fetchLinesCommon();
340  return $result;
341  }
342 
343 
356  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
357  {
358  dol_syslog(__METHOD__, LOG_DEBUG);
359 
360  $records = array();
361 
362  $sql = "SELECT ";
363  $sql .= $this->getFieldList('t');
364  $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
365  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
366  $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
367  } else {
368  $sql .= " WHERE 1 = 1";
369  }
370 
371  // Manage filter
372  $errormessage = '';
373  $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
374  if ($errormessage) {
375  $this->errors[] = $errormessage;
376  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
377  return -1;
378  }
379 
380  if (!empty($sortfield)) {
381  $sql .= $this->db->order($sortfield, $sortorder);
382  }
383  if (!empty($limit)) {
384  $sql .= $this->db->plimit($limit, $offset);
385  }
386 
387  $resql = $this->db->query($sql);
388  if ($resql) {
389  $num = $this->db->num_rows($resql);
390  $i = 0;
391  while ($i < ($limit ? min($limit, $num) : $num)) {
392  $obj = $this->db->fetch_object($resql);
393 
394  $record = new self($this->db);
395  $record->setVarsFromFetchObj($obj);
396 
397  $records[$record->id] = $record;
398 
399  $i++;
400  }
401  $this->db->free($resql);
402 
403  return $records;
404  } else {
405  $this->errors[] = 'Error '.$this->db->lasterror();
406  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
407 
408  return -1;
409  }
410  }
411 
419  public function update(User $user, $notrigger = 0)
420  {
421  return $this->updateCommon($user, $notrigger);
422  }
423 
431  public function delete(User $user, $notrigger = 0)
432  {
433  return $this->deleteCommon($user, $notrigger);
434  //return $this->deleteCommon($user, $notrigger, 1);
435  }
436 
445  public function deleteLine(User $user, $idline, $notrigger = 0)
446  {
447  if ($this->status < 0) {
448  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
449  return -2;
450  }
451 
452  return $this->deleteLineCommon($user, $idline, $notrigger);
453  }
454 
455 
463  public function validate($user, $notrigger = 0)
464  {
465  global $conf;
466 
467  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
468 
469  $error = 0;
470 
471  // Protection
472  if ($this->status == self::STATUS_VALIDATED) {
473  dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
474  return 0;
475  }
476 
477  $now = dol_now();
478 
479  $this->db->begin();
480 
481  // Define new ref
482  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
483  $num = $this->getNextNumRef();
484  } else {
485  $num = $this->ref;
486  }
487  $this->newref = $num;
488 
489  if (!empty($num)) {
490  // Validate
491  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
492  $sql .= " SET ref = '".$this->db->escape($num)."',";
493  $sql .= " status = ".self::STATUS_VALIDATED;
494  if (!empty($this->fields['date_validation'])) {
495  $sql .= ", date_validation = '".$this->db->idate($now)."'";
496  }
497  if (!empty($this->fields['fk_user_valid'])) {
498  $sql .= ", fk_user_valid = ".((int) $user->id);
499  }
500  $sql .= " WHERE rowid = ".((int) $this->id);
501 
502  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
503  $resql = $this->db->query($sql);
504  if (!$resql) {
505  dol_print_error($this->db);
506  $this->error = $this->db->lasterror();
507  $error++;
508  }
509 
510  if (!$error && !$notrigger) {
511  // Call trigger
512  $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
513  if ($result < 0) {
514  $error++;
515  }
516  // End call triggers
517  }
518  }
519 
520  if (!$error) {
521  $this->oldref = $this->ref;
522 
523  // Rename directory if dir was a temporary ref
524  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
525  // Now we rename also files into index
526  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'calendar/".$this->db->escape($this->newref)."'";
527  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
528  $resql = $this->db->query($sql);
529  if (!$resql) {
530  $error++;
531  $this->error = $this->db->lasterror();
532  }
533  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'calendar/".$this->db->escape($this->newref)."'";
534  $sql .= " WHERE filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
535  $resql = $this->db->query($sql);
536  if (!$resql) {
537  $error++;
538  $this->error = $this->db->lasterror();
539  }
540 
541  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
542  $oldref = dol_sanitizeFileName($this->ref);
543  $newref = dol_sanitizeFileName($num);
544  $dirsource = $conf->bookcal->dir_output.'/calendar/'.$oldref;
545  $dirdest = $conf->bookcal->dir_output.'/calendar/'.$newref;
546  if (!$error && file_exists($dirsource)) {
547  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
548 
549  if (@rename($dirsource, $dirdest)) {
550  dol_syslog("Rename ok");
551  // Rename docs starting with $oldref with $newref
552  $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/calendar/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
553  foreach ($listoffiles as $fileentry) {
554  $dirsource = $fileentry['name'];
555  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
556  $dirsource = $fileentry['path'].'/'.$dirsource;
557  $dirdest = $fileentry['path'].'/'.$dirdest;
558  @rename($dirsource, $dirdest);
559  }
560  }
561  }
562  }
563  }
564 
565  // Set new ref and current status
566  if (!$error) {
567  $this->ref = $num;
568  $this->status = self::STATUS_VALIDATED;
569  }
570 
571  if (!$error) {
572  $this->db->commit();
573  return 1;
574  } else {
575  $this->db->rollback();
576  return -1;
577  }
578  }
579 
580 
588  public function setDraft($user, $notrigger = 0)
589  {
590  // Protection
591  if ($this->status <= self::STATUS_DRAFT) {
592  return 0;
593  }
594 
595  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
596  }
597 
605  public function cancel($user, $notrigger = 0)
606  {
607  // Protection
608  if ($this->status != self::STATUS_VALIDATED) {
609  return 0;
610  }
611 
612  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
613  }
614 
622  public function reopen($user, $notrigger = 0)
623  {
624  // Protection
625  if ($this->status == self::STATUS_VALIDATED) {
626  return 0;
627  }
628 
629  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
630  }
631 
639  public function getTooltipContentArray($params)
640  {
641  global $langs;
642 
643  $datas = [];
644 
645  if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
646  return ['optimize' => $langs->trans("ShowCalendar")];
647  }
648  $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans("Calendar").'</u>';
649  if (isset($this->status)) {
650  $datas['picto'] .= ' '.$this->getLibStatut(5);
651  }
652  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
653 
654  return $datas;
655  }
656 
667  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
668  {
669  global $conf, $langs, $hookmanager;
670 
671  if (!empty($conf->dol_no_mouse_hover)) {
672  $notooltip = 1; // Force disable tooltips
673  }
674 
675  $result = '';
676  $params = [
677  'id' => $this->id,
678  'objecttype' => $this->element.($this->module ? '@'.$this->module : ''),
679  'option' => $option,
680  ];
681  $classfortooltip = 'classfortooltip';
682  $dataparams = '';
683  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
684  $classfortooltip = 'classforajaxtooltip';
685  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
686  $label = '';
687  } else {
688  $label = implode($this->getTooltipContentArray($params));
689  }
690 
691  $url = dol_buildpath('/bookcal/calendar_card.php', 1).'?id='.$this->id;
692 
693  if ($option !== 'nolink') {
694  // Add param to save lastsearch_values or not
695  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
696  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
697  $add_save_lastsearch_values = 1;
698  }
699  if ($url && $add_save_lastsearch_values) {
700  $url .= '&save_lastsearch_values=1';
701  }
702  }
703 
704  $linkclose = '';
705  if (empty($notooltip)) {
706  if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
707  $label = $langs->trans("ShowCalendar");
708  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
709  }
710  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
711  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
712  } else {
713  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
714  }
715 
716  if ($option == 'nolink' || empty($url)) {
717  $linkstart = '<span';
718  } else {
719  $linkstart = '<a href="'.$url.'"';
720  }
721  $linkstart .= $linkclose.'>';
722  if ($option == 'nolink' || empty($url)) {
723  $linkend = '</span>';
724  } else {
725  $linkend = '</a>';
726  }
727 
728  $result .= $linkstart;
729 
730  if (empty($this->showphoto_on_popup)) {
731  if ($withpicto) {
732  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
733  }
734  } else {
735  if ($withpicto) {
736  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
737 
738  list($class, $module) = explode('@', $this->picto);
739  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
740  $filearray = dol_dir_list($upload_dir, "files");
741  $filename = $filearray[0]['name'];
742  if (!empty($filename)) {
743  $pospoint = strpos($filearray[0]['name'], '.');
744 
745  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
746  if (!getDolGlobalInt(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
747  $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>';
748  } else {
749  $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>';
750  }
751 
752  $result .= '</div>';
753  } else {
754  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
755  }
756  }
757  }
758 
759  if ($withpicto != 2) {
760  $result .= $this->ref;
761  }
762 
763  $result .= $linkend;
764  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
765 
766  global $action, $hookmanager;
767  $hookmanager->initHooks(array($this->element.'dao'));
768  $parameters = array('id' => $this->id, 'getnomurl' => &$result);
769  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
770  if ($reshook > 0) {
771  $result = $hookmanager->resPrint;
772  } else {
773  $result .= $hookmanager->resPrint;
774  }
775 
776  return $result;
777  }
778 
786  public function getKanbanView($option = '', $arraydata = null)
787  {
788  global $conf, $langs;
789 
790  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
791 
792  $return = '<div class="box-flex-item box-flex-grow-zero">';
793  $return .= '<div class="info-box info-box-sm">';
794  $return .= '<span class="info-box-icon bg-infobox-action">';
795  $return .= img_picto('', $this->picto);
796  $return .= '</span>';
797  $return .= '<div class="info-box-content">';
798  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
799  if ($selected >= 0) {
800  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
801  }
802  if (property_exists($this, 'label')) {
803  $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
804  }
805  if (property_exists($this, 'amount')) {
806  $return .= '<br>';
807  $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
808  }
809  if (method_exists($this, 'getLibStatut')) {
810  $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
811  }
812  $return .= '</div>';
813  $return .= '</div>';
814  $return .= '</div>';
815 
816  return $return;
817  }
818 
825  public function getLabelStatus($mode = 0)
826  {
827  return $this->LibStatut($this->status, $mode);
828  }
829 
836  public function getLibStatut($mode = 0)
837  {
838  return $this->LibStatut($this->status, $mode);
839  }
840 
841  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
849  public function LibStatut($status, $mode = 0)
850  {
851  // phpcs:enable
852  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
853  global $langs;
854 
855  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
856  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
857  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
858  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
859  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
860  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
861  }
862 
863  $statusType = 'status'.$status;
864  if ($status == self::STATUS_VALIDATED) {
865  $statusType = 'status4';
866  }
867  if ($status == self::STATUS_CANCELED) {
868  $statusType = 'status6';
869  }
870 
871  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
872  }
873 
880  public function info($id)
881  {
882  $sql = "SELECT rowid,";
883  $sql .= " date_creation as datec, tms as datem,";
884  $sql .= " fk_user_creat, fk_user_modif";
885  $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
886  $sql .= " WHERE t.rowid = ".((int) $id);
887 
888  $result = $this->db->query($sql);
889  if ($result) {
890  if ($this->db->num_rows($result)) {
891  $obj = $this->db->fetch_object($result);
892 
893  $this->id = $obj->rowid;
894 
895  $this->user_creation_id = $obj->fk_user_creat;
896  $this->user_modification_id = $obj->fk_user_modif;
897  $this->date_creation = $this->db->jdate($obj->datec);
898  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
899  }
900 
901  $this->db->free($result);
902  } else {
903  dol_print_error($this->db);
904  }
905  }
906 
913  public function initAsSpecimen()
914  {
915  // Set here init that are not commonf fields
916  // $this->property1 = ...
917  // $this->property2 = ...
918 
919  return $this->initAsSpecimenCommon();
920  }
921 
927  public function getLinesArray()
928  {
929  $this->lines = array();
930 
931  $objectline = new CalendarLine($this->db);
932  $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_calendar:=:'.((int) $this->id).')');
933 
934  if (is_numeric($result)) {
935  $this->setErrorsFromObject($objectline);
936  return $result;
937  } else {
938  $this->lines = $result;
939  return $this->lines;
940  }
941  }
942 
948  public function getNextNumRef()
949  {
950  global $langs, $conf;
951  $langs->load("agenda");
952 
953  if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
954  $conf->global->BOOKCAL_MYOBJECT_ADDON = 'mod_calendar_standard';
955  }
956 
957  if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
958  $mybool = false;
959 
960  $file = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON').".php";
961  $classname = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON');
962 
963  // Include file with class
964  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
965  foreach ($dirmodels as $reldir) {
966  $dir = dol_buildpath($reldir."core/modules/bookcal/");
967 
968  // Load file with numbering class (if found)
969  $mybool = ((bool) @include_once $dir.$file) || $mybool;
970  }
971 
972  if ($mybool === false) {
973  dol_print_error(null, "Failed to include file ".$file);
974  return '';
975  }
976 
977  if (class_exists($classname)) {
978  $obj = new $classname();
979  $numref = $obj->getNextValue($this);
980 
981  if ($numref != '' && $numref != '-1') {
982  return $numref;
983  } else {
984  $this->error = $obj->error;
985  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
986  return "";
987  }
988  } else {
989  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
990  return "";
991  }
992  } else {
993  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
994  return "";
995  }
996  }
997 
1009  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1010  {
1011  global $conf, $langs;
1012 
1013  $result = 0;
1014  $includedocgeneration = 0;
1015 
1016  $langs->load("agenda");
1017 
1018  if (!dol_strlen($modele)) {
1019  $modele = 'standard_calendar';
1020 
1021  if (!empty($this->model_pdf)) {
1022  $modele = $this->model_pdf;
1023  } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) {
1024  $modele = getDolGlobalString('MYOBJECT_ADDON_PDF');
1025  }
1026  }
1027 
1028  $modelpath = "core/modules/bookcal/doc/";
1029 
1030  if ($includedocgeneration && !empty($modele)) {
1031  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1032  }
1033 
1034  return $result;
1035  }
1036 
1044  public function doScheduledJob()
1045  {
1046  //global $conf, $langs;
1047 
1048  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1049 
1050  $error = 0;
1051  $this->output = '';
1052  $this->error = '';
1053 
1054  dol_syslog(__METHOD__, LOG_DEBUG);
1055 
1056  $now = dol_now();
1057 
1058  $this->db->begin();
1059 
1060  // ...
1061 
1062  $this->db->commit();
1063 
1064  return $error;
1065  }
1066 }
1067 
1068 
1069 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1070 
1075 {
1076  // To complete with content of an object CalendarLine
1077  // We should have a field rowid, fk_calendar and position
1078 
1082  public $isextrafieldmanaged = 0;
1083 
1089  public function __construct(DoliDB $db)
1090  {
1091  $this->db = $db;
1092  }
1093 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition: security.php:604
$object ref
Definition: info.php:79
Class for Calendar.
createFromClone(User $user, $fromid)
Clone an object into another one.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getLinesArray()
Create an array of lines.
getKanbanView($option='', $arraydata=null)
Return a thumb for kanban views.
getTooltipContentArray($params)
getTooltipContentArray
getLabelStatus($mode=0)
Return the label of the status.
__construct(DoliDB $db)
Constructor.
setDraft($user, $notrigger=0)
Set draft status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
info($id)
Load the info information in the object.
LibStatut($status, $mode=0)
Return the label of a given status.
validate($user, $notrigger=0)
Validate object.
cancel($user, $notrigger=0)
Set cancel status.
getLibStatut($mode=0)
Return the label of the status.
create(User $user, $notrigger=0)
Create object into database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
reopen($user, $notrigger=0)
Set back to validated status.
fetch($id, $ref=null)
Load object in memory from the database.
fetchLines()
Load object lines in memory from the database.
update(User $user, $notrigger=0)
Update object into database.
Class CalendarLine.
__construct(DoliDB $db)
Constructor.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object into database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
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.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in 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 to manage Dolibarr users.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('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') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:744
dol_dir_list($utf8_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:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
td amount
Definition: global.inc.php:554