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