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