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