dolibarr 21.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
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 );
128 public $rowid;
132 public $entity;
136 public $ref;
140 public $label;
144 public $type;
148 public $visibility;
152 public $fk_soc;
156 public $fk_project;
160 public $description;
164 public $note_public;
168 public $note_private;
172 public $fk_user_creat;
176 public $fk_user_modif;
180 public $import_key;
184 public $status;
185 // END MODULEBUILDER PROPERTIES
186
187
193 public function __construct(DoliDB $db)
194 {
195 global $langs, $user;
196
197 $this->db = $db;
198
199 $this->ismultientitymanaged = 1;
200 $this->isextrafieldmanaged = 1;
201
202 if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
203 $this->fields['rowid']['visible'] = 0;
204 }
205 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
206 $this->fields['entity']['enabled'] = 0;
207 }
208
209 // Example to show how to set values of fields definition dynamically
210 /*if ($user->hasRight('bookcal', 'calendar', 'read')) {
211 $this->fields['myfield']['visible'] = 1;
212 $this->fields['myfield']['noteditable'] = 0;
213 }*/
214 $this->fields['visibility']['default'] = $user->id;
215
216 // Unset fields that are disabled
217 foreach ($this->fields as $key => $val) {
218 if (isset($val['enabled']) && empty($val['enabled'])) {
219 unset($this->fields[$key]);
220 }
221 }
222
223 // Translate some data of arrayofkeyval
224 if (is_object($langs)) {
225 foreach ($this->fields as $key => $val) {
226 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
227 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
228 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
229 }
230 }
231 }
232 }
233 }
234
242 public function create(User $user, $notrigger = 0)
243 {
244 $resultcreate = $this->createCommon($user, $notrigger);
245
246 //$resultvalidate = $this->validate($user, $notrigger);
247
248 return $resultcreate;
249 }
250
258 public function createFromClone(User $user, $fromid)
259 {
260 global $langs, $extrafields;
261 $error = 0;
262
263 dol_syslog(__METHOD__, LOG_DEBUG);
264
265 $object = new self($this->db);
266
267 $this->db->begin();
268
269 // Load source object
270 $result = $object->fetchCommon($fromid);
271 if ($result > 0 && !empty($object->table_element_line)) {
272 $object->fetchLines();
273 }
274
275 // get lines so they will be cloned
276 //foreach($this->lines as $line)
277 // $line->fetch_optionals();
278
279 // Reset some properties
280 unset($object->id);
281 unset($object->fk_user_creat);
282 unset($object->import_key);
283
284 // Clear fields
285 if (property_exists($object, 'ref')) {
286 // @phan-suppress-next-line PhanTypeInvalidDimOffset
287 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
288 }
289 if (property_exists($object, 'label')) {
290 // @phan-suppress-next-line PhanTypeInvalidDimOffset
291 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
292 }
293 if (property_exists($object, 'status')) {
294 $object->status = self::STATUS_DRAFT;
295 }
296 if (property_exists($object, 'date_creation')) {
297 $object->date_creation = dol_now();
298 }
299 if (property_exists($object, 'date_modification')) {
300 $object->date_modification = null;
301 }
302 // ...
303 // Clear extrafields that are unique
304 if (is_array($object->array_options) && count($object->array_options) > 0) {
305 $extrafields->fetch_name_optionals_label($this->table_element);
306 foreach ($object->array_options as $key => $option) {
307 $shortkey = preg_replace('/options_/', '', $key);
308 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
309 //var_dump($key);
310 //var_dump($clonedObj->array_options[$key]); exit;
311 unset($object->array_options[$key]);
312 }
313 }
314 }
315
316 // Create clone
317 $object->context['createfromclone'] = 'createfromclone';
318 $result = $object->createCommon($user);
319 if ($result < 0) {
320 $error++;
322 }
323
324 if (!$error) {
325 // copy internal contacts
326 if ($this->copy_linked_contact($object, 'internal') < 0) {
327 $error++;
328 }
329 }
330
331 if (!$error) {
332 // copy external contacts if same company
333 if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
334 if ($this->copy_linked_contact($object, 'external') < 0) {
335 $error++;
336 }
337 }
338 }
339
340 unset($object->context['createfromclone']);
341
342 // End
343 if (!$error) {
344 $this->db->commit();
345 return $object;
346 } else {
347 $this->db->rollback();
348 return -1;
349 }
350 }
351
359 public function fetch($id, $ref = null)
360 {
361 $result = $this->fetchCommon($id, $ref);
362 if ($result > 0 && !empty($this->table_element_line)) {
363 $this->fetchLines();
364 }
365 return $result;
366 }
367
373 public function fetchLines()
374 {
375 $this->lines = array();
376
377 $result = $this->fetchLinesCommon();
378 return $result;
379 }
380
381
394 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
395 {
396 dol_syslog(__METHOD__, LOG_DEBUG);
397
398 $records = array();
399
400 $sql = "SELECT ";
401 $sql .= $this->getFieldList('t');
402 $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
403 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
404 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
405 } else {
406 $sql .= " WHERE 1 = 1";
407 }
408
409 // Manage filter
410 $errormessage = '';
411 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
412 if ($errormessage) {
413 $this->errors[] = $errormessage;
414 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
415 return -1;
416 }
417
418 if (!empty($sortfield)) {
419 $sql .= $this->db->order($sortfield, $sortorder);
420 }
421 if (!empty($limit)) {
422 $sql .= $this->db->plimit($limit, $offset);
423 }
424
425 $resql = $this->db->query($sql);
426 if ($resql) {
427 $num = $this->db->num_rows($resql);
428 $i = 0;
429 while ($i < ($limit ? min($limit, $num) : $num)) {
430 $obj = $this->db->fetch_object($resql);
431
432 $record = new self($this->db);
433 $record->setVarsFromFetchObj($obj);
434
435 $records[$record->id] = $record;
436
437 $i++;
438 }
439 $this->db->free($resql);
440
441 return $records;
442 } else {
443 $this->errors[] = 'Error '.$this->db->lasterror();
444 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
445
446 return -1;
447 }
448 }
449
457 public function update(User $user, $notrigger = 0)
458 {
459 return $this->updateCommon($user, $notrigger);
460 }
461
469 public function delete(User $user, $notrigger = 0)
470 {
471 return $this->deleteCommon($user, $notrigger);
472 //return $this->deleteCommon($user, $notrigger, 1);
473 }
474
483 public function deleteLine(User $user, $idline, $notrigger = 0)
484 {
485 if ($this->status < 0) {
486 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
487 return -2;
488 }
489
490 return $this->deleteLineCommon($user, $idline, $notrigger);
491 }
492
493
501 public function validate($user, $notrigger = 0)
502 {
503 global $conf;
504
505 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
506
507 $error = 0;
508
509 // Protection
510 if ($this->status == self::STATUS_VALIDATED) {
511 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
512 return 0;
513 }
514
515 $now = dol_now();
516
517 $this->db->begin();
518
519 // Define new ref
520 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
521 $num = $this->getNextNumRef();
522 } else {
523 $num = $this->ref;
524 }
525 $this->newref = $num;
526
527 if (!empty($num)) {
528 // Validate
529 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
530 $sql .= " SET ref = '".$this->db->escape($num)."',";
531 $sql .= " status = ".self::STATUS_VALIDATED;
532 if (!empty($this->fields['date_validation'])) {
533 $sql .= ", date_validation = '".$this->db->idate($now)."'";
534 }
535 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
536 $sql .= ", fk_user_valid = ".((int) $user->id);
537 }
538 $sql .= " WHERE rowid = ".((int) $this->id);
539
540 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
541 $resql = $this->db->query($sql);
542 if (!$resql) {
543 dol_print_error($this->db);
544 $this->error = $this->db->lasterror();
545 $error++;
546 }
547
548 if (!$error && !$notrigger) {
549 // Call trigger
550 $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
551 if ($result < 0) {
552 $error++;
553 }
554 // End call triggers
555 }
556 }
557
558 if (!$error) {
559 $this->oldref = $this->ref;
560
561 // Rename directory if dir was a temporary ref
562 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
563 // Now we rename also files into index
564 $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)."'";
565 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
566 $resql = $this->db->query($sql);
567 if (!$resql) {
568 $error++;
569 $this->error = $this->db->lasterror();
570 }
571 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'calendar/".$this->db->escape($this->newref)."'";
572 $sql .= " WHERE filepath = 'calendar/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
573 $resql = $this->db->query($sql);
574 if (!$resql) {
575 $error++;
576 $this->error = $this->db->lasterror();
577 }
578
579 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
580 $oldref = dol_sanitizeFileName($this->ref);
581 $newref = dol_sanitizeFileName($num);
582 $dirsource = $conf->bookcal->dir_output.'/calendar/'.$oldref;
583 $dirdest = $conf->bookcal->dir_output.'/calendar/'.$newref;
584 if (!$error && file_exists($dirsource)) {
585 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
586
587 if (@rename($dirsource, $dirdest)) {
588 dol_syslog("Rename ok");
589 // Rename docs starting with $oldref with $newref
590 $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/calendar/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
591 foreach ($listoffiles as $fileentry) {
592 $dirsource = $fileentry['name'];
593 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
594 $dirsource = $fileentry['path'].'/'.$dirsource;
595 $dirdest = $fileentry['path'].'/'.$dirdest;
596 @rename($dirsource, $dirdest);
597 }
598 }
599 }
600 }
601 }
602
603 // Set new ref and current status
604 if (!$error) {
605 $this->ref = $num;
606 $this->status = self::STATUS_VALIDATED;
607 }
608
609 if (!$error) {
610 $this->db->commit();
611 return 1;
612 } else {
613 $this->db->rollback();
614 return -1;
615 }
616 }
617
618
626 public function setDraft($user, $notrigger = 0)
627 {
628 // Protection
629 if ($this->status <= self::STATUS_DRAFT) {
630 return 0;
631 }
632
633 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
634 }
635
643 public function cancel($user, $notrigger = 0)
644 {
645 // Protection
646 if ($this->status != self::STATUS_VALIDATED) {
647 return 0;
648 }
649
650 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
651 }
652
660 public function reopen($user, $notrigger = 0)
661 {
662 // Protection
663 if ($this->status == self::STATUS_VALIDATED) {
664 return 0;
665 }
666
667 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
668 }
669
676 public function getTooltipContentArray($params)
677 {
678 global $langs;
679
680 $datas = [];
681
682 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
683 return ['optimize' => $langs->trans("ShowCalendar")];
684 }
685 $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans("Calendar").'</u>';
686 if (isset($this->status)) {
687 $datas['picto'] .= ' '.$this->getLibStatut(5);
688 }
689 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
690
691 return $datas;
692 }
693
704 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
705 {
706 global $conf, $langs, $hookmanager;
707
708 if (!empty($conf->dol_no_mouse_hover)) {
709 $notooltip = 1; // Force disable tooltips
710 }
711
712 $result = '';
713 $params = [
714 'id' => $this->id,
715 'objecttype' => $this->element.($this->module ? '@'.$this->module : ''),
716 'option' => $option,
717 ];
718 $classfortooltip = 'classfortooltip';
719 $dataparams = '';
720 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
721 $classfortooltip = 'classforajaxtooltip';
722 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
723 $label = '';
724 } else {
725 $label = implode($this->getTooltipContentArray($params));
726 }
727
728 $url = dol_buildpath('/bookcal/calendar_card.php', 1).'?id='.$this->id;
729
730 if ($option !== 'nolink') {
731 // Add param to save lastsearch_values or not
732 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
733 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
734 $add_save_lastsearch_values = 1;
735 }
736 if ($url && $add_save_lastsearch_values) {
737 $url .= '&save_lastsearch_values=1';
738 }
739 }
740
741 $linkclose = '';
742 if (empty($notooltip)) {
743 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
744 $label = $langs->trans("ShowCalendar");
745 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
746 }
747 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
748 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
749 } else {
750 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
751 }
752
753 if ($option == 'nolink' || empty($url)) {
754 $linkstart = '<span';
755 } else {
756 $linkstart = '<a href="'.$url.'"';
757 }
758 $linkstart .= $linkclose.'>';
759 if ($option == 'nolink' || empty($url)) {
760 $linkend = '</span>';
761 } else {
762 $linkend = '</a>';
763 }
764
765 $result .= $linkstart;
766
767 if (empty($this->showphoto_on_popup)) {
768 if ($withpicto) {
769 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
770 }
771 } else {
772 if ($withpicto) {
773 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
774
775 list($class, $module) = explode('@', $this->picto);
776 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
777 $filearray = dol_dir_list($upload_dir, "files");
778 $filename = $filearray[0]['name'];
779 if (!empty($filename)) {
780 $pospoint = strpos($filearray[0]['name'], '.');
781
782 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
783 if (!getDolGlobalInt(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
784 $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>';
785 } else {
786 $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>';
787 }
788
789 $result .= '</div>';
790 } else {
791 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
792 }
793 }
794 }
795
796 if ($withpicto != 2) {
797 $result .= $this->ref;
798 }
799
800 $result .= $linkend;
801 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
802
803 global $action, $hookmanager;
804 $hookmanager->initHooks(array($this->element.'dao'));
805 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
806 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
807 if ($reshook > 0) {
808 $result = $hookmanager->resPrint;
809 } else {
810 $result .= $hookmanager->resPrint;
811 }
812
813 return $result;
814 }
815
823 public function getKanbanView($option = '', $arraydata = null)
824 {
825 global $conf, $langs;
826
827 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
828
829 $return = '<div class="box-flex-item box-flex-grow-zero">';
830 $return .= '<div class="info-box info-box-sm">';
831 $return .= '<span class="info-box-icon bg-infobox-action">';
832 $return .= img_picto('', $this->picto);
833 $return .= '</span>';
834 $return .= '<div class="info-box-content">';
835 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
836 if ($selected >= 0) {
837 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
838 }
839 if (property_exists($this, 'label')) {
840 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
841 }
842 if (property_exists($this, 'amount')) {
843 $return .= '<br>';
844 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
845 }
846 if (method_exists($this, 'getLibStatut')) {
847 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
848 }
849 $return .= '</div>';
850 $return .= '</div>';
851 $return .= '</div>';
852
853 return $return;
854 }
855
862 public function getLabelStatus($mode = 0)
863 {
864 return $this->LibStatut($this->status, $mode);
865 }
866
873 public function getLibStatut($mode = 0)
874 {
875 return $this->LibStatut($this->status, $mode);
876 }
877
878 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
886 public function LibStatut($status, $mode = 0)
887 {
888 // phpcs:enable
889 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
890 global $langs;
891
892 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
893 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
894 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
895 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
896 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
897 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
898 }
899
900 $statusType = 'status'.$status;
901 if ($status == self::STATUS_VALIDATED) {
902 $statusType = 'status4';
903 }
904 if ($status == self::STATUS_CANCELED) {
905 $statusType = 'status6';
906 }
907
908 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
909 }
910
917 public function info($id)
918 {
919 $sql = "SELECT rowid,";
920 $sql .= " date_creation as datec, tms as datem,";
921 $sql .= " fk_user_creat, fk_user_modif";
922 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
923 $sql .= " WHERE t.rowid = ".((int) $id);
924
925 $result = $this->db->query($sql);
926 if ($result) {
927 if ($this->db->num_rows($result)) {
928 $obj = $this->db->fetch_object($result);
929
930 $this->id = $obj->rowid;
931
932 $this->user_creation_id = $obj->fk_user_creat;
933 $this->user_modification_id = $obj->fk_user_modif;
934 $this->date_creation = $this->db->jdate($obj->datec);
935 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
936 }
937
938 $this->db->free($result);
939 } else {
940 dol_print_error($this->db);
941 }
942 }
943
950 public function initAsSpecimen()
951 {
952 // Set here init that are not commonf fields
953 // $this->property1 = ...
954 // $this->property2 = ...
955
956 return $this->initAsSpecimenCommon();
957 }
958
964 public function getLinesArray()
965 {
966 $this->lines = array();
967
968 $objectline = new CalendarLine($this->db);
969 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_calendar:=:'.((int) $this->id).')');
970
971 if (is_numeric($result)) {
972 $this->setErrorsFromObject($objectline);
973 return $result;
974 } else {
975 $this->lines = $result;
976 // @phpstan-ignore-next-line
977 return $result; // @phan-suppress-current-line PhanTypeMismatchReturn
978 }
979 }
980
986 public function getNextNumRef()
987 {
988 global $langs, $conf;
989 $langs->load("agenda");
990
991 if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
992 $conf->global->BOOKCAL_MYOBJECT_ADDON = 'mod_calendar_standard';
993 }
994
995 if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
996 $mybool = false;
997
998 $file = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON').".php";
999 $classname = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON');
1000
1001 // Include file with class
1002 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1003 foreach ($dirmodels as $reldir) {
1004 $dir = dol_buildpath($reldir."core/modules/bookcal/");
1005
1006 // Load file with numbering class (if found)
1007 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1008 }
1009
1010 if (!$mybool) {
1011 dol_print_error(null, "Failed to include file ".$file);
1012 return '';
1013 }
1014
1015 if (class_exists($classname)) {
1016 $obj = new $classname();
1017 '@phan-var-force CommonNumRefGenerator $obj';
1018
1019 $numref = $obj->getNextValue($this);
1020
1021 if ($numref != '' && $numref != '-1') {
1022 return $numref;
1023 } else {
1024 $this->error = $obj->error;
1025 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1026 return "";
1027 }
1028 } else {
1029 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1030 return "";
1031 }
1032 } else {
1033 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1034 return "";
1035 }
1036 }
1037
1049 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1050 {
1051 global $conf, $langs;
1052
1053 $result = 0;
1054 $includedocgeneration = 0;
1055
1056 $langs->load("agenda");
1057
1058 if (!dol_strlen($modele)) {
1059 $modele = 'standard_calendar';
1060
1061 if (!empty($this->model_pdf)) {
1062 $modele = $this->model_pdf;
1063 } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) {
1064 $modele = getDolGlobalString('MYOBJECT_ADDON_PDF');
1065 }
1066 }
1067
1068 $modelpath = "core/modules/bookcal/doc/";
1069
1070 if ($includedocgeneration && !empty($modele)) {
1071 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1072 }
1073
1074 return $result;
1075 }
1076
1084 public function doScheduledJob()
1085 {
1086 //global $conf, $langs;
1087
1088 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1089
1090 $error = 0;
1091 $this->output = '';
1092 $this->error = '';
1093
1094 dol_syslog(__METHOD__, LOG_DEBUG);
1095
1096 $now = dol_now();
1097
1098 $this->db->begin();
1099
1100 // ...
1101
1102 $this->db->commit();
1103
1104 return $error;
1105 }
1106}
1107
1108
1109require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1110
1115{
1116 // To complete with content of an object CalendarLine
1117 // We should have a field rowid, fk_calendar and position
1118
1119
1125 public function __construct(DoliDB $db)
1126 {
1127 $this->db = $db;
1128
1129 $this->isextrafieldmanaged = 0;
1130 }
1131}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
$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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:162
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 a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.