dolibarr 20.0.0
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-2024 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 * or see https://www.gnu.org/
23 */
24
31require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
32require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
33require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
34require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
35require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
36require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
37require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
43if (isModEnabled("propal")) {
44 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
45}
46if (isModEnabled('invoice')) {
47 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
48}
49if (isModEnabled('invoice')) {
50 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
51}
52if (isModEnabled('order')) {
53 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
54}
55if (isModEnabled("supplier_invoice")) {
56 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
57}
58if (isModEnabled("supplier_order")) {
59 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
60}
61if (isModEnabled('contract')) {
62 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
63}
64if (isModEnabled('intervention')) {
65 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
66}
67if (isModEnabled('deplacement')) {
68 require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
69}
70if (isModEnabled('agenda')) {
71 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
72}
73
74
79{
84 public $version = 'dolibarr';
85
86
92 public function __construct($db)
93 {
94 global $langs, $mysoc;
95
96 // Load translation files required by the page
97 $langs->loadLangs(array("main", "companies"));
98
99 $this->db = $db;
100 $this->name = "ODT templates";
101 $this->description = $langs->trans("DocumentModelOdt");
102 $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
103
104 // Page size for A4 format
105 $this->type = 'odt';
106 $this->page_largeur = 0;
107 $this->page_hauteur = 0;
108 $this->format = array($this->page_largeur, $this->page_hauteur);
109 $this->marge_gauche = 0;
110 $this->marge_droite = 0;
111 $this->marge_haute = 0;
112 $this->marge_basse = 0;
113
114 $this->option_logo = 1; // Display logo
115 $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
116 $this->option_modereg = 0; // Display payment mode
117 $this->option_condreg = 0; // Display payment terms
118 $this->option_multilang = 0; // Available in several languages
119 $this->option_escompte = 0; // Displays if there has been a discount
120 $this->option_credit_note = 0; // Support credit notes
121 $this->option_freetext = 1; // Support add of a personalised text
122 $this->option_draft_watermark = 0; // Support add of a watermark on drafts
123
124 // Get source company
125 $this->emetteur = $mysoc;
126 if (!$this->emetteur->country_code) {
127 $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
128 }
129 }
130
131
132 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
141 public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
142 {
143 // phpcs:enable
144 global $extrafields;
145
146 if (!$object instanceof Project) {
147 dol_syslog("Expected Project object, got ".gettype($object), LOG_ERR);
148 return array();
149 }
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 $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 return array(
232 'projcontacts_id' => $contact['id'],
233 'projcontacts_rowid' => $contact['rowid'],
234 'projcontacts_role' => $contact['libelle'],
235 'projcontacts_lastname' => $contact['lastname'],
236 'projcontacts_firstname' => $contact['firstname'],
237 'projcontacts_fullcivname' => $contact['fullname'],
238 'projcontacts_socname' => $contact['socname'],
239 'projcontacts_email' => $contact['email']
240 );
241 }
242
243 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
251 public function get_substitutionarray_project_file($file, $outputlangs)
252 {
253 // phpcs:enable
254 return array(
255 'projfile_name' => $file['name'],
256 'projfile_date' => dol_print_date($file['date'], 'day'),
257 'projfile_size' => $file['size']
258 );
259 }
260
261 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
269 public function get_substitutionarray_project_reference($refdetail, $outputlangs)
270 {
271 // phpcs:enable
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($taskresource, $outputlangs)
292 {
293 // phpcs:enable
294
295 //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
296 return array(
297 'taskressource_rowid' => $taskresource['rowid'],
298 'taskressource_role' => $taskresource['libelle'],
299 'taskressource_lastname' => $taskresource['lastname'],
300 'taskressource_firstname' => $taskresource['firstname'],
301 'taskressource_fullcivname' => $taskresource['fullname'],
302 'taskressource_socname' => $taskresource['socname'],
303 'taskressource_email' => $taskresource['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['lastname'],
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 return array(
344 'tasksfile_name' => $file['name'],
345 'tasksfile_date' => dol_print_date($file['date'], 'day'),
346 'tasksfile_size' => $file['size']
347 );
348 }
349
350
357 public function info($langs)
358 {
359 global $conf, $langs;
360
361 // Load translation files required by the page
362 $langs->loadLangs(array("errors", "companies"));
363
364 $form = new Form($this->db);
365
366 $texte = $this->description.".<br>\n";
367 $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" enctype="multipart/form-data">';
368 $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
369 $texte .= '<input type="hidden" name="page_y" value="">';
370 $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
371 $texte .= '<input type="hidden" name="param1" value="PROJECT_TASK_ADDON_PDF_ODT_PATH">';
372 $texte .= '<table class="nobordernopadding centpercent">';
373
374 // List of directories area
375 $texte .= '<tr><td>';
376 $texttitle = $langs->trans("ListOfDirectories");
377 $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)));
378 $listoffiles = array();
379 foreach ($listofdir as $key => $tmpdir) {
380 $tmpdir = trim($tmpdir);
381 $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
382 if (!$tmpdir) {
383 unset($listofdir[$key]);
384 continue;
385 }
386 if (!is_dir($tmpdir)) {
387 $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
388 } else {
389 $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
390 if (count($tmpfiles)) {
391 $listoffiles = array_merge($listoffiles, $tmpfiles);
392 }
393 }
394 }
395 $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
396 $texthelp .= '<br><br><span class="opacitymedium">'.$langs->trans("ExampleOfDirectoriesForModelGen").'</span>';
397 // Add list of substitution keys
398 $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
399 $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
400
401 $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1, 3, $this->name);
402 $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
403 $texte .= '<textarea class="flat" cols="60" name="value1">';
404 $texte .= getDolGlobalString('PROJECT_TASK_ADDON_PDF_ODT_PATH');
405 $texte .= '</textarea>';
406 $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
407 $texte .= '<input type="submit" class="button button-edit reposition smallpaddingimp" name="modify" value="'.dol_escape_htmltag($langs->trans("Modify")).'">';
408 $texte .= '<br></div></div>';
409
410 // Scan directories
411 $nbofiles = count($listoffiles);
412 if (getDolGlobalString('PROJECT_TASK_ADDON_PDF_ODT_PATH')) {
413 $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
414 //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
415 $texte .= $nbofiles;
416 //$texte.=$nbofiles?'</a>':'';
417 $texte .= '</b>';
418 }
419
420 if ($nbofiles) {
421 $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
422 // Show list of found files
423 foreach ($listoffiles as $file) {
424 $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=tasks/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
425 $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>';
426 $texte .= '<br>';
427 }
428 $texte .= '</div>';
429 }
430 // Add input to upload a new template file.
431 $texte .= '<div>'.$langs->trans("UploadNewTemplate");
432 $maxfilesizearray = getMaxFileSizeArray();
433 $maxmin = $maxfilesizearray['maxmin'];
434 if ($maxmin > 0) {
435 $texte .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
436 }
437 $texte .= ' <input type="file" name="uploadfile">';
438 $texte .= '<input type="hidden" value="PROJECT_TASK_ADDON_PDF_ODT_PATH" name="keyforuploaddir">';
439 $texte .= '<input type="submit" class="button smallpaddingimp reposition" value="'.dol_escape_htmltag($langs->trans("Upload")).'" name="upload">';
440 $texte .= '</div>';
441 $texte .= '</td>';
442
443 $texte .= '</tr>';
444
445 $texte .= '</table>';
446 $texte .= '</form>';
447
448 return $texte;
449 }
450
451 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
460 public function write_file($object, $outputlangs, $srctemplatepath)
461 {
462 // phpcs:enable
463 global $user, $langs, $conf, $mysoc, $hookmanager;
464
465 if (empty($srctemplatepath)) {
466 dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
467 return -1;
468 }
469
470 if (!is_object($outputlangs)) {
471 $outputlangs = $langs;
472 }
473 $sav_charset_output = $outputlangs->charset_output;
474 $outputlangs->charset_output = 'UTF-8';
475
476 // Load translation files required by the page
477 $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
478
479 if ($conf->project->dir_output) {
480 // If $object is id instead of object
481 if (!is_object($object)) {
482 $id = $object;
483 $object = new Task($this->db);
484 $result = $object->fetch($id);
485 if ($result < 0) {
486 dol_print_error($this->db, $object->error);
487 return -1;
488 }
489 }
490 $project = new Project($this->db);
491 $project->fetch($object->fk_project);
492 $project->fetch_thirdparty();
493
494 $dir = $conf->project->dir_output."/".$project->ref."/";
495 $objectref = dol_sanitizeFileName($object->ref);
496 if (!preg_match('/specimen/i', $objectref)) {
497 $dir .= "/".$objectref;
498 }
499 $file = $dir."/".$objectref.".odt";
500
501 if (!file_exists($dir)) {
502 if (dol_mkdir($dir) < 0) {
503 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
504 return -1;
505 }
506 }
507
508
509 if (file_exists($dir)) {
510 //print "srctemplatepath=".$srctemplatepath; // Src filename
511 $newfile = basename($srctemplatepath);
512 $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
513 $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
514 $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
515 $newfiletmp = $objectref . '_' . $newfiletmp;
516 //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
517 $file = $dir . '/' . $newfiletmp . '.odt';
518 //print "newdir=".$dir;
519 //print "newfile=".$newfile;
520 //print "file=".$file;
521 //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
522
523 dol_mkdir($conf->project->dir_temp);
524 if (!is_writable($conf->project->dir_temp)) {
525 $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
526 dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
527 return -1;
528 }
529
530 $socobject = $project->thirdparty;
531
532 // Make substitution
533 $substitutionarray = array(
534 '__FROM_NAME__' => $this->emetteur->name,
535 '__FROM_EMAIL__' => $this->emetteur->email,
536 );
537 complete_substitutions_array($substitutionarray, $langs, $object);
538 // Call the ODTSubstitution hook
539 $tmparray = array();
540 $action = '';
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 $odfHandler->setVars($key, $value, true, 'UTF-8');
589 }
590 } catch (OdfException $e) {
591 dol_syslog($e->getMessage(), LOG_INFO);
592 }
593 }
594
595 // Replace tags of lines for tasks
596 try {
597 // Security check
598 $socid = 0;
599 if (!empty($project->fk_soc)) {
600 $socid = $project->fk_soc;
601 }
602
603 $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
604 complete_substitutions_array($tmparray, $outputlangs, $object);
605 foreach ($tmparray as $key => $val) {
606 try {
607 $odfHandler->setVars($key, $val, true, 'UTF-8');
608 } catch (OdfException $e) {
609 dol_syslog($e->getMessage(), LOG_INFO);
610 } catch (SegmentException $e) {
611 dol_syslog($e->getMessage(), LOG_INFO);
612 }
613 }
614
615 // Replace tags of lines for contacts task
616 $sourcearray = array('internal', 'external');
617 $contact_arrray = array();
618 foreach ($sourcearray as $source) {
619 $contact_temp = $object->liste_contact(-1, $source);
620 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
621 $contact_arrray = array_merge($contact_arrray, $contact_temp);
622 }
623 }
624 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
625 $listlinestaskres = $odfHandler->setSegment('tasksressources');
626
627 foreach ($contact_arrray as $contact) {
628 if ($contact['source'] == 'internal') {
629 $objectdetail = new User($this->db);
630 $objectdetail->fetch($contact['id']);
631 $contact['socname'] = $mysoc->name;
632 } elseif ($contact['source'] == 'external') {
633 $objectdetail = new Contact($this->db);
634 $objectdetail->fetch($contact['id']);
635
636 $soc = new Societe($this->db);
637 $soc->fetch($contact['socid']);
638 $contact['socname'] = $soc->name;
639 }
640 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
641
642 $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
643
644 foreach ($tmparray as $key => $val) {
645 try {
646 $listlinestaskres->setVars($key, $val, true, 'UTF-8');
647 } catch (OdfException $e) {
648 dol_syslog($e->getMessage(), LOG_INFO);
649 } catch (SegmentException $e) {
650 dol_syslog($e->getMessage(), LOG_INFO);
651 }
652 }
653 $listlinestaskres->merge();
654 }
655 $odfHandler->mergeSegment($listlinestaskres);
656 }
657
658 // Time resources
659 $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
660 $sql .= ", u.lastname, u.firstname";
661 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
662 $sql .= " , ".MAIN_DB_PREFIX."user as u";
663 $sql .= " WHERE t.fk_element =".((int) $object->id);
664 $sql .= " AND t.elementtype = 'task'";
665 $sql .= " AND t.fk_user = u.rowid";
666 $sql .= " ORDER BY t.element_date DESC";
667
668 $resql = $this->db->query($sql);
669 if ($resql) {
670 $num = $this->db->num_rows($resql);
671 $i = 0;
672 $tasks = array();
673 $listlinestasktime = $odfHandler->setSegment('taskstimes');
674 while ($i < $num) {
675 $row = $this->db->fetch_array($resql);
676 if (!empty($row['fk_user'])) {
677 $objectdetail = new User($this->db);
678 $objectdetail->fetch($row['fk_user']);
679 // TODO Use a cache to aoid fetch for same user
680 $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
681 } else {
682 $row['fullcivname'] = '';
683 }
684
685 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
686
687 foreach ($tmparray as $key => $val) {
688 try {
689 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
690 } catch (OdfException $e) {
691 dol_syslog($e->getMessage(), LOG_INFO);
692 } catch (SegmentException $e) {
693 dol_syslog($e->getMessage(), LOG_INFO);
694 }
695 }
696 $listlinestasktime->merge();
697 $i++;
698 }
699 $this->db->free($resql);
700
701 $odfHandler->mergeSegment($listlinestasktime);
702 }
703
704
705 // Replace tags of project files
706 $listtasksfiles = $odfHandler->setSegment('tasksfiles');
707
708 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
709 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
710
711
712 foreach ($filearray as $filedetail) {
713 $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
714 //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
715 foreach ($tmparray as $key => $val) {
716 try {
717 $listtasksfiles->setVars($key, $val, true, 'UTF-8');
718 } catch (OdfException $e) {
719 dol_syslog($e->getMessage(), LOG_INFO);
720 } catch (SegmentException $e) {
721 dol_syslog($e->getMessage(), LOG_INFO);
722 }
723 }
724 $listtasksfiles->merge();
725 }
726 //$listlines->merge();
727
728 $odfHandler->mergeSegment($listtasksfiles);
729 } catch (OdfException $e) {
730 $this->error = $e->getMessage();
731 dol_syslog($this->error, LOG_WARNING);
732 return -1;
733 }
734
735
736
737 // Replace tags of project files
738 try {
739 $listlines = $odfHandler->setSegment('projectfiles');
740
741 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
742 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
743
744
745 foreach ($filearray as $filedetail) {
746 //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
747 $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
748
749 foreach ($tmparray as $key => $val) {
750 try {
751 $listlines->setVars($key, $val, true, 'UTF-8');
752 } catch (OdfException $e) {
753 dol_syslog($e->getMessage(), LOG_INFO);
754 } catch (SegmentException $e) {
755 dol_syslog($e->getMessage(), LOG_INFO);
756 }
757 }
758 $listlines->merge();
759 }
760 $odfHandler->mergeSegment($listlines);
761 } catch (OdfException $e) {
762 $this->error = $e->getMessage();
763 dol_syslog($this->error, LOG_WARNING);
764 return -1;
765 }
766
767 // Replace tags of lines for contacts
768 $sourcearray = array('internal', 'external');
769 $contact_arrray = array();
770 foreach ($sourcearray as $source) {
771 $contact_temp = $project->liste_contact(-1, $source);
772 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
773 $contact_arrray = array_merge($contact_arrray, $contact_temp);
774 }
775 }
776 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
777 try {
778 $listlines = $odfHandler->setSegment('projectcontacts');
779
780 foreach ($contact_arrray as $contact) {
781 if ($contact['source'] == 'internal') {
782 $objectdetail = new User($this->db);
783 $objectdetail->fetch($contact['id']);
784 $contact['socname'] = $mysoc->name;
785 } elseif ($contact['source'] == 'external') {
786 $objectdetail = new Contact($this->db);
787 $objectdetail->fetch($contact['id']);
788
789 $soc = new Societe($this->db);
790 $soc->fetch($contact['socid']);
791 $contact['socname'] = $soc->name;
792 }
793 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
794
795 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
796
797 foreach ($tmparray as $key => $val) {
798 try {
799 $listlines->setVars($key, $val, true, 'UTF-8');
800 } catch (OdfException $e) {
801 dol_syslog($e->getMessage(), LOG_INFO);
802 } catch (SegmentException $e) {
803 dol_syslog($e->getMessage(), LOG_INFO);
804 }
805 }
806 $listlines->merge();
807 }
808 $odfHandler->mergeSegment($listlines);
809 } catch (OdfException $e) {
810 $this->error = $e->getMessage();
811 dol_syslog($this->error, LOG_WARNING);
812 return -1;
813 }
814 }
815
816
817 // Call the beforeODTSave hook
818 $parameters = array('odfHandler' => &$odfHandler, 'file' => $file, 'object' => $object, 'outputlangs' => $outputlangs, 'substitutionarray' => &$tmparray);
819 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
820
821
822 // Write new file
823 if (getDolGlobalString('MAIN_ODT_AS_PDF')) {
824 try {
825 $odfHandler->exportAsAttachedPDF($file);
826 } catch (Exception $e) {
827 $this->error = $e->getMessage();
828 dol_syslog($e->getMessage(), LOG_INFO);
829 return -1;
830 }
831 } else {
832 try {
833 $odfHandler->saveToDisk($file);
834 } catch (Exception $e) {
835 $this->error = $e->getMessage();
836 dol_syslog($e->getMessage(), LOG_INFO);
837 return -1;
838 }
839 }
840 $parameters = array('odfHandler' => &$odfHandler, 'file' => $file, 'object' => $object, 'outputlangs' => $outputlangs, 'substitutionarray' => &$tmparray);
841 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
842
843 dolChmod($file);
844
845 $odfHandler = null; // Destroy object
846
847 $this->result = array('fullpath' => $file);
848
849 return 1; // Success
850 } else {
851 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
852 return -1;
853 }
854 }
855
856 return -1;
857 }
858}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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 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_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.
get_substitutionarray_tasksressource($taskresource, $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($utf8_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:63
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
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.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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:139
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:142
getMaxFileSizeArray()
Return the max allowed for file upload.