dolibarr 19.0.4
doc_generic_task_odt.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
4 * Copyright (C) 2013 Florian Henry <florian.henry@ope-concept.pro>
5 * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
6 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
7 * 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 // 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 $tmparray = array();
550 $action = '';
551 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
552 $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
553
554 // Open and load template
555 require_once ODTPHP_PATH.'odf.php';
556 try {
557 $odfHandler = new Odf(
558 $srctemplatepath,
559 array(
560 'PATH_TO_TMP' => $conf->project->dir_temp,
561 'ZIP_PROXY' => getDolGlobalString('MAIN_ODF_ZIP_PROXY', 'PclZipProxy'), // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
562 'DELIMITER_LEFT' => '{',
563 'DELIMITER_RIGHT' => '}'
564 )
565 );
566 } catch (Exception $e) {
567 $this->error = $e->getMessage();
568 return -1;
569 }
570 // After construction $odfHandler->contentXml contains content and
571 // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
572 // [!-- BEGIN lines --]*[!-- END lines --]
573 //print html_entity_decode($odfHandler->__toString());
574 //print exit;
575
576
577 // Define substitution array
578 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
579 $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
580 $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
581 $array_user = $this->get_substitutionarray_user($user, $outputlangs);
582 $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
583 $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
584 $array_other = $this->get_substitutionarray_other($outputlangs);
585
586 $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
587 complete_substitutions_array($tmparray, $outputlangs, $object);
588
589 foreach ($tmparray as $key => $value) {
590 try {
591 if (preg_match('/logo$/', $key)) { // Image
592 if (file_exists($value)) {
593 $odfHandler->setImage($key, $value);
594 } else {
595 $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
596 }
597 } else { // Text
598 $odfHandler->setVars($key, $value, true, 'UTF-8');
599 }
600 } catch (OdfException $e) {
601 dol_syslog($e->getMessage(), LOG_INFO);
602 }
603 }
604
605 // Replace tags of lines for tasks
606 try {
607 // Security check
608 $socid = 0;
609 if (!empty($project->fk_soc)) {
610 $socid = $project->fk_soc;
611 }
612
613 $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
614 complete_substitutions_array($tmparray, $outputlangs, $object);
615 foreach ($tmparray as $key => $val) {
616 try {
617 $odfHandler->setVars($key, $val, true, 'UTF-8');
618 } catch (OdfException $e) {
619 dol_syslog($e->getMessage(), LOG_INFO);
620 } catch (SegmentException $e) {
621 dol_syslog($e->getMessage(), LOG_INFO);
622 }
623 }
624
625 // Replace tags of lines for contacts task
626 $sourcearray = array('internal', 'external');
627 $contact_arrray = array();
628 foreach ($sourcearray as $source) {
629 $contact_temp = $object->liste_contact(-1, $source);
630 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
631 $contact_arrray = array_merge($contact_arrray, $contact_temp);
632 }
633 }
634 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
635 $listlinestaskres = $odfHandler->setSegment('tasksressources');
636
637 foreach ($contact_arrray as $contact) {
638 if ($contact['source'] == 'internal') {
639 $objectdetail = new User($this->db);
640 $objectdetail->fetch($contact['id']);
641 $contact['socname'] = $mysoc->name;
642 } elseif ($contact['source'] == 'external') {
643 $objectdetail = new Contact($this->db);
644 $objectdetail->fetch($contact['id']);
645
646 $soc = new Societe($this->db);
647 $soc->fetch($contact['socid']);
648 $contact['socname'] = $soc->name;
649 }
650 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
651
652 $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
653
654 foreach ($tmparray as $key => $val) {
655 try {
656 $listlinestaskres->setVars($key, $val, true, 'UTF-8');
657 } catch (OdfException $e) {
658 dol_syslog($e->getMessage(), LOG_INFO);
659 } catch (SegmentException $e) {
660 dol_syslog($e->getMessage(), LOG_INFO);
661 }
662 }
663 $listlinestaskres->merge();
664 }
665 $odfHandler->mergeSegment($listlinestaskres);
666 }
667
668 // Time ressources
669 $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
670 $sql .= ", u.lastname, u.firstname";
671 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
672 $sql .= " , ".MAIN_DB_PREFIX."user as u";
673 $sql .= " WHERE t.fk_element =".((int) $object->id);
674 $sql .= " AND t.elementtype = 'task'";
675 $sql .= " AND t.fk_user = u.rowid";
676 $sql .= " ORDER BY t.element_date DESC";
677
678 $resql = $this->db->query($sql);
679 if ($resql) {
680 $num = $this->db->num_rows($resql);
681 $i = 0;
682 $tasks = array();
683 $listlinestasktime = $odfHandler->setSegment('taskstimes');
684 while ($i < $num) {
685 $row = $this->db->fetch_array($resql);
686 if (!empty($row['fk_user'])) {
687 $objectdetail = new User($this->db);
688 $objectdetail->fetch($row['fk_user']);
689 // TODO Use a cache to aoid fetch for same user
690 $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
691 } else {
692 $row['fullcivname'] = '';
693 }
694
695 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
696
697 foreach ($tmparray as $key => $val) {
698 try {
699 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
700 } catch (OdfException $e) {
701 dol_syslog($e->getMessage(), LOG_INFO);
702 } catch (SegmentException $e) {
703 dol_syslog($e->getMessage(), LOG_INFO);
704 }
705 }
706 $listlinestasktime->merge();
707 $i++;
708 }
709 $this->db->free($resql);
710
711 $odfHandler->mergeSegment($listlinestasktime);
712 }
713
714
715 // Replace tags of project files
716 $listtasksfiles = $odfHandler->setSegment('tasksfiles');
717
718 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
719 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
720
721
722 foreach ($filearray as $filedetail) {
723 $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
724 //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
725 foreach ($tmparray as $key => $val) {
726 try {
727 $listtasksfiles->setVars($key, $val, true, 'UTF-8');
728 } catch (OdfException $e) {
729 dol_syslog($e->getMessage(), LOG_INFO);
730 } catch (SegmentException $e) {
731 dol_syslog($e->getMessage(), LOG_INFO);
732 }
733 }
734 $listtasksfiles->merge();
735 }
736 //$listlines->merge();
737
738 $odfHandler->mergeSegment($listtasksfiles);
739 } catch (OdfException $e) {
740 $this->error = $e->getMessage();
741 dol_syslog($this->error, LOG_WARNING);
742 return -1;
743 }
744
745
746
747 // Replace tags of project files
748 try {
749 $listlines = $odfHandler->setSegment('projectfiles');
750
751 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
752 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
753
754
755 foreach ($filearray as $filedetail) {
756 //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
757 $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
758
759 foreach ($tmparray as $key => $val) {
760 try {
761 $listlines->setVars($key, $val, true, 'UTF-8');
762 } catch (OdfException $e) {
763 dol_syslog($e->getMessage(), LOG_INFO);
764 } catch (SegmentException $e) {
765 dol_syslog($e->getMessage(), LOG_INFO);
766 }
767 }
768 $listlines->merge();
769 }
770 $odfHandler->mergeSegment($listlines);
771 } catch (OdfException $e) {
772 $this->error = $e->getMessage();
773 dol_syslog($this->error, LOG_WARNING);
774 return -1;
775 }
776
777 // Replace tags of lines for contacts
778 $sourcearray = array('internal', 'external');
779 $contact_arrray = array();
780 foreach ($sourcearray as $source) {
781 $contact_temp = $project->liste_contact(-1, $source);
782 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
783 $contact_arrray = array_merge($contact_arrray, $contact_temp);
784 }
785 }
786 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
787 try {
788 $listlines = $odfHandler->setSegment('projectcontacts');
789
790 foreach ($contact_arrray as $contact) {
791 if ($contact['source'] == 'internal') {
792 $objectdetail = new User($this->db);
793 $objectdetail->fetch($contact['id']);
794 $contact['socname'] = $mysoc->name;
795 } elseif ($contact['source'] == 'external') {
796 $objectdetail = new Contact($this->db);
797 $objectdetail->fetch($contact['id']);
798
799 $soc = new Societe($this->db);
800 $soc->fetch($contact['socid']);
801 $contact['socname'] = $soc->name;
802 }
803 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
804
805 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
806
807 foreach ($tmparray as $key => $val) {
808 try {
809 $listlines->setVars($key, $val, true, 'UTF-8');
810 } catch (OdfException $e) {
811 dol_syslog($e->getMessage(), LOG_INFO);
812 } catch (SegmentException $e) {
813 dol_syslog($e->getMessage(), LOG_INFO);
814 }
815 }
816 $listlines->merge();
817 }
818 $odfHandler->mergeSegment($listlines);
819 } catch (OdfException $e) {
820 $this->error = $e->getMessage();
821 dol_syslog($this->error, LOG_WARNING);
822 return -1;
823 }
824 }
825
826
827 // Call the beforeODTSave hook
828 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
829 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
830
831
832 // Write new file
833 if (getDolGlobalString('MAIN_ODT_AS_PDF')) {
834 try {
835 $odfHandler->exportAsAttachedPDF($file);
836 } catch (Exception $e) {
837 $this->error = $e->getMessage();
838 dol_syslog($e->getMessage(), LOG_INFO);
839 return -1;
840 }
841 } else {
842 try {
843 $odfHandler->saveToDisk($file);
844 } catch (Exception $e) {
845 $this->error = $e->getMessage();
846 dol_syslog($e->getMessage(), LOG_INFO);
847 return -1;
848 }
849 }
850 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
851 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
852
853 dolChmod($file);
854
855 $odfHandler = null; // Destroy object
856
857 $this->result = array('fullpath'=>$file);
858
859 return 1; // Success
860 } else {
861 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
862 return -1;
863 }
864 }
865
866 return -1;
867 }
868}
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.
Class to manage hooks.
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