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