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