dolibarr 18.0.6
doc_generic_project_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-2023 Charlene Benke <charlene@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.'/projet/class/project.class.php';
32require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
33require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
34require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
35require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41if (isModEnabled("propal")) {
42 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
43}
44if (isModEnabled('facture')) {
45 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
46}
47if (isModEnabled('facture')) {
48 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
49}
50if (isModEnabled('commande')) {
51 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
52}
53if (isModEnabled("supplier_invoice")) {
54 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55}
56if (isModEnabled("supplier_order")) {
57 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
58}
59if (isModEnabled('contrat')) {
60 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
61}
62if (isModEnabled('ficheinter')) {
63 require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
64}
65if (isModEnabled('deplacement')) {
66 require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
67}
68if (isModEnabled('agenda')) {
69 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
70}
71if (isModEnabled('expedition')) {
72 require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
73}
74
79{
84 public $emetteur;
85
90 public $version = 'dolibarr';
91
92
98 public function __construct($db)
99 {
100 global $conf, $langs, $mysoc;
101
102 // Load traductions files required by page
103 $langs->loadLangs(array("companies", "main"));
104
105 $this->db = $db;
106 $this->name = "ODT templates";
107 $this->description = $langs->trans("DocumentModelOdt");
108 $this->scandir = 'PROJECT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
109
110 // Page size for A4 format
111 $this->type = 'odt';
112 $this->page_largeur = 0;
113 $this->page_hauteur = 0;
114 $this->format = array($this->page_largeur, $this->page_hauteur);
115 $this->marge_gauche = 0;
116 $this->marge_droite = 0;
117 $this->marge_haute = 0;
118 $this->marge_basse = 0;
119
120 $this->option_logo = 1; // Display logo
121 $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
122 $this->option_modereg = 0; // Display payment mode
123 $this->option_condreg = 0; // Display payment terms
124 $this->option_multilang = 1; // Available in several languages
125 $this->option_escompte = 0; // Displays if there has been a discount
126 $this->option_credit_note = 0; // Support credit notes
127 $this->option_freetext = 1; // Support add of a personalised text
128 $this->option_draft_watermark = 0; // Support add of a watermark on drafts
129
130 // Get source company
131 $this->emetteur = $mysoc;
132 if (!$this->emetteur->country_code) {
133 $this->emetteur->country_code = substr($langs->defaultlang, -2); // Par defaut, si n'etait pas defini
134 }
135 }
136
137
138 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
147 public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
148 {
149 // phpcs:enable
150 global $conf;
151
152 $resarray = array(
153 $array_key.'_id'=>$object->id,
154 $array_key.'_ref'=>$object->ref,
155 $array_key.'_title'=>$object->title,
156 $array_key.'_description'=>$object->description,
157 $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
158 $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
159 $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
160 $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
161 $array_key.'_note_private'=>$object->note_private,
162 $array_key.'_note_public'=>$object->note_public,
163 $array_key.'_public'=>$object->public,
164 $array_key.'_statut'=>$object->getLibStatut()
165 );
166
167 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
168 $extrafields = new ExtraFields($this->db);
169 $extrafields->fetch_name_optionals_label($object->table_element, true);
170 $object->fetch_optionals();
171
172 $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
173
174 return $resarray;
175 }
176
177 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
185 public function get_substitutionarray_tasks(Task $task, $outputlangs)
186 {
187 // phpcs:enable
188 $resarray = array(
189 'task_ref'=>$task->ref,
190 'task_fk_project'=>$task->fk_project,
191 'task_projectref'=>$task->projectref,
192 'task_projectlabel'=>$task->projectlabel,
193 'task_label'=>$task->label,
194 'task_description'=>$task->description,
195 'task_fk_parent'=>$task->fk_task_parent,
196 'task_duration'=>$task->duration,
197 'task_duration_hour'=>convertSecondToTime($task->duration, 'all'),
198 'task_planned_workload'=>$task->planned_workload,
199 'task_planned_workload_hour'=>convertSecondToTime($task->planned_workload, 'all'),
200 'task_progress'=>$task->progress,
201 'task_public'=>$task->public,
202 'task_date_start'=>dol_print_date($task->date_start, 'day'),
203 'task_date_end'=>dol_print_date($task->date_end, 'day'),
204 'task_note_private'=>$task->note_private,
205 'task_note_public'=>$task->note_public
206 );
207
208 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
209 $extrafields = new ExtraFields($this->db);
210 $extrafields->fetch_name_optionals_label($task->table_element, true);
211 $task->fetch_optionals();
212
213 $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, 'task', $outputlangs);
214
215 return $resarray;
216 }
217
218 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
226 public function get_substitutionarray_project_contacts($contact, $outputlangs)
227 {
228 // phpcs:enable
229 global $conf;
230 $pc = 'projcontacts_'; // prefix to avoid typos
231
232 $ret = array(
233 $pc.'id'=>$contact['id'],
234 $pc.'rowid'=>$contact['rowid'],
235 $pc.'role'=>$contact['libelle'],
236 $pc.'lastname'=>$contact['lastname'],
237 $pc.'firstname'=>$contact['firstname'],
238 $pc.'civility'=>$contact['civility'],
239 $pc.'fullcivname'=>$contact['fullname'],
240 $pc.'socname'=>$contact['socname'],
241 $pc.'email'=>$contact['email']
242 );
243
244 if ($contact['source'] == 'external') {
245 $ret[$pc.'isInternal'] = ''; // not internal
246
247 $ct = new Contact($this->db);
248 $ct->fetch($contact['id']);
249 $ret[$pc.'phone_pro'] = $ct->phone_pro;
250 $ret[$pc.'phone_perso'] = $ct->phone_perso;
251 $ret[$pc.'phone_mobile'] = $ct->phone_mobile;
252
253 // fetch external user extrafields
254 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
255 $extrafields = new ExtraFields($this->db);
256 $extrafields->fetch_name_optionals_label($ct->table_element, true);
257 $extrafields_num = $ct->fetch_optionals();
258 //dol_syslog(get_class($this)."::get_substitutionarray_project_contacts: ===== Number of Extrafields found: ".$extrafields_num, LOG_DEBUG);
259 foreach ($ct->array_options as $efkey => $efval) {
260 dol_syslog(get_class($this)."::get_substitutionarray_project_contacts: +++++ Extrafield ".$efkey." => ".$efval, LOG_DEBUG);
261 $ret[$pc.$efkey] = $efval; // add nothing else because it already comes as 'options_XX'
262 }
263 } elseif ($contact['source'] == 'internal') {
264 $ret[$pc.'isInternal'] = '1'; // this is an internal user
265
266 $ct = new User($this->db);
267 $ct->fetch($contact['id']);
268 $ret[$pc.'phone_pro'] = $ct->office_phone;
269 $ret[$pc.'phone_perso'] = '';
270 $ret[$pc.'phone_mobile'] = $ct->user_mobile;
271 // do internal users have extrafields ?
272 }
273 return $ret;
274 }
275
276 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
284 public function get_substitutionarray_project_file($file, $outputlangs)
285 {
286 // phpcs:enable
287 global $conf;
288
289 return array(
290 'projfile_name'=>$file['name'],
291 'projfile_date'=>dol_print_date($file['date'], 'day'),
292 'projfile_size'=>$file['size']
293 );
294 }
295
296 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
304 public function get_substitutionarray_project_reference($refdetail, $outputlangs)
305 {
306 // phpcs:enable
307 global $conf;
308
309 return array(
310 'projref_type'=>$refdetail['type'],
311 'projref_ref'=>$refdetail['ref'],
312 'projref_date'=>dol_print_date($refdetail['date'], 'day'),
313 'projref_socname'=>$refdetail['socname'],
314 'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
315 'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
316 'projref_status'=>$refdetail['status']
317 );
318 }
319
320 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
328 public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
329 {
330 // phpcs:enable
331 global $conf;
332 //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
333 return array(
334 'taskressource_rowid'=>$taskressource['rowid'],
335 'taskressource_role'=>$taskressource['libelle'],
336 'taskressource_lastname'=>$taskressource['lastname'],
337 'taskressource_firstname'=>$taskressource['firstname'],
338 'taskressource_fullcivname'=>$taskressource['fullname'],
339 'taskressource_socname'=>$taskressource['socname'],
340 'taskressource_email'=>$taskressource['email']
341 );
342 }
343
344 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
352 public function get_substitutionarray_taskstime($tasktime, $outputlangs)
353 {
354 // phpcs:enable
355 global $conf;
356
357 return array(
358 'tasktime_rowid'=>$tasktime['rowid'],
359 'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
360 'tasktime_task_duration_sec'=>$tasktime['task_duration'],
361 'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
362 'tasktime_note'=>$tasktime['note'],
363 'tasktime_fk_user'=>$tasktime['fk_user'],
364 'tasktime_user_name'=>$tasktime['name'],
365 'tasktime_user_first'=>$tasktime['firstname'],
366 'tasktime_fullcivname'=>$tasktime['fullcivname'],
367 'tasktime_amountht'=>$tasktime['amountht'],
368 'tasktime_amountttc'=>$tasktime['amountttc'],
369 'tasktime_thm'=>$tasktime['thm'],
370 );
371 }
372
373 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
381 public function get_substitutionarray_task_file($file, $outputlangs)
382 {
383 // phpcs:enable
384 global $conf;
385
386 return array(
387 'tasksfile_name'=>$file['name'],
388 'tasksfile_date'=>dol_print_date($file['date'], 'day'),
389 'tasksfile_size'=>$file['size']
390 );
391 }
392
393
400 public function info($langs)
401 {
402 global $conf, $langs;
403
404 // Load translation files required by the page
405 $langs->loadLangs(array("companies", "errors"));
406
407 $form = new Form($this->db);
408
409 $texte = $this->description.".<br>\n";
410 $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
411 $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
412 $texte .= '<input type="hidden" name="page_y" value="">';
413 $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
414 $texte .= '<input type="hidden" name="param1" value="PROJECT_ADDON_PDF_ODT_PATH">';
415 $texte .= '<table class="nobordernopadding" width="100%">';
416
417 // List of directories area
418 $texte .= '<tr><td>';
419 $texttitle = $langs->trans("ListOfDirectories");
420 $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_ADDON_PDF_ODT_PATH)));
421 $listoffiles = array();
422 foreach ($listofdir as $key => $tmpdir) {
423 $tmpdir = trim($tmpdir);
424 $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
425 if (!$tmpdir) {
426 unset($listofdir[$key]);
427 continue;
428 }
429 if (!is_dir($tmpdir)) {
430 $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
431 } else {
432 $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
433 if (count($tmpfiles)) {
434 $listoffiles = array_merge($listoffiles, $tmpfiles);
435 }
436 }
437 }
438 $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
439 // Add list of substitution keys
440 $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
441 $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
442
443 $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
444 $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
445 $texte .= '<textarea class="flat" cols="60" name="value1">';
446 $texte .= $conf->global->PROJECT_ADDON_PDF_ODT_PATH;
447 $texte .= '</textarea>';
448 $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
449 $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.$langs->trans("Modify").'">';
450 $texte .= '<br></div></div>';
451
452 // Scan directories
453 $nbofiles = count($listoffiles);
454 if (!empty($conf->global->PROJECT_ADDON_PDF_ODT_PATH)) {
455 $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
456 //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
457 $texte .= $nbofiles;
458 //$texte.=$nbofiles?'</a>':'';
459 $texte .= '</b>';
460 }
461
462 if ($nbofiles) {
463 $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
464 // Show list of found files
465 foreach ($listoffiles as $file) {
466 $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=projects/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
467 $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=PROJECT_ADDON_PDF_ODT_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
468 $texte .= '<br>';
469 }
470 $texte .= '</div>';
471 }
472
473 $texte .= '</td>';
474
475 $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
476 $texte .= '<span class="opacitymedium">';
477 $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
478 $texte .= '</span>';
479 $texte .= '</td>';
480 $texte .= '</tr>';
481
482 $texte .= '</table>';
483 $texte .= '</form>';
484
485 return $texte;
486 }
487
488 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
497 public function write_file($object, $outputlangs, $srctemplatepath)
498 {
499 // phpcs:enable
500 global $user, $langs, $conf, $mysoc, $hookmanager;
501
502 if (empty($srctemplatepath)) {
503 dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
504 return -1;
505 }
506
507 // Add odtgeneration hook
508 if (!is_object($hookmanager)) {
509 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
510 $hookmanager = new HookManager($this->db);
511 }
512 $hookmanager->initHooks(array('odtgeneration'));
513 global $action;
514
515 if (!is_object($outputlangs)) {
516 $outputlangs = $langs;
517 }
518 $sav_charset_output = $outputlangs->charset_output;
519 $outputlangs->charset_output = 'UTF-8';
520
521 // Load translation files required by the page
522 $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
523
524 if ($conf->project->dir_output) {
525 // If $object is id instead of object
526 if (!is_object($object)) {
527 $id = $object;
528 $object = new Project($this->db);
529 $result = $object->fetch($id);
530 if ($result < 0) {
531 dol_print_error($this->db, $object->error);
532 return -1;
533 }
534 }
535
536 $object->fetch_thirdparty();
537
538 $dir = $conf->project->dir_output;
539 $objectref = dol_sanitizeFileName($object->ref);
540 if (!preg_match('/specimen/i', $objectref)) {
541 $dir .= "/".$objectref;
542 }
543 $file = $dir."/".$objectref.".odt";
544
545 if (!file_exists($dir)) {
546 if (dol_mkdir($dir) < 0) {
547 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
548 return -1;
549 }
550 }
551
552 if (file_exists($dir)) {
553 //print "srctemplatepath=".$srctemplatepath; // Src filename
554 $newfile = basename($srctemplatepath);
555 $newfiletmp = preg_replace('/\.od[ts]/i', '', $newfile);
556 $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
557 $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
558 $newfiletmp = $objectref . '_' . $newfiletmp;
559 //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
560 // Get extension (ods or odt)
561 $newfileformat = substr($newfile, strrpos($newfile, '.') + 1);
562 if (getDolGlobalString('MAIN_DOC_USE_TIMING')) {
563 $format = getDolGlobalString('MAIN_DOC_USE_TIMING');
564 if ($format == '1') {
565 $format = '%Y%m%d%H%M%S';
566 }
567 $filename = $newfiletmp . '-' . dol_print_date(dol_now(), $format) . '.' . $newfileformat;
568 } else {
569 $filename = $newfiletmp . '.' . $newfileformat;
570 }
571 $file = $dir . '/' . $filename;
572 //print "newdir=".$dir;
573 //print "newfile=".$newfile;
574 //print "file=".$file;
575 //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
576
577 dol_mkdir($conf->project->dir_temp);
578 if (!is_writable($conf->project->dir_temp)) {
579 $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
580 dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
581 return -1;
582 }
583
584 // If PROJECTLEADER contact defined on project, we use it
585 $usecontact = false;
586 $arrayidcontact = $object->getIdContact('external', 'PROJECTLEADER');
587 if (count($arrayidcontact) > 0) {
588 $usecontact = true;
589 $result = $object->fetch_contact($arrayidcontact[0]);
590 }
591
592 // Recipient name
593 $contactobject = null;
594 if (!empty($usecontact)) {
595 // if we have a PROJECTLEADER contact and we dont use it as recipient we store the contact object for later use
596 $contactobject = $object->contact;
597 }
598
599 $socobject = $object->thirdparty;
600
601 // Make substitution
602 $substitutionarray = array(
603 '__FROM_NAME__' => $this->emetteur->name,
604 '__FROM_EMAIL__' => $this->emetteur->email,
605 );
606 complete_substitutions_array($substitutionarray, $langs, $object);
607 // Call the ODTSubstitution hook
608 $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$substitutionarray);
609 $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
610
611 // Open and load template
612 require_once ODTPHP_PATH.'odf.php';
613 try {
614 $odfHandler = new Odf(
615 $srctemplatepath,
616 array(
617 'PATH_TO_TMP' => $conf->project->dir_temp,
618 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
619 'DELIMITER_LEFT' => '{',
620 'DELIMITER_RIGHT' => '}'
621 )
622 );
623 } catch (Exception $e) {
624 $this->error = $e->getMessage();
625 dol_syslog($e->getMessage(), LOG_INFO);
626 return -1;
627 }
628 // After construction $odfHandler->contentXml contains content and
629 // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
630 // [!-- BEGIN lines --]*[!-- END lines --]
631 //print html_entity_decode($odfHandler->__toString());
632 //print exit;
633
634
635 // Define substitution array
636 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
637 $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
638 $array_objet = $this->get_substitutionarray_object($object, $outputlangs);
639 $array_user = $this->get_substitutionarray_user($user, $outputlangs);
640 $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
641 $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
642 $array_other = $this->get_substitutionarray_other($outputlangs);
643 // retrieve contact information for use in object as contact_xxx tags
644 $array_project_contact = array();
645 if ($usecontact && is_object($contactobject)) {
646 $array_project_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact');
647 }
648
649 $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_project_contact);
650 complete_substitutions_array($tmparray, $outputlangs, $object);
651
652 // Call the ODTSubstitution hook
653 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
654 $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
655
656 foreach ($tmparray as $key => $value) {
657 try {
658 if (preg_match('/logo$/', $key)) { // Image
659 if (file_exists($value)) {
660 $odfHandler->setImage($key, $value);
661 } else {
662 $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
663 }
664 } else // Text
665 {
666 $odfHandler->setVars($key, $value, true, 'UTF-8');
667 }
668 } catch (OdfException $e) {
669 dol_syslog($e->getMessage(), LOG_INFO);
670 }
671 }
672
673 // Replace tags of lines for tasks
674 try {
675 $listlines = $odfHandler->setSegment('tasks');
676
677 $taskstatic = new Task($this->db);
678
679 // Security check
680 $socid = 0;
681 if (!empty($object->fk_soc)) {
682 $socid = $object->fk_soc;
683 }
684
685 $tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $socid, 0);
686
687
688 foreach ($tasksarray as $task) {
689 $tmparray = $this->get_substitutionarray_tasks($task, $outputlangs);
690 //complete_substitutions_array($tmparray, $outputlangs, $object, $task, "completesubstitutionarray_lines");
691 foreach ($tmparray as $key => $val) {
692 try {
693 $listlines->setVars($key, $val, true, 'UTF-8');
694 } catch (OdfException $e) {
695 dol_syslog($e->getMessage(), LOG_INFO);
696 } catch (SegmentException $e) {
697 dol_syslog($e->getMessage(), LOG_INFO);
698 }
699 }
700
701 $taskobj = new Task($this->db);
702 $taskobj->fetch($task->id);
703
704 // Replace tags of lines for contacts task
705 $sourcearray = array('internal', 'external');
706 $contact_arrray = array();
707 foreach ($sourcearray as $source) {
708 $contact_temp = $taskobj->liste_contact(-1, $source);
709 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
710 $contact_arrray = array_merge($contact_arrray, $contact_temp);
711 }
712 }
713 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
714 $listlinestaskres = $listlines->__get('tasksressources');
715
716 foreach ($contact_arrray as $contact) {
717 if ($contact['source'] == 'internal') {
718 $objectdetail = new User($this->db);
719 $objectdetail->fetch($contact['id']);
720 $contact['socname'] = $mysoc->name;
721 } elseif ($contact['source'] == 'external') {
722 $objectdetail = new Contact($this->db);
723 $objectdetail->fetch($contact['id']);
724
725 $soc = new Societe($this->db);
726 $soc->fetch($contact['socid']);
727 $contact['socname'] = $soc->name;
728 }
729 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
730
731 $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
732
733 foreach ($tmparray as $key => $val) {
734 try {
735 $listlinestaskres->setVars($key, $val, true, 'UTF-8');
736 } catch (OdfException $e) {
737 dol_syslog($e->getMessage(), LOG_INFO);
738 } catch (SegmentException $e) {
739 dol_syslog($e->getMessage(), LOG_INFO);
740 }
741 }
742 $listlinestaskres->merge();
743 }
744 }
745
746 //Time ressources
747 $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
748 $sql .= ", u.lastname, u.firstname, t.thm";
749 $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
750 $sql .= " , ".MAIN_DB_PREFIX."user as u";
751 $sql .= " WHERE t.fk_element =".((int) $task->id);
752 $sql .= " AND t.elementtype = 'task'";
753 $sql .= " AND t.fk_user = u.rowid";
754 $sql .= " ORDER BY t.element_date DESC";
755
756 $resql = $this->db->query($sql);
757 if ($resql) {
758 $num = $this->db->num_rows($resql);
759 $i = 0;
760 $tasks = array();
761 $row = array();
762 $listlinestasktime = $listlines->__get('taskstimes');
763 if (empty($num)) {
764 $row['rowid'] = '';
765 $row['task_date'] = '';
766 $row['task_duration'] = '';
767 $row['$tasktime'] = '';
768 $row['note'] = '';
769 $row['fk_user'] = '';
770 $row['name'] = '';
771 $row['firstname'] = '';
772 $row['fullcivname'] = '';
773 $row['amountht'] = '';
774 $row['amountttc'] = '';
775 $row['thm'] = '';
776 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
777 foreach ($tmparray as $key => $val) {
778 try {
779 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
780 } catch (OdfException $e) {
781 dol_syslog($e->getMessage(), LOG_INFO);
782 } catch (SegmentException $e) {
783 dol_syslog($e->getMessage(), LOG_INFO);
784 }
785 }
786 $listlinestasktime->merge();
787 }
788 while ($i < $num) {
789 $row = $this->db->fetch_array($resql);
790 if (!empty($row['fk_user'])) {
791 $objectdetail = new User($this->db);
792 $objectdetail->fetch($row['fk_user']);
793 $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
794 } else {
795 $row['fullcivname'] = '';
796 }
797
798 if (!empty($row['thm'])) {
799 $row['amountht'] = ($row['task_duration'] / 3600) * $row['thm'];
800 $defaultvat = get_default_tva($mysoc, $mysoc);
801 $row['amountttc'] = price2num($row['amountht'] * (1 + ($defaultvat / 100)), 'MT');
802 } else {
803 $row['amountht'] = 0;
804 $row['amountttc'] = 0;
805 $row['thm'] = 0;
806 }
807
808 $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
809
810 foreach ($tmparray as $key => $val) {
811 try {
812 $listlinestasktime->setVars($key, $val, true, 'UTF-8');
813 } catch (OdfException $e) {
814 dol_syslog($e->getMessage(), LOG_INFO);
815 } catch (SegmentException $e) {
816 dol_syslog($e->getMessage(), LOG_INFO);
817 }
818 }
819 $listlinestasktime->merge();
820 $i++;
821 }
822 $this->db->free($resql);
823 }
824
825
826 // Replace tags of project files
827 $listtasksfiles = $listlines->__get('tasksfiles');
828
829 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref).'/'.dol_sanitizeFileName($task->ref);
830 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
831
832
833 foreach ($filearray as $filedetail) {
834 $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
835 //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
836 foreach ($tmparray as $key => $val) {
837 try {
838 $listtasksfiles->setVars($key, $val, true, 'UTF-8');
839 } catch (OdfException $e) {
840 dol_syslog($e->getMessage(), LOG_INFO);
841 } catch (SegmentException $e) {
842 dol_syslog($e->getMessage(), LOG_INFO);
843 }
844 }
845 $listtasksfiles->merge();
846 }
847 $listlines->merge();
848 }
849 $odfHandler->mergeSegment($listlines);
850 } catch (OdfException $e) {
851 $ExceptionTrace = $e->getTrace();
852 // no segment defined on ODT is not an error
853 if ($ExceptionTrace[0]['function'] != 'setSegment') {
854 $this->error = $e->getMessage();
855 dol_syslog($this->error, LOG_WARNING);
856 return -1;
857 }
858 }
859
860 // Replace tags of project files
861 try {
862 $listlines = $odfHandler->setSegment('projectfiles');
863
864 $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
865 $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
866
867 foreach ($filearray as $filedetail) {
868 //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
869 $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
870
871 foreach ($tmparray as $key => $val) {
872 try {
873 $listlines->setVars($key, $val, true, 'UTF-8');
874 } catch (OdfException $e) {
875 dol_syslog($e->getMessage(), LOG_INFO);
876 } catch (SegmentException $e) {
877 dol_syslog($e->getMessage(), LOG_INFO);
878 }
879 }
880 $listlines->merge();
881 }
882 $odfHandler->mergeSegment($listlines);
883 } catch (OdfException $e) {
884 $this->error = $e->getMessage();
885 dol_syslog($this->error, LOG_WARNING);
886 return -1;
887 }
888
889 // Replace tags of lines for contacts
890 $sourcearray = array('internal', 'external');
891 $contact_arrray = array();
892 foreach ($sourcearray as $source) {
893 $contact_temp = $object->liste_contact(-1, $source);
894 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
895 $contact_arrray = array_merge($contact_arrray, $contact_temp);
896 }
897 }
898 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
899 try {
900 $listlines = $odfHandler->setSegment('projectcontacts');
901
902 foreach ($contact_arrray as $contact) {
903 if ($contact['source'] == 'internal') {
904 $objectdetail = new User($this->db);
905 $objectdetail->fetch($contact['id']);
906 $contact['socname'] = $mysoc->name;
907 } elseif ($contact['source'] == 'external') {
908 $objectdetail = new Contact($this->db);
909 $objectdetail->fetch($contact['id']);
910
911 $soc = new Societe($this->db);
912 $soc->fetch($contact['socid']);
913 $contact['socname'] = $soc->name;
914 }
915 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
916
917 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
918 foreach ($tmparray as $key => $val) {
919 try {
920 $listlines->setVars($key, $val, true, 'UTF-8');
921 } catch (OdfException $e) {
922 dol_syslog($e->getMessage(), LOG_INFO);
923 } catch (SegmentException $e) {
924 dol_syslog($e->getMessage(), LOG_INFO);
925 }
926 }
927 $listlines->merge();
928 }
929 $odfHandler->mergeSegment($listlines);
930 } catch (OdfException $e) {
931 $this->error = $e->getMessage();
932 dol_syslog($this->error, LOG_WARNING);
933 return -1;
934 }
935 }
936
937 //List of referent
938
939 $listofreferent = array(
940 'propal' => array(
941 'title' => "ListProposalsAssociatedProject",
942 'class' => 'Propal',
943 'table' => 'propal',
944 'test' => isModEnabled('propal') && $user->hasRight('propal', 'lire')
945 ),
946 'order' => array(
947 'title' => "ListOrdersAssociatedProject",
948 'class' => 'Commande',
949 'table' => 'commande',
950 'test' => isModEnabled('commande') && $user->hasRight('commande', 'lire')
951 ),
952 'invoice' => array(
953 'title' => "ListInvoicesAssociatedProject",
954 'class' => 'Facture',
955 'table' => 'facture',
956 'test' => isModEnabled('facture') && $user->hasRight('facture', 'lire')
957 ),
958 'invoice_predefined' => array(
959 'title' => "ListPredefinedInvoicesAssociatedProject",
960 'class' => 'FactureRec',
961 'table' => 'facture_rec',
962 'test' => isModEnabled('facture') && $user->hasRight('facture', 'lire')
963 ),
964 'proposal_supplier' => array(
965 'title' => "ListSupplierProposalsAssociatedProject",
966 'class' => 'SupplierProposal',
967 'table' => 'supplier_proposal',
968 'test' => isModEnabled('supplier_proposal') && $user->rights->supplier_proposal->lire
969 ),
970 'order_supplier' => array(
971 'title' => "ListSupplierOrdersAssociatedProject",
972 'table' => 'commande_fournisseur',
973 'class' => 'CommandeFournisseur',
974 'test' => (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (isModEnabled("supplier_order") && $user->rights->supplier_order->lire)
975 ),
976 'invoice_supplier' => array(
977 'title' => "ListSupplierInvoicesAssociatedProject",
978 'table' => 'facture_fourn',
979 'class' => 'FactureFournisseur',
980 'test' => (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled("supplier_invoice") && $user->rights->supplier_invoice->lire)
981 ),
982 'contract' => array(
983 'title' => "ListContractAssociatedProject",
984 'class' => 'Contrat',
985 'table' => 'contrat',
986 'test' => isModEnabled('contrat') && $user->hasRight('contrat', 'lire')
987 ),
988 'intervention' => array(
989 'title' => "ListFichinterAssociatedProject",
990 'class' => 'Fichinter',
991 'table' => 'fichinter',
992 'disableamount' => 1,
993 'test' => isModEnabled('ficheinter') && $user->hasRight('ficheinter', 'lire')
994 ),
995 'shipping' => array(
996 'title' => "ListShippingAssociatedProject",
997 'class' => 'Expedition',
998 'table' => 'expedition',
999 'disableamount' => 1,
1000 'test' => isModEnabled('expedition') && $user->rights->expedition->lire
1001 ),
1002 'trip' => array(
1003 'title' => "ListTripAssociatedProject",
1004 'class' => 'Deplacement',
1005 'table' => 'deplacement',
1006 'disableamount' => 1,
1007 'test' => isModEnabled('deplacement') && $user->rights->deplacement->lire
1008 ),
1009 'expensereport' => array(
1010 'title' => "ListExpenseReportsAssociatedProject",
1011 'class' => 'ExpenseReportLine',
1012 'table' => 'expensereport_det',
1013 'test' => isModEnabled('expensereport') && $user->rights->expensereport->lire
1014 ),
1015 'donation' => array(
1016 'title' => "ListDonationsAssociatedProject",
1017 'class' => 'Don',
1018 'table' => 'don',
1019 'test' => isModEnabled('don') && $user->rights->don->lire
1020 ),
1021 'loan' => array(
1022 'title' => "ListLoanAssociatedProject",
1023 'class' => 'Loan',
1024 'table' => 'loan',
1025 'test' => isModEnabled('loan') && $user->rights->loan->read
1026 ),
1027 'chargesociales' => array(
1028 'title' => "ListSocialContributionAssociatedProject",
1029 'class' => 'ChargeSociales',
1030 'table' => 'chargesociales',
1031 'urlnew' => DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$object->id,
1032 'test' => isModEnabled('tax') && $user->rights->tax->charges->lire
1033 ),
1034 'stock_mouvement' => array(
1035 'title' => "ListMouvementStockProject",
1036 'class' => 'MouvementStock',
1037 'table' => 'stock_mouvement',
1038 'test' => (isModEnabled('stock') && $user->rights->stock->mouvement->lire && !empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))
1039 ),
1040 'agenda' => array(
1041 'title' => "ListActionsAssociatedProject",
1042 'class' => 'ActionComm',
1043 'table' => 'actioncomm',
1044 'disableamount' => 1,
1045 'test' => isModEnabled('agenda') && $user->rights->agenda->allactions->lire
1046 ),
1047 );
1048
1049 //Insert reference
1050 try {
1051 $listlines = $odfHandler->setSegment('projectrefs');
1052
1053 foreach ($listofreferent as $keyref => $valueref) {
1054 $title = $valueref['title'];
1055 $tablename = $valueref['table'];
1056 $classname = $valueref['class'];
1057 $qualified = $valueref['test'];
1058 if ($qualified) {
1059 $elementarray = $object->get_element_list($keyref, $tablename);
1060 if (count($elementarray) > 0 && is_array($elementarray)) {
1061 $total_ht = 0;
1062 $total_ttc = 0;
1063 $num = count($elementarray);
1064 for ($i = 0; $i < $num; $i++) {
1065 $ref_array = array();
1066 $ref_array['type'] = $langs->trans($classname);
1067
1068 $element = new $classname($this->db);
1069 $element->fetch($elementarray[$i]);
1070 $element->fetch_thirdparty();
1071
1072 //Ref object
1073 $ref_array['ref'] = $element->ref;
1074
1075 //Date object
1076 $dateref = $element->date;
1077 if (empty($dateref)) {
1078 $dateref = $element->datep;
1079 }
1080 if (empty($dateref)) {
1081 $dateref = $element->date_contrat;
1082 }
1083 $ref_array['date'] = $dateref;
1084
1085 //Soc object
1086 if (is_object($element->thirdparty)) {
1087 $ref_array['socname'] = $element->thirdparty->name;
1088 } else {
1089 $ref_array['socname'] = '';
1090 }
1091
1092 //Amount object
1093 if (empty($valueref['disableamount'])) {
1094 if (!empty($element->total_ht)) {
1095 $ref_array['amountht'] = $element->total_ht;
1096 $ref_array['amountttc'] = $element->total_ttc;
1097 } else {
1098 $ref_array['amountht'] = 0;
1099 $ref_array['amountttc'] = 0;
1100 }
1101 } else {
1102 $ref_array['amountht'] = '';
1103 $ref_array['amountttc'] = '';
1104 }
1105
1106 $ref_array['status'] = $element->getLibStatut(0);
1107
1108 $tmparray = $this->get_substitutionarray_project_reference($ref_array, $outputlangs);
1109
1110 foreach ($tmparray as $key => $val) {
1111 try {
1112 $listlines->setVars($key, $val, true, 'UTF-8');
1113 } catch (OdfException $e) {
1114 dol_syslog($e->getMessage(), LOG_INFO);
1115 } catch (SegmentException $e) {
1116 dol_syslog($e->getMessage(), LOG_INFO);
1117 }
1118 }
1119 $listlines->merge();
1120 }
1121 }
1122 }
1123 $odfHandler->mergeSegment($listlines);
1124 }
1125 } catch (OdfException $e) {
1126 $this->error = $e->getMessage();
1127 dol_syslog($this->error, LOG_WARNING);
1128 return -1;
1129 }
1130
1131 // Replace labels translated
1132 $tmparray = $outputlangs->get_translations_for_substitutions();
1133 foreach ($tmparray as $key => $value) {
1134 try {
1135 $odfHandler->setVars($key, $value, true, 'UTF-8');
1136 } catch (OdfException $e) {
1137 dol_syslog($e->getMessage(), LOG_INFO);
1138 }
1139 }
1140
1141 // Call the beforeODTSave hook
1142 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
1143 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1144
1145
1146 // Write new file
1147 if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
1148 try {
1149 $odfHandler->exportAsAttachedPDF($file);
1150 } catch (Exception $e) {
1151 $this->error = $e->getMessage();
1152 return -1;
1153 }
1154 } else {
1155 try {
1156 $odfHandler->saveToDisk($file);
1157 } catch (Exception $e) {
1158 $this->error = $e->getMessage();
1159 dol_syslog($e->getMessage(), LOG_INFO);
1160 return -1;
1161 }
1162 }
1163 $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
1164 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1165
1166 dolChmod($file);
1167
1168 $odfHandler = null; // Destroy object
1169
1170 $this->result = array('fullpath'=>$file);
1171
1172 return 1; // Success
1173 } else {
1174 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
1175 return -1;
1176 }
1177 }
1178
1179 return -1;
1180 }
1181}
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_contact($object, $outputlangs, $array_key='object')
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 standard extra fields.
Class to manage generation of HTML components Only common components must be here.
Class to manage hooks.
Parent class for projects models.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Class to manage Dolibarr users.
Class to build documents using ODF templates generator.
get_substitutionarray_tasks(Task $task, $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_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_project_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_project_contacts($contact, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
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.
info($langs)
Return description of a module.
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:240
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
dol_now($mode='auto')
Return date for now.
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.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:120
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:123