dolibarr 20.0.0
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
28require_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
36{
40 public $module = 'bookcal';
41
45 public $element = 'calendar';
46
50 public $table_element = 'bookcal_calendar';
51
55 public $picto = 'fa-calendar-check';
56
57
58 const STATUS_DRAFT = 0;
59 const STATUS_VALIDATED = 1;
60 const STATUS_CANCELED = 9;
61
62
102 // BEGIN MODULEBUILDER PROPERTIES
106 public $fields = array(
107 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'right', 'comment' => "Id"),
108 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
109 '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'),
110 '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,),
111 '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',),
112 'type' => array('type' => 'integer', 'label' => 'Type', 'enabled' => 1, 'position' => 42, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array('0' => 'Customer', '1' => 'Supplier', '3' => 'Other'),),
113 '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,),
114 '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,),
115 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 3, 'validate' => 1,),
116 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
117 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
118 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
119 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
120 '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',),
121 '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',),
122 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
123 '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,),
124 );
125 public $rowid;
126 public $entity;
127 public $ref;
128 public $label;
129 public $type;
130 public $visibility;
131 public $fk_soc;
132 public $fk_project;
133 public $description;
134 public $note_public;
135 public $note_private;
136 public $date_creation;
137 public $fk_user_creat;
138 public $fk_user_modif;
139 public $import_key;
140 public $status;
141 // END MODULEBUILDER PROPERTIES
142
143
149 public function __construct(DoliDB $db)
150 {
151 global $langs, $user;
152
153 $this->db = $db;
154
155 $this->ismultientitymanaged = 1;
156 $this->isextrafieldmanaged = 1;
157
158 if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
159 $this->fields['rowid']['visible'] = 0;
160 }
161 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
162 $this->fields['entity']['enabled'] = 0;
163 }
164
165 // Example to show how to set values of fields definition dynamically
166 /*if ($user->hasRight('bookcal', 'calendar', 'read')) {
167 $this->fields['myfield']['visible'] = 1;
168 $this->fields['myfield']['noteditable'] = 0;
169 }*/
170 $this->fields['visibility']['default'] = $user->id;
171
172 // Unset fields that are disabled
173 foreach ($this->fields as $key => $val) {
174 if (isset($val['enabled']) && empty($val['enabled'])) {
175 unset($this->fields[$key]);
176 }
177 }
178
179 // Translate some data of arrayofkeyval
180 if (is_object($langs)) {
181 foreach ($this->fields as $key => $val) {
182 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
183 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
184 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
185 }
186 }
187 }
188 }
189 }
190
198 public function create(User $user, $notrigger = 0)
199 {
200 $resultcreate = $this->createCommon($user, $notrigger);
201
202 //$resultvalidate = $this->validate($user, $notrigger);
203
204 return $resultcreate;
205 }
206
214 public function createFromClone(User $user, $fromid)
215 {
216 global $langs, $extrafields;
217 $error = 0;
218
219 dol_syslog(__METHOD__, LOG_DEBUG);
220
221 $object = new self($this->db);
222
223 $this->db->begin();
224
225 // Load source object
226 $result = $object->fetchCommon($fromid);
227 if ($result > 0 && !empty($object->table_element_line)) {
228 $object->fetchLines();
229 }
230
231 // get lines so they will be clone
232 //foreach($this->lines as $line)
233 // $line->fetch_optionals();
234
235 // Reset some properties
236 unset($object->id);
237 unset($object->fk_user_creat);
238 unset($object->import_key);
239
240 // Clear fields
241 if (property_exists($object, 'ref')) {
242 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
243 }
244 if (property_exists($object, 'label')) {
245 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
246 }
247 if (property_exists($object, 'status')) {
248 $object->status = self::STATUS_DRAFT;
249 }
250 if (property_exists($object, 'date_creation')) {
251 $object->date_creation = dol_now();
252 }
253 if (property_exists($object, 'date_modification')) {
254 $object->date_modification = null;
255 }
256 // ...
257 // Clear extrafields that are unique
258 if (is_array($object->array_options) && count($object->array_options) > 0) {
259 $extrafields->fetch_name_optionals_label($this->table_element);
260 foreach ($object->array_options as $key => $option) {
261 $shortkey = preg_replace('/options_/', '', $key);
262 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
263 //var_dump($key);
264 //var_dump($clonedObj->array_options[$key]); exit;
265 unset($object->array_options[$key]);
266 }
267 }
268 }
269
270 // Create clone
271 $object->context['createfromclone'] = 'createfromclone';
272 $result = $object->createCommon($user);
273 if ($result < 0) {
274 $error++;
276 }
277
278 if (!$error) {
279 // copy internal contacts
280 if ($this->copy_linked_contact($object, 'internal') < 0) {
281 $error++;
282 }
283 }
284
285 if (!$error) {
286 // copy external contacts if same company
287 if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
288 if ($this->copy_linked_contact($object, 'external') < 0) {
289 $error++;
290 }
291 }
292 }
293
294 unset($object->context['createfromclone']);
295
296 // End
297 if (!$error) {
298 $this->db->commit();
299 return $object;
300 } else {
301 $this->db->rollback();
302 return -1;
303 }
304 }
305
313 public function fetch($id, $ref = null)
314 {
315 $result = $this->fetchCommon($id, $ref);
316 if ($result > 0 && !empty($this->table_element_line)) {
317 $this->fetchLines();
318 }
319 return $result;
320 }
321
327 public function fetchLines()
328 {
329 $this->lines = array();
330
331 $result = $this->fetchLinesCommon();
332 return $result;
333 }
334
335
348 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
349 {
350 dol_syslog(__METHOD__, LOG_DEBUG);
351
352 $records = array();
353
354 $sql = "SELECT ";
355 $sql .= $this->getFieldList('t');
356 $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
357 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
358 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
359 } else {
360 $sql .= " WHERE 1 = 1";
361 }
362
363 // Manage filter
364 $errormessage = '';
365 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
366 if ($errormessage) {
367 $this->errors[] = $errormessage;
368 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
369 return -1;
370 }
371
372 if (!empty($sortfield)) {
373 $sql .= $this->db->order($sortfield, $sortorder);
374 }
375 if (!empty($limit)) {
376 $sql .= $this->db->plimit($limit, $offset);
377 }
378
379 $resql = $this->db->query($sql);
380 if ($resql) {
381 $num = $this->db->num_rows($resql);
382 $i = 0;
383 while ($i < ($limit ? min($limit, $num) : $num)) {
384 $obj = $this->db->fetch_object($resql);
385
386 $record = new self($this->db);
387 $record->setVarsFromFetchObj($obj);
388
389 $records[$record->id] = $record;
390
391 $i++;
392 }
393 $this->db->free($resql);
394
395 return $records;
396 } else {
397 $this->errors[] = 'Error '.$this->db->lasterror();
398 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
399
400 return -1;
401 }
402 }
403
411 public function update(User $user, $notrigger = 0)
412 {
413 return $this->updateCommon($user, $notrigger);
414 }
415
423 public function delete(User $user, $notrigger = 0)
424 {
425 return $this->deleteCommon($user, $notrigger);
426 //return $this->deleteCommon($user, $notrigger, 1);
427 }
428
437 public function deleteLine(User $user, $idline, $notrigger = 0)
438 {
439 if ($this->status < 0) {
440 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
441 return -2;
442 }
443
444 return $this->deleteLineCommon($user, $idline, $notrigger);
445 }
446
447
455 public function validate($user, $notrigger = 0)
456 {
457 global $conf;
458
459 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
460
461 $error = 0;
462
463 // Protection
464 if ($this->status == self::STATUS_VALIDATED) {
465 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
466 return 0;
467 }
468
469 $now = dol_now();
470
471 $this->db->begin();
472
473 // Define new ref
474 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
475 $num = $this->getNextNumRef();
476 } else {
477 $num = $this->ref;
478 }
479 $this->newref = $num;
480
481 if (!empty($num)) {
482 // Validate
483 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
484 $sql .= " SET ref = '".$this->db->escape($num)."',";
485 $sql .= " status = ".self::STATUS_VALIDATED;
486 if (!empty($this->fields['date_validation'])) {
487 $sql .= ", date_validation = '".$this->db->idate($now)."'";
488 }
489 if (!empty($this->fields['fk_user_valid'])) {
490 $sql .= ", fk_user_valid = ".((int) $user->id);
491 }
492 $sql .= " WHERE rowid = ".((int) $this->id);
493
494 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
495 $resql = $this->db->query($sql);
496 if (!$resql) {
497 dol_print_error($this->db);
498 $this->error = $this->db->lasterror();
499 $error++;
500 }
501
502 if (!$error && !$notrigger) {
503 // Call trigger
504 $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
505 if ($result < 0) {
506 $error++;
507 }
508 // End call triggers
509 }
510 }
511
512 if (!$error) {
513 $this->oldref = $this->ref;
514
515 // Rename directory if dir was a temporary ref
516 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
517 // Now we rename also files into index
518 $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)."'";
519 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
520 $resql = $this->db->query($sql);
521 if (!$resql) {
522 $error++;
523 $this->error = $this->db->lasterror();
524 }
525 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'calendar/".$this->db->escape($this->newref)."'";
526 $sql .= " WHERE filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
527 $resql = $this->db->query($sql);
528 if (!$resql) {
529 $error++;
530 $this->error = $this->db->lasterror();
531 }
532
533 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
534 $oldref = dol_sanitizeFileName($this->ref);
535 $newref = dol_sanitizeFileName($num);
536 $dirsource = $conf->bookcal->dir_output.'/calendar/'.$oldref;
537 $dirdest = $conf->bookcal->dir_output.'/calendar/'.$newref;
538 if (!$error && file_exists($dirsource)) {
539 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
540
541 if (@rename($dirsource, $dirdest)) {
542 dol_syslog("Rename ok");
543 // Rename docs starting with $oldref with $newref
544 $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/calendar/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
545 foreach ($listoffiles as $fileentry) {
546 $dirsource = $fileentry['name'];
547 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
548 $dirsource = $fileentry['path'].'/'.$dirsource;
549 $dirdest = $fileentry['path'].'/'.$dirdest;
550 @rename($dirsource, $dirdest);
551 }
552 }
553 }
554 }
555 }
556
557 // Set new ref and current status
558 if (!$error) {
559 $this->ref = $num;
560 $this->status = self::STATUS_VALIDATED;
561 }
562
563 if (!$error) {
564 $this->db->commit();
565 return 1;
566 } else {
567 $this->db->rollback();
568 return -1;
569 }
570 }
571
572
580 public function setDraft($user, $notrigger = 0)
581 {
582 // Protection
583 if ($this->status <= self::STATUS_DRAFT) {
584 return 0;
585 }
586
587 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
588 }
589
597 public function cancel($user, $notrigger = 0)
598 {
599 // Protection
600 if ($this->status != self::STATUS_VALIDATED) {
601 return 0;
602 }
603
604 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
605 }
606
614 public function reopen($user, $notrigger = 0)
615 {
616 // Protection
617 if ($this->status == self::STATUS_VALIDATED) {
618 return 0;
619 }
620
621 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
622 }
623
631 public function getTooltipContentArray($params)
632 {
633 global $langs;
634
635 $datas = [];
636
637 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
638 return ['optimize' => $langs->trans("ShowCalendar")];
639 }
640 $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans("Calendar").'</u>';
641 if (isset($this->status)) {
642 $datas['picto'] .= ' '.$this->getLibStatut(5);
643 }
644 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
645
646 return $datas;
647 }
648
659 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
660 {
661 global $conf, $langs, $hookmanager;
662
663 if (!empty($conf->dol_no_mouse_hover)) {
664 $notooltip = 1; // Force disable tooltips
665 }
666
667 $result = '';
668 $params = [
669 'id' => $this->id,
670 'objecttype' => $this->element.($this->module ? '@'.$this->module : ''),
671 'option' => $option,
672 ];
673 $classfortooltip = 'classfortooltip';
674 $dataparams = '';
675 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
676 $classfortooltip = 'classforajaxtooltip';
677 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
678 $label = '';
679 } else {
680 $label = implode($this->getTooltipContentArray($params));
681 }
682
683 $url = dol_buildpath('/bookcal/calendar_card.php', 1).'?id='.$this->id;
684
685 if ($option !== 'nolink') {
686 // Add param to save lastsearch_values or not
687 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
688 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
689 $add_save_lastsearch_values = 1;
690 }
691 if ($url && $add_save_lastsearch_values) {
692 $url .= '&save_lastsearch_values=1';
693 }
694 }
695
696 $linkclose = '';
697 if (empty($notooltip)) {
698 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
699 $label = $langs->trans("ShowCalendar");
700 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
701 }
702 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
703 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
704 } else {
705 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
706 }
707
708 if ($option == 'nolink' || empty($url)) {
709 $linkstart = '<span';
710 } else {
711 $linkstart = '<a href="'.$url.'"';
712 }
713 $linkstart .= $linkclose.'>';
714 if ($option == 'nolink' || empty($url)) {
715 $linkend = '</span>';
716 } else {
717 $linkend = '</a>';
718 }
719
720 $result .= $linkstart;
721
722 if (empty($this->showphoto_on_popup)) {
723 if ($withpicto) {
724 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
725 }
726 } else {
727 if ($withpicto) {
728 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
729
730 list($class, $module) = explode('@', $this->picto);
731 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
732 $filearray = dol_dir_list($upload_dir, "files");
733 $filename = $filearray[0]['name'];
734 if (!empty($filename)) {
735 $pospoint = strpos($filearray[0]['name'], '.');
736
737 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
738 if (!getDolGlobalInt(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
739 $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>';
740 } else {
741 $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>';
742 }
743
744 $result .= '</div>';
745 } else {
746 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
747 }
748 }
749 }
750
751 if ($withpicto != 2) {
752 $result .= $this->ref;
753 }
754
755 $result .= $linkend;
756 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
757
758 global $action, $hookmanager;
759 $hookmanager->initHooks(array($this->element.'dao'));
760 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
761 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
762 if ($reshook > 0) {
763 $result = $hookmanager->resPrint;
764 } else {
765 $result .= $hookmanager->resPrint;
766 }
767
768 return $result;
769 }
770
778 public function getKanbanView($option = '', $arraydata = null)
779 {
780 global $conf, $langs;
781
782 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
783
784 $return = '<div class="box-flex-item box-flex-grow-zero">';
785 $return .= '<div class="info-box info-box-sm">';
786 $return .= '<span class="info-box-icon bg-infobox-action">';
787 $return .= img_picto('', $this->picto);
788 $return .= '</span>';
789 $return .= '<div class="info-box-content">';
790 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
791 if ($selected >= 0) {
792 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
793 }
794 if (property_exists($this, 'label')) {
795 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
796 }
797 if (property_exists($this, 'amount')) {
798 $return .= '<br>';
799 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
800 }
801 if (method_exists($this, 'getLibStatut')) {
802 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
803 }
804 $return .= '</div>';
805 $return .= '</div>';
806 $return .= '</div>';
807
808 return $return;
809 }
810
817 public function getLabelStatus($mode = 0)
818 {
819 return $this->LibStatut($this->status, $mode);
820 }
821
828 public function getLibStatut($mode = 0)
829 {
830 return $this->LibStatut($this->status, $mode);
831 }
832
833 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
841 public function LibStatut($status, $mode = 0)
842 {
843 // phpcs:enable
844 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
845 global $langs;
846
847 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
848 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
849 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
850 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
851 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
852 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
853 }
854
855 $statusType = 'status'.$status;
856 if ($status == self::STATUS_VALIDATED) {
857 $statusType = 'status4';
858 }
859 if ($status == self::STATUS_CANCELED) {
860 $statusType = 'status6';
861 }
862
863 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
864 }
865
872 public function info($id)
873 {
874 $sql = "SELECT rowid,";
875 $sql .= " date_creation as datec, tms as datem,";
876 $sql .= " fk_user_creat, fk_user_modif";
877 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
878 $sql .= " WHERE t.rowid = ".((int) $id);
879
880 $result = $this->db->query($sql);
881 if ($result) {
882 if ($this->db->num_rows($result)) {
883 $obj = $this->db->fetch_object($result);
884
885 $this->id = $obj->rowid;
886
887 $this->user_creation_id = $obj->fk_user_creat;
888 $this->user_modification_id = $obj->fk_user_modif;
889 $this->date_creation = $this->db->jdate($obj->datec);
890 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
891 }
892
893 $this->db->free($result);
894 } else {
895 dol_print_error($this->db);
896 }
897 }
898
905 public function initAsSpecimen()
906 {
907 // Set here init that are not commonf fields
908 // $this->property1 = ...
909 // $this->property2 = ...
910
911 return $this->initAsSpecimenCommon();
912 }
913
919 public function getLinesArray()
920 {
921 $this->lines = array();
922
923 $objectline = new CalendarLine($this->db);
924 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_calendar:=:'.((int) $this->id).')');
925
926 if (is_numeric($result)) {
927 $this->setErrorsFromObject($objectline);
928 return $result;
929 } else {
930 $this->lines = $result;
931 return $this->lines;
932 }
933 }
934
940 public function getNextNumRef()
941 {
942 global $langs, $conf;
943 $langs->load("agenda");
944
945 if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
946 $conf->global->BOOKCAL_MYOBJECT_ADDON = 'mod_calendar_standard';
947 }
948
949 if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
950 $mybool = false;
951
952 $file = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON').".php";
953 $classname = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON');
954
955 // Include file with class
956 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
957 foreach ($dirmodels as $reldir) {
958 $dir = dol_buildpath($reldir."core/modules/bookcal/");
959
960 // Load file with numbering class (if found)
961 $mybool = ((bool) @include_once $dir.$file) || $mybool;
962 }
963
964 if ($mybool === false) {
965 dol_print_error(null, "Failed to include file ".$file);
966 return '';
967 }
968
969 if (class_exists($classname)) {
970 $obj = new $classname();
971 $numref = $obj->getNextValue($this);
972
973 if ($numref != '' && $numref != '-1') {
974 return $numref;
975 } else {
976 $this->error = $obj->error;
977 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
978 return "";
979 }
980 } else {
981 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
982 return "";
983 }
984 } else {
985 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
986 return "";
987 }
988 }
989
1001 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1002 {
1003 global $conf, $langs;
1004
1005 $result = 0;
1006 $includedocgeneration = 0;
1007
1008 $langs->load("agenda");
1009
1010 if (!dol_strlen($modele)) {
1011 $modele = 'standard_calendar';
1012
1013 if (!empty($this->model_pdf)) {
1014 $modele = $this->model_pdf;
1015 } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) {
1016 $modele = getDolGlobalString('MYOBJECT_ADDON_PDF');
1017 }
1018 }
1019
1020 $modelpath = "core/modules/bookcal/doc/";
1021
1022 if ($includedocgeneration && !empty($modele)) {
1023 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1024 }
1025
1026 return $result;
1027 }
1028
1036 public function doScheduledJob()
1037 {
1038 //global $conf, $langs;
1039
1040 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1041
1042 $error = 0;
1043 $this->output = '';
1044 $this->error = '';
1045
1046 dol_syslog(__METHOD__, LOG_DEBUG);
1047
1048 $now = dol_now();
1049
1050 $this->db->begin();
1051
1052 // ...
1053
1054 $this->db->commit();
1055
1056 return $error;
1057 }
1058}
1059
1060
1061require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1062
1067{
1068 // To complete with content of an object CalendarLine
1069 // We should have a field rowid, fk_calendar and position
1070
1071
1077 public function __construct(DoliDB $db)
1078 {
1079 $this->db = $db;
1080
1081 $this->isextrafieldmanaged = 0;
1082 }
1083}
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:636
$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 in the 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.
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.
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.