dolibarr 22.0.5
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-2024 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 = floatval(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 $this->error = $e->getMessage();
881 dol_syslog($this->error, LOG_WARNING);
882 return -1;
883 }
884
885 // Replace tags of lines for contacts
886 $sourcearray = array('internal', 'external');
887 $contact_arrray = array();
888 foreach ($sourcearray as $source) {
889 $contact_temp = $object->liste_contact(-1, $source);
890 if ((is_array($contact_temp) && count($contact_temp) > 0)) {
891 $contact_arrray = array_merge($contact_arrray, $contact_temp);
892 }
893 }
894 if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
895 try {
896 $listlines = $odfHandler->setSegment('projectcontacts');
897
898 foreach ($contact_arrray as $contact) {
899 if ($contact['source'] == 'internal') {
900 $objectdetail = new User($this->db);
901 $objectdetail->fetch($contact['id']);
902 $contact['socname'] = $mysoc->name;
903 } elseif ($contact['source'] == 'external') {
904 $objectdetail = new Contact($this->db);
905 $objectdetail->fetch($contact['id']);
906
907 $soc = new Societe($this->db);
908 $soc->fetch($contact['socid']);
909 $contact['socname'] = $soc->name;
910 }
911 $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
912
913 $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
914 foreach ($tmparray as $key => $val) {
915 try {
916 $listlines->setVars($key, $val, true, 'UTF-8');
917 } catch (SegmentException $e) {
918 dol_syslog($e->getMessage(), LOG_INFO);
919 }
920 }
921 $listlines->merge();
922 }
923 $odfHandler->mergeSegment($listlines);
924 } catch (OdfException $e) {
925 $this->error = $e->getMessage();
926 dol_syslog($this->error, LOG_WARNING);
927 return -1;
928 }
929 }
930
931 //List of referent
932
933 $listofreferent = array(
934 'propal' => array(
935 'title' => "ListProposalsAssociatedProject",
936 'class' => 'Propal',
937 'table' => 'propal',
938 'test' => isModEnabled('propal') && $user->hasRight('propal', 'lire')
939 ),
940 'order' => array(
941 'title' => "ListOrdersAssociatedProject",
942 'class' => 'Commande',
943 'table' => 'commande',
944 'test' => isModEnabled('order') && $user->hasRight('commande', 'lire')
945 ),
946 'invoice' => array(
947 'title' => "ListInvoicesAssociatedProject",
948 'class' => 'Facture',
949 'table' => 'facture',
950 'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
951 ),
952 'invoice_predefined' => array(
953 'title' => "ListPredefinedInvoicesAssociatedProject",
954 'class' => 'FactureRec',
955 'table' => 'facture_rec',
956 'test' => isModEnabled('invoice') && $user->hasRight('facture', 'lire')
957 ),
958 'proposal_supplier' => array(
959 'title' => "ListSupplierProposalsAssociatedProject",
960 'class' => 'SupplierProposal',
961 'table' => 'supplier_proposal',
962 'test' => isModEnabled('supplier_proposal') && $user->hasRight('supplier_proposal', 'lire')
963 ),
964 'order_supplier' => array(
965 'title' => "ListSupplierOrdersAssociatedProject",
966 'table' => 'commande_fournisseur',
967 'class' => 'CommandeFournisseur',
968 'test' => (isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight('fournisseur', 'commande', 'lire')) || (isModEnabled("supplier_order") && $user->hasRight('supplier_order', 'lire'))
969 ),
970 'invoice_supplier' => array(
971 'title' => "ListSupplierInvoicesAssociatedProject",
972 'table' => 'facture_fourn',
973 'class' => 'FactureFournisseur',
974 'test' => (isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled("supplier_invoice") && $user->hasRight('supplier_invoice', 'lire'))
975 ),
976 'contract' => array(
977 'title' => "ListContractAssociatedProject",
978 'class' => 'Contrat',
979 'table' => 'contrat',
980 'test' => isModEnabled('contract') && $user->hasRight('contrat', 'lire')
981 ),
982 'intervention' => array(
983 'title' => "ListFichinterAssociatedProject",
984 'class' => 'Fichinter',
985 'table' => 'fichinter',
986 'disableamount' => 1,
987 'test' => isModEnabled('intervention') && $user->hasRight('ficheinter', 'lire')
988 ),
989 'shipping' => array(
990 'title' => "ListShippingAssociatedProject",
991 'class' => 'Expedition',
992 'table' => 'expedition',
993 'disableamount' => 1,
994 'test' => isModEnabled('shipping') && $user->hasRight('expedition', 'lire')
995 ),
996 'trip' => array(
997 'title' => "ListTripAssociatedProject",
998 'class' => 'Deplacement',
999 'table' => 'deplacement',
1000 'disableamount' => 1,
1001 'test' => isModEnabled('deplacement') && $user->hasRight('deplacement', 'lire')
1002 ),
1003 'expensereport' => array(
1004 'title' => "ListExpenseReportsAssociatedProject",
1005 'class' => 'ExpenseReportLine',
1006 'table' => 'expensereport_det',
1007 'test' => isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')
1008 ),
1009 'donation' => array(
1010 'title' => "ListDonationsAssociatedProject",
1011 'class' => 'Don',
1012 'table' => 'don',
1013 'test' => isModEnabled('don') && $user->hasRight('don', 'lire')
1014 ),
1015 'loan' => array(
1016 'title' => "ListLoanAssociatedProject",
1017 'class' => 'Loan',
1018 'table' => 'loan',
1019 'test' => isModEnabled('loan') && $user->hasRight('loan', 'read')
1020 ),
1021 'chargesociales' => array(
1022 'title' => "ListSocialContributionAssociatedProject",
1023 'class' => 'ChargeSociales',
1024 'table' => 'chargesociales',
1025 'urlnew' => DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$object->id,
1026 'test' => isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')
1027 ),
1028 'stock_mouvement' => array(
1029 'title' => "ListMouvementStockProject",
1030 'class' => 'MouvementStock',
1031 'table' => 'stock_mouvement',
1032 'test' => (isModEnabled('stock') && $user->hasRight('stock', 'mouvement', 'lire') && getDolGlobalString('STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW'))
1033 ),
1034 'agenda' => array(
1035 'title' => "ListActionsAssociatedProject",
1036 'class' => 'ActionComm',
1037 'table' => 'actioncomm',
1038 'disableamount' => 1,
1039 'test' => isModEnabled('agenda') && $user->hasRight('agenda', 'allactions', 'lire')
1040 ),
1041 );
1042
1043 // Insert list of objects into the project
1044 try {
1045 $listlines = $odfHandler->setSegment('projectrefs');
1046
1047 foreach ($listofreferent as $keyref => $valueref) {
1048 $title = $valueref['title'];
1049 $tablename = $valueref['table'];
1050 $classname = $valueref['class'];
1051 $qualified = $valueref['test'];
1052 if ($qualified) {
1053 $elementarray = $object->get_element_list($keyref, $tablename);
1054 if (count($elementarray) > 0 && is_array($elementarray)) {
1055 $total_ht = 0;
1056 $total_ttc = 0;
1057 $num = count($elementarray);
1058 for ($i = 0; $i < $num; $i++) {
1059 $ref_array = array();
1060 $ref_array['type'] = (string) $langs->trans($classname);
1061
1062 $element = new $classname($this->db);
1063 $element->fetch((int) $elementarray[$i]);
1064 $element->fetch_thirdparty();
1065
1066 //Ref object
1067 $ref_array['ref'] = $element->ref;
1068
1069 //Date object
1070 $dateref = $element->date;
1071 if (empty($dateref)) {
1072 $dateref = $element->datep;
1073 }
1074 if (empty($dateref)) {
1075 $dateref = $element->date_contrat;
1076 }
1077 $ref_array['date'] = (string) $dateref;
1078
1079 //Soc object
1080 if (is_object($element->thirdparty)) {
1081 $ref_array['socname'] = $element->thirdparty->name;
1082 } else {
1083 $ref_array['socname'] = '';
1084 }
1085
1086 //Amount object
1087 if (empty($valueref['disableamount'])) {
1088 if (!empty($element->total_ht)) {
1089 $ref_array['amountht'] = $element->total_ht;
1090 $ref_array['amountttc'] = $element->total_ttc;
1091 } else {
1092 $ref_array['amountht'] = 0;
1093 $ref_array['amountttc'] = 0;
1094 }
1095 } else {
1096 $ref_array['amountht'] = '';
1097 $ref_array['amountttc'] = '';
1098 }
1099
1100 $ref_array['status'] = $element->getLibStatut(0);
1101
1102 $tmparray = $this->get_substitutionarray_project_reference($ref_array, $outputlangs);
1103
1104 foreach ($tmparray as $key => $val) {
1105 try {
1106 $listlines->setVars($key, $val, true, 'UTF-8');
1107 } catch (SegmentException $e) {
1108 dol_syslog($e->getMessage(), LOG_INFO);
1109 }
1110 }
1111 $listlines->merge();
1112 }
1113 }
1114 }
1115 $odfHandler->mergeSegment($listlines);
1116 }
1117 } catch (OdfExceptionSegmentNotFound $e) {
1118 // Do nothing
1119 } catch (OdfException $e) {
1120 $this->error = $e->getMessage();
1121 dol_syslog($this->error, LOG_WARNING);
1122 return -1;
1123 }
1124
1125 // Replace labels translated
1126 $tmparray = $outputlangs->get_translations_for_substitutions();
1127 foreach ($tmparray as $key => $value) {
1128 try {
1129 $odfHandler->setVars($key, $value, true, 'UTF-8');
1130 } catch (OdfException $e) {
1131 dol_syslog($e->getMessage(), LOG_INFO);
1132 }
1133 }
1134
1135 // Call the beforeODTSave hook
1136 $parameters = array('odfHandler' => &$odfHandler, 'file' => $file, 'object' => $object, 'outputlangs' => $outputlangs, 'substitutionarray' => &$tmparray);
1137 $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1138
1139
1140 // Write new file
1141 if (getDolGlobalString('MAIN_ODT_AS_PDF')) {
1142 try {
1143 $odfHandler->exportAsAttachedPDF($file);
1144 } catch (Exception $e) {
1145 $this->error = $e->getMessage();
1146 return -1;
1147 }
1148 } else {
1149 try {
1150 $odfHandler->saveToDisk($file);
1151 } catch (Exception $e) {
1152 $this->error = $e->getMessage();
1153 dol_syslog($e->getMessage(), LOG_INFO);
1154 return -1;
1155 }
1156 }
1157 $parameters = array('odfHandler' => &$odfHandler, 'file' => $file, 'object' => $object, 'outputlangs' => $outputlangs, 'substitutionarray' => &$tmparray);
1158 $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1159
1160 dolChmod($file);
1161
1162 $odfHandler = null; // Destroy object
1163
1164 $this->result = array('fullpath' => $file);
1165
1166 return 1; // Success
1167 } else {
1168 $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
1169 return -1;
1170 }
1171 }
1172
1173 return -1;
1174 }
1175}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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_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.
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:244
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_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.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a 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)
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:161
getMaxFileSizeArray()
Return the max allowed for file upload.