dolibarr  17.0.4
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
25 require_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  public $question;
133  public $answer;
134  public $url;
135  public $status;
136  public $lang;
137  // END MODULEBUILDER PROPERTIES
138 
139 
140  // If this object has a subtable with lines
141 
142  // /**
143  // * @var string Name of subtable line
144  // */
145  // public $table_element_line = 'knowledgemanagement_knowledgerecordline';
146 
147  // /**
148  // * @var string Field with ID of parent key if this object has a parent
149  // */
150  // public $fk_element = 'fk_knowledgerecord';
151 
152  // /**
153  // * @var string Name of subtable class that manage subtable lines
154  // */
155  // public $class_element_line = 'KnowledgeRecordline';
156 
157  // /**
158  // * @var array List of child tables. To test if we can delete object.
159  // */
160  // protected $childtables = array();
161 
162  // /**
163  // * @var array List of child tables. To know object to delete on cascade.
164  // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
165  // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
166  // */
167  // protected $childtablesoncascade = array('knowledgemanagement_knowledgerecorddet');
168 
169  // /**
170  // * @var KnowledgeRecordLine[] Array of subtable lines
171  // */
172  // public $lines = array();
173 
174 
175 
181  public function __construct(DoliDB $db)
182  {
183  global $conf, $langs;
184 
185  $this->db = $db;
186 
187  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
188  $this->fields['rowid']['visible'] = 0;
189  }
190  if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
191  $this->fields['entity']['enabled'] = 0;
192  }
193 
194  // Example to show how to set values of fields definition dynamically
195  /*if ($user->rights->knowledgemanagement->knowledgerecord->read) {
196  $this->fields['myfield']['visible'] = 1;
197  $this->fields['myfield']['noteditable'] = 0;
198  }*/
199 
200  // Unset fields that are disabled
201  foreach ($this->fields as $key => $val) {
202  if (isset($val['enabled']) && empty($val['enabled'])) {
203  unset($this->fields[$key]);
204  }
205  }
206 
207  // Translate some data of arrayofkeyval
208  if (is_object($langs)) {
209  foreach ($this->fields as $key => $val) {
210  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
211  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
212  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
213  }
214  }
215  }
216  }
217  }
218 
226  public function create(User $user, $notrigger = false)
227  {
228  return $this->createCommon($user, $notrigger);
229  }
230 
238  public function createFromClone(User $user, $fromid)
239  {
240  global $langs, $extrafields;
241  $error = 0;
242 
243  dol_syslog(__METHOD__, LOG_DEBUG);
244 
245  $object = new self($this->db);
246 
247  $this->db->begin();
248 
249  // Load source object
250  $result = $object->fetchCommon($fromid);
251  if ($result > 0 && !empty($object->table_element_line)) {
252  $object->fetchLines();
253  }
254 
255  // get lines so they will be clone
256  //foreach($this->lines as $line)
257  // $line->fetch_optionals();
258 
259  // Reset some properties
260  unset($object->id);
261  unset($object->fk_user_creat);
262  unset($object->import_key);
263 
264  // Clear fields
265  if (property_exists($object, 'ref')) {
266  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
267  }
268  if (property_exists($object, 'label')) {
269  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
270  }
271  if (property_exists($object, 'status')) {
272  $object->status = self::STATUS_DRAFT;
273  }
274  if (property_exists($object, 'date_creation')) {
275  $object->date_creation = dol_now();
276  }
277  if (property_exists($object, 'date_modification')) {
278  $object->date_modification = null;
279  }
280  // ...
281  // Clear extrafields that are unique
282  if (is_array($object->array_options) && count($object->array_options) > 0) {
283  $extrafields->fetch_name_optionals_label($this->table_element);
284  foreach ($object->array_options as $key => $option) {
285  $shortkey = preg_replace('/options_/', '', $key);
286  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
287  //var_dump($key);
288  //var_dump($clonedObj->array_options[$key]); exit;
289  unset($object->array_options[$key]);
290  }
291  }
292  }
293 
294  // Create clone
295  $object->context['createfromclone'] = 'createfromclone';
296  $result = $object->createCommon($user);
297  if ($result < 0) {
298  $error++;
299  $this->error = $object->error;
300  $this->errors = $object->errors;
301  }
302 
303  if (!$error) {
304  // copy internal contacts
305  if ($this->copy_linked_contact($object, 'internal') < 0) {
306  $error++;
307  }
308  }
309 
310  if (!$error) {
311  // copy external contacts if same company
312  if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
313  if ($this->copy_linked_contact($object, 'external') < 0) {
314  $error++;
315  }
316  }
317  }
318 
319  unset($object->context['createfromclone']);
320 
321  // End
322  if (!$error) {
323  $this->db->commit();
324  return $object;
325  } else {
326  $this->db->rollback();
327  return -1;
328  }
329  }
330 
338  public function fetch($id, $ref = null)
339  {
340  $result = $this->fetchCommon($id, $ref);
341  if ($result > 0 && !empty($this->table_element_line)) {
342  $this->fetchLines();
343  }
344  return $result;
345  }
346 
352  public function fetchLines()
353  {
354  $this->lines = array();
355 
356  $result = $this->fetchLinesCommon();
357  return $result;
358  }
359 
360 
372  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
373  {
374  global $conf;
375 
376  dol_syslog(__METHOD__, LOG_DEBUG);
377 
378  $records = array();
379 
380  $sql = 'SELECT ';
381  $sql .= $this->getFieldList('t');
382  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
383  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
384  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
385  } else {
386  $sql .= ' WHERE 1 = 1';
387  }
388  // Manage filter
389  $sqlwhere = array();
390  if (count($filter) > 0) {
391  foreach ($filter as $key => $value) {
392  if ($key == 't.rowid') {
393  $sqlwhere[] = $key." = ".((int) $value);
394  } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
395  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
396  } elseif ($key == 'customsql') {
397  $sqlwhere[] = $value;
398  } elseif (strpos($value, '%') === false) {
399  $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')';
400  } else {
401  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
402  }
403  }
404  }
405  if (count($sqlwhere) > 0) {
406  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
407  }
408 
409  if (!empty($sortfield)) {
410  $sql .= $this->db->order($sortfield, $sortorder);
411  }
412  if (!empty($limit)) {
413  $sql .= $this->db->plimit($limit, $offset);
414  }
415 
416  $resql = $this->db->query($sql);
417  if ($resql) {
418  $num = $this->db->num_rows($resql);
419  $i = 0;
420  while ($i < ($limit ? min($limit, $num) : $num)) {
421  $obj = $this->db->fetch_object($resql);
422 
423  $record = new self($this->db);
424  $record->setVarsFromFetchObj($obj);
425 
426  $records[$record->id] = $record;
427 
428  $i++;
429  }
430  $this->db->free($resql);
431 
432  return $records;
433  } else {
434  $this->errors[] = 'Error '.$this->db->lasterror();
435  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
436 
437  return -1;
438  }
439  }
440 
448  public function update(User $user, $notrigger = false)
449  {
450  return $this->updateCommon($user, $notrigger);
451  }
452 
460  public function delete(User $user, $notrigger = false)
461  {
462  $error = 0;
463  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_knowledgemanagement WHERE fk_knowledgemanagement = ".((int) $this->id);
464  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
465  $resql = $this->db->query($sql);
466  if (!$resql) {
467  $error++;
468  $this->error .= $this->db->lasterror();
469  $errorflag = -1;
470  }
471 
472  // Delete all child tables
473  if (!$error) {
474  $elements = array('categorie_knowledgemanagement');
475  foreach ($elements as $table) {
476  if (!$error) {
477  $sql = "DELETE FROM ".MAIN_DB_PREFIX.$table;
478  $sql .= " WHERE fk_knowledgemanagement = ".(int) $this->id;
479 
480  $result = $this->db->query($sql);
481  if (!$result) {
482  $error++;
483  $this->errors[] = $this->db->lasterror();
484  }
485  }
486  }
487  }
488 
489  return $this->deleteCommon($user, $notrigger);
490  //return $this->deleteCommon($user, $notrigger, 1);
491  }
492 
501  public function deleteLine(User $user, $idline, $notrigger = false)
502  {
503  if ($this->status < 0) {
504  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
505  return -2;
506  }
507 
508  return $this->deleteLineCommon($user, $idline, $notrigger);
509  }
510 
511 
519  public function validate($user, $notrigger = 0)
520  {
521  global $conf, $langs;
522 
523  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
524 
525  $error = 0;
526 
527  // Protection
528  if ($this->status == self::STATUS_VALIDATED) {
529  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
530  return 0;
531  }
532 
533  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgerecord->write))
534  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgerecord->knowledgerecord_advance->validate))))
535  {
536  $this->error='NotEnoughPermissions';
537  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
538  return -1;
539  }*/
540 
541  $now = dol_now();
542 
543  $this->db->begin();
544 
545  // Define new ref
546  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
547  $num = $this->getNextNumRef();
548  } else {
549  $num = $this->ref;
550  }
551  $this->newref = $num;
552 
553  if (!empty($num)) {
554  // Validate
555  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
556  $sql .= " SET ref = '".$this->db->escape($num)."',";
557  $sql .= " status = ".self::STATUS_VALIDATED;
558  if (!empty($this->fields['date_validation'])) {
559  $sql .= ", date_validation = '".$this->db->idate($now)."'";
560  }
561  if (!empty($this->fields['fk_user_valid'])) {
562  $sql .= ", fk_user_valid = ".((int) $user->id);
563  }
564  $sql .= " WHERE rowid = ".((int) $this->id);
565 
566  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
567  $resql = $this->db->query($sql);
568  if (!$resql) {
569  dol_print_error($this->db);
570  $this->error = $this->db->lasterror();
571  $error++;
572  }
573 
574  if (!$error && !$notrigger) {
575  // Call trigger
576  $result = $this->call_trigger('KNOWLEDGERECORD_VALIDATE', $user);
577  if ($result < 0) {
578  $error++;
579  }
580  // End call triggers
581  }
582  }
583 
584  if (!$error) {
585  $this->oldref = $this->ref;
586 
587  // Rename directory if dir was a temporary ref
588  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
589  // Now we rename also files into index
590  $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)."'";
591  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'knowledgerecord/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
592  $resql = $this->db->query($sql);
593  if (!$resql) {
594  $error++; $this->error = $this->db->lasterror();
595  }
596 
597  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
598  $oldref = dol_sanitizeFileName($this->ref);
599  $newref = dol_sanitizeFileName($num);
600  $dirsource = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$oldref;
601  $dirdest = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$newref;
602  if (!$error && file_exists($dirsource)) {
603  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
604 
605  if (@rename($dirsource, $dirdest)) {
606  dol_syslog("Rename ok");
607  // Rename docs starting with $oldref with $newref
608  $listoffiles = dol_dir_list($conf->knowledgemanagement->dir_output.'/knowledgerecord/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
609  foreach ($listoffiles as $fileentry) {
610  $dirsource = $fileentry['name'];
611  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
612  $dirsource = $fileentry['path'].'/'.$dirsource;
613  $dirdest = $fileentry['path'].'/'.$dirdest;
614  @rename($dirsource, $dirdest);
615  }
616  }
617  }
618  }
619  }
620 
621  // Set new ref and current status
622  if (!$error) {
623  $this->ref = $num;
624  $this->status = self::STATUS_VALIDATED;
625  }
626 
627  if (!$error) {
628  $this->db->commit();
629  return 1;
630  } else {
631  $this->db->rollback();
632  return -1;
633  }
634  }
635 
636 
644  public function setDraft($user, $notrigger = 0)
645  {
646  // Protection
647  if ($this->status <= self::STATUS_DRAFT) {
648  return 0;
649  }
650 
651  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
652  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
653  {
654  $this->error='Permission denied';
655  return -1;
656  }*/
657 
658  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'KNOWLEDGERECORD_UNVALIDATE');
659  }
660 
668  public function cancel($user, $notrigger = 0)
669  {
670  // Protection
671  if ($this->status != self::STATUS_VALIDATED) {
672  return 0;
673  }
674 
675  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
676  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
677  {
678  $this->error='Permission denied';
679  return -1;
680  }*/
681 
682  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'KNOWLEDGERECORD_CANCEL');
683  }
684 
692  public function reopen($user, $notrigger = 0)
693  {
694  // Protection
695  if ($this->status != self::STATUS_CANCELED) {
696  return 0;
697  }
698 
699  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->write))
700  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->knowledgemanagement->knowledgemanagement_advance->validate))))
701  {
702  $this->error='Permission denied';
703  return -1;
704  }*/
705 
706  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'KNOWLEDGERECORD_REOPEN');
707  }
708 
719  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
720  {
721  global $conf, $langs, $hookmanager;
722 
723  if (!empty($conf->dol_no_mouse_hover)) {
724  $notooltip = 1; // Force disable tooltips
725  }
726 
727  $result = '';
728 
729  $label = img_picto('', $this->picto).' <u>'.$langs->trans("KnowledgeRecord").'</u>';
730  if (isset($this->status)) {
731  $label .= ' '.$this->getLibStatut(5);
732  }
733  $label .= '<br>';
734  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
735 
736  $url = dol_buildpath('/knowledgemanagement/knowledgerecord_card.php', 1).'?id='.$this->id;
737 
738  if ($option != 'nolink') {
739  // Add param to save lastsearch_values or not
740  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
741  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
742  $add_save_lastsearch_values = 1;
743  }
744  if ($add_save_lastsearch_values) {
745  $url .= '&save_lastsearch_values=1';
746  }
747  }
748 
749  $linkclose = '';
750  if (empty($notooltip)) {
751  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
752  $label = $langs->trans("ShowKnowledgeRecord");
753  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
754  }
755  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
756  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
757  } else {
758  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
759  }
760 
761  if ($option == 'nolink') {
762  $linkstart = '<span';
763  } else {
764  $linkstart = '<a href="'.$url.'"';
765  }
766  $linkstart .= $linkclose.'>';
767  if ($option == 'nolink') {
768  $linkend = '</span>';
769  } else {
770  $linkend = '</a>';
771  }
772 
773  $result .= $linkstart;
774 
775  if (empty($this->showphoto_on_popup)) {
776  if ($withpicto) {
777  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
778  }
779  } else {
780  if ($withpicto) {
781  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
782 
783  list($class, $module) = explode('@', $this->picto);
784  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
785  $filearray = dol_dir_list($upload_dir, "files");
786  $filename = $filearray[0]['name'];
787  if (!empty($filename)) {
788  $pospoint = strpos($filearray[0]['name'], '.');
789 
790  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
791  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
792  $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>';
793  } else {
794  $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>';
795  }
796 
797  $result .= '</div>';
798  } else {
799  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
800  }
801  }
802  }
803 
804  if ($withpicto != 2) {
805  $result .= $this->ref;
806  }
807 
808  $result .= $linkend;
809  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
810 
811  global $action, $hookmanager;
812  $hookmanager->initHooks(array('knowledgerecorddao'));
813  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
814  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
815  if ($reshook > 0) {
816  $result = $hookmanager->resPrint;
817  } else {
818  $result .= $hookmanager->resPrint;
819  }
820 
821  return $result;
822  }
823 
830  public function getLibStatut($mode = 0)
831  {
832  return $this->LibStatut($this->status, $mode);
833  }
834 
835  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
843  public function LibStatut($status, $mode = 0)
844  {
845  // phpcs:enable
846  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
847  global $langs;
848  //$langs->load("knowledgemanagement");
849  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
850  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
851  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Obsolete');
852  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
853  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
854  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Obsolete');
855  }
856 
857  $statusType = 'status'.$status;
858  if ($status == self::STATUS_VALIDATED) $statusType = 'status4';
859  if ($status == self::STATUS_CANCELED) {
860  $statusType = 'status6';
861  }
862 
863  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
864  }
865 
872  public function info($id)
873  {
874  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
875  $sql .= ' fk_user_creat, fk_user_modif';
876  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
877  $sql .= ' WHERE t.rowid = '.((int) $id);
878  $result = $this->db->query($sql);
879  if ($result) {
880  if ($this->db->num_rows($result)) {
881  $obj = $this->db->fetch_object($result);
882  $this->id = $obj->rowid;
883 
884  $this->user_creation_id = $obj->fk_user_creat;
885  $this->user_modification_id = $obj->fk_user_modif;
886  $this->date_creation = $this->db->jdate($obj->datec);
887  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
888  }
889 
890  $this->db->free($result);
891  } else {
892  dol_print_error($this->db);
893  }
894  }
895 
902  public function initAsSpecimen()
903  {
904  $this->question = "ABCD";
905  $this->initAsSpecimenCommon();
906  }
907 
913  public function getLinesArray()
914  {
915  $this->lines = array();
916 
917  $objectline = new KnowledgeRecordLine($this->db);
918  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_knowledgerecord = '.((int) $this->id)));
919 
920  if (is_numeric($result)) {
921  $this->error = $objectline->error;
922  $this->errors = $objectline->errors;
923  return $result;
924  } else {
925  $this->lines = $result;
926  return $this->lines;
927  }
928  }
929 
935  public function getNextNumRef()
936  {
937  global $langs, $conf;
938  $langs->load("knowledgemanagement");
939 
940  if (empty($conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON)) {
941  $conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON = 'mod_knowledgerecord_standard';
942  }
943 
944  if (!empty($conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON)) {
945  $mybool = false;
946 
947  $file = $conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON.".php";
948  $classname = $conf->global->KNOWLEDGEMANAGEMENT_KNOWLEDGERECORD_ADDON;
949 
950  // Include file with class
951  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
952  foreach ($dirmodels as $reldir) {
953  $dir = dol_buildpath($reldir."core/modules/knowledgemanagement/");
954 
955  // Load file with numbering class (if found)
956  $mybool |= @include_once $dir.$file;
957  }
958 
959  if ($mybool === false) {
960  dol_print_error('', "Failed to include file ".$file);
961  return '';
962  }
963 
964  if (class_exists($classname)) {
965  $obj = new $classname();
966  $numref = $obj->getNextValue($this);
967 
968  if ($numref != '' && $numref != '-1') {
969  return $numref;
970  } else {
971  $this->error = $obj->error;
972  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
973  return "";
974  }
975  } else {
976  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
977  return "";
978  }
979  } else {
980  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
981  return "";
982  }
983  }
984 
996  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
997  {
998  global $conf, $langs;
999 
1000  $result = 0;
1001  $includedocgeneration = 0;
1002 
1003  $langs->load("knowledgemanagement");
1004 
1005  if (!dol_strlen($modele)) {
1006  $modele = 'standard_knowledgerecord';
1007 
1008  if (!empty($this->model_pdf)) {
1009  $modele = $this->model_pdf;
1010  } elseif (!empty($conf->global->KNOWLEDGERECORD_ADDON_PDF)) {
1011  $modele = $conf->global->KNOWLEDGERECORD_ADDON_PDF;
1012  }
1013  }
1014 
1015  $modelpath = "core/modules/knowledgemanagement/doc/";
1016 
1017  if ($includedocgeneration && !empty($modele)) {
1018  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1019  }
1020 
1021  return $result;
1022  }
1023 
1031  public function doScheduledJob()
1032  {
1033  global $conf, $langs;
1034 
1035  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1036 
1037  $error = 0;
1038  $this->output = '';
1039  $this->error = '';
1040 
1041  dol_syslog(__METHOD__, LOG_DEBUG);
1042 
1043  $now = dol_now();
1044 
1045  $this->db->begin();
1046 
1047  // ...
1048 
1049  $this->db->commit();
1050 
1051  return $error;
1052  }
1053 
1064  public function setCategories($categories)
1065  {
1066  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1067  return parent::setCategoriesCommon($categories, Categorie::TYPE_KNOWLEDGEMANAGEMENT);
1068  }
1069 }
1070 
1071 
1072 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1073 
1078 {
1079  // To complete with content of an object KnowledgeRecordLine
1080  // We should have a field rowid, fk_knowledgerecord and position
1081 
1085  public $isextrafieldmanaged = 0;
1086 
1092  public function __construct(DoliDB $db)
1093  {
1094  $this->db = $db;
1095  }
1096 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getFieldList($alias='')
Function to concat keys of fields.
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.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
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 KnowledgeRecord.
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.
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.
Definition: user.class.php:47
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
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:61
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db
API class for accounts.
Definition: inc.php:41