dolibarr 24.0.1
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2016-2023 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
4 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
29// We allow POST of rich content with js and style, but only for this php file and if into some given POST variable
30define('NOSCANPOSTFORINJECTION', array('PAGE_CONTENT', 'WEBSITE_CSS_INLINE', 'WEBSITE_JS_INLINE', 'WEBSITE_HTML_HEADER', 'htmlheader'));
31
32define('USEDOLIBARREDITOR', 1);
33define('FORCE_CKEDITOR', 1); // We need CKEditor, even if module is off.
34if (!defined('DISABLE_JS_GRAHP')) {
35 define('DISABLE_JS_GRAPH', 1);
36}
37
38//header('X-XSS-Protection:0'); // Disable XSS filtering protection of some browsers (note: use of Content-Security-Policy is more efficient). Disabled as deprecated.
39
40// Load Dolibarr environment
41require '../main.inc.php';
51require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
52require_once DOL_DOCUMENT_ROOT.'/website/lib/website.lib.php';
53require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
54require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';
55require_once DOL_DOCUMENT_ROOT.'/core/lib/website2.lib.php';
56require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
57require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
58require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
59require_once DOL_DOCUMENT_ROOT.'/core/class/html.formwebsite.class.php';
60require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
61require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
62require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
63require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
64require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
65require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
66
67// Load translation files required by the page
68$langs->loadLangs(array("admin", "other", "users", "website"));
69
70// Security check
71if (!$user->hasRight('website', 'read')) {
73}
74
75$conf->dol_hide_leftmenu = 1; // Force hide of left menu.
76
77$error = 0;
78$virtualurl = '';
79$dataroot = '';
80$websiteid = GETPOSTINT('websiteid');
81$websitekey = GETPOST('website', 'alpha');
82$page = GETPOST('page', 'alpha');
83$pageid = GETPOSTINT('pageid');
84$pageref = GETPOST('pageref', 'alphanohtml');
85
86$action = GETPOST('action', 'aZ09');
87$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
88$confirm = GETPOST('confirm', 'alpha');
89$cancel = GETPOST('cancel', 'alpha');
90$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
91$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'websitelist'; // To manage different context of search
92$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
93$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
94$dol_hide_topmenu = GETPOSTINT('dol_hide_topmenu');
95$dol_hide_leftmenu = GETPOSTINT('dol_hide_leftmenu');
96$dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
97
98$type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha');
99$section_dir = GETPOST('section_dir', 'alpha');
100$file_manager = GETPOST('file_manager', 'alpha');
101$replacesite = GETPOST('replacesite', 'alpha');
102$mode = GETPOST('mode', 'alpha');
103
104if (GETPOST('deletesite', 'alpha')) {
105 $action = 'deletesite';
106}
107if (GETPOST('delete', 'alpha')) {
108 $action = 'delete';
109}
110if (GETPOST('preview', 'alpha')) {
111 $action = 'preview';
112}
113if (GETPOST('createsite', 'alpha')) {
114 $action = 'createsite';
115}
116if (GETPOST('createcontainer', 'alpha')) {
117 $action = 'createcontainer';
118}
119if (GETPOST('editcss', 'alpha')) {
120 $action = 'editcss';
121}
122if (GETPOST('editmenu', 'alpha')) {
123 $action = 'editmenu';
124}
125if (GETPOST('setashome', 'alpha')) {
126 $action = 'setashome';
127}
128if (GETPOST('editmeta', 'alpha')) {
129 $action = 'editmeta';
130}
131if (GETPOST('editsource', 'alpha')) {
132 $action = 'editsource';
133}
134if (GETPOST('editcontent', 'alpha')) {
135 $action = 'editcontent';
136}
137if (GETPOST('exportsite', 'alpha')) {
138 $action = 'exportsite';
139}
140if (GETPOST('importsite')) { // Can be a string when clicking on button "Import site"
141 $action = 'importsite';
142}
143if (GETPOST('createfromclone', 'alpha')) {
144 $action = 'createfromclone';
145}
146if (GETPOST('createpagefromclone', 'alpha')) {
147 $action = 'createpagefromclone';
148}
149if (empty($action) && $file_manager) {
150 $action = 'file_manager';
151}
152if ($action == 'replacesite' || (empty($action) && $replacesite)) { // Test on permission not required
153 $mode = 'replacesite';
154}
155if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x')) {
156 $pageid = 0;
157}
158
159// Load variable for pagination
160$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
161$sortfield = (string) GETPOST('sortfield', 'aZ09comma');
162$sortorder = GETPOST('sortorder', 'aZ09comma');
163$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
164if (empty($page) || $page == -1) {
165 $page = 0;
166} // If $page is not defined, or '' or -1
167$offset = $limit * $page;
168$pageprev = $page - 1;
169$pagenext = $page + 1;
170
171if (empty($action)) {
172 $action = 'preview';
173}
174
175$object = new Website($db);
176$objectpage = new WebsitePage($db);
177
178$listofwebsites = $object->fetchAll('ASC', 'position'); // Init list of websites
179
180// If website not defined, we take first found
181if (!($websiteid > 0) && empty($websitekey) && $action != 'createsite') {
182 foreach ($listofwebsites as $key => $valwebsite) {
183 $websitekey = $valwebsite->ref;
184 break;
185 }
186}
187if ($websiteid > 0 || $websitekey) {
188 $res = $object->fetch($websiteid, $websitekey);
189 $websitekey = $object->ref;
190}
191
192$website = $object;
193
194// Check pageid received as parameter
195if ($pageid < 0) {
196 $pageid = 0;
197}
198if (($pageid > 0 || $pageref) && $action != 'addcontainer') {
199 $res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), $pageref);
200 // @phan-suppress
201 if ($res == 0) {
202 $res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), null, $pageref);
203 }
204
205 // Check if pageid is inside the new website, if not we reset param pageid
206 if ($res >= 0 && $object->id > 0) {
207 if ($objectpage->fk_website != $object->id) { // We have a bad page that does not belong to web site
208 if ($object->fk_default_home > 0) {
209 $res = $objectpage->fetch($object->fk_default_home, (string) $object->id, ''); // We search first page of web site
210 if ($res > 0) {
211 $pageid = $object->fk_default_home;
212 }
213 } else {
214 $res = $objectpage->fetch(0, (string) $object->id, ''); // We search first page of web site
215 if ($res == 0) { // Page was not found, we reset it
216 $objectpage = new WebsitePage($db);
217 } else { // We found a page, we set pageid to it.
218 $pageid = $objectpage->id;
219 }
220 }
221 } else { // We have a valid page. We force pageid for the case we got the page with a fetch on ref.
222 $pageid = $objectpage->id;
223 }
224 }
225}
226
227// Define pageid if pageid and pageref not received as parameter or was wrong
228$atleastonepage = false;
229if (empty($pageid) && empty($pageref) && $object->id > 0 && $action != 'createcontainer') {
230 $pageid = $object->fk_default_home;
231 if (empty($pageid)) {
232 $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
233 if (!is_array($array) && $array < 0) {
234 dol_print_error(null, $objectpage->error, $objectpage->errors);
235 }
236 $atleastonepage = (is_array($array) && count($array) > 0);
237
238 $firstpageid = 0;
239 $homepageid = 0;
240 foreach ($array as $key => $valpage) {
241 if (empty($firstpageid)) {
242 $firstpageid = $valpage->id;
243 }
244 if ($object->fk_default_home && $key == $object->fk_default_home) {
245 $homepageid = $valpage->id;
246 }
247 }
248 $pageid = ($homepageid ? $homepageid : $firstpageid); // We choose home page and if not defined yet, we take first page
249 }
250}
251
252
253global $dolibarr_main_data_root;
254$pathofwebsite = $dolibarr_main_data_root.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$websitekey;
255$filehtmlheader = $pathofwebsite.'/htmlheader.html';
256$filecss = $pathofwebsite.'/styles.css.php';
257$filejs = $pathofwebsite.'/javascript.js.php';
258$filerobot = $pathofwebsite.'/robots.txt';
259$filehtaccess = $pathofwebsite.'/.htaccess';
260$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
261$fileindex = $pathofwebsite.'/index.php';
262$filewrapper = $pathofwebsite.'/wrapper.php';
263$filemanifestjson = $pathofwebsite.'/manifest.json.php';
264$filereadme = $pathofwebsite.'/README.md';
265$filelicense = $pathofwebsite.'/LICENSE';
266$filemaster = $pathofwebsite.'/master.inc.php';
267
268$forceCSP = getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSP");
269
270// Define $urlwithroot
271$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
272$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
273//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
274
275
276$permtouploadfile = $user->hasRight('website', 'write');
277$diroutput = $conf->medias->multidir_output[$conf->entity];
278
279$relativepath = $section_dir;
280$upload_dir = preg_replace('/\/$/', '', $diroutput).'/'.preg_replace('/^\//', '', $relativepath);
281
282$htmlheadercontentdefault = '';
283$htmlheadercontentdefault .= '<link rel="stylesheet" id="google-fonts-css" href="//fonts.googleapis.com/css?family=Open+Sans:300,400,700" />'."\n";
284$htmlheadercontentdefault .= '<link rel="stylesheet" id="font-wasesome-css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />'."\n";
285$htmlheadercontentdefault .= '<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>'."\n";
286$htmlheadercontentdefault .= '<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>'."\n";
287$htmlheadercontentdefault .= '<!--'."\n";
288$htmlheadercontentdefault .= '<script src="/document.php?modulepart=medias&file=css/myfile.css"></script>'."\n";
289$htmlheadercontentdefault .= '<script src="/document.php?modulepart=medias&file=js/myfile.js"></script>'."\n";
290$htmlheadercontentdefault .= '-->'."\n";
291
292$manifestjsoncontentdefault = '';
293$manifestjsoncontentdefault .= '{
294 "name": "MyWebsite",
295 "short_name": "MyWebsite",
296 "start_url": "/",
297 "lang": "en-US",
298 "display": "standalone",
299 "background_color": "#fff",
300 "description": "A simple Web app.",
301 "icons": [{
302 "src": "images/'.urlencode($website->ref).'/homescreen48.png",
303 "sizes": "48x48",
304 "type": "image/png"
305 }, {
306 "src": "image/'.urlencode($website->ref).'/homescreen72.png",
307 "sizes": "72x72",
308 "type": "image/png"
309 }, {
310 "src": "image/'.urlencode($website->ref).'/homescreen96.png",
311 "sizes": "96x96",
312 "type": "image/png"
313 }, {
314 "src": "image/'.urlencode($website->ref).'/homescreen144.png",
315 "sizes": "144x144",
316 "type": "image/png"
317 }, {
318 "src": "image/'.urlencode($website->ref).'/homescreen168.png",
319 "sizes": "168x168",
320 "type": "image/png"
321 }, {
322 "src": "image/'.urlencode($website->ref).'/homescreen192.png",
323 "sizes": "192x192",
324 "type": "image/png"
325 }],
326 "related_applications": [{
327 "platform": "play",
328 "url": "https://play.google.com/store/apps/details?id=com.nltechno.dolidroidpro"
329 }]
330}';
331
332$listofpages = array();
333
334$algo = '';
335if (GETPOST('optionpcontent')) {
336 $algo .= 'content';
337}
338if (GETPOST('optionmeta')) {
339 $algo .= 'meta';
340}
341if (GETPOST('optionsitefiles')) {
342 $algo .= 'sitefiles';
343}
344
345$searchkey = GETPOST('searchstring', 'restricthtmlallowunvalid'); // or 'none', must be same as $searchstring
346
347if ($sortfield == '') {
348 if ($action == 'file_manager') { // Test on permission not required
349 $sortfield = 'name';
350 $sortorder = 'ASC';
351 } else {
352 $sortfield = 'pageurl';
353 $sortorder = 'ASC';
354 }
355}
356'@phan-var-force string $sortfield';
357
358$langcode = '';
359$containertype = '';
360$otherfilters = array();
361
362if ($action == 'replacesite' || $mode == 'replacesite') { // Test on permission not required
363 $containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : '';
364 $langcode = GETPOST('optionlanguage', 'aZ09');
365 if (GETPOSTINT('optioncategory') > 0) {
366 $otherfilters['category'] = GETPOSTINT('optioncategory');
367 }
368
369 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters, -1);
370}
371
372$usercanedit = $user->hasRight('website', 'write');
373$permissiontoadd = $user->hasRight('website', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php
374$permissiontodelete = $user->hasRight('website', 'delete');
375
376
377/*
378 * Actions
379 */
380
381// Protections
382if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x')) {
383 $action = 'preview'; // To avoid to make an action on another page or another site when we click on button to select another site or page.
384}
385if (GETPOST('refreshsite', 'alpha') || GETPOST('refreshsite.x', 'alpha') || GETPOST('refreshsite_x', 'alpha')) { // If we change the site, we reset the pageid and cancel addsite action.
386 if ($action == 'addsite') { // Test on permission not required here
387 $action = 'preview';
388 }
389 if ($action == 'updatesource') { // Test on permission not required here
390 $action = 'preview';
391 }
392
393 $pageid = $object->fk_default_home;
394 if (empty($pageid)) {
395 $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
396 if (!is_array($array) && $array < 0) {
397 dol_print_error(null, $objectpage->error, $objectpage->errors);
398 }
399 $atleastonepage = (is_array($array) && count($array) > 0);
400
401 $firstpageid = 0;
402 $homepageid = 0;
403 foreach ($array as $key => $valpage) {
404 if (empty($firstpageid)) {
405 $firstpageid = $valpage->id;
406 }
407 if ($object->fk_default_home && $key == $object->fk_default_home) {
408 $homepageid = $valpage->id;
409 }
410 }
411 $pageid = ($homepageid ? $homepageid : $firstpageid); // We choose home page and if not defined yet, we take first page
412 }
413}
414if (GETPOST('refreshpage', 'alpha') && !in_array($action, array('updatecss'))) {
415 $action = 'preview';
416}
417
418if ($cancel && $action == 'renamefile') { // Test on permission not required here
419 $cancel = '';
420}
421
422// Cancel
423if ($cancel) {
424 $action = 'preview';
425 $mode = '';
426 if ($backtopage) {
427 header("Location: ".$backtopage);
428 exit;
429 }
430}
431
432$savbacktopage = $backtopage;
433$backtopage = $_SERVER["PHP_SELF"].'?file_manager=1&website='.urlencode($websitekey).'&pageid='.urlencode((string) $pageid).(GETPOST('section_dir', 'alpha') ? '&section_dir='.urlencode(GETPOST('section_dir', 'alpha')) : ''); // used after a confirm_deletefile into actions_linkedfiles.inc.php
434if ($sortfield) {
435 $backtopage .= '&sortfield='.urlencode($sortfield);
436}
437if ($sortorder) {
438 $backtopage .= '&sortorder='.urlencode($sortorder);
439}
440include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; // This manage 'sendit', 'confirm_deletefile', 'renamefile' action when submitting a new file.
441
442$backtopage = $savbacktopage;
443//var_dump($backtopage);
444//var_dump($action);
445
446if ($action == 'renamefile') { // Test on permission not required here. Must be after include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; If action were renamefile, we set it to 'file_manager'
447 $action = 'file_manager';
448}
449
450if ($action == 'setwebsiteonline' && $usercanedit) {
451 $website->setStatut($website::STATUS_VALIDATED, null, '', 'WEBSITE_MODIFY', 'status');
452
453 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('websitepage'));
454 exit;
455}
456if ($action == 'setwebsiteoffline' && $usercanedit) {
457 $result = $website->setStatut($website::STATUS_DRAFT, null, '', 'WEBSITE_MODIFY', 'status');
458
459 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('websitepage'));
460 exit;
461}
462if ($action == 'seteditinline') { // Test on permission not required here
463 if (!getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) {
464 // Show warning for feature not yet ready
465 setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
466 }
467
468 dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 1);
469 //dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 0); // Force disable of 'Include dynamic content'
470 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid'));
471 exit;
472}
473if ($action == 'unseteditinline') { // Test on permission not required here
474 dolibarr_del_const($db, 'WEBSITE_EDITINLINE');
475 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid'));
476 exit;
477}
478if ($action == 'setshowsubcontainers') { // Test on permission not required here
479 dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1);
480 //dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 0); // Force disable of edit inline
481 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid'));
482 exit;
483}
484if ($action == 'unsetshowsubcontainers') { // Test on permission not required here
485 dolibarr_del_const($db, 'WEBSITE_SUBCONTAINERSINLINE');
486 header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid'));
487 exit;
488}
489
490if ($massaction == 'replace' && GETPOST('confirmmassaction', 'alpha') && !$searchkey && $usercanedit) {
491 $mode = 'replacesite';
492 $action = 'replacesite';
493 $massaction = '';
494}
495
496if ($action == 'deletetemplate' && $usercanedit) {
497 $dirthemes = array('/doctemplates/websites');
498 if (!empty($conf->modules_parts['websitetemplates'])) { // Using this feature slow down application
499 foreach ($conf->modules_parts['websitetemplates'] as $reldir) {
500 $dirthemes = array_merge($dirthemes, (array) ($reldir.'doctemplates/websites'));
501 }
502 }
503 $dirthemes = array_unique($dirthemes);
504
505
506 // Delete template files and dir
507 $mode = 'importsite';
508 $action = 'importsite';
509
510 if (count($dirthemes)) {
511 $i = 0;
512 foreach ($dirthemes as $dir) {
513 //print $dirroot.$dir;exit;
514 $dirtheme = DOL_DATA_ROOT.$dir; // This include loop on $conf->file->dol_document_root
515 if (is_dir($dirtheme)) {
516 $templateuserfile = GETPOST('templateuserfile');
517 $imguserfile = preg_replace('/\.zip$/', '', $templateuserfile).'.jpg';
518 dol_delete_file($dirtheme.'/'.$templateuserfile);
519 dol_delete_file($dirtheme.'/'.$imguserfile);
520 }
521 }
522 }
523}
524
525// Set category
526if ($massaction == 'setcategory' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) {
527 $error = 0;
528 $nbupdate = 0;
529
530 $db->begin();
531
532 $categoryid = GETPOSTINT('setcategory');
533 if ($categoryid > 0) {
534 $tmpwebsitepage = new WebsitePage($db);
535 $category = new Categorie($db);
536 $category->fetch($categoryid);
537
538 foreach ($toselect as $tmpid) {
539 $tmpwebsitepage->id = (int) $tmpid;
540 $result = $category->add_type($tmpwebsitepage, 'website_page');
541 if ($result < 0 && $result != -3) {
542 $error++;
543 setEventMessages($category->error, $category->errors, 'errors');
544 break;
545 } else {
546 $nbupdate++;
547 }
548 }
549 }
550
551 if ($error) {
552 $db->rollback();
553 } else {
554 if ($nbupdate) {
555 setEventMessages($langs->trans("RecordsModified", $nbupdate), null, 'mesgs');
556 }
557
558 $db->commit();
559 }
560 // Now we reload list
561 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters, -1);
562}
563
564// Del category
565if ($massaction == 'delcategory' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) {
566 $error = 0;
567 $nbupdate = 0;
568
569 $db->begin();
570
571 $categoryid = GETPOSTINT('setcategory');
572 if ($categoryid > 0) {
573 $tmpwebsitepage = new WebsitePage($db);
574 $category = new Categorie($db);
575 $category->fetch($categoryid);
576
577 foreach ($toselect as $tmpid) {
578 $tmpwebsitepage->id = (int) $tmpid;
579 $result = $category->del_type($tmpwebsitepage, 'website_page');
580 if ($result < 0 && $result != -3) {
581 $error++;
582 setEventMessages($category->error, $category->errors, 'errors');
583 break;
584 } else {
585 $nbupdate++;
586 }
587 }
588 }
589
590 if ($error) {
591 $db->rollback();
592 } else {
593 if ($nbupdate) {
594 setEventMessages($langs->trans("RecordsModified", $nbupdate), null, 'mesgs');
595 }
596
597 $db->commit();
598 }
599 // Now we reload list
600 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters, -1);
601}
602
603// Replacement of string into pages
604if ($massaction == 'replace' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) {
605 $replacestring = GETPOST('replacestring', 'restricthtmlallowunvalid'); // or 'none', must be same then $searchstring
606
607 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
608 $allowimportsite = true;
609 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
610 $allowimportsite = false;
611 }
612
613 if (!$allowimportsite) {
614 // Blocked by installmodules.lock
615 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
616 // Show clean corporate message
617 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
618 } else {
619 // Show technical generic message
620 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
621 }
622 setEventMessages($message, null, 'errors');
623 } elseif (!$user->hasRight('website', 'writephp')) {
624 setEventMessages("NotAllowedToAddDynamicContent", null, 'errors');
625 } elseif (!$replacestring) {
626 setEventMessages("ErrorReplaceStringEmpty", null, 'errors');
627 } else {
628 $nbreplacement = 0;
629
630 foreach ($toselect as $keyselected) {
631 $objectpage = $listofpages['list'][$keyselected];
632 if ($objectpage->pageurl) {
633 dol_syslog("Replace string into page ".$objectpage->pageurl);
634
635 if (GETPOST('optionpcontent', 'aZ09')) {
636 $objectpage->content = str_replace($searchkey, $replacestring, $objectpage->content);
637 }
638 if (GETPOST('optionmeta', 'aZ09')) {
639 $objectpage->title = str_replace($searchkey, $replacestring, $objectpage->title);
640 $objectpage->description = str_replace($searchkey, $replacestring, $objectpage->description);
641 $objectpage->keywords = str_replace($searchkey, $replacestring, $objectpage->keywords);
642 }
643
644 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
645 $filetpl = $pathofwebsite.'/page'.$objectpage->id.'.tpl.php';
646
647 // Save page alias
648 $result = dolSavePageAlias($filealias, $object, $objectpage);
649 if (!$result) {
650 setEventMessages('Failed to write file '.basename($filealias), null, 'errors');
651 }
652
653 // Save page of content
654 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
655 if ($result) {
656 $nbreplacement++;
657 //var_dump($objectpage->content);exit;
658 $objectpage->update($user);
659 } else {
660 $error++;
661 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
662 $action = 'createcontainer';
663 break;
664 }
665 }
666 }
667
668 if ($nbreplacement > 0) {
669 setEventMessages($langs->trans("ReplacementDoneInXPages", $nbreplacement), null, 'mesgs');
670 }
671
672 $containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : '';
673 $langcode = GETPOST('optionlanguage', 'aZ09');
674 $otherfilters = array();
675 if (GETPOSTINT('optioncategory') > 0) {
676 $otherfilters['category'] = GETPOSTINT('optioncategory');
677 }
678
679 // Now we reload list
680 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters);
681 }
682}
683
684
685// Add directory
686/*
687if ($action == 'adddir' && $permtouploadfile)
688{
689 $ecmdir->ref = 'NOTUSEDYET';
690 $ecmdir->label = GETPOST("label");
691 $ecmdir->description = GETPOST("desc");
692
693 //$id = $ecmdir->create($user);
694 if ($id > 0)
695 {
696 header("Location: ".$_SERVER["PHP_SELF"]);
697 exit;
698 }
699 else
700 {
701 setEventMessages('Error '.$langs->trans($ecmdir->error), null, 'errors');
702 $action = "createcontainer";
703 }
704
705 clearstatcache();
706}
707*/
708
709// Add a website
710if ($action == 'addsite' && $usercanedit) {
711 $db->begin();
712
713 if (GETPOST('virtualhost', 'alpha') && !preg_match('/^http/', GETPOST('virtualhost', 'alpha'))) {
714 $error++;
715 setEventMessages($langs->trans('ErrorURLMustStartWithHttp', $langs->transnoentitiesnoconv("VirtualHost")), null, 'errors');
716 }
717
718 if (!$error && !GETPOST('WEBSITE_REF', 'alpha')) {
719 $error++;
720 $langs->load("errors");
721 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("WebsiteName")), null, 'errors');
722 }
723 if (!$error && !preg_match('/^[a-z0-9_\-\.]+$/i', GETPOST('WEBSITE_REF', 'alpha'))) {
724 $error++;
725 $langs->load("errors");
726 setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("Ref")), null, 'errors');
727 }
728
729 $tmpobject = null;
730 if (!$error) {
731 $arrayotherlang = explode(',', GETPOST('WEBSITE_OTHERLANG', 'alphanohtml'));
732 foreach ($arrayotherlang as $key => $val) {
733 // It possible we have empty val here if postparam WEBSITE_OTHERLANG is empty or set like this : 'en,,sv' or 'en,sv,'
734 if (empty(trim($val))) {
735 continue;
736 }
737 $arrayotherlang[$key] = substr(trim($val), 0, 2); // Kept short language code only
738 }
739
740 $tmpobject = new Website($db);
741 $tmpobject->ref = GETPOST('WEBSITE_REF', 'alpha');
742 $tmpobject->description = GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml');
743 $tmpobject->lang = GETPOST('WEBSITE_LANG', 'aZ09');
744 $tmpobject->otherlang = implode(',', $arrayotherlang);
745 $tmpobject->virtualhost = GETPOST('virtualhost', 'alpha');
746
747 $result = $tmpobject->create($user);
748 if ($result == 0) {
749 $error++;
750 setEventMessages($langs->trans("ErrorLabelAlreadyExists"), null, 'errors');
751 } elseif ($result < 0) {
752 $error++;
753 setEventMessages($tmpobject->error, $tmpobject->errors, 'errors');
754 }
755 }
756
757 if (!$error && $tmpobject !== null) {
758 $db->commit();
759 setEventMessages($langs->trans("SiteAdded", $object->ref), null, 'mesgs');
760 $action = '';
761
762 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$tmpobject->ref);
763 exit;
764 } else {
765 $db->rollback();
766 $action = 'createsite';
767 }
768
769 if (!$error) {
770 $action = 'preview';
771 $id = $object->id;
772 }
773}
774
775'@phan-var-force int $error';
776
777// Add page/container
778if ($action == 'addcontainer' && $usercanedit) {
779 dol_mkdir($pathofwebsite);
780
781 $db->begin();
782
783 $objectpage->fk_website = $object->id;
784 $objectpage->status = $objectpage::STATUS_DRAFT;
785
786 if (GETPOSTISSET('fetchexternalurl')) { // Fetch from external url
787 $urltograb = GETPOST('externalurl', 'alpha');
788 $grabimages = GETPOSTINT('grabimages') ? 1 : 0;
789 $grabimagesinto = GETPOST('grabimagesinto', 'alpha');
790
791 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
792 // The include seems to break typing on variables
793
794 if (empty($urltograb)) {
795 $error++;
796 $langs->load("errors");
797 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("URL")), null, 'errors');
798 $action = 'createcontainer';
799 } elseif (!preg_match('/^http/', $urltograb)) {
800 $error++;
801 $langs->load("errors");
802 setEventMessages('Error URL must start with http:// or https://', null, 'errors');
803 $action = 'createcontainer';
804 }
805
806 $pageurl = '';
807 $urltograbdirwithoutslash = '';
808 $urltograbdirrootwithoutslash = '';
809 if (!$error) {
810 // Clean url to grab, so url can be
811 // http://www.example.com/ or http://www.example.com/dir1/ or http://www.example.com/dir1/aaa
812 $urltograbwithoutdomainandparam = preg_replace('/^https?:\/\/[^\/]+\/?/i', '', $urltograb);
813 //$urltograbwithoutdomainandparam = preg_replace('/^file:\/\/[^\/]+\/?/i', '', $urltograb);
814 $urltograbwithoutdomainandparam = preg_replace('/\?.*$/', '', $urltograbwithoutdomainandparam);
815 if (empty($urltograbwithoutdomainandparam) && !preg_match('/\/$/', $urltograb)) {
816 $urltograb .= '/';
817 }
818 $pageurl = dol_sanitizeFileName(preg_replace('/[\/\.]/', '-', preg_replace('/\/+$/', '', $urltograbwithoutdomainandparam)));
819
820 $urltograbdirwithoutslash = dirname($urltograb.'.');
821 $urltograbdirrootwithoutslash = getRootURLFromURL($urltograbdirwithoutslash);
822 // Example, now $urltograbdirwithoutslash is https://www.dolimed.com/screenshots
823 // and $urltograbdirrootwithoutslash is https://www.dolimed.com
824 }
825
826 // Check pageurl is not already used
827 if ($pageurl) {
828 $tmpwebsitepage = new WebsitePage($db);
829 $result = $tmpwebsitepage->fetch(0, (string) $object->id, $pageurl);
830 if ($result > 0) {
831 setEventMessages($langs->trans("AliasPageAlreadyExists", $pageurl), null, 'errors');
832 $error++;
833 $action = 'createcontainer';
834 }
835 }
836
837 if (!$error) {
838 // Download URL to grab
839 $tmp = getURLContent($urltograb, 'GET', '', 1, array(), array('http', 'https'), 0);
840
841 // Test charset of result and convert it into UTF-8 if not in this encoding charset
842 if (!empty($tmp['content_type']) && preg_match('/ISO-8859-1/', $tmp['content_type'])) {
843 if (function_exists('mb_check_encoding')) {
844 if (mb_check_encoding($tmp['content'], 'ISO-8859-1')) {
845 // This is a ISO-8829-1 encoding string
846 $tmp['content'] = mb_convert_encoding($tmp['content'], 'ISO-8859-1', 'UTF-8');
847 } else {
848 $error++;
849 setEventMessages('Error getting '.$urltograb.': content seems non valid ISO-8859-1', null, 'errors');
850 $action = 'createcontainer';
851 }
852 } else {
853 $error++;
854 setEventMessages('Error getting '.$urltograb.': content seems ISO-8859-1 but functions to convert into UTF-8 are not available in your PHP', null, 'errors');
855 $action = 'createcontainer';
856 }
857 }
858 if (empty($tmp['content_type']) || (!empty($tmp['content_type']) && preg_match('/UTF-8/', $tmp['content_type']))) {
859 if (function_exists('mb_check_encoding')) {
860 if (mb_check_encoding($tmp['content'], 'UTF-8')) {
861 // This is a UTF8 or ASCII compatible string
862 } else {
863 $error++;
864 setEventMessages('Error getting '.$urltograb.': content seems not a valid UTF-8', null, 'errors');
865 $action = 'createcontainer';
866 }
867 }
868 }
869
870 if (!empty($tmp['curl_error_no'])) {
871 $error++;
872 setEventMessages('Error getting '.$urltograb.': '.$tmp['curl_error_msg'], null, 'errors');
873 $action = 'createcontainer';
874 } elseif ($tmp['http_code'] != 200) {
875 $error++;
876 setEventMessages('Error getting '.$urltograb.': '.$tmp['http_code'], null, 'errors');
877 $action = 'createcontainer';
878 } else {
879 // Remove comments
880 $tmp['content'] = removeHtmlComment($tmp['content']);
881
882 /* disable this, moved into the create() method
883 // Check there is no PHP content into the imported file (must be only HTML + JS)
884 $phpcontent = dolKeepOnlyPhpCode($tmp['content']);
885 if ($phpcontent) {
886 $error++;
887 setEventMessages('Error getting '.$urltograb.': file that include PHP content is not allowed', null, 'errors');
888 $action = 'createcontainer';
889 }
890 */
891 }
892
893 if (!$error) {
894 $regs = array();
895
896 preg_match('/<head>(.*)<\/head>/ims', $tmp['content'], $regs);
897 $head = $regs[1];
898
899 $objectpage->type_container = 'page';
900 $objectpage->pageurl = $pageurl;
901 if (empty($objectpage->pageurl)) {
902 $tmpdomain = getDomainFromURL($urltograb);
903 $objectpage->pageurl = $tmpdomain.'-home';
904 }
905
906 $objectpage->aliasalt = '';
907
908 if (preg_match('/^(\d+)\-/', basename($urltograb), $regs)) {
909 $objectpage->aliasalt = $regs[1];
910 }
911
912 $regtmp = array();
913 if (preg_match('/<title>(.*)<\/title>/ims', $head, $regtmp)) {
914 $objectpage->title = $regtmp[1];
915 }
916 if (preg_match('/<meta name="title"[^"]+content="([^"]+)"/ims', $head, $regtmp)) {
917 if (empty($objectpage->title)) {
918 $objectpage->title = $regtmp[1]; // If title not found into <title>, we get it from <meta title>
919 }
920 }
921 if (preg_match('/<meta name="description"[^"]+content="([^"]+)"/ims', $head, $regtmp)) {
922 $objectpage->description = $regtmp[1];
923 }
924 if (preg_match('/<meta name="keywords"[^"]+content="([^"]+)"/ims', $head, $regtmp)) {
925 $objectpage->keywords = $regtmp[1];
926 }
927 if (preg_match('/<html\s+lang="([^"]+)"/ims', $tmp['content'], $regtmp)) {
928 $tmplang = explode('-', $regtmp[1]);
929 $objectpage->lang = $tmplang[0].(empty($tmplang[1]) ? '' : '_'.strtoupper($tmplang[1]));
930 }
931
932 $tmp['content'] = preg_replace('/\s*<meta name="generator"[^"]+content="([^"]+)"\s*\/?>/ims', '', $tmp['content']);
933
934 $objectpage->content = $tmp['content'];
935 $objectpage->content = preg_replace('/^.*<body(\s[^>]*)*>/ims', '', $objectpage->content);
936 $objectpage->content = preg_replace('/<\/body(\s[^>]*)*>.*$/ims', '', $objectpage->content);
937
938 // TODO Replace 'action="$urltograbdirwithoutslash' into action="/"
939 // TODO Replace 'action="$urltograbdirwithoutslash..."' into action="..."
940 // TODO Replace 'a href="$urltograbdirwithoutslash' into a href="/"
941 // TODO Replace 'a href="$urltograbdirwithoutslash..."' into a href="..."
942
943 // Now loop to fetch all css files. Include them inline into header of page
944 $objectpage->htmlheader = $tmp['content'];
945 $objectpage->htmlheader = preg_replace('/^.*<head(\s[^>]*)*>/ims', '', $objectpage->htmlheader);
946 $objectpage->htmlheader = preg_replace('/<\/head(\s[^>]*)*>.*$/ims', '', $objectpage->htmlheader);
947 $objectpage->htmlheader = preg_replace('/<base(\s[^>]*)*>\n*/ims', '', $objectpage->htmlheader);
948 $objectpage->htmlheader = preg_replace('/<meta http-equiv="content-type"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
949 $objectpage->htmlheader = preg_replace('/<meta name="robots"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
950 $objectpage->htmlheader = preg_replace('/<meta name="title"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
951 $objectpage->htmlheader = preg_replace('/<meta name="description"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
952 $objectpage->htmlheader = preg_replace('/<meta name="keywords"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
953 $objectpage->htmlheader = preg_replace('/<meta name="generator"([^>]*)*>\n*/ims', '', $objectpage->htmlheader);
954 //$objectpage->htmlheader = preg_replace('/<meta name="verify-v1[^>]*>\n*/ims', '', $objectpage->htmlheader);
955 //$objectpage->htmlheader = preg_replace('/<meta name="msvalidate.01[^>]*>\n*/ims', '', $objectpage->htmlheader);
956 $objectpage->htmlheader = preg_replace('/<title>[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader);
957 $objectpage->htmlheader = preg_replace('/<link[^>]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader);
958 $objectpage->htmlheader = preg_replace('/<link[^>]*rel="alternate[^>]*>\n/ims', '', $objectpage->htmlheader);
959 $objectpage->htmlheader = preg_replace('/<link[^>]*rel="canonical[^>]*>\n/ims', '', $objectpage->htmlheader);
960
961 // Now loop to fetch JS
962 $tmp = $objectpage->htmlheader;
963
964 // We grab files found into <script> tags
965 preg_match_all('/<script([^\.>]+)src=["\']([^"\'>]+)["\']([^>]*)><\/script>/i', $objectpage->htmlheader, $regs);
966 $errorforsubresource = 0;
967 foreach ($regs[0] as $key => $val) {
968 dol_syslog("We will grab the script resource found into script tag ".$regs[2][$key]);
969
970 $linkwithoutdomain = $regs[2][$key];
971 if (preg_match('/^\//', $regs[2][$key])) {
972 $urltograbbis = $urltograbdirrootwithoutslash.$regs[2][$key]; // We use dirroot
973 } else {
974 $urltograbbis = $urltograbdirwithoutslash.'/'.$regs[2][$key]; // We use dir of grabbed file
975 }
976
977 //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key];
978 if (preg_match('/^http/', $regs[2][$key])) {
979 $urltograbbis = $regs[2][$key];
980 $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]);
981 //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain;
982 }
983
984 //print $domaintograb.' - '.$domaintograbbis.' - '.$urltograbdirwithoutslash.' - ';
985 //print $linkwithoutdomain.' - '.$urltograbbis."<br>\n";
986
987 // Test if this is an external URL of grabbed web site. If yes, we do not load resource
988 $domaintograb = getDomainFromURL($urltograbdirwithoutslash);
989 $domaintograbbis = getDomainFromURL($urltograbbis);
990 if ($domaintograb != $domaintograbbis) {
991 continue;
992 }
993
994 /*
995 $tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
996 if (!empty($tmpgeturl['curl_error_no']))
997 {
998 $error++;
999 setEventMessages('Error getting script url '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors');
1000 $errorforsubresource++;
1001 $action='createcontainer';
1002 }
1003 elseif ($tmpgeturl['http_code'] != 200)
1004 {
1005 $error++;
1006 setEventMessages('Error getting script url '.$urltograbbis.': '.$tmpgeturl['http_code'], null, 'errors');
1007 $errorforsubresource++;
1008 $action='createcontainer';
1009 }
1010 else
1011 {
1012 dol_mkdir(dirname($filetosave));
1013
1014 $fp = fopen($filetosave, "w");
1015 fputs($fp, $tmpgeturl['content']);
1016 fclose($fp);
1017 dolChmod($file);
1018 }
1019 */
1020
1021 //$filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain;
1022 $tmp = preg_replace('/'.preg_quote($regs[0][$key], '/').'/i', '', $tmp);
1023 }
1024 $objectpage->htmlheader = trim($tmp)."\n";
1025
1026
1027 // Now we grab CSS found into <link> tags
1028 $pagecsscontent = "\n".'<style>'."\n";
1029
1030 preg_match_all('/<link([^\.>]+)href=["\']([^"\'>]+\.css[^"\'>]*)["\']([^>]*)>/i', $objectpage->htmlheader, $regs);
1031 $errorforsubresource = 0;
1032 foreach ($regs[0] as $key => $val) {
1033 dol_syslog("We will grab the css resources found into link tag ".$regs[2][$key]);
1034
1035 $linkwithoutdomain = $regs[2][$key];
1036 if (preg_match('/^\//', $regs[2][$key])) {
1037 $urltograbbis = $urltograbdirrootwithoutslash.$regs[2][$key]; // We use dirroot
1038 } else {
1039 $urltograbbis = $urltograbdirwithoutslash.'/'.$regs[2][$key]; // We use dir of grabbed file
1040 }
1041
1042 //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key];
1043 if (preg_match('/^http/', $regs[2][$key])) {
1044 $urltograbbis = $regs[2][$key];
1045 $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]);
1046 //$filetosave = $conf->medias->multidir_output[$conf->entity].'/css/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain;
1047 }
1048
1049 //print $domaintograb.' - '.$domaintograbbis.' - '.$urltograbdirwithoutslash.' - ';
1050 //print $linkwithoutdomain.' - '.$urltograbbis."<br>\n";
1051
1052 // Test if this is an external URL of grabbed web site. If yes, we do not load resource
1053 $domaintograb = getDomainFromURL($urltograbdirwithoutslash);
1054 $domaintograbbis = getDomainFromURL($urltograbbis);
1055 if ($domaintograb != $domaintograbbis) {
1056 continue;
1057 }
1058
1059 $tmpgeturl = getURLContent($urltograbbis, 'GET', '', 1, array(), array('http', 'https'), 0);
1060 if (!empty($tmpgeturl['curl_error_no'])) {
1061 $errorforsubresource++;
1062 setEventMessages('Error getting link tag url '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors');
1063 dol_syslog('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg']);
1064 $action = 'createcontainer';
1065 } elseif ($tmpgeturl['http_code'] != 200) {
1066 $errorforsubresource++;
1067 setEventMessages('Error getting link tag url '.$urltograbbis.': '.$tmpgeturl['http_code'], null, 'errors');
1068 dol_syslog('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg']);
1069 $action = 'createcontainer';
1070 } else {
1071 // Clean some comment
1072 //$tmpgeturl['content'] = dol_string_is_good_iso($tmpgeturl['content'], 1);
1073 //$tmpgeturl['content'] = mb_convert_encoding($tmpgeturl['content'], 'UTF-8', 'UTF-8');
1074 //$tmpgeturl['content'] = remove_bs($tmpgeturl['content']);
1075 //$tmpgeturl['content'] = str_replace('$screen-md-max', 'auto', $tmpgeturl['content']);
1076
1077 //var_dump($tmpgeturl['content']);exit;
1078 $tmpgeturl['content'] = preg_replace('/\/\*\s+CSS content[a-z\s]*\s+\*\//', '', $tmpgeturl['content']);
1079
1080 //dol_mkdir(dirname($filetosave));
1081
1082 //$fp = fopen($filetosave, "w");
1083 //fputs($fp, $tmpgeturl['content']);
1084 //fclose($fp);
1085 //dolChmod($file);
1086
1087 // $filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain;
1088 $pagecsscontent .= "\n".'/* Content of file '.$urltograbbis.' */'."\n";
1089
1090 getAllImages($object, $objectpage, $urltograbbis, $tmpgeturl['content'], $action, 1, $grabimages, $grabimagesinto);
1091
1092 // We try to convert the CSS we got by adding a prefix .bodywebsite with lessc to avoid conflict with CSS of Dolibarr.
1093 include_once DOL_DOCUMENT_ROOT.'/core/class/lessc.class.php';
1094 $lesscobj = new Lessc();
1095 try {
1096 $contentforlessc = ".bodywebsite {\n".$tmpgeturl['content']."\n}\n";
1097 //print '<pre>'.$contentforlessc.'</pre>';
1098 $contentforlessc = $lesscobj->compile($contentforlessc);
1099 //var_dump($contentforlessc); exit;
1100
1101 $pagecsscontent .= $contentforlessc."\n";
1102 //$pagecsscontent.=$tmpgeturl['content']."\n";
1103 } catch (Exception $e) {
1104 //echo "failed to compile lessc";
1105 dol_syslog("Failed to compile the CSS from URL ".$urltograbbis." with lessc: ".$e->getMessage(), LOG_WARNING);
1106 $pagecsscontent .= $tmpgeturl['content']."\n";
1107 }
1108
1109 $objectpage->htmlheader = preg_replace('/'.preg_quote($regs[0][$key], '/').'\n*/ims', '', $objectpage->htmlheader);
1110 }
1111 }
1112
1113 $pagecsscontent .= '</style>';
1114 //var_dump($pagecsscontent);
1115
1116 //print dol_escape_htmltag($tmp);exit;
1117 $objectpage->htmlheader .= trim($pagecsscontent)."\n";
1118
1119
1120 // Now we have to fetch all images into page
1121 $tmp = $objectpage->content;
1122
1123 getAllImages($object, $objectpage, $urltograb, $tmp, $action, 1, $grabimages, $grabimagesinto);
1124
1125 // Normalize links href to Dolibarr internal naming
1126 $tmp = preg_replace('/a href="\/([^\/"]+)\/([^\/"]+)"/', 'a href="/\1-\2.php"', $tmp);
1127 $tmp = preg_replace('/a href="\/([^\/"]+)\/([^\/"]+)\/([^\/"]+)"/', 'a href="/\1-\2-\3.php"', $tmp);
1128 $tmp = preg_replace('/a href="\/([^\/"]+)\/([^\/"]+)\/([^\/"]+)\/([^\/"]+)"/', 'a href="/\1-\2-\3-\4.php"', $tmp);
1129
1130 //print dol_escape_htmltag($tmp);exit;
1131 $objectpage->content = $tmp;
1132
1133 $objectpage->grabbed_from = $urltograb;
1134 }
1135 }
1136 } else { // add website from scratch
1137 $newaliasnames = '';
1138 if (!$error && GETPOST('WEBSITE_ALIASALT', 'alpha')) {
1139 $arrayofaliastotest = explode(',', str_replace(array('<', '>'), '', GETPOST('WEBSITE_ALIASALT', 'alpha')));
1140 $websitepagetemp = new WebsitePage($db);
1141 foreach ($arrayofaliastotest as $aliastotest) {
1142 $aliastotest = trim(preg_replace('/\.php$/i', '', $aliastotest));
1143
1144 // Disallow alias name pageX (already used to save the page with id)
1145 if (preg_match('/^page\d+/i', $aliastotest)) {
1146 $error++;
1147 $langs->load("errors");
1148 setEventMessages("Alias name 'pageX' is not allowed", null, 'errors');
1149 $action = 'createcontainer';
1150 break;
1151 } else {
1152 $result = $websitepagetemp->fetch(0, (string) $object->id, $aliastotest);
1153 if ($result < 0) {
1154 $error++;
1155 $langs->load("errors");
1156 setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
1157 $action = 'createcontainer';
1158 break;
1159 }
1160 if ($result > 0) {
1161 $error++;
1162 $langs->load("errors");
1163 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
1164 $action = 'createcontainer';
1165 break;
1166 }
1167 $newaliasnames .= ($newaliasnames ? ', ' : '').$aliastotest;
1168 }
1169 }
1170 }
1171
1172 $objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
1173 $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09');
1174 $objectpage->pageurl = dol_sanitizeUrl(GETPOST('WEBSITE_PAGENAME', 'alpha'));
1175 $objectpage->ref = $objectpage->pageurl;
1176 $objectpage->aliasalt = $newaliasnames;
1177 $objectpage->description = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
1178 $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09');
1179 $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
1180 $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha');
1181 $objectpage->keywords = str_replace(array('<', '>'), '', GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'));
1182 $objectpage->allowed_in_frames = GETPOST('WEBSITE_ALLOWED_IN_FRAMES', 'aZ09') ? 1 : 0;
1183 $objectpage->htmlheader = GETPOST('htmlheader', 'restricthtmlallowlinkscript'); // Must accept tags like '<script>' and '<link>'
1184
1185 $objectpage->author_alias = GETPOST('WEBSITE_AUTHORALIAS', 'alphanohtml');
1186 $objectpage->object_type = GETPOST('WEBSITE_OBJECTCLASS');
1187 $objectpage->fk_object = GETPOST('WEBSITE_OBJECTID');
1188 $substitutionarray = array();
1189 $substitutionarray['__WEBSITE_CREATED_BY__'] = $user->getFullName($langs);
1190
1191 // Define id of the page the new page is translation of
1192 /*
1193 if ($objectpage->lang == $object->lang) {
1194 // If
1195 $pageidfortranslation = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
1196 if ($pageidfortranslation > 0) {
1197 // We must update the page $pageidfortranslation to set fk_page = $object->id.
1198 // But what if page $pageidfortranslation is already linked to another ?
1199 }
1200 } else {
1201 */
1202 $pageidfortranslation = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
1203 if ($pageidfortranslation > 0) {
1204 // Check if the page we are translation of is already a translation of a source page. if yes, we will use source id instead
1205 $objectpagetmp = new WebsitePage($db);
1206 $objectpagetmp->fetch($pageidfortranslation);
1207 if ($objectpagetmp->fk_page > 0) {
1208 $pageidfortranslation = $objectpagetmp->fk_page;
1209 }
1210 }
1211 $objectpage->fk_page = $pageidfortranslation;
1212 //}
1213
1214 $content = '';
1215 if (GETPOSTISSET('content')) {
1216 //$content = GETPOST('content', 'restricthtmlallowunvalid'); // @TODO Use a restricthtmlallowunvalidwithphp
1217 $content = GETPOST('content', 'none'); // @TODO Use a restricthtmlallowunvalidwithphp
1218
1219 $objectpage->content = make_substitutions($content, $substitutionarray);
1220 } else {
1221 /*$sample = GETPOST('sample', 'alpha');
1222 if (empty($sample)) {
1223 $sample = 'empty';
1224 }
1225
1226 $pathtosample = DOL_DOCUMENT_ROOT.'/website/samples/page-sample-'.dol_sanitizeFileName(strtolower($sample)).'.html';
1227 */
1228 // Init content with content into page-sample-...
1229 //$objectpage->content = make_substitutions(@file_get_contents($pathtosample), $substitutionarray);
1230 }
1231 }
1232
1233 if (!$error) {
1234 if (empty($objectpage->pageurl)) {
1235 $langs->load("errors");
1236 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_PAGENAME")), null, 'errors');
1237 $error++;
1238 $action = 'createcontainer';
1239 } elseif (!preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) {
1240 $langs->load("errors");
1241 setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors');
1242 $error++;
1243 $action = 'createcontainer';
1244 }
1245 if (empty($objectpage->title)) {
1246 $langs->load("errors");
1247 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_TITLE")), null, 'errors');
1248 $error++;
1249 $action = 'createcontainer';
1250 }
1251 if ($objectpage->fk_page > 0 && empty($objectpage->lang)) {
1252 $langs->load("errors");
1253 setEventMessages($langs->trans("ErrorLanguageRequiredIfPageIsTranslationOfAnother"), null, 'errors');
1254 $error++;
1255 $action = 'createcontainer';
1256 }
1257 if ($objectpage->fk_page > 0 && !empty($objectpage->lang)) {
1258 if ($objectpage->lang == $website->lang) {
1259 $langs->load("errors");
1260 setEventMessages($langs->trans("ErrorLanguageMustNotBeSourceLanguageIfPageIsTranslationOfAnother"), null, 'errors');
1261 $error++;
1262 $action = 'createcontainer';
1263 }
1264 }
1265 }
1266
1267 $pageid = 0;
1268 if (!$error) {
1269 // Create page. This also check there is no PHP content if user has no permissions for that.
1270 $pageid = $objectpage->create($user);
1271 if ($pageid <= 0) {
1272 $error++;
1273 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
1274 $action = 'createcontainer';
1275 }
1276 }
1277
1278 if (!$error) {
1279 // Website categories association
1280 $categoriesarray = GETPOST('categories', 'array:int');
1281 $result = $objectpage->setCategories($categoriesarray);
1282 if ($result < 0) {
1283 $error++;
1284 setEventMessages($object->error, $object->errors, 'errors');
1285 }
1286 }
1287
1288 if (!$error) {
1289 // If there is no home page yet, this new page will be set as the home page
1290 if (empty($object->fk_default_home)) {
1291 $object->fk_default_home = $pageid;
1292 $res = $object->update($user);
1293 if ($res <= 0) {
1294 $error++;
1295 setEventMessages($object->error, $object->errors, 'errors');
1296 } else {
1297 $filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
1298
1299 // Generate the index.php page (to be the home page) and the wrapper.php file
1300 $result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object);
1301
1302 if ($result <= 0) {
1303 setEventMessages('Failed to write file '.$fileindex, null, 'errors');
1304 }
1305 }
1306 }
1307 }
1308
1309 if (!$error) {
1310 if ($pageid > 0) {
1311 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
1312 $filetpl = $pathofwebsite.'/page'.$objectpage->id.'.tpl.php';
1313
1314 // Save page alias
1315 $result = dolSavePageAlias($filealias, $object, $objectpage);
1316 if (!$result) {
1317 setEventMessages('Failed to write file '.basename($filealias), null, 'errors');
1318 }
1319
1320 // Save page of content
1321 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
1322 if ($result) {
1323 setEventMessages($langs->trans("Saved"), null, 'mesgs');
1324 } else {
1325 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
1326 $action = 'createcontainer';
1327 }
1328 }
1329 }
1330
1331 if (!$error) {
1332 $db->commit();
1333 setEventMessages($langs->trans("PageAdded", $objectpage->pageurl), null, 'mesgs');
1334 $action = '';
1335 } else {
1336 $db->rollback();
1337 }
1338
1339 if (!$error) {
1340 $pageid = $objectpage->id;
1341
1342 // To generate the CSS, robot and htmlheader file.
1343
1344 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
1345 // Recreate also dir of website if not found.
1346 $pathtomedias = DOL_DATA_ROOT.'/medias';
1347 $pathtomediasinwebsite = $pathofwebsite.'/medias';
1348 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
1349 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
1350 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
1351 $result = symlink($pathtomedias, $pathtomediasinwebsite);
1352 if (!$result) {
1353 $langs->load("errors");
1354 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
1355 }
1356 }
1357
1358 // Now generate the master.inc.php page if it does not exists yet
1359 if (!dol_is_file($filemaster)) {
1360 $result = dolSaveMasterFile($filemaster);
1361 if (!$result) {
1362 $error++;
1363 setEventMessages('Failed to write file '.$filemaster, null, 'errors');
1364 }
1365 }
1366
1367 if (!dol_is_file($filehtmlheader)) {
1368 $htmlheadercontent = "<html>\n";
1369 $htmlheadercontent .= $htmlheadercontentdefault;
1370 $htmlheadercontent .= "</html>";
1371 $result = dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent);
1372 }
1373
1374 if (!dol_is_file($filecss)) {
1375 $csscontent = "/* CSS content (all pages) */\nbody.bodywebsite { margin: 0; font-family: 'Open Sans', sans-serif; }\n.bodywebsite h1 { margin-top: 0; margin-bottom: 0; padding: 10px;}";
1376 $result = dolSaveCssFile($filecss, $csscontent);
1377 }
1378
1379 if (!dol_is_file($filejs)) {
1380 $jscontent = "/* JS content (all pages) */\n";
1381 $result = dolSaveJsFile($filejs, $jscontent);
1382 }
1383
1384 if (!dol_is_file($filerobot)) {
1385 $robotcontent = "# Robot file. Generated with Dolibarr\nUser-agent: *\nAllow: /public/\nDisallow: /administrator/";
1386 $result = dolSaveRobotFile($filerobot, $robotcontent);
1387 }
1388
1389 if (!dol_is_file($filehtaccess)) {
1390 $htaccesscontent = "# Order allow,deny\n# Deny from all";
1391 $result = dolSaveHtaccessFile($filehtaccess, $htaccesscontent);
1392 }
1393
1394 if (!dol_is_file($filemanifestjson)) {
1395 $manifestjsoncontent = "";
1396 $result = dolSaveManifestJson($filemanifestjson, $manifestjsoncontent);
1397 }
1398
1399 if (!dol_is_file($filereadme)) {
1400 $readmecontent = "Website generated by Dolibarr ERP CRM";
1401 $result = dolSaveReadme($filereadme, $readmecontent);
1402 }
1403
1404 if (!dol_is_file($filelicense)) {
1405 $licensecontent = "LICENSE\n-------\nThis website template content (HTML and PHP code) is published under the license CC-BY-SA - https://creativecommons.org/licenses/by/4.0/";
1406 $result = dolSaveLicense($filelicense, $licensecontent);
1407 }
1408
1409 $action = 'preview';
1410 }
1411}
1412
1413// Delete site
1414if ($action == 'confirm_deletesite' && $confirm == 'yes' && $permissiontodelete) {
1415 $error = 0;
1416
1417 $db->begin();
1418
1419 $res = $object->fetch(GETPOSTINT('id'));
1420 $website = $object;
1421
1422 if ($res > 0) {
1423 $res = $object->delete($user);
1424 if ($res <= 0) {
1425 $error++;
1426 setEventMessages($object->error, $object->errors, 'errors');
1427 }
1428 }
1429 if (!$error) {
1430 if (GETPOST('delete_also_js', 'alpha') == 'on') {
1431 $pathofwebsitejs = DOL_DATA_ROOT.'/medias/js/'.$object->ref;
1432
1433 dol_delete_dir_recursive($pathofwebsitejs);
1434 }
1435 if (GETPOST('delete_also_medias', 'alpha') == 'on') {
1436 $pathofwebsitemedias = DOL_DATA_ROOT.'/medias/image/'.$object->ref;
1437
1438 dol_delete_dir_recursive($pathofwebsitemedias);
1439 }
1440 }
1441
1442 if (!$error) {
1443 $db->commit();
1444 setEventMessages($langs->trans("SiteDeleted", $object->ref), null, 'mesgs');
1445
1446 header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id);
1447 exit;
1448 } else {
1449 $db->rollback();
1450 setEventMessages($object->error, $object->errors, 'errors');
1451 }
1452}
1453
1454// Delete page (from website page menu)
1455if (GETPOSTISSET('pageid') && $action == 'delete' && $permissiontodelete && !GETPOST('file_manager')) {
1456 $error = 0;
1457
1458 $db->begin();
1459
1460 $res = $object->fetch(0, $websitekey);
1461 $website = $object;
1462
1463 $res = $objectpage->fetch($pageid, (string) $object->id);
1464
1465 if ($res > 0) {
1466 $res = $objectpage->delete($user);
1467 if ($res <= 0) {
1468 $error++;
1469 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
1470 }
1471 }
1472
1473 if (!$error) {
1474 $db->commit();
1475 setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $websitekey), null, 'mesgs');
1476
1477 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey);
1478 exit;
1479 } else {
1480 $db->rollback();
1482 }
1483}
1484// Delete page (from menu search)
1485if (!GETPOSTISSET('pageid')) {
1486 $objectclass = 'WebsitePage';
1487
1488 // Add part of code from actions_massactions.inc.php
1489 // Delete record from mass action (massaction = 'delete' for direct delete, action/confirm='delete'/'yes' with a confirmation step before)
1490 if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == 'yes')) && $permissiontodelete) {
1491 $db->begin();
1492
1493 $objecttmp = new $objectclass($db);
1494 $nbok = 0;
1495 foreach ($toselect as $toselectid) {
1496 $result = $objecttmp->fetch($toselectid);
1497 if ($result > 0) {
1498 $result = $objecttmp->delete($user);
1499
1500 if ($result <= 0) {
1501 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
1502 $error++;
1503 break;
1504 } else {
1505 $nbok++;
1506 }
1507 } else {
1508 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
1509 $error++;
1510 break;
1511 }
1512 }
1513
1514 if (!$error) {
1515 if ($nbok > 1) {
1516 setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
1517 } else {
1518 setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
1519 }
1520 $db->commit();
1521 } else {
1522 $db->rollback();
1523 }
1524 //var_dump($listofobjectthirdparties);exit;
1525 }
1526
1527 if ($action == 'delete') { // Test on permission not required here
1528 $mode = 'replacesite';
1529 $action = 'replacesite';
1530
1531 $containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : '';
1532 $langcode = GETPOST('optionlanguage', 'aZ09');
1533 $otherfilters = array();
1534 if (GETPOSTINT('optioncategory') > 0) {
1535 $otherfilters['category'] = GETPOSTINT('optioncategory');
1536 }
1537
1538 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters);
1539 }
1540}
1541
1542// Update css site properties. Re-generates also the wrapper.
1543if ($action == 'updatecss' && $usercanedit) {
1544 // If we tried to reload another site/page, we stay on editcss mode.
1545 if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x')) {
1546 $action = 'editcss';
1547 } else {
1548 $res = $object->fetch(0, $websitekey);
1549 $website = $object;
1550
1551 if (GETPOSTISSET('virtualhost')) {
1552 $tmpvirtualhost = preg_replace('/\/$/', '', GETPOST('virtualhost', 'alpha'));
1553 if ($tmpvirtualhost && !preg_match('/^http/', $tmpvirtualhost)) {
1554 $error++;
1555 setEventMessages($langs->trans('ErrorURLMustStartWithHttp', $langs->transnoentitiesnoconv("VirtualHost")), null, 'errors');
1556 $action = 'editcss';
1557 }
1558
1559 if (!$error) {
1560 $arrayotherlang = explode(',', GETPOST('WEBSITE_OTHERLANG', 'alphanohtml'));
1561 foreach ($arrayotherlang as $key => $val) {
1562 // It possible we have empty val here if postparam WEBSITE_OTHERLANG is empty or set like this : 'en,,sv' or 'en,sv,'
1563 if (empty(trim($val))) {
1564 continue;
1565 }
1566 $arrayotherlang[$key] = substr(trim($val), 0, 2); // Kept short language code only
1567 }
1568
1569 $object->virtualhost = $tmpvirtualhost;
1570 $object->lang = GETPOST('WEBSITE_LANG', 'aZ09');
1571 $object->otherlang = implode(',', $arrayotherlang);
1572 $object->use_manifest = GETPOSTINT('use_manifest');
1573
1574 $result = $object->update($user);
1575 if ($result < 0) {
1576 $error++;
1577 setEventMessages($object->error, $object->errors, 'errors');
1578 $action = 'editcss';
1579 }
1580 }
1581 }
1582
1583 if (!$error) {
1584 if (($_FILES['addedfile']["name"] != '')) {
1585 $uploadfolder = $conf->website->dir_output.'/'.$websitekey;
1586 if ($_FILES['addedfile']['type'] != 'image/png') {
1587 $error++;
1588 setEventMessages($langs->trans('ErrorFaviconType'), array(), 'errors');
1589 }
1590 $filetoread = realpath(dol_osencode($_FILES['addedfile']['tmp_name']));
1591 $filesize = getimagesize($filetoread);
1592 if ($filesize[0] != $filesize[1]) {
1593 $error++;
1594 setEventMessages($langs->trans('ErrorFaviconMustBeASquaredImage'), array(), 'errors');
1595 }
1596 if (! $error && ($filesize[0] != 16 && $filesize[0] != 32 && $filesize[0] != 64)) {
1597 $error++;
1598 setEventMessages($langs->trans('ErrorFaviconSize'), array(), 'errors');
1599 }
1600 if (!$error) {
1601 dol_add_file_process($uploadfolder, 1, 0, 'addedfile', 'favicon.png');
1602 }
1603 }
1604 if ($error) {
1605 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
1606 $action = 'preview';
1607 if ($backtopage) {
1608 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
1609 header("Location: ".$backtopage);
1610 exit;
1611 }
1612 } else {
1613 $action = 'editcss';
1614 }
1615 }
1616 }
1617
1618 if (!$error) {
1619 // Save master.inc.php file
1620 dol_syslog("Save master file ".$filemaster);
1621
1622 dol_mkdir($pathofwebsite);
1623
1624 // Now generate the master.inc.php page
1625 $result = dolSaveMasterFile($filemaster);
1626 if (!$result) {
1627 $error++;
1628 setEventMessages('Failed to write file '.$filemaster, null, 'errors');
1629 }
1630
1631
1632 $dataposted = trim(GETPOST('WEBSITE_HTML_HEADER', 'restricthtmlallowlinkscript')); // Must accept tags like '<script>' and '<link>'
1633
1634 $dataposted = preg_replace(array('/<html>\n*/ims', '/<\/html>\n*/ims'), array('', ''), $dataposted);
1635 $dataposted = str_replace('<?=', '<?php', $dataposted);
1636
1637 // Html header file
1638 $phpfullcodestringold = '';
1639 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1640
1641 // Security analysis
1642 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1643
1644 if (!$errorphpcheck) {
1645 $htmlheadercontent = '';
1646
1647 /* We disable php code since global htmlheader for all website is never executed as an include but only read by fgets_content.
1648 $htmlheadercontent.= "<?php // BEGIN PHP\n";
1649 $htmlheadercontent.= '$websitekey=basename(__DIR__);'."\n";
1650 $htmlheadercontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load env if not already loaded"."\n";
1651 $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1652 $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1653 $htmlheadercontent.= "ob_start();\n";
1654 // $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page
1655 $htmlheadercontent.= "// END PHP ?>\n";*/
1656
1657 $htmlheadercontent .= $dataposted."\n";
1658
1659 /*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n";
1660 $htmlheadercontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
1661 $htmlheadercontent.= "// END PHP"."\n";*/
1662
1663 $result = dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent);
1664 if (!$result) {
1665 $error++;
1666 setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors');
1667 }
1668 } else {
1669 $error++;
1670 }
1671
1672 $dataposted = trim(GETPOST('WEBSITE_CSS_INLINE', 'none'));
1673 $dataposted = str_replace('<?=', '<?php', $dataposted);
1674
1675 // Css file
1676 $phpfullcodestringold = '';
1677 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1678
1679 // Security analysis
1680 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1681
1682 if (!$errorphpcheck) {
1683 $csscontent = '';
1684
1685 $csscontent .= "<?php // BEGIN PHP\n";
1686 $csscontent .= '$websitekey=basename(__DIR__);'."\n";
1687 $csscontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once __DIR__.'/master.inc.php'; } // Load env if not already loaded\n"; // For the css, we need to set path of master using the dirname of css file.
1688 $csscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1689 $csscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1690 $csscontent .= "ob_start();\n";
1691 $csscontent .= "if (! headers_sent()) { /* because file is included inline when in edit mode and we don't want warning */ \n";
1692 $csscontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1693 $csscontent .= "header('Content-type: text/css');\n";
1694 $csscontent .= "}\n";
1695 $csscontent .= "// END PHP ?>\n";
1696
1697 $csscontent .= $dataposted."\n";
1698
1699 $csscontent .= '<?php // BEGIN PHP'."\n";
1700 $csscontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "css");'."\n";
1701 $csscontent .= "// END PHP\n";
1702
1703 dol_syslog("Save css content into ".$filecss);
1704
1705 $result = dolSaveCssFile($filecss, $csscontent);
1706 if (!$result) {
1707 $error++;
1708 setEventMessages('Failed to write file '.$filecss, null, 'errors');
1709 }
1710 } else {
1711 $error++;
1712 }
1713
1714
1715 $dataposted = trim(GETPOST('WEBSITE_JS_INLINE', 'none'));
1716 $dataposted = str_replace('<?=', '<?php', $dataposted);
1717
1718 // Js file
1719 $phpfullcodestringold = '';
1720 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1721
1722 // Security analysis
1723 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1724
1725 if (!$errorphpcheck) {
1726 $jscontent = '';
1727
1728 $jscontent .= "<?php // BEGIN PHP\n";
1729 $jscontent .= '$websitekey=basename(__DIR__);'."\n";
1730 $jscontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once __DIR__.'/master.inc.php'; } // Load env if not already loaded\n"; // For the css, we need to set path of master using the dirname of css file.
1731 $jscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1732 $jscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1733 $jscontent .= "ob_start();\n";
1734 $jscontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1735 $jscontent .= "header('Content-type: application/javascript');\n";
1736 $jscontent .= "// END PHP ?>\n";
1737
1738 $jscontent .= $dataposted."\n";
1739
1740 $jscontent .= '<?php // BEGIN PHP'."\n";
1741 $jscontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "js");'."\n";
1742 $jscontent .= "// END PHP\n";
1743
1744 $result = dolSaveJsFile($filejs, $jscontent);
1745 if (!$result) {
1746 $error++;
1747 setEventMessages('Failed to write file '.$filejs, null, 'errors');
1748 }
1749 } else {
1750 $error++;
1751 }
1752
1753 $dataposted = trim(GETPOST('WEBSITE_ROBOT', 'nohtml'));
1754 $dataposted = str_replace('<?=', '<?php', $dataposted);
1755
1756 // Robot file
1757 $phpfullcodestringold = '';
1758 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1759
1760 // Security analysis
1761 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1762
1763 if (!$errorphpcheck) {
1764 $robotcontent = '';
1765
1766 /*$robotcontent.= "<?php // BEGIN PHP\n";
1767 $robotcontent.= '$websitekey=basename(__DIR__);'."\n";
1768 $robotcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load env if not already loaded"."\n";
1769 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1770 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1771 $robotcontent.= "ob_start();\n";
1772 $robotcontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1773 $robotcontent.= "header('Content-type: text/css');\n";
1774 $robotcontent.= "// END PHP ?>\n";*/
1775
1776 $robotcontent .= $dataposted."\n";
1777
1778 /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n";
1779 $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "robot");'."\n";
1780 $robotcontent.= "// END PHP ?>"."\n";*/
1781
1782 $result = dolSaveRobotFile($filerobot, $robotcontent);
1783 if (!$result) {
1784 $error++;
1785 setEventMessages('Failed to write file '.$filerobot, null, 'errors');
1786 }
1787 } else {
1788 $error++;
1789 }
1790
1791 $dataposted = trim(GETPOST('WEBSITE_HTACCESS', 'nohtml'));
1792 $dataposted = str_replace('<?=', '<?php', $dataposted);
1793
1794 // Htaccess file
1795 $phpfullcodestringold = '';
1796 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1797
1798 // Security analysis
1799 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1800
1801 if (!$errorphpcheck) {
1802 if ($dataposted) {
1803 $htaccesscontent = '';
1804 $htaccesscontent .= $dataposted."\n";
1805
1806 $result = dolSaveHtaccessFile($filehtaccess, $htaccesscontent);
1807 if (!$result) {
1808 $error++;
1809 setEventMessages('Failed to write file '.$filehtaccess, null, 'errors');
1810 }
1811 } else {
1812 dol_delete_file($filehtaccess, 0, 0);
1813 }
1814 } else {
1815 $error++;
1816 }
1817
1818
1819 $dataposted = trim(GETPOST('WEBSITE_MANIFEST_JSON', 'restricthtmlallowunvalid'));
1820 $dataposted = str_replace('<?=', '<?php', $dataposted);
1821
1822 // Manifest.json file
1823 $phpfullcodestringold = '';
1824 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1825
1826 // Security analysis
1827 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1828
1829 if (!$errorphpcheck) {
1830 $manifestjsoncontent = '';
1831
1832 $manifestjsoncontent .= "<?php // BEGIN PHP\n";
1833 $manifestjsoncontent .= '$websitekey=basename(__DIR__);'."\n";
1834 $manifestjsoncontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once __DIR__.'/master.inc.php'; } // Load env if not already loaded\n"; // For the css, we need to set path of master using the dirname of css file.
1835 $manifestjsoncontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1836 $manifestjsoncontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1837 $manifestjsoncontent .= "ob_start();\n";
1838 $manifestjsoncontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1839 $manifestjsoncontent .= "header('Content-type: application/manifest+json');\n";
1840 $manifestjsoncontent .= "// END PHP ?>\n";
1841
1842 $manifestjsoncontent .= $dataposted."\n";
1843
1844 $manifestjsoncontent .= '<?php // BEGIN PHP'."\n";
1845 $manifestjsoncontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1846 $manifestjsoncontent .= "// END PHP\n";
1847
1848 $result = dolSaveManifestJson($filemanifestjson, $manifestjsoncontent);
1849 if (!$result) {
1850 $error++;
1851 setEventMessages('Failed to write file '.$filemanifestjson, null, 'errors');
1852 }
1853 } else {
1854 $error++;
1855 }
1856
1857
1858 $dataposted = trim(GETPOST('WEBSITE_README', 'nohtml'));
1859 $dataposted = str_replace('<?=', '<?php', $dataposted);
1860
1861 // README.md file
1862 $phpfullcodestringold = '';
1863 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1864
1865 // Security analysis
1866 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1867
1868 if (!$errorphpcheck) {
1869 $readmecontent = '';
1870
1871 /*$readmecontent.= "<?php // BEGIN PHP\n";
1872 $readmecontent.= '$websitekey=basename(__DIR__);'."\n";
1873 $readmecontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once __DIR__.'/master.inc.php'; } // Load env if not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file.
1874 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1875 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1876 $readmecontent.= "ob_start();\n";
1877 $readmecontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1878 $readmecontent.= "header('Content-type: application/manifest+json');\n";
1879 $readmecontent.= "// END PHP ?>\n";*/
1880
1881 $readmecontent .= $dataposted."\n";
1882
1883 /*$readmecontent.= '<?php // BEGIN PHP'."\n";
1884 $readmecontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1885 $readmecontent.= "// END PHP ?>"."\n";*/
1886
1887 $result = dolSaveReadme($filereadme, $readmecontent);
1888 if (!$result) {
1889 $error++;
1890 setEventMessages('Failed to write file '.$filereadme, null, 'errors');
1891 }
1892 } else {
1893 $error++;
1894 }
1895
1896
1897 $dataposted = trim(GETPOST('WEBSITE_LICENSE', 'nohtml'));
1898 $dataposted = str_replace('<?=', '<?php', $dataposted);
1899
1900 // LICENSE file
1901 $phpfullcodestringold = '';
1902 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1903
1904 // Security analysis
1905 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1906
1907 if (!$errorphpcheck) {
1908 $licensecontent = '';
1909
1910 /*$readmecontent.= "<?php // BEGIN PHP\n";
1911 $readmecontent.= '$websitekey=basename(__DIR__);'."\n";
1912 $readmecontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once __DIR__.'/master.inc.php'; } // Load env if not already loaded"."\n"; // For the css, we need to set path of master using the dirname of css file.
1913 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1914 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1915 $readmecontent.= "ob_start();\n";
1916 $readmecontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1917 $readmecontent.= "header('Content-type: application/manifest+json');\n";
1918 $readmecontent.= "// END PHP ?>\n";*/
1919
1920 $licensecontent .= $dataposted."\n";
1921
1922 /*$readmecontent.= '<?php // BEGIN PHP'."\n";
1923 $readmecontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1924 $readmecontent.= "// END PHP ?>"."\n";*/
1925
1926 $result = dolSaveLicense($filelicense, $licensecontent);
1927 if (!$result) {
1928 $error++;
1929 setEventMessages('Failed to write file '.$filelicense, null, 'errors');
1930 }
1931 } else {
1932 $error++;
1933 }
1934
1935 // Save wrapper.php
1936 $result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper, $object);
1937
1938
1939 // Message if no error
1940 if (!$error) {
1941 setEventMessages($langs->trans("Saved"), null, 'mesgs');
1942 }
1943
1944 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
1945 $action = 'preview';
1946 if ($backtopage) {
1947 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
1948 header("Location: ".$backtopage);
1949 exit;
1950 }
1951 } else {
1952 $action = 'editcss';
1953 }
1954 }
1955 }
1956}
1957
1958$sourcetype = '';
1959if ($action == "updatesecurity" && $usercanedit && GETPOST("btn_WEBSITE_SECURITY_FORCECSP")) {
1960 $directivecsp = GETPOST("select_identifier_WEBSITE_SECURITY_FORCECSP");
1961 $sourcecsp = GETPOST("select_source_WEBSITE_SECURITY_FORCECSP");
1962 $sourcedatacsp = GETPOST("input_data_WEBSITE_SECURITY_FORCECSP");
1963
1964 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
1965 $directivesarray = websiteGetContentPolicyDirectives();
1966 $sourcesarray = websiteGetContentPolicySources();
1967 if (empty($directivecsp)) {
1968 $error++;
1969 }
1970 if ($error || (!isset($sourcecsp) && $directivesarray[$directivecsp]["data-directivetype"] != "none")) {
1971 $error++;
1972 }
1973 if (!$error) {
1974 $directivetype = $directivesarray[$directivecsp]["data-directivetype"];
1975 if (isset($sourcecsp)) {
1976 $sourcetype = $sourcesarray[$directivetype][$sourcecsp]["data-sourcetype"];
1977 }
1978 $securityspstring = "";
1979 if (isset($sourcetype) && $sourcetype == "data") {
1980 $forceCSPArr[$directivecsp][] = "data:".$sourcedatacsp;
1981 } elseif (isset($sourcetype) && $sourcetype == "input") {
1982 if (empty($forceCSPArr[$directivecsp])) {
1983 $forceCSPArr[$directivecsp] = array();
1984 }
1985 $forceCSPArr[$directivecsp] = array_merge(explode(" ", $sourcedatacsp), $forceCSPArr[$directivecsp]);
1986 } else {
1987 if (empty($forceCSPArr[$directivecsp])) {
1988 $forceCSPArr[$directivecsp] = array();
1989 }
1990 if (!isset($sourcecsp)) {
1991 $sourcecsp = "";
1992 }
1993 array_unshift($forceCSPArr[$directivecsp], $sourcecsp);
1994 }
1995 foreach ($forceCSPArr as $directive => $sourcekeys) {
1996 if ($securityspstring != "") {
1997 $securityspstring .= "; ";
1998 }
1999 $sourcestring = "";
2000 foreach ($sourcekeys as $key => $source) {
2001 $directivetype = $directivesarray[$directive]["data-directivetype"];
2002 $sourcetype = $sourcesarray[$directivetype][$source]["data-sourcetype"];
2003 if (isset($sourcetype) && $sourcetype == "quoted") {
2004 $sourcestring .= " '".$source."'";
2005 } elseif ($directivetype != "none") {
2006 $sourcestring .= " ".$source;
2007 }
2008 }
2009 $securityspstring .= $directive . $sourcestring;
2010 }
2011 $res = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securityspstring, 'chaine', 0, '', $conf->entity);
2012 if ($res <= 0) {
2013 $error++;
2014 }
2015 }
2016
2017 if (!$error) {
2018 $db->commit();
2019 setEventMessages($langs->trans("SecurityPolicySucesfullyAdded"), null, 'mesgs');
2020 } else {
2021 $db->rollback();
2022 setEventMessages($langs->trans("ErrorAddingSecurityPolicy"), null, 'errors');
2023 }
2024 header("Location: ".$_SERVER["PHP_SELF"].'?websiteid='.$websiteid."&action=editsecurity");
2025 exit();
2026}
2027
2028if ($action == "updatesecurity" && $usercanedit) {
2029 $db->begin();
2030 $res1 = $res2 = $res3 = $res4 = 0;
2031 $securityrp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCERP', 'alpha');
2032 $securitysts = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCESTS', 'alpha');
2033 $securitypp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCEPP', 'alpha');
2034 $securitysp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCECSP', 'alpha');
2035 $securitycspro = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO', 'alpha');
2036
2037 $res1 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCERP', $securityrp, 'chaine', 0, '', $conf->entity);
2038 $res2 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCESTS', $securitysts, 'chaine', 0, '', $conf->entity);
2039 $res3 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCEPP', $securitypp, 'chaine', 0, '', $conf->entity);
2040 $res4 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securitysp, 'chaine', 0, '', $conf->entity);
2041 $res5 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO', $securitycspro, 'chaine', 0, '', $conf->entity);
2042
2043 if ($res1 >= 0 && $res2 >= 0 && $res3 >= 0 && $res4 >= 0 && $res5 >= 0) {
2044 $db->commit();
2045 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2046 } else {
2047 $db->rollback();
2048 setEventMessages($langs->trans("ErrorSavingChanges"), null, 'errors');
2049 }
2050
2051 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
2052 $action = 'preview';
2053 if ($backtopage) {
2054 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
2055 header("Location: ".$backtopage);
2056 exit;
2057 }
2058 } else {
2059 $action = 'editsecurity';
2060 $forceCSP = getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSP");
2061 }
2062}
2063
2064// Update page
2065if ($action == 'setashome' && $usercanedit) {
2066 $db->begin();
2067 $object->fetch(0, $websitekey);
2068 $website = $object;
2069
2070 $object->fk_default_home = $pageid;
2071 $res = $object->update($user);
2072 if (! ($res > 0)) {
2073 $error++;
2074 setEventMessages($object->error, $object->errors, 'errors');
2075 }
2076
2077 if (!$error) {
2078 $db->commit();
2079
2080 $filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
2081
2082 // Generate the index.php page to be the home page
2083 $result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object);
2084
2085 if ($result) {
2086 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2087 } else {
2088 setEventMessages('Failed to write file '.$fileindex, null, 'errors');
2089 }
2090
2091 $action = 'preview';
2092 } else {
2093 $db->rollback();
2094 }
2095}
2096
2097// Update page properties (meta)
2098if ($action == 'updatemeta' && $usercanedit) {
2099 $db->begin();
2100
2101 $result = $object->fetch(0, $websitekey);
2102 $website = $object;
2103
2104 $objectpage->fk_website = $object->id;
2105
2106 // Check parameters
2107 if (!preg_match('/^[a-z0-9\-\_]+$/i', GETPOST('WEBSITE_PAGENAME', 'alpha'))) {
2108 $error++;
2109 $langs->load("errors");
2110 setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors');
2111 $action = 'editmeta';
2112 }
2113
2114 $res = $objectpage->fetch($pageid, (string) $object->id);
2115 if ($res <= 0) {
2116 $error++;
2117 setEventMessages('Page not found '.$objectpage->error, $objectpage->errors, 'errors');
2118 }
2119
2120 // Check alias not exists
2121 if (!$error && GETPOST('WEBSITE_PAGENAME', 'alpha')) {
2122 $websitepagetemp = new WebsitePage($db);
2123 $result = $websitepagetemp->fetch(-1 * $objectpage->id, (string) $object->id, GETPOST('WEBSITE_PAGENAME', 'alpha'));
2124 if ($result < 0) {
2125 $error++;
2126 $langs->load("errors");
2127 setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
2128 $action = 'editmeta';
2129 }
2130 if ($result > 0) {
2131 $error++;
2132 $langs->load("errors");
2133 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
2134 $action = 'editmeta';
2135 }
2136 }
2137
2138 $newaliasnames = '';
2139 if (!$error && GETPOST('WEBSITE_ALIASALT', 'alpha')) {
2140 $arrayofaliastotest = explode(',', str_replace(array('<', '>'), '', GETPOST('WEBSITE_ALIASALT', 'alpha')));
2141
2142 $websitepagetemp = new WebsitePage($db);
2143 foreach ($arrayofaliastotest as $aliastotest) {
2144 $aliastotest = trim(preg_replace('/\.php$/i', '', $aliastotest));
2145
2146 // Disallow alias name pageX (already used to save the page with id)
2147 if (preg_match('/^page\d+/i', $aliastotest)) {
2148 $error++;
2149 $langs->load("errors");
2150 setEventMessages("Alias name 'pageX' is not allowed", null, 'errors');
2151 $action = 'editmeta';
2152 break;
2153 } else {
2154 $result = $websitepagetemp->fetch(-1 * $objectpage->id, (string) $object->id, $aliastotest);
2155 if ($result < 0) {
2156 $error++;
2157 $langs->load("errors");
2158 setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
2159 $action = 'editmeta';
2160 break;
2161 }
2162 if ($result > 0) {
2163 $error++;
2164 $langs->load("errors");
2165 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
2166 $action = 'editmeta';
2167 break;
2168 }
2169 $newaliasnames .= ($newaliasnames ? ', ' : '').$aliastotest;
2170 }
2171 }
2172 }
2173
2174 if (!$error) {
2175 $objectpage->old_object = clone $objectpage;
2176
2177 $objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
2178 $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09');
2179 $objectpage->pageurl = dol_sanitizeUrl(GETPOST('WEBSITE_PAGENAME', 'alpha'));
2180 $objectpage->aliasalt = $newaliasnames;
2181 $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09');
2182 $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
2183 $objectpage->description = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
2184 $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha');
2185 $objectpage->keywords = str_replace(array('<', '>'), '', GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'));
2186 $objectpage->allowed_in_frames = GETPOST('WEBSITE_ALLOWED_IN_FRAMES', 'aZ09') ? 1 : 0;
2187 $objectpage->htmlheader = trim(GETPOST('htmlheader', 'restricthtmlallowlinkscript')); // Must accept tags like '<script>' and '<link>'
2188 $objectpage->fk_page = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
2189 $objectpage->author_alias = trim(GETPOST('WEBSITE_AUTHORALIAS', 'alphanohtml'));
2190 $objectpage->object_type = GETPOST('WEBSITE_OBJECTCLASS', 'alpha');
2191 $objectpage->fk_object = GETPOST('WEBSITE_OBJECTID', 'aZ09');
2192
2193 $newdatecreation = dol_mktime(GETPOSTINT('datecreationhour'), GETPOSTINT('datecreationmin'), GETPOSTINT('datecreationsec'), GETPOSTINT('datecreationmonth'), GETPOSTINT('datecreationday'), GETPOSTINT('datecreationyear'));
2194 if ($newdatecreation) {
2195 $objectpage->date_creation = $newdatecreation;
2196 }
2197
2198 $res = $objectpage->update($user);
2199 if (!($res > 0)) {
2200 $langs->load("errors");
2201 if ($db->lasterrno == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2202 $error++;
2203 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists"), null, 'errors');
2204 $action = 'editmeta';
2205 } else {
2206 $error++;
2207 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2208 $action = 'editmeta';
2209 }
2210 }
2211 }
2212
2213 if (!$error) {
2214 // Website categories association
2215 $categoriesarray = GETPOST('categories', 'array:int');
2216 $result = $objectpage->setCategories($categoriesarray);
2217 if ($result < 0) {
2218 $error++;
2219 setEventMessages($object->error, $object->errors, 'errors');
2220 }
2221 }
2222
2223 if (!$error) {
2224 $db->commit();
2225 } else {
2226 $db->rollback();
2227 }
2228
2229 if (!$error) {
2230 $filemaster = $pathofwebsite.'/master.inc.php';
2231 $fileoldalias = $pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php';
2232 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
2233
2234 dol_mkdir($pathofwebsite);
2235
2236 // Now generate the master.inc.php page
2237 $result = dolSaveMasterFile($filemaster);
2238 if (!$result) {
2239 setEventMessages('Failed to write file '.$filemaster, null, 'errors');
2240 }
2241
2242 // Now delete the alias.php page
2243 if (!empty($fileoldalias)) {
2244 dol_syslog("We delete old alias page name=".$fileoldalias." to build a new alias page=".$filealias);
2245 dol_delete_file($fileoldalias);
2246
2247 // Delete also pages into language subdirectories
2248 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2249 $dirname = dirname($fileoldalias);
2250 $filename = basename($fileoldalias);
2251 $sublangs = explode(',', $object->otherlang);
2252 foreach ($sublangs as $sublang) {
2253 // Under certain conditions $sublang can be an empty string
2254 // ($object->otherlang with empty string or with string like this 'en,,sv')
2255 // if is the case we try to re-delete the main alias file. Avoid it.
2256 if (empty(trim($sublang))) {
2257 continue;
2258 }
2259 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2260 dol_delete_file($fileoldaliassub);
2261 }
2262 }
2263 }
2264 // Now delete the alternative alias.php pages
2265 if (!empty($objectpage->old_object->aliasalt)) {
2266 $tmpaltaliases = explode(',', $objectpage->old_object->aliasalt);
2267 if (is_array($tmpaltaliases)) {
2268 foreach ($tmpaltaliases as $tmpaliasalt) {
2269 dol_syslog("We delete old alt alias pages name=".trim($tmpaliasalt));
2270 dol_delete_file($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2271
2272 // Delete also pages into language subdirectories
2273 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2274 $dirname = dirname($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2275 $filename = basename($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2276 $sublangs = explode(',', $object->otherlang);
2277 foreach ($sublangs as $sublang) {
2278 // Under certain conditions $ sublang can be an empty string
2279 // ($object->otherlang with empty string or with string like this 'en,,sv')
2280 // if is the case we try to re-delete the main alias file. Avoid it.
2281 if (empty(trim($sublang))) {
2282 continue;
2283 }
2284 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2285 dol_delete_file($fileoldaliassub);
2286 }
2287 }
2288 }
2289 }
2290 }
2291
2292 // Save page main alias
2293 $result = dolSavePageAlias($filealias, $object, $objectpage);
2294 if (!$result) {
2295 setEventMessages('Failed to write file '.$filealias, null, 'errors');
2296 }
2297 // Save alt aliases
2298 if (!empty($objectpage->aliasalt)) {
2299 $tmpaltaliases = explode(',', $objectpage->aliasalt);
2300 if (is_array($tmpaltaliases)) {
2301 foreach ($tmpaltaliases as $tmpaliasalt) {
2302 if (trim($tmpaliasalt)) {
2303 $filealias = $pathofwebsite.'/'.trim($tmpaliasalt).'.php';
2304 $result = dolSavePageAlias($filealias, $object, $objectpage);
2305 if (!$result) {
2306 setEventMessages('Failed to write file '.basename($filealias), null, 'errors');
2307 }
2308 }
2309 }
2310 }
2311 }
2312
2313
2314 // Save page of content
2315 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
2316 if ($result) {
2317 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2318
2319 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we do not make the redirect
2320 //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2321 //exit;
2322 $action = 'preview';
2323 } else {
2324 $action = 'editmeta';
2325 }
2326 } else {
2327 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
2328 //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2329 //exit;
2330 $action = 'preview';
2331 }
2332 }
2333}
2334
2335// Update page
2336if ((($action == 'updatesource' || $action == 'updatecontent' || $action == 'confirm_createfromclone' || $action == 'confirm_createpagefromclone') || ($action == 'preview' && (GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview')))) && $usercanedit) {
2337 $object->fetch(0, $websitekey);
2338 $website = $object;
2339
2340 if ($action == 'confirm_createfromclone') { // Test on permissions already done
2341 $db->begin();
2342
2343 $objectnew = new Website($db);
2344 $result = $objectnew->createFromClone($user, GETPOSTINT('id'), GETPOST('siteref'), (GETPOSTINT('newlang') ? GETPOSTINT('newlang') : ''));
2345
2346 if ($result < 0) {
2347 $error++;
2348 setEventMessages($objectnew->error, $objectnew->errors, 'errors');
2349 $action = 'preview';
2350
2351 $db->rollback();
2352 } else {
2353 setEventMessages("ObjectClonedSuccessfuly", null, 'mesgs');
2354 $object = $objectnew;
2355 $id = $object->id;
2356 $pageid = $object->fk_default_home;
2357 $websitekey = GETPOST('siteref', 'aZ09');
2358
2359 $db->commit();
2360 }
2361 }
2362
2363 if ($action == 'confirm_createpagefromclone') { // Test on permissions already done
2364 $istranslation = (GETPOST('is_a_translation', 'aZ09') == 'on' ? 1 : 0);
2365 // Protection if it is a translation page
2366 if ($istranslation) {
2367 if (GETPOST('newlang', 'aZ09') == $objectpage->lang || !GETPOST('newlang', 'aZ09')) {
2368 $error++;
2369 setEventMessages($langs->trans("LanguageMustNotBeSameThanClonedPage"), null, 'errors');
2370 $action = 'preview';
2371 }
2372 if (GETPOSTINT('newwebsite') != $object->id) {
2373 $error++;
2374 setEventMessages($langs->trans("WebsiteMustBeSameThanClonedPageIfTranslation"), null, 'errors');
2375 $action = 'preview';
2376 }
2377 }
2378
2379 if (!$error) {
2380 $db->begin();
2381
2382 $newwebsiteid = GETPOSTINT('newwebsite');
2383 $pathofwebsitenew = $pathofwebsite;
2384
2385 $tmpwebsite = new Website($db);
2386 if ($newwebsiteid > 0 && $newwebsiteid != $object->id) {
2387 $tmpwebsite->fetch($newwebsiteid);
2388 $pathofwebsitenew = $dolibarr_main_data_root.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$tmpwebsite->ref;
2389 } else {
2390 $tmpwebsite = $object;
2391 }
2392
2393 $objectpage = new WebsitePage($db);
2394 $resultpage = $objectpage->createFromClone($user, $pageid, GETPOST('newpageurl', 'aZ09'), (GETPOST('newlang', 'aZ09') ? GETPOST('newlang', 'aZ09') : ''), $istranslation, $newwebsiteid, GETPOST('newtitle', 'alphanohtml'), $tmpwebsite);
2395 if ($resultpage < 0) {
2396 $error++;
2397 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2398 $action = 'createpagefromclone';
2399
2400 $db->rollback();
2401 } else {
2402 $filetpl = $pathofwebsitenew.'/page'.$resultpage->id.'.tpl.php';
2403 $fileindex = $pathofwebsitenew.'/index.php';
2404 $filewrapper = $pathofwebsitenew.'/wrapper.php';
2405
2406 //var_dump($pathofwebsitenew);
2407 //var_dump($filetpl);
2408 //exit;
2409
2410 dolSavePageContent($filetpl, $tmpwebsite, $resultpage, 1);
2411
2412 // Switch on the new page if web site of new page/container is same
2413 if (empty($newwebsiteid) || $newwebsiteid == $object->id) {
2414 $pageid = $resultpage->id;
2415 }
2416
2417 $db->commit();
2418 }
2419 }
2420 }
2421
2422 $res = 0;
2423
2424 if (!$error) {
2425 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2426 // Recreate also dir of website if not found.
2427 $pathtomedias = DOL_DATA_ROOT.'/medias';
2428 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2429 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2430 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2431 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
2432 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2433 if (!$result) {
2434 $langs->load("errors");
2435 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2436 }
2437 }
2438
2439 /*if (GETPOST('savevirtualhost') && $object->virtualhost != GETPOST('previewsite'))
2440 {
2441 $object->virtualhost = GETPOST('previewsite', 'alpha');
2442 $object->update($user);
2443 }*/
2444
2445 $objectpage->fk_website = $object->id;
2446
2447 if ($pageid > 0) {
2448 $res = $objectpage->fetch($pageid);
2449 } else {
2450 $res = 0;
2451 if ($object->fk_default_home > 0) {
2452 $res = $objectpage->fetch($object->fk_default_home);
2453 }
2454 if (!($res > 0)) {
2455 $res = $objectpage->fetch(0, (string) $object->id);
2456 }
2457 }
2458 }
2459
2460 if (!$error && $res > 0) {
2461 if ($action == 'updatesource' || $action == 'updatecontent') { // Test on permissions already done
2462 $db->begin();
2463
2464 $phpfullcodestringold = dolKeepOnlyPhpCode($objectpage->content);
2465
2466 $objectpage->content = GETPOST('PAGE_CONTENT', 'none'); // any HTML content allowed
2467
2468 $phpfullcodestring = dolKeepOnlyPhpCode($objectpage->content);
2469
2470 // Security analysis (check PHP content and check permission website->writephp if php content is modified)
2471 $error = checkPHPCode($phpfullcodestringold, $phpfullcodestring);
2472
2473 if ($error) {
2474 if ($action == 'updatesource') { // Test on permissions already done
2475 $action = 'editsource';
2476 }
2477 if ($action == 'updatecontent') { // Test on permissions already done
2478 $action = 'editcontent';
2479 }
2480 }
2481
2482 // Clean data. We remove all the head section.
2483 $objectpage->content = preg_replace('/<head>.*<\/head>/ims', '', $objectpage->content);
2484 /* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */
2485
2486
2487 $res = $objectpage->update($user);
2488 if ($res < 0) {
2489 $error++;
2490 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2491 if ($action == 'updatesource') { // Test on permissions already done
2492 $action = 'editsource';
2493 }
2494 if ($action == 'updatecontent') { // Test on permissions already done
2495 $action = 'editcontent';
2496 }
2497 }
2498
2499 if (!$error) {
2500 $db->commit();
2501
2502 $filemaster = $pathofwebsite.'/master.inc.php';
2503 //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php';
2504 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
2505
2506 dol_mkdir($pathofwebsite);
2507
2508 // Now generate the master.inc.php page
2509 $result = dolSaveMasterFile($filemaster);
2510
2511 if (!$result) {
2512 setEventMessages('Failed to write the master file file '.$filemaster, null, 'errors');
2513 }
2514
2515 // Now delete the old alias.php page if we removed one
2516 /*if (!empty($fileoldalias))
2517 {
2518 dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias);
2519 dol_delete_file($fileoldalias);
2520
2521 // Delete also pages into language subdirectories
2522 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2523 $dirname = dirname($fileoldalias);
2524 $filename = basename($fileoldalias);
2525 $sublangs = explode(',', $object->otherlang);
2526 foreach ($sublangs as $sublang) {
2527 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2528 dol_delete_file($fileoldaliassub);
2529 }
2530 }
2531 }*/
2532
2533 // Save page alias
2534 $result = dolSavePageAlias($filealias, $object, $objectpage);
2535 if (!$result) {
2536 setEventMessages('Failed to write the alias file '.basename($filealias), null, 'errors');
2537 }
2538
2539 // Save page content
2540 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
2541 if ($result) {
2542 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2543
2544 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we do not make the redirect
2545 if ($backtopage) {
2546 header("Location: ".$backtopage);
2547 exit;
2548 } else {
2549 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2550 exit;
2551 }
2552 } else {
2553 if ($action == 'updatesource') { // Test on permissions already done
2554 $action = 'editsource';
2555 }
2556 if ($action == 'updatecontent') { // Test on permissions already done
2557 $action = 'editcontent';
2558 }
2559 }
2560 } else {
2561 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
2562 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2563 exit;
2564 }
2565 } else {
2566 $db->rollback();
2567 }
2568 } else {
2569 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2570 exit;
2571 }
2572 } else {
2573 if (!$error) {
2574 if (empty($websitekey) || $websitekey == '-1') {
2575 setEventMessages($langs->trans("NoWebSiteCreateOneFirst"), null, 'warnings');
2576 } else {
2577 setEventMessages($langs->trans("NoPageYet"), null, 'warnings');
2578 setEventMessages($langs->trans("YouCanCreatePageOrImportTemplate"), null, 'warnings');
2579 }
2580 }
2581 }
2582}
2583
2584if ($action == 'deletelang' && $usercanedit) {
2585 $sql = "UPDATE ".MAIN_DB_PREFIX."website_page SET fk_page = NULL";
2586 $sql .= " WHERE rowid = ".GETPOSTINT('deletelangforid');
2587 //$sql .= " AND fk_page = ".((int) $objectpage->id);
2588
2589 $resql = $db->query($sql);
2590 if (!$resql) {
2591 setEventMessages($db->lasterror(), null, 'errors');
2592 } else {
2593 $objectpage->fk_page = null;
2594 }
2595
2596 $action = 'editmeta';
2597}
2598
2599
2600// Export site
2601if ($action == 'exportsite' && $user->hasRight('website', 'export')) {
2602 $fileofzip = $object->exportWebSite();
2603
2604 if ($fileofzip) {
2605 $file_name = basename($fileofzip);
2606 header("Content-Type: application/zip");
2607 header("Content-Disposition: attachment; filename=".$file_name);
2608 header("Content-Length: ".filesize($fileofzip));
2609
2610 readfile($fileofzip);
2611 exit;
2612 } else {
2613 setEventMessages($object->error, $object->errors, 'errors');
2614 $action = 'preview';
2615 }
2616}
2617
2618// Overwrite site
2619if ($action == 'overwritesite' && $user->hasRight('website', 'export')) {
2620 if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) {
2621 // Generate a zip of the website
2622 $fileofzip = $object->exportWebSite();
2623 $pathToExport = GETPOST('export_path');
2624 if ($fileofzip) {
2625 // Uncompress the exported web site into a destination directory
2626 $result = $object->overwriteTemplate($fileofzip, $pathToExport);
2627 if ($result < 0) {
2628 $action = 'preview';
2629 }
2630 } else {
2631 setEventMessages($object->error, $object->errors, 'errors');
2632 $action = 'preview';
2633 }
2634 }
2635}
2636// Regenerate site
2637if ($action == 'regeneratesite' && $usercanedit) {
2638 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2639 // Recreate also dir of website if not found.
2640 $pathtomedias = DOL_DATA_ROOT.'/medias';
2641 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2642 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2643 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2644 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
2645 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2646 if (!$result) {
2647 $langs->load("errors");
2648 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2649 $action = 'preview';
2650 }
2651 }
2652
2653 $result = $object->rebuildWebSiteFiles();
2654 if ($result > 0) {
2655 setEventMessages($langs->trans("PagesRegenerated", $result), null, 'mesgs');
2656 $action = 'preview';
2657 } else {
2658 setEventMessages($object->error, $object->errors, 'errors');
2659 $action = 'preview';
2660 }
2661}
2662
2663// Import site
2664if ($action == 'importsiteconfirm' && $usercanedit) {
2665 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
2666 $allowimportsite = true;
2667 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
2668 $allowimportsite = false;
2669 }
2670
2671 if ($allowimportsite) {
2672 if (empty($_FILES) && !GETPOSTISSET('templateuserfile')) {
2673 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
2674 $action = 'importsite';
2675 } else {
2676 if (!empty($_FILES) || GETPOSTISSET('templateuserfile')) {
2677 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2678 // Recreate also dir of website if not found.
2679 $pathtomedias = DOL_DATA_ROOT.'/medias';
2680 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2681 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2682 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2683 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
2684 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2685 if (!$result) {
2686 $langs->load("errors");
2687 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2688 $action = 'importsite';
2689 }
2690 }
2691
2692 $fileofzip = '';
2693 if (GETPOSTISSET('templateuserfile')) {
2694 // Case we selected one template
2695 $fileofzip = DOL_DATA_ROOT.'/doctemplates/websites/'.GETPOST('templateuserfile', 'alpha'); // $fileofzip will be sanitized later into the importWebSite()
2696 } elseif (!empty($_FILES) && is_array($_FILES['userfile'])) {
2697 // Case we upload a new template
2698 if (is_array($_FILES['userfile']['tmp_name'])) {
2699 $userfiles = $_FILES['userfile']['tmp_name'];
2700 } else {
2701 $userfiles = array($_FILES['userfile']['tmp_name']);
2702 }
2703
2704 // Check if $_FILES is ok
2705 foreach ($userfiles as $key => $userfile) {
2706 if (empty($_FILES['userfile']['tmp_name'][$key])) {
2707 $error++;
2708 if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2) {
2709 setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
2710 $action = 'importsite';
2711 } else {
2712 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
2713 $action = 'importsite';
2714 }
2715 }
2716 }
2717
2718 if (!$error) {
2719 //$upload_dir = $conf->website->dir_temp;
2720 $upload_dir = DOL_DATA_ROOT.'/doctemplates/websites/';
2721 $result = dol_add_file_process($upload_dir, 1, -1, 'userfile', '');
2722 }
2723
2724 // Get name of file (take last one if several name provided)
2725 /*
2726 $fileofzip = $upload_dir.'/unknown';
2727 foreach ($_FILES as $key => $ifile) {
2728 foreach ($ifile['name'] as $key2 => $ifile2) {
2729 $fileofzip = $upload_dir.'/'.$ifile2;
2730 }
2731 }
2732 */
2733
2734 $action = 'importsite';
2735 }
2736
2737 if (!$error && GETPOSTISSET('templateuserfile')) {
2738 $templatewithoutzip = preg_replace('/\.zip$/i', '', GETPOST('templateuserfile'));
2739 $object->setTemplateName($templatewithoutzip);
2740
2741 $result = $object->importWebSite($fileofzip);
2742
2743 if ($result < 0) {
2744 setEventMessages($object->error, $object->errors, 'errors');
2745 $action = 'importsite';
2746 } else {
2747 // Force mode dynamic on
2748 dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1, 'chaine', 0, '', $conf->entity);
2749
2750 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$object->ref);
2751 exit();
2752 }
2753 }
2754 }
2755 }
2756 } else {
2757 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
2758 // Show clean corporate message
2759 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
2760 } else {
2761 // Show technical generic message
2762 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
2763 }
2764 setEventMessages($message, null, 'errors');
2765 }
2766}
2767
2768$domainname = '0.0.0.0:8080';
2769$tempdir = $conf->website->dir_output.'/'.$websitekey.'/';
2770
2771// Generate web site sitemaps
2772if ($action == 'generatesitemaps' && $usercanedit) {
2773 // Define $domainname
2774 if ($website->virtualhost) {
2775 $domainname = $website->virtualhost;
2776 }
2777 if (! preg_match('/^http/i', $domainname)) {
2778 $domainname = 'https://'.$domainname;
2779 }
2780
2781 $domtree = new DOMDocument('1.0', 'UTF-8');
2782
2783 $root = $domtree->createElementNS('http://www.sitemaps.org/schemas/sitemap/0.9', 'urlset');
2784 $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
2785
2786 $domtree->formatOutput = true;
2787
2788 $addrsswrapper = 0;
2789 $xmlname = 'sitemap.xml';
2790
2791 $sql = "SELECT wp.rowid, wp.type_container , wp.pageurl, wp.lang, wp.fk_page, wp.tms as tms,";
2792 $sql .= " w.virtualhost, w.fk_default_home";
2793 $sql .= " FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
2794 $sql .= " WHERE wp.type_container IN ('page', 'blogpost')";
2795 $sql .= " AND wp.fk_website = w.rowid";
2796 $sql .= " AND wp.status = ".WebsitePage::STATUS_VALIDATED;
2797 $sql .= " AND wp.pageurl NOT IN ('404', '500', '501', '503')";
2798 $sql .= " AND w.ref = '".dol_escape_json($websitekey)."'";
2799 $sql .= " ORDER BY wp.tms DESC, wp.rowid DESC";
2800 $resql = $db->query($sql);
2801 if ($resql) {
2802 $num_rows = $db->num_rows($resql);
2803 if ($num_rows > 0) {
2804 $i = 0;
2805 while ($i < $num_rows) {
2806 $objp = $db->fetch_object($resql);
2807 $url = $domtree->createElement('url');
2808
2809 $shortlangcode = '';
2810 if ($objp->lang) {
2811 $shortlangcode = substr($objp->lang, 0, 2); // en_US or en-US -> en
2812 }
2813 if (empty($shortlangcode)) {
2814 $shortlangcode = substr($object->lang, 0, 2); // Use short lang code of website
2815 }
2816
2817 // Is it a blog post for the RSS wrapper ?
2818 if ($objp->type_container == 'blogpost') {
2819 $addrsswrapper = 1;
2820 }
2821
2822 // Forge $pageurl, adding language prefix if it is an alternative language
2823 $pageurl = $objp->pageurl.'.php';
2824 if ($objp->fk_default_home == $objp->rowid) {
2825 $pageurl = '';
2826 } else {
2827 if ($shortlangcode != substr($object->lang, 0, 2)) {
2828 $pageurl = $shortlangcode.'/'.$pageurl;
2829 }
2830 }
2831
2832 //$pathofpage = $dolibarr_main_url_root.'/'.$pageurl.'.php';
2833
2834 // URL of sitemaps must end with trailing slash if page is ''
2835 $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl);
2836 $lastmod = $domtree->createElement('lastmod', dol_print_date($db->jdate($objp->tms), 'dayrfc', 'gmt'));
2837 $priority = $domtree->createElement('priority', '1');
2838
2839 $url->appendChild($loc);
2840 $url->appendChild($lastmod);
2841 // Add suggested frequency for refresh
2842 if (getDolGlobalString('WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ')) {
2843 $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values
2844 $url->appendChild($changefreq);
2845 }
2846 // Add higher priority for home page
2847 if ($objp->fk_default_home == $objp->rowid) {
2848 $url->appendChild($priority);
2849 }
2850
2851 // Now add alternate language entries
2852 if ($object->isMultiLang()) {
2853 $alternatefound = 0;
2854
2855 // Add page "translation of"
2856 $translationof = $objp->fk_page;
2857 if ($translationof) {
2858 $tmppage = new WebsitePage($db);
2859 $tmppage->fetch($translationof);
2860 if ($tmppage->id > 0) {
2861 $tmpshortlangcode = '';
2862 if ($tmppage->lang) {
2863 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en
2864 }
2865 if (empty($tmpshortlangcode)) {
2866 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en
2867 }
2868 if ($tmpshortlangcode != $shortlangcode) {
2869 $xhtmllink = $domtree->createElement('xhtml:link', '');
2870 $xhtmllink->setAttribute("rel", "alternate");
2871 $xhtmllink->setAttribute("hreflang", $tmpshortlangcode);
2872 $xhtmllink->setAttribute("href", $domainname.($objp->fk_default_home == $tmppage->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2)) ? '/'.$tmpshortlangcode : '').'/'.$tmppage->pageurl.'.php'));
2873 $url->appendChild($xhtmllink);
2874
2875 $alternatefound++;
2876 }
2877 }
2878 }
2879
2880 // Add "has translation pages"
2881 $sql = 'SELECT rowid as id, lang, pageurl from '.MAIN_DB_PREFIX.'website_page';
2882 $sql .= " WHERE status = ".((int) WebsitePage::STATUS_VALIDATED).' AND fk_page IN ('.$db->sanitize($objp->rowid.($translationof ? ", ".$translationof : "")).")";
2883 $resqlhastrans = $db->query($sql);
2884 if ($resqlhastrans) {
2885 $num_rows_hastrans = $db->num_rows($resqlhastrans);
2886 if ($num_rows_hastrans > 0) {
2887 while ($objhastrans = $db->fetch_object($resqlhastrans)) {
2888 $tmpshortlangcode = '';
2889 if ($objhastrans->lang) {
2890 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $objhastrans->lang); // en_US or en-US -> en
2891 }
2892 if ($tmpshortlangcode != $shortlangcode) {
2893 $xhtmllink = $domtree->createElement('xhtml:link', '');
2894 $xhtmllink->setAttribute("rel", "alternate");
2895 $xhtmllink->setAttribute("hreflang", $tmpshortlangcode);
2896 $xhtmllink->setAttribute("href", $domainname.($objp->fk_default_home == $objhastrans->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2) ? '/'.$tmpshortlangcode : '')).'/'.$objhastrans->pageurl.'.php'));
2897 $url->appendChild($xhtmllink);
2898
2899 $alternatefound++;
2900 }
2901 }
2902 }
2903 } else {
2905 }
2906
2907 if ($alternatefound) {
2908 // Add myself
2909 $xhtmllink = $domtree->createElement('xhtml:link', '');
2910 $xhtmllink->setAttribute("rel", "alternate");
2911 $xhtmllink->setAttribute("hreflang", $shortlangcode);
2912 $xhtmllink->setAttribute("href", $domainname.'/'.$pageurl);
2913 $url->appendChild($xhtmllink);
2914 }
2915 }
2916
2917 // Now add sitempas extension for news
2918 // TODO When adding and when not ?
2919 /*<news:news>
2920 <news:publication>
2921 <news:name>The Example Times</news:name>
2922 <news:language>en</news:language>
2923 </news:publication>
2924 <news:publication_date>2008-12-23</news:publication_date>
2925 <news:title>Companies A, B in Merger Talks</news:title>
2926 </news:news>
2927 */
2928
2929 $root->appendChild($url);
2930 $i++;
2931 }
2932
2933 // Adding a RSS feed into a sitemap should not be required. The RSS contains pages that are already included into
2934 // the sitemap and RSS feeds are not shown into index.
2935 if ($addrsswrapper && getDolGlobalInt('WEBSITE_ADD_RSS_FEED_INTO_SITEMAP')) {
2936 $url = $domtree->createElement('url');
2937
2938 $pageurl = 'wrapper.php?rss=1';
2939
2940 // URL of sitemaps must end with trailing slash if page is ''
2941 $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl);
2942 $lastmod = $domtree->createElement('lastmod', dol_print_date(dol_now(), 'dayrfc', 'gmt'));
2943
2944 $url->appendChild($loc);
2945 $url->appendChild($lastmod);
2946 // Add suggested frequency for refresh
2947 if (getDolGlobalString('WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ')) {
2948 $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values
2949 $url->appendChild($changefreq);
2950 }
2951
2952 $root->appendChild($url);
2953 }
2954
2955 $domtree->appendChild($root);
2956
2957 if ($domtree->save($tempdir.$xmlname)) {
2958 dolChmod($tempdir.$xmlname);
2959 setEventMessages($langs->trans("SitemapGenerated", $xmlname), null, 'mesgs');
2960 } else {
2961 setEventMessages($object->error, $object->errors, 'errors');
2962 }
2963 }
2964 } else {
2966 }
2967
2968 // Add the entry Sitemap: into the robot.txt file.
2969 $robotcontent = @file_get_contents($filerobot);
2970 $result = preg_replace('/<?php \/\/ BEGIN PHP[^?]END PHP ?>\n/ims', '', $robotcontent);
2971 if ($result) {
2972 $robotcontent = $result;
2973 }
2974 $robotsitemap = "Sitemap: ".$domainname."/".$xmlname;
2975 $result = strpos($robotcontent, 'Sitemap: ');
2976 if ($result) {
2977 $result = preg_replace('/Sitemap:.*/', $robotsitemap, $robotcontent);
2978 $robotcontent = $result ? $result : $robotcontent;
2979 } else {
2980 $robotcontent .= $robotsitemap."\n";
2981 }
2982 $result = dolSaveRobotFile($filerobot, $robotcontent);
2983 if (!$result) {
2984 $error++;
2985 setEventMessages('Failed to write file '.$filerobot, null, 'errors');
2986 }
2987 $action = 'preview';
2988}
2989
2990if ($action == 'removecspsource' && $usercanedit) {
2991 $db->begin();
2992 $sourcetype = "";
2993 $sourcecsp = explode("_", GETPOST("sourcecsp"));
2994 $directive = $sourcecsp[0];
2995 $sourcekey = isset($sourcecsp[1]) ? $sourcecsp[1] : null;
2996 $sourcedata = isset($sourcecsp[2]) ? $sourcecsp[2] : null;
2997 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
2998 $directivesarray = websiteGetContentPolicyDirectives();
2999 $sourcesarray = websiteGetContentPolicySources();
3000 if (empty($directive)) {
3001 $error++;
3002 }
3003
3004 if (!empty($directivesarray[$directive])) {
3005 $directivetype = (string) $directivesarray[$directive]["data-directivetype"];
3006 if (isset($sourcekey)) {
3007 $sourcetype = $sourcesarray[$directivetype][$sourcekey]["data-sourcetype"];
3008 }
3009 }
3010
3011 $securityspstring = "";
3012 if (!$error && !empty($forceCSPArr)) {
3013 if (isset($sourcekey) && !empty($forceCSPArr[$directive][$sourcekey])) {
3014 unset($forceCSPArr[$directive][$sourcekey]);
3015 }
3016 if (count($forceCSPArr[$directive]) == 0) {
3017 unset($forceCSPArr[$directive]);
3018 }
3019 foreach ($forceCSPArr as $directive => $sourcekeys) {
3020 if ($securityspstring != "") {
3021 $securityspstring .= "; ";
3022 }
3023 $sourcestring = "";
3024 foreach ($sourcekeys as $key => $source) {
3025 $directivetype = $directivesarray[$directive]["data-directivetype"];
3026 $sourcetype = $sourcesarray[$directivetype][$source]["data-sourcetype"];
3027 if ($sourcetype == "quoted") {
3028 $sourcestring .= " '".$source."'";
3029 } else {
3030 $sourcestring .= " ".$source;
3031 }
3032 }
3033 $securityspstring .= $directive . $sourcestring;
3034 }
3035 $res = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securityspstring, 'chaine', 0, '', $conf->entity);
3036 if ($res <= 0) {
3037 $error++;
3038 }
3039 }
3040
3041 if (!$error) {
3042 $db->commit();
3043 setEventMessages($langs->trans("SecurityPolicySucesfullyRemoved"), null, 'mesgs');
3044 } else {
3045 $db->rollback();
3046 setEventMessages($langs->trans("ErrorRemovingSecurityPolicy"), null, 'errors');
3047 }
3048
3049 header("Location: ".$_SERVER["PHP_SELF"].'?websiteid='.$websiteid."&action=editsecurity");
3050 exit();
3051}
3052
3053
3054/*
3055 * View
3056 */
3057
3058$form = new Form($db);
3059$formadmin = new FormAdmin($db);
3060$formwebsite = new FormWebsite($db);
3061$formother = new FormOther($db);
3062$formconfirm = "";
3063
3064// Confirm generation of website sitemaps
3065if ($action == 'confirmgeneratesitemaps') {
3066 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.urlencode($website->ref), $langs->trans('ConfirmSitemapsCreation'), $langs->trans('ConfirmGenerateSitemaps', $object->ref), 'generatesitemaps', '', "yes", 1);
3067 $action = 'preview';
3068}
3069$helpurl = 'EN:Module_Website|FR:Module_Website_FR|ES:M&oacute;dulo_Website';
3070
3071$arrayofjs = array(
3072 '/includes/ace/src/ace.js',
3073 '/includes/ace/src/ext-statusbar.js',
3074 '/includes/ace/src/ext-language_tools.js',
3075 //'/includes/ace/src/ext-chromevox.js'
3076);
3077$arrayofcss = array();
3078
3079if (!getDolGlobalString('MAIN_ECM_DISABLE_JS')) {
3080 $arrayofjs[] = "public/includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
3081}
3082
3083llxHeader('', $langs->trans("Website").(empty($website->ref) ? '' : ' - '.$website->ref), $helpurl, '', 0, 0, $arrayofjs, $arrayofcss, '', 'mod-website page-index', '<!-- Begin div class="fiche" -->'."\n".'<div class="fichebutwithotherclass">');
3084
3085print "\n";
3086print '<!-- Open form common to all pages generated by website/index.php -->'."\n";
3087print '<form action="'.$_SERVER["PHP_SELF"].($action == 'file_manager' ? '?uploadform=1' : '').'" method="POST" enctype="multipart/form-data" class="websiteformtoolbar">'."\n";
3088print '<input type="hidden" name="token" value="'.newToken().'">';
3089print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
3090print '<input type="hidden" name="dol_openinpopup" value="'.$dol_openinpopup.'">';
3091
3092if ($action == 'createsite') {
3093 print '<input type="hidden" name="action" value="addsite">';
3094}
3095if ($action == 'createcontainer') {
3096 print '<input type="hidden" name="action" value="addcontainer">';
3097}
3098if ($action == 'editcss') {
3099 print '<input type="hidden" name="action" value="updatecss">';
3100}
3101if ($action == 'editmenu') {
3102 print '<input type="hidden" name="action" value="updatemenu">';
3103}
3104if ($action == 'setashome') {
3105 print '<input type="hidden" name="action" value="updateashome">';
3106}
3107if ($action == 'editmeta') {
3108 print '<input type="hidden" name="action" value="updatemeta">';
3109}
3110if ($action == 'editsource') {
3111 print '<input type="hidden" name="action" value="updatesource">';
3112}
3113if ($action == 'editcontent') {
3114 print '<input type="hidden" name="action" value="updatecontent">';
3115}
3116if ($action == 'edit') {
3117 print '<input type="hidden" name="action" value="update">';
3118}
3119if ($action == 'importsite') {
3120 print '<input type="hidden" name="action" value="importsiteconfirm">';
3121}
3122if ($action == 'file_manager') {
3123 print '<input type="hidden" name="action" value="file_manager">';
3124}
3125if ($mode) {
3126 print '<input type="hidden" name="mode" value="'.$mode.'">';
3127}
3128if ($action == 'editsecurity') {
3129 print '<input type="hidden" name="action" value="updatesecurity">';
3130}
3131
3132print '<div>'."\n";
3133
3134// Add a margin under toolbar ?
3135$style = '';
3136if ($action != 'preview' && $action != 'editcontent' && $action != 'editsource' && !GETPOST('createpagefromclone', 'alphanohtml')) {
3137 $style = ' margin-bottom: 5px;';
3138}
3139
3140
3141$disabled = '';
3142if (!GETPOST('hide_websitemenu')) {
3143 if (!$user->hasRight('website', 'write')) {
3144 $disabled = ' disabled="disabled"';
3145 }
3146 $disabledexport = '';
3147 if (!$user->hasRight('website', 'export')) {
3148 $disabledexport = ' disabled="disabled"';
3149 }
3150
3151 if ($websitekey) {
3152 $virtualurl = '';
3153 $dataroot = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$websitekey;
3154 if (!empty($object->virtualhost)) {
3155 $virtualurl = $object->virtualhost;
3156 }
3157 }
3158
3159 $array = array();
3160 if ($object->id > 0) {
3161 $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
3162 $object->lines = $array;
3163 }
3164 if (!is_array($array) && $array < 0) {
3165 dol_print_error(null, $objectpage->error, $objectpage->errors);
3166 }
3167 $atleastonepage = (is_array($array) && count($array) > 0);
3168
3169 $websitepage = new WebsitePage($db);
3170 if ($pageid > 0) {
3171 $websitepage->fetch($pageid);
3172 }
3173
3174
3175 $disabled = '';
3176 $morecss = '';
3177 if (!$user->hasRight('website', 'write')) {
3178 $disabled = ' disabled="disabled"';
3179 $morecss = 'opacitymedium cursordefault';
3180 }
3181
3182 //var_dump($objectpage);exit;
3183 print '<div class="centpercent websitebar'.(GETPOST('dol_openinpopup', 'aZ09') ? ' hiddenforpopup' : '').'">'."\n";
3184
3185 //
3186 // Toolbar for websites
3187 //
3188
3189 print '<!-- Toolbar for website -->';
3190 if ($action != 'file_manager') {
3191 print '<div class="websiteselection hideonsmartphoneimp minwidth75 tdoverflowmax100 inline-block">';
3192 print $langs->trans("Website").': ';
3193 print '</div>';
3194
3195 // Button Add new website
3196 $urltocreatenewwebsite = $_SERVER["PHP_SELF"].'?action=createsite';
3197 if ($user->hasRight('website', 'write')) {
3198 print '<span class="websiteselection paddingrightonly">';
3199 print '<a href="'.$urltocreatenewwebsite.'" class=""'.$disabled.' title="'.dol_escape_htmltag($langs->trans("AddWebsite")).'"><span class="fa fa-plus-circle valignmiddle btnTitle-icon"><span></a>';
3200 print '</span>';
3201 }
3202
3203 // List of website
3204 print '<span class="websiteselection nopaddingrightimp">';
3205
3206 $out = '';
3207 $out .= '<select name="website" class="minwidth100 width200 maxwidth150onsmartphone" id="website">';
3208 if (empty($listofwebsites)) {
3209 $out .= '<option value="-1">&nbsp;</option>';
3210 }
3211
3212 // Loop on each sites
3213 $i = 0;
3214 foreach ($listofwebsites as $key => $valwebsite) {
3215 if (empty($websitekey)) {
3216 if ($action != 'createsite') {
3217 $websitekey = $valwebsite->ref;
3218 }
3219 }
3220
3221 $out .= '<option value="'.$valwebsite->ref.'"';
3222 if ($websitekey == $valwebsite->ref) {
3223 $out .= ' selected'; // To preselect a value
3224 }
3225 //$outoption = $valwebsite->getLibStatut(3).' '.$valwebsite->ref.' ';
3226 $outoption = (($valwebsite->status == $valwebsite::STATUS_DRAFT) ? '<span class="opacitymedium">' : '').$valwebsite->ref.(($valwebsite->status == $valwebsite::STATUS_DRAFT) ? '</span>' : '');
3227 $out .= ' data-html="'.dol_escape_htmltag($outoption).'"';
3228 $out .= '>';
3229 $out .= $valwebsite->ref;
3230 $out .= '</option>';
3231 $i++;
3232 }
3233 $out .= '</select>';
3234 $out .= ajax_combobox('website');
3235
3236 if (!empty($conf->use_javascript_ajax)) {
3237 $out .= '<script type="text/javascript">';
3238 $out .= 'jQuery(document).ready(function () {';
3239 $out .= ' jQuery("#website").change(function () {';
3240 $out .= ' console.log("We select "+jQuery("#website option:selected").val());';
3241 $out .= ' if (jQuery("#website option:selected").val() == \'-2\') {';
3242 $out .= ' window.location.href = "'.dol_escape_js($urltocreatenewwebsite).'";';
3243 $out .= ' } else {';
3244 $out .= ' window.location.href = "'.$_SERVER["PHP_SELF"].'?website="+jQuery("#website option:selected").val();';
3245 $out .= ' }';
3246 $out .= ' });';
3247 $out .= '});';
3248 $out .= '</script>';
3249 }
3250 print $out;
3251
3252 print '</span>';
3253
3254 // Switch offline/onine
3255 if (!empty($conf->use_javascript_ajax)) {
3256 print '<span class="websiteselection">';
3257 // Do not use ajax, we need a refresh of full page when we change status of a website
3258 //print '<div class="inline-block marginrightonly">';
3259 //print ajax_object_onoff($object, 'status', 'status', 'Online', 'Offline', array(), 'valignmiddle inline-block', 'statuswebsite');
3260 //print '</div>';
3261 if ($website->status == $website::STATUS_DRAFT) {
3262 $text_off = 'Offline';
3263 print '<a href="'.$_SERVER["PHP_SELF"].'?action=setwebsiteonline&token='.newToken().'&website='.urlencode($website->ref).'&websitepage='.((int) $websitepage->id).'"'.$disabled.'>'.img_picto($langs->trans($text_off), 'switch_off', '', 0, 0, 0, '', $morecss).'</a>';
3264 } else {
3265 $text_off = 'Online';
3266 print '<a href="'.$_SERVER["PHP_SELF"].'?action=setwebsiteoffline&token='.newToken().'&website='.urlencode($website->ref).'&websitepage='.((int) $websitepage->id).'"'.$disabled.'>'.img_picto($langs->trans($text_off), 'switch_on', '', 0, 0, 0, '', $morecss).'</a>';
3267 }
3268 print '</span>';
3269 }
3270
3271 // Refresh / Reload web site (for non javascript browsers)
3272 if (empty($conf->use_javascript_ajax)) {
3273 print '<span class="websiteselection">';
3274 print '<input type="image" class="valignmiddle" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshsite" value="'.$langs->trans("Load").'"'.$disabled.'>';
3275 print '</span>';
3276 }
3277
3278
3279 print '<span class="websiteselection">';
3280
3281 if ($websitekey && $websitekey != '-1' && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3282 // Edit website properties
3283 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($object->ref).'&pageid='.((int) $pageid).'&action=editcss&token='.newToken().'" class="button bordertransp valignmiddle" title="'.dol_escape_htmltag($langs->trans("EditCss")).'"'.$disabled.'>';
3284 print img_picto('', 'setup');
3285 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans("EditCss")).'</span>';
3286 print '</a>';
3287
3288 // Import web site
3289 $importlabel = $langs->trans("ImportSite");
3290 $exportlabel = $langs->trans("ExportSite");
3291 if (!empty($conf->dol_optimize_smallscreen)) {
3292 $importlabel = $langs->trans("Import");
3293 $exportlabel = $langs->trans("Export");
3294 }
3295
3296 if ($atleastonepage) {
3297 print '<input type="submit" class="button bordertransp" disabled="disabled" value="'.dol_escape_htmltag($importlabel).'" name="importsite">';
3298 } else {
3299 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($importlabel).'" name="importsite">';
3300 }
3301
3302 // // Export web site
3303 $extraCssClass = getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE') ? 'hideobject' : '';
3304 print '<input type="submit" class="button bordertransp ' . $extraCssClass . '" ' . $disabledexport . ' value="' . dol_escape_htmltag($exportlabel) . '" name="exportsite">';
3305
3306 if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) {
3307 // Overwrite template in sources
3308 $overwriteGitUrl = $_SERVER["PHP_SELF"] . '?action=overwritesite&website=' . urlencode($website->ref);
3309 print dolButtonToOpenExportDialog('exportpopup', $langs->trans('ExportOptions'), $langs->trans('ExportSite'), 'exportsite', $overwriteGitUrl, $website);
3310 //print '<a href="'.$_SERVER["PHP_SELF"].'?action=overwritesite&website='.urlencode($website->ref).'" class="button bordertransp hideobject" title="'.dol_escape_htmltag($langs->trans("ExportIntoGIT").". Directory ".getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')).'">'.dol_escape_htmltag($langs->trans("ExportIntoGIT")).'</a>';
3311 }
3312
3313 // Clone web site
3314 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">';
3315
3316 // Delete website
3317 if (!$permissiontodelete) {
3318 $disabled = ' disabled="disabled"';
3319 $title = $langs->trans("NotEnoughPermissions");
3320 $url = '#';
3321 } else {
3322 if ($website->status == $website::STATUS_VALIDATED) {
3323 $disabled = ' disabled="disabled"';
3324 $title = $langs->trans("WebsiteMustBeDisabled", $langs->transnoentitiesnoconv($website->LibStatut(0, 0)));
3325 $url = '#';
3326 } else {
3327 $disabled = '';
3328 $title = $langs->trans("Delete");
3329 $url = $_SERVER["PHP_SELF"].'?action=deletesite&token='.newToken().'&website='.urlencode($website->ref);
3330 }
3331 }
3332 print '<a href="'.$url.'" class="button buttonDelete bordertransp'.($disabled ? ' disabled' : '').'"'.$disabled.' title="'.dol_escape_htmltag($title).'">'.img_picto('', 'delete', 'class=""').'<span class="hideonsmartphone paddingleft">'.$langs->trans("Delete").'</span></a>';
3333
3334 // Regenerate all pages
3335 print '<a href="'.$_SERVER["PHP_SELF"].'?action=regeneratesite&token='.newToken().'&website='.urlencode($website->ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("RegenerateWebsiteContent")).'"><span class="far fa-hdd"></span></a>';
3336
3337 // Generate site map
3338 print '<a href="'.$_SERVER["PHP_SELF"].'?action=confirmgeneratesitemaps&token='.newToken().'&website='.urlencode($website->ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("GenerateSitemaps")).'"><span class="fa fa-sitemap"></span></a>';
3339
3340 // Find / replace tool
3341 print '<a href="'.$_SERVER["PHP_SELF"].'?action=replacesite&token='.newToken().'&website='.urlencode($website->ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("ReplaceWebsiteContent")).'"><span class="fa fa-search"></span></a>';
3342 }
3343
3344 print '</span>';
3345
3346 if ($websitekey && $websitekey != '-1' && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3347 print '<span class="websiteselection">';
3348
3349 print dolButtonToOpenUrlInDialogPopup('file_manager', $langs->transnoentitiesnoconv("MediaFiles"), '<span class="fa fa-image"></span>', '/website/index.php?action=file_manager&website='.urlencode($website->ref).'&section_dir='.urlencode('image/'.$website->ref.'/'), $disabled);
3350
3351 if (isModEnabled('category')) {
3352 //print '<a href="'.DOL_URL_ROOT.'/categories/categorie_list.php?leftmenu=website&dol_hide_leftmenu=1&nosearch=1&type=website_page&website='.$website->ref.'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("Categories")).'"><span class="fa fa-tags"></span></a>';
3353 print dolButtonToOpenUrlInDialogPopup('categories', $langs->transnoentitiesnoconv("Categories"), '<span class="fa fa-tags"></span>', '/categories/categorie_list.php?leftmenu=website&nosearch=1&type='.urlencode(Categorie::TYPE_WEBSITE_PAGE).'&website='.urlencode($website->ref), $disabled);
3354 }
3355
3356 print '</span>';
3357 }
3358 } else {
3359 print '<input type="hidden" name="website" id="website" value="'.$websitekey.'">';
3360 }
3361
3362
3363 print '<span class="websitetools">';
3364
3365 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite') {
3366 $urlext = $virtualurl;
3367 $urlint = $urlwithroot.'/public/website/index.php?website='.$websitekey;
3368
3369 print '<span class="websiteinputurl valignmiddle" id="websiteinputurl">';
3370 $linktotestonwebserver = '<a href="'.($virtualurl ? $virtualurl : '#').'" class="valignmiddle">';
3371 $linktotestonwebserver .= '<span class="hideonsmartphone paddingrightonly">'.$langs->trans("TestDeployOnWeb", $virtualurl).'</span>'.img_picto('', 'globe');
3372 $linktotestonwebserver .= '</a>';
3373
3374 $htmltext = '';
3375 if (empty($object->fk_default_home)) {
3376 $htmltext .= '<br><span class="error">'.$langs->trans("YouMustDefineTheHomePage").'</span><br><br>';
3377 } elseif (empty($virtualurl)) {
3378 //$htmltext .= '<br><span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span><br><br>';
3379 } else {
3380 $htmltext .= '<br><center>'.$langs->trans("GoTo").' <a href="'.$virtualurl.'" target="_website">'.$virtualurl.' '.img_picto('', 'url').'</a></center><br>';
3381 }
3382 if (getDolGlobalString('WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER')) {
3383 $htmltext .= '<!-- Message defined translate key set into WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER -->';
3384 $htmltext .= '<br>'.$langs->trans(getDolGlobalString('WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER'));
3385 } else {
3386 $htmltext .= $langs->trans("ToDeployYourWebsiteOnLiveYouHave3Solutions").'<br><br>';
3387 $htmltext .= '<div class="titre inline-block">1</div> - '.$langs->trans("SetHereVirtualHost", $dataroot);
3388 $htmltext .= '<br>';
3389 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
3390 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
3391 $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias', $htmltext);
3392
3393 $examplewithapache = "<VirtualHost *:80>\n";
3394 $examplewithapache .= '#php_admin_value open_basedir /tmp/:'.DOL_DOCUMENT_ROOT.':'.DOL_DATA_ROOT.':/dev/urandom'."\n";
3395 //$examplewithapache .= '#php_admin_value disable_functions "exec,passthru,shell_exec,system,popen,proc_open"'."\n"; This is not effective if not in php.ini
3396 $examplewithapache .= "\n";
3397 $examplewithapache .= 'DocumentRoot "'.DOL_DOCUMENT_ROOT.'"'."\n";
3398 $examplewithapache .= "\n";
3399 $examplewithapache .= '<Directory "'.DOL_DOCUMENT_ROOT.'">'."\n";
3400 $examplewithapache .= 'AllowOverride FileInfo Options
3401 Options -Indexes -MultiViews -FollowSymLinks -ExecCGI
3402 Require all granted
3403 </Directory>'."\n".'
3404 <Directory "'.DOL_DATA_ROOT.'/website">
3405 AllowOverride FileInfo Options
3406 Options -Indexes -MultiViews +FollowSymLinks -ExecCGI
3407 Require all granted
3408 </Directory>'."\n".'
3409 <Directory "'.DOL_DATA_ROOT.'/medias">
3410 AllowOverride FileInfo Options
3411 Options -Indexes -MultiViews -FollowSymLinks -ExecCGI
3412 Require all granted
3413 </Directory>'."\n";
3414
3415 $examplewithapache .= "\n";
3416 $examplewithapache .= "#ErrorLog /var/log/apache2/".$websitekey."_error_log\n";
3417 $examplewithapache .= "#TransferLog /var/log/apache2/".$websitekey."_access_log\n";
3418
3419 $examplewithapache .= "\n";
3420 $examplewithapache .= "# If you need include the payment page into a frame of the website,\n";
3421 $examplewithapache .= "# you need to make a proxy redirection of URLs required for the payment to your backoffice pages\n";
3422 $examplewithapache .= "#SSLProxyEngine On\n";
3423 $examplewithapache .= "#SSLProxyVerify none\n";
3424 $examplewithapache .= "#SSLProxyCheckPeerCN off\n";
3425 $examplewithapache .= "#SSLProxyCheckPeerName off\n";
3426 $examplewithapache .= "#ProxyPreserveHost Off\n";
3427 $examplewithapache .= '#ProxyPass "/public/payment/" "'.$urlwithroot.'/public/payment/'."\n";
3428 $examplewithapache .= '#ProxyPassReverse "/public/payment/" "'.$urlwithroot.'/public/payment/'."\n";
3429 $examplewithapache .= '#ProxyPass "/includes/" "'.$urlwithroot.'/includes/'."\n";
3430 $examplewithapache .= '#ProxyPassReverse "/includes/" "'.$urlwithroot.'/includes/'."\n";
3431 $examplewithapache .= '#ProxyPass "/theme/" "'.$urlwithroot.'/theme/'."\n";
3432 $examplewithapache .= '#ProxyPassReverse "/theme/" "'.$urlwithroot.'/theme/'."\n";
3433 $examplewithapache .= '#ProxyPass "/core/js/" "'.$urlwithroot.'/core/js/'."\n";
3434 $examplewithapache .= '#ProxyPassReverse "/core/js/" "'.$urlwithroot.'/core/js/'."\n";
3435 $examplewithapache .= "\n";
3436
3437 $examplewithapache .= "</VirtualHost>\n";
3438
3439 $htmltext .= '<br>'.$langs->trans("ExampleToUseInApacheVirtualHostConfig").':<br>';
3440 $htmltext .= '<div class="quatrevingtpercent exampleapachesetup wordbreak" spellcheck="false">'.dol_nl2br(dol_escape_htmltag($examplewithapache, 1, 1)).'</div>';
3441
3442 $htmltext .= '<br>';
3443 $htmltext .= '<div class="titre inline-block">2</div> - '.$langs->trans("YouCanAlsoTestWithPHPS");
3444 $htmltext .= '<br><div class="urllink"><input type="text" id="cliphpserver" spellcheck="false" class="quatrevingtpercent" value="php -S 0.0.0.0:8080 -t '.$dataroot.'"></div>';
3445 $htmltext .= ajax_autoselect("cliphpserver");
3446 $htmltext .= '<br>';
3447 $htmltext .= '<div class="titre inline-block">3</div> - '.$langs->trans("YouCanAlsoDeployToAnotherWHP");
3448 }
3449 print $form->textwithpicto($linktotestonwebserver, $htmltext, 1, 'none', 'valignmiddle', 0, 3, 'helpvirtualhost');
3450 print '</span>';
3451 }
3452
3453 if (in_array($action, array('editcss', 'editmenu', 'file_manager', 'replacesiteconfirm', 'editsecurity')) || in_array($mode, array('replacesite'))) {
3454 if (!$user->hasRight('website', 'write')) {
3455 $disabled = ' disabled';
3456 }
3457 if ($action == 'editcss' || $action == 'editsecurity') {
3458 print '<input type="submit" accesskey="s" title="'.dol_escape_htmltag($conf->browser->stringforfirstkey.' s').'" id="savefileandstay" class="button buttonforacesave hideonsmartphone small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("SaveAndStay")).'" name="updateandstay">';
3459 }
3460 if (preg_match('/^create/', $action) && $action != 'file_manager' && $action != 'replacesite' && $action != 'replacesiteconfirm') {
3461 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3462 }
3463 if (preg_match('/^edit/', $action) && $action != 'file_manager' && $action != 'replacesite' && $action != 'replacesiteconfirm') {
3464 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3465 }
3466 if ($action != 'preview') {
3467 print '<input type="submit" class="button button-cancel small" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="cancel">';
3468 }
3469 }
3470
3471 print '</span>';
3472
3473 //
3474 // Toolbar for pages
3475 //
3476
3477 if ($websitekey && $websitekey != '-1' && (!in_array($action, array('editcss', 'editmenu', 'importsite', 'file_manager', 'replacesite', 'replacesiteconfirm', 'editsecurity'))) && (!in_array($mode, array('replacesite'))) && !$file_manager) {
3478 print '</div>'; // Close current websitebar to open a new one
3479
3480 print '<!-- Toolbar for websitepage -->';
3481 print '<div class="centpercent websitebar"'.($style ? ' style="'.$style.'"' : '').'>'."\n";
3482
3483 print '<div class="websiteselection hideonsmartphoneimp minwidth75 tdoverflowmax100 inline-block">';
3484 print $langs->trans("PageContainer").': ';
3485 print '</div>';
3486
3487 // Button Add new web page
3488 if ($user->hasRight('website', 'write')) {
3489 print '<span class="websiteselection paddingrightonly">';
3490 print '<a href="'.$_SERVER["PHP_SELF"].'?action=createcontainer&token='.newToken().'&website='.urlencode($website->ref).'" class=""'.$disabled.' title="'.dol_escape_htmltag($langs->trans("AddPage")).'"><span class="fa fa-plus-circle valignmiddle btnTitle-icon"></span></a>';
3491 print '</span>';
3492 }
3493
3494 $out = '';
3495
3496 $s = $formwebsite->selectContainer($website, 'pageid', $pageid, 0, $action, 'minwidth100 maxwidth200onsmartphone');
3497
3498 $out .= '<span class="websiteselection nopaddingrightimp">';
3499 $out .= $s;
3500 $out .= '</span>';
3501
3502 $urltocreatenewpage = $_SERVER["PHP_SELF"].'?action=createcontainer&token='.newToken().'&website='.urlencode($website->ref);
3503
3504 if (!empty($conf->use_javascript_ajax)) {
3505 $out .= '<script type="text/javascript">';
3506 $out .= 'jQuery(document).ready(function () {';
3507 $out .= ' jQuery("#pageid").change(function () {';
3508 $out .= ' console.log("We select "+jQuery("#pageid option:selected").val());';
3509 $out .= ' if (jQuery("#pageid option:selected").val() == \'-2\') {';
3510 $out .= ' window.location.href = "'.$urltocreatenewpage.'";';
3511 $out .= ' } else {';
3512 $out .= ' window.location.href = "'.$_SERVER["PHP_SELF"].'?website='.urlencode($website->ref).'&pageid="+jQuery("#pageid option:selected").val();';
3513 $out .= ' }';
3514 $out .= ' });';
3515 $out .= '});';
3516 $out .= '</script>';
3517 }
3518
3519 print $out;
3520
3521 // Button to switch status
3522 if (!empty($conf->use_javascript_ajax)) {
3523 print '<span class="websiteselection">';
3524 //print '<div class="inline-block marginrightonly">';
3525 if ($object->status == $object::STATUS_DRAFT) { // website is off, we do not allow to change status of page
3526 $text_off = 'SetWebsiteOnlineBefore';
3527 if ($websitepage->status == $websitepage::STATUS_DRAFT) { // page is off
3528 print '<span class="valignmiddle disabled opacitymedium">'.img_picto($langs->trans($text_off), 'switch_off', '', 0, 0, 0, '', $morecss).'</span>';
3529 } else {
3530 print '<span class="valignmiddle disabled opacitymedium">'.img_picto($langs->trans($text_off), 'switch_on', '', 0, 0, 0, '', $morecss).'</span>';
3531 }
3532 } else {
3533 if ($objectpage->type_container != 'setup') { // we do not allow to change status of setup pages
3534 print ajax_object_onoff($websitepage, 'status', 'status', 'Online', 'Offline', array(), 'valignmiddle inline-block'.((empty($websitepage->id) || !$user->hasRight('website', 'write')) ? ' opacitymedium disabled' : ''), 'statuswebsitepage', 1, 'website='.urlencode($website->ref).'&pageid='.((int) $websitepage->id), $user->hasRight('website', 'write') ? 0 : 1);
3535 }
3536 }
3537 //print '</div>';
3538 print '</span>';
3539 }
3540
3541 print '<span class="websiteselection">';
3542
3543 print '<input type="image" class="valignmiddle buttonwebsite hideonsmartphone" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'"'.(($action != 'editsource') ? '' : ' disabled="disabled"').'>';
3544
3545 // Print nav arrows
3546 $pagepreviousid = 0;
3547 $pagenextid = 0;
3548 if ($pageid) {
3549 $sql = "SELECT MAX(rowid) as pagepreviousid FROM ".MAIN_DB_PREFIX."website_page WHERE rowid < ".((int) $pageid)." AND fk_website = ".((int) $object->id);
3550 $resql = $db->query($sql);
3551 if ($resql) {
3552 $obj = $db->fetch_object($resql);
3553 if ($obj) {
3554 $pagepreviousid = $obj->pagepreviousid;
3555 }
3556 } else {
3558 }
3559 $sql = "SELECT MIN(rowid) as pagenextid FROM ".MAIN_DB_PREFIX."website_page WHERE rowid > ".((int) $pageid)." AND fk_website = ".((int) $object->id);
3560 $resql = $db->query($sql);
3561 if ($resql) {
3562 $obj = $db->fetch_object($resql);
3563 if ($obj) {
3564 $pagenextid = $obj->pagenextid;
3565 }
3566 } else {
3568 }
3569 }
3570
3571 if ($pagepreviousid) {
3572 print '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.((int) $pagepreviousid).'&action='.urlencode($action).'&token='.newToken().'">'.img_previous($langs->trans("PreviousContainer")).'</a>';
3573 } else {
3574 print '<span class="valignmiddle opacitymedium">'.img_previous($langs->trans("PreviousContainer")).'</span>';
3575 }
3576 if ($pagenextid) {
3577 print '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.((int) $pagenextid).'&action='.urlencode($action).'&token='.newToken().'">'.img_next($langs->trans("NextContainer")).'</a>';
3578 } else {
3579 print '<span class="valignmiddle opacitymedium">'.img_next($langs->trans("NextContainer")).'</span>';
3580 }
3581
3582 print '</span>';
3583
3584 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite') {
3585 $disabled = '';
3586 if (!$user->hasRight('website', 'write')) {
3587 $disabled = ' disabled="disabled"';
3588 }
3589
3590 // Confirmation delete site
3591 if ($action == 'deletesite') {
3592 // Create an array for form
3593 $formquestion = array(
3594 array('type' => 'checkbox', 'name' => 'delete_also_js', 'label' => $langs->trans("DeleteAlsoJs"), 'value' => 0),
3595 array('type' => 'checkbox', 'name' => 'delete_also_medias', 'label' => $langs->trans("DeleteAlsoMedias"), 'value' => 0),
3596 //array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'aZ09')?GETPOST('newlang', 'aZ09'):$langs->defaultlang, 'newlang', 0, null, '', 0, 0, 'minwidth200')),
3597 //array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0))
3598 );
3599
3600 if ($atleastonepage) {
3601 $langs->load("errors");
3602 $formquestion[] = array('type' => 'onecolumn', 'value' => '<div class="warning">'.$langs->trans("WarningPagesWillBeDeleted").'</div>');
3603 }
3604
3605 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteWebsite'), '', 'confirm_deletesite', $formquestion, 0, 1, 210 + ($atleastonepage ? 70 : 0), 580);
3606
3607 print $formconfirm;
3608 }
3609
3610 // Confirmation to clone
3611 if ($action == 'createfromclone') {
3612 // Create an array for form
3613 $formquestion = array(
3614 array('type' => 'text', 'name' => 'siteref', 'label' => $langs->trans("WebSite"), 'value' => 'copy_of_'.$object->ref)
3615 );
3616
3617 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('CloneSite'), '', 'confirm_createfromclone', $formquestion, 0, 1, 0);
3618
3619 print $formconfirm;
3620 }
3621
3622 if ($pageid > 0 && $atleastonepage) { // pageid can be set without pages, if homepage of site is set and all pages were removed
3623 // Confirmation to clone
3624 if ($action == 'createpagefromclone') {
3625 // Create an array for form
3626 $preselectedlanguage = GETPOST('newlang', 'aZ09') ? GETPOST('newlang', 'aZ09') : ($objectpage->lang ?: ''); // Dy default, we do not force any language on pages
3627 $onlylang = array();
3628 if ($website->otherlang) {
3629 if (!empty($website->lang)) {
3630 $onlylang[$website->lang] = $website->lang.' ('.$langs->trans("Default").')';
3631 }
3632 foreach (explode(',', $website->otherlang) as $langkey) {
3633 if (empty(trim($langkey))) {
3634 continue;
3635 }
3636 $onlylang[$langkey] = $langkey;
3637 }
3638 $textifempty = $langs->trans("Default");
3639 } else {
3640 $onlylang['none'] = 'none';
3641 $textifempty = $langs->trans("Default");
3642 }
3643
3644 $formquestion = array(
3645 array('type' => 'hidden', 'name' => 'sourcepageurl', 'value' => $objectpage->pageurl),
3646 array('type' => 'other', 'tdclass' => 'fieldrequired', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite((string) $object->id, 'newwebsite', 0)),
3647 array('type' => 'text', 'tdclass' => 'maxwidth200 fieldrequired', 'moreattr' => 'autofocus="autofocus"', 'name' => 'newtitle', 'label' => $langs->trans("WEBSITE_TITLE"), 'value' => $langs->trans("CopyOf").' '.$objectpage->title),
3648 array('type' => 'text', 'tdclass' => 'maxwidth200', 'name' => 'newpageurl', 'label' => $langs->trans("WEBSITE_PAGENAME"), 'value' => '')
3649 );
3650 if (count($onlylang) > 1) {
3651 $formquestion[] = array('type' => 'checkbox', 'tdclass' => 'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0,
3652 'morecss' => 'margintoponly',
3653 'moreattr' => 'onclick="console.log(\'Click on is_a_translation\'); jQuery(\'#newlang\').val(-1).trigger(\'change\');"'
3654 );
3655 }
3656
3657 $value = $formadmin->select_language($preselectedlanguage, 'newlang', 0, array(), $textifempty, 0, 0, 'minwidth200', 1, 0, 0, $onlylang, 1);
3658 $formquestion[] = array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $value);
3659
3660 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 0, 550);
3661
3662 print $formconfirm;
3663 }
3664
3665 print '<span class="websiteselection">';
3666
3667 // Edit web page properties
3668 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid.'&action=editmeta&token='.newToken().'" class="button bordertransp valignmiddle" title="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'"'.$disabled.'>';
3669 print img_picto('', 'setup');
3670 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans("EditPageMeta")).'</span>';
3671 print '</a>';
3672
3673 // Edit HTML content
3674 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid.'&action=editsource&token='.newToken().'" class="button bordertransp"'.$disabled.'>';
3675 print img_picto('', 'code');
3676 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans($conf->dol_optimize_smallscreen ? "HTML" : "EditHTMLSource")).'</span>';
3677 print '</a>';
3678
3679 // Edit CKEditor
3680 if (getDolGlobalInt('WEBSITE_ALLOW_CKEDITOR')) {
3681 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid.'&action=editcontent&token='.newToken().'" class="button bordertransp"'.$disabled.'>'.dol_escape_htmltag("CKEditor").'</a>';
3682 } else {
3683 print '<!-- Add option WEBSITE_ALLOW_CKEDITOR to allow ckeditor -->';
3684 }
3685
3686 print '</span>';
3687
3688
3689 // Switch include dynamic content / edit inline
3690 print '<!-- button EditInLine and ShowSubcontainers -->'."\n";
3691 print '<div class="websiteselectionsection inline-block">';
3692
3693 // Force to show subcontainers if we are in setup mode
3694 if ($objectpage->type_container == 'setup') {
3695 dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1);
3696 }
3697
3698 if ($objectpage->type_container != 'setup') {
3699 print '<div class="inline-block marginrightonly">'; // Button includes dynamic content
3700 print $langs->trans("ShowSubcontainers");
3701 if (!getDolGlobalString('WEBSITE_SUBCONTAINERSINLINE')) {
3702 print '<a class="nobordertransp nohoverborder marginleftonlyshort valignmiddle"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=setshowsubcontainers&token='.newToken().'">'.img_picto($langs->trans("ShowSubContainersOnOff", $langs->transnoentitiesnoconv("Off")), 'switch_off', '', 0, 0, 0, '', 'nomarginleft').'</a>';
3703 } else {
3704 print '<a class="nobordertransp nohoverborder marginleftonlyshort valignmiddle"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=unsetshowsubcontainers&token='.newToken().'">'.img_picto($langs->trans("ShowSubContainersOnOff", $langs->transnoentitiesnoconv("On")), 'switch_on', '', 0, 0, 0, '', 'nomarginleft').'</a>';
3705 }
3706 print '</div>';
3707 }
3708
3709 print '<div class="inline-block marginrightonly">'; // Button edit inline
3710
3711 print '<span id="switchckeditorinline">'."\n";
3712 // Enable CKEditor inline with js on section and div with conteneditable=true
3713 print '<!-- Code to enabled edit inline ckeditor -->'."\n";
3714 print '<script type="text/javascript">
3715 $(document).ready(function() {
3716 var isEditingEnabled = '.(getDolGlobalString("WEBSITE_EDITINLINE") ? 'true' : 'false').';
3717 if (isEditingEnabled)
3718 {
3719 switchEditorOnline(true);
3720 }
3721
3722 $( "#switchckeditorinline" ).click(function() {
3723 switchEditorOnline();
3724 });
3725
3726 function switchEditorOnline(forceenable)
3727 {
3728 if (! isEditingEnabled || forceenable)
3729 {
3730 console.log("Enable inline edit for some html tags with contenteditable=true attribute");
3731
3732 jQuery(\'section[contenteditable="true"],div[contenteditable="true"],header[contenteditable="true"],main[contenteditable="true"],footer[contenteditable="true"]\').each(function(idx){
3733 var idtouse = $(this).attr(\'id\');
3734 console.log("Enable inline edit for "+idtouse);
3735 if (idtouse !== undefined) {
3736 var inlineditor = CKEDITOR.inline(idtouse, {
3737 // Allow some non-standard markup that we used in the introduction.
3738 // + a[target];div{float,display} ?
3739 extraAllowedContent: \'span(*);cite(*);q(*);dl(*);dt(*);dd(*);ul(*);li(*);header(*);main(*);footer(*);button(*);h1(*);h2(*);h3(*);\',
3740 //extraPlugins: \'sourcedialog\',
3741 removePlugins: \'flash,stylescombo,exportpdf,scayt,wsc,pagebreak,iframe,smiley\',
3742 // Show toolbar on startup (optional).
3743 // startupFocus: true
3744 });
3745
3746 // Custom bar tool
3747 // Note the Source tool does not work on inline
3748 inlineditor.config.toolbar = [
3749 [\'Templates\',\'NewPage\'],
3750 [\'Save\'],
3751 [\'Maximize\',\'Preview\'],
3752 [\'PasteText\'],
3753 [\'Undo\',\'Redo\',\'-\',\'Find\',\'Replace\',\'-\',\'SelectAll\',\'RemoveFormat\'],
3754 [\'CreateDiv\',\'ShowBlocks\'],
3755 [\'Form\', \'Checkbox\', \'Radio\', \'TextField\', \'Textarea\', \'Select\', \'Button\', \'ImageButton\', \'HiddenField\'],
3756 [\'Bold\',\'Italic\',\'Underline\',\'Strike\',\'Superscript\'],
3757 [\'NumberedList\',\'BulletedList\',\'-\',\'Outdent\',\'Indent\',\'Blockquote\'],
3758 [\'JustifyLeft\',\'JustifyCenter\',\'JustifyRight\',\'JustifyBlock\'],
3759 [\'Link\',\'Unlink\'],
3760 [\'Image\',\'Table\',\'HorizontalRule\'],
3761 [\'Styles\',\'Format\',\'Font\',\'FontSize\'],
3762 [\'TextColor\',\'BGColor\']
3763 ];
3764
3765 // Start editor
3766 //inlineditor.on(\'instanceReady\', function () {
3767 // ...
3768 //});
3769
3770 CKEDITOR.instances[idtouse].on(\'change\', function() {
3771 $(this.element.$).addClass(\'modified\');
3772 })
3773 } else {
3774 console.warn("A html section has the contenteditable=true attribute but has no id attribute");
3775 }
3776 })
3777
3778 isEditingEnabled = true;
3779
3780 // Trigger the function when clicking outside the elements with contenteditable=true attribute
3781 // so we can save the change.
3782 $(document).on(\'click\', function(e) {
3783 var target = $(e.target);
3784
3785 // Check if the click is outside the elements with contenteditable=true attribute
3786 if (!target.closest(\'[contenteditable="true"]\').length) {
3787 // Repeat through the elements with contenteditable="true" attribute
3788 $(\'[contenteditable="true"]\').each(function() {
3789 var idToUse = $(this).attr(\'id\');
3790 var elementType = $(this).prop("tagName").toLowerCase(); // Get the tag name (div, section, footer...)
3791 var instance = CKEDITOR.instances[idToUse];
3792
3793 // Check if the element has been modified
3794 if ($(this).hasClass(\'modified\')) {
3795 var content = instance.getData();
3796 content = "\\n" + content;
3797
3798 // Retrieving the content and ID of the element
3799 var elementId = $(this).attr(\'id\');
3800
3801 ';
3802 if (getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) {
3803 print '
3804 console.log("A change has been detected, we send new content for update with ajax");
3805
3806 // Sending data via AJAX to update section
3807 $.ajax({
3808 type: \'POST\',
3809 url: \'' . DOL_URL_ROOT . '/core/ajax/editinline.php\',
3810 data: {
3811 website_ref: \''.dol_escape_js($website->ref).'\',
3812 page_id: \'' . ((int) $websitepage->id) . '\',
3813 content: content,
3814 element_id: elementId,
3815 element_type: elementType,
3816 action: \'updatedElementContent\',
3817 token: \'' . currentToken() . '\'
3818 },
3819 success: function(response) {
3820 console.log(response);
3821 var $lastWebsitebar = $(".websitebar").last();
3822 var $span = $("<span></span>").html("'.$langs->trans("Saved").'").css({
3823 \'display\': \'block\',
3824 \'position\': \'absolute\',
3825 \'margin-top\': \'6px\',
3826 \'right\': \'5px\',
3827 \'background-color\': \'#e3f0db\',
3828 \'color\': \'#446548\',
3829 \'font-size\': \'14px\',
3830 \'padding\': \'0px 5px\',
3831 \'z-index\': 1000
3832 });
3833 $lastWebsitebar.after($span);
3834
3835 // Close message after 2 seconds
3836 setTimeout(function() {
3837 $span.fadeOut(500, function() {
3838 $(this).remove();
3839 });
3840 }, 2000);
3841 }
3842 });
3843 ';
3844 } else {
3845 print 'console.log("A change has been detected, but saving is not enabled by option WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT, so no ajax update is done");';
3846 }
3847 print '
3848
3849 $(this).removeClass(\'modified\');
3850 }
3851 });
3852 }
3853 });
3854
3855 } else {
3856 console.log("Disable inline edit");
3857 for(name in CKEDITOR.instances) {
3858 CKEDITOR.instances[name].destroy(true);
3859 }
3860 isEditingEnabled = false;
3861 }
3862 }
3863 });
3864 </script>';
3865 print $langs->trans("EditInLine");
3866 print '</span>';
3867
3868 //$disableeditinline = $websitepage->grabbed_from;
3869 $disableeditinline = 0;
3870 if ($disableeditinline) {
3871 //print '<input type="submit" class="button bordertransp" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'" value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
3872 print '<a class="nobordertransp opacitymedium nohoverborder marginleftonlyshort"'.$disabled.' href="#" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'">'.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"), 'switch_off', '', 0, 0, 0, '', 'nomarginleft').'</a>';
3873 } else {
3874 //print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
3875 if (!getDolGlobalString('WEBSITE_EDITINLINE')) {
3876 print '<a class="nobordertransp nohoverborder marginleftonlyshort valignmiddle"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=seteditinline&token='.newToken().'">'.img_picto($langs->trans("EditInLineOnOff", $langs->transnoentitiesnoconv("Off")), 'switch_off', '', 0, 0, 0, '', 'nomarginleft').'</a>';
3877 } else {
3878 print '<a class="nobordertransp nohoverborder marginleftonlyshort valignmiddle"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=unseteditinline&token='.newToken().'">'.img_picto($langs->trans("EditInLineOnOff", $langs->transnoentitiesnoconv("On")), 'switch_on', '', 0, 0, 0, '', 'nomarginleft').'</a>';
3879 }
3880 }
3881
3882 print '</div>';
3883
3884 print '</div>';
3885
3886 // Set page as homepage
3887 print '<span class="websiteselection">';
3888 if ($object->fk_default_home > 0 && $pageid == $object->fk_default_home) {
3889 //$disabled=' disabled="disabled"';
3890 //print '<span class="button bordertransp disabled"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'"><span class="fas fa-home"></span></span>';
3891 //print '<input type="submit" class="button bordertransp" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
3892 print '<a href="#" class="button bordertransp disabled" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'"><span class="fas fa-home valignmiddle btnTitle-icon"></span></a>';
3893 } else {
3894 //$disabled='';
3895 //print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
3896 print '<a href="'.$_SERVER["PHP_SELF"].'?action=setashome&token='.newToken().'&website='.urlencode($website->ref).'&pageid='.((int) $pageid).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'"><span class="fas fa-home valignmiddle btnTitle-icon"></span></a>';
3897 }
3898 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ClonePage")).'" name="createpagefromclone">';
3899
3900 // Delete
3901 if ($websitepage->status != $websitepage::STATUS_DRAFT) {
3902 $disabled = ' disabled="disabled"';
3903 $title = $langs->trans("WebpageMustBeDisabled", $langs->transnoentitiesnoconv($websitepage->LibStatut(0, 0)));
3904 $url = '#';
3905 } else {
3906 $disabled = '';
3907 $title = '';
3908 $url = $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&pageid='.((int) $websitepage->id).'&website='.urlencode($website->ref); // action=delete for webpage, deletesite for website
3909 }
3910 print '<a href="'.$url.'" class="button buttonDelete bordertransp'.($disabled ? ' disabled' : '').'"'.$disabled.' title="'.dol_escape_htmltag($title).'">'.img_picto('', 'delete', 'class=""').'<span class="hideonsmartphone paddingleft">'.$langs->trans("Delete").'</span></a>';
3911 print '</span>';
3912 }
3913 }
3914
3915 //print '</span>'; // end website selection
3916
3917 print '<span class="websitetools">';
3918
3919 if (($pageid > 0 && $atleastonepage) && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3920 $realpage = $urlwithroot.'/public/website/index.php?website='.$websitekey.'&pageref='.$websitepage->pageurl;
3921 $pagealias = $websitepage->pageurl;
3922
3923 $htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $langs->transnoentitiesnoconv("TestDeployOnWeb"));
3924 //$htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), '{s1}');
3925 //$htmltext = str_replace('{s1}', $dataroot.'<br>'.DOL_DATA_ROOT.'/medias<br>'.DOL_DOCUMENT_ROOT, $htmltext);
3926 //$htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
3927 //$htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/medias', $htmltext);
3928
3929 print '<div class="websiteinputurl inline-block paddingright">';
3930 print '<a class="websitebuttonsitepreview inline-block" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
3931 print $form->textwithpicto('', $htmltext, 1, 'preview');
3932 print '</a>'; // View page in new Tab
3933 print '</div>';
3934
3935 /*print '<div class="websiteinputurl inline-block" id="websiteinputpage">';
3936 print '<input type="text" id="previewpageurl" class="minwidth200imp" name="previewsite" value="'.$pagealias.'" disabled="disabled">';
3937 $htmltext = $langs->trans("PageNameAliasHelp", $langs->transnoentitiesnoconv("EditPageMeta"));
3938 print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helppagealias');
3939 print '</div>';*/
3940
3941 /*
3942 $urlext = $virtualurl.'/'.$pagealias.'.php';
3943 $urlint = $urlwithroot.'/public/website/index.php?website='.$websitekey;
3944
3945 $htmltext = $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $virtualurl ? $urlext : '<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>');
3946
3947 print '<a class="websitebuttonsitepreview'.($virtualurl ? '' : ' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($htmltext).'">';
3948 print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
3949 print '</a>';
3950 */
3951 //print '<input type="submit" class="button" name="previewpage" target="tab'.$websitekey.'"value="'.$langs->trans("ViewPageInNewTab").'">';
3952
3953 // TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext
3954 }
3955 if (!in_array($mode, array('replacesite')) && !in_array($action, array('editcss', 'editmenu', 'file_manager', 'replacesiteconfirm', 'createsite', 'createcontainer', 'createfromclone', 'createpagefromclone', 'deletesite', 'editsecurity'))) {
3956 if (!$user->hasRight('website', 'write')) {
3957 $disabled = ' disabled';
3958 }
3959 if ($action == 'editsource' || $action == 'editmeta') {
3960 print '<input type="submit" accesskey="s" title="'.dol_escape_htmltag($conf->browser->stringforfirstkey.' s').'" id="savefileandstay" class="button buttonforacesave hideonsmartphone small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("SaveAndStay")).'" name="updateandstay">';
3961 }
3962 if (preg_match('/^create/', $action)) {
3963 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3964 }
3965 if (preg_match('/^edit/', $action)) {
3966 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3967 }
3968 if ($action != 'preview') {
3969 print '<input type="submit" class="button button-cancel small" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="cancel">';
3970 }
3971 }
3972
3973 print '</span>'; // end websitetools
3974
3975 print '<span class="websitehelp">';
3976 if ($action == 'editsource' || $action == 'editcontent' || GETPOST('editsource', 'alpha') || GETPOST('editcontent', 'alpha')) {
3977 $url = 'https://wiki.dolibarr.org/index.php/Module_Website';
3978
3979 $htmltext = '<small>';
3980 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource", $url);
3981 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceb", $url);
3982 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourcec", $url);
3983 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourced", $url);
3984 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource1", $url);
3985 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource2", $url);
3986 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource3", $url);
3987 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource4", $url);
3988 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceMore", $url);
3989 $htmltext .= '<br>';
3990 $htmltext .= '</small>';
3991 if ($conf->browser->layout == 'phone') {
3992 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
3993 } else {
3994 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
3995 print $form->textwithpicto($langs->trans("SyntaxHelp").' '.img_help(2, $langs->trans("SyntaxHelp")), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
3996 }
3997 }
3998 print '</span>'; // end websitehelp
3999
4000
4001 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') {
4002 // Adding jquery code to change on the fly url of preview ext
4003 if (!empty($conf->use_javascript_ajax)) {
4004 print '<script type="text/javascript">
4005 jQuery(document).ready(function() {
4006 jQuery("#websiteinputurl").keyup(function() {
4007 console.log("Website external url modified "+jQuery("#previewsiteurl").val());
4008 if (jQuery("#previewsiteurl").val() != "" && jQuery("#previewsiteurl").val().startsWith("http"))
4009 {
4010 jQuery("a.websitebuttonsitepreviewdisabled img").css({ opacity: 1 });
4011 }
4012 else jQuery("a.websitebuttonsitepreviewdisabled img").css({ opacity: 0.2 });
4013 ';
4014 print '
4015 });
4016 jQuery("#previewsiteext,#previewpageext").click(function() {
4017
4018 newurl=jQuery("#previewsiteurl").val();
4019 if (! newurl.startsWith("http"))
4020 {
4021 alert(\''.dol_escape_js($langs->trans("ErrorURLMustStartWithHttp")).'\');
4022 return false;
4023 }
4024
4025 newpage=jQuery("#previewsiteurl").val() + "/" + jQuery("#previewpageurl").val() + ".php";
4026 console.log("Open url "+newurl);
4027 /* Save url */
4028 jQuery.ajax({
4029 method: "POST",
4030 url: "'.DOL_URL_ROOT.'/core/ajax/saveinplace.php",
4031 data: {
4032 token: \''.currentToken().'\',
4033 field: \'editval_virtualhost\',
4034 element: \'website\',
4035 table_element: \'website\',
4036 fk_element: '.((int) $object->id).',
4037 value: newurl,
4038 },
4039 context: document.body
4040 });
4041
4042 jQuery("#previewsiteext").attr("href",newurl);
4043 jQuery("#previewpageext").attr("href",newpage);
4044 });
4045 });
4046 </script>';
4047 }
4048 }
4049 }
4050
4051 print '</div>'."\n"; // end current websitebar
4052}
4053
4054
4055$head = array();
4056
4057
4058/*
4059 * Edit Site HTML header and CSS
4060 */
4061
4062if ($action == 'editcss') {
4063 print '<div class="fiche">';
4064
4065 print '<br>';
4066
4067 if (!GETPOSTISSET('WEBSITE_CSS_INLINE')) {
4068 $csscontent = @file_get_contents($filecss);
4069 // Clean the php css file to remove php code and get only css part
4070 $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $csscontent);
4071 } else {
4072 $csscontent = GETPOST('WEBSITE_CSS_INLINE', 'none');
4073 }
4074 if (!trim($csscontent)) {
4075 $csscontent = '/* CSS content (all pages) */'."\nbody.bodywebsite { margin: 0; font-family: 'Open Sans', sans-serif; }\n.bodywebsite h1 { margin-top: 0; margin-bottom: 0; padding: 10px;}";
4076 }
4077
4078 if (!GETPOSTISSET('WEBSITE_JS_INLINE')) {
4079 $jscontent = @file_get_contents($filejs);
4080 // Clean the php js file to remove php code and get only js part
4081 $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $jscontent);
4082 } else {
4083 $jscontent = GETPOST('WEBSITE_JS_INLINE', 'none');
4084 }
4085 if (!trim($jscontent)) {
4086 $jscontent = '/* JS content (all pages) */'."\n";
4087 }
4088
4089 if (!GETPOSTISSET('WEBSITE_HTML_HEADER')) {
4090 $htmlheadercontent = @file_get_contents($filehtmlheader);
4091 // Clean the php htmlheader file to remove php code and get only html part
4092 $htmlheadercontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $htmlheadercontent);
4093 } else {
4094 $htmlheadercontent = GETPOST('WEBSITE_HTML_HEADER', 'none'); // Must accept tags like '<script>' and '<link>'
4095 }
4096 if (!trim($htmlheadercontent)) {
4097 $htmlheadercontent = "<html>\n";
4098 $htmlheadercontent .= $htmlheadercontentdefault;
4099 $htmlheadercontent .= "</html>";
4100 } else {
4101 $htmlheadercontent = preg_replace('/^\s*<html>/ims', '', $htmlheadercontent);
4102 $htmlheadercontent = preg_replace('/<\/html>\s*$/ims', '', $htmlheadercontent);
4103 $htmlheadercontent = '<html>'."\n".trim($htmlheadercontent)."\n".'</html>';
4104 }
4105
4106 if (!GETPOSTISSET('WEBSITE_ROBOT')) {
4107 $robotcontent = @file_get_contents($filerobot);
4108 // Clean the php htmlheader file to remove php code and get only html part
4109 $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $robotcontent);
4110 } else {
4111 $robotcontent = GETPOST('WEBSITE_ROBOT', 'nohtml');
4112 }
4113 if (!trim($robotcontent)) {
4114 $robotcontent .= "# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n";
4115 $robotcontent .= "User-agent: *\n";
4116 $robotcontent .= "Allow: /public/\n";
4117 $robotcontent .= "Disallow: /administrator/\n";
4118 }
4119
4120 if (!GETPOSTISSET('WEBSITE_HTACCESS')) {
4121 $htaccesscontent = @file_get_contents($filehtaccess);
4122 // Clean the php htaccesscontent file to remove php code and get only html part
4123 $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $htaccesscontent);
4124 } else {
4125 $htaccesscontent = GETPOST('WEBSITE_HTACCESS', 'nohtml'); // We must use 'nohtml' and not 'alphanohtml' because we must accept "
4126 }
4127
4128 if (!GETPOSTISSET('WEBSITE_MANIFEST_JSON')) {
4129 $manifestjsoncontent = @file_get_contents($filemanifestjson);
4130 // Clean the manifestjson file to remove php code and get only html part
4131 $manifestjsoncontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $manifestjsoncontent);
4132 } else {
4133 $manifestjsoncontent = trim(GETPOST('WEBSITE_MANIFEST_JSON', 'restricthtmlallowunvalid'));
4134 $manifestjsoncontent = str_replace('<?=', '<?php', $manifestjsoncontent);
4135 }
4136
4137 //if (!trim($manifestjsoncontent)) {
4138 //$manifestjsoncontent.="";
4139 //}
4140
4141 if (!GETPOSTISSET('WEBSITE_README')) {
4142 $readmecontent = @file_get_contents($filereadme);
4143 // Clean the readme file to remove php code and get only html part
4144 $readmecontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $readmecontent);
4145 } else {
4146 $readmecontent = GETPOST('WEBSITE_README', 'restricthtmlallowunvalid');
4147 }
4148 //if (!trim($readmecontent)) {
4149 //$readmecontent.="";
4150 //}
4151
4152 if (!GETPOSTISSET('WEBSITE_LICENSE')) {
4153 $licensecontent = @file_get_contents($filelicense);
4154 // Clean the readme file to remove php code and get only html part
4155 $licensecontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $licensecontent);
4156 } else {
4157 $licensecontent = GETPOST('WEBSITE_LICENSE', 'restricthtmlallowunvalid');
4158 }
4159 //if (!trim($licensecontent)) {
4160 //$readmecontent.="";
4161 //}
4162
4163 $head = websiteconfigPrepareHead($object);
4164 print dol_get_fiche_head($head, 'general', $langs->trans("General"), 0, 'website');
4165
4166 print '<!-- Edit Website properties (CSS, Language, ...) -->'."\n";
4167 print '<table class="border centpercent">';
4168
4169 // Website
4170 print '<tr><td class="titlefieldcreate fieldrequired">';
4171 print $langs->trans('WebSite');
4172 print '</td><td>';
4173 print $websitekey;
4174 print '</td></tr>';
4175
4176 // Status of web site
4177 if ($action != 'createcontainer') {
4178 if (empty($conf->use_javascript_ajax)) {
4179 print '<!-- Status of web site page -->'."\n";
4180 print '<tr><td class="fieldrequired">';
4181 print $langs->trans('Status');
4182 print '</td><td>';
4183 print $form->selectyesno('status', $object->status);
4184 print '</td></tr>';
4185 }
4186 }
4187
4188 // Main language
4189 print '<tr><td class="tdtop fieldrequired">';
4190 $htmltext = '';
4191 print $form->textwithpicto($langs->trans('MainLanguage'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_LANG');
4192 print '</td><td>';
4193 print img_picto('', 'language', 'class="pictofixedwidth"');
4194 print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : ($object->lang ? $object->lang : '0')), 'WEBSITE_LANG', 0, array(), 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1);
4195 print '</td>';
4196 print '</tr>';
4197
4198 // Other languages
4199 print '<tr><td class="tdtop">';
4200 $htmltext = $langs->trans("Example").': fr,de,sv,it,pt';
4201 print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2);
4202 print '</td><td>';
4203 print img_picto('', 'language', 'class="pictofixedwidth"');
4204 print '<input type="text" class="flat maxwidth200" value="'.(GETPOSTISSET('WEBSITE_OTHERLANG') ? GETPOST('WEBSITE_OTHERLANG', 'alpha') : $object->otherlang).'" name="WEBSITE_OTHERLANG">';
4205 print '</td>';
4206 print '</tr>';
4207
4208 // VirtualHost
4209 print '<tr><td class="tdtop">';
4210
4211 $htmltext = $langs->trans("VirtualhostDesc");
4212 print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'virtualhosttooltip');
4213 print '</td><td>';
4214 print '<input type="text" class="flat minwidth300" value="'.(GETPOSTISSET('virtualhost') ? GETPOST('virtualhost', 'alpha') : $virtualurl).'" name="virtualhost">';
4215 print '</td>';
4216 print '</tr>';
4217
4218 // Favicon
4219 print '<tr><td>';
4220 print $form->textwithpicto($langs->trans('ImportFavicon'), $langs->trans('FaviconTooltip'));
4221 print '</td><td>';
4222 $maxfilesizearray = getMaxFileSizeArray();
4223 $maxmin = $maxfilesizearray['maxmin'];
4224 if ($maxmin > 0) {
4225 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
4226 }
4227 print '<input type="file" class="flat minwidth300" name="addedfile" id="addedfile"/>';
4228
4229 $uploadfolder = $conf->website->dir_output.'/'.$websitekey;
4230 if (dol_is_file($uploadfolder.'/favicon.png')) {
4231 print '<div class="inline-block valignmiddle marginrightonly">';
4232 print '<img style="max-height: 80px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=website&file='.$websitekey.'/favicon.png">';
4233 print '</div>';
4234 }
4235 print '</tr></td>';
4236
4237 // CSS file
4238 print '<tr><td class="tdtop">';
4239 $htmlhelp = $langs->trans("CSSContentTooltipHelp");
4240 print $form->textwithpicto($langs->trans('WEBSITE_CSS_INLINE'), $htmlhelp, 1, 'help', '', 0, 2, 'csstooltip');
4241 print '</td><td>';
4242
4243 $poscursor = array('x' => GETPOST('WEBSITE_CSS_INLINE_x'), 'y' => GETPOST('WEBSITE_CSS_INLINE_y'));
4244 $doleditor = new DolEditor('WEBSITE_CSS_INLINE', $csscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4245 print $doleditor->Create(1, '', true, 'CSS', 'css');
4246
4247 print '</td></tr>';
4248
4249 // JS file
4250 print '<tr><td class="tdtop">';
4251 $textwithhelp = $langs->trans('WEBSITE_JS_INLINE');
4252 $htmlhelp2 = $langs->trans("LinkAndScriptsHereAreNotLoadedInEditor").'<br>';
4253 print $form->textwithpicto($textwithhelp, $htmlhelp2, 1, 'warning', '', 0, 2, 'htmljstooltip2');
4254
4255 print '</td><td>';
4256
4257 $poscursor = array('x' => GETPOST('WEBSITE_JS_INLINE_x'), 'y' => GETPOST('WEBSITE_JS_INLINE_y'));
4258 $doleditor = new DolEditor('WEBSITE_JS_INLINE', $jscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4259 print $doleditor->Create(1, '', true, 'JS', 'javascript');
4260
4261 print '</td></tr>';
4262
4263 // Common HTML header
4264 print '<tr><td class="tdtop">';
4265 print $langs->trans('WEBSITE_HTML_HEADER');
4266 $htmlhelp = $langs->trans("Example").' :<br>';
4267 $htmlhelp .= dol_nl2br(dol_htmlentities($htmlheadercontentdefault)); // do not use dol_htmlentitiesbr here, $htmlheadercontentdefault is HTML with content like <link> and <script> that we want to be html encode as they must be show as doc content not executable instruction.
4268 $textwithhelp = $form->textwithpicto('', $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
4269 $htmlhelp2 = $langs->trans("LinkAndScriptsHereAreNotLoadedInEditor").'<br>';
4270 print $form->textwithpicto($textwithhelp, $htmlhelp2, 1, 'warning', '', 0, 2, 'htmlheadertooltip2');
4271 print '</td><td>';
4272
4273 $poscursor = array('x' => GETPOST('WEBSITE_HTML_HEADER_x'), 'y' => GETPOST('WEBSITE_HTML_HEADER_y'));
4274 $doleditor = new DolEditor('WEBSITE_HTML_HEADER', $htmlheadercontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4275 print $doleditor->Create(1, '', true, 'HTML Header', 'html');
4276
4277 print '</td></tr>';
4278
4279 // Robot file
4280 print '<tr><td class="tdtop">';
4281 print $langs->trans('WEBSITE_ROBOT');
4282 print '</td><td>';
4283
4284 $poscursor = array('x' => GETPOST('WEBSITE_ROBOT_x'), 'y' => GETPOST('WEBSITE_ROBOT_y'));
4285 $doleditor = new DolEditor('WEBSITE_ROBOT', $robotcontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4286 print $doleditor->Create(1, '', true, 'Robot file', 'text');
4287
4288 print '</td></tr>';
4289
4290 // .htaccess
4291 print '<tr><td class="tdtop">';
4292
4293 $textwithhelp3 = $langs->trans("Example").' :';
4294 $textwithhelp3 .= "<br># Order allow,deny\n";
4295 $textwithhelp3 .= "<br># Deny from all\n";
4296 $textwithhelp3 .= "<br># Require all granted\n";
4297
4298 print $form->textwithpicto($langs->trans('WEBSITE_HTACCESS'), $textwithhelp3, 1, 'help', '', 0, 2, 'htmlheadertooltip3');
4299 print '</td><td>';
4300
4301 $poscursor = array('x' => GETPOST('WEBSITE_HTACCESS_x'), 'y' => GETPOST('WEBSITE_HTACCESS_y'));
4302 $doleditor = new DolEditor('WEBSITE_HTACCESS', $htaccesscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4303 print $doleditor->Create(1, '', true, $langs->trans("File").' .htaccess', 'text');
4304
4305 print '</td></tr>';
4306
4307 // Manifest.json
4308 print '<tr><td class="tdtop">';
4309 $htmlhelp = $langs->trans("Example").' :<br>';
4310 $htmlhelp .= '<small>'.dol_htmlentitiesbr($manifestjsoncontentdefault).'</small>';
4311 print $form->textwithpicto($langs->trans('WEBSITE_MANIFEST_JSON'), $htmlhelp, 1, 'help', '', 0, 2, 'manifestjsontooltip');
4312 print '</td><td>';
4313 print $langs->trans("UseManifest").': '.$form->selectyesno('use_manifest', $website->use_manifest, 1).'<br>';
4314
4315 $poscursor = array('x' => GETPOST('WEBSITE_MANIFEST_JSON_x'), 'y' => GETPOST('WEBSITE_MANIFEST_JSON_y'));
4316 $doleditor = new DolEditor('WEBSITE_MANIFEST_JSON', $manifestjsoncontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4317 print $doleditor->Create(1, '', true, $langs->trans("File").' manifest.json', 'text');
4318 print '</td></tr>';
4319
4320 // README.md
4321 print '<tr><td class="tdtop">';
4322 $htmlhelp = $langs->trans("EnterHereReadmeInformation");
4323 print $form->textwithpicto($langs->trans("File").' README.md', $htmlhelp, 1, 'help', '', 0, 2, 'readmetooltip');
4324 print '</td><td>';
4325
4326 $poscursor = array('x' => GETPOST('WEBSITE_README_x'), 'y' => GETPOST('WEBSITE_README_y'));
4327 $doleditor = new DolEditor('WEBSITE_README', $readmecontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4328 print $doleditor->Create(1, '', true, $langs->trans("File").' README.md', 'text');
4329
4330 print '</td></tr>';
4331
4332 // LICENSE
4333 print '<tr><td class="tdtop">';
4334 $htmlhelp = $langs->trans("EnterHereLicenseInformation");
4335 print $form->textwithpicto($langs->trans("File").' LICENSE', $htmlhelp, 1, 'help', '', 0, 2, 'licensetooltip');
4336 print '</td><td>';
4337
4338 $poscursor = array('x' => GETPOST('WEBSITE_LICENSE_x'), 'y' => GETPOST('WEBSITE_LICENSE_y'));
4339 $doleditor = new DolEditor('WEBSITE_LICENSE', $licensecontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4340 print $doleditor->Create(1, '', true, $langs->trans("File").' LICENSE', 'text');
4341
4342 print '</td></tr>';
4343
4344 // RSS
4345 print '<tr><td class="tdtop">';
4346 $htmlhelp = $langs->trans('RSSFeedDesc');
4347 print $form->textwithpicto($langs->trans('RSSFeed'), $htmlhelp, 1, 'help', '', 0, 2, '');
4348 print '</td><td>';
4349 print '/wrapper.php?rss=1[&l=XX][&limit=99][&cachedelay=99]';
4350 print '</td></tr>';
4351
4352 print '</table>';
4353
4354 print dol_get_fiche_end();
4355
4356 print '</div>';
4357
4358 print '<br>';
4359}
4360
4361if ($action == 'editsecurity') {
4362 $selectarrayCSPDirectives = websiteGetContentPolicyDirectives();
4363 $selectarrayCSPSources = websiteGetContentPolicySources();
4364 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
4365 print '<div class="fiche">';
4366 print '<br>';
4367
4368 $head = websiteconfigPrepareHead($object);
4369 print dol_get_fiche_head($head, 'security', $langs->trans("General"), -1, 'website');
4370
4371 print '<span class="opacitymedium">'.$langs->trans("HTTPHeaderEditor").'. '.$langs->trans("ReservedToAdvancedUsers").'.</span><br><br>';
4372
4373 print '<div class="div-table-responsive-no-min">';
4374 print '<table class="noborder centpercent">';
4375 print '<tr class="liste_titre">';
4376 print '<td>'.$langs->trans("HTTPHeader").'</td>';
4377 print '<td></td>'."\n";
4378 print '</tr>';
4379
4380 // Force RP
4381 print '<tr class="oddeven">';
4382 print '<td>'.$form->textwithpicto($langs->trans('WebsiteSecurityForceRP'), 'HTTP Header Referer-Policy<br><br>'.$langs->trans("Recommended").':<br>strict-origin-when-cross-origin <span class="opacitymedium">'.$langs->trans("or").'</span> same-origin"=more secured', 1, 'help', 'valignmiddle', 0, 3, 'WEBSITE_'.$object->id.'_SECURITY_FORCERP').'</td>';
4383 print '<td><input class="minwidth500" name="WEBSITE_'.$object->id.'_SECURITY_FORCERP" id="WEBSITE_'.$object->id.'_SECURITY_FORCERP" value="'.getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCERP").'"></td>';
4384 print '</tr>';
4385 // Force STS
4386 print '<tr class="oddeven">';
4387 print '<td>'.$form->textwithpicto($langs->trans('WebsiteSecurityForceSTS'), 'HTTP Header Strict-Transport-Security<br><br>'.$langs->trans("Example").':<br>max-age=31536000; includeSubDomains', 1, 'help', 'valignmiddle', 0, 3, 'WEBSITE_'.$object->id.'_SECURITY_FORCESTS').'</td>';
4388 print '<td><input class="minwidth500" name="WEBSITE_'.$object->id.'_SECURITY_FORCESTS" id="WEBSITE_'.$object->id.'_SECURITY_FORCESTS" value="'.getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCESTS").'"></td>';
4389 print '</tr>';
4390 // Force PP
4391 print '<tr class="oddeven">';
4392 print '<td>'.$form->textwithpicto($langs->trans('WebsiteSecurityForcePP'), 'HTTP Header Permissions-Policy<br><br>'.$langs->trans("Example").':<br>camera=*, microphone=(), geolocation=*', 1, 'help', 'valignmiddle', 0, 3, 'WEBSITE_'.$object->id.'_SECURITY_FORCEPP').'</td>';
4393 print '<td><input class="minwidth500" name="WEBSITE_'.$object->id.'_SECURITY_FORCEPP" id="WEBSITE_'.$object->id.'_SECURITY_FORCEPP" value="'.getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCEPP").'"></td>';
4394 print '</tr>';
4395
4396 $examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
4397
4398 // Force CSP - Content Security Policy
4399 print '<tr class="oddeven nohover">';
4400 print '<td class="tdtop">'.$form->textwithpicto($langs->trans('ContentSecurityPolicy'), 'HTTP Header Content-Security-Policy<br><br>'.$langs->trans("Example").":<br>".$examplecsprule, 1, 'help', 'valignmiddle', 0, 3, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP').'</td>';
4401 print '<td>';
4402
4403 print '<div class="div-table-responsive-no-min">';
4404
4405 print '<input class="minwidth500 quatrevingtpercent" name="WEBSITE_'.$object->id.'_SECURITY_FORCECSP" id="WEBSITE_'.$object->id.'_SECURITY_FORCECSP" value="'.$forceCSP.'"> <a href="#" id="btnaddcontentsecuritypolicy">'.img_picto('', 'add').'</a><br>';
4406
4407 print '<br class="selectaddcontentsecuritypolicy hidden">';
4408
4409 print '<div id="selectaddcontentsecuritypolicy" class="hidden selectaddcontentsecuritypolicy">';
4410 print $form->selectarray("select_identifier_WEBSITE_SECURITY_FORCECSP", $selectarrayCSPDirectives, "select_identifier_WEBSITE_SECURITY_FORCECSP", $langs->trans("FillCSPDirective"), 0, 0, '', 0, 0, 0, '', 'minwidth200 maxwidth350 inline-block');
4411 print ' ';
4412 print '<input type="hidden" id="select_source_WEBSITE_SECURITY_FORCECSP" name="select_source_WEBSITE_SECURITY_FORCECSP">';
4413 foreach ($selectarrayCSPSources as $key => $values) {
4414 print '<div class="div_WEBSITE_SECURITY_FORCECSP hidden inline-block maxwidth350" id="div_'.$key.'_WEBSITE_SECURITY_FORCECSP">';
4415 print $form->selectarray("select_".$key."_WEBSITE_SECURITY_FORCECSP", $values, "select_".$key."_WEBSITE_SECURITY_FORCECSP", $langs->trans("FillCSPSource"), 0, 0, '', 0, 0, 0, '', 'minwidth200 maxwidth300 inline-block select_WEBSITE_SECURITY_FORCECSP');
4416 print '</div>';
4417 }
4418 print ' ';
4419 print '<div class="div_input_data_WEBSITE_SECURITY_FORCECSP hidden inline-block maxwidth200"><input id="input_data_WEBSITE_SECURITY_FORCECSP" name="input_data_WEBSITE_SECURITY_FORCECSP"></div>';
4420 print ' ';
4421 print '<div class="div_btn_class_WEBSITE_SECURITY_FORCECSP inline-block maxwidth200"><input type="submit" id="btn_WEBSITE_SECURITY_FORCECSP" name="btn_WEBSITE_SECURITY_FORCECSP" class="butAction small smallpaddingimp" value="'.$langs->trans("Add").'" disabled></div>';
4422 print '<br><br>';
4423 print '</div>';
4424
4425 if (!empty($forceCSP)) {
4426 // Content Security Policy list of selected rules
4427 print '<br>';
4428 print '<div class="div-table-responsive-no-min">';
4429 print img_picto('', 'graph', 'class="pictofixedwidth"').$langs->trans("HierarchicView").'<br>';
4430 print '<ul>';
4431 foreach ($forceCSPArr as $directive => $sources) {
4432 print '<li>';
4433 if (in_array($directive, array_keys($selectarrayCSPDirectives))) {
4434 print '<span>'.$directive.'</span>';
4435 } else {
4436 print $form->textwithpicto($directive, $langs->trans("UnknowContentSecurityPolicyDirective"), 1, 'warning');
4437 }
4438 if (!empty($sources)) {
4439 print '<ul>';
4440 foreach ($sources as $key => $source) {
4441 print '<li><span>'.$source.'</span>&nbsp;<a href="'.$_SERVER["PHP_SELF"].'?websiteid='.$websiteid.'&action=removecspsource&sourcecsp='.$directive.'_'.$key.'&token='.newToken().'">'.img_delete().'</a></li>';
4442 }
4443 print '</ul>';
4444 } else {
4445 print '&nbsp;<a href="'.$_SERVER["PHP_SELF"].'?websiteid='.$websiteid.'&action=removecspsource&sourcecsp='.$directive.'&token='.newToken().'">'.img_delete().'</a>';
4446 }
4447 print '</li>';
4448 }
4449 print '</ul>';
4450 print '</div>';
4451 }
4452 print '</div>';
4453
4454 print '</td>';
4455 print '</tr>';
4456
4457 // Force CSPRO
4458 if (getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSPRO")) {
4459 print '<tr class="oddeven">';
4460 print '<td>'.$form->textwithpicto($langs->trans('WebsiteSecurityForceCSPRO'), 'HTTP Header Content-Security-Policy-Report-Only<br><br>'.$langs->trans("Example").":<br>".$examplecsprule, 1, 'help', 'valignmiddle', 0, 3, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO').'</td>';
4461 print '<td><input class="minwidth500" name="WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO" id="WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO" value="'.getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSPRO").'"></td>';
4462 print '</tr>';
4463 }
4464
4465 print '</table>';
4466 print '</div>';
4467
4468
4469 print '<div class="center">';
4470
4471 print '<input type="submit" class="button small" name="updateandstay" value="'.$langs->trans("Save").'">';
4472 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
4473
4474 print '</div>';
4475
4476
4477 print '<script>
4478 $(document).ready(function() {
4479 $("#btnaddcontentsecuritypolicy").on("click", function(){
4480 if($("#selectaddcontentsecuritypolicy").is(":visible")){
4481 console.log("We hide select to add Content Security Policy");
4482 $(".selectaddcontentsecuritypolicy").hide();
4483 } else {
4484 console.log("We show select to add Content Security Policy");
4485 $(".selectaddcontentsecuritypolicy").show();
4486 }
4487 });
4488
4489 $("#select_identifier_WEBSITE_SECURITY_FORCECSP").on("change", function() {
4490 key = $(this).find(":selected").data("directivetype");
4491 console.log("We hide all select div");
4492 $(".div_WEBSITE_SECURITY_FORCECSP").hide();
4493 $(".select_WEBSITE_SECURITY_FORCECSP").val(null).trigger("change");
4494 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").hide();
4495 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4496 if (key == "none"){
4497 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4498 } else {
4499 console.log("We show div select with key "+key);
4500 $("#div_"+key+"_WEBSITE_SECURITY_FORCECSP").css("display", "inline-block");
4501 }
4502 });
4503
4504 $(".select_WEBSITE_SECURITY_FORCECSP").on("change", function() {
4505 keysource = $(this).find(":selected").data("sourcetype");
4506 $("#select_source_WEBSITE_SECURITY_FORCECSP").val($(this).val());
4507 console.log("We hide and show fields");
4508 if (keysource == "data" || keysource == "input") {
4509 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").css("display", "inline-block");
4510 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4511 } else {
4512 $("#input_data_WEBSITE_SECURITY_FORCECSP").val("");
4513 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").hide();
4514 if (keysource != undefined) {
4515 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4516 } else {
4517 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4518 }
4519 }
4520 });
4521
4522 $("#input_data_WEBSITE_SECURITY_FORCECSP").on("change keyup", function(){
4523 if ($(this).val() != "") {
4524 console.log("We show add button");
4525 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4526 } else {
4527 console.log("We hide add button");
4528 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4529 }
4530 });
4531 });
4532 </script>';
4533
4534 print dol_get_fiche_end();
4535 print '</div>';
4536}
4537
4538
4539if ($action == 'createsite') {
4540 print '<div class="fiche">';
4541
4542 print '<br>';
4543
4544 /*$h = 0;
4545 $head = array();
4546
4547 $head[$h][0] = dol_buildpath('/website/index.php',1).'?id='.$object->id;
4548 $head[$h][1] = $langs->trans("AddWebsite");
4549 $head[$h][2] = 'card';
4550 $h++;
4551
4552 print dol_get_fiche_head($head, 'card', '', -1, 'website');
4553 */
4554 if ($action == 'createcontainer') {
4555 print load_fiche_titre($langs->trans("AddWebsite"));
4556 }
4557
4558 print '<!-- Add site -->'."\n";
4559 print '<div class="tabBar tabBarWithBottom">';
4560
4561 print '<table class="border centpercent">';
4562
4563 $siteref = $sitedesc = $sitelang = $siteotherlang = '';
4564 if (GETPOST('WEBSITE_REF')) {
4565 $siteref = GETPOST('WEBSITE_REF', 'aZ09');
4566 }
4567 if (GETPOST('WEBSITE_DESCRIPTION')) {
4568 $sitedesc = GETPOST('WEBSITE_DESCRIPTION', 'alpha');
4569 }
4570 if (GETPOST('WEBSITE_LANG')) {
4571 $sitelang = GETPOST('WEBSITE_LANG', 'aZ09');
4572 }
4573 if (GETPOST('WEBSITE_OTHERLANG')) {
4574 $siteotherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
4575 }
4576
4577 print '<tr><td class="titlefieldcreate fieldrequired">';
4578 print $form->textwithpicto($langs->trans('WebsiteName'), $langs->trans("Example").': MyPortal, www.mywebsite.com, ...');
4579 print '</td><td>';
4580 print '<input type="text" class="flat maxwidth300" name="WEBSITE_REF" value="'.dol_escape_htmltag($siteref).'" autofocus>';
4581 print '</td></tr>';
4582
4583 print '<tr><td class="fieldrequired">';
4584 print $langs->trans('MainLanguage');
4585 print '</td><td>';
4586 $shortlangcode = preg_replace('/[_-].*$/', '', trim($langs->defaultlang));
4587 print img_picto('', 'language', 'class="pictofixedwidth"');
4588 print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : $shortlangcode), 'WEBSITE_LANG', 0, array(), 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1);
4589 print '</td></tr>';
4590
4591 print '<tr><td>';
4592 $htmltext = $langs->trans("Example").': fr,de,sv,it,pt';
4593 print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2);
4594 print '</td><td>';
4595 print img_picto('', 'language', 'class="pictofixedwidth"');
4596 print '<input type="text" class="flat minwidth300" name="WEBSITE_OTHERLANG" value="'.dol_escape_htmltag($siteotherlang).'">';
4597 print '</td></tr>';
4598
4599 print '<tr><td>';
4600 print $langs->trans('Description');
4601 print '</td><td>';
4602 print '<input type="text" class="flat minwidth500" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">';
4603 print '</td></tr>';
4604
4605 print '<tr><td>';
4606
4607 $htmltext = $langs->trans("VirtualhostDesc");
4608 /*$htmltext = str_replace('{s1}', DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/<i>websiteref</i>', $htmltext);
4609 $htmltext .= '<br>';
4610 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
4611 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
4612 $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias', $htmltext);*/
4613
4614
4615 print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, '');
4616 print '</td><td>';
4617 print '<input type="text" class="flat minwidth300" name="virtualhost" value="'.dol_escape_htmltag(GETPOST('virtualhost', 'alpha')).'">';
4618 print '</td></tr>';
4619
4620 print '</table>';
4621 print '</div>';
4622
4623 if ($action == 'createsite') {
4624 print '<div class="center">';
4625
4626 print '<input type="submit" class="button small" name="addcontainer" value="'.$langs->trans("Create").'">';
4627 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
4628
4629 print '</div>';
4630 }
4631
4632
4633 //print '</div>';
4634
4635 //print dol_get_fiche_end();
4636
4637 print '</div>';
4638
4639 print '<br>';
4640}
4641
4642// Page view to import a website template
4643if ($action == 'importsite') {
4644 print '<!-- action=importsite -->';
4645 print '<div class="fiche">';
4646
4647 print '<br>';
4648
4649 print load_fiche_titre($langs->trans("ImportSite"));
4650
4651 print dol_get_fiche_head(array(), '0', '', -1);
4652
4653 print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToImport").'</span><br><br>';
4654
4655
4656 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
4657 $allowimportsite = true;
4658 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
4659 $allowimportsite = false;
4660 }
4661
4662 if ($allowimportsite) {
4663 $maxfilesizearray = getMaxFileSizeArray();
4664 $maxmin = $maxfilesizearray['maxmin'];
4665 if ($maxmin > 0) {
4666 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
4667 }
4668 print '<input class="flat minwidth400" type="file" name="userfile[]" accept=".zip">';
4669 print '<input type="submit" class="button small" name="buttonsubmitimportfile" value="'.dol_escape_htmltag($langs->trans("Upload")).'">';
4670 print '<input type="submit" class="button button-cancel small" name="preview" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4671 print '<br><br><br>';
4672 } else {
4673 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
4674 // Show clean corporate message
4675 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
4676 } else {
4677 // Show technical generic message
4678 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
4679 }
4680 print info_admin($message).'<br><br>';
4681 }
4682
4683
4684 print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToLoad").'</span><br><br>';
4685
4686 // This will scan the dir /doctemplates/websites and show all templates.
4687 showWebsiteTemplates($website, GETPOSTINT('importsite') == 2 ? 1 : 0);
4688
4689 print dol_get_fiche_end();
4690
4691 print '</div>';
4692
4693 print '<br>';
4694}
4695
4696if ($action == 'editmeta' || $action == 'createcontainer') { // Edit properties of a web site OR properties of a web page
4697 print '<div class="fiche">';
4698
4699 print '<br>';
4700
4701 /*$h = 0;
4702 $head = array();
4703
4704 $head[$h][0] = dol_buildpath('/website/index.php',1).'?id='.$object->id;
4705 $head[$h][1] = $langs->trans("AddPage");
4706 $head[$h][2] = 'card';
4707 $h++;
4708
4709 print dol_get_fiche_head($head, 'card', '', -1, 'website');
4710 */
4711 if ($action == 'createcontainer') {
4712 print load_fiche_titre($langs->trans("AddPage"));
4713 }
4714
4715 print '<!-- Edit or create page/container -->'."\n";
4716 //print '<div class="fichecenter">';
4717
4718 $hiddenfromfetchingafterload = ' hideobject';
4719 $hiddenmanuallyafterload = ' hideobject';
4720 if (GETPOST('radiocreatefrom') == 'checkboxcreatefromfetching') {
4721 $hiddenfromfetchingafterload = '';
4722 }
4723 if (GETPOST('radiocreatefrom') == 'checkboxcreatemanually') {
4724 $hiddenmanuallyafterload = '';
4725 }
4726
4727 if ($action == 'editmeta' || empty($conf->use_javascript_ajax)) { // No autohide/show in such case
4728 $hiddenfromfetchingafterload = '';
4729 $hiddenmanuallyafterload = '';
4730 }
4731
4732 if ($action == 'createcontainer') {
4733 print '<br>';
4734
4735 if (!empty($conf->use_javascript_ajax)) {
4736 print '<input type="radio" name="radiocreatefrom" id="checkboxcreatemanually" value="checkboxcreatemanually"'.(GETPOST('radiocreatefrom') == 'checkboxcreatemanually' ? ' checked' : '').'> ';
4737 }
4738 print '<label for="checkboxcreatemanually"><span class="opacitymediumxx">'.$langs->trans("OrEnterPageInfoManually").'</span></label><br>';
4739 print '<hr class="tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
4740 }
4741
4742
4743
4744 print '<table class="border tableforfield nobackground centpercent tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
4745
4746 if ($action != 'createcontainer') {
4747 print '<tr><td class="titlefield fieldrequired">';
4748 print $langs->trans('IDOfPage').' - '.$langs->trans('InternalURLOfPage');
4749 print '</td><td>';
4750 print $pageid;
4751 //print '</td></tr>';
4752
4753 //print '<tr><td class="titlefield fieldrequired">';
4754 //print $langs->trans('InternalURLOfPage');
4755 //print '</td><td>';
4756 print ' &nbsp; - &nbsp; ';
4757 print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode((string) $pageid);
4758 //if ($objectpage->grabbed_from) print ' - <span class="opacitymedium">'.$langs->trans('InitiallyGrabbedFrom').' '.$objectpage->grabbed_from.'</span>';
4759 print '</td></tr>';
4760
4761 $type_container = $objectpage->type_container;
4762 $pageurl = $objectpage->pageurl;
4763 $pagealiasalt = $objectpage->aliasalt;
4764 $pagetitle = $objectpage->title;
4765 $pagedescription = $objectpage->description;
4766 $pageimage = $objectpage->image;
4767 $pagekeywords = $objectpage->keywords;
4768 $pagelang = $objectpage->lang;
4769 $pageallowedinframes = $objectpage->allowed_in_frames;
4770 $pagehtmlheader = $objectpage->htmlheader;
4771 $pagedatecreation = (string) $objectpage->date_creation;
4772 $pagedatemodification = $objectpage->date_modification;
4773 $pageauthorid = $objectpage->fk_user_creat;
4774 $pageusermodifid = $objectpage->fk_user_modif;
4775 $pageauthoralias = $objectpage->author_alias;
4776 $pagestatus = $objectpage->status;
4777 } else { // $action = 'createcontainer'
4778 $type_container = 'page';
4779 $pageurl = '';
4780 $pagealiasalt = '';
4781 $pagetitle = '';
4782 $pagedescription = '';
4783 $pageimage = '';
4784 $pagekeywords = '';
4785 $pagelang = '';
4786 $pageallowedinframes = 0;
4787 $pagehtmlheader = '';
4788 $pagedatecreation = dol_now();
4789 $pagedatemodification = '';
4790 $pageauthorid = $user->id;
4791 $pageusermodifid = 0;
4792 $pageauthoralias = '';
4793 $pagestatus = 1;
4794 }
4795 if (GETPOST('WEBSITE_TITLE', 'alpha')) {
4796 $pagetitle = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
4797 }
4798 if (GETPOST('WEBSITE_PAGENAME', 'alpha')) {
4799 $pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha');
4800 }
4801 if (GETPOST('WEBSITE_ALIASALT', 'alpha')) {
4802 $pagealiasalt = str_replace(array('<', '>'), '', GETPOST('WEBSITE_ALIASALT', 'alphanohtml'));
4803 }
4804 if (GETPOST('WEBSITE_DESCRIPTION', 'alpha')) {
4805 $pagedescription = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
4806 }
4807 if (GETPOST('WEBSITE_IMAGE', 'alpha')) {
4808 $pageimage = GETPOST('WEBSITE_IMAGE', 'alpha');
4809 }
4810 if (GETPOST('WEBSITE_KEYWORDS', 'alpha')) {
4811 $pagekeywords = str_replace(array('<', '>'), '', GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'));
4812 }
4813 if (GETPOST('WEBSITE_LANG', 'aZ09')) {
4814 $pagelang = GETPOST('WEBSITE_LANG', 'aZ09');
4815 }
4816 if (GETPOST('WEBSITE_ALLOWED_IN_FRAMES', 'aZ09')) {
4817 $pageallowedinframes = 1;
4818 }
4819 if (GETPOST('htmlheader', 'restricthtmlallowlinkscript')) { // Must accept tags like '<script>' and '<link>'
4820 $pagehtmlheader = GETPOST('htmlheader', 'restricthtmlallowlinkscript');
4821 }
4822
4823 if ($action != 'createcontainer') {
4824 if (empty($conf->use_javascript_ajax)) {
4825 print '<!-- Status of web site page -->'."\n";
4826 print '<tr><td class="fieldrequired">';
4827 print $langs->trans('Status');
4828 print '</td><td>';
4829 print $form->selectyesno('status', $objectpage->status);
4830 print '</td></tr>';
4831 }
4832 }
4833
4834 // Type of container
4835 print '<tr><td class="titlefield fieldrequired">';
4836 print $langs->trans('WEBSITE_TYPE_CONTAINER');
4837 print '</td><td>';
4838 print img_picto('', 'object_technic', 'class="paddingrightonly"').' ';
4839 print $formwebsite->selectTypeOfContainer('WEBSITE_TYPE_CONTAINER', (GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha') ? GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha') : $type_container), 0, '', 1, 'minwidth300');
4840 print '</td></tr>';
4841
4842 print '<script type="text/javascript">
4843 jQuery(document).ready(function() {
4844 jQuery("#selectWEBSITE_TYPE_CONTAINER").change(function() {
4845 console.log("We change type of page : "+jQuery("#selectWEBSITE_TYPE_CONTAINER").val());
4846 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'blogpost\') {
4847 jQuery(".trpublicauthor").show();
4848 } else {
4849 jQuery(".trpublicauthor").hide();
4850 }
4851 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'service\' || jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'library\') {
4852 $(".spanprefix").html("_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_");
4853 jQuery(".spanprefix").show();
4854 } else {
4855 jQuery(".spanprefix").hide();
4856 }
4857 });
4858
4859 // Force at init execution a first time of the handler change
4860 jQuery("#selectWEBSITE_TYPE_CONTAINER").trigger(\'change\');
4861 });
4862 </script>
4863 ';
4864
4865 // Title
4866 print '<tr><td class="fieldrequired">';
4867 print $langs->trans('WEBSITE_TITLE');
4868 print '</td><td>';
4869 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_TITLE" id="WEBSITE_TITLE" value="'.dol_escape_htmltag($pagetitle).'" autofocus>';
4870 print '</td></tr>';
4871
4872 // Alias page
4873 print '<tr><td class="titlefieldcreate fieldrequired">';
4874 print $langs->trans('WEBSITE_PAGENAME');
4875 print '</td><td>';
4876 print '<span class="opacitymedium spanprefix hidden"></span> ';
4877 print '<input type="text" class="flat minwidth300" name="WEBSITE_PAGENAME" id="WEBSITE_PAGENAME" value="'.dol_escape_htmltag((string) preg_replace('/^_[a-z]+_/', '', (string) $pageurl)).'">';
4878 print '</td></tr>';
4879
4880 print '<script type="text/javascript">
4881 $(document).ready(function() {
4882 console.log("Manage prefix for service or library");
4883 if ($("#selectWEBSITE_TYPE_CONTAINER").val() == "service" || $("#selectWEBSITE_TYPE_CONTAINER").val() == "library") {
4884 $(".spanprefix").html("_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_");
4885 $(".spanprefix").show();
4886 }
4887 $(".websiteformtoolbar").on("submit", function(event) {
4888 if ($("#selectWEBSITE_TYPE_CONTAINER").val() == "service" || $("#selectWEBSITE_TYPE_CONTAINER").val() == "library") {
4889 var prefix = "_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_";
4890 var userInput = $("#WEBSITE_PAGENAME").val();
4891 var $inputField = $("#WEBSITE_PAGENAME");
4892 if (userInput.indexOf(prefix) !== 0) {
4893 $inputField.val(prefix + userInput);
4894 }
4895 }
4896 });
4897 });
4898 </script>
4899 ';
4900
4901 print '<tr><td class="titlefieldcreate">';
4902 $htmlhelp = $langs->trans("WEBSITE_ALIASALTDesc");
4903 print $form->textwithpicto($langs->trans('WEBSITE_ALIASALT'), $htmlhelp, 1, 'help', '', 0, 2, 'aliastooltip');
4904 print '</td><td>';
4905 print '<input type="text" class="flat minwidth500" name="WEBSITE_ALIASALT" value="'.dol_escape_htmltag($pagealiasalt).'">';
4906 print '</td></tr>';
4907
4908 print '<tr><td>';
4909 print $langs->trans('WEBSITE_DESCRIPTION');
4910 print '</td><td>';
4911 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($pagedescription).'">';
4912 print '</td></tr>';
4913
4914 // Deprecated. Image for RSS or Thumbs are now taken from the content.
4915 if (getDolGlobalInt('WEBSITE_MANAGE_IMAGE_FOR_PAGES')) {
4916 print '<tr class="trimageforpage hidden"><td>';
4917 $htmlhelp = $langs->trans("WEBSITE_IMAGEDesc");
4918 print $form->textwithpicto($langs->trans('WEBSITE_IMAGE'), $htmlhelp, 1, 'help', '', 0, 2, 'imagetooltip');
4919 print '</td><td>';
4920 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_IMAGE" value="'.dol_escape_htmltag($pageimage).'">';
4921 print '</td></tr>';
4922
4923 print '<script type="text/javascript">
4924 jQuery(document).ready(function() {
4925 jQuery("#selectWEBSITE_TYPE_CONTAINER").change(function() {
4926 console.log("We change type of page : "+jQuery("#selectWEBSITE_TYPE_CONTAINER").val());
4927 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'blogpost\') {
4928 jQuery(".trimageforpage").show();
4929 } else {
4930 jQuery(".trimageforpage").hide();
4931 }
4932 });
4933 });
4934 </script>
4935 ';
4936 }
4937
4938 // Keywords
4939 print '<tr><td>';
4940 $htmlhelp = $langs->trans("WEBSITE_KEYWORDSDesc");
4941 print $form->textwithpicto($langs->trans('WEBSITE_KEYWORDS'), $htmlhelp, 1, 'help', '', 0, 2, 'keywordtooltip');
4942 print '</td><td>';
4943 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($pagekeywords).'">';
4944 print '</td></tr>';
4945
4946 print '<tr><td>';
4947 print $langs->trans('Language');
4948 print '</td><td>';
4949 $onlykeys = array();
4950 if ($object->lang) {
4951 $onlykeys[$object->lang] = $object->lang;
4952 } else {
4953 $onlykeys[$langs->defaultlang] = $langs->defaultlang;
4954 }
4955 if ($object->otherlang) {
4956 $tmparray = explode(',', $object->otherlang);
4957 foreach ($tmparray as $key) {
4958 $tmpkey = trim($key);
4959 if (strlen($key) == 2) {
4960 $tmpkey = strtolower($key);
4961 }
4962 $onlykeys[$tmpkey] = $tmpkey;
4963 }
4964 }
4965 if (empty($object->lang) && empty($object->otherlang)) {
4966 $onlykeys = array(); // We keep full list of languages
4967 }
4968 print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language($pagelang ? $pagelang : '', 'WEBSITE_LANG', 0, array(), '1', 0, 0, 'minwidth200', 0, 0, 0, $onlykeys, 1);
4969 $htmltext = $langs->trans("AvailableLanguagesAreDefinedIntoWebsiteProperties");
4970 print $form->textwithpicto('', $htmltext);
4971 print '</td></tr>';
4972
4973 // Translation of
4974 $translationof = 0;
4975 $translatedby = 0;
4976 print '<!-- Translation of --><tr><td>';
4977 print $langs->trans('TranslationLinks');
4978 print '</td><td>';
4979 if ($action != 'createcontainer') {
4980 // Has translation pages
4981 $sql = "SELECT rowid, lang from ".MAIN_DB_PREFIX."website_page where fk_page = ".((int) $objectpage->id);
4982 $resql = $db->query($sql);
4983 if ($resql) {
4984 $num_rows = $db->num_rows($resql);
4985 if ($num_rows > 0) {
4986 print '<span class="opacitymedium">'.$langs->trans('ThisPageHasTranslationPages').':</span>';
4987 $i = 0;
4988 $tmppage = new WebsitePage($db);
4989 $tmpstring = '';
4990 while ($obj = $db->fetch_object($resql)) {
4991 $result = $tmppage->fetch($obj->rowid);
4992 if ($result > 0) {
4993 if ($i > 0) {
4994 $tmpstring .= '<br>';
4995 }
4996 $tmpstring .= $tmppage->getNomUrl(1).' '.picto_from_langcode($tmppage->lang).' '.$tmppage->lang;
4997 // Button unlink
4998 $tmpstring .= ' <a class="paddingleft" href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($object->ref).'&pageid='.((int) $objectpage->id).'&action=deletelang&token='.newToken().'&deletelangforid='.((int) $tmppage->id).'">'.img_picto($langs->trans("Remove"), 'unlink').'</a>';
4999 $translatedby++;
5000 $i++;
5001 }
5002 }
5003 if ($i > 1) {
5004 print '<br>';
5005 } else {
5006 print ' ';
5007 }
5008 print $tmpstring;
5009 }
5010 } else {
5012 }
5013 }
5014 if ((empty($translatedby) || ($objectpage->lang != $object->lang)) && ($action == 'editmeta' || $action == 'createcontainer' || $objectpage->fk_page > 0)) {
5015 $sourcepage = new WebsitePage($db);
5016 $result = 1;
5017 if ($objectpage->fk_page > 0) {
5018 $result = $sourcepage->fetch($objectpage->fk_page);
5019 if ($result == 0) {
5020 // not found, we can reset value to clean database
5021 // TODO
5022 }
5023 }
5024 if ($result >= 0) {
5025 if ($translatedby) {
5026 print '<br>';
5027 }
5028 $translationof = $objectpage->fk_page;
5029 print '<span class="opacitymedium">'.$langs->trans('ThisPageIsTranslationOf').'</span> ';
5030 print $sourcepage->getNomUrl(2).' '.$formwebsite->selectContainer($website, 'pageidfortranslation', ($translationof ? $translationof : -1), 1, $action, 'minwidth300', array($objectpage->id));
5031 if ($translationof > 0 && $sourcepage->lang) {
5032 print picto_from_langcode($sourcepage->lang).' '.$sourcepage->lang;
5033 // Button unlink
5034 print ' <a class="paddingleft" href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($object->ref).'&pageid='.((int) $objectpage->id).'&action=deletelang&token='.newToken().'&deletelangforid='.((int) $objectpage->id).'">'.img_picto($langs->trans("Remove"), 'unlink').'</a>';
5035 }
5036 }
5037 }
5038 print '</td></tr>';
5039
5040 // Categories
5041 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5042 $disabled = '';
5043 $langs->load('categories');
5044
5045 print '<tr><td class="toptd">'.$form->editfieldkey('Categories', 'categories', '', $objectpage, 0).'</td><td>';
5046 print $form->selectCategories(Categorie::TYPE_WEBSITE_PAGE, 'categories', $objectpage);
5047 //print dolButtonToOpenUrlInDialogPopup('categories', $langs->transnoentitiesnoconv("Categories"), img_picto('', 'add'), '/categories/categorie_list.php?leftmenu=website&nosearch=1&type='.urlencode(Categorie::TYPE_WEBSITE_PAGE).'&website='.urlencode($website->ref), $disabled);
5048 print "</td></tr>";
5049 }
5050
5051 if (getDolGlobalString('WEBSITE_PAGE_SHOW_INTERNAL_LINKS_TO_OBJECT')) { // TODO Replace this with link into element_element ?
5052 print '<tr><td class="titlefieldcreate">';
5053 print 'ObjectClass';
5054 print '</td><td>';
5055 print '<input type="text" class="flat minwidth300" name="WEBSITE_OBJECTCLASS" placeholder="ClassName::/path/class/ObjectClass.class.php" >';
5056 print '</td></tr>';
5057
5058 print '<tr><td class="titlefieldcreate">';
5059 print 'ObjectID';
5060 print '</td><td>';
5061 print '<input type="text" class="flat minwidth300" name="WEBSITE_OBJECTID" >';
5062 print '</td></tr>';
5063 }
5064
5065 $fuser = new User($db);
5066
5067 // Date last modification
5068 if ($action != 'createcontainer') {
5069 print '<tr><td>';
5070 print $langs->trans('DateLastModification');
5071 print '</td><td>';
5072 print dol_print_date($pagedatemodification, 'dayhour', 'tzuser');
5073 print '</td></tr>';
5074
5075 print '<tr><td>';
5076 print $langs->trans('UserModification');
5077 print '</td><td>';
5078 if ($pageusermodifid > 0) {
5079 $fuser->fetch($pageusermodifid);
5080 print $fuser->getNomUrl(-1);
5081 } else {
5082 print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>';
5083 }
5084 print '</td></tr>';
5085 }
5086
5087 // Content - Example/templates of page
5088 $url = 'https://wiki.dolibarr.org/index.php/Module_Website';
5089 $htmltext = '<small>';
5090 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource", $url);
5091 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource1", $url);
5092 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource2", $url);
5093 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource3", $url);
5094 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource4", $url);
5095 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceMore", $url);
5096 $htmltext .= '<br>';
5097 $htmltext .= '</small>';
5098
5099 $formmail = new FormMail($db);
5100 $formmail->withaiprompt = 'html';
5101 $formmail->withlayout = 'websitepage';
5102 $showlinktolayout = $formmail->withlayout;
5103 $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationwebpage' : '';
5104 if (($action == 'createcontainer' && $showlinktolayout) || ($action == 'createcontainer' && $showlinktoai)) {
5105 print '<tr><td class="titlefield tdtop">';
5106 if ($conf->browser->layout == 'phone') {
5107 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
5108 } else {
5109 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
5110 print $form->textwithpicto($langs->trans("PreviewPageContent").' '.img_help(2, $langs->trans("PreviewPageContent")), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
5111 }
5112 print '</td><td class="tdtop">';
5113
5114 $out = '';
5115
5116 $showlinktolayoutlabel = $langs->trans("FillPageWithALayout");
5117 $showlinktoailabel = $langs->trans("FillPageWithAIContent");
5118 $htmlname = 'content';
5119 // Fill $out
5120 include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
5121
5122 print $out;
5123 print '</td></tr>';
5124 }
5125
5126 if ($action == 'createcontainer') {
5127 print '<tr id="pageContent"><td class="tdtop">';
5128 if (!$showlinktolayout || !$showlinktoai) {
5129 if ($conf->browser->layout == 'phone') {
5130 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
5131 } else {
5132 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
5133 print $form->textwithpicto($showlinktolayout ? '' : ($langs->trans("PreviewPageContent").' '.img_help(2, $langs->trans("PreviewPageContent"))), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
5134 }
5135 }
5136 print '</td><td>';
5137 //$doleditor = new DolEditor('content', GETPOST('content', 'restricthtmlallowunvalid'), '', 200, 'dolibarr_mailings', 'In', true, true, true, 40, '90%');
5138 $doleditor = new DolEditor('content', GETPOST('content', 'none'), '', 200, 'dolibarr_mailings', 'In', true, true, true, 40, '90%');
5139 $doleditor->Create();
5140 print '</div>';
5141 print '</td></tr>';
5142 }
5143
5144 // Date creation
5145 print '<tr><td>';
5146 print $langs->trans('DateCreation');
5147 print '</td><td>';
5148 print $form->selectDate($pagedatecreation, 'datecreation', 1, 1, 0, '', 1, 1);
5149 //print dol_print_date($pagedatecreation, 'dayhour');
5150 print '</td></tr>';
5151
5152 // Author
5153 print '<tr><td>';
5154 print $langs->trans('Author');
5155 print '</td><td>';
5156 if ($pageauthorid > 0) {
5157 $fuser->fetch($pageauthorid);
5158 print $fuser->getNomUrl(-1);
5159 } else {
5160 print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>';
5161 }
5162 print '</td></tr>';
5163
5164 // Author - public alias
5165 print '<tr class="trpublicauthor hidden"><td>';
5166 print $langs->trans('PublicAuthorAlias');
5167 print '</td><td>';
5168 print '<input type="text" class="flat minwidth300" name="WEBSITE_AUTHORALIAS" value="'.dol_escape_htmltag($pageauthoralias).'" placeholder="'.dol_escape_htmltag($langs->trans("Anonymous")).'">';
5169 print '</td></tr>';
5170
5171 // Web page header
5172 print '<tr><td class="tdhtmlheader tdtop">';
5173 $htmlhelp = $langs->trans("EditTheWebSiteForACommonHeader").'<br><br>';
5174 $htmlhelp .= $langs->trans("Examples").' :<br>';
5175 $htmlhelp .= '<span class="small">';
5176 $htmlhelp .= dol_nl2br(dol_htmlentities($htmlheadercontentdefault)); // do not use dol_htmlentitiesbr here, $htmlheadercontentdefault is HTML with content like <link> and <script> that we want to be html encode as they must be show as doc content not executable instruction.
5177 $htmlhelp .= '</span>';
5178 print $form->textwithpicto($langs->transnoentitiesnoconv('HtmlHeaderPage'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
5179 print '</td><td>';
5180 $poscursor = array('x' => GETPOST('htmlheader_x'), 'y' => GETPOST('htmlheader_y'));
5181 $doleditor = new DolEditor('htmlheader', $pagehtmlheader, '', 160, 'ace', 'In', true, false, 'ace', ROWS_4, '100%', 0, $poscursor);
5182 print $doleditor->Create(1, '', true, 'HTML Header', 'html');
5183 print '</td></tr>';
5184
5185 // Allowed in frames
5186 print '<tr><td>';
5187 print $langs->trans('AllowedInFrames');
5188 //$htmlhelp = $langs->trans("AllowedInFramesDesc");
5189 //print $form->textwithpicto($langs->trans('AllowedInFrames'), $htmlhelp, 1, 'help', '', 0, 2, 'allowedinframestooltip');
5190 print '</td><td>';
5191 print '<input type="checkbox" class="flat" name="WEBSITE_ALLOWED_IN_FRAMES" value="1"'.($pageallowedinframes ? 'checked="checked"' : '').'>';
5192 print '</td></tr>';
5193
5194 print '</table>';
5195
5196
5197 if ($action == 'createcontainer') {
5198 $langs->load("website");
5199
5200 print '<div class="center tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
5201
5202 print '<input type="submit" class="button small buttonforacesave" name="addcontainer" value="'.$langs->trans("Create").'">';
5203 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
5204
5205 print '</div>';
5206
5207 print '<br>';
5208
5209 if (!empty($conf->use_javascript_ajax)) {
5210 print '<input type="radio" name="radiocreatefrom" id="checkboxcreatefromfetching" value="checkboxcreatefromfetching"'.(GETPOST('radiocreatefrom') == 'checkboxcreatefromfetching' ? ' checked' : '').'> ';
5211 }
5212 print '<label for="checkboxcreatefromfetching"><span class="opacitymediumxx">'.$langs->trans("CreateByFetchingExternalPage").'</span> <span class="small opacitymedium">('.$langs->trans("ForAdvancedWebmastersOnly").')</small></label><br>';
5213 print '<hr class="tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload.'">';
5214
5215 print info_admin($langs->trans("OnlyEditionOfSourceForGrabbedContentFuture"), 0, 0, 'warning tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload);
5216 print '<br>';
5217
5218 print '<table class="tableforfield centpercent tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload.'">';
5219 print '<tr><td class="titlefield tdtop">';
5220 print $langs->trans("URL");
5221 print '</td><td>';
5222 print '<input class="flat minwidth500 marginbottomonly" type="text" name="externalurl" value="'.dol_escape_htmltag(GETPOST('externalurl', 'alpha')).'" placeholder="https://externalsite/pagetofetch"> ';
5223 print '<br>';
5224 print '<div class="paddingtop">';
5225 print '<input class="flat paddingtop paddingright" type="checkbox" name="grabimages" value="1" checked="checked">';
5226 print '<span class="valignmiddle">'.$langs->trans("GrabImagesInto");
5227 print ' ';
5228 print $langs->trans("ImagesShouldBeSavedInto").' ';
5229 print '</span>';
5230 $arraygrabimagesinto = array('root' => $langs->trans("WebsiteRootOfImages"), 'subpage' => $langs->trans("SubdirOfPage"));
5231 print $form->selectarray('grabimagesinto', $arraygrabimagesinto, GETPOSTISSET('grabimagesinto') ? GETPOST('grabimagesinto') : 'root', 0, 0, 0, '', 0, 0, 0, '', 'minwidth75 valignmiddle', 1);
5232 print '</div>';
5233
5234 print '<input class="button small" style="margin-top: 5px" type="submit" name="fetchexternalurl" value="'.dol_escape_htmltag($langs->trans("FetchAndCreate")).'">';
5235 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
5236
5237 print '</td></tr>';
5238 print '</table>';
5239 }
5240
5241 if ($action == 'createcontainer') {
5242 print '<script type="text/javascript">
5243 jQuery(document).ready(function() {
5244 var disableautofillofalias = 0;
5245 var selectedm = \'\';
5246 var selectedf = \'\';
5247
5248 jQuery("#WEBSITE_TITLE").keyup(function() {
5249 if (disableautofillofalias == 0) {
5250 var valnospecial = jQuery("#WEBSITE_TITLE").val();
5251 valnospecial = valnospecial.replace(/[éèê]/g, \'e\').replace(/[à]/g, \'a\').replace(/[ù]/g, \'u\').replace(/[î]/g, \'i\');
5252 valnospecial = valnospecial.replace(/[ç]/g, \'c\').replace(/[ö]/g, \'o\');
5253 valnospecial = valnospecial.replace(/[^\w]/gi, \'-\').toLowerCase();
5254 valnospecial = valnospecial.replace(/\-+/g, \'-\').replace(/\-$/, \'\');
5255 console.log("disableautofillofalias=0 so we replace WEBSITE_TITLE with "+valnospecial);
5256 jQuery("#WEBSITE_PAGENAME").val(valnospecial);
5257 }
5258 });
5259 jQuery("#WEBSITE_PAGENAME").keyup(function() {
5260 if (jQuery("#WEBSITE_PAGENAME").val() == \'\') {
5261 disableautofillofalias = 0;
5262 } else {
5263 disableautofillofalias = 1;
5264 }
5265 });
5266 jQuery("#WEBSITE_PAGENAME").blur(function() {
5267 if (jQuery("#WEBSITE_PAGENAME").val() == \'\') {
5268 disableautofillofalias = 0;
5269 jQuery("#WEBSITE_TITLE").trigger(\'keyup\');
5270 }
5271 });
5272
5273 jQuery("#checkboxcreatefromfetching,#checkboxcreatemanually").click(function() {
5274 console.log("we select a method to create a new container "+jQuery("#checkboxcreatefromfetching:checked").val())
5275 jQuery(".tablecheckboxcreatefromfetching").hide();
5276 jQuery(".tablecheckboxcreatemanually").hide();
5277 if (typeof(jQuery("#checkboxcreatefromfetching:checked").val()) != \'undefined\') {
5278 console.log("show create from spider form");
5279 if (selectedf != \'createfromfetching\') {
5280 jQuery(".tablecheckboxcreatefromfetching").show();
5281 selectedf = \'createfromfetching\';
5282 selectedm = \'\';
5283 } else {
5284 jQuery(".tablecheckboxcreatefromfetching").hide();
5285 selectedf = \'\';
5286 }
5287 }
5288 if (typeof(jQuery("#checkboxcreatemanually:checked").val()) != \'undefined\') {
5289 console.log("show create from scratch or template form");
5290 if (selectedm != \'createmanually\') {
5291 jQuery(".tablecheckboxcreatemanually").show();
5292 selectedm = \'createmanually\';
5293 selectedf = \'\';
5294 } else {
5295 jQuery(".tablecheckboxcreatemanually").hide();
5296 selectedm = \'\';
5297 }
5298 }
5299 });
5300 });
5301 </script>';
5302 }
5303
5304 print '</div>';
5305
5306 print '<br>';
5307}
5308
5309
5310// Print formconfirm
5311if ($action == 'preview') {
5312 print $formconfirm;
5313}
5314
5315if ($action == 'editfile' || $action == 'file_manager' || $action == 'convertimgwebp' || $action == 'confirmconvertimgwebp') {
5316 print '<!-- Edit Media -->'."\n";
5317 print '<div class="fichenopadding" style="padding-right: 20px"><br>';
5318
5319 $module = 'medias';
5320 $formalreadyopen = 2; // So the form to submit a new file will not be open another time inside the core/tpl/filemanager.tpl.php
5321 if (empty($url)) {
5322 $url = DOL_URL_ROOT.'/website/index.php'; // Must be an url without param
5323 }
5324 include DOL_DOCUMENT_ROOT.'/core/tpl/filemanager.tpl.php';
5325
5326 print '</div>';
5327}
5328
5329if ($action == 'editmenu') {
5330 print '<!-- Edit Menu -->'."\n";
5331 print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
5332}
5333
5334if ($action == 'editsource') {
5335 // Editing with source editor
5336
5337 $contentforedit = '';
5338 //$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers
5339 //$contentforedit.=$csscontent;
5340 //$contentforedit.='</style>'."\n";
5341 $contentforedit .= $objectpage->content;
5342
5343 // We set maxheightwin in px. We take the height of screen in px and we remove a part for the top banner and more
5344 $maxheightwin = 480;
5345 if (isset($_SESSION["dol_screenheight"])) {
5346 if ($_SESSION["dol_screenheight"] > 680) {
5347 $maxheightwin = (int) $_SESSION["dol_screenheight"] - 300; // We remove a height for header
5348 }
5349 if ($_SESSION["dol_screenheight"] > 800) {
5350 $maxheightwin = (int) $_SESSION["dol_screenheight"] - 250; // We remove a height for header (on large width, risk to have header on 2 lines is lower)
5351 }
5352 }
5353
5354 $poscursor = array('x' => GETPOST('PAGE_CONTENT_x'), 'y' => GETPOST('PAGE_CONTENT_y'));
5355 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
5356 $doleditor = new DolEditor('PAGE_CONTENT', $contentforedit, '', $maxheightwin, 'Full', '', true, true, 'ace', ROWS_5, '40%', 0, $poscursor);
5357 $doleditor->Create(0, '', false, 'HTML Source', 'php');
5358}
5359
5360if ($action == 'editcontent') {
5361 // Editing with default ckeditor
5362
5363 $contentforedit = '';
5364 //$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers
5365 //$contentforedit.=$csscontent;
5366 //$contentforedit.='</style>'."\n";
5367 $contentforedit .= $objectpage->content;
5368
5369 $nbrep = array();
5370 // If contentforedit has a string <img src="xxx", we replace the xxx with /viewimage.php?modulepart=medias&file=xxx except if xxx starts
5371 // with http, /viewimage.php or DOL_URL_ROOT./viewimage.phps
5372 $contentforedit = preg_replace('/(<img.*\ssrc=")(?!http|\/viewimage\.php|'.preg_quote(DOL_URL_ROOT, '/').'\/viewimage\.php)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $contentforedit, -1, $nbrep);
5373
5374 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
5375 $poscursor = array('x' => GETPOST('PAGE_CONTENT_x'), 'y' => GETPOST('PAGE_CONTENT_y'));
5376 $doleditor = new DolEditor('PAGE_CONTENT', $contentforedit, '', 500, 'Full', '', true, true, true, ROWS_5, '90%', 0, $poscursor);
5377 $doleditor->Create(0, '', false);
5378}
5379
5380print "</div>\n";
5381print "</form>\n";
5382
5383
5384if ($mode == 'replacesite' || $massaction == 'replace') {
5385 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5386 print '<input type="hidden" name="token" value="'.newToken().'">';
5387 print '<input type="hidden" name="action" value="replacesiteconfirm">';
5388 print '<input type="hidden" name="mode" value="replacesite">';
5389 print '<input type="hidden" name="website" value="'.$website->ref.'">';
5390
5391
5392 print '<!-- Search page and replace string -->'."\n";
5393 print '<div class="fiche"><br>';
5394
5395 print load_fiche_titre($langs->trans("ReplaceWebsiteContent"), '', 'search');
5396
5397 print '<div class="neutral">';
5398
5399 print '<div class="display-flex"><div class="flex-item">';
5400
5401 print '<div class="tagtable">';
5402
5403 print '<div class="tagtr">';
5404 print '<div class="tagtd paddingrightonly opacitymedium">';
5405 print $langs->trans("SearchReplaceInto");
5406 print '</div>';
5407 print '<div class="tagtd">';
5408 print '<input type="checkbox" class="marginleftonly" id="checkboxoptionpcontent" name="optionpcontent" value="content"'.((!GETPOSTISSET('buttonreplacesitesearch') || GETPOST('optionpcontent', 'aZ09')) ? ' checked' : '').'> <label for="checkboxoptionpcontent" class="tdoverflowmax150onsmartphone inline-block valignmiddle">'.$langs->trans("Content").'</label><br>';
5409 print '<input type="checkbox" class="marginleftonly" id="checkboxoptionmeta" name="optionmeta" value="meta"'.(GETPOST('optionmeta', 'aZ09') ? ' checked' : '').'> <label for="checkboxoptionmeta" class="tdoverflowmax150onsmartphone inline-block valignmiddle">'.$langs->trans("WEBSITE_PAGENAME").' | '.$langs->trans("Title").' | '.$langs->trans("Description").' | '.$langs->trans("Keywords").'</label><br>';
5410 print '<input type="checkbox" class="marginleftonly" id="checkboxoptionsitefiles" name="optionsitefiles" value="sitefiles"'.(GETPOST('optionsitefiles', 'aZ09') ? ' checked' : '').'> <label for="checkboxoptionsitefiles" class="tdoverflowmax150onsmartphone inline-block valignmiddle">'.$langs->trans("GlobalCSSorJS").'</label><br>';
5411 print '</div>';
5412 print '</div>';
5413
5414 print '<div class="tagtr">';
5415 print '<div class="tagtd paddingrightonly opacitymedium" style="padding-right: 10px !important">';
5416 print $langs->trans("SearchString");
5417 print '</div>';
5418 print '<div class="tagtd">';
5419 print '<input type="text" name="searchstring" value="'.dol_escape_htmltag($searchkey, 0, 0, '', 1).'" autofocus>';
5420 print '</div>';
5421 print '</div>';
5422
5423 print '</div>';
5424
5425 print '</div><div class="flex-item">';
5426
5427 print '<div class="tagtable">';
5428
5429 print '<div class="tagtr">';
5430 print '<div class="tagtd paddingrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5431 print $langs->trans("WEBSITE_TYPE_CONTAINER");
5432 print '</div>';
5433 print '<div class="tagtd">';
5434 print img_picto('', 'object_technic', 'class="pictofixedwidth"').' ';
5435 print $formwebsite->selectTypeOfContainer('optioncontainertype', (GETPOST('optioncontainertype', 'alpha') ? GETPOST('optioncontainertype', 'alpha') : ''), 1, '', 1, 'minwidth125 maxwidth400 widthcentpercentminusx');
5436 print '</div>';
5437 print '</div>';
5438
5439 print '<div class="tagtr">';
5440 print '<div class="tagtd paddingrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5441 print $langs->trans("Language");
5442 print '</div>';
5443 print '<div class="tagtd">';
5444 print img_picto('', 'language', 'class="pictofixedwidth"').' '.$formadmin->select_language(GETPOSTISSET('optionlanguage') ? GETPOST('optionlanguage') : '', 'optionlanguage', 0, array(), '1', 0, 0, 'minwidth125 maxwidth400 widthcentpercentminusx', 2, 0, 0, array(), 1);
5445 print '</div>';
5446 print '</div>';
5447
5448 // Categories
5449 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5450 print '<div class="tagtr">';
5451 print '<div class="tagtd paddingrightonly marginrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5452 print $langs->trans("Category");
5453 print '</div>';
5454 print '<div class="tagtd">';
5455 //print $form->selectCategories(Categorie::TYPE_WEBSITE_PAGE, 'optioncategory', $object);
5456 print img_picto('', 'category', 'class="pictofixedwidth"').' '.$form->select_all_categories(Categorie::TYPE_WEBSITE_PAGE, GETPOSTISSET('optioncategory') ? GETPOST('optioncategory') : '', 'optioncategory', 0, 0, 0, 0, 'minwidth125 maxwidth400 widthcentpercentminusx');
5457 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
5458 print ajax_combobox('optioncategory');
5459 print '</div>';
5460 print '</div>';
5461 }
5462
5463 print '</div>';
5464
5465 print '</div></div>';
5466
5467 print '<center>';
5468 print '<input type="submit" class="button margintoponly" name="buttonreplacesitesearch" value="'.dol_escape_htmltag($langs->trans("Search")).'">';
5469 print '</center>';
5470
5471 print '</div>';
5472
5473
5474 if ($mode == 'replacesite') {
5475 print '<!-- List of search result -->'."\n";
5476 print '<div class="rowsearchresult clearboth">';
5477
5478 print '<br>';
5479 print '<br>';
5480
5481 if ($listofpages['code'] == 'OK') {
5482 $arrayofselected = is_array($toselect) ? $toselect : array();
5483 $param = '';
5484 $nbtotalofrecords = count($listofpages['list']);
5485 $num = $limit;
5486 $permissiontodelete = $user->hasRight('website', 'delete');
5487
5488 // List of mass actions available
5489 $arrayofmassactions = array();
5490 if ($user->hasRight('website', 'writephp') && $searchkey) {
5491 $arrayofmassactions['replace'] = img_picto('', 'replacement', 'class="pictofixedwidth"').$langs->trans("Replace");
5492 }
5493 if ($user->hasRight('website', 'write')) {
5494 $langs->load("categories");
5495 $arrayofmassactions['setcategory'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("ClassifyInCategory");
5496 }
5497 if ($user->hasRight('website', 'write')) {
5498 $langs->load("categories");
5499 $arrayofmassactions['delcategory'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("RemoveCategory");
5500 }
5501 if ($permissiontodelete) {
5502 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
5503 }
5504 if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
5505 $arrayofmassactions = array();
5506 }
5507
5508 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
5509 $massactionbutton .= '<div class="massactionother massactionreplace hidden">';
5510 $massactionbutton .= $langs->trans("ReplaceString");
5511 $massactionbutton .= ' <input type="text" name="replacestring" value="'.dol_escape_htmltag(GETPOST('replacestring', 'none')).'">';
5512 $massactionbutton .= '</div>';
5513 $massactionbutton .= '<div class="massactionother massactionsetcategory massactiondelcategory hidden">';
5514 $massactionbutton .= img_picto('', 'category', 'class="pictofixedwidth"');
5515 $massactionbutton .= $form->select_all_categories(Categorie::TYPE_WEBSITE_PAGE, GETPOSTISSET('setcategory') ? GETPOST('setcategory') : '', 'setcategory', 64, 0, 0, 0, 'minwidth300 alignstart');
5516 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
5517 $massactionbutton .= ajax_combobox('setcategory');
5518 $massactionbutton .= '</div>';
5519
5520 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
5521
5522 //$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields
5523 $selectedfields = '';
5524 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
5525
5526 print_barre_liste($langs->trans("Results"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit, 1, 1, 1);
5527
5528 $topicmail = "WebsitePageRef";
5529 $modelmail = "websitepage_send";
5530 $objecttmp = new WebsitePage($db);
5531 $trackid = 'wsp'.$object->id;
5532 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
5533
5534 $param = 'mode=replacesite&website='.urlencode($website->ref);
5535 $param .= '&searchstring='.urlencode($searchkey);
5536 if (GETPOST('optionpcontent')) {
5537 $param .= '&optionpcontent=content';
5538 }
5539 if (GETPOST('optionmeta')) {
5540 $param .= '&optionmeta=meta';
5541 }
5542 if (GETPOST('optionsitefiles')) {
5543 $param .= '&optionsitefiles=optionsitefiles';
5544 }
5545 if (GETPOST('optioncontainertype')) {
5546 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5547 }
5548 if (GETPOST('optionlanguage')) {
5549 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5550 }
5551 if (GETPOST('optioncategory')) {
5552 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5553 }
5554
5555 print '<div class="div-table-responsive-no-min">';
5556 print '<table class="noborder centpercent">';
5557 print '<tr class="liste_titre">';
5558 // Action column
5559 if ($conf->main_checkbox_left_column) {
5560 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
5561 }
5562 print getTitleFieldOfList("Type", 0, $_SERVER['PHP_SELF'], 'type_container', '', $param, '', $sortfield, $sortorder, '')."\n";
5563 print getTitleFieldOfList("Page", 0, $_SERVER['PHP_SELF'], 'pageurl', '', $param, '', $sortfield, $sortorder, '')."\n";
5564 print getTitleFieldOfList("Language", 0, $_SERVER['PHP_SELF'], 'lang', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
5565 print getTitleFieldOfList("Categories", 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
5566 print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']);
5567 print getTitleFieldOfList("UserCreation", 0, $_SERVER['PHP_SELF'], 'fk_user_creat', '', $param, '', $sortfield, $sortorder, '')."\n";
5568 print getTitleFieldOfList("DateCreation", 0, $_SERVER['PHP_SELF'], 'date_creation', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; // Date creation
5569 print getTitleFieldOfList("DateLastModification", 0, $_SERVER['PHP_SELF'], 'tms', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; // Date last modif
5570 print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']);
5571 // Action column
5572 if (!$conf->main_checkbox_left_column) {
5573 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
5574 }
5575 print '</tr>';
5576
5577 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
5578 $c = new Categorie($db);
5579
5580 $totalnbwords = 0;
5581
5582 foreach ($listofpages['list'] as $answerrecord) {
5583 if (is_object($answerrecord) && get_class($answerrecord) == 'WebsitePage') {
5584 $param = '?mode=replacesite';
5585 $param .= '&websiteid='.$website->id;
5586 $param .= '&optionpcontent='.GETPOST('optionpcontent', 'aZ09');
5587 $param .= '&optionmeta='.GETPOST('optionmeta', 'aZ09');
5588 $param .= '&optionsitefiles='.GETPOST('optionsitefiles', 'aZ09');
5589 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5590 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5591 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5592 $param .= '&searchstring='.urlencode($searchkey);
5593
5594 print '<tr>';
5595
5596 // Action column
5597 if ($conf->main_checkbox_left_column) {
5598 print '<td class="nowrap center">';
5599
5600 print '<!-- Status of page -->'."\n";
5601 if ($massactionbutton || $massaction) {
5602 $selected = 0;
5603 if (in_array($answerrecord->id, $arrayofselected)) {
5604 $selected = 1;
5605 }
5606 print '<input id="'.$answerrecord->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$answerrecord->id.'"'.($selected ? ' checked="checked"' : '').'>';
5607 }
5608 print '</td>';
5609 }
5610
5611 // Type of container
5612 print '<td class="nowraponall">';
5613 //print $langs->trans("Container").'<br>';
5614 if (!empty($conf->cache['type_of_container'][$answerrecord->type_container])) {
5615 print $langs->trans($conf->cache['type_of_container'][$answerrecord->type_container]);
5616 } else {
5617 print $langs->trans($answerrecord->type_container);
5618 }
5619 print '</td>';
5620
5621 // Container url and label
5622 $titleofpage = ($answerrecord->title ? $answerrecord->title : $langs->trans("NoTitle"));
5623 print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($titleofpage).'">';
5624 print $answerrecord->getNomUrl(1);
5625 print ' <span class="opacitymedium">('.dol_escape_htmltag($titleofpage).')</span>';
5626 //print '</td>';
5627 //print '<td class="tdoverflow100">';
5628 print '<br>';
5629 print '<span class="opacitymedium">'.dol_escape_htmltag($answerrecord->description ? $answerrecord->description : $langs->trans("NoDescription")).'</span>';
5630 print '</td>';
5631
5632 // Language
5633 print '<td class="center">';
5634 print picto_from_langcode($answerrecord->lang, $answerrecord->lang);
5635 print '</td>';
5636
5637 // Categories - Tags
5638 print '<td class="center">';
5639 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5640 // Get current categories
5641 $existing = $c->containing($answerrecord->id, Categorie::TYPE_WEBSITE_PAGE, 'object');
5642 if (is_array($existing)) {
5643 foreach ($existing as $tmpcategory) {
5644 //var_dump($tmpcategory);
5645 print img_object($langs->trans("Category").' : '.$tmpcategory->label, 'category', 'style="padding-left: 2px; padding-right: 2px; color: #'.($tmpcategory->color != '' ? $tmpcategory->color : '888').'"');
5646 }
5647 }
5648 }
5649 //var_dump($existing);
5650 print '</td>';
5651
5652 // Number of words
5653 print '<td class="center nowraponall">';
5654 $textwithouthtml = dol_string_nohtmltag(dolStripPhpCode($answerrecord->content));
5655 $characterMap = 'áàéèëíóúüñùç0123456789';
5656 $nbofwords = str_word_count($textwithouthtml, 0, $characterMap);
5657 if ($nbofwords) {
5658 print $nbofwords.' '.$langs->trans("words");
5659 $totalnbwords += $nbofwords;
5660 }
5661 print '</td>';
5662
5663 // Author
5664 print '<td class="tdoverflowmax125">';
5665 if (!empty($answerrecord->fk_user_creat)) {
5666 if (empty($conf->cache['user'][$answerrecord->fk_user_creat])) {
5667 $tmpuser = new User($db);
5668 $tmpuser->fetch($answerrecord->fk_user_creat);
5669 $conf->cache['user'][$answerrecord->fk_user_creat] = $tmpuser;
5670 } else {
5671 $tmpuser = $conf->cache['user'][$answerrecord->fk_user_creat];
5672 }
5673 print $tmpuser->getNomUrl(-1, '', 0, 0, 0, 0, 'login');
5674 }
5675 print '</td>';
5676
5677 // Date creation
5678 print '<td class="center nowraponall">';
5679 print dol_print_date($answerrecord->date_creation, 'dayhour');
5680 print '</td>';
5681
5682 // Date last modification
5683 print '<td class="center nowraponall">';
5684 print dol_print_date($answerrecord->date_modification, 'dayhour');
5685 print '</td>';
5686
5687 // Edit properties, HTML sources, status
5688 print '<td class="tdwebsitesearchresult right nowraponall">';
5689 $disabled = '';
5690 $urltoedithtmlsource = $_SERVER["PHP_SELF"].'?action=editmeta&token='.newToken().'&websiteid='.$website->id.'&pageid='.$answerrecord->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].$param);
5691 if (!$user->hasRight('website', 'write')) {
5692 $disabled = ' disabled';
5693 $urltoedithtmlsource = '';
5694 }
5695 print '<a class="editfielda marginleftonly marginrightonly '.$disabled.'" href="'.$urltoedithtmlsource.'" title="'.$langs->trans("EditPageMeta").'">'.img_picto($langs->trans("EditPageMeta"), 'pencil-ruler').'</a>';
5696
5697 $disabled = '';
5698 $urltoedithtmlsource = $_SERVER["PHP_SELF"].'?action=editsource&token='.newToken().'&websiteid='.$website->id.'&pageid='.$answerrecord->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].$param);
5699 if (!$user->hasRight('website', 'write')) {
5700 $disabled = ' disabled';
5701 $urltoedithtmlsource = '';
5702 }
5703 print '<a class="editfielda marginleftonly marginrightonly '.$disabled.'" href="'.$urltoedithtmlsource.'" title="'.$langs->trans("EditHTMLSource").'">'.img_picto($langs->trans("EditHTMLSource"), 'edit').'</a>';
5704
5705 print '<span class="marginleftonly marginrightonly"></span>';
5706 print ajax_object_onoff($answerrecord, 'status', 'status', 'Enabled', 'Disabled', array(), 'valignmiddle inline-block');
5707
5708 print '</td>';
5709
5710 // Action column
5711 if (!$conf->main_checkbox_left_column) {
5712 print '<td class="nowrap center">';
5713
5714 print '<!-- Status of page -->'."\n";
5715 if ($massactionbutton || $massaction) {
5716 $selected = 0;
5717 if (in_array($answerrecord->id, $arrayofselected)) {
5718 $selected = 1;
5719 }
5720 print '<input id="'.$answerrecord->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$answerrecord->id.'"'.($selected ? ' checked="checked"' : '').'>';
5721 }
5722 print '</td>';
5723 }
5724
5725 print '</tr>';
5726 } else {
5727 // $answerrecord is not list of WebsitePage
5728 '@phan-var-force array{type:string} $answerrecord';
5729 $param = '?mode=replacesite';
5730 $param .= '&websiteid='.$website->id;
5731 $param .= '&optionpcontent='.GETPOST('optionpcontent', 'aZ09');
5732 $param .= '&optionmeta='.GETPOST('optionmeta', 'aZ09');
5733 $param .= '&optionsitefiles='.GETPOST('optionsitefiles', 'aZ09');
5734 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5735 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5736 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5737 $param .= '&searchstring='.urlencode($searchkey);
5738
5739 print '<tr>';
5740
5741 // Action column
5742 if ($conf->main_checkbox_left_column) {
5743 print '<td class="nowrap center">';
5744 print '</td>';
5745 }
5746
5747 // Type of container
5748 print '<td>';
5749 $translateofrecordtype = array(
5750 'website_csscontent' => 'WEBSITE_CSS_INLINE',
5751 'website_jscontent' => 'WEBSITE_JS_INLINE',
5752 'website_robotcontent' => 'WEBSITE_ROBOT',
5753 'website_htmlheadercontent' => 'WEBSITE_HTML_HEADER',
5754 'website_htaccess' => 'WEBSITE_HTACCESS',
5755 'website_readme' => 'WEBSITE_README',
5756 'website_manifestjson' => 'WEBSITE_MANIFEST_JSON'
5757 );
5758 print '<span class="opacitymedium">';
5759 if (!empty($translateofrecordtype[$answerrecord['type']])) {
5760 print $langs->trans($translateofrecordtype[$answerrecord['type']]);
5761 } else {
5762 print $answerrecord['type'];
5763 }
5764 print '</span>';
5765 print '</td>';
5766
5767 // Container url and label
5768 print '<td>';
5769 $backtopageurl = $_SERVER["PHP_SELF"].$param;
5770 print '<a href="'.$_SERVER["PHP_SELF"].'?action=editcss&token='.newToken().'&website='.urlencode($website->ref).'&backtopage='.urlencode($backtopageurl).'">'.$langs->trans("EditCss").'</a>';
5771 print '</td>';
5772
5773 // Language
5774 print '<td>';
5775 print '</td>';
5776
5777 // Categories - Tags
5778 print '<td>';
5779 print '</td>';
5780
5781 // Nb of words
5782 print '<td>';
5783 print '</td>';
5784
5785 print '<td>';
5786 print '</td>';
5787
5788 print '<td>';
5789 print '</td>';
5790
5791 // Date last modification
5792 print '<td class="center nowraponall">';
5793 //print dol_print_date(filemtime());
5794 print '</td>';
5795
5796 // Edit properties, HTML sources, status
5797 print '<td>';
5798 print '</td>';
5799
5800 // Action column
5801 if (!$conf->main_checkbox_left_column) {
5802 print '<td class="nowrap center">';
5803 print '</td>';
5804 }
5805
5806 print '</tr>';
5807 }
5808 }
5809
5810 if (count($listofpages['list']) >= 2) {
5811 // Total
5812 print '<tr class="lite_titre">';
5813
5814 // Action column
5815 if ($conf->main_checkbox_left_column) {
5816 print '<td class="nowrap center">';
5817 print '</td>';
5818 }
5819
5820 // Type of container
5821 print '<td>';
5822 print $langs->trans("Total");
5823 print '</td>';
5824
5825 // Container url and label
5826 print '<td>';
5827 print '</td>';
5828
5829 // Language
5830 print '<td>';
5831 print '</td>';
5832
5833 // Categories - Tags
5834 print '<td>';
5835 print '</td>';
5836
5837 // Nb of words
5838 print '<td class="center nowraponall">';
5839 print $totalnbwords.' '.$langs->trans("words");
5840 print '</td>';
5841
5842 print '<td>';
5843 print '</td>';
5844
5845 print '<td>';
5846 print '</td>';
5847
5848 // Date last modification
5849 print '<td>';
5850 print '</td>';
5851
5852 // Edit properties, HTML sources, status
5853 print '<td>';
5854 print '</td>';
5855
5856 // Action column
5857 if (!$conf->main_checkbox_left_column) {
5858 print '<td class="nowrap center">';
5859 print '</td>';
5860 }
5861
5862 print '</tr>';
5863 }
5864
5865 print '</table>';
5866 print '</div>';
5867 print '<br>';
5868 } else {
5869 print '<div class="warning">'.$listofpages['message'].'</div>';
5870 }
5871
5872 print '</div>';
5873 }
5874
5875 print '</form>';
5876}
5877
5878if ((empty($action) || $action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') && !in_array($mode, array('replacesite'))) {
5879 if ($pageid > 0 && $atleastonepage) {
5880 // $filejs
5881 // $filecss
5882 // $filephp
5883
5884 // Output page under the Dolibarr top menu
5885 $objectpage->fetch($pageid);
5886
5887 $jscontent = @file_get_contents($filejs);
5888
5889 $out = '<!-- Page content '.$filetpl.' : Div with (Htmlheader/Style of page from database + CSS Of website from file + Page content from database or by include if WEBSITE_SUBCONTAINERSINLINE is on) -->'."\n";
5890
5891 // Include a html so we can benefit of the header of page.
5892 // Note: We can't use iframe as it can be used to include another external html file
5893 // Note: We can't use frame as it is deprecated.
5894 /*if ($includepageintoaframeoradiv == 'iframe')
5895 {
5896 $out .= "<iframe><body></html>";
5897 }*/
5898 $out .= "\n<html><head>\n";
5899 $out .= "<!-- htmlheader/style of page from database -->\n";
5900 $out .= dolWebsiteReplacementOfLinks($object, $objectpage->htmlheader, 1, 'htmlheader');
5901
5902 $out .= "<!-- htmlheader/style of website from files -->\n";
5903 // TODO Keep only the <link> or the <script> tags
5904 /*
5905 $htmlheadercontent = @file_get_contents($filehtmlheader);
5906 $dom = new DOMDocument;
5907 @$dom->loadHTML($htmlheadercontent);
5908 $styles = $dom->getElementsByTagName('link');
5909 $scripts = $dom->getElementsByTagName('script');
5910 foreach($styles as $stylescursor)
5911 {
5912 $out.=$stylescursor;
5913 }
5914 foreach($scripts as $scriptscursor)
5915 {
5916 $out.=$scriptscursor;
5917 }
5918 */
5919
5920 $out .= "</head>\n";
5921 $out .= "\n";
5922 $out .= "<body>\n";
5923
5924
5925 $out .= '<div id="websitecontentundertopmenu" class="websitecontentundertopmenu boostrap-iso">'."\n";
5926
5927 // REPLACEMENT OF LINKS When page called by website editor
5928
5929 $out .= '<!-- style of website from file -->'."\n";
5930 $out .= '<style scoped>'."\n"; // "scoped" means "apply to parent element only and not grand parent". No more supported by browsers, snif !
5931 $tmpout = '';
5932 $tmpout .= '/* Include website CSS file */'."\n";
5933 //$csscontent = @file_get_contents($filecss);
5934 if (dol_is_file($filecss)) {
5935 ob_start();
5936 include $filecss;
5937 $csscontent = ob_get_contents();
5938 ob_end_clean();
5939 } else {
5940 $csscontent = '';
5941 }
5942 $tmpout .= dolWebsiteReplacementOfLinks($object, $csscontent, 1, 'css');
5943 $tmpout .= '/* Include style from the HTML header of page */'."\n";
5944 // Clean the html header of page to get only <style> content
5945 $tmp = preg_split('(<style[^>]*>|</style>)', $objectpage->htmlheader);
5946 $tmpstyleinheader = '';
5947 $i = 0;
5948 foreach ($tmp as $valtmp) {
5949 $i++;
5950 if ($i % 2 == 0) {
5951 $tmpstyleinheader .= $valtmp."\n";
5952 }
5953 }
5954 $tmpout .= $tmpstyleinheader."\n";
5955 // Clean style that may affect global style of Dolibarr
5956 $tmpout = preg_replace('/}[\s\n]*body\s*{[^}]+}/ims', '}', $tmpout);
5957 $out .= $tmpout;
5958 $out .= '</style>'."\n";
5959
5960 // Note: <div>, <section>, ... with contenteditable="true" inside this can be edited with inline ckeditor
5961
5962 // Do not enable the contenteditable when page was grabbed, ckeditor is removing span and adding borders,
5963 // so editable will be available only from container created from scratch
5964 //$out.='<div id="bodywebsite" class="bodywebsite"'.($objectpage->grabbed_from ? ' contenteditable="true"' : '').'>'."\n";
5965 $out .= '<div id="divbodywebsite" class="bodywebsite bodywebpage-'.$objectpage->ref.'">'."\n";
5966
5967 $newcontent = $objectpage->content;
5968
5969 // If mode WEBSITE_SUBCONTAINERSINLINE is on
5970 if (getDolGlobalString('WEBSITE_SUBCONTAINERSINLINE')) {
5971 // TODO Check file $filephp exists, if not create it.
5972
5973 //var_dump($filetpl);
5974 $filephp = $filetpl;
5975
5976 // Get session info and obfuscate session cookie
5977 $savsessionname = session_name();
5978 $savsessionid = $_COOKIE[$savsessionname];
5979 $_COOKIE[$savsessionname] = 'obfuscatedcookie';
5980
5981 ob_start();
5982 try {
5983 $res = include $filephp;
5984 if (empty($res)) {
5985 print "ERROR: Failed to include file '".$filephp."'. Try to edit and re-save page with this ID.";
5986 }
5987 } catch (Exception $e) {
5988 print $e->getMessage();
5989 }
5990 $newcontent = ob_get_contents();
5991 ob_end_clean();
5992
5993 // Restore data
5994 $_COOKIE[$savsessionname] = $savsessionid;
5995 }
5996
5997 // Change the contenteditable to "true" or "false" when mode Edit Inline is on or off
5998 if (!getDolGlobalString('WEBSITE_EDITINLINE')) {
5999 // Remove the contenteditable="true"
6000 $newcontent = preg_replace('/(div|section|header|main|footer)(\s[^>]*)contenteditable="true"/', '\1\2', $newcontent);
6001 } else {
6002 // Keep the contenteditable="true" when mode Edit Inline is on
6003 }
6004 $out .= dolWebsiteReplacementOfLinks($object, $newcontent, 0, 'html', $objectpage->id)."\n";
6005 //$out.=$newcontent;
6006
6007 $out .= '</div>'."\n";
6008
6009 $out .= '</div> <!-- End div id=websitecontentundertopmenu -->'."\n";
6010
6011 /*if ($includepageintoaframeoradiv == 'iframe')
6012 {
6013 $out .= "</body></html></iframe>";
6014 }*/
6015 $out .= "\n</body></html>\n";
6016
6017 $out .= "\n".'<!-- End page content '.$filetpl.' -->'."\n\n";
6018
6019 print $out;
6020
6021 /*
6022 file_put_contents($filetpl, $out);
6023 dolChmod($filetpl);
6024
6025 // Output file on browser
6026 dol_syslog("index.php include $filetpl $filename content-type=$type");
6027 $original_file_osencoded=dol_osencode($filetpl); // New file name encoded in OS encoding charset
6028
6029 // This test if file exists should be useless. We keep it to find bug more easily
6030 if (! file_exists($original_file_osencoded))
6031 {
6032 dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
6033 exit;
6034 }
6035
6036 //include_once $original_file_osencoded;
6037 */
6038
6039 /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$pageid.'"/>';
6040 print '</iframe>';*/
6041 } else {
6042 if (empty($websitekey) || $websitekey == '-1') {
6043 print '<br><br><div class="center previewnotyetavailable"><span class="">'.$langs->trans("NoWebSiteCreateOneFirst").'</span></div><br><br><br>';
6044 print '<div class="center"><div class="logo_setup"></div></div>';
6045 } else {
6046 print '<br><br><div class="center previewnotyetavailable"><span class="">'.$langs->trans("PreviewOfSiteNotYetAvailable", $object->ref).'</span></div><br><br><br>';
6047 print '<div class="center"><div class="logo_setup"></div></div>';
6048 }
6049 }
6050}
6051
6052// End of page
6053llxFooter();
6054$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
global $dolibarr_main_url_root
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=array(), $morecss='', $htmlname='', $forcenojs=0, $moreparam='', $readonly=0)
On/off button to change a property status of an object This uses the ajax service objectonoff....
Definition ajax.lib.php:804
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
$c
Definition line.php:334
$object ref
Definition info.php:90
Class to manage categories.
Class to manage a WYSIWYG editor.
Class to generate html code for admin pages.
Class to manage generation of HTML components Only common components must be here.
Class to manage a HTML form to send a unitary email Usage: $formail = new FormMail($db) $formmail->pr...
Class to help generate other html components Only common components are here.
Class to manage component html for module website.
The LESS compiler and parser.
Class to manage Dolibarr users.
Class Website.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modifylinks=0, $grabimages=1, $grabimagesinto='subpage')
Download all images found into an external URL.
dolStripPhpCode($str, $replacewith='')
Remove PHP code part from a string.
dolWebsiteReplacementOfLinks($website, $content, $removephppart=0, $contenttype='html', $containerid=0)
Convert a page content to have correct links (based on DOL_URL_ROOT) into an html content.
dolKeepOnlyPhpCode($str)
Keep only PHP code part from a HTML string page.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_add_file_process($upload_dir, $allowoverwrite=0, $updatesessionordb=0, $keyforsourcefile='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1, $object=null, $forceFullTextIndexation='', $mode=0)
Get and save an upload file (for example after submitting a new file in a mail form).
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_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_is_file($pathoffile)
Return if path is a file.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_help($usehelpcursor=1, $usealttitle=1)
Show help logo with cursor "?".
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $jsonclose='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
currentToken()
Return the value of token currently saved into session with name 'token'.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dolButtonToOpenExportDialog($name, $label, $buttonstring, $exportSiteName, $overwriteGitUrl, $website)
Create a dialog with two buttons for export and overwrite of a website.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
ajax_autoselect($htmlname, $addlink='', $textonlink='Link')
Make content of an input box selected when we click into input field.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
img_previous($titlealt='default', $moreatt='')
Show previous logo.
dol_htmlentities($string, $flags=ENT_QUOTES|ENT_SUBSTITUTE, $encoding='UTF-8', $double_encode=false)
Replace htmlentities functions.
dol_sanitizeUrl($stringtoclean, $type=1)
Clean a string to use it as an URL (into a href or src attribute)
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_next($titlealt='default', $moreatt='')
Show next logo.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
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)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getDomainFromURL($url, $mode=0)
Function get second level domain name.
getRootURLFromURL($url)
Function root url from a long url For example: https://www.abc.mydomain.com/dir/page....
removeHtmlComment($content)
Function to remove comments into HTML content.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1, $timeoutconnect=0, $timeoutresponse=0, $otherCurlOptions=array(), $morelogsuffix='')
Function to get a content from an URL (use proxy if proxy defined).
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
getMaxFileSizeArray()
Return the max allowed for file upload.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dolSaveMasterFile($filemaster)
Save content of a page on disk.
dolSaveLicense($file, $content)
Save content of a page on disk.
checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
Check that the new string $phpfullcodestring contains 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).
showWebsiteTemplates(Website $website, int $refresh)
Show list of themes.
dolSaveCssFile($filecss, $csscontent)
Save content of a page on disk.
dolSaveRobotFile($filerobot, $robotcontent)
Save content of a page on disk.
websiteGetContentPolicyDirectives()
Prepare array of directives for Website.
websiteGetContentPolicySources()
Prepare array of sources for Website.
websiteGetContentPolicyToArray($forceCSP)
Transform a Content Security Policy to an array.
websiteconfigPrepareHead($object)
Prepare array of tabs for Website.