Passed
Branch develop (21edb4)
by
unknown
41:33
created

doc_generic_bom_odt::info()   B

Complexity

Conditions 8
Paths 20

Size

Total Lines 81
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 54
nc 20
nop 1
dl 0
loc 81
rs 7.7591
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2010-2012 	Laurent Destailleur <[email protected]>
3
 * Copyright (C) 2012		Juanjo Menent		<[email protected]>
4
 * Copyright (C) 2014		Marcos García		<[email protected]>
5
 * Copyright (C) 2016		Charlie Benke		<[email protected]>
6
 * Copyright (C) 2018-2019  Philippe Grand      <[email protected]>
7
 * Copyright (C) 2018       Frédéric France     <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 * or see https://www.gnu.org/
22
 */
23
24
/**
25
 *	\file       htdocs/core/modules/bom/doc/doc_generic_bom_odt.modules.php
26
 *	\ingroup    bom
27
 *	\brief      File of class to build ODT documents for BOMs
28
 */
29
30
require_once DOL_DOCUMENT_ROOT.'/core/modules/bom/modules_bom.php';
31
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
32
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
33
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
34
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
35
require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
36
37
38
/**
39
 *	Class to build documents using ODF templates generator
40
 */
41
class doc_generic_bom_odt extends ModelePDFBom
42
{
43
	/**
44
	 * Issuer
45
	 * @var Societe
46
	 */
47
	public $emetteur;
48
49
	/**
50
	 * @var array Minimum version of PHP required by module.
51
	 * e.g.: PHP ≥ 5.6 = array(5, 6)
52
	 */
53
	public $phpmin = array(5, 6);
54
55
	/**
56
	 * @var string Dolibarr version of the loaded document
57
	 */
58
	public $version = 'dolibarr';
59
60
61
	/**
62
	 *	Constructor
63
	 *
64
	 *  @param		DoliDB		$db      Database handler
65
	 */
66
	public function __construct($db)
67
	{
68
		global $conf, $langs, $mysoc;
69
70
		// Load translation files required by the page
71
		$langs->loadLangs(array("main", "companies"));
72
73
		$this->db = $db;
74
		$this->name = "ODT templates";
75
		$this->description = $langs->trans("DocumentModelOdt");
76
		$this->scandir = 'BOM_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
77
78
		// Page size for A4 format
79
		$this->type = 'odt';
80
		$this->page_largeur = 0;
81
		$this->page_hauteur = 0;
82
		$this->format = array($this->page_largeur, $this->page_hauteur);
83
		$this->marge_gauche = 0;
84
		$this->marge_droite = 0;
85
		$this->marge_haute = 0;
86
		$this->marge_basse = 0;
87
88
		$this->option_multilang = 1; // Dispo en plusieurs langues
89
		$this->option_freetext = 1; // Support add of a personalised text
90
		$this->option_draft_watermark = 0; // Support add of a watermark on drafts
91
92
		// Recupere emetteur
93
		$this->emetteur = $mysoc;
94
		if (!$this->emetteur->country_code) {
95
			$this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined
96
		}
97
	}
98
99
100
	/**
101
	 *	Return description of a module
102
	 *
103
	 *	@param	Translate	$langs      Lang object to use for output
104
	 *	@return string       			Description
105
	 */
106
	public function info($langs)
107
	{
108
		global $conf, $langs;
109
110
		// Load translation files required by the page
111
		$langs->loadLangs(array("errors", "companies"));
112
113
		$form = new Form($this->db);
114
115
		$texte = $this->description.".<br>\n";
116
		$texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
117
		$texte .= '<input type="hidden" name="token" value="'.newToken().'">';
118
		$texte .= '<input type="hidden" name="action" value="setModuleOptions">';
119
		$texte .= '<input type="hidden" name="param1" value="BOM_ADDON_PDF_ODT_PATH">';
120
		$texte .= '<table class="nobordernopadding" width="100%">';
121
122
		// List of directories area
123
		$texte .= '<tr><td>';
124
		$texttitle = $langs->trans("ListOfDirectories");
125
		$listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->BOM_ADDON_PDF_ODT_PATH)));
126
		$listoffiles = array();
127
		foreach ($listofdir as $key => $tmpdir) {
128
			$tmpdir = trim($tmpdir);
129
			$tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
130
			if (!$tmpdir) {
131
				unset($listofdir[$key]);
132
				continue;
133
			}
134
			if (!is_dir($tmpdir)) {
135
				$texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
136
			} else {
137
				$tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
138
				if (count($tmpfiles)) {
139
					$listoffiles = array_merge($listoffiles, $tmpfiles);
140
				}
141
			}
142
		}
143
		$texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
144
		// Add list of substitution keys
145
		$texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
146
		$texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
147
148
		$texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
149
		$texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
150
		$texte .= '<textarea class="flat" cols="60" name="value1">';
151
		$texte .= $conf->global->BOM_ADDON_PDF_ODT_PATH;
152
		$texte .= '</textarea>';
153
		$texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
154
		$texte .= '<input type="submit" class="button small" value="'.$langs->trans("Modify").'" name="Button">';
155
		$texte .= '<br></div></div>';
156
157
		// Scan directories
158
		$nbofiles = count($listoffiles);
159
		if (!empty($conf->global->BOM_ADDON_PDF_ODT_PATH)) {
160
			$texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
161
			//$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
162
			$texte .= count($listoffiles);
163
			//$texte.=$nbofiles?'</a>':'';
164
			$texte .= '</b>';
165
		}
166
167
		if ($nbofiles) {
168
			$texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
169
			// Show list of found files
170
			foreach ($listoffiles as $file) {
171
				$texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=boms&file=invoices/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a><br>';
172
			}
173
			$texte .= '</div>';
174
		}
175
176
		$texte .= '</td>';
177
178
		$texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
179
		$texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
180
		$texte .= '</td>';
181
		$texte .= '</tr>';
182
183
		$texte .= '</table>';
184
		$texte .= '</form>';
185
186
		return $texte;
187
	}
188
189
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
190
	/**
191
	 *  Function to build a document on disk using the generic odt module.
192
	 *
193
	 *	@param		BOM			$object				Object source to build document
194
	 *	@param		Translate	$outputlangs		Lang output object
195
	 * 	@param		string		$srctemplatepath	Full path of source filename for generator using a template file
196
	 *  @param		int			$hidedetails		Do not show line details
197
	 *  @param		int			$hidedesc			Do not show desc
198
	 *  @param		int			$hideref			Do not show ref
199
	 *	@return		int         					1 if OK, <=0 if KO
200
	 */
201
	public function write_file($object, $outputlangs, $srctemplatepath, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
202
	{
203
		// phpcs:enable
204
		global $user, $langs, $conf, $mysoc, $hookmanager;
205
206
		if (empty($srctemplatepath)) {
207
			dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
208
			return -1;
209
		}
210
211
		// Add odtgeneration hook
212
		if (!is_object($hookmanager)) {
213
			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
214
			$hookmanager = new HookManager($this->db);
215
		}
216
		$hookmanager->initHooks(array('odtgeneration'));
217
		global $action;
218
219
		if (!is_object($outputlangs)) {
220
			$outputlangs = $langs;
221
		}
222
		$sav_charset_output = $outputlangs->charset_output;
223
		$outputlangs->charset_output = 'UTF-8';
224
225
		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
226
227
		if ($conf->bom->dir_output) {
228
			// If $object is id instead of object
229
			if (!is_object($object)) {
230
				$id = $object;
231
				$object = new Bom($this->db);
232
				$result = $object->fetch($id);
233
				if ($result < 0) {
234
					dol_print_error($this->db, $object->error);
235
					return -1;
236
				}
237
			}
238
239
			$object->fetch_thirdparty();
240
241
			$dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1];
242
			$objectref = dol_sanitizeFileName($object->ref);
243
			if (!preg_match('/specimen/i', $objectref)) {
244
				$dir .= "/".$objectref;
245
			}
246
			$file = $dir."/".$objectref.".odt";
247
248
			if (!file_exists($dir)) {
249
				if (dol_mkdir($dir) < 0) {
250
					$this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
251
					return -1;
252
				}
253
			}
254
255
			if (file_exists($dir)) {
256
				//print "srctemplatepath=".$srctemplatepath;	// Src filename
257
				$newfile = basename($srctemplatepath);
258
				$newfiletmp = preg_replace('/\.od(t|s)/i', '', $newfile);
259
				$newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
260
				$newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
261
				$newfiletmp = $objectref.'_'.$newfiletmp;
262
				//$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
263
				// Get extension (ods or odt)
264
				$newfileformat = substr($newfile, strrpos($newfile, '.') + 1);
265
				if (!empty($conf->global->MAIN_DOC_USE_TIMING)) {
266
					$format = $conf->global->MAIN_DOC_USE_TIMING;
267
					if ($format == '1') {
268
						$format = '%Y%m%d%H%M%S';
269
					}
270
					$filename = $newfiletmp.'-'.dol_print_date(dol_now(), $format).'.'.$newfileformat;
271
				} else {
272
					$filename = $newfiletmp.'.'.$newfileformat;
273
				}
274
				$file = $dir.'/'.$filename;
275
				//print "newdir=".$dir;
276
				//print "newfile=".$newfile;
277
				//print "file=".$file;
278
				//print "conf->societe->dir_temp=".$conf->societe->dir_temp;
279
280
				dol_mkdir($conf->bom->dir_temp);
281
				if (!is_writable($conf->bom->dir_temp)) {
282
					$this->error = "Failed to write in temp directory ".$conf->bom->dir_temp;
283
					dol_syslog('Error in write_file: '.$this->error, LOG_ERR);
284
					return -1;
285
				}
286
287
				// If CUSTOMER contact defined on order, we use it
288
				$usecontact = false;
289
				$arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
290
				if (count($arrayidcontact) > 0) {
291
					$usecontact = true;
292
					$result = $object->fetch_contact($arrayidcontact[0]);
293
				}
294
295
				// Recipient name
296
				$contactobject = null;
297
				if (!empty($usecontact)) {
298
					// On peut utiliser le nom de la societe du contact
299
					if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) {
300
						$socobject = $object->contact;
301
					} else {
302
						$socobject = $object->thirdparty;
303
						// if we have a CUSTOMER contact and we dont use as recipient we store the contact object for later use
304
						$contactobject = $object->contact;
305
					}
306
				} else {
307
					$socobject = $object->thirdparty;
308
				}
309
310
				// Make substitution
311
				$substitutionarray = array(
312
					'__QTY_TO_PRODUCE__' => $object->qty,
313
				);
314
				complete_substitutions_array($substitutionarray, $langs, $object);
315
				// Call the ODTSubstitution hook
316
				$parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$substitutionarray);
317
				$reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
318
319
				// Line of free text
320
				$newfreetext = '';
321
				$paramfreetext = 'BOM_FREE_TEXT';
322
				if (!empty($conf->global->$paramfreetext)) {
323
					$newfreetext = make_substitutions($conf->global->$paramfreetext, $substitutionarray);
324
				}
325
326
				// Open and load template
327
				require_once ODTPHP_PATH.'odf.php';
328
				try {
329
					$odfHandler = new odf(
330
						$srctemplatepath,
331
						array(
332
						'PATH_TO_TMP'	  => $conf->bom->dir_temp,
333
						'ZIP_PROXY'		  => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
334
						'DELIMITER_LEFT'  => '{',
335
						'DELIMITER_RIGHT' => '}'
336
						)
337
					);
338
				} catch (Exception $e) {
339
					$this->error = $e->getMessage();
340
					dol_syslog($e->getMessage(), LOG_INFO);
341
					return -1;
342
				}
343
				// After construction $odfHandler->contentXml contains content and
344
				// [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
345
				// [!-- BEGIN lines --]*[!-- END lines --]
346
				//print html_entity_decode($odfHandler->__toString());
347
				//print exit;
348
349
350
				// Make substitutions into odt of freetext
351
				try {
352
					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
353
				} catch (OdfException $e) {
354
					dol_syslog($e->getMessage(), LOG_INFO);
355
				}
356
357
				// Define substitution array
358
				$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
359
				$array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
360
				$array_objet = $this->get_substitutionarray_object($object, $outputlangs);
361
				$array_user = $this->get_substitutionarray_user($user, $outputlangs);
362
				$array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
363
				$array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
364
				$array_other = $this->get_substitutionarray_other($outputlangs);
365
				// retrieve contact information for use in object as contact_xxx tags
366
				$array_thirdparty_contact = array();
367
				if ($usecontact && is_object($contactobject)) {
368
					$array_thirdparty_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact');
369
				}
370
371
				$tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_thirdparty_contact);
372
				complete_substitutions_array($tmparray, $outputlangs, $object);
373
374
				// Call the ODTSubstitution hook
375
				$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
376
				$reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
377
378
				foreach ($tmparray as $key => $value) {
379
					try {
380
						if (preg_match('/logo$/', $key)) { // Image
381
							if (file_exists($value)) {
382
								$odfHandler->setImage($key, $value);
383
							} else {
384
								$odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
385
							}
386
						} else // Text
387
						{
388
							$odfHandler->setVars($key, $value, true, 'UTF-8');
389
						}
390
					} catch (OdfException $e) {
391
						dol_syslog($e->getMessage(), LOG_INFO);
392
					}
393
				}
394
				// Replace tags of lines
395
				try {
396
					$foundtagforlines = 1;
397
					try {
398
						$listlines = $odfHandler->setSegment('lines');
399
					} catch (OdfException $e) {
400
						// We may arrive here if tags for lines not present into template
401
						$foundtagforlines = 0;
402
						dol_syslog($e->getMessage(), LOG_INFO);
403
					}
404
					if ($foundtagforlines) {
405
						$linenumber = 0;
406
						foreach ($object->lines as $line) {
407
							$linenumber++;
408
							$tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
409
							complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
410
							// Call the ODTSubstitutionLine hook
411
							$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
412
							$reshook = $hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
413
							foreach ($tmparray as $key => $val) {
414
								try {
415
									$listlines->setVars($key, $val, true, 'UTF-8');
416
								} catch (OdfException $e) {
417
									dol_syslog($e->getMessage(), LOG_INFO);
418
								} catch (SegmentException $e) {
419
									dol_syslog($e->getMessage(), LOG_INFO);
420
								}
421
							}
422
							$listlines->merge();
423
						}
424
						$odfHandler->mergeSegment($listlines);
425
					}
426
				} catch (OdfException $e) {
427
					$this->error = $e->getMessage();
428
					dol_syslog($this->error, LOG_WARNING);
429
					return -1;
430
				}
431
432
				// Replace labels translated
433
				$tmparray = $outputlangs->get_translations_for_substitutions();
434
				foreach ($tmparray as $key => $value) {
435
					try {
436
						$odfHandler->setVars($key, $value, true, 'UTF-8');
437
					} catch (OdfException $e) {
438
						dol_syslog($e->getMessage(), LOG_INFO);
439
					}
440
				}
441
442
				// Call the beforeODTSave hook
443
444
				$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
445
				$reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
446
447
				// Write new file
448
				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
449
					try {
450
						$odfHandler->exportAsAttachedPDF($file);
451
					} catch (Exception $e) {
452
						$this->error = $e->getMessage();
453
						dol_syslog($e->getMessage(), LOG_INFO);
454
						return -1;
455
					}
456
				} else {
457
					try {
458
						$odfHandler->saveToDisk($file);
459
					} catch (Exception $e) {
460
						$this->error = $e->getMessage();
461
						dol_syslog($e->getMessage(), LOG_INFO);
462
						return -1;
463
					}
464
				}
465
466
				$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
467
				$reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
468
469
				if (!empty($conf->global->MAIN_UMASK)) {
470
					@chmod($file, octdec($conf->global->MAIN_UMASK));
471
				}
472
473
				$odfHandler = null; // Destroy object
474
475
				$this->result = array('fullpath'=>$file);
476
477
				return 1; // Success
478
			} else {
479
				$this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
480
				return -1;
481
			}
482
		}
483
484
		return -1;
485
	}
486
}
487