dolibarr  16.0.5
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 (!empty($conf->propal->enabled)) {
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 (!empty($conf->commande->enabled)) {
51  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
52 }
53 if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled)) {
54  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55 }
56 if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) {
57  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
58 }
59 if (!empty($conf->contrat->enabled)) {
60  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
61 }
62 if (!empty($conf->ficheinter->enabled)) {
63  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
64 }
65 if (!empty($conf->deplacement->enabled)) {
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(5, 6);
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><br>';
437  }
438  $texte .= '</div>';
439  }
440 
441  $texte .= '</td>';
442 
443  $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
444  $texte .= '<span class="opacitymedium">';
445  $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
446  $texte .= '</span>';
447  $texte .= '</td>';
448  $texte .= '</tr>';
449 
450  $texte .= '</table>';
451  $texte .= '</form>';
452 
453  return $texte;
454  }
455 
456  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
465  public function write_file($object, $outputlangs, $srctemplatepath)
466  {
467  // phpcs:enable
468  global $user, $langs, $conf, $mysoc, $hookmanager;
469 
470  if (empty($srctemplatepath)) {
471  dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
472  return -1;
473  }
474 
475  if (!is_object($outputlangs)) {
476  $outputlangs = $langs;
477  }
478  $sav_charset_output = $outputlangs->charset_output;
479  $outputlangs->charset_output = 'UTF-8';
480 
481  // Load translation files required by the page
482  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
483 
484  if ($conf->project->dir_output) {
485  // If $object is id instead of object
486  if (!is_object($object)) {
487  $id = $object;
488  $object = new Task($this->db);
489  $result = $object->fetch($id);
490  if ($result < 0) {
491  dol_print_error($this->db, $object->error);
492  return -1;
493  }
494  }
495  $project = new Project($this->db);
496  $project->fetch($object->fk_project);
497  $project->fetch_thirdparty();
498 
499  $dir = $conf->project->dir_output."/".$project->ref."/";
500  $objectref = dol_sanitizeFileName($object->ref);
501  if (!preg_match('/specimen/i', $objectref)) {
502  $dir .= "/".$objectref;
503  }
504  $file = $dir."/".$objectref.".odt";
505 
506  if (!file_exists($dir)) {
507  if (dol_mkdir($dir) < 0) {
508  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
509  return -1;
510  }
511  }
512 
513 
514  if (file_exists($dir)) {
515  //print "srctemplatepath=".$srctemplatepath; // Src filename
516  $newfile = basename($srctemplatepath);
517  $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
518  $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
519  $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
520  $newfiletmp = $objectref.'_'.$newfiletmp;
521  //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
522  $file = $dir.'/'.$newfiletmp.'.odt';
523  //print "newdir=".$dir;
524  //print "newfile=".$newfile;
525  //print "file=".$file;
526  //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
527 
528  dol_mkdir($conf->project->dir_temp);
529  if (!is_writable($conf->project->dir_temp)) {
530  $this->error = "Failed to write in temp directory ".$conf->project->dir_temp;
531  dol_syslog('Error in write_file: '.$this->error, LOG_ERR);
532  return -1;
533  }
534 
535  $socobject = $project->thirdparty;
536 
537  // Make substitution
538  $substitutionarray = array(
539  '__FROM_NAME__' => $this->emetteur->name,
540  '__FROM_EMAIL__' => $this->emetteur->email,
541  );
542  complete_substitutions_array($substitutionarray, $langs, $object);
543  // Call the ODTSubstitution hook
544  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
545  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
546 
547  // Open and load template
548  require_once ODTPHP_PATH.'odf.php';
549  try {
550  $odfHandler = new odf(
551  $srctemplatepath,
552  array(
553  'PATH_TO_TMP' => $conf->project->dir_temp,
554  'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
555  'DELIMITER_LEFT' => '{',
556  'DELIMITER_RIGHT' => '}'
557  )
558  );
559  } catch (Exception $e) {
560  $this->error = $e->getMessage();
561  return -1;
562  }
563  // After construction $odfHandler->contentXml contains content and
564  // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
565  // [!-- BEGIN lines --]*[!-- END lines --]
566  //print html_entity_decode($odfHandler->__toString());
567  //print exit;
568 
569 
570  // Define substitution array
571  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
572  $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
573  $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
574  $array_user = $this->get_substitutionarray_user($user, $outputlangs);
575  $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
576  $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
577  $array_other = $this->get_substitutionarray_other($outputlangs);
578 
579  $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
580  complete_substitutions_array($tmparray, $outputlangs, $object);
581 
582  foreach ($tmparray as $key => $value) {
583  try {
584  if (preg_match('/logo$/', $key)) { // Image
585  if (file_exists($value)) {
586  $odfHandler->setImage($key, $value);
587  } else {
588  $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
589  }
590  } else // Text
591  {
592  $odfHandler->setVars($key, $value, true, 'UTF-8');
593  }
594  } catch (OdfException $e) {
595  dol_syslog($e->getMessage(), LOG_INFO);
596  }
597  }
598 
599  // Replace tags of lines for tasks
600  try {
601  // Security check
602  $socid = 0;
603  if (!empty($project->fk_soc)) {
604  $socid = $project->fk_soc;
605  }
606 
607  $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
608  complete_substitutions_array($tmparray, $outputlangs, $object);
609  foreach ($tmparray as $key => $val) {
610  try {
611  $odfHandler->setVars($key, $val, true, 'UTF-8');
612  } catch (OdfException $e) {
613  dol_syslog($e->getMessage(), LOG_INFO);
614  } catch (SegmentException $e) {
615  dol_syslog($e->getMessage(), LOG_INFO);
616  }
617  }
618 
619  // Replace tags of lines for contacts task
620  $sourcearray = array('internal', 'external');
621  $contact_arrray = array();
622  foreach ($sourcearray as $source) {
623  $contact_temp = $object->liste_contact(-1, $source);
624  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
625  $contact_arrray = array_merge($contact_arrray, $contact_temp);
626  }
627  }
628  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
629  $listlinestaskres = $odfHandler->setSegment('tasksressources');
630 
631  foreach ($contact_arrray as $contact) {
632  if ($contact['source'] == 'internal') {
633  $objectdetail = new User($this->db);
634  $objectdetail->fetch($contact['id']);
635  $contact['socname'] = $mysoc->name;
636  } elseif ($contact['source'] == 'external') {
637  $objectdetail = new Contact($this->db);
638  $objectdetail->fetch($contact['id']);
639 
640  $soc = new Societe($this->db);
641  $soc->fetch($contact['socid']);
642  $contact['socname'] = $soc->name;
643  }
644  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
645 
646  $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
647 
648  foreach ($tmparray as $key => $val) {
649  try {
650  $listlinestaskres->setVars($key, $val, true, 'UTF-8');
651  } catch (OdfException $e) {
652  dol_syslog($e->getMessage(), LOG_INFO);
653  } catch (SegmentException $e) {
654  dol_syslog($e->getMessage(), LOG_INFO);
655  }
656  }
657  $listlinestaskres->merge();
658  }
659  $odfHandler->mergeSegment($listlinestaskres);
660  }
661 
662  // Time ressources
663  $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note";
664  $sql .= ", u.lastname, u.firstname";
665  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
666  $sql .= " , ".MAIN_DB_PREFIX."user as u";
667  $sql .= " WHERE t.fk_task =".((int) $object->id);
668  $sql .= " AND t.fk_user = u.rowid";
669  $sql .= " ORDER BY t.task_date DESC";
670 
671  $resql = $this->db->query($sql);
672  if ($resql) {
673  $num = $this->db->num_rows($resql);
674  $i = 0;
675  $tasks = array();
676  $listlinestasktime = $odfHandler->setSegment('taskstimes');
677  while ($i < $num) {
678  $row = $this->db->fetch_array($resql);
679  if (!empty($row['fk_user'])) {
680  $objectdetail = new User($this->db);
681  $objectdetail->fetch($row['fk_user']);
682  // TODO Use a cache to aoid fetch for same user
683  $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
684  } else {
685  $row['fullcivname'] = '';
686  }
687 
688  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
689 
690  foreach ($tmparray as $key => $val) {
691  try {
692  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
693  } catch (OdfException $e) {
694  dol_syslog($e->getMessage(), LOG_INFO);
695  } catch (SegmentException $e) {
696  dol_syslog($e->getMessage(), LOG_INFO);
697  }
698  }
699  $listlinestasktime->merge();
700  $i++;
701  }
702  $this->db->free($resql);
703 
704  $odfHandler->mergeSegment($listlinestasktime);
705  }
706 
707 
708  // Replace tags of project files
709  $listtasksfiles = $odfHandler->setSegment('tasksfiles');
710 
711  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
712  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
713 
714 
715  foreach ($filearray as $filedetail) {
716  $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
717  //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
718  foreach ($tmparray as $key => $val) {
719  try {
720  $listtasksfiles->setVars($key, $val, true, 'UTF-8');
721  } catch (OdfException $e) {
722  dol_syslog($e->getMessage(), LOG_INFO);
723  } catch (SegmentException $e) {
724  dol_syslog($e->getMessage(), LOG_INFO);
725  }
726  }
727  $listtasksfiles->merge();
728  }
729  //$listlines->merge();
730 
731  $odfHandler->mergeSegment($listtasksfiles);
732  } catch (OdfException $e) {
733  $this->error = $e->getMessage();
734  dol_syslog($this->error, LOG_WARNING);
735  return -1;
736  }
737 
738 
739 
740  // Replace tags of project files
741  try {
742  $listlines = $odfHandler->setSegment('projectfiles');
743 
744  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
745  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
746 
747 
748  foreach ($filearray as $filedetail) {
749  //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
750  $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
751 
752  foreach ($tmparray as $key => $val) {
753  try {
754  $listlines->setVars($key, $val, true, 'UTF-8');
755  } catch (OdfException $e) {
756  dol_syslog($e->getMessage(), LOG_INFO);
757  } catch (SegmentException $e) {
758  dol_syslog($e->getMessage(), LOG_INFO);
759  }
760  }
761  $listlines->merge();
762  }
763  $odfHandler->mergeSegment($listlines);
764  } catch (OdfException $e) {
765  $this->error = $e->getMessage();
766  dol_syslog($this->error, LOG_WARNING);
767  return -1;
768  }
769 
770  // Replace tags of lines for contacts
771  $sourcearray = array('internal', 'external');
772  $contact_arrray = array();
773  foreach ($sourcearray as $source) {
774  $contact_temp = $project->liste_contact(-1, $source);
775  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
776  $contact_arrray = array_merge($contact_arrray, $contact_temp);
777  }
778  }
779  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
780  try {
781  $listlines = $odfHandler->setSegment('projectcontacts');
782 
783  foreach ($contact_arrray as $contact) {
784  if ($contact['source'] == 'internal') {
785  $objectdetail = new User($this->db);
786  $objectdetail->fetch($contact['id']);
787  $contact['socname'] = $mysoc->name;
788  } elseif ($contact['source'] == 'external') {
789  $objectdetail = new Contact($this->db);
790  $objectdetail->fetch($contact['id']);
791 
792  $soc = new Societe($this->db);
793  $soc->fetch($contact['socid']);
794  $contact['socname'] = $soc->name;
795  }
796  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
797 
798  $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
799 
800  foreach ($tmparray as $key => $val) {
801  try {
802  $listlines->setVars($key, $val, true, 'UTF-8');
803  } catch (OdfException $e) {
804  dol_syslog($e->getMessage(), LOG_INFO);
805  } catch (SegmentException $e) {
806  dol_syslog($e->getMessage(), LOG_INFO);
807  }
808  }
809  $listlines->merge();
810  }
811  $odfHandler->mergeSegment($listlines);
812  } catch (OdfException $e) {
813  $this->error = $e->getMessage();
814  dol_syslog($this->error, LOG_WARNING);
815  return -1;
816  }
817  }
818 
819 
820  // Call the beforeODTSave hook
821  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
822  $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
823 
824 
825  // Write new file
826  if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
827  try {
828  $odfHandler->exportAsAttachedPDF($file);
829  } catch (Exception $e) {
830  $this->error = $e->getMessage();
831  dol_syslog($e->getMessage(), LOG_INFO);
832  return -1;
833  }
834  } else {
835  try {
836  $odfHandler->saveToDisk($file);
837  } catch (Exception $e) {
838  $this->error = $e->getMessage();
839  dol_syslog($e->getMessage(), LOG_INFO);
840  return -1;
841  }
842  }
843  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
844  $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
845 
846  if (!empty($conf->global->MAIN_UMASK)) {
847  @chmod($file, octdec($conf->global->MAIN_UMASK));
848  }
849 
850  $odfHandler = null; // Destroy object
851 
852  $this->result = array('fullpath'=>$file);
853 
854  return 1; // Success
855  } else {
856  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
857  return -1;
858  }
859  }
860 
861  return -1;
862  }
863 }
doc_generic_task_odt\get_substitutionarray_tasksressource
get_substitutionarray_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:302
doc_generic_task_odt\get_substitutionarray_object
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:151
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:48
db
$conf db
API class for accounts.
Definition: inc.php:41
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1226
description
print *****$script_file(".$version.") pid cd cd cd description as description
Definition: email_expire_services_to_customers.php:83
Project
Class to manage projects.
Definition: project.class.php:35
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
CommonDocGenerator\get_substitutionarray_user
get_substitutionarray_user($user, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:108
img_warning
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
Definition: functions.lib.php:4521
Task
Class to manage tasks.
Definition: task.class.php:37
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
dol_dir_list
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
name
$conf db name
Definition: repair.php:122
doc_generic_task_odt\info
info($langs)
Return description of a module.
Definition: doc_generic_task_odt.modules.php:370
doc_generic_task_odt
Class to build documents using ODF templates generator.
Definition: doc_generic_task_odt.modules.php:76
ModelePDFTask
Parent class for projects models.
Definition: modules_task.php:33
convertSecondToTime
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:236
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2514
doc_generic_task_odt\get_substitutionarray_task_file
get_substitutionarray_task_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:351
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
Exception
doc_generic_task_odt\__construct
__construct($db)
Constructor.
Definition: doc_generic_task_odt.modules.php:102
CommonDocGenerator\fill_substitutionarray_with_extrafields
fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs)
Fill array with couple extrafield key => extrafield value.
Definition: commondocgenerator.class.php:885
doc_generic_task_odt\get_substitutionarray_tasks
get_substitutionarray_tasks($task, $outputlangs, $array_key='task')
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:190
CommonDocGenerator\get_substitutionarray_thirdparty
get_substitutionarray_thirdparty($object, $outputlangs, $array_key='company')
Define array with couple substitution key => substitution value For example {company_name},...
Definition: commondocgenerator.class.php:256
doc_generic_task_odt\get_substitutionarray_project_file
get_substitutionarray_project_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:258
CommonDocGenerator\get_substitutionarray_each_var_object
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=1)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:841
getCommonSubstitutionArray
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null)
Return array of possible common substitutions.
Definition: functions.lib.php:7275
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
Contact
Class to manage contact/addresses.
Definition: contact.class.php:40
doc_generic_task_odt\get_substitutionarray_taskstime
get_substitutionarray_taskstime($tasktime, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:326
doc_generic_task_odt\get_substitutionarray_project_contacts
get_substitutionarray_project_contacts($contact, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:233
CommonDocGenerator\get_substitutionarray_mysoc
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:197
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
User
Class to manage Dolibarr users.
Definition: user.class.php:44
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->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->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
price
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.
Definition: functions.lib.php:5541
doc_generic_task_odt\get_substitutionarray_project_reference
get_substitutionarray_project_reference($refdetail, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:278
dol_mkdir
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
Definition: functions.lib.php:6603
type
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
complete_substitutions_array
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...
Definition: functions.lib.php:7961
CommonDocGenerator\get_substitutionarray_other
get_substitutionarray_other($outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:379
doc_generic_task_odt\write_file
write_file($object, $outputlangs, $srctemplatepath)
Function to build a document on disk using the generic odt module.
Definition: doc_generic_task_odt.modules.php:465