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 if (!is_object($outputlangs)) {
473 $outputlangs = $langs;
474 }
475 $sav_charset_output = $outputlangs->charset_output;
476 $outputlangs->charset_output = 'UTF-8';
477
478 // Load translation files required by the page
479 $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
480
481 if ($conf->project->dir_output) {
482 // If $object is id instead of object
483 if (!is_object($object)) {
484 $id = $object;
485 $object = new Task($this->db);
486 $result = $object->fetch($id);
487 if ($result < 0) {
488 dol_print_error($this->db, $object->error);
489 return -1;
490 }
491 }
492 $project = new Project($this->db);
493 $project->fetch($object->fk_project);
494 $project->fetch_thirdparty();
495
496 $dir = $conf->project->dir_output."/".$project->ref."/";
497 $objectref = dol_sanitizeFileName($object->ref);
498 if (!preg_match('/specimen/i', $objectref)) {
499 $dir .= "/".$objectref;
500 }
501 $file = $dir."/".$objectref.".odt";
502
503 if (!file_exists($dir)) {
504 if (dol_mkdir($dir) < 0) {
505 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
506 return -1;
507 }
508 }
509
510
511 if (file_exists($dir)) {
512 //print "srctemplatepath=".$srctemplatepath; // Src filename
513 $newfile = basename($srctemplatepath);
514 $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
515 $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
516 $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
517 $newfiletmp = $objectref . '_' . $newfiletmp;
518 //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
519 $file = $dir . '/' . $newfiletmp . '.odt';
520 //print "newdir=".$dir;
521 //print "newfile=".$newfile;
522 //print "file=".$file;
523 //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
524
525 dol_mkdir($conf->project->dir_temp);
526 if (!is_writable($conf->project->dir_temp)) {
527 $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
528 dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
529 return -1;
530 }
531
532 $socobject = $project->thirdparty;
533
534 // Make substitution
535 $substitutionarray = array(
536 '__FROM_NAME__' => $this->emetteur->name,
537 '__FROM_EMAIL__' => $this->emetteur->email,
538 );
539 complete_substitutions_array($substitutionarray, $langs, $object);
540 // Call the ODTSubstitution hook
541 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
542 $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
543
544 // Open and load template
545 require_once ODTPHP_PATH.'odf.php';
546 try {
547 $odfHandler = new Odf(
548 $srctemplatepath,
549 array(
550 'PATH_TO_TMP' => $conf->project->dir_temp,
551 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
552 'DELIMITER_LEFT' => '{',
553 'DELIMITER_RIGHT' => '}'
554 )
555 );
556 } catch (Exception $e) {
557 $this->error = $e->getMessage();
558 return -1;
559 }
560 // After construction $odfHandler->contentXml contains content and
561 // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
562 // [!-- BEGIN lines --]*[!-- END lines --]
563 //print html_entity_decode($odfHandler->__toString());
564 //print exit;
565
566
567 // Define substitution array
568 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
569 $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
570 $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
571 $array_user = $this->get_substitutionarray_user($user, $outputlangs);
572 $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
573 $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
574 $array_other = $this->get_substitutionarray_other($outputlangs);
575
576 $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
577 complete_substitutions_array($tmparray, $outputlangs, $object);
578
579 foreach ($tmparray as $key => $value) {
580 try {
581 if (preg_match('/logo$/', $key)) { // Image
582 if (file_exists($value)) {
583 $odfHandler->setImage($key, $value);
584 } else {
585 $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
586 }
587 } else // Text
588 {
589 $odfHandler->setVars($key, $value, true, 'UTF-8');
590 }
591 } catch (OdfException $e) {
592 dol_syslog($e->getMessage(), LOG_INFO);
593 }
594 }
595
596 // Replace tags of lines for tasks
597 try {
598 // Security check
599 $socid = 0;
600 if (!empty($project->fk_soc)) {
601 $socid = $project->fk_soc;
602 }
603
604 $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
605 complete_substitutions_array($tmparray, $outputlangs, $object);
606 foreach ($tmparray as $key => $val) {
607 try {
608 $odfHandler->setVars($key, $val, true, 'UTF-8');
609 } catch (OdfException $e) {
610 dol_syslog($e->getMessage(), LOG_INFO);
611 } catch (SegmentException $e) {
612 dol_syslog($e->getMessage(), LOG_INFO);
613 }
614 }
615
616 // Replace tags of lines for contacts task
617 $sourcearray = array('internal', 'external');
618 $contact_arrray = array();
619 foreach ($sourcearray as $source) {
620 $contact_temp = $object->liste_contact(-1, $source);
621 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
622 $contact_arrray = array_merge($contact_arrray, $contact_temp);
623 }
624 }
625 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
626 $listlinestaskres = $odfHandler->setSegment('tasksressources');
627
628 foreach ($contact_arrray as $contact) {
629 if ($contact['source'] == 'internal') {
630 $objectdetail = new User($this->db);
631 $objectdetail->fetch($contact['id']);
632 $contact['socname'] = $mysoc->name;
633 } elseif ($contact['source'] == 'external') {
634 $objectdetail = new Contact($this->db);
635 $objectdetail->fetch($contact['id']);
636
637 $soc = new Societe($this->db);
638 $soc->fetch($contact['socid']);
639 $contact['socname'] = $soc->name;
640 }
641 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
642
643 $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
644
645 foreach ($tmparray as $key => $val) {
646 try {
647 $listlinestaskres->setVars($key, $val, true, 'UTF-8');
648 } catch (OdfException $e) {
649 dol_syslog($e->getMessage(), LOG_INFO);
650 } catch (SegmentException $e) {
651 dol_syslog($e->getMessage(), LOG_INFO);
652 }
653 }
654 $listlinestaskres->merge();
655 }
656 $odfHandler->mergeSegment($listlinestaskres);
657 }
658
659 // Time ressources
660 $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
661 $sql .= ", u.lastname, u.firstname";
662 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
663 $sql .= " , ".MAIN_DB_PREFIX."user as u";
664 $sql .= " WHERE t.fk_element =".((int) $object->id);
665 $sql .= " AND t.elementtype = 'task'";
666 $sql .= " AND t.fk_user = u.rowid";
667 $sql .= " ORDER BY t.element_date DESC";
668
669 $resql = $this->db->query($sql);
670 if ($resql) {
671 $num = $this->db->num_rows($resql);
672 $i = 0;
673 $tasks = array();
674 $listlinestasktime = $odfHandler->setSegment('taskstimes');
675 while ($i < $num) {
676 $row = $this->db->fetch_array($resql);
677 if (!empty($row['fk_user'])) {
678 $objectdetail = new User($this->db);
679 $objectdetail->fetch($row['fk_user']);
680 // TODO Use a cache to aoid fetch for same user
681 $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
682 } else {
683 $row['fullcivname'] = '';
684 }
685
686 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
687
688 foreach ($tmparray as $key => $val) {
689 try {
690 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
691 } catch (OdfException $e) {
692 dol_syslog($e->getMessage(), LOG_INFO);
693 } catch (SegmentException $e) {
694 dol_syslog($e->getMessage(), LOG_INFO);
695 }
696 }
697 $listlinestasktime->merge();
698 $i++;
699 }
700 $this->db->free($resql);
701
702 $odfHandler->mergeSegment($listlinestasktime);
703 }
704
705
706 // Replace tags of project files
707 $listtasksfiles = $odfHandler->setSegment('tasksfiles');
708
709 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
710 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
711
712
713 foreach ($filearray as $filedetail) {
714 $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
715 //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
716 foreach ($tmparray as $key => $val) {
717 try {
718 $listtasksfiles->setVars($key, $val, true, 'UTF-8');
719 } catch (OdfException $e) {
720 dol_syslog($e->getMessage(), LOG_INFO);
721 } catch (SegmentException $e) {
722 dol_syslog($e->getMessage(), LOG_INFO);
723 }
724 }
725 $listtasksfiles->merge();
726 }
727 //$listlines->merge();
728
729 $odfHandler->mergeSegment($listtasksfiles);
730 } catch (OdfException $e) {
731 $this->error = $e->getMessage();
732 dol_syslog($this->error, LOG_WARNING);
733 return -1;
734 }
735
736
737
738 // Replace tags of project files
739 try {
740 $listlines = $odfHandler->setSegment('projectfiles');
741
742 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
743 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
744
745
746 foreach ($filearray as $filedetail) {
747 //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
748 $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
749
750 foreach ($tmparray as $key => $val) {
751 try {
752 $listlines->setVars($key, $val, true, 'UTF-8');
753 } catch (OdfException $e) {
754 dol_syslog($e->getMessage(), LOG_INFO);
755 } catch (SegmentException $e) {
756 dol_syslog($e->getMessage(), LOG_INFO);
757 }
758 }
759 $listlines->merge();
760 }
761 $odfHandler->mergeSegment($listlines);
762 } catch (OdfException $e) {
763 $this->error = $e->getMessage();
764 dol_syslog($this->error, LOG_WARNING);
765 return -1;
766 }
767
768 // Replace tags of lines for contacts
769 $sourcearray = array('internal', 'external');
770 $contact_arrray = array();
771 foreach ($sourcearray as $source) {
772 $contact_temp = $project->liste_contact(-1, $source);
773 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
774 $contact_arrray = array_merge($contact_arrray, $contact_temp);
775 }
776 }
777 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
778 try {
779 $listlines = $odfHandler->setSegment('projectcontacts');
780
781 foreach ($contact_arrray as $contact) {
782 if ($contact['source'] == 'internal') {
783 $objectdetail = new User($this->db);
784 $objectdetail->fetch($contact['id']);
785 $contact['socname'] = $mysoc->name;
786 } elseif ($contact['source'] == 'external') {
787 $objectdetail = new Contact($this->db);
788 $objectdetail->fetch($contact['id']);
789
790 $soc = new Societe($this->db);
791 $soc->fetch($contact['socid']);
792 $contact['socname'] = $soc->name;
793 }
794 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
795
796 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
797
798 foreach ($tmparray as $key => $val) {
799 try {
800 $listlines->setVars($key, $val, true, 'UTF-8');
801 } catch (OdfException $e) {
802 dol_syslog($e->getMessage(), LOG_INFO);
803 } catch (SegmentException $e) {
804 dol_syslog($e->getMessage(), LOG_INFO);
805 }
806 }
807 $listlines->merge();
808 }
809 $odfHandler->mergeSegment($listlines);
810 } catch (OdfException $e) {
811 $this->error = $e->getMessage();
812 dol_syslog($this->error, LOG_WARNING);
813 return -1;
814 }
815 }
816
817
818 // Call the beforeODTSave hook
819 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
820 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
821
822
823 // Write new file
824 if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
825 try {
826 $odfHandler->exportAsAttachedPDF($file);
827 } catch (Exception $e) {
828 $this->error = $e->getMessage();
829 dol_syslog($e->getMessage(), LOG_INFO);
830 return -1;
831 }
832 } else {
833 try {
834 $odfHandler->saveToDisk($file);
835 } catch (Exception $e) {
836 $this->error = $e->getMessage();
837 dol_syslog($e->getMessage(), LOG_INFO);
838 return -1;
839 }
840 }
841 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
842 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
843
844 dolChmod($file);
845
846 $odfHandler = null; // Destroy object
847
848 $this->result = array('fullpath'=>$file);
849
850 return 1; // Success
851 } else {
852 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
853 return -1;
854 }
855 }
856
857 return -1;
858 }
859}
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.
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