dolibarr 20.0.0
website2.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
31function dolSaveMasterFile($filemaster)
32{
33 // Now generate the master.inc.php page
34 dol_syslog("We regenerate the master.inc.php file");
35
36 dol_delete_file($filemaster);
37
38 $mastercontent = '<?php'."\n";
39 $mastercontent .= '// File generated to link to the master file - DO NOT MODIFY - It is just an include'."\n";
40 $mastercontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) {\n";
41 $mastercontent .= " if (! defined('USEEXTERNALSERVER')) define('USEEXTERNALSERVER', 1);\n";
42 $mastercontent .= " require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n";
43 $mastercontent .= "}\n";
44 $mastercontent .= '?>'."\n";
45 $result = file_put_contents($filemaster, $mastercontent);
46 dolChmod($filemaster);
47
48 return $result;
49}
50
61function dolSavePageAlias($filealias, $object, $objectpage)
62{
63 // Now create the .tpl file
64 dol_syslog("dolSavePageAlias We regenerate the alias page filealias=".$filealias." and a wrapper into all language subdirectories");
65
66 $aliascontent = '<?php'."\n";
67 $aliascontent .= "// File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page\n";
68 $aliascontent .= 'global $dolibarr_main_data_root;'."\n";
69 $aliascontent .= 'if (empty($dolibarr_main_data_root)) require \'./page'.$objectpage->id.'.tpl.php\'; ';
70 $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n";
71 $aliascontent .= '?>'."\n";
72 $result = file_put_contents($filealias, $aliascontent);
73 if ($result === false) {
74 dol_syslog("Failed to write file ".$filealias, LOG_WARNING);
75 }
76 dolChmod($filealias);
77
78 // Save also alias into language subdirectory if it is not a main language
79 if ($objectpage->lang && in_array($objectpage->lang, explode(',', $object->otherlang))) {
80 $dirname = dirname($filealias);
81 $filename = basename($filealias);
82 $filealiassub = $dirname.'/'.$objectpage->lang.'/'.$filename;
83
84 dol_mkdir($dirname.'/'.$objectpage->lang, DOL_DATA_ROOT);
85
86 $aliascontent = '<?php'."\n";
87 $aliascontent .= "// File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page\n";
88 $aliascontent .= 'global $dolibarr_main_data_root;'."\n";
89 $aliascontent .= 'if (empty($dolibarr_main_data_root)) require \'../page'.$objectpage->id.'.tpl.php\'; ';
90 $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n";
91 $aliascontent .= '?>'."\n";
92 $result = file_put_contents($filealiassub, $aliascontent);
93 if ($result === false) {
94 dol_syslog("Failed to write file ".$filealiassub, LOG_WARNING);
95 }
96 dolChmod($filealiassub);
97 } elseif (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
98 // Save also alias into all language subdirectories if it is a main language
99 if (!getDolGlobalString('WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR') && !empty($object->otherlang)) {
100 $dirname = dirname($filealias);
101 $filename = basename($filealias);
102 foreach (explode(',', $object->otherlang) as $sublang) {
103 // Avoid to erase main alias file if $sublang is empty string
104 if (empty(trim($sublang))) {
105 continue;
106 }
107 $filealiassub = $dirname.'/'.$sublang.'/'.$filename;
108
109 $aliascontent = '<?php'."\n";
110 $aliascontent .= "// File generated to wrap the alias page - DO NOT MODIFY - It is just a wrapper to real page\n";
111 $aliascontent .= 'global $dolibarr_main_data_root;'."\n";
112 $aliascontent .= 'if (empty($dolibarr_main_data_root)) require \'../page'.$objectpage->id.'.tpl.php\'; ';
113 $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n";
114 $aliascontent .= '?>'."\n";
115
116 dol_mkdir($dirname.'/'.$sublang);
117 $result = file_put_contents($filealiassub, $aliascontent);
118 if ($result === false) {
119 dol_syslog("Failed to write file ".$filealiassub, LOG_WARNING);
120 }
121 dolChmod($filealiassub);
122 }
123 }
124 }
125
126 return ($result ? true : false);
127}
128
129
141function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $backupold = 0)
142{
143 global $db;
144
145 // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header)
146 dol_syslog("dolSavePageContent We regenerate the tpl page filetpl=".$filetpl);
147
148 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
149
150 if (dol_is_file($filetpl)) {
151 if ($backupold) {
152 $result = archiveOrBackupFile($filetpl);
153 if (! $result) {
154 return false;
155 }
156 } else {
157 dol_delete_file($filetpl);
158 }
159 }
160
161 $shortlangcode = '';
162 if ($objectpage->lang) {
163 $shortlangcode = substr($objectpage->lang, 0, 2); // en_US or en-US -> en
164 }
165 if (empty($shortlangcode)) {
166 $shortlangcode = substr($object->lang, 0, 2); // en_US or en-US -> en
167 }
168
169 if (!empty($objectpage->type_container) && in_array($objectpage->type_container, array('library', 'service'))) {
170 $originalcontentonly = 1;
171 }
172
173 $tplcontent = '';
174 if (!isset($originalcontentonly)) {
175 $tplcontent .= "<?php // BEGIN PHP\n";
176 $tplcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
177 $tplcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) {\n";
178 $tplcontent .= ' $pathdepth = count(explode(\'/\', $_SERVER[\'SCRIPT_NAME\'])) - 2;'."\n";
179 $tplcontent .= ' require_once ($pathdepth ? str_repeat(\'../\', $pathdepth) : \'./\').\'master.inc.php\';'."\n";
180 $tplcontent .= "} // Not already loaded\n";
181 $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
182 $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
183 $tplcontent .= "ob_start();\n";
184 $tplcontent .= "// END PHP ?>\n";
185 if (getDolGlobalString('WEBSITE_FORCE_DOCTYPE_HTML5')) {
186 $tplcontent .= "<!DOCTYPE html>\n";
187 }
188 $tplcontent .= '<html'.($shortlangcode ? ' lang="'.$shortlangcode.'"' : '').'>'."\n";
189 $tplcontent .= '<head>'."\n";
190 $tplcontent .= '<title>'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'</title>'."\n";
191 $tplcontent .= '<meta charset="utf-8">'."\n";
192 $tplcontent .= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'."\n";
193 $tplcontent .= '<meta name="robots" content="index, follow" />'."\n";
194 $tplcontent .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n";
195 $tplcontent .= '<meta name="keywords" content="'.dol_string_nohtmltag($objectpage->keywords).'" />'."\n";
196 $tplcontent .= '<meta name="title" content="'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'" />'."\n";
197 $tplcontent .= '<meta name="description" content="'.dol_string_nohtmltag($objectpage->description, 0, 'UTF-8').'" />'."\n";
198 $tplcontent .= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.' '.DOL_VERSION.' (https://www.dolibarr.org)" />'."\n";
199 $tplcontent .= '<meta name="dolibarr:pageid" content="'.dol_string_nohtmltag($objectpage->id).'" />'."\n";
200
201 // Add favicon
202 if ($objectpage->id == $object->fk_default_home) {
203 $tplcontent .= '<link rel="icon" type="image/png" href="/favicon.png" />'."\n";
204 }
205
206 // Add canonical reference
207 if ($object->virtualhost) {
208 $tplcontent .= '<link rel="canonical" href="'.(($objectpage->id == $object->fk_default_home) ? '/' : (($shortlangcode != substr($object->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$objectpage->pageurl.'.php')).'" />'."\n";
209 }
210 // Add translation reference (main language)
211 if ($object->isMultiLang()) {
212 // Add page "translation of"
213 $translationof = $objectpage->fk_page;
214 if ($translationof) {
215 $tmppage = new WebsitePage($db);
216 $tmppage->fetch($translationof);
217 if ($tmppage->id > 0) {
218 $tmpshortlangcode = '';
219 if ($tmppage->lang) {
220 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en
221 }
222 if (empty($tmpshortlangcode)) {
223 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en
224 }
225 if ($tmpshortlangcode != $shortlangcode) {
226 $tplcontent .= '<link rel="alternate" hreflang="'.$tmpshortlangcode.'" href="<?php echo $website->virtualhost; ?>'.($object->fk_default_home == $tmppage->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2)) ? '/'.$tmpshortlangcode : '').'/'.$tmppage->pageurl.'.php').'" />'."\n";
227 }
228 }
229 }
230
231 // Add "has translation pages"
232 $sql = "SELECT rowid as id, lang, pageurl from ".MAIN_DB_PREFIX.'website_page where fk_page IN ('.$db->sanitize($objectpage->id.($translationof ? ", ".$translationof : '')).")";
233 $resql = $db->query($sql);
234 if ($resql) {
235 $num_rows = $db->num_rows($resql);
236 if ($num_rows > 0) {
237 while ($obj = $db->fetch_object($resql)) {
238 $tmpshortlangcode = '';
239 if ($obj->lang) {
240 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en
241 }
242 if ($tmpshortlangcode != $shortlangcode) {
243 $tplcontent .= '<link rel="alternate" hreflang="'.$tmpshortlangcode.'" href="<?php echo $website->virtualhost; ?>'.($object->fk_default_home == $obj->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2) ? '/'.$tmpshortlangcode : '')).'/'.$obj->pageurl.'.php').'" />'."\n";
244 }
245 }
246 }
247 } else {
248 dol_print_error($db);
249 }
250
251 // Add myself
252 $tplcontent .= '<?php if ($_SERVER["PHP_SELF"] == "'.(($object->fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '')).'/'.$objectpage->pageurl.'.php") { ?>'."\n";
253 $tplcontent .= '<link rel="alternate" hreflang="'.$shortlangcode.'" href="<?php echo $website->virtualhost; ?>'.(($object->fk_default_home == $objectpage->id) ? '/' : (($shortlangcode != substr($object->lang, 0, 2)) ? '/'.$shortlangcode : '').'/'.$objectpage->pageurl.'.php').'" />'."\n";
254
255 $tplcontent .= '<?php } ?>'."\n";
256 }
257 // Add manifest.json. Do we have to add it only on home page ?
258 $tplcontent .= '<?php if ($website->use_manifest) { print \'<link rel="manifest" href="/manifest.json.php" />\'."\n"; } ?>'."\n";
259 $tplcontent .= '<!-- Include link to CSS file -->'."\n";
260 // Add js
261 $tplcontent .= '<link rel="stylesheet" href="/styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />'."\n";
262 $tplcontent .= '<!-- Include link to JS file -->'."\n";
263 $tplcontent .= '<script nonce="'.getNonce().'" async src="/javascript.js.php?website=<?php echo $websitekey; ?>"></script>'."\n";
264 // Add headers
265 $tplcontent .= '<!-- Include HTML header from common file -->'."\n";
266 $tplcontent .= '<?php if (file_exists(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")) include DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html"; ?>'."\n";
267 $tplcontent .= '<!-- Include HTML header from page header block -->'."\n";
268 $tplcontent .= preg_replace('/<\/?html>/ims', '', $objectpage->htmlheader)."\n";
269 $tplcontent .= '</head>'."\n";
270
271 $tplcontent .= '<!-- File generated by Dolibarr website module editor -->'."\n";
272 $tplcontent .= '<body id="bodywebsite" class="bodywebsite bodywebpage-'.$objectpage->ref.'">'."\n";
273 $tplcontent .= $objectpage->content."\n";
274 $tplcontent .= '</body>'."\n";
275 $tplcontent .= '</html>'."\n";
276
277 $tplcontent .= '<?php // BEGIN PHP'."\n";
278 $tplcontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "html", '.$objectpage->id.'); dolWebsiteIncrementCounter('.$object->id.', "'.$objectpage->type_container.'", '.$objectpage->id.');'."\n";
279 $tplcontent .= "// END PHP ?>\n";
280 } else {
281 $tplcontent .= "<?php\n// This is a library page.\n?>\n";
282 $tplcontent .= $objectpage->content;
283 }
284
285 //var_dump($filetpl);exit;
286 $result = file_put_contents($filetpl, $tplcontent);
287
288 dolChmod($filetpl);
289
290 return $result;
291}
292
293
304function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object = null)
305{
306 global $db;
307
308 $result1 = false;
309 $result2 = false;
310
311 dol_mkdir($pathofwebsite);
312
313 if ($fileindex) {
314 dol_delete_file($fileindex);
315 $indexcontent = '<?php'."\n";
316 $indexcontent .= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
317 $indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
318 $indexcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
319 $indexcontent .= 'if (!empty($_GET[\'pageref\']) || !empty($_GET[\'pagealiasalt\']) || !empty($_GET[\'pageid\'])) {'."\n";
320 $indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
321 $indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
322 $indexcontent .= ' redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);'."\n";
323 $indexcontent .= "}\n";
324 $indexcontent .= "include_once './".basename($filetpl)."'\n";
325 $indexcontent .= '// END PHP ?>'."\n";
326
327 $result1 = file_put_contents($fileindex, $indexcontent);
328
329 dolChmod($fileindex);
330
331 if (is_object($object) && $object->fk_default_home > 0) {
332 $objectpage = new WebsitePage($db);
333 $objectpage->fetch($object->fk_default_home);
334
335 // Create a version for sublanguages
336 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
337 if (!getDolGlobalString('WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR') && is_object($object) && !empty($object->otherlang)) {
338 $dirname = dirname($fileindex);
339 foreach (explode(',', $object->otherlang) as $sublang) {
340 // Avoid to erase main alias file if $sublang is empty string
341 if (empty(trim($sublang))) {
342 continue;
343 }
344 $fileindexsub = $dirname.'/'.$sublang.'/index.php';
345
346 // Same indexcontent than previously but with ../ instead of ./ for master and tpl file include/require_once.
347 $relpath = '..';
348 $indexcontent = '<?php'."\n";
349 $indexcontent .= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
350 $indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
351 $indexcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once '".$relpath."/master.inc.php'; } // Load master if not already loaded\n";
352 $indexcontent .= 'if (!empty($_GET[\'pageref\']) || !empty($_GET[\'pagealiasalt\']) || !empty($_GET[\'pageid\'])) {'."\n";
353 $indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
354 $indexcontent .= " require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
355 $indexcontent .= ' redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);'."\n";
356 $indexcontent .= "}\n";
357 $indexcontent .= "include_once '".$relpath."/".basename($filetpl)."'\n"; // use .. instead of .
358 $indexcontent .= '// END PHP ?>'."\n";
359 $result = file_put_contents($fileindexsub, $indexcontent);
360 if ($result === false) {
361 dol_syslog("Failed to write file ".$fileindexsub, LOG_WARNING);
362 }
363 dolChmod($fileindexsub);
364 }
365 }
366 }
367 }
368 } else {
369 $result1 = true;
370 }
371
372 if ($filewrapper) {
373 dol_delete_file($filewrapper);
374 $wrappercontent = file_get_contents(DOL_DOCUMENT_ROOT.'/website/samples/wrapper.php');
375
376 $result2 = file_put_contents($filewrapper, $wrappercontent);
377 dolChmod($filewrapper);
378 } else {
379 $result2 = true;
380 }
381
382 return ($result1 && $result2);
383}
384
385
393function dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent)
394{
395 global $pathofwebsite;
396
397 dol_syslog("Save html header into ".$filehtmlheader);
398
399 dol_mkdir($pathofwebsite);
400 $result = file_put_contents($filehtmlheader, $htmlheadercontent);
401 dolChmod($filehtmlheader);
402
403 return $result;
404}
405
413function dolSaveCssFile($filecss, $csscontent)
414{
415 global $pathofwebsite;
416
417 dol_syslog("Save css file into ".$filecss);
418
419 dol_mkdir($pathofwebsite);
420 $result = file_put_contents($filecss, $csscontent);
421 dolChmod($filecss);
422
423 return $result;
424}
425
433function dolSaveJsFile($filejs, $jscontent)
434{
435 global $pathofwebsite;
436
437 dol_syslog("Save js file into ".$filejs);
438
439 dol_mkdir($pathofwebsite);
440 $result = file_put_contents($filejs, $jscontent);
441 dolChmod($filejs);
442
443 return $result;
444}
445
453function dolSaveRobotFile($filerobot, $robotcontent)
454{
455 global $pathofwebsite;
456
457 dol_syslog("Save robot file into ".$filerobot);
458
459 dol_mkdir($pathofwebsite);
460 $result = file_put_contents($filerobot, $robotcontent);
461 dolChmod($filerobot);
462
463 return $result;
464}
465
473function dolSaveHtaccessFile($filehtaccess, $htaccess)
474{
475 global $pathofwebsite;
476
477 dol_syslog("Save htaccess file into ".$filehtaccess);
478
479 dol_mkdir($pathofwebsite);
480 $result = file_put_contents($filehtaccess, $htaccess);
481 dolChmod($filehtaccess);
482
483 return $result;
484}
485
493function dolSaveManifestJson($file, $content)
494{
495 global $pathofwebsite;
496
497 dol_syslog("Save manifest.js.php file into ".$file);
498
499 dol_mkdir($pathofwebsite);
500 $result = file_put_contents($file, $content);
501 dolChmod($file);
502
503 return $result;
504}
505
513function dolSaveReadme($file, $content)
514{
515 global $pathofwebsite;
516
517 dol_syslog("Save README.md file into ".$file);
518
519 dol_mkdir($pathofwebsite);
520 $result = file_put_contents($file, $content);
521 dolChmod($file);
522
523 return $result;
524}
525
533function dolSaveLicense($file, $content)
534{
535 global $pathofwebsite;
536
537 dol_syslog("Save LICENSE file into ".$file);
538
539 dol_mkdir($pathofwebsite);
540 $result = file_put_contents($file, $content);
541 dolChmod($file);
542
543 return $result;
544}
545
553{
554 global $conf, $langs, $form, $user;
555
556 $dirthemes = array('/doctemplates/websites');
557 /*
558 if (!empty($conf->modules_parts['websitetemplates'])) {
559 foreach ($conf->modules_parts['websitetemplates'] as $reldir) {
560 $dirthemes = array_merge($dirthemes, (array) ($reldir.'doctemplates/websites'));
561 }
562 }
563 */
564 $dirthemes = array_unique($dirthemes);
565 // Now dir_themes=array('/themes') or dir_themes=array('/theme','/mymodule/theme')
566
567 $colspan = 2;
568
569 print '<!-- For website template import -->'."\n";
570 print '<table class="noborder centpercent">';
571
572 // Title
573 print '<tr class="liste_titre"><th class="titlefield">';
574 print $form->textwithpicto($langs->trans("Templates"), $langs->trans("ThemeDir").' : '.implode(", ", $dirthemes));
575 print ' ';
576 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($website->ref).'&importsite=1" rel="noopener noreferrer external">';
577 print img_picto('', 'refresh');
578 print '</a>';
579 print '</th>';
580 print '<th class="right">';
581 $url = 'https://www.dolistore.com/43-web-site-templates';
582 print '<a href="'.$url.'" target="_blank" rel="noopener noreferrer external">';
583 print img_picto('', 'globe', 'class="pictofixedwidth"').$langs->trans('DownloadMoreSkins');
584 print '</a>';
585 print '</th></tr>';
586
587 print '<tr><td colspan="'.$colspan.'">';
588
589 print '<table class="nobordernopadding centpercent"><tr><td><div class="display-flex">';
590
591 if (count($dirthemes)) {
592 $i = 0;
593 foreach ($dirthemes as $dir) {
594 if (preg_match('/^\/doctemplates\//', $dir)) {
595 $dirtheme = DOL_DATA_ROOT.$dir; // This include loop on $conf->file->dol_document_root
596 } else {
597 $dirtheme = dol_buildpath($dir); // This include loop on $conf->file->dol_document_root
598 }
599 if (is_dir($dirtheme)) {
600 $handle = opendir($dirtheme);
601 if (is_resource($handle)) {
602 while (($subdir = readdir($handle)) !== false) {
603 //var_dump($dirtheme.'/'.$subdir);
604 if (is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) != '.' && substr($subdir, 0, 3) != 'CVS' && preg_match('/\.zip$/i', $subdir)) {
605 $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir);
606
607 // Disable not stable themes (dir ends with _exp or _dev)
608 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2 && preg_match('/_dev$/i', $subdir)) {
609 continue;
610 }
611 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1 && preg_match('/_exp$/i', $subdir)) {
612 continue;
613 }
614
615 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px; margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">';
616
617 $templatedir = $dirtheme."/".$subdir;
618 $file = $dirtheme."/".$subdirwithoutzip.".jpg";
619 $url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzip.".jpg";
620
621 if (!file_exists($file)) {
622 $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png';
623 }
624
625 $originalfile = basename($file);
626 $entity = $conf->entity;
627 $modulepart = 'doctemplateswebsite';
628 $cache = '';
629 $title = $file;
630
631 $ret = '';
632 $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 1, '&entity='.$entity);
633 if (!empty($urladvanced)) {
634 $ret .= '<a class="'.$urladvanced['css'].'" target="'.$urladvanced['target'].'" mime="'.$urladvanced['mime'].'" href="'.$urladvanced['url'].'">';
635 } else {
636 $ret .= '<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.urlencode($modulepart).'&entity='.((int) $entity).'&file='.urlencode($originalfile).'&cache='.((int) $cache).'">';
637 }
638 print $ret;
639 print '<img class="img-skinthumb shadow" src="'.$url.'" border="0" alt="'.$title.'" title="'.$title.'" style="margin-bottom: 5px;">';
640 print '</a>';
641
642 print '<br>';
643 print $subdir;
644 print '<br>';
645 print '<span class="opacitymedium">'.dol_print_size(dol_filesize($dirtheme."/".$subdir), 1, 1).' - '.dol_print_date(dol_filemtime($templatedir), 'dayhour', 'tzuserrel').'</span>';
646 if ($user->hasRight('website', 'delete')) {
647 print ' <a href="'.$_SERVER["PHP_SELF"].'?action=deletetemplate&token='.newToken().'&website='.urlencode($website->ref).'&templateuserfile='.urlencode($subdir).'">'.img_picto('', 'delete').'</a>';
648 }
649 print '<br><a href="'.$_SERVER["PHP_SELF"].'?action=importsiteconfirm&token='.newToken().'&website='.urlencode($website->ref).'&templateuserfile='.urlencode($subdir).'" class="button">'.$langs->trans("Load").'</a>';
650 print '</div>';
651
652 $i++;
653 }
654 }
655 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>';
656 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>';
657 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>';
658 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>';
659 print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px;margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;"></div>';
660 }
661 }
662 }
663 } else {
664 print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
665 }
666
667 print '</div></td></tr></table>';
668
669 print '</td></tr>';
670 print '</table>';
671}
672
673
684function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
685{
686 global $langs, $user;
687
688 $error = 0;
689
690 if (empty($phpfullcodestringold) && empty($phpfullcodestring)) {
691 return 0;
692 }
693
694 // First check permission
695 if ($phpfullcodestringold != $phpfullcodestring) {
696 if (!$error && !$user->hasRight('website', 'writephp')) {
697 $error++;
698 setEventMessages($langs->trans("NotAllowedToAddDynamicContent"), null, 'errors');
699 }
700 }
701
702 // Then check forbidden commands
703 if (!$error) {
704 $forbiddenphpstrings = array('$$', '}[');
705 $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('ReflectionFunction'));
706
707 $forbiddenphpfunctions = array();
708 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id"));
709 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes"));
710 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func"));
711 //$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
712 if (!getDolGlobalString('WEBSITE_PHP_ALLOW_EXEC')) { // If option is not on, we disallow functions to execute commands
713 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen"));
714 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions
715 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities
716 }
717 if (!getDolGlobalString('WEBSITE_PHP_ALLOW_WRITE')) { // If option is not on, we disallow functions to write files
718 $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
719 }
720
721 $forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function
722
723 foreach ($forbiddenphpstrings as $forbiddenphpstring) {
724 if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ms', $phpfullcodestring)) {
725 $error++;
726 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpstring), null, 'errors');
727 break;
728 }
729 }
730 foreach ($forbiddenphpfunctions as $forbiddenphpcommand) {
731 if (preg_match('/'.$forbiddenphpcommand.'\s*\‍(/ms', $phpfullcodestring)) {
732 $error++;
733 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors');
734 break;
735 }
736 }
737 foreach ($forbiddenphpmethods as $forbiddenphpmethod) {
738 if (preg_match('/->'.$forbiddenphpmethod.'/ms', $phpfullcodestring)) {
739 $error++;
740 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors');
741 break;
742 }
743 }
744 }
745
746 // This char can be used to execute RCE for example using with echo `ls`
747 if (!$error) {
748 $forbiddenphpchars = array();
749 if (!getDolGlobalString('WEBSITE_PHP_ALLOW_DANGEROUS_CHARS')) { // If option is not on, we disallow functions to execute commands
750 $forbiddenphpchars = array("`");
751 }
752 foreach ($forbiddenphpchars as $forbiddenphpchar) {
753 if (preg_match('/'.$forbiddenphpchar.'/ms', $phpfullcodestring)) {
754 $error++;
755 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpchar), null, 'errors');
756 break;
757 }
758 }
759 }
760
761 // Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and ']('
762 if (!$error) {
763 if (preg_match('/[}\]]\‍(/ims', $phpfullcodestring)) {
764 $error++;
765 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors');
766 }
767 }
768
769 // Deny dynamic functions '$xxx('
770 if (!$error) {
771 if (preg_match('/\$[a-z0-9_\-\/\*]+\‍(/ims', $phpfullcodestring)) {
772 $error++;
773 setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors');
774 }
775 }
776
777 // No need to block $conf->global->aaa() because PHP try to run method aaa an not function into $conf->global->aaa.
778
779 // Then check if installmodules does not block dynamic PHP code change.
780 if ($phpfullcodestringold != $phpfullcodestring) {
781 if (!$error) {
782 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
783 $allowimportsite = true;
784 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
785 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
786 $allowimportsite = false;
787 }
788
789 if (!$allowimportsite) {
790 $error++;
791 // Blocked by installmodules.lock
792 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
793 // Show clean corporate message
794 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
795 } else {
796 // Show technical generic message
797 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
798 }
799 setEventMessages($message, null, 'errors');
800 }
801 }
802 }
803
804 return $error;
805}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Class Website.
Class Websitepage.
dol_filemtime($pathoffile)
Return time of a file.
dol_filesize($pathoffile)
Return size of a file.
archiveOrBackupFile($filetpl, $max_versions=5, $archivedir='', $suffix="v", $moveorcopy='move')
Manage backup versions for a given file, ensuring only a maximum number of versions are kept.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_is_file($pathoffile)
Return if path is a file.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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'.
getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='')
Return URL we can use for advanced preview links.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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)
dolSaveMasterFile($filemaster)
Save content of a page on disk.
showWebsiteTemplates(Website $website)
Show list of themes.
dolSaveLicense($file, $content)
Save content of a page on disk.
checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
Check a new string containing only php code (including <php tag)
dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent)
Save content of a page on disk.
dolSaveReadme($file, $content)
Save content of a page on disk.
dolSaveManifestJson($file, $content)
Save content of a page on disk.
dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object=null)
Save content of the index.php and/or the wrapper.php page.
dolSavePageAlias($filealias, $object, $objectpage)
Save an alias page on disk (A page that include the reference page).
dolSaveHtaccessFile($filehtaccess, $htaccess)
Save content of a page on disk.
dolSaveJsFile($filejs, $jscontent)
Save content of a page on disk.
dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $backupold=0)
Save content of a page on disk (page name is generally ID_of_page.php).
dolSaveCssFile($filecss, $csscontent)
Save content of a page on disk.
dolSaveRobotFile($filerobot, $robotcontent)
Save content of a page on disk.