28require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
40 public $module =
'quickmemo';
45 public $element =
'memo';
51 public $TRIGGER_PREFIX =
'QUICKMEMO_MEMO';
56 public $table_element =
'quickmemo_memo';
66 public $picto =
'fa-file';
71 public $isextrafieldmanaged = 0;
77 public $ismultientitymanaged = 0;
82 const STATUS_VALIDATED = 1;
83 const STATUS_CANCELED = 9;
84 const STATUS_ARCHIVED = 9;
134 "rowid" => array(
"type" =>
"integer",
"label" =>
"TechnicalID",
'enabled' => 1,
'position' => 1,
'notnull' => 1,
"visible" => 0,
'noteditable' => 1,
'index' => 1,
"css" =>
"left",
"comment" =>
"Id"),
135 "quick_note" => array(
"type" =>
"text",
"label" =>
"Note",
'enabled' => 1,
'position' => 61,
'notnull' => 0,
"visible" => -1,
"cssview" =>
"wordbreak",
"validate" => 1,),
136 "date_creation" => array(
"type" =>
"datetime",
"label" =>
"DateCreation",
'enabled' => 1,
'position' => 500,
'notnull' => 1,
"visible" => -2,),
137 "tms" => array(
"type" =>
"timestamp",
"label" =>
"DateModification",
'enabled' => 1,
'position' => 501,
'notnull' => 0,
"visible" => -2,),
138 "date_archived" => array(
"type" =>
"timestamp",
"label" =>
"DateArchived",
'enabled' => 1,
'position' => 502,
'notnull' => 0,
"visible" => -2,),
139 "fk_user_creat" => array(
"type" =>
"integer:User:user/class/user.class.php",
"label" =>
"UserAuthor",
"picto" =>
"user",
'enabled' => 1,
'position' => 510,
'notnull' => 1,
"visible" => -2,
"csslist" =>
"tdoverflowmax150",),
140 "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",),
141 "fk_user_archived" => array(
"type" =>
"integer:User:user/class/user.class.php",
"label" =>
"ArchivedBy",
"picto" =>
"user",
'enabled' => 1,
'position' => 511,
'notnull' => -1,
"visible" => -2,
"csslist" =>
"tdoverflowmax150",),
142 "fk_element" => array(
'type' =>
'integer',
'label' =>
'MemoLinkedTo',
'help' =>
'MemoLinkedToHelp',
'enabled' => 1,
'visible' => 5,
'notnull' => 0,
'default' => 0,
'index' => 1,
'position' => 0),
143 "element_type" => array(
'type' =>
'varchar(64)',
'label' =>
'QuickMemoElementType',
'enabled' => 1,
'visible' => 5,
'position' => 10,
'required' => 0),
144 "pos_z" => array(
"type" =>
"integer",
"label" =>
"PosZ",
'enabled' => 1,
'position' => 1000,
'notnull' => 1,
"visible" => 0,
"default" => 0,
"validate" => 1),
145 "pos_y" => array(
"type" =>
"integer",
"label" =>
"PosY",
'enabled' => 1,
'position' => 1000,
'notnull' => 1,
"visible" => 0,
"default" => 0,
"validate" => 1),
146 "pos_x" => array(
"type" =>
"integer",
"label" =>
"PosX",
'enabled' => 1,
'position' => 1000,
'notnull' => 1,
"visible" => 0,
"default" => 0,
"validate" => 1),
147 "pos_w" => array(
"type" =>
"integer",
"label" =>
"PosW",
'enabled' => 1,
'position' => 1000,
'notnull' => 1,
"visible" => 0,
"default" => 0,
"validate" => 1),
148 "pos_h" => array(
"type" =>
"integer",
"label" =>
"PosH",
'enabled' => 1,
'position' => 1000,
'notnull' => 1,
"visible" => 0,
"default" => 0,
"validate" => 1),
149 "color" => array(
'type' =>
'varchar(10)',
'label' =>
'Color',
'enabled' => 1,
'visible' => 1,
'position' => 10,
'required' => 0),
150 "context_tab" => array(
'type' =>
'varchar(64)',
'label' =>
'ContextTab',
'enabled' => 1,
'visible' => 1,
'position' => 10,
'required' => 0),
151 "private" => array(
"type" =>
"integer",
"label" =>
"Private",
'enabled' => 1,
'position' => 1990,
'notnull' => 1,
"visible" => 1,
'index' => 1,
"arrayofkeyval" => array(0 =>
"No", 1 =>
"Yes"),
'default' => 1,
"validate" => 1,),
152 "private_tpl" => array(
"type" =>
"integer",
"label" =>
"PrivateTemplate",
'enabled' => 1,
'position' => 1990,
'notnull' => 0,
"visible" => 1,
'index' => 1,
"arrayofkeyval" => array(0 =>
"No", 1 =>
"Yes"),
'default' => 0,
"validate" => 1,),
153 "rank_tpl" => array(
"type" =>
"integer",
"label" =>
"TemplateRank",
'enabled' => 1,
'position' => 1990,
'notnull' => 0,
"visible" => 0,
'index' => 1,
'default' => 0,
"validate" => 1,),
154 "name_tpl" => array(
'type' =>
'varchar(256)',
'label' =>
'QuickMemoTemplateName',
'enabled' => 1,
'visible' => -1,
'position' => 1,
'required' => 0),
155 "shared_on_element" => array(
"type" =>
"integer",
"label" =>
"SharedBetweenElement",
'enabled' => 1,
'position' => 1991,
'notnull' => 1,
"visible" => 1,
'index' => 1,
"arrayofkeyval" => array(0 =>
"No", 1 =>
"Yes"),
"validate" => 1,),
156 "import_key" => array(
"type" =>
"varchar(14)",
"label" =>
"ImportId",
'enabled' => 1,
'position' => 1000,
'notnull' => -1,
"visible" => -2,),
157 "status" => array(
"type" =>
"integer",
"label" =>
"Status",
'enabled' => 1,
'position' => 2000,
'notnull' => 1,
"visible" => 1,
'index' => 1,
"arrayofkeyval" => array(1 =>
"Active",2 =>
"Template", 9 =>
"Archived"),
"validate" => 1,),
164 public $date_archived;
167 public $fk_user_archived;
182 public $element_type;
228 public $shared_on_element;
241 if (!
getDolGlobalInt(
'MAIN_SHOW_TECHNICAL_ID') && isset($this->fields[
'rowid']) && !empty($this->fields[
'ref'])) {
242 $this->fields[
'rowid'][
'visible'] = 0;
244 if (!
isModEnabled(
'multicompany') && isset($this->fields[
'entity'])) {
245 $this->fields[
'entity'][
'enabled'] = 0;
249 foreach ($this->fields as $key => $val) {
250 if (isset($val[
'enabled']) && empty($val[
'enabled'])) {
251 unset($this->fields[$key]);
256 if (is_object($langs)) {
257 foreach ($this->fields as $key => $val) {
258 if (!empty($val[
'arrayofkeyval']) && is_array($val[
'arrayofkeyval'])) {
259 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
260 $this->fields[$key][
'arrayofkeyval'][$key2] = $langs->trans($val2);
290 global $langs, $extrafields;
300 $result =
$object->fetchCommon($fromid);
301 if ($result > 0 && !empty(
$object->table_element_line)) {
311 $object->status = self::STATUS_VALIDATED;
315 $object->date_modification =
null;
319 if (is_array(
$object->array_options) && count(
$object->array_options) > 0) {
320 $extrafields->fetch_name_optionals_label($this->table_element);
321 foreach (
$object->array_options as $key => $option) {
322 $shortkey = preg_replace(
'/options_/',
'', $key);
323 if (!empty($extrafields->attributes[$this->table_element][
'unique'][$shortkey])) {
326 unset(
$object->array_options[$key]);
332 $object->context[
'createfromclone'] =
'createfromclone';
333 $result =
$object->createCommon($user);
339 unset(
$object->context[
'createfromclone']);
346 $this->db->rollback();
360 public function fetch($id, $ref =
null, $noextrafields = 0, $nolines = 0)
362 $result = $this->
fetchCommon($id, $ref,
'', $noextrafields);
363 if ($result > 0 && !empty($this->table_element_line) && empty($nolines)) {
377 $this->lines = array();
398 public function fetchAll($sortorder =
'', $sortfield =
'', $limit = 1000, $offset = 0,
string $filter =
'', $filtermode =
'AND')
406 $sql .=
" FROM ".$this->db->prefix().$this->table_element.
" as t";
407 if (!empty($this->isextrafieldmanaged) && $this->isextrafieldmanaged == 1) {
408 $sql .=
" LEFT JOIN ".$this->db->prefix().$this->table_element.
"_extrafields as te ON te.fk_object = t.rowid";
410 if (!empty($this->ismultientitymanaged) && (
int) $this->ismultientitymanaged == 1) {
411 $sql .=
" WHERE t.entity IN (".getEntity($this->element).
")";
412 } elseif (preg_match(
'/^\w+@\w+$/', (
string) $this->ismultientitymanaged)) {
413 $tmparray = explode(
'@', (
string) $this->ismultientitymanaged);
414 $sql .=
" LEFT JOIN ".$this->db->prefix().$tmparray[1].
" as pt ON t.".$this->db->sanitize($tmparray[0]).
" = pt.rowid";
415 $sql .=
" WHERE pt.entity IN (".getEntity($this->element).
")";
417 $sql .=
" WHERE 1 = 1";
422 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
424 $this->errors[] = $errormessage;
425 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
429 if (!empty($sortfield)) {
430 $sql .= $this->db->order($sortfield, $sortorder);
432 if (!empty($limit)) {
433 $sql .= $this->db->plimit($limit, $offset);
436 $resql = $this->db->query($sql);
438 $num = $this->db->num_rows($resql);
440 while ($i < ($limit ? min($limit, $num) : $num)) {
441 $obj = $this->db->fetch_object($resql);
443 $record =
new self($this->db);
444 $record->setVarsFromFetchObj($obj);
446 if (!empty($record->isextrafieldmanaged)) {
447 $record->fetch_optionals();
450 $records[$record->id] = $record;
454 $this->db->free($resql);
458 $this->errors[] =
'Error '.$this->db->lasterror();
459 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
491 if (empty($this->
id)) {
502 if ((
int) $this->fk_user_creat === (int) $user->id) {
509 if ($this->
update($user) <= 0) {
518 $sql =
'SELECT rowid';
519 $sql .=
' FROM '.$this->db->prefix().
'quickmemo_memo_user';
520 $sql .=
' WHERE fk_memo = '.((int) $this->
id);
521 $sql .=
' AND fk_user = '.((int) $user->id);
523 $resql = $this->db->query($sql);
528 if ($this->db->num_rows($resql) > 0) {
530 $sql =
'UPDATE '.$this->db->prefix().
'quickmemo_memo_user SET';
531 $sql .=
' pos_x = '. (int) $x.
',';
532 $sql .=
' pos_y = '. (int) $y.
',';
533 $sql .=
' pos_w = '. (int) $w.
',';
534 $sql .=
' pos_h = '. (int) $h.
',';
535 $sql .=
' pos_z = '. (int) $z;
536 $sql .=
' WHERE fk_memo = '.((int) $this->
id);
537 $sql .=
' AND fk_user = '.((int) $user->id);
539 if (!$this->db->query($sql)) {
544 $sql =
'INSERT INTO '.$this->db->prefix().
'quickmemo_memo_user (';
547 $sql .=
'date_creation,';
553 $sql .=
') VALUES (';
554 $sql .= ((int) $this->
id).
',';
555 $sql .= ((int) $user->id).
',';
556 $sql .=
'\''. $this->db->idate(
dol_now()) .
'\',
';
557 $sql .= (int) $x.',
';
558 $sql .= (int) $y.',
';
559 $sql .= (int) $w.',
';
560 $sql .= (int) $h.',
';
564 if (!$this->db->query($sql)) {
580 public function delete(User $user, $notrigger = 0)
582 return $this->deleteCommon($user, $notrigger);
583 //return $this->deleteCommon($user, $notrigger, 1);
594 public function deleteLine(User $user, $idline, $notrigger = 0)
596 if ($this->status < 0) {
597 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus
';
601 return $this->deleteLineCommon($user, $idline, $notrigger);
612 public function validate($user, $notrigger = 0)
616 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php
';
621 if ($this->status == self::STATUS_VALIDATED) {
622 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
626 /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
', 'memo
', 'write
'))
627 || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
', 'memo_advance
', 'validate')))
629 $this->error='NotEnoughPermissions
';
630 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
639 if (preg_match('/^[\(]?PROV/i
', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life
640 $num = $this->getNextNumRef();
642 $num = (string) $this->ref;
644 $this->newref = $num;
648 $sql = "UPDATE ".$this->db->prefix().$this->table_element;
650 if (!empty($this->fields['ref'])) {
651 $sql .= " ref = '".$this->db->escape($num)."',";
653 $sql .= " status = ".self::STATUS_VALIDATED;
654 if (!empty($this->fields['date_validation
'])) {
655 $sql .= ", date_validation = '".$this->db->idate($now)."'";
657 if (!empty($this->fields['fk_user_valid
'])) {
658 $sql .= ", fk_user_valid = ".((int) $user->id);
660 $sql .= " WHERE rowid = ".((int) $this->id);
662 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
663 $resql = $this->db->query($sql);
665 dol_print_error($this->db);
666 $this->error = $this->db->lasterror();
670 if (!$error && !$notrigger) {
672 $result = $this->call_trigger('MEMO_VALIDATE
', $user);
681 $this->oldref = $this->ref;
683 // Rename directory if dir was a temporary ref
684 if (preg_match('/^[\(]?PROV/i
', $this->ref)) {
685 // Now we rename also files into index
686 $sql = 'UPDATE
'.$this->db->prefix()."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'memo/
".$this->db->escape($this->newref)."'";
687 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%
' AND filepath = 'memo/
".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
688 $resql = $this->db->query($sql);
691 $this->error = $this->db->lasterror();
693 $sql = 'UPDATE
'.$this->db->prefix()."ecm_files set filepath = 'memo/
".$this->db->escape($this->newref)."'";
694 $sql .= " WHERE filepath = 'memo/
".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
695 $resql = $this->db->query($sql);
698 $this->error = $this->db->lasterror();
701 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
702 $oldref = dol_sanitizeFileName($this->ref);
703 $newref = dol_sanitizeFileName($num);
704 $dirsource = $conf->quickmemo->dir_output.'/memo/
'.$oldref;
705 $dirdest = $conf->quickmemo->dir_output.'/memo/
'.$newref;
706 if (!$error && file_exists($dirsource)) {
707 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
709 if (@rename($dirsource, $dirdest)) {
710 dol_syslog("Rename ok");
711 // Rename docs starting with $oldref with $newref
712 $listoffiles = dol_dir_list($conf->quickmemo->dir_output.'/memo/
'.$newref, 'files
', 1, '^
'.preg_quote($oldref, '/
'));
713 foreach ($listoffiles as $fileentry) {
714 $dirsource = $fileentry['name'];
715 $dirdest = preg_replace('/^
'.preg_quote($oldref, '/
').'/
', $newref, $dirsource);
716 $dirsource = $fileentry['path
'].'/
'.$dirsource;
717 $dirdest = $fileentry['path
'].'/
'.$dirdest;
718 @rename($dirsource, $dirdest);
725 // Set new ref and current status
728 $this->status = self::STATUS_VALIDATED;
735 $this->db->rollback();
748 public function setDraft($user, $notrigger = 0)
751 if ($this->status <= self::STATUS_VALIDATED) {
755 /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','write
'))
756 || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','quickmemo_advance
','validate'))))
758 $this->error='Permission denied
';
762 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'QUICKMEMO_MEMO_UNVALIDATE
');
773 public function setArchived($user, $notrigger = 0)
775 $this->date_archived = dol_now();
776 $this->fk_user_archived = $user->id;
777 $this->status = self::STATUS_ARCHIVED;
778 return $this->update($user, $notrigger);
789 public function setUnArchived($user, $notrigger = 0)
791 $this->date_archived = null;
792 $this->fk_user_archived = null;
793 $this->status = self::STATUS_VALIDATED;
794 return $this->update($user, $notrigger);
804 public function cancel($user, $notrigger = 0)
807 if ($this->status != self::STATUS_VALIDATED) {
811 /* if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','write
'))
812 || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','quickmemo_advance
','validate'))))
814 $this->error='Permission denied
';
818 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'QUICKMEMO_MEMO_CANCEL
');
828 public function reopen($user, $notrigger = 0)
831 if ($this->status == self::STATUS_VALIDATED) {
835 /*if (! ((!getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','write
'))
836 || (getDolGlobalInt('MAIN_USE_ADVANCED_PERMS
') && $user->hasRight('quickmemo
','quickmemo_advance
','validate'))))
838 $this->error='Permission denied
';
842 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'QUICKMEMO_MEMO_REOPEN
');
852 public function getTooltipContentArray($params)
858 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER
')) {
859 return ['optimize
' => $langs->trans("ShowMemo")];
861 $datas['picto
'] = img_picto('', $this->picto).' <u>
'.$langs->trans("Memo").'</u>
';
862 if (isset($this->status)) {
863 $datas['picto
'] .= ' '.$this->getLibStatut(5);
879 public function getNomUrl($withpicto = 0, $option = '
', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
881 global $conf, $langs, $hookmanager;
883 if (!empty($conf->dol_no_mouse_hover)) {
884 $notooltip = 1; // Force disable tooltips
889 'id' => (string) $this->id,
890 'objecttype
' => $this->element.($this->module ? '@
'.$this->module : ''),
893 $classfortooltip = 'classfortooltip
';
895 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP
')) {
896 $classfortooltip = 'classforajaxtooltip
';
897 $dataparams = ' data-params=
"'.dol_escape_htmltag(json_encode($params)).'"';
900 $label = implode($this->getTooltipContentArray($params));
903 $baseurl = dol_buildpath('/quickmemo/memo_card.php
', 1);
904 $query = ['id' => $this->id];
905 if ($option !== 'nolink
') {
906 // Add param to save lastsearch_values or not
907 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
908 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/
', $_SERVER["PHP_SELF"])) {
909 $add_save_lastsearch_values = 1;
911 if ($add_save_lastsearch_values) {
912 $query = array_merge($query, ['save_lastsearch_values
' => 1]);
915 $url = dolBuildUrl($baseurl, $query);
918 if (empty($notooltip)) {
919 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER
')) {
920 $label = $langs->trans("ShowMemo");
921 $linkclose .= ' alt=
"'.dolPrintHTMLForAttribute($label).'"';
923 $linkclose .= ($label ? ' title=
"'.dolPrintHTMLForAttribute($label).'"' : ' title=
"tocomplete"');
924 $linkclose .= $dataparams.' class=
"'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
926 $linkclose = ($morecss ? ' class=
"'.$morecss.'"' : '');
929 if ($option == 'nolink
') {
930 $linkstart = '<span
';
932 $linkstart = '<a href=
"'.$url.'"';
934 $linkstart .= $linkclose.'>
';
935 if ($option == 'nolink
') {
936 $linkend = '</span>
';
941 $result .= $linkstart;
943 if (empty($this->showphoto_on_popup)) {
945 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class=
"paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
949 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php
';
951 [$class, $module] = explode('@
', $this->picto);
952 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
953 $filearray = dol_dir_list($upload_dir, "files");
954 $filename = $filearray[0]['name'];
955 if (!empty($filename)) {
956 $pospoint = strpos($filearray[0]['name'], '.
');
958 $pathtophoto = $class.'/
'.$this->ref.'/thumbs/
'.substr($filename, 0, $pospoint).'_mini
'.substr($filename, $pospoint);
959 if (!getDolGlobalString(strtoupper($module.'_
'.$class).'_FORMATLISTPHOTOSASUSERS
')) {
960 $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>
';
962 $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>
';
967 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class=
"paddingright"' : '') : 'class=
"'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
972 if ($withpicto != 2) {
973 $result .= $this->ref;
977 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
979 global $action, $hookmanager;
980 $hookmanager->initHooks(array($this->element.'dao
'));
981 $parameters = array('id' => $this->id, 'getnomurl
' => &$result);
982 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
984 $result = $hookmanager->resPrint;
986 $result .= $hookmanager->resPrint;
999 public function getKanbanView($option = '
', $arraydata = null)
1001 global $conf, $langs;
1003 $selected = (empty($arraydata['selected
']) ? 0 : $arraydata['selected
']);
1005 $return = '<div
class=
"box-flex-item box-flex-grow-zero">
';
1006 $isDarkMode = !empty($this->color) && !colorIsLight($this->color) ? '--memo-is-dark
' : '';
1007 $style = !empty($this->color) && Memo::checkColor($this->color) ? ' style=
"--memo-color : '.$this->color.'" ' : '';
1008 $return .= '<div
class=
"info-box-quickmemo '.$isDarkMode.'" '.$style.' >
';
1009 $return .= '<div
class=
"info-box-content-quickmemo">
';
1011 $return .= '<span
class=
"info-box-status">
'.$this->getLibStatut(4).'</span>
';
1013 // $return .= '<span
class=
"info-box-ref inline-block tdoverflowmax150 valignmiddle">
'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>
';
1014 if ($selected >= 0) {
1015 $return .= '<input
id=
"cb'.$this->id.'" class=
"flat checkforselect fright" type=
"checkbox" name=
"toselect[]" value=
"'.$this->id.'"'.($selected ? ' checked=
"checked"' : '').'>
';
1020 $return .= ' <div
class=
"info-box-content-quicknote">
';
1021 $return .= nl2br(htmlentities($this->quick_note));
1022 $return .= '</div>
';
1024 $return .= '<div
class=
"quickmemo-info" >
';
1025 $return .= ' <div
class=
"quickmemo-info__create" >
';
1026 $return .= ' <span
class=
"quickmemo-info__user-create-name">
'.$this->showOutputField($this->fields['fk_user_creat
'], 'fk_user_creat
', $this->user_creation_id).'</span>
';
1027 $return .= ' <span
class=
"quickmemo-info__date_create">
'.dol_print_date($this->date_creation, '%d/%m/%Y %H:%M
', 'tzuserrel
').'</span>
';
1028 $return .= ' </div>
';
1031 if (!empty($this->tms) && $this->tms != $this->date_creation) {
1032 $return .= ' <div class=
"quickmemo-info__update" >
';
1034 $return .= ' <span class=
"quickmemo-info__date_update">
'.$langs->trans('QuickMemoModified
') . ' ' .dol_print_date($this->date_modification, '%d/%m/%Y %H:%M
', 'tzuserrel
').'</span>
';
1035 if ($this->user_modification_id != $this->user_creation_id) {
1036 $return .= ' <span class=
"quickmemo-info__user-update-name">
'.$langs->trans('QuickMemoBy
') . ' ' .$this->showOutputField($this->fields['fk_user_modif
'], 'fk_user_modif
', $this->user_modification_id).'</span>
';
1039 $return .= ' </div>
';
1042 if (!empty($this->date_archived) && $this->status == self::STATUS_ARCHIVED) {
1043 $return .= ' <div class=
"quickmemo-info__update" >
';
1045 $return .= ' <span class=
"quickmemo-info__date_update">
'.$langs->trans('QuickMemoArchived
') . ' ' .dol_print_date($this->date_archived, '%d/%m/%Y %H:%M
', 'tzuserrel
').'</span>
';
1046 if ($this->fk_user_modif != $this->fk_user_archived) {
1047 $return .= ' <span class=
"quickmemo-info__user-update-name">
'.$langs->trans('QuickMemoBy
') . ' ' .$this->showOutputField($this->fields['fk_user_archived
'], 'fk_user_archived
', $this->fk_user_archived).'</span>
';
1050 $return .= ' </div>
';
1053 $return .= '</div>
';
1058 $return .= '</div>
';
1059 $return .= '</div>
';
1060 $return .= '</div>
';
1071 public function getLabelStatus($mode = 0)
1073 return $this->LibStatut($this->status, $mode);
1082 public function getLibStatut($mode = 0)
1084 return $this->LibStatut($this->status, $mode);
1087 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1095 public function LibStatut($status, $mode = 0)
1098 if (is_null($status)) {
1102 $paramsBadge = array('badgeParams
' => array('attr
' => array(
1103 'data-
status-element
' => $this->element,
1104 'data-
status' => (int) $status
1108 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1110 //$langs->load("quickmemo");
1111 $this->labelStatus[self::STATUS_TPL] = $langs->transnoentitiesnoconv('Template
');
1112 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled
');
1113 $this->labelStatus[self::STATUS_ARCHIVED] = $langs->transnoentitiesnoconv('Archived
');
1114 $this->labelStatusShort[self::STATUS_TPL] = $langs->transnoentitiesnoconv('Template
');
1115 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled
');
1116 $this->labelStatusShort[self::STATUS_ARCHIVED] = $langs->transnoentitiesnoconv('Archived
');
1119 $statusType = 'status'.$status;
1120 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1
';
1121 if ($status == self::STATUS_ARCHIVED) {
1122 $statusType = 'status6
';
1125 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $paramsBadge);
1134 public function info($id)
1136 $sql = "SELECT t.rowid, t.date_creation as datec";
1137 if (!empty($this->isextrafieldmanaged) && $this->isextrafieldmanaged == 1) {
1138 $sql .= ", GREATEST(t.tms, te.tms) as datem";
1140 $sql .= ", t.tms as datem";
1142 if (!empty($this->fields['date_validation
'])) {
1143 $sql .= ", t.date_validation as datev";
1145 if (!empty($this->fields['fk_user_creat
'])) {
1146 $sql .= ", t.fk_user_creat";
1148 if (!empty($this->fields['fk_user_modif
'])) {
1149 $sql .= ", t.fk_user_modif";
1151 if (!empty($this->fields['fk_user_valid
'])) {
1152 $sql .= ", t.fk_user_valid";
1154 $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
1155 if (!empty($this->isextrafieldmanaged) && $this->isextrafieldmanaged == 1) {
1156 $sql .= " LEFT JOIN ".$this->db->prefix().$this->table_element."_extrafields as te ON te.fk_object = t.rowid";
1158 $sql .= " WHERE t.rowid = ".((int) $id);
1160 $result = $this->db->query($sql);
1162 if ($this->db->num_rows($result)) {
1163 $obj = $this->db->fetch_object($result);
1165 $this->id = $obj->rowid;
1167 if (!empty($this->fields['fk_user_creat
'])) {
1168 $this->user_creation_id = $obj->fk_user_creat;
1170 if (!empty($this->fields['fk_user_modif
'])) {
1171 $this->user_modification_id = $obj->fk_user_modif;
1173 if (!empty($this->fields['fk_user_valid
'])) {
1174 $this->user_validation_id = $obj->fk_user_valid;
1176 $this->date_creation = $this->db->jdate($obj->datec);
1177 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1178 if (!empty($obj->datev)) {
1179 $this->date_validation = empty($obj->datev) ? '' : $this->db->jdate($obj->datev);
1183 $this->db->free($result);
1185 dol_print_error($this->db);
1195 public function initAsSpecimen()
1197 // Set here init that are not commonf fields
1198 // $this->property1 = ...
1199 // $this->property2 = ...
1201 return $this->initAsSpecimenCommon();
1210 public function getNextNumRef()
1226 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1237 public static function checkColor($color)
1239 if (!is_string($color)) {
1243 // Remove spaces at the beginning/end
1244 $color = trim($color);
1246 // Vérifie #fff ou #ffffff
1247 return preg_match('/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
', $color) === 1;
1255 public static function getColorPreset()
1258 $colorsConf = getDolGlobalString('QUICKMEMO_COLORS_PRESET
');
1259 $colors = explode(',
', $colorsConf);
1260 if (!empty($colors)) {
1261 foreach ($colors as $iColor => $color) {
1262 if (!preg_match('/^#[a-f0-9]{6}$/i
', $color)) {
1263 unset($colors[$iColor]);
1268 if (empty($colors)) {
1269 $colors = ['#fff8a6
', '#ffd6d6
', '#d6ffd9
', '#d6e6ff
', '#f3d6ff
', '#ffffff
', '#f5f5f5
'];
1272 return array_values($colors);
1283 public static function getMemoContext($context, $object = null)
1285 global $db,$action, $hookmanager;
1287 if (!isModEnabled('quickmemo
')) {
1291 if (!is_array($context)) {
1292 $context = explode(':
', $context);
1295 $contextMapping = self::getAvailableMemoContextMapping();
1298 foreach ($contextMapping as $key => $values) {
1299 $values = (array) $values;
1301 if (array_intersect($context, $values)) {
1302 $memoContext = $key;
1307 $staticMemo = new self($db);
1309 $hookmanager->initHooks(array($staticMemo->element.'dao
'));
1310 $parameters = array(
1311 'memoContext
' => & $memoContext
1314 $reshook = $hookmanager->executeHooks('getMemoContext', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1316 return $hookmanager->resPrint;
1319 return $memoContext;
1329 public static function completeMemoContextMapping(array &$contextTabMapping, string $tabContext, string $dolibarrContext = '
')
1331 $dolibarrContext = trim($dolibarrContext) ?: $tabContext;
1333 if (!isset($contextTabMapping[$tabContext])) {
1334 $contextTabMapping[$tabContext] = [$dolibarrContext];
1338 if (!in_array($dolibarrContext, $contextTabMapping[$tabContext], true)) {
1339 $contextTabMapping[$tabContext][] = $dolibarrContext;
1351 public static function getAvailableMemoContextMapping($object = null, $onlyActiveModules = true)
1353 global $db,$action, $hookmanager;
1355 $contextTabMapping = [];
1357 // Start Correction of no standard Dolibarr context and special context
1358 if (isModEnabled('propal
') || !$onlyActiveModules) {
1359 self::completeMemoContextMapping($contextTabMapping, 'contactcard
', 'proposalcontactcard
');
1362 if (isModEnabled('supplier_order
') || !$onlyActiveModules) {
1363 self::completeMemoContextMapping($contextTabMapping, 'contactcard
', 'ordersuppliercontactcard
');
1364 self::completeMemoContextMapping($contextTabMapping, 'document
', 'ordersuppliercarddocument
');
1365 self::completeMemoContextMapping($contextTabMapping, 'agenda
', 'ordersuppliercardinfo
');
1366 self::completeMemoContextMapping($contextTabMapping, 'ordersupplierdispatch
');
1369 if (isModEnabled('contract
') || !$onlyActiveModules) {
1370 self::completeMemoContextMapping($contextTabMapping, 'agenda
', 'agendacontract
');
1373 if (isModEnabled('order
') || !$onlyActiveModules) {
1374 self::completeMemoContextMapping($contextTabMapping, 'ordershipmentcard
');
1377 if (isModEnabled('shipping
')) {
1378 self::completeMemoContextMapping($contextTabMapping, 'contactcard
', 'shipmentcontactcard
');
1381 if (isModEnabled('product
')) {
1382 self::completeMemoContextMapping($contextTabMapping, 'productpricecard
');
1383 self::completeMemoContextMapping($contextTabMapping, 'pricesuppliercard
');
1384 self::completeMemoContextMapping($contextTabMapping, 'producttranslationcard
');
1385 self::completeMemoContextMapping($contextTabMapping, 'productcompositioncard
');
1386 self::completeMemoContextMapping($contextTabMapping, 'stockproductcard
');
1387 self::completeMemoContextMapping($contextTabMapping, 'productstatsinvoice
');
1388 self::completeMemoContextMapping($contextTabMapping, 'productstatscard
');
1389 self::completeMemoContextMapping($contextTabMapping, 'tabproductmarginlist
');
1392 // End of corrections
1394 // Generate standard context
1395 // TODO : Common contexts such as document, agenda, contact card, and stat, which are used across most Dolibarr objects, are not defined as standard global contexts.
1396 // Instead of having dedicated contexts like global_document, global_agenda, global_contactcard, or global_stat (similar to global_card), pages currently mix global_card with object-specific contexts (e.g. product_document, propal_agenda, etc.).
1397 // This creates inconsistent context handling. These contexts should include both their object-specific context and a proper global context (e.g. global_document or global_agenda) depending on the active tab.
1398 $commonCardContext = ['document
', 'agenda
', 'contactcard
', 'stats
']; // for common object
1399 $modules = ['order
', 'propal
', 'invoice
', 'supplier_proposal
', 'supplier_order
', 'supplier_invoice
', 'contract
', 'product
', 'shipping
'];
1400 foreach ($modules as $module) {
1401 if (!isModEnabled($module) && $onlyActiveModules) {
1405 $moduleClean = str_replace('_
', '', $module);
1407 foreach ($commonCardContext as $context) {
1408 self::completeMemoContextMapping($contextTabMapping, $context, $moduleClean.$context);
1412 if (!empty($object) && !empty($object->element)) {
1413 foreach ($commonCardContext as $context) {
1414 self::completeMemoContextMapping($contextTabMapping, $context, $object->element.$context);
1418 // Need to be at end of tests
1419 self::completeMemoContextMapping($contextTabMapping, 'index
');
1420 self::completeMemoContextMapping($contextTabMapping, 'card
', 'globalcard
');
1422 $staticMemo = new self($db);
1423 $hookmanager->initHooks(array($staticMemo->element.'dao
'));
1424 $parameters = array(
1425 'contextTabMapping
' => & $contextTabMapping,
1426 'onlyActiveModules
' => $onlyActiveModules
1429 $reshook = $hookmanager->executeHooks('getAvailableMemoContextMapping', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1431 return $hookmanager->resArray;
1434 return $contextTabMapping;
1443 public static function getAvailableMemoContext()
1445 global $db,$action, $hookmanager;
1447 $contextMapping = self::getAvailableMemoContextMapping();
1448 $list = array_keys($contextMapping);
1450 $staticMemo = new self($db);
1451 $hookmanager->initHooks(array($staticMemo->element.'dao
'));
1452 $parameters = array(
1455 $object = null; // @phan-suppress-next-line PhanPluginConstantVariableNull
1456 $reshook = $hookmanager->executeHooks('getAvailableMemoContext', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1458 $list = $hookmanager->resArray;
1463 foreach ($list as $k => $v) {
1464 if (!is_string($v)) {
1467 if (strlen($v) > 64) {
1470 if (preg_match('/^[a-zA-Z0-9_]+$/
', $k) !== 1) {
1490 public function countArchivedMemoQuery($element_type, $element_id, $context, $id = 0)
1494 $sql = 'SELECT COUNT(m.rowid) nb
1495 FROM '.MAIN_DB_PREFIX.$this->table_element.' m
1496 WHERE m.element_type = \''.$this->db->escape($element_type).'\'
1497 AND ( m.fk_element = '.(
int) $element_id.' OR m.shared_on_element = 1 )
1498 AND m.context_tab = \''.$this->db->escape($context).'\'
1500 AND (m.private = 0 OR m.fk_user_creat = '.(
int) $user->
id.')
1503 if ((
int) $id > 0) {
1504 $sql .=
' AND m.rowid = ' . (int)
$id;
1507 $obj = $this->db->getRow($sql);
1512 return (
int) $obj->nb;
1529 $sql =
'SELECT m.rowid, m.quick_note, m.pos_x, m.pos_y, m.pos_w, m.pos_h, m.pos_z, m.color, m.fk_user_creat, m.fk_user_modif, m.shared_on_element, m.date_creation, m.tms, m.private,
1530 mu.pos_x as user_pos_x, mu.pos_y as user_pos_y, mu.pos_w as user_pos_w, mu.pos_h as user_pos_h, mu.pos_z as user_pos_z
1531 FROM '.MAIN_DB_PREFIX.$this->table_element.
' m
1532 LEFT JOIN '.MAIN_DB_PREFIX.$this->table_element.
'_user mu
1533 ON mu.fk_memo = m.rowid
1534 AND mu.fk_user = '.(int) $user->id.
'
1535 WHERE m.element_type = \''.$this->db->escape($element_type).
'\'
1536 AND ( m.fk_element =
'.(int) $element_id.' OR m.shared_on_element = 1 )
1537 AND m.context_tab = \
''.$this->db->escape($context).
'\'
1538 AND m.status =
'.self::STATUS_VALIDATED.'
1539 AND (COALESCE(m.private, 0) = 0 OR m.fk_user_creat =
'.(int) $user->id.')
1542 if ((int) $id > 0) {
1543 $sql .= ' AND m.rowid =
' . (int) $id;
1546 $sql .= ' ORDER BY COALESCE(mu.pos_z, m.pos_z) ASC
';
1560 public function getTemplateMemosQuery($element_type, $context_tab = '
', $id = 0)
1564 $sql = 'SELECT m.rowid, m.quick_note, m.pos_x, m.pos_y, m.pos_w, m.pos_h, m.color, m.pos_z,
1565 m.fk_user_creat, m.fk_user_modif, m.shared_on_element, m.date_creation, m.tms, m.private, m.name_tpl,m.rank_tpl,
1566 mu.pos_x as user_pos_x, mu.pos_y as user_pos_y, mu.pos_w as user_pos_w, mu.pos_h as user_pos_h, mu.pos_z as user_pos_z
1567 FROM
'.MAIN_DB_PREFIX.$this->table_element.' m
1568 LEFT JOIN
'.MAIN_DB_PREFIX.$this->table_element.'_user mu
1569 ON mu.fk_memo = m.rowid
1570 AND mu.fk_user =
'.(int) $user->id.'
1571 WHERE m.element_type IN (\
''.$this->db->escape($element_type).
'\', \
'\')
1572 AND m.status =
'.self::STATUS_TPL.'
1573 AND (COALESCE(m.private_tpl, 0) = 0 OR m.fk_user_creat =
'.(int) $user->id.')
1576 if (!empty($context_tab)) {
1577 //$sql.= ' AND (m.context_tab = \
''.$this->db->escape($context_tab).
'\' OR m.element_type = \
'\' )
';
1580 if ((int) $id > 0) {
1581 $sql .= ' AND m.rowid =
' . (int) $id;
1584 $sql .= " ORDER BY m.rank_tpl DESC, m.rowid ASC "; // Due to multiple type of sort panel rank_tpl is reversed higher is first and rowid ASC to keep last add is last
1602 public function showOutputField($val, $key, $value, $moreparam = '
', $keysuffix = '', $keyprefix = '', $morecss = '')
1604 global $conf, $langs, $form;
1606 if ($key == 'color
' && self::checkColor($value)) {
1607 $badgeBase = colorIsLight($value) ? 'badge-light
' : 'badge-dark
';
1608 return '<span
class=
"badge badge-pill '.$badgeBase.'" style=
"background-color: '.$value.'" >
'.$value.'</span>
';
1611 if ($key == 'quick_note
') {
1612 return nl2br(htmlentities($value));
1615 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
1624 public static function loadQuickMemoJsInterface($jsConfVars)
1628 if (!isModEnabled('quickmemo
')) {
1632 // DO NOT LOAD TWICE
1633 if (defined('QUICKMEMOJS
')) {
1637 if (defined('NOREQUIRETRAN
') || empty($user) || empty($user->id) || (int) $user->socid > 0) {
1641 if (!$user->hasRight('quickmemo
', 'memo
', 'read
')) {
1645 $autoResizeFontMin = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MIN_FONT_SIZE
', 1);
1646 $autoResizeFontMax = getDolGlobalFloat('QUICKMEMO_AUTO_RESIZE_MAX_FONT_SIZE
', 1.4);
1648 // Apply safety limits
1649 $autoResizeFontMin = max($autoResizeFontMin, 0.3);
1650 $autoResizeFontMax = min($autoResizeFontMax, 5);
1652 // Ensure min value is always lower than max value
1653 if ($autoResizeFontMin >= $autoResizeFontMax) {
1654 $autoResizeFontMin = max(0.3, $autoResizeFontMax - 0.1);
1657 $defaultJsConfVars = [
1658 'interfaceUrl
' => dol_buildpath('quickmemo/interface.php
', 1),
1659 'archivesUrl
' => dol_buildpath('quickmemo/memo_list.php
', 1) . '?mode=kanban&search_status=
'.Memo::STATUS_ARCHIVED . ($jsConfVars['archivesUrlParams
'] ?? ''),
1661 'elementType
' => '',
1663 'token
' => newToken(),
1664 'colors
' => Memo::getColorPreset(),
1665 'userReadRight
' => $user->hasRight('quickmemo
', 'memo
', 'read
'),
1666 'userWriteRight
' => $user->hasRight('quickmemo
', 'memo
', 'write
'),
1667 'userDeleteRight
' => $user->hasRight('quickmemo
', 'memo
', 'delete'),
1668 'autoResizeFontSize
' => !getDolGlobalInt('QUICKMEMO_DISABLE_AUTO_RESIZE_FONT_SIZE
'),
1669 'autoResizeFontMin
' => $autoResizeFontMin,
1670 'autoResizeFontMax
' => $autoResizeFontMax,
1672 $jsConfVars = array_merge($defaultJsConfVars, $jsConfVars);
1674 if (!empty($jsConfVars['elementType
'])) {
1675 $jsConfVars['shareBtnStatus
'] = 1;
1679 print '<link rel=
"stylesheet" type=
"text/css" href=
"'.dol_buildpath('quickmemo/css/memo.css', 1) . '">
'."\n";
1680 print '<link rel=
"stylesheet" type=
"text/css" href=
"'.dol_buildpath('quickmemo/css/memo-dialog.css', 1) . '">
'."\n";
1681 print '<script nonce=
"'.getNonce().'" src=
"'.dol_buildpath('quickmemo/js/QuickMemo.js', 1).'" ></script>
'."\n";
1683 print '<script nonce=
"'.getNonce().'">
1684 document.addEventListener(\
'Dolibarr:Ready\', function() {
1685 if(!Dolibarr.checkToolExist(\'quickMemo\')) {
1686 Dolibarr.defineTool(\'quickMemo\', new QuickMemo('.json_encode($jsConfVars).
') );
1691 define(
'QUICKMEMOJS',
true);
1707 $memo->id = $this->id;
1708 $memo->color = $this->color;
1709 $memo->note = $this->quick_note;
1711 $memo->pos_x = (int) $this->pos_x;
1712 $memo->pos_y = (int) $this->pos_y;
1713 $memo->pos_w = (int) $this->pos_w;
1714 $memo->pos_h = (int) $this->pos_h;
1716 if ($currentUser->id != $memo->fk_user_creat) {
1720 $memo->shared_on_element = $this->shared_on_element;
1721 $memo->private = (int) $this->
private;
1722 $memo->date_creation =
dol_print_date($this->date_creation,
'%d/%m/%Y %H:%M',
'tzuserrel');
1723 $memo->date_change =
'';
1724 if (!empty($this->tms) && ((
int) $this->date_creation !== (
int) $this->tms || (
int) $this->fk_user_modif > 0)) {
1725 $memo->date_change =
dol_print_date($this->tms,
'%d/%m/%Y %H:%M',
'tzuserrel');
1728 $memo->fk_user_creat = $this->fk_user_creat;
1729 $memo->user_name =
'';
1730 if ((
int) $this->fk_user_creat > 0) {
1731 $userCreate =
new User($this->db);
1732 if ($userCreate->fetch((
int) $this->fk_user_creat) > 0) {
1733 $memo->user_name = $userCreate->getFullName($langs);
1737 $memo->fk_user_modif = $this->fk_user_modif;
1738 $memo->user_change_name =
'';
1739 if ((
int) $this->fk_user_modif > 0) {
1740 $userMod =
new User($this->db);
1741 if ($userMod->fetch((
int) $this->fk_user_modif) > 0) {
1742 $memo->user_change_name = $userMod->getFullName($langs);
1758 $memo->color =
null;
1764 $memo->shared_on_element = 0;
1766 $memo->date_creation =
'';
1767 $memo->date_change =
'';
1768 $memo->fk_user_creat =
null;
1769 $memo->user_name =
'';
1770 $memo->fk_user_modif =
null;
1771 $memo->user_change_name =
'';
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
Parent class of all other business classes (invoices, contracts, proposals, orders,...
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.
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.
Class to manage Dolibarr database access.
$fields
'type' field format: 'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortf...
static getAvailableMemoContext()
Get available memo context.
createFromClone(User $user, $fromid)
Clone an object into another one.
create(User $user, $notrigger=0)
Create object into database.
static getAvailableMemoContextMapping($object=null, $onlyActiveModules=true)
Get available memo context.
fetchAll($sortorder='', $sortfield='', $limit=1000, $offset=0, string $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getJsMemo(User $currentUser)
Get JS memo.
update(User $user, $notrigger=0)
Update object into database.
static getJsMemoDefault()
Get JS memo default.
getMemosQuery($element_type, $element_id, $context, $id=0)
Get memos query.
fetch($id, $ref=null, $noextrafields=0, $nolines=0)
Load object in memory from the database.
__construct(DoliDB $db)
Constructor.
fetchLines($noextrafields=0)
Load object lines in memory from the database.
static getMemoContext($context, $object=null)
Get memo context.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
validate($user, $notrigger=0)
Validate object.
updatePosition(User $user, int $x, int $y, int $w, int $h, int $z)
Update position of a memo for a specific user.
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...
dol_now($mode='gmt')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
Abort invoice creation with a given error message.
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
$conf db name
Only used if Module[ID]Name translation string is not found.