dolibarr 19.0.3
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 $version = 'dolibarr';
84
85
91 public function __construct($db)
92 {
93 global $langs, $mysoc;
94
95 // Load translation files required by the page
96 $langs->loadLangs(array("main", "companies"));
97
98 $this->db = $db;
99 $this->name = "ODT templates";
100 $this->description = $langs->trans("DocumentModelOdt");
101 $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
102
103 // Page size for A4 format
104 $this->type = 'odt';
105 $this->page_largeur = 0;
106 $this->page_hauteur = 0;
107 $this->format = array($this->page_largeur, $this->page_hauteur);
108 $this->marge_gauche = 0;
109 $this->marge_droite = 0;
110 $this->marge_haute = 0;
111 $this->marge_basse = 0;
112
113 $this->option_logo = 1; // Display logo
114 $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
115 $this->option_modereg = 0; // Display payment mode
116 $this->option_condreg = 0; // Display payment terms
117 $this->option_multilang = 0; // Available in several languages
118 $this->option_escompte = 0; // Displays if there has been a discount
119 $this->option_credit_note = 0; // Support credit notes
120 $this->option_freetext = 1; // Support add of a personalised text
121 $this->option_draft_watermark = 0; // Support add of a watermark on drafts
122
123 // Get source company
124 $this->emetteur = $mysoc;
125 if (!$this->emetteur->country_code) {
126 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
127 }
128 }
129
130
131 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
140 public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
141 {
142 // phpcs:enable
143 global $conf, $extrafields;
144
145 $resarray = array(
146 $array_key.'_id'=>$object->id,
147 $array_key.'_ref'=>$object->ref,
148 $array_key.'_title'=>$object->title,
149 $array_key.'_description'=>$object->description,
150 $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
151 $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
152 $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
153 $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
154 $array_key.'_note_private'=>$object->note_private,
155 $array_key.'_note_public'=>$object->note_public,
156 $array_key.'_public'=>$object->public,
157 $array_key.'_statut'=>$object->getLibStatut()
158 );
159
160 // Retrieve extrafields
161 if (is_array($object->array_options) && count($object->array_options)) {
162 $object->fetch_optionals();
163
164 $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
165 }
166
167 return $resarray;
168 }
169
170 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
179 public function get_substitutionarray_tasks($task, $outputlangs, $array_key = 'task')
180 {
181 // phpcs:enable
182 global $conf, $extrafields;
183
184 $resarray = array(
185 'task_ref'=>$task->ref,
186 'task_fk_project'=>$task->fk_project,
187 'task_projectref'=>$task->projectref,
188 'task_projectlabel'=>$task->projectlabel,
189 'task_label'=>$task->label,
190 'task_description'=>$task->description,
191 'task_fk_parent'=>$task->fk_task_parent,
192 'task_duration'=>$task->duration_effective,
193 'task_duration_formated'=>convertSecondToTime($task->duration_effective, 'allhourmin'),
194 'task_planned_workload'=>$task->planned_workload,
195 'task_planned_workload_formated'=>convertSecondToTime($task->planned_workload, 'allhourmin'),
196 'task_progress'=>$task->progress,
197 'task_public'=>$task->public,
198 'task_date_start'=>dol_print_date($task->date_start, 'day'),
199 'task_date_end'=>dol_print_date($task->date_end, 'day'),
200 'task_note_private'=>$task->note_private,
201 'task_note_public'=>$task->note_public
202 );
203
204 // Retrieve extrafields
205 if (is_array($task->array_options) && count($task->array_options)) {
206 $task->fetch_optionals();
207
208 $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, $array_key, $outputlangs);
209 }
210
211 return $resarray;
212 }
213
214 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
222 public function get_substitutionarray_project_contacts($contact, $outputlangs)
223 {
224 // phpcs:enable
225 global $conf;
226
227 return array(
228 'projcontacts_id'=>$contact['id'],
229 'projcontacts_rowid'=>$contact['rowid'],
230 'projcontacts_role'=>$contact['libelle'],
231 'projcontacts_lastname'=>$contact['lastname'],
232 'projcontacts_firstname'=>$contact['firstname'],
233 'projcontacts_fullcivname'=>$contact['fullname'],
234 'projcontacts_socname'=>$contact['socname'],
235 'projcontacts_email'=>$contact['email']
236 );
237 }
238
239 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
247 public function get_substitutionarray_project_file($file, $outputlangs)
248 {
249 // phpcs:enable
250 global $conf;
251
252 return array(
253 'projfile_name'=>$file['name'],
254 'projfile_date'=>dol_print_date($file['date'], 'day'),
255 'projfile_size'=>$file['size']
256 );
257 }
258
259 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
267 public function get_substitutionarray_project_reference($refdetail, $outputlangs)
268 {
269 // phpcs:enable
270 global $conf;
271
272 return array(
273 'projref_type'=>$refdetail['type'],
274 'projref_ref'=>$refdetail['ref'],
275 'projref_date'=>dol_print_date($refdetail['date'], 'day'),
276 'projref_socname'=>$refdetail['socname'],
277 'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
278 'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
279 'projref_status'=>$refdetail['status']
280 );
281 }
282
283 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
291 public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
292 {
293 // phpcs:enable
294 global $conf;
295 //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
296 return array(
297 'taskressource_rowid'=>$taskressource['rowid'],
298 'taskressource_role'=>$taskressource['libelle'],
299 'taskressource_lastname'=>$taskressource['lastname'],
300 'taskressource_firstname'=>$taskressource['firstname'],
301 'taskressource_fullcivname'=>$taskressource['fullname'],
302 'taskressource_socname'=>$taskressource['socname'],
303 'taskressource_email'=>$taskressource['email']
304 );
305 }
306
307 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
315 public function get_substitutionarray_taskstime($tasktime, $outputlangs)
316 {
317 // phpcs:enable
318 global $conf;
319
320 return array(
321 'tasktime_rowid'=>$tasktime['rowid'],
322 'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
323 'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
324 'tasktime_note'=>$tasktime['note'],
325 'tasktime_fk_user'=>$tasktime['fk_user'],
326 'tasktime_user_name'=>$tasktime['name'],
327 'tasktime_user_first'=>$tasktime['firstname'],
328 'tasktime_fullcivname'=>$tasktime['fullcivname']
329 );
330 }
331
332 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
340 public function get_substitutionarray_task_file($file, $outputlangs)
341 {
342 // phpcs:enable
343 global $conf;
344
345 return array(
346 'tasksfile_name'=>$file['name'],
347 'tasksfile_date'=>dol_print_date($file['date'], 'day'),
348 'tasksfile_size'=>$file['size']
349 );
350 }
351
352
359 public function info($langs)
360 {
361 global $conf, $langs;
362
363 // Load translation files required by the page
364 $langs->loadLangs(array("errors", "companies"));
365
366 $form = new Form($this->db);
367
368 $texte = $this->description.".<br>\n";
369 $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" enctype="multipart/form-data">';
370 $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
371 $texte .= '<input type="hidden" name="page_y" value="">';
372 $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
373 $texte .= '<input type="hidden" name="param1" value="PROJECT_TASK_ADDON_PDF_ODT_PATH">';
374 $texte .= '<table class="nobordernopadding centpercent">';
375
376 // List of directories area
377 $texte .= '<tr><td>';
378 $texttitle = $langs->trans("ListOfDirectories");
379 $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)));
380 $listoffiles = array();
381 foreach ($listofdir as $key => $tmpdir) {
382 $tmpdir = trim($tmpdir);
383 $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
384 if (!$tmpdir) {
385 unset($listofdir[$key]);
386 continue;
387 }
388 if (!is_dir($tmpdir)) {
389 $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
390 } else {
391 $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
392 if (count($tmpfiles)) {
393 $listoffiles = array_merge($listoffiles, $tmpfiles);
394 }
395 }
396 }
397 $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
398 $texthelp .= '<br><br><span class="opacitymedium">'.$langs->trans("ExampleOfDirectoriesForModelGen").'</span>';
399 // Add list of substitution keys
400 $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
401 $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
402
403 $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1, 3, $this->name);
404 $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
405 $texte .= '<textarea class="flat" cols="60" name="value1">';
406 $texte .= getDolGlobalString('PROJECT_TASK_ADDON_PDF_ODT_PATH');
407 $texte .= '</textarea>';
408 $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
409 $texte .= '<input type="submit" class="button button-edit reposition smallpaddingimp" name="modify" value="'.dol_escape_htmltag($langs->trans("Modify")).'">';
410 $texte .= '<br></div></div>';
411
412 // Scan directories
413 $nbofiles = count($listoffiles);
414 if (getDolGlobalString('PROJECT_TASK_ADDON_PDF_ODT_PATH')) {
415 $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
416 //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
417 $texte .= $nbofiles;
418 //$texte.=$nbofiles?'</a>':'';
419 $texte .= '</b>';
420 }
421
422 if ($nbofiles) {
423 $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
424 // Show list of found files
425 foreach ($listoffiles as $file) {
426 $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=tasks/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
427 $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>';
428 $texte .= '<br>';
429 }
430 $texte .= '</div>';
431 }
432 // Add input to upload a new template file.
433 $texte .= '<div>'.$langs->trans("UploadNewTemplate");
434 $maxfilesizearray = getMaxFileSizeArray();
435 $maxmin = $maxfilesizearray['maxmin'];
436 if ($maxmin > 0) {
437 $texte .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
438 }
439 $texte .= ' <input type="file" name="uploadfile">';
440 $texte .= '<input type="hidden" value="PROJECT_TASK_ADDON_PDF_ODT_PATH" name="keyforuploaddir">';
441 $texte .= '<input type="submit" class="button smallpaddingimp reposition" value="'.dol_escape_htmltag($langs->trans("Upload")).'" name="upload">';
442 $texte .= '</div>';
443 $texte .= '</td>';
444
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 $tmparray = array();
542 $action = '';
543 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
544 $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
545
546 // Open and load template
547 require_once ODTPHP_PATH.'odf.php';
548 try {
549 $odfHandler = new Odf(
550 $srctemplatepath,
551 array(
552 'PATH_TO_TMP' => $conf->project->dir_temp,
553 'ZIP_PROXY' => getDolGlobalString('MAIN_ODF_ZIP_PROXY', 'PclZipProxy'), // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
554 'DELIMITER_LEFT' => '{',
555 'DELIMITER_RIGHT' => '}'
556 )
557 );
558 } catch (Exception $e) {
559 $this->error = $e->getMessage();
560 return -1;
561 }
562 // After construction $odfHandler->contentXml contains content and
563 // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
564 // [!-- BEGIN lines --]*[!-- END lines --]
565 //print html_entity_decode($odfHandler->__toString());
566 //print exit;
567
568
569 // Define substitution array
570 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
571 $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
572 $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
573 $array_user = $this->get_substitutionarray_user($user, $outputlangs);
574 $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
575 $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
576 $array_other = $this->get_substitutionarray_other($outputlangs);
577
578 $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
579 complete_substitutions_array($tmparray, $outputlangs, $object);
580
581 foreach ($tmparray as $key => $value) {
582 try {
583 if (preg_match('/logo$/', $key)) { // Image
584 if (file_exists($value)) {
585 $odfHandler->setImage($key, $value);
586 } else {
587 $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
588 }
589 } else { // Text
590 $odfHandler->setVars($key, $value, true, 'UTF-8');
591 }
592 } catch (OdfException $e) {
593 dol_syslog($e->getMessage(), LOG_INFO);
594 }
595 }
596
597 // Replace tags of lines for tasks
598 try {
599 // Security check
600 $socid = 0;
601 if (!empty($project->fk_soc)) {
602 $socid = $project->fk_soc;
603 }
604
605 $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
606 complete_substitutions_array($tmparray, $outputlangs, $object);
607 foreach ($tmparray as $key => $val) {
608 try {
609 $odfHandler->setVars($key, $val, true, 'UTF-8');
610 } catch (OdfException $e) {
611 dol_syslog($e->getMessage(), LOG_INFO);
612 } catch (SegmentException $e) {
613 dol_syslog($e->getMessage(), LOG_INFO);
614 }
615 }
616
617 // Replace tags of lines for contacts task
618 $sourcearray = array('internal', 'external');
619 $contact_arrray = array();
620 foreach ($sourcearray as $source) {
621 $contact_temp = $object->liste_contact(-1, $source);
622 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
623 $contact_arrray = array_merge($contact_arrray, $contact_temp);
624 }
625 }
626 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
627 $listlinestaskres = $odfHandler->setSegment('tasksressources');
628
629 foreach ($contact_arrray as $contact) {
630 if ($contact['source'] == 'internal') {
631 $objectdetail = new User($this->db);
632 $objectdetail->fetch($contact['id']);
633 $contact['socname'] = $mysoc->name;
634 } elseif ($contact['source'] == 'external') {
635 $objectdetail = new Contact($this->db);
636 $objectdetail->fetch($contact['id']);
637
638 $soc = new Societe($this->db);
639 $soc->fetch($contact['socid']);
640 $contact['socname'] = $soc->name;
641 }
642 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
643
644 $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
645
646 foreach ($tmparray as $key => $val) {
647 try {
648 $listlinestaskres->setVars($key, $val, true, 'UTF-8');
649 } catch (OdfException $e) {
650 dol_syslog($e->getMessage(), LOG_INFO);
651 } catch (SegmentException $e) {
652 dol_syslog($e->getMessage(), LOG_INFO);
653 }
654 }
655 $listlinestaskres->merge();
656 }
657 $odfHandler->mergeSegment($listlinestaskres);
658 }
659
660 // Time ressources
661 $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
662 $sql .= ", u.lastname, u.firstname";
663 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
664 $sql .= " , ".MAIN_DB_PREFIX."user as u";
665 $sql .= " WHERE t.fk_element =".((int) $object->id);
666 $sql .= " AND t.elementtype = 'task'";
667 $sql .= " AND t.fk_user = u.rowid";
668 $sql .= " ORDER BY t.element_date DESC";
669
670 $resql = $this->db->query($sql);
671 if ($resql) {
672 $num = $this->db->num_rows($resql);
673 $i = 0;
674 $tasks = array();
675 $listlinestasktime = $odfHandler->setSegment('taskstimes');
676 while ($i < $num) {
677 $row = $this->db->fetch_array($resql);
678 if (!empty($row['fk_user'])) {
679 $objectdetail = new User($this->db);
680 $objectdetail->fetch($row['fk_user']);
681 // TODO Use a cache to aoid fetch for same user
682 $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
683 } else {
684 $row['fullcivname'] = '';
685 }
686
687 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
688
689 foreach ($tmparray as $key => $val) {
690 try {
691 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
692 } catch (OdfException $e) {
693 dol_syslog($e->getMessage(), LOG_INFO);
694 } catch (SegmentException $e) {
695 dol_syslog($e->getMessage(), LOG_INFO);
696 }
697 }
698 $listlinestasktime->merge();
699 $i++;
700 }
701 $this->db->free($resql);
702
703 $odfHandler->mergeSegment($listlinestasktime);
704 }
705
706
707 // Replace tags of project files
708 $listtasksfiles = $odfHandler->setSegment('tasksfiles');
709
710 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
711 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
712
713
714 foreach ($filearray as $filedetail) {
715 $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
716 //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
717 foreach ($tmparray as $key => $val) {
718 try {
719 $listtasksfiles->setVars($key, $val, true, 'UTF-8');
720 } catch (OdfException $e) {
721 dol_syslog($e->getMessage(), LOG_INFO);
722 } catch (SegmentException $e) {
723 dol_syslog($e->getMessage(), LOG_INFO);
724 }
725 }
726 $listtasksfiles->merge();
727 }
728 //$listlines->merge();
729
730 $odfHandler->mergeSegment($listtasksfiles);
731 } catch (OdfException $e) {
732 $this->error = $e->getMessage();
733 dol_syslog($this->error, LOG_WARNING);
734 return -1;
735 }
736
737
738
739 // Replace tags of project files
740 try {
741 $listlines = $odfHandler->setSegment('projectfiles');
742
743 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
744 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
745
746
747 foreach ($filearray as $filedetail) {
748 //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
749 $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
750
751 foreach ($tmparray as $key => $val) {
752 try {
753 $listlines->setVars($key, $val, true, 'UTF-8');
754 } catch (OdfException $e) {
755 dol_syslog($e->getMessage(), LOG_INFO);
756 } catch (SegmentException $e) {
757 dol_syslog($e->getMessage(), LOG_INFO);
758 }
759 }
760 $listlines->merge();
761 }
762 $odfHandler->mergeSegment($listlines);
763 } catch (OdfException $e) {
764 $this->error = $e->getMessage();
765 dol_syslog($this->error, LOG_WARNING);
766 return -1;
767 }
768
769 // Replace tags of lines for contacts
770 $sourcearray = array('internal', 'external');
771 $contact_arrray = array();
772 foreach ($sourcearray as $source) {
773 $contact_temp = $project->liste_contact(-1, $source);
774 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
775 $contact_arrray = array_merge($contact_arrray, $contact_temp);
776 }
777 }
778 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
779 try {
780 $listlines = $odfHandler->setSegment('projectcontacts');
781
782 foreach ($contact_arrray as $contact) {
783 if ($contact['source'] == 'internal') {
784 $objectdetail = new User($this->db);
785 $objectdetail->fetch($contact['id']);
786 $contact['socname'] = $mysoc->name;
787 } elseif ($contact['source'] == 'external') {
788 $objectdetail = new Contact($this->db);
789 $objectdetail->fetch($contact['id']);
790
791 $soc = new Societe($this->db);
792 $soc->fetch($contact['socid']);
793 $contact['socname'] = $soc->name;
794 }
795 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
796
797 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
798
799 foreach ($tmparray as $key => $val) {
800 try {
801 $listlines->setVars($key, $val, true, 'UTF-8');
802 } catch (OdfException $e) {
803 dol_syslog($e->getMessage(), LOG_INFO);
804 } catch (SegmentException $e) {
805 dol_syslog($e->getMessage(), LOG_INFO);
806 }
807 }
808 $listlines->merge();
809 }
810 $odfHandler->mergeSegment($listlines);
811 } catch (OdfException $e) {
812 $this->error = $e->getMessage();
813 dol_syslog($this->error, LOG_WARNING);
814 return -1;
815 }
816 }
817
818
819 // Call the beforeODTSave hook
820 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
821 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
822
823
824 // Write new file
825 if (getDolGlobalString('MAIN_ODT_AS_PDF')) {
826 try {
827 $odfHandler->exportAsAttachedPDF($file);
828 } catch (Exception $e) {
829 $this->error = $e->getMessage();
830 dol_syslog($e->getMessage(), LOG_INFO);
831 return -1;
832 }
833 } else {
834 try {
835 $odfHandler->saveToDisk($file);
836 } catch (Exception $e) {
837 $this->error = $e->getMessage();
838 dol_syslog($e->getMessage(), LOG_INFO);
839 return -1;
840 }
841 }
842 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
843 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
844
845 dolChmod($file);
846
847 $odfHandler = null; // Destroy object
848
849 $this->result = array('fullpath'=>$file);
850
851 return 1; // Success
852 } else {
853 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
854 return -1;
855 }
856 }
857
858 return -1;
859 }
860}
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 generation of HTML components Only common components must be here.
Parent class for task 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:243
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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:121
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:124
getMaxFileSizeArray()
Return the max allowed for file upload.
Contact()
Old copy.
Definition index.php:572