dolibarr  17.0.4
doc_generic_task_odt.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
4  * Copyright (C) 2013 Florian Henry <florian.henry@ope-concept.pro>
5  * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
6  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  * or see https://www.gnu.org/
21  */
22 
29 require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
31 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41 if (isModEnabled("propal")) {
42  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
43 }
44 if (isModEnabled('facture')) {
45  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
46 }
47 if (isModEnabled('facture')) {
48  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
49 }
50 if (isModEnabled('commande')) {
51  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
52 }
53 if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_invoice")) {
54  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55 }
56 if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order")) {
57  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
58 }
59 if (isModEnabled('contrat')) {
60  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
61 }
62 if (isModEnabled('ficheinter')) {
63  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
64 }
65 if (isModEnabled('deplacement')) {
66  require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
67 }
68 if (isModEnabled('agenda')) {
69  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
70 }
71 
72 
77 {
82  public $emetteur;
83 
88  public $phpmin = array(7, 0);
89 
94  public $version = 'dolibarr';
95 
96 
102  public function __construct($db)
103  {
104  global $conf, $langs, $mysoc;
105 
106  // Load translation files required by the page
107  $langs->loadLangs(array("main", "companies"));
108 
109  $this->db = $db;
110  $this->name = "ODT templates";
111  $this->description = $langs->trans("DocumentModelOdt");
112  $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
113 
114  // Page size for A4 format
115  $this->type = 'odt';
116  $this->page_largeur = 0;
117  $this->page_hauteur = 0;
118  $this->format = array($this->page_largeur, $this->page_hauteur);
119  $this->marge_gauche = 0;
120  $this->marge_droite = 0;
121  $this->marge_haute = 0;
122  $this->marge_basse = 0;
123 
124  $this->option_logo = 1; // Display logo
125  $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
126  $this->option_modereg = 0; // Display payment mode
127  $this->option_condreg = 0; // Display payment terms
128  $this->option_multilang = 0; // Available in several languages
129  $this->option_escompte = 0; // Displays if there has been a discount
130  $this->option_credit_note = 0; // Support credit notes
131  $this->option_freetext = 1; // Support add of a personalised text
132  $this->option_draft_watermark = 0; // Support add of a watermark on drafts
133 
134  // Get source company
135  $this->emetteur = $mysoc;
136  if (!$this->emetteur->country_code) {
137  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
138  }
139  }
140 
141 
142  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
151  public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
152  {
153  // phpcs:enable
154  global $conf, $extrafields;
155 
156  $resarray = array(
157  $array_key.'_id'=>$object->id,
158  $array_key.'_ref'=>$object->ref,
159  $array_key.'_title'=>$object->title,
160  $array_key.'_description'=>$object->description,
161  $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
162  $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
163  $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
164  $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
165  $array_key.'_note_private'=>$object->note_private,
166  $array_key.'_note_public'=>$object->note_public,
167  $array_key.'_public'=>$object->public,
168  $array_key.'_statut'=>$object->getLibStatut()
169  );
170 
171  // Retrieve extrafields
172  if (is_array($object->array_options) && count($object->array_options)) {
173  $object->fetch_optionals();
174 
175  $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
176  }
177 
178  return $resarray;
179  }
180 
181  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
190  public function get_substitutionarray_tasks($task, $outputlangs, $array_key = 'task')
191  {
192  // phpcs:enable
193  global $conf, $extrafields;
194 
195  $resarray = array(
196  'task_ref'=>$task->ref,
197  'task_fk_project'=>$task->fk_project,
198  'task_projectref'=>$task->projectref,
199  'task_projectlabel'=>$task->projectlabel,
200  'task_label'=>$task->label,
201  'task_description'=>$task->description,
202  'task_fk_parent'=>$task->fk_parent,
203  'task_duration'=>$task->duration_effective,
204  'task_duration_formated'=>convertSecondToTime($task->duration_effective, 'allhourmin'),
205  'task_planned_workload'=>$task->planned_workload,
206  'task_planned_workload_formated'=>convertSecondToTime($task->planned_workload, 'allhourmin'),
207  'task_progress'=>$task->progress,
208  'task_public'=>$task->public,
209  'task_date_start'=>dol_print_date($task->date_start, 'day'),
210  'task_date_end'=>dol_print_date($task->date_end, 'day'),
211  'task_note_private'=>$task->note_private,
212  'task_note_public'=>$task->note_public
213  );
214 
215  // Retrieve extrafields
216  if (is_array($task->array_options) && count($task->array_options)) {
217  $task->fetch_optionals();
218 
219  $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, $array_key, $outputlangs);
220  }
221 
222  return $resarray;
223  }
224 
225  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
233  public function get_substitutionarray_project_contacts($contact, $outputlangs)
234  {
235  // phpcs:enable
236  global $conf;
237 
238  return array(
239  'projcontacts_id'=>$contact['id'],
240  'projcontacts_rowid'=>$contact['rowid'],
241  'projcontacts_role'=>$contact['libelle'],
242  'projcontacts_lastname'=>$contact['lastname'],
243  'projcontacts_firstname'=>$contact['firstname'],
244  'projcontacts_fullcivname'=>$contact['fullname'],
245  'projcontacts_socname'=>$contact['socname'],
246  'projcontacts_email'=>$contact['email']
247  );
248  }
249 
250  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
258  public function get_substitutionarray_project_file($file, $outputlangs)
259  {
260  // phpcs:enable
261  global $conf;
262 
263  return array(
264  'projfile_name'=>$file['name'],
265  'projfile_date'=>dol_print_date($file['date'], 'day'),
266  'projfile_size'=>$file['size']
267  );
268  }
269 
270  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
278  public function get_substitutionarray_project_reference($refdetail, $outputlangs)
279  {
280  // phpcs:enable
281  global $conf;
282 
283  return array(
284  'projref_type'=>$refdetail['type'],
285  'projref_ref'=>$refdetail['ref'],
286  'projref_date'=>dol_print_date($refdetail['date'], 'day'),
287  'projref_socname'=>$refdetail['socname'],
288  'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
289  'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
290  'projref_status'=>$refdetail['status']
291  );
292  }
293 
294  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
302  public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
303  {
304  // phpcs:enable
305  global $conf;
306  //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
307  return array(
308  'taskressource_rowid'=>$taskressource['rowid'],
309  'taskressource_role'=>$taskressource['libelle'],
310  'taskressource_lastname'=>$taskressource['lastname'],
311  'taskressource_firstname'=>$taskressource['firstname'],
312  'taskressource_fullcivname'=>$taskressource['fullname'],
313  'taskressource_socname'=>$taskressource['socname'],
314  'taskressource_email'=>$taskressource['email']
315  );
316  }
317 
318  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
326  public function get_substitutionarray_taskstime($tasktime, $outputlangs)
327  {
328  // phpcs:enable
329  global $conf;
330 
331  return array(
332  'tasktime_rowid'=>$tasktime['rowid'],
333  'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
334  'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
335  'tasktime_note'=>$tasktime['note'],
336  'tasktime_fk_user'=>$tasktime['fk_user'],
337  'tasktime_user_name'=>$tasktime['name'],
338  'tasktime_user_first'=>$tasktime['firstname'],
339  'tasktime_fullcivname'=>$tasktime['fullcivname']
340  );
341  }
342 
343  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
351  public function get_substitutionarray_task_file($file, $outputlangs)
352  {
353  // phpcs:enable
354  global $conf;
355 
356  return array(
357  'tasksfile_name'=>$file['name'],
358  'tasksfile_date'=>dol_print_date($file['date'], 'day'),
359  'tasksfile_size'=>$file['size']
360  );
361  }
362 
363 
370  public function info($langs)
371  {
372  global $conf, $langs;
373 
374  // Load translation files required by the page
375  $langs->loadLangs(array("errors", "companies"));
376 
377  $form = new Form($this->db);
378 
379  $texte = $this->description.".<br>\n";
380  $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
381  $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
382  $texte .= '<input type="hidden" name="page_y" value="">';
383  $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
384  $texte .= '<input type="hidden" name="param1" value="PROJECT_TASK_ADDON_PDF_ODT_PATH">';
385  $texte .= '<table class="nobordernopadding" width="100%">';
386 
387  // List of directories area
388  $texte .= '<tr><td>';
389  $texttitle = $langs->trans("ListOfDirectories");
390  $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)));
391  $listoffiles = array();
392  foreach ($listofdir as $key => $tmpdir) {
393  $tmpdir = trim($tmpdir);
394  $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
395  if (!$tmpdir) {
396  unset($listofdir[$key]);
397  continue;
398  }
399  if (!is_dir($tmpdir)) {
400  $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
401  } else {
402  $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
403  if (count($tmpfiles)) {
404  $listoffiles = array_merge($listoffiles, $tmpfiles);
405  }
406  }
407  }
408  $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
409  // Add list of substitution keys
410  $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
411  $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
412 
413  $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
414  $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
415  $texte .= '<textarea class="flat" cols="60" name="value1">';
416  $texte .= $conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH;
417  $texte .= '</textarea>';
418  $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
419  $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.$langs->trans("Modify").'">';
420  $texte .= '<br></div></div>';
421 
422  // Scan directories
423  $nbofiles = count($listoffiles);
424  if (!empty($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)) {
425  $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
426  //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
427  $texte .= $nbofiles;
428  //$texte.=$nbofiles?'</a>':'';
429  $texte .= '</b>';
430  }
431 
432  if ($nbofiles) {
433  $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
434  // Show list of found files
435  foreach ($listoffiles as $file) {
436  $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=tasks/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
437  $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=PROJECT_TASK_ADDON_PDF_ODT_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
438  $texte .= '<br>';
439  }
440  $texte .= '</div>';
441  }
442 
443  $texte .= '</td>';
444 
445  $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
446  $texte .= '<span class="opacitymedium">';
447  $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
448  $texte .= '</span>';
449  $texte .= '</td>';
450  $texte .= '</tr>';
451 
452  $texte .= '</table>';
453  $texte .= '</form>';
454 
455  return $texte;
456  }
457 
458  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
467  public function write_file($object, $outputlangs, $srctemplatepath)
468  {
469  // phpcs:enable
470  global $user, $langs, $conf, $mysoc, $hookmanager;
471 
472  if (empty($srctemplatepath)) {
473  dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
474  return -1;
475  }
476 
477  if (!is_object($outputlangs)) {
478  $outputlangs = $langs;
479  }
480  $sav_charset_output = $outputlangs->charset_output;
481  $outputlangs->charset_output = 'UTF-8';
482 
483  // Load translation files required by the page
484  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
485 
486  if ($conf->project->dir_output) {
487  // If $object is id instead of object
488  if (!is_object($object)) {
489  $id = $object;
490  $object = new Task($this->db);
491  $result = $object->fetch($id);
492  if ($result < 0) {
493  dol_print_error($this->db, $object->error);
494  return -1;
495  }
496  }
497  $project = new Project($this->db);
498  $project->fetch($object->fk_project);
499  $project->fetch_thirdparty();
500 
501  $dir = $conf->project->dir_output."/".$project->ref."/";
502  $objectref = dol_sanitizeFileName($object->ref);
503  if (!preg_match('/specimen/i', $objectref)) {
504  $dir .= "/".$objectref;
505  }
506  $file = $dir."/".$objectref.".odt";
507 
508  if (!file_exists($dir)) {
509  if (dol_mkdir($dir) < 0) {
510  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
511  return -1;
512  }
513  }
514 
515 
516  if (file_exists($dir)) {
517  //print "srctemplatepath=".$srctemplatepath; // Src filename
518  $newfile = basename($srctemplatepath);
519  $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
520  $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
521  $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
522  $newfiletmp = $objectref . '_' . $newfiletmp;
523  //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
524  $file = $dir . '/' . $newfiletmp . '.odt';
525  //print "newdir=".$dir;
526  //print "newfile=".$newfile;
527  //print "file=".$file;
528  //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
529 
530  dol_mkdir($conf->project->dir_temp);
531  if (!is_writable($conf->project->dir_temp)) {
532  $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
533  dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
534  return -1;
535  }
536 
537  $socobject = $project->thirdparty;
538 
539  // Make substitution
540  $substitutionarray = array(
541  '__FROM_NAME__' => $this->emetteur->name,
542  '__FROM_EMAIL__' => $this->emetteur->email,
543  );
544  complete_substitutions_array($substitutionarray, $langs, $object);
545  // Call the ODTSubstitution hook
546  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
547  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
548 
549  // Open and load template
550  require_once ODTPHP_PATH.'odf.php';
551  try {
552  $odfHandler = new odf(
553  $srctemplatepath,
554  array(
555  'PATH_TO_TMP' => $conf->project->dir_temp,
556  'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
557  'DELIMITER_LEFT' => '{',
558  'DELIMITER_RIGHT' => '}'
559  )
560  );
561  } catch (Exception $e) {
562  $this->error = $e->getMessage();
563  return -1;
564  }
565  // After construction $odfHandler->contentXml contains content and
566  // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
567  // [!-- BEGIN lines --]*[!-- END lines --]
568  //print html_entity_decode($odfHandler->__toString());
569  //print exit;
570 
571 
572  // Define substitution array
573  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
574  $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
575  $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
576  $array_user = $this->get_substitutionarray_user($user, $outputlangs);
577  $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
578  $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
579  $array_other = $this->get_substitutionarray_other($outputlangs);
580 
581  $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
582  complete_substitutions_array($tmparray, $outputlangs, $object);
583 
584  foreach ($tmparray as $key => $value) {
585  try {
586  if (preg_match('/logo$/', $key)) { // Image
587  if (file_exists($value)) {
588  $odfHandler->setImage($key, $value);
589  } else {
590  $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
591  }
592  } else // Text
593  {
594  $odfHandler->setVars($key, $value, true, 'UTF-8');
595  }
596  } catch (OdfException $e) {
597  dol_syslog($e->getMessage(), LOG_INFO);
598  }
599  }
600 
601  // Replace tags of lines for tasks
602  try {
603  // Security check
604  $socid = 0;
605  if (!empty($project->fk_soc)) {
606  $socid = $project->fk_soc;
607  }
608 
609  $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
610  complete_substitutions_array($tmparray, $outputlangs, $object);
611  foreach ($tmparray as $key => $val) {
612  try {
613  $odfHandler->setVars($key, $val, true, 'UTF-8');
614  } catch (OdfException $e) {
615  dol_syslog($e->getMessage(), LOG_INFO);
616  } catch (SegmentException $e) {
617  dol_syslog($e->getMessage(), LOG_INFO);
618  }
619  }
620 
621  // Replace tags of lines for contacts task
622  $sourcearray = array('internal', 'external');
623  $contact_arrray = array();
624  foreach ($sourcearray as $source) {
625  $contact_temp = $object->liste_contact(-1, $source);
626  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
627  $contact_arrray = array_merge($contact_arrray, $contact_temp);
628  }
629  }
630  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
631  $listlinestaskres = $odfHandler->setSegment('tasksressources');
632 
633  foreach ($contact_arrray as $contact) {
634  if ($contact['source'] == 'internal') {
635  $objectdetail = new User($this->db);
636  $objectdetail->fetch($contact['id']);
637  $contact['socname'] = $mysoc->name;
638  } elseif ($contact['source'] == 'external') {
639  $objectdetail = new Contact($this->db);
640  $objectdetail->fetch($contact['id']);
641 
642  $soc = new Societe($this->db);
643  $soc->fetch($contact['socid']);
644  $contact['socname'] = $soc->name;
645  }
646  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
647 
648  $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
649 
650  foreach ($tmparray as $key => $val) {
651  try {
652  $listlinestaskres->setVars($key, $val, true, 'UTF-8');
653  } catch (OdfException $e) {
654  dol_syslog($e->getMessage(), LOG_INFO);
655  } catch (SegmentException $e) {
656  dol_syslog($e->getMessage(), LOG_INFO);
657  }
658  }
659  $listlinestaskres->merge();
660  }
661  $odfHandler->mergeSegment($listlinestaskres);
662  }
663 
664  // Time ressources
665  $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note";
666  $sql .= ", u.lastname, u.firstname";
667  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
668  $sql .= " , ".MAIN_DB_PREFIX."user as u";
669  $sql .= " WHERE t.fk_task =".((int) $object->id);
670  $sql .= " AND t.fk_user = u.rowid";
671  $sql .= " ORDER BY t.task_date DESC";
672 
673  $resql = $this->db->query($sql);
674  if ($resql) {
675  $num = $this->db->num_rows($resql);
676  $i = 0;
677  $tasks = array();
678  $listlinestasktime = $odfHandler->setSegment('taskstimes');
679  while ($i < $num) {
680  $row = $this->db->fetch_array($resql);
681  if (!empty($row['fk_user'])) {
682  $objectdetail = new User($this->db);
683  $objectdetail->fetch($row['fk_user']);
684  // TODO Use a cache to aoid fetch for same user
685  $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
686  } else {
687  $row['fullcivname'] = '';
688  }
689 
690  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
691 
692  foreach ($tmparray as $key => $val) {
693  try {
694  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
695  } catch (OdfException $e) {
696  dol_syslog($e->getMessage(), LOG_INFO);
697  } catch (SegmentException $e) {
698  dol_syslog($e->getMessage(), LOG_INFO);
699  }
700  }
701  $listlinestasktime->merge();
702  $i++;
703  }
704  $this->db->free($resql);
705 
706  $odfHandler->mergeSegment($listlinestasktime);
707  }
708 
709 
710  // Replace tags of project files
711  $listtasksfiles = $odfHandler->setSegment('tasksfiles');
712 
713  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
714  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
715 
716 
717  foreach ($filearray as $filedetail) {
718  $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
719  //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
720  foreach ($tmparray as $key => $val) {
721  try {
722  $listtasksfiles->setVars($key, $val, true, 'UTF-8');
723  } catch (OdfException $e) {
724  dol_syslog($e->getMessage(), LOG_INFO);
725  } catch (SegmentException $e) {
726  dol_syslog($e->getMessage(), LOG_INFO);
727  }
728  }
729  $listtasksfiles->merge();
730  }
731  //$listlines->merge();
732 
733  $odfHandler->mergeSegment($listtasksfiles);
734  } catch (OdfException $e) {
735  $this->error = $e->getMessage();
736  dol_syslog($this->error, LOG_WARNING);
737  return -1;
738  }
739 
740 
741 
742  // Replace tags of project files
743  try {
744  $listlines = $odfHandler->setSegment('projectfiles');
745 
746  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
747  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
748 
749 
750  foreach ($filearray as $filedetail) {
751  //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
752  $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
753 
754  foreach ($tmparray as $key => $val) {
755  try {
756  $listlines->setVars($key, $val, true, 'UTF-8');
757  } catch (OdfException $e) {
758  dol_syslog($e->getMessage(), LOG_INFO);
759  } catch (SegmentException $e) {
760  dol_syslog($e->getMessage(), LOG_INFO);
761  }
762  }
763  $listlines->merge();
764  }
765  $odfHandler->mergeSegment($listlines);
766  } catch (OdfException $e) {
767  $this->error = $e->getMessage();
768  dol_syslog($this->error, LOG_WARNING);
769  return -1;
770  }
771 
772  // Replace tags of lines for contacts
773  $sourcearray = array('internal', 'external');
774  $contact_arrray = array();
775  foreach ($sourcearray as $source) {
776  $contact_temp = $project->liste_contact(-1, $source);
777  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
778  $contact_arrray = array_merge($contact_arrray, $contact_temp);
779  }
780  }
781  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
782  try {
783  $listlines = $odfHandler->setSegment('projectcontacts');
784 
785  foreach ($contact_arrray as $contact) {
786  if ($contact['source'] == 'internal') {
787  $objectdetail = new User($this->db);
788  $objectdetail->fetch($contact['id']);
789  $contact['socname'] = $mysoc->name;
790  } elseif ($contact['source'] == 'external') {
791  $objectdetail = new Contact($this->db);
792  $objectdetail->fetch($contact['id']);
793 
794  $soc = new Societe($this->db);
795  $soc->fetch($contact['socid']);
796  $contact['socname'] = $soc->name;
797  }
798  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
799 
800  $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
801 
802  foreach ($tmparray as $key => $val) {
803  try {
804  $listlines->setVars($key, $val, true, 'UTF-8');
805  } catch (OdfException $e) {
806  dol_syslog($e->getMessage(), LOG_INFO);
807  } catch (SegmentException $e) {
808  dol_syslog($e->getMessage(), LOG_INFO);
809  }
810  }
811  $listlines->merge();
812  }
813  $odfHandler->mergeSegment($listlines);
814  } catch (OdfException $e) {
815  $this->error = $e->getMessage();
816  dol_syslog($this->error, LOG_WARNING);
817  return -1;
818  }
819  }
820 
821 
822  // Call the beforeODTSave hook
823  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
824  $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
825 
826 
827  // Write new file
828  if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
829  try {
830  $odfHandler->exportAsAttachedPDF($file);
831  } catch (Exception $e) {
832  $this->error = $e->getMessage();
833  dol_syslog($e->getMessage(), LOG_INFO);
834  return -1;
835  }
836  } else {
837  try {
838  $odfHandler->saveToDisk($file);
839  } catch (Exception $e) {
840  $this->error = $e->getMessage();
841  dol_syslog($e->getMessage(), LOG_INFO);
842  return -1;
843  }
844  }
845  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
846  $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
847 
848  if (!empty($conf->global->MAIN_UMASK)) {
849  @chmod($file, octdec($conf->global->MAIN_UMASK));
850  }
851 
852  $odfHandler = null; // Destroy object
853 
854  $this->result = array('fullpath'=>$file);
855 
856  return 1; // Success
857  } else {
858  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
859  return -1;
860  }
861  }
862 
863  return -1;
864  }
865 }
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=1)
Define array with couple substitution key => substitution value.
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_other($outputlangs)
Define array with couple substitution key => substitution value.
fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs)
Fill array with couple extrafield key => extrafield value.
get_substitutionarray_thirdparty($object, $outputlangs, $array_key='company')
Define array with couple substitution key => substitution value For example {company_name},...
get_substitutionarray_user($user, $outputlangs)
Define array with couple substitution key => substitution value.
Class to manage contact/addresses.
Class to manage generation of HTML components Only common components must be here.
Parent class for projects models.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Definition: task.class.php:38
Class to manage Dolibarr users.
Definition: user.class.php:47
Class to build documents using ODF templates generator.
get_substitutionarray_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_task_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_taskstime($tasktime, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_tasks($task, $outputlangs, $array_key='task')
Define array with couple substitution key => substitution value.
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
get_substitutionarray_project_contacts($contact, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_project_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
info($langs)
Return description of a module.
write_file($object, $outputlangs, $srctemplatepath)
Function to build a document on disk using the generic odt module.
get_substitutionarray_project_reference($refdetail, $outputlangs)
Define array with couple substitution key => substitution value.
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
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:238
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
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
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
newToken()
Return the value of token currently saved into session with name 'newtoken'.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null)
Return array of possible common substitutions.
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.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:122
$conf db
API class for accounts.
Definition: inc.php:41