dolibarr 19.0.3
knowledgerecord.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
24// Put here all includes required by your class file
25require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
26//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
27//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
28
33{
37 public $module = 'knowledgemanagement';
38
42 public $element = 'knowledgerecord';
43
47 public $table_element = 'knowledgemanagement_knowledgerecord';
48
53 public $ismultientitymanaged = 1;
54
58 public $isextrafieldmanaged = 1;
59
63 public $picto = 'knowledgemanagement';
64
65
66 const STATUS_DRAFT = 0;
67 const STATUS_VALIDATED = 1;
68 const STATUS_CANCELED = 9;
69
70
98 // BEGIN MODULEBUILDER PROPERTIES
102 public $fields=array(
103 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
104 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'visible'=>5, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", "csslist"=>"nowraponall", "showoncombobox"=>1),
105 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>20, 'index'=>1),
106 'question' => array('type'=>'text', 'label'=>'Question', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1, 'tdcss'=>'titlefieldcreate nowraponall'),
107 'lang' => array('type'=>'varchar(6)', 'label'=>'Language', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'tdcss'=>'titlefieldcreate nowraponall', "csslist"=>"tdoverflowmax100"),
108 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
109 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>2,),
110 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>0,),
111 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCreation', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',),
112 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
113 'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>'1', 'position'=>512, 'notnull'=>0, 'visible'=>-2,),
114 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
115 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
116 //'url' => array('type'=>'varchar(255)', 'label'=>'URL', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'csslist'=>'tdoverflow200', 'help'=>'UrlForInfoPage'),
117 'fk_c_ticket_category' => array('type'=>'integer:CTicketCategory:ticket/class/cticketcategory.class.php:0:(t.active:=:1):pos', 'label'=>'SuggestedForTicketsInGroup', 'enabled'=>'isModEnabled("ticket")', 'position'=>520, 'notnull'=>0, 'visible'=>-1, 'help'=>'YouCanLinkArticleToATicketCategory', 'csslist'=>'minwidth200 tdoverflowmax250'),
118 'answer' => array('type'=>'html', 'label'=>'Solution', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>3, 'searchall'=>1, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1, 'tdcss'=>'titlefieldcreate nowraponall'),
119 'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'default'=>0, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Obsolete'),),
120 );
121 public $rowid;
122 public $ref;
123 public $entity;
124 public $date_creation;
125 public $tms;
126 public $last_main_doc;
127 public $fk_user_creat;
128 public $fk_user_modif;
129 public $fk_user_valid;
130 public $import_key;
131 public $model_pdf;
132
136 public $question;
137
141 public $answer;
142 public $url;
143 public $status;
144 public $lang;
145 // END MODULEBUILDER PROPERTIES
146
147
148 // If this object has a subtable with lines
149
150 // /**
151 // * @var string Name of subtable line
152 // */
153 // public $table_element_line = 'knowledgemanagement_knowledgerecordline';
154
155 // /**
156 // * @var string Field with ID of parent key if this object has a parent
157 // */
158 // public $fk_element = 'fk_knowledgerecord';
159
160 // /**
161 // * @var string Name of subtable class that manage subtable lines
162 // */
163 // public $class_element_line = 'KnowledgeRecordline';
164
165 // /**
166 // * @var array List of child tables. To test if we can delete object.
167 // */
168 // protected $childtables = array();
169
170 // /**
171 // * @var array List of child tables. To know object to delete on cascade.
172 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
173 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
174 // */
175 // protected $childtablesoncascade = array('knowledgemanagement_knowledgerecorddet');
176
177 // /**
178 // * @var KnowledgeRecordLine[] Array of subtable lines
179 // */
180 // public $lines = array();
181
182
183
189 public function __construct(DoliDB $db)
190 {
191 global $conf, $langs;
192
193 $this->db = $db;
194
195 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
196 $this->fields['rowid']['visible'] = 0;
197 }
198 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
199 $this->fields['entity']['enabled'] = 0;
200 }
201
202 // Example to show how to set values of fields definition dynamically
203 /*if ($user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
204 $this->fields['myfield']['visible'] = 1;
205 $this->fields['myfield']['noteditable'] = 0;
206 }*/
207
208 // Unset fields that are disabled
209 foreach ($this->fields as $key => $val) {
210 if (isset($val['enabled']) && empty($val['enabled'])) {
211 unset($this->fields[$key]);
212 }
213 }
214
215 // Translate some data of arrayofkeyval
216 if (is_object($langs)) {
217 foreach ($this->fields as $key => $val) {
218 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
219 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
220 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
221 }
222 }
223 }
224 }
225 }
226
234 public function create(User $user, $notrigger = false)
235 {
236 return $this->createCommon($user, $notrigger);
237 }
238
246 public function createFromClone(User $user, $fromid)
247 {
248 global $langs, $extrafields;
249 $error = 0;
250
251 dol_syslog(__METHOD__, LOG_DEBUG);
252
253 $object = new self($this->db);
254
255 $this->db->begin();
256
257 // Load source object
258 $result = $object->fetchCommon($fromid);
259 if ($result > 0 && !empty($object->table_element_line)) {
260 $object->fetchLines();
261 }
262
263 // get lines so they will be clone
264 //foreach($this->lines as $line)
265 // $line->fetch_optionals();
266
267 // Reset some properties
268 unset($object->id);
269 unset($object->fk_user_creat);
270 unset($object->import_key);
271
272 // Clear fields
273 if (property_exists($object, 'ref')) {
274 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
275 }
276 if (property_exists($object, 'question')) {
277 $object->question = empty($this->fields['question']['default']) ? $langs->trans("CopyOf")." ".$object->question : $this->fields['question']['default'];
278 }
279 if (property_exists($object, 'status')) {
280 $object->status = self::STATUS_DRAFT;
281 }
282 if (property_exists($object, 'date_creation')) {
283 $object->date_creation = dol_now();
284 }
285 if (property_exists($object, 'date_modification')) {
286 $object->date_modification = null;
287 }
288 // ...
289 // Clear extrafields that are unique
290 if (is_array($object->array_options) && count($object->array_options) > 0) {
291 $extrafields->fetch_name_optionals_label($this->table_element);
292 foreach ($object->array_options as $key => $option) {
293 $shortkey = preg_replace('/options_/', '', $key);
294 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
295 //var_dump($key);
296 //var_dump($clonedObj->array_options[$key]); exit;
297 unset($object->array_options[$key]);
298 }
299 }
300 }
301
302 // Create clone
303 $object->context['createfromclone'] = 'createfromclone';
304 $result = $object->createCommon($user);
305 if ($result < 0) {
306 $error++;
307 $this->error = $object->error;
308 $this->errors = $object->errors;
309 }
310
311 if (!$error) {
312 // copy internal contacts
313 if ($this->copy_linked_contact($object, 'internal') < 0) {
314 $error++;
315 }
316 }
317
318 if (!$error) {
319 // copy external contacts if same company
320 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
321 if ($this->copy_linked_contact($object, 'external') < 0) {
322 $error++;
323 }
324 }
325 }
326
327 unset($object->context['createfromclone']);
328
329 // End
330 if (!$error) {
331 $this->db->commit();
332 return $object;
333 } else {
334 $this->db->rollback();
335 return -1;
336 }
337 }
338
346 public function fetch($id, $ref = null)
347 {
348 $result = $this->fetchCommon($id, $ref);
349 if ($result > 0 && !empty($this->table_element_line)) {
350 $this->fetchLines();
351 }
352 return $result;
353 }
354
360 public function fetchLines()
361 {
362 $this->lines = array();
363
364 $result = $this->fetchLinesCommon();
365 return $result;
366 }
367
368
380 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
381 {
382 global $conf;
383
384 dol_syslog(__METHOD__, LOG_DEBUG);
385
386 $records = array();
387
388 $sql = 'SELECT ';
389 $sql .= $this->getFieldList('t');
390 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
391 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
392 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
393 } else {
394 $sql .= ' WHERE 1 = 1';
395 }
396 // Manage filter
397 $sqlwhere = array();
398 if (count($filter) > 0) {
399 foreach ($filter as $key => $value) {
400 if ($key == 't.rowid') {
401 $sqlwhere[] = $key." = ".((int) $value);
402 } elseif (array_key_exists($key, $this->fields) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
403 $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
404 } elseif ($key == 'customsql') {
405 $sqlwhere[] = $value;
406 } elseif (strpos($value, '%') === false) {
407 $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')';
408 } else {
409 $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
410 }
411 }
412 }
413 if (count($sqlwhere) > 0) {
414 $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
415 }
416
417 if (!empty($sortfield)) {
418 $sql .= $this->db->order($sortfield, $sortorder);
419 }
420 if (!empty($limit)) {
421 $sql .= $this->db->plimit($limit, $offset);
422 }
423
424 $resql = $this->db->query($sql);
425 if ($resql) {
426 $num = $this->db->num_rows($resql);
427 $i = 0;
428 while ($i < ($limit ? min($limit, $num) : $num)) {
429 $obj = $this->db->fetch_object($resql);
430
431 $record = new self($this->db);
432 $record->setVarsFromFetchObj($obj);
433
434 $records[$record->id] = $record;
435
436 $i++;
437 }
438 $this->db->free($resql);
439
440 return $records;
441 } else {
442 $this->errors[] = 'Error '.$this->db->lasterror();
443 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
444
445 return -1;
446 }
447 }
448
456 public function update(User $user, $notrigger = false)
457 {
458 return $this->updateCommon($user, $notrigger);
459 }
460
468 public function delete(User $user, $notrigger = false)
469 {
470 $error = 0;
471 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_knowledgemanagement WHERE fk_knowledgemanagement = ".((int) $this->id);
472 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
473 $resql = $this->db->query($sql);
474 if (!$resql) {
475 $error++;
476 $this->error .= $this->db->lasterror();
477 $errorflag = -1;
478 }
479
480 // Delete all child tables
481 if (!$error) {
482 $elements = array('categorie_knowledgemanagement');
483 foreach ($elements as $table) {
484 if (!$error) {
485 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$table;
486 $sql .= " WHERE fk_knowledgemanagement = ".(int) $this->id;
487
488 $result = $this->db->query($sql);
489 if (!$result) {
490 $error++;
491 $this->errors[] = $this->db->lasterror();
492 }
493 }
494 }
495 }
496
497 return $this->deleteCommon($user, $notrigger);
498 //return $this->deleteCommon($user, $notrigger, 1);
499 }
500
509 public function deleteLine(User $user, $idline, $notrigger = false)
510 {
511 if ($this->status < 0) {
512 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
513 return -2;
514 }
515
516 return $this->deleteLineCommon($user, $idline, $notrigger);
517 }
518
519
527 public function validate($user, $notrigger = 0)
528 {
529 global $conf, $langs;
530
531 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
532
533 $error = 0;
534
535 // Protection
536 if ($this->status == self::STATUS_VALIDATED) {
537 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
538 return 0;
539 }
540
541 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->hasRight('knowledgemanagement', 'knowledgerecord', 'write'))
542 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgerecord->knowledgerecord_advance->validate))))
543 {
544 $this->error='NotEnoughPermissions';
545 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
546 return -1;
547 }*/
548
549 $now = dol_now();
550
551 $this->db->begin();
552
553 // Define new ref
554 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
555 $num = $this->getNextNumRef();
556 } else {
557 $num = $this->ref;
558 }
559 $this->newref = $num;
560
561 if (!empty($num)) {
562 // Validate
563 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
564 $sql .= " SET ref = '".$this->db->escape($num)."',";
565 $sql .= " status = ".self::STATUS_VALIDATED;
566 if (!empty($this->fields['date_validation'])) {
567 $sql .= ", date_validation = '".$this->db->idate($now)."'";
568 }
569 if (!empty($this->fields['fk_user_valid'])) {
570 $sql .= ", fk_user_valid = ".((int) $user->id);
571 }
572 $sql .= " WHERE rowid = ".((int) $this->id);
573
574 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
575 $resql = $this->db->query($sql);
576 if (!$resql) {
577 dol_print_error($this->db);
578 $this->error = $this->db->lasterror();
579 $error++;
580 }
581
582 if (!$error && !$notrigger) {
583 // Call trigger
584 $result = $this->call_trigger('KNOWLEDGERECORD_VALIDATE', $user);
585 if ($result < 0) {
586 $error++;
587 }
588 // End call triggers
589 }
590 }
591
592 if (!$error) {
593 $this->oldref = $this->ref;
594
595 // Rename directory if dir was a temporary ref
596 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
597 // Now we rename also files into index
598 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'knowledgerecord/".$this->db->escape($this->newref)."'";
599 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'knowledgerecord/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
600 $resql = $this->db->query($sql);
601 if (!$resql) {
602 $error++;
603 $this->error = $this->db->lasterror();
604 }
605 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'knowledgerecord/".$this->db->escape($this->newref)."'";
606 $sql .= " WHERE filepath = 'knowledgerecord/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
607 $resql = $this->db->query($sql);
608 if (!$resql) {
609 $error++;
610 $this->error = $this->db->lasterror();
611 }
612
613 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
614 $oldref = dol_sanitizeFileName($this->ref);
615 $newref = dol_sanitizeFileName($num);
616 $dirsource = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$oldref;
617 $dirdest = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$newref;
618 if (!$error && file_exists($dirsource)) {
619 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
620
621 if (@rename($dirsource, $dirdest)) {
622 dol_syslog("Rename ok");
623 // Rename docs starting with $oldref with $newref
624 $listoffiles = dol_dir_list($conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
625 foreach ($listoffiles as $fileentry) {
626 $dirsource = $fileentry['name'];
627 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
628 $dirsource = $fileentry['path'].'/'.$dirsource;
629 $dirdest = $fileentry['path'].'/'.$dirdest;
630 @rename($dirsource, $dirdest);
631 }
632 }
633 }
634 }
635 }
636
637 // Set new ref and current status
638 if (!$error) {
639 $this->ref = $num;
640 $this->status = self::STATUS_VALIDATED;
641 }
642
643 if (!$error) {
644 $this->db->commit();
645 return 1;
646 } else {
647 $this->db->rollback();
648 return -1;
649 }
650 }
651
652
660 public function setDraft($user, $notrigger = 0)
661 {
662 // Protection
663 if ($this->status <= self::STATUS_DRAFT) {
664 return 0;
665 }
666
667 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
668 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
669 {
670 $this->error='Permission denied';
671 return -1;
672 }*/
673
674 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'KNOWLEDGERECORD_UNVALIDATE');
675 }
676
684 public function cancel($user, $notrigger = 0)
685 {
686 // Protection
687 if ($this->status != self::STATUS_VALIDATED) {
688 return 0;
689 }
690
691 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
692 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
693 {
694 $this->error='Permission denied';
695 return -1;
696 }*/
697
698 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'KNOWLEDGERECORD_CANCEL');
699 }
700
708 public function reopen($user, $notrigger = 0)
709 {
710 // Protection
711 if ($this->status != self::STATUS_CANCELED) {
712 return 0;
713 }
714
715 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
716 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
717 {
718 $this->error='Permission denied';
719 return -1;
720 }*/
721
722 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'KNOWLEDGERECORD_REOPEN');
723 }
724
732 public function getTooltipContentArray($params)
733 {
734 global $conf, $langs;
735
736 $langs->loadLangs(['knowledgemanagement', 'languages']);
737
738 $datas = array();
739 $nofetch = !empty($params['nofetch']);
740
741 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("KnowledgeRecord").'</u>';
742 if (isset($this->statut)) {
743 $datas['picto'] .= ' '.$this->getLibStatut(5);
744 }
745 $datas['label'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
746 $datas['question'] = '<br><b>'.$langs->trans('Question').':</b> '.$this->question;
747 $labellang = ($this->lang ? $langs->trans('Language_'.$this->lang) : '');
748 $datas['lang'] = '<br><b>'.$langs->trans('Language').':</b> ' . picto_from_langcode($this->lang, 'class="paddingrightonly saturatemedium opacitylow"') . $labellang;
749 // show categories for this record only in ajax to not overload lists
750 if (isModEnabled('categorie') && !$nofetch) {
751 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
752 $form = new Form($this->db);
753 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_KNOWLEDGEMANAGEMENT, 1);
754 }
755
756 return $datas;
757 }
758
769 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
770 {
771 global $conf, $langs, $hookmanager;
772
773 if (!empty($conf->dol_no_mouse_hover)) {
774 $notooltip = 1; // Force disable tooltips
775 }
776
777 $result = '';
778
779 $params = [
780 'id' => $this->id,
781 'objecttype' => $this->element.($this->module ? '@'.$this->module : ''),
782 'option' => $option,
783 'nofetch' => 1,
784 ];
785 $classfortooltip = 'classfortooltip';
786 $dataparams = '';
787 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
788 $classfortooltip = 'classforajaxtooltip';
789 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
790 $label = '';
791 } else {
792 $label = implode($this->getTooltipContentArray($params));
793 }
794
795 $url = dol_buildpath('/knowledgemanagement/knowledgerecord_card.php', 1).'?id='.$this->id;
796
797 if ($option != 'nolink') {
798 // Add param to save lastsearch_values or not
799 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
800 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
801 $add_save_lastsearch_values = 1;
802 }
803 if ($add_save_lastsearch_values) {
804 $url .= '&save_lastsearch_values=1';
805 }
806 }
807
808 $linkclose = '';
809 if (empty($notooltip)) {
810 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
811 $label = $langs->trans("ShowKnowledgeRecord");
812 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
813 }
814 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
815 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
816 } else {
817 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
818 }
819
820 if ($option == 'nolink') {
821 $linkstart = '<span';
822 } else {
823 $linkstart = '<a href="'.$url.'"';
824 }
825 $linkstart .= $linkclose.'>';
826 if ($option == 'nolink') {
827 $linkend = '</span>';
828 } else {
829 $linkend = '</a>';
830 }
831
832 $result .= $linkstart;
833
834 if (empty($this->showphoto_on_popup)) {
835 if ($withpicto) {
836 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1);
837 }
838 } else {
839 if ($withpicto) {
840 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
841
842 list($class, $module) = explode('@', $this->picto);
843 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
844 $filearray = dol_dir_list($upload_dir, "files");
845 $filename = $filearray[0]['name'];
846 if (!empty($filename)) {
847 $pospoint = strpos($filearray[0]['name'], '.');
848
849 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
850 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
851 $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>';
852 } else {
853 $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>';
854 }
855
856 $result .= '</div>';
857 } else {
858 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
859 }
860 }
861 }
862
863 if ($withpicto != 2) {
864 $result .= $this->ref;
865 }
866
867 $result .= $linkend;
868 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
869
870 global $action, $hookmanager;
871 $hookmanager->initHooks(array('knowledgerecorddao'));
872 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
873 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
874 if ($reshook > 0) {
875 $result = $hookmanager->resPrint;
876 } else {
877 $result .= $hookmanager->resPrint;
878 }
879
880 return $result;
881 }
882
889 public function getLibStatut($mode = 0)
890 {
891 return $this->LibStatut($this->status, $mode);
892 }
893
894 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
902 public function LibStatut($status, $mode = 0)
903 {
904 // phpcs:enable
905 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
906 global $langs;
907 //$langs->load("knowledgemanagement");
908 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
909 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
910 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Obsolete');
911 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
912 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
913 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Obsolete');
914 }
915
916 $statusType = 'status'.$status;
917 if ($status == self::STATUS_VALIDATED) {
918 $statusType = 'status4';
919 }
920 if ($status == self::STATUS_CANCELED) {
921 $statusType = 'status6';
922 }
923
924 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
925 }
926
933 public function info($id)
934 {
935 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
936 $sql .= ' fk_user_creat, fk_user_modif';
937 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
938 $sql .= ' WHERE t.rowid = '.((int) $id);
939 $result = $this->db->query($sql);
940 if ($result) {
941 if ($this->db->num_rows($result)) {
942 $obj = $this->db->fetch_object($result);
943
944 $this->id = $obj->rowid;
945
946 $this->user_creation_id = $obj->fk_user_creat;
947 $this->user_modification_id = $obj->fk_user_modif;
948 $this->date_creation = $this->db->jdate($obj->datec);
949 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
950 }
951
952 $this->db->free($result);
953 } else {
954 dol_print_error($this->db);
955 }
956 }
957
964 public function initAsSpecimen()
965 {
966 $this->question = "ABCD";
967 $this->initAsSpecimenCommon();
968 }
969
975 public function getLinesArray()
976 {
977 $this->lines = array();
978
979 $objectline = new KnowledgeRecordLine($this->db);
980 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_knowledgerecord = '.((int) $this->id)));
981
982 if (is_numeric($result)) {
983 $this->error = $objectline->error;
984 $this->errors = $objectline->errors;
985 return $result;
986 } else {
987 $this->lines = $result;
988 return $this->lines;
989 }
990 }
991
997 public function getNextNumRef()
998 {
999 global $langs, $conf;
1000 $langs->load("knowledgemanagement");
1001
1002 if (!getDolGlobalString('KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON')) {
1003 $conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON = 'mod_knowledgerecord_standard';
1004 }
1005
1006 if (getDolGlobalString('KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON')) {
1007 $mybool = false;
1008
1009 $file = getDolGlobalString('KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON') . ".php";
1010 $classname = $conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON;
1011
1012 // Include file with class
1013 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1014 foreach ($dirmodels as $reldir) {
1015 $dir = dol_buildpath($reldir."core/modules/knowledgemanagement/");
1016
1017 // Load file with numbering class (if found)
1018 $mybool |= @include_once $dir.$file;
1019 }
1020
1021 if ($mybool === false) {
1022 dol_print_error('', "Failed to include file ".$file);
1023 return '';
1024 }
1025
1026 if (class_exists($classname)) {
1027 $obj = new $classname();
1028 $numref = $obj->getNextValue($this);
1029
1030 if ($numref != '' && $numref != '-1') {
1031 return $numref;
1032 } else {
1033 $this->error = $obj->error;
1034 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1035 return "";
1036 }
1037 } else {
1038 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1039 return "";
1040 }
1041 } else {
1042 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1043 return "";
1044 }
1045 }
1046
1058 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1059 {
1060 global $conf, $langs;
1061
1062 $result = 0;
1063 $includedocgeneration = 0;
1064
1065 $langs->load("knowledgemanagement");
1066
1067 if (!dol_strlen($modele)) {
1068 $modele = 'standard_knowledgerecord';
1069
1070 if (!empty($this->model_pdf)) {
1071 $modele = $this->model_pdf;
1072 } elseif (getDolGlobalString('KNOWLEDGERECORD_ADDON_PDF')) {
1073 $modele = $conf->global->KNOWLEDGERECORD_ADDON_PDF;
1074 }
1075 }
1076
1077 $modelpath = "core/modules/knowledgemanagement/doc/";
1078
1079 if ($includedocgeneration && !empty($modele)) {
1080 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1081 }
1082
1083 return $result;
1084 }
1085
1093 public function doScheduledJob()
1094 {
1095 global $conf, $langs;
1096
1097 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1098
1099 $error = 0;
1100 $this->output = '';
1101 $this->error = '';
1102
1103 dol_syslog(__METHOD__, LOG_DEBUG);
1104
1105 $now = dol_now();
1106
1107 $this->db->begin();
1108
1109 // ...
1110
1111 $this->db->commit();
1112
1113 return $error;
1114 }
1115
1126 public function setCategories($categories)
1127 {
1128 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1129 return parent::setCategoriesCommon($categories, Categorie::TYPE_KNOWLEDGEMANAGEMENT);
1130 }
1131
1139 public function getKanbanView($option = '', $arraydata = null)
1140 {
1141 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1142
1143 $return = '<div class="box-flex-item box-flex-grow-zero">';
1144 $return .= '<div class="info-box info-box-sm">';
1145 $return .= '<span class="info-box-icon bg-infobox-action">';
1146 $return .= img_picto('', $this->picto);
1147 $return .= '</span>';
1148 $return .= '<div class="info-box-content">';
1149 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1150 if ($selected >= 0) {
1151 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1152 }
1153 if (property_exists($this, 'lang') && !empty($this->lang)) {
1154 //$return .= '<br><span class="opacitymedium">'.$langs->trans("Language").'</span> : <span class="info-box-label" title="'.$langs->trans("Language_".$this->lang).'">'.$langs->trans("Language_".$this->lang, '', '', '', '', 12).'</span>';
1155 $return .= '<br>'.picto_from_langcode($this->lang, 'class="paddingrightonly saturatemedium opacitylow paddingrightonly"');
1156 }
1157 if (property_exists($this, 'question')) {
1158 $return .= '<span class="info-box-label">'.dolGetFirstLineOfText($this->question).'</span>';
1159 }
1160 if (method_exists($this, 'getLibStatut')) {
1161 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1162 }
1163 $return .= '</div>';
1164 $return .= '</div>';
1165 $return .= '</div>';
1166 return $return;
1167 }
1168}
1169
1170
1171require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1172
1177{
1178 // To complete with content of an object KnowledgeRecordLine
1179 // We should have a field rowid, fk_knowledgerecord and position
1180
1184 public $isextrafieldmanaged = 0;
1185
1191 public function __construct(DoliDB $db)
1192 {
1193 $this->db = $db;
1194 }
1195}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
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.
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='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
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 to manage generation of HTML components Only common components must be here.
Class for KnowledgeRecord.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
fetch($id, $ref=null)
Load object in memory from the database.
validate($user, $notrigger=0)
Validate object.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
info($id)
Load the info information in the object.
cancel($user, $notrigger=0)
Set cancel status.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchLines()
Load object lines in memory from the database.
LibStatut($status, $mode=0)
Return the status.
create(User $user, $notrigger=false)
Create object into database.
getTooltipContentArray($params)
getTooltipContentArray
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
createFromClone(User $user, $fromid)
Clone an object into another one.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
setCategories($categories)
Sets object to supplied categories.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
getLinesArray()
Create an array of lines.
__construct(DoliDB $db)
Constructor.
getLibStatut($mode=0)
Return the label of the status.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
reopen($user, $notrigger=0)
Set back to validated status.
setDraft($user, $notrigger=0)
Set draft status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
update(User $user, $notrigger=false)
Update object into database.
Class KnowledgeRecordLine.
__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
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
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 a 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.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1926