dolibarr 25.0.0-alpha
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-2026 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 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1424 $res = $object->delete($user);
1425 if ($res <= 0) {
1426 $error++;
1427 setEventMessages($object->error, $object->errors, 'errors');
1428 }
1429 }
1430 if (!$error) {
1431 if (GETPOST('delete_also_js', 'alpha') == 'on') {
1432 $pathofwebsitejs = DOL_DATA_ROOT.'/medias/js/'.$object->ref;
1433
1434 dol_delete_dir_recursive($pathofwebsitejs);
1435 }
1436 if (GETPOST('delete_also_medias', 'alpha') == 'on') {
1437 $pathofwebsitemedias = DOL_DATA_ROOT.'/medias/image/'.$object->ref;
1438
1439 dol_delete_dir_recursive($pathofwebsitemedias);
1440 }
1441 }
1442
1443 if (!$error) {
1444 $db->commit();
1445 setEventMessages($langs->trans("SiteDeleted", $object->ref), null, 'mesgs');
1446
1447 header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id);
1448 exit;
1449 } else {
1450 $db->rollback();
1451 setEventMessages($object->error, $object->errors, 'errors');
1452 }
1453}
1454
1455// Delete page (from website page menu)
1456if (GETPOSTISSET('pageid') && $action == 'delete' && $permissiontodelete && !GETPOST('file_manager')) {
1457 $error = 0;
1458
1459 $db->begin();
1460
1461 $res = $object->fetch(0, $websitekey);
1462 $website = $object;
1463
1464 $res = $objectpage->fetch($pageid, (string) $object->id);
1465
1466 if ($res > 0) {
1467 $res = $objectpage->delete($user);
1468 if ($res <= 0) {
1469 $error++;
1470 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
1471 }
1472 }
1473
1474 if (!$error) {
1475 $db->commit();
1476 setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $websitekey), null, 'mesgs');
1477
1478 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey);
1479 exit;
1480 } else {
1481 $db->rollback();
1482 dol_print_error($db);
1483 }
1484}
1485// Delete page (from menu search)
1486if (!GETPOSTISSET('pageid')) {
1487 $objectclass = 'WebsitePage';
1488
1489 // Add part of code from actions_massactions.inc.php
1490 // Delete record from mass action (massaction = 'delete' for direct delete, action/confirm='delete'/'yes' with a confirmation step before)
1491 if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == 'yes')) && $permissiontodelete) {
1492 $db->begin();
1493
1494 $objecttmp = new $objectclass($db);
1495 $nbok = 0;
1496 foreach ($toselect as $toselectid) {
1497 $result = $objecttmp->fetch($toselectid);
1498 if ($result > 0) {
1499 $result = $objecttmp->delete($user);
1500
1501 if ($result <= 0) {
1502 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
1503 $error++;
1504 break;
1505 } else {
1506 $nbok++;
1507 }
1508 } else {
1509 setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
1510 $error++;
1511 break;
1512 }
1513 }
1514
1515 if (!$error) {
1516 if ($nbok > 1) {
1517 setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
1518 } else {
1519 setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
1520 }
1521 $db->commit();
1522 } else {
1523 $db->rollback();
1524 }
1525 //var_dump($listofobjectthirdparties);exit;
1526 }
1527
1528 if ($action == 'delete') { // Test on permission not required here
1529 $mode = 'replacesite';
1530 $action = 'replacesite';
1531
1532 $containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : '';
1533 $langcode = GETPOST('optionlanguage', 'aZ09');
1534 $otherfilters = array();
1535 if (GETPOSTINT('optioncategory') > 0) {
1536 $otherfilters['category'] = GETPOSTINT('optioncategory');
1537 }
1538
1539 $listofpages = getPagesFromSearchCriterias($containertype, $algo, $searchkey, 1000, $sortfield, $sortorder, $langcode, $otherfilters);
1540 }
1541}
1542
1543// Update css site properties. Re-generates also the wrapper.
1544if ($action == 'updatecss' && $usercanedit) {
1545 // If we tried to reload another site/page, we stay on editcss mode.
1546 if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x')) {
1547 $action = 'editcss';
1548 } else {
1549 $res = $object->fetch(0, $websitekey);
1550 $website = $object;
1551
1552 if (GETPOSTISSET('virtualhost')) {
1553 $tmpvirtualhost = preg_replace('/\/$/', '', GETPOST('virtualhost', 'alpha'));
1554 if ($tmpvirtualhost && !preg_match('/^http/', $tmpvirtualhost)) {
1555 $error++;
1556 setEventMessages($langs->trans('ErrorURLMustStartWithHttp', $langs->transnoentitiesnoconv("VirtualHost")), null, 'errors');
1557 $action = 'editcss';
1558 }
1559
1560 if (!$error) {
1561 $arrayotherlang = explode(',', GETPOST('WEBSITE_OTHERLANG', 'alphanohtml'));
1562 foreach ($arrayotherlang as $key => $val) {
1563 // It possible we have empty val here if postparam WEBSITE_OTHERLANG is empty or set like this : 'en,,sv' or 'en,sv,'
1564 if (empty(trim($val))) {
1565 continue;
1566 }
1567 $arrayotherlang[$key] = substr(trim($val), 0, 2); // Kept short language code only
1568 }
1569
1570 $object->virtualhost = $tmpvirtualhost;
1571 $object->lang = GETPOST('WEBSITE_LANG', 'aZ09');
1572 $object->otherlang = implode(',', $arrayotherlang);
1573 $object->use_manifest = GETPOSTINT('use_manifest');
1574
1575 $result = $object->update($user);
1576 if ($result < 0) {
1577 $error++;
1578 setEventMessages($object->error, $object->errors, 'errors');
1579 $action = 'editcss';
1580 }
1581 }
1582 }
1583
1584 if (!$error) {
1585 if (($_FILES['addedfile']["name"] != '')) {
1586 $uploadfolder = $conf->website->dir_output.'/'.$websitekey;
1587 if ($_FILES['addedfile']['type'] != 'image/png') {
1588 $error++;
1589 setEventMessages($langs->trans('ErrorFaviconType'), array(), 'errors');
1590 }
1591 $filetoread = realpath(dol_osencode($_FILES['addedfile']['tmp_name']));
1592 $filesize = getimagesize($filetoread);
1593 if ($filesize[0] != $filesize[1]) {
1594 $error++;
1595 setEventMessages($langs->trans('ErrorFaviconMustBeASquaredImage'), array(), 'errors');
1596 }
1597 if (! $error && ($filesize[0] != 16 && $filesize[0] != 32 && $filesize[0] != 64)) {
1598 $error++;
1599 setEventMessages($langs->trans('ErrorFaviconSize'), array(), 'errors');
1600 }
1601 if (!$error) {
1602 dol_add_file_process($uploadfolder, 1, 0, 'addedfile', 'favicon.png');
1603 }
1604 }
1605 if ($error) {
1606 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
1607 $action = 'preview';
1608 if ($backtopage) {
1609 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
1610 header("Location: ".$backtopage);
1611 exit;
1612 }
1613 } else {
1614 $action = 'editcss';
1615 }
1616 }
1617 }
1618
1619 if (!$error) {
1620 // Save master.inc.php file
1621 dol_syslog("Save master file ".$filemaster);
1622
1623 dol_mkdir($pathofwebsite);
1624
1625 // Now generate the master.inc.php page
1626 $result = dolSaveMasterFile($filemaster);
1627 if (!$result) {
1628 $error++;
1629 setEventMessages('Failed to write file '.$filemaster, null, 'errors');
1630 }
1631
1632
1633 $dataposted = trim(GETPOST('WEBSITE_HTML_HEADER', 'restricthtmlallowlinkscript')); // Must accept tags like '<script>' and '<link>'
1634
1635 $dataposted = preg_replace(array('/<html>\n*/ims', '/<\/html>\n*/ims'), array('', ''), $dataposted);
1636 $dataposted = str_replace('<?=', '<?php', $dataposted);
1637
1638 // Html header file
1639 $phpfullcodestringold = '';
1640 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1641
1642 // Security analysis
1643 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1644
1645 if (!$errorphpcheck) {
1646 $htmlheadercontent = '';
1647
1648 /* We disable php code since global htmlheader for all website is never executed as an include but only read by fgets_content.
1649 $htmlheadercontent.= "<?php // BEGIN PHP\n";
1650 $htmlheadercontent.= '$websitekey=basename(__DIR__);'."\n";
1651 $htmlheadercontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load env if not already loaded"."\n";
1652 $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1653 $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1654 $htmlheadercontent.= "ob_start();\n";
1655 // $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page
1656 $htmlheadercontent.= "// END PHP ?>\n";*/
1657
1658 $htmlheadercontent .= $dataposted."\n";
1659
1660 /*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n";
1661 $htmlheadercontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
1662 $htmlheadercontent.= "// END PHP"."\n";*/
1663
1664 $result = dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent);
1665 if (!$result) {
1666 $error++;
1667 setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors');
1668 }
1669 } else {
1670 $error++;
1671 }
1672
1673 $dataposted = trim(GETPOST('WEBSITE_CSS_INLINE', 'none'));
1674 $dataposted = str_replace('<?=', '<?php', $dataposted);
1675
1676 // Css file
1677 $phpfullcodestringold = '';
1678 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1679
1680 // Security analysis
1681 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1682
1683 if (!$errorphpcheck) {
1684 $csscontent = '';
1685
1686 $csscontent .= "<?php // BEGIN PHP\n";
1687 $csscontent .= '$websitekey=basename(__DIR__);'."\n";
1688 $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.
1689 $csscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1690 $csscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1691 $csscontent .= "ob_start();\n";
1692 $csscontent .= "if (! headers_sent()) { /* because file is included inline when in edit mode and we don't want warning */ \n";
1693 $csscontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1694 $csscontent .= "header('Content-type: text/css');\n";
1695 $csscontent .= "}\n";
1696 $csscontent .= "// END PHP ?>\n";
1697
1698 $csscontent .= $dataposted."\n";
1699
1700 $csscontent .= '<?php // BEGIN PHP'."\n";
1701 $csscontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "css");'."\n";
1702 $csscontent .= "// END PHP\n";
1703
1704 dol_syslog("Save css content into ".$filecss);
1705
1706 $result = dolSaveCssFile($filecss, $csscontent);
1707 if (!$result) {
1708 $error++;
1709 setEventMessages('Failed to write file '.$filecss, null, 'errors');
1710 }
1711 } else {
1712 $error++;
1713 }
1714
1715
1716 $dataposted = trim(GETPOST('WEBSITE_JS_INLINE', 'none'));
1717 $dataposted = str_replace('<?=', '<?php', $dataposted);
1718
1719 // Js file
1720 $phpfullcodestringold = '';
1721 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1722
1723 // Security analysis
1724 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1725
1726 if (!$errorphpcheck) {
1727 $jscontent = '';
1728
1729 $jscontent .= "<?php // BEGIN PHP\n";
1730 $jscontent .= '$websitekey=basename(__DIR__);'."\n";
1731 $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.
1732 $jscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1733 $jscontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1734 $jscontent .= "ob_start();\n";
1735 $jscontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1736 $jscontent .= "header('Content-type: application/javascript');\n";
1737 $jscontent .= "// END PHP ?>\n";
1738
1739 $jscontent .= $dataposted."\n";
1740
1741 $jscontent .= '<?php // BEGIN PHP'."\n";
1742 $jscontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "js");'."\n";
1743 $jscontent .= "// END PHP\n";
1744
1745 $result = dolSaveJsFile($filejs, $jscontent);
1746 if (!$result) {
1747 $error++;
1748 setEventMessages('Failed to write file '.$filejs, null, 'errors');
1749 }
1750 } else {
1751 $error++;
1752 }
1753
1754 $dataposted = trim(GETPOST('WEBSITE_ROBOT', 'nohtml'));
1755 $dataposted = str_replace('<?=', '<?php', $dataposted);
1756
1757 // Robot file
1758 $phpfullcodestringold = '';
1759 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1760
1761 // Security analysis
1762 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1763
1764 if (!$errorphpcheck) {
1765 $robotcontent = '';
1766
1767 /*$robotcontent.= "<?php // BEGIN PHP\n";
1768 $robotcontent.= '$websitekey=basename(__DIR__);'."\n";
1769 $robotcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load env if not already loaded"."\n";
1770 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1771 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1772 $robotcontent.= "ob_start();\n";
1773 $robotcontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1774 $robotcontent.= "header('Content-type: text/css');\n";
1775 $robotcontent.= "// END PHP ?>\n";*/
1776
1777 $robotcontent .= $dataposted."\n";
1778
1779 /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n";
1780 $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "robot");'."\n";
1781 $robotcontent.= "// END PHP ?>"."\n";*/
1782
1783 $result = dolSaveRobotFile($filerobot, $robotcontent);
1784 if (!$result) {
1785 $error++;
1786 setEventMessages('Failed to write file '.$filerobot, null, 'errors');
1787 }
1788 } else {
1789 $error++;
1790 }
1791
1792 $dataposted = trim(GETPOST('WEBSITE_HTACCESS', 'nohtml'));
1793 $dataposted = str_replace('<?=', '<?php', $dataposted);
1794
1795 // Htaccess file
1796 $phpfullcodestringold = '';
1797 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1798
1799 // Security analysis
1800 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1801
1802 if (!$errorphpcheck) {
1803 if ($dataposted) {
1804 $htaccesscontent = '';
1805 $htaccesscontent .= $dataposted."\n";
1806
1807 $result = dolSaveHtaccessFile($filehtaccess, $htaccesscontent);
1808 if (!$result) {
1809 $error++;
1810 setEventMessages('Failed to write file '.$filehtaccess, null, 'errors');
1811 }
1812 } else {
1813 dol_delete_file($filehtaccess, 0, 0);
1814 }
1815 } else {
1816 $error++;
1817 }
1818
1819
1820 $dataposted = trim(GETPOST('WEBSITE_MANIFEST_JSON', 'restricthtmlallowunvalid'));
1821 $dataposted = str_replace('<?=', '<?php', $dataposted);
1822
1823 // Manifest.json file
1824 $phpfullcodestringold = '';
1825 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1826
1827 // Security analysis
1828 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1829
1830 if (!$errorphpcheck) {
1831 $manifestjsoncontent = '';
1832
1833 $manifestjsoncontent .= "<?php // BEGIN PHP\n";
1834 $manifestjsoncontent .= '$websitekey=basename(__DIR__);'."\n";
1835 $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.
1836 $manifestjsoncontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1837 $manifestjsoncontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1838 $manifestjsoncontent .= "ob_start();\n";
1839 $manifestjsoncontent .= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1840 $manifestjsoncontent .= "header('Content-type: application/manifest+json');\n";
1841 $manifestjsoncontent .= "// END PHP ?>\n";
1842
1843 $manifestjsoncontent .= $dataposted."\n";
1844
1845 $manifestjsoncontent .= '<?php // BEGIN PHP'."\n";
1846 $manifestjsoncontent .= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1847 $manifestjsoncontent .= "// END PHP\n";
1848
1849 $result = dolSaveManifestJson($filemanifestjson, $manifestjsoncontent);
1850 if (!$result) {
1851 $error++;
1852 setEventMessages('Failed to write file '.$filemanifestjson, null, 'errors');
1853 }
1854 } else {
1855 $error++;
1856 }
1857
1858
1859 $dataposted = trim(GETPOST('WEBSITE_README', 'nohtml'));
1860 $dataposted = str_replace('<?=', '<?php', $dataposted);
1861
1862 // README.md file
1863 $phpfullcodestringold = '';
1864 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1865
1866 // Security analysis
1867 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1868
1869 if (!$errorphpcheck) {
1870 $readmecontent = '';
1871
1872 /*$readmecontent.= "<?php // BEGIN PHP\n";
1873 $readmecontent.= '$websitekey=basename(__DIR__);'."\n";
1874 $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.
1875 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1876 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1877 $readmecontent.= "ob_start();\n";
1878 $readmecontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1879 $readmecontent.= "header('Content-type: application/manifest+json');\n";
1880 $readmecontent.= "// END PHP ?>\n";*/
1881
1882 $readmecontent .= $dataposted."\n";
1883
1884 /*$readmecontent.= '<?php // BEGIN PHP'."\n";
1885 $readmecontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1886 $readmecontent.= "// END PHP ?>"."\n";*/
1887
1888 $result = dolSaveReadme($filereadme, $readmecontent);
1889 if (!$result) {
1890 $error++;
1891 setEventMessages('Failed to write file '.$filereadme, null, 'errors');
1892 }
1893 } else {
1894 $error++;
1895 }
1896
1897
1898 $dataposted = trim(GETPOST('WEBSITE_LICENSE', 'nohtml'));
1899 $dataposted = str_replace('<?=', '<?php', $dataposted);
1900
1901 // LICENSE file
1902 $phpfullcodestringold = '';
1903 $phpfullcodestring = dolKeepOnlyPhpCode($dataposted);
1904
1905 // Security analysis
1906 $errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
1907
1908 if (!$errorphpcheck) {
1909 $licensecontent = '';
1910
1911 /*$readmecontent.= "<?php // BEGIN PHP\n";
1912 $readmecontent.= '$websitekey=basename(__DIR__);'."\n";
1913 $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.
1914 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
1915 $readmecontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
1916 $readmecontent.= "ob_start();\n";
1917 $readmecontent.= "header('Cache-Control: max-age=3600, public, must-revalidate');\n";
1918 $readmecontent.= "header('Content-type: application/manifest+json');\n";
1919 $readmecontent.= "// END PHP ?>\n";*/
1920
1921 $licensecontent .= $dataposted."\n";
1922
1923 /*$readmecontent.= '<?php // BEGIN PHP'."\n";
1924 $readmecontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp, "manifest");'."\n";
1925 $readmecontent.= "// END PHP ?>"."\n";*/
1926
1927 $result = dolSaveLicense($filelicense, $licensecontent);
1928 if (!$result) {
1929 $error++;
1930 setEventMessages('Failed to write file '.$filelicense, null, 'errors');
1931 }
1932 } else {
1933 $error++;
1934 }
1935
1936 // Save wrapper.php
1937 $result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper, $object);
1938
1939
1940 // Message if no error
1941 if (!$error) {
1942 setEventMessages($langs->trans("Saved"), null, 'mesgs');
1943 }
1944
1945 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
1946 $action = 'preview';
1947 if ($backtopage) {
1948 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
1949 header("Location: ".$backtopage);
1950 exit;
1951 }
1952 } else {
1953 $action = 'editcss';
1954 }
1955 }
1956 }
1957}
1958
1959$sourcetype = '';
1960if ($action == "updatesecurity" && $usercanedit && GETPOST("btn_WEBSITE_SECURITY_FORCECSP")) {
1961 $directivecsp = GETPOST("select_identifier_WEBSITE_SECURITY_FORCECSP");
1962 $sourcecsp = GETPOST("select_source_WEBSITE_SECURITY_FORCECSP");
1963 $sourcedatacsp = GETPOST("input_data_WEBSITE_SECURITY_FORCECSP");
1964
1965 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
1966 $directivesarray = websiteGetContentPolicyDirectives();
1967 $sourcesarray = websiteGetContentPolicySources();
1968 if (empty($directivecsp)) {
1969 $error++;
1970 }
1971 if ($error || (!isset($sourcecsp) && $directivesarray[$directivecsp]["data-directivetype"] != "none")) {
1972 $error++;
1973 }
1974 if (!$error) {
1975 $directivetype = $directivesarray[$directivecsp]["data-directivetype"];
1976 if (isset($sourcecsp)) {
1977 $sourcetype = $sourcesarray[$directivetype][$sourcecsp]["data-sourcetype"];
1978 }
1979 $securityspstring = "";
1980 if (isset($sourcetype) && $sourcetype == "data") {
1981 $forceCSPArr[$directivecsp][] = "data:".$sourcedatacsp;
1982 } elseif (isset($sourcetype) && $sourcetype == "input") {
1983 if (empty($forceCSPArr[$directivecsp])) {
1984 $forceCSPArr[$directivecsp] = array();
1985 }
1986 $forceCSPArr[$directivecsp] = array_merge(explode(" ", $sourcedatacsp), $forceCSPArr[$directivecsp]);
1987 } else {
1988 if (empty($forceCSPArr[$directivecsp])) {
1989 $forceCSPArr[$directivecsp] = array();
1990 }
1991 if (!isset($sourcecsp)) {
1992 $sourcecsp = "";
1993 }
1994 array_unshift($forceCSPArr[$directivecsp], $sourcecsp);
1995 }
1996 foreach ($forceCSPArr as $directive => $sourcekeys) {
1997 if ($securityspstring != "") {
1998 $securityspstring .= "; ";
1999 }
2000 $sourcestring = "";
2001 foreach ($sourcekeys as $key => $source) {
2002 $directivetype = $directivesarray[$directive]["data-directivetype"];
2003 $sourcetype = $sourcesarray[$directivetype][$source]["data-sourcetype"];
2004 if (isset($sourcetype) && $sourcetype == "quoted") {
2005 $sourcestring .= " '".$source."'";
2006 } elseif ($directivetype != "none") {
2007 $sourcestring .= " ".$source;
2008 }
2009 }
2010 $securityspstring .= $directive . $sourcestring;
2011 }
2012 $res = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securityspstring, 'chaine', 0, '', $conf->entity);
2013 if ($res <= 0) {
2014 $error++;
2015 }
2016 }
2017
2018 if (!$error) {
2019 $db->commit();
2020 setEventMessages($langs->trans("SecurityPolicySucesfullyAdded"), null, 'mesgs');
2021 } else {
2022 $db->rollback();
2023 setEventMessages($langs->trans("ErrorAddingSecurityPolicy"), null, 'errors');
2024 }
2025 header("Location: ".$_SERVER["PHP_SELF"].'?websiteid='.$websiteid."&action=editsecurity");
2026 exit();
2027}
2028
2029if ($action == "updatesecurity" && $usercanedit) {
2030 $db->begin();
2031 $res1 = $res2 = $res3 = $res4 = 0;
2032 $securityrp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCERP', 'alpha');
2033 $securitysts = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCESTS', 'alpha');
2034 $securitypp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCEPP', 'alpha');
2035 $securitysp = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCECSP', 'alpha');
2036 $securitycspro = GETPOST('WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO', 'alpha');
2037
2038 $res1 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCERP', $securityrp, 'chaine', 0, '', $conf->entity);
2039 $res2 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCESTS', $securitysts, 'chaine', 0, '', $conf->entity);
2040 $res3 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCEPP', $securitypp, 'chaine', 0, '', $conf->entity);
2041 $res4 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securitysp, 'chaine', 0, '', $conf->entity);
2042 $res5 = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSPRO', $securitycspro, 'chaine', 0, '', $conf->entity);
2043
2044 if ($res1 >= 0 && $res2 >= 0 && $res3 >= 0 && $res4 >= 0 && $res5 >= 0) {
2045 $db->commit();
2046 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2047 } else {
2048 $db->rollback();
2049 setEventMessages($langs->trans("ErrorSavingChanges"), null, 'errors');
2050 }
2051
2052 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we don not make the redirect
2053 $action = 'preview';
2054 if ($backtopage) {
2055 $backtopage = preg_replace('/searchstring=[^&]*/', '', $backtopage); // Clean backtopage url
2056 header("Location: ".$backtopage);
2057 exit;
2058 }
2059 } else {
2060 $action = 'editsecurity';
2061 $forceCSP = getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSP");
2062 }
2063}
2064
2065// Update page
2066if ($action == 'setashome' && $usercanedit) {
2067 $db->begin();
2068 $object->fetch(0, $websitekey);
2069 $website = $object;
2070
2071 $object->fk_default_home = $pageid;
2072 $res = $object->update($user);
2073 if (! ($res > 0)) {
2074 $error++;
2075 setEventMessages($object->error, $object->errors, 'errors');
2076 }
2077
2078 if (!$error) {
2079 $db->commit();
2080
2081 $filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
2082
2083 // Generate the index.php page to be the home page
2084 $result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object);
2085
2086 if ($result) {
2087 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2088 } else {
2089 setEventMessages('Failed to write file '.$fileindex, null, 'errors');
2090 }
2091
2092 $action = 'preview';
2093 } else {
2094 $db->rollback();
2095 }
2096}
2097
2098// Update page properties (meta)
2099if ($action == 'updatemeta' && $usercanedit) {
2100 $db->begin();
2101
2102 $result = $object->fetch(0, $websitekey);
2103 $website = $object;
2104
2105 $objectpage->fk_website = $object->id;
2106
2107 // Check parameters
2108 if (!preg_match('/^[a-z0-9\-\_]+$/i', GETPOST('WEBSITE_PAGENAME', 'alpha'))) {
2109 $error++;
2110 $langs->load("errors");
2111 setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors');
2112 $action = 'editmeta';
2113 }
2114
2115 $res = $objectpage->fetch($pageid, (string) $object->id);
2116 if ($res <= 0) {
2117 $error++;
2118 setEventMessages('Page not found '.$objectpage->error, $objectpage->errors, 'errors');
2119 }
2120
2121 // Check alias not exists
2122 if (!$error && GETPOST('WEBSITE_PAGENAME', 'alpha')) {
2123 $websitepagetemp = new WebsitePage($db);
2124 $result = $websitepagetemp->fetch(-1 * $objectpage->id, (string) $object->id, GETPOST('WEBSITE_PAGENAME', 'alpha'));
2125 if ($result < 0) {
2126 $error++;
2127 $langs->load("errors");
2128 setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
2129 $action = 'editmeta';
2130 }
2131 if ($result > 0) {
2132 $error++;
2133 $langs->load("errors");
2134 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
2135 $action = 'editmeta';
2136 }
2137 }
2138
2139 $newaliasnames = '';
2140 if (!$error && GETPOST('WEBSITE_ALIASALT', 'alpha')) {
2141 $arrayofaliastotest = explode(',', str_replace(array('<', '>'), '', GETPOST('WEBSITE_ALIASALT', 'alpha')));
2142
2143 $websitepagetemp = new WebsitePage($db);
2144 foreach ($arrayofaliastotest as $aliastotest) {
2145 $aliastotest = trim(preg_replace('/\.php$/i', '', $aliastotest));
2146
2147 // Disallow alias name pageX (already used to save the page with id)
2148 if (preg_match('/^page\d+/i', $aliastotest)) {
2149 $error++;
2150 $langs->load("errors");
2151 setEventMessages("Alias name 'pageX' is not allowed", null, 'errors');
2152 $action = 'editmeta';
2153 break;
2154 } else {
2155 $result = $websitepagetemp->fetch(-1 * $objectpage->id, (string) $object->id, $aliastotest);
2156 if ($result < 0) {
2157 $error++;
2158 $langs->load("errors");
2159 setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
2160 $action = 'editmeta';
2161 break;
2162 }
2163 if ($result > 0) {
2164 $error++;
2165 $langs->load("errors");
2166 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
2167 $action = 'editmeta';
2168 break;
2169 }
2170 $newaliasnames .= ($newaliasnames ? ', ' : '').$aliastotest;
2171 }
2172 }
2173 }
2174
2175 if (!$error) {
2176 $objectpage->old_object = clone $objectpage;
2177
2178 $objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
2179 $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09');
2180 $objectpage->pageurl = dol_sanitizeUrl(GETPOST('WEBSITE_PAGENAME', 'alpha'));
2181 $objectpage->aliasalt = $newaliasnames;
2182 $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09');
2183 $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
2184 $objectpage->description = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
2185 $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha');
2186 $objectpage->keywords = str_replace(array('<', '>'), '', GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'));
2187 $objectpage->allowed_in_frames = GETPOST('WEBSITE_ALLOWED_IN_FRAMES', 'aZ09') ? 1 : 0;
2188 $objectpage->htmlheader = trim(GETPOST('htmlheader', 'restricthtmlallowlinkscript')); // Must accept tags like '<script>' and '<link>'
2189 $objectpage->fk_page = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
2190 $objectpage->author_alias = trim(GETPOST('WEBSITE_AUTHORALIAS', 'alphanohtml'));
2191 $objectpage->object_type = GETPOST('WEBSITE_OBJECTCLASS', 'alpha');
2192 $objectpage->fk_object = GETPOST('WEBSITE_OBJECTID', 'aZ09');
2193
2194 $newdatecreation = dol_mktime(GETPOSTINT('datecreationhour'), GETPOSTINT('datecreationmin'), GETPOSTINT('datecreationsec'), GETPOSTINT('datecreationmonth'), GETPOSTINT('datecreationday'), GETPOSTINT('datecreationyear'));
2195 if ($newdatecreation) {
2196 $objectpage->date_creation = $newdatecreation;
2197 }
2198
2199 $res = $objectpage->update($user);
2200 if (!($res > 0)) {
2201 $langs->load("errors");
2202 if ($db->lasterrno == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2203 $error++;
2204 setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists"), null, 'errors');
2205 $action = 'editmeta';
2206 } else {
2207 $error++;
2208 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2209 $action = 'editmeta';
2210 }
2211 }
2212 }
2213
2214 if (!$error) {
2215 // Website categories association
2216 $categoriesarray = GETPOST('categories', 'array:int');
2217 $result = $objectpage->setCategories($categoriesarray);
2218 if ($result < 0) {
2219 $error++;
2220 setEventMessages($object->error, $object->errors, 'errors');
2221 }
2222 }
2223
2224 if (!$error) {
2225 $db->commit();
2226 } else {
2227 $db->rollback();
2228 }
2229
2230 if (!$error) {
2231 $filemaster = $pathofwebsite.'/master.inc.php';
2232 $fileoldalias = $pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php';
2233 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
2234
2235 dol_mkdir($pathofwebsite);
2236
2237 // Now generate the master.inc.php page
2238 $result = dolSaveMasterFile($filemaster);
2239 if (!$result) {
2240 setEventMessages('Failed to write file '.$filemaster, null, 'errors');
2241 }
2242
2243 // Now delete the alias.php page
2244 if (!empty($fileoldalias)) {
2245 dol_syslog("We delete old alias page name=".$fileoldalias." to build a new alias page=".$filealias);
2246 dol_delete_file($fileoldalias);
2247
2248 // Delete also pages into language subdirectories
2249 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2250 $dirname = dirname($fileoldalias);
2251 $filename = basename($fileoldalias);
2252 $sublangs = explode(',', $object->otherlang);
2253 foreach ($sublangs as $sublang) {
2254 // Under certain conditions $sublang can be an empty string
2255 // ($object->otherlang with empty string or with string like this 'en,,sv')
2256 // if is the case we try to re-delete the main alias file. Avoid it.
2257 if (empty(trim($sublang))) {
2258 continue;
2259 }
2260 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2261 dol_delete_file($fileoldaliassub);
2262 }
2263 }
2264 }
2265 // Now delete the alternative alias.php pages
2266 if (!empty($objectpage->old_object->aliasalt)) {
2267 $tmpaltaliases = explode(',', $objectpage->old_object->aliasalt);
2268 if (is_array($tmpaltaliases)) {
2269 foreach ($tmpaltaliases as $tmpaliasalt) {
2270 dol_syslog("We delete old alt alias pages name=".trim($tmpaliasalt));
2271 dol_delete_file($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2272
2273 // Delete also pages into language subdirectories
2274 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2275 $dirname = dirname($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2276 $filename = basename($pathofwebsite.'/'.trim($tmpaliasalt).'.php');
2277 $sublangs = explode(',', $object->otherlang);
2278 foreach ($sublangs as $sublang) {
2279 // Under certain conditions $ sublang can be an empty string
2280 // ($object->otherlang with empty string or with string like this 'en,,sv')
2281 // if is the case we try to re-delete the main alias file. Avoid it.
2282 if (empty(trim($sublang))) {
2283 continue;
2284 }
2285 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2286 dol_delete_file($fileoldaliassub);
2287 }
2288 }
2289 }
2290 }
2291 }
2292
2293 // Save page main alias
2294 $result = dolSavePageAlias($filealias, $object, $objectpage);
2295 if (!$result) {
2296 setEventMessages('Failed to write file '.$filealias, null, 'errors');
2297 }
2298 // Save alt aliases
2299 if (!empty($objectpage->aliasalt)) {
2300 $tmpaltaliases = explode(',', $objectpage->aliasalt);
2301 if (is_array($tmpaltaliases)) {
2302 foreach ($tmpaltaliases as $tmpaliasalt) {
2303 if (trim($tmpaliasalt)) {
2304 $filealias = $pathofwebsite.'/'.trim($tmpaliasalt).'.php';
2305 $result = dolSavePageAlias($filealias, $object, $objectpage);
2306 if (!$result) {
2307 setEventMessages('Failed to write file '.basename($filealias), null, 'errors');
2308 }
2309 }
2310 }
2311 }
2312 }
2313
2314
2315 // Save page of content
2316 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
2317 if ($result) {
2318 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2319
2320 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we do not make the redirect
2321 //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2322 //exit;
2323 $action = 'preview';
2324 } else {
2325 $action = 'editmeta';
2326 }
2327 } else {
2328 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
2329 //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2330 //exit;
2331 $action = 'preview';
2332 }
2333 }
2334}
2335
2336// Update page
2337if ((($action == 'updatesource' || $action == 'updatecontent' || $action == 'confirm_createfromclone' || $action == 'confirm_createpagefromclone') || ($action == 'preview' && (GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview')))) && $usercanedit) {
2338 $object->fetch(0, $websitekey);
2339 $website = $object;
2340
2341 if ($action == 'confirm_createfromclone') { // Test on permissions already done
2342 $db->begin();
2343
2344 $objectnew = new Website($db);
2345 $result = $objectnew->createFromClone($user, GETPOSTINT('id'), GETPOST('siteref'), (GETPOSTINT('newlang') ? GETPOSTINT('newlang') : ''));
2346
2347 if ($result < 0) {
2348 $error++;
2349 setEventMessages($objectnew->error, $objectnew->errors, 'errors');
2350 $action = 'preview';
2351
2352 $db->rollback();
2353 } else {
2354 setEventMessages("ObjectClonedSuccessfuly", null, 'mesgs');
2355 $object = $objectnew;
2356 $id = $object->id;
2357 $pageid = $object->fk_default_home;
2358 $websitekey = GETPOST('siteref', 'aZ09');
2359
2360 $db->commit();
2361 }
2362 }
2363
2364 if ($action == 'confirm_createpagefromclone') { // Test on permissions already done
2365 $istranslation = (GETPOST('is_a_translation', 'aZ09') == 'on' ? 1 : 0);
2366 // Protection if it is a translation page
2367 if ($istranslation) {
2368 if (GETPOST('newlang', 'aZ09') == $objectpage->lang || !GETPOST('newlang', 'aZ09')) {
2369 $error++;
2370 setEventMessages($langs->trans("LanguageMustNotBeSameThanClonedPage"), null, 'errors');
2371 $action = 'preview';
2372 }
2373 if (GETPOSTINT('newwebsite') != $object->id) {
2374 $error++;
2375 setEventMessages($langs->trans("WebsiteMustBeSameThanClonedPageIfTranslation"), null, 'errors');
2376 $action = 'preview';
2377 }
2378 }
2379
2380 if (!$error) {
2381 $db->begin();
2382
2383 $newwebsiteid = GETPOSTINT('newwebsite');
2384 $pathofwebsitenew = $pathofwebsite;
2385
2386 $tmpwebsite = new Website($db);
2387 if ($newwebsiteid > 0 && $newwebsiteid != $object->id) {
2388 $tmpwebsite->fetch($newwebsiteid);
2389 $pathofwebsitenew = $dolibarr_main_data_root.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$tmpwebsite->ref;
2390 } else {
2391 $tmpwebsite = $object;
2392 }
2393
2394 $objectpage = new WebsitePage($db);
2395 $resultpage = $objectpage->createFromClone($user, $pageid, GETPOST('newpageurl', 'aZ09'), (GETPOST('newlang', 'aZ09') ? GETPOST('newlang', 'aZ09') : ''), $istranslation, $newwebsiteid, GETPOST('newtitle', 'alphanohtml'), $tmpwebsite);
2396 if ($resultpage < 0) {
2397 $error++;
2398 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2399 $action = 'createpagefromclone';
2400
2401 $db->rollback();
2402 } else {
2403 $filetpl = $pathofwebsitenew.'/page'.$resultpage->id.'.tpl.php';
2404 $fileindex = $pathofwebsitenew.'/index.php';
2405 $filewrapper = $pathofwebsitenew.'/wrapper.php';
2406
2407 //var_dump($pathofwebsitenew);
2408 //var_dump($filetpl);
2409 //exit;
2410
2411 dolSavePageContent($filetpl, $tmpwebsite, $resultpage, 1);
2412
2413 // Switch on the new page if web site of new page/container is same
2414 if (empty($newwebsiteid) || $newwebsiteid == $object->id) {
2415 $pageid = $resultpage->id;
2416 }
2417
2418 $db->commit();
2419 }
2420 }
2421 }
2422
2423 $res = 0;
2424
2425 if (!$error) {
2426 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2427 // Recreate also dir of website if not found.
2428 $pathtomedias = DOL_DATA_ROOT.'/medias';
2429 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2430 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2431 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2432 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
2433 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2434 if (!$result) {
2435 $langs->load("errors");
2436 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2437 }
2438 }
2439
2440 /*if (GETPOST('savevirtualhost') && $object->virtualhost != GETPOST('previewsite'))
2441 {
2442 $object->virtualhost = GETPOST('previewsite', 'alpha');
2443 $object->update($user);
2444 }*/
2445
2446 $objectpage->fk_website = $object->id;
2447
2448 if ($pageid > 0) {
2449 $res = $objectpage->fetch($pageid);
2450 } else {
2451 $res = 0;
2452 if ($object->fk_default_home > 0) {
2453 $res = $objectpage->fetch($object->fk_default_home);
2454 }
2455 if (!($res > 0)) {
2456 $res = $objectpage->fetch(0, (string) $object->id);
2457 }
2458 }
2459 }
2460
2461 if (!$error && $res > 0) {
2462 if ($action == 'updatesource' || $action == 'updatecontent') { // Test on permissions already done
2463 $db->begin();
2464
2465 $phpfullcodestringold = dolKeepOnlyPhpCode($objectpage->content);
2466
2467 $objectpage->content = GETPOST('PAGE_CONTENT', 'none'); // any HTML content allowed
2468
2469 $phpfullcodestring = dolKeepOnlyPhpCode($objectpage->content);
2470
2471 // Security analysis (check PHP content and check permission website->writephp if php content is modified)
2472 $error = checkPHPCode($phpfullcodestringold, $phpfullcodestring);
2473
2474 if ($error) {
2475 if ($action == 'updatesource') { // Test on permissions already done
2476 $action = 'editsource';
2477 }
2478 if ($action == 'updatecontent') { // Test on permissions already done
2479 $action = 'editcontent';
2480 }
2481 }
2482
2483 // Clean data. We remove all the head section.
2484 $objectpage->content = preg_replace('/<head>.*<\/head>/ims', '', $objectpage->content);
2485 /* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */
2486
2487
2488 $res = $objectpage->update($user);
2489 if ($res < 0) {
2490 $error++;
2491 setEventMessages($objectpage->error, $objectpage->errors, 'errors');
2492 if ($action == 'updatesource') { // Test on permissions already done
2493 $action = 'editsource';
2494 }
2495 if ($action == 'updatecontent') { // Test on permissions already done
2496 $action = 'editcontent';
2497 }
2498 }
2499
2500 if (!$error) {
2501 $db->commit();
2502
2503 $filemaster = $pathofwebsite.'/master.inc.php';
2504 //$fileoldalias=$pathofwebsite.'/'.$objectpage->old_object->pageurl.'.php';
2505 $filealias = $pathofwebsite.'/'.$objectpage->pageurl.'.php';
2506
2507 dol_mkdir($pathofwebsite);
2508
2509 // Now generate the master.inc.php page
2510 $result = dolSaveMasterFile($filemaster);
2511
2512 if (!$result) {
2513 setEventMessages('Failed to write the master file file '.$filemaster, null, 'errors');
2514 }
2515
2516 // Now delete the old alias.php page if we removed one
2517 /*if (!empty($fileoldalias))
2518 {
2519 dol_syslog("We regenerate alias page new name=".$filealias.", old name=".$fileoldalias);
2520 dol_delete_file($fileoldalias);
2521
2522 // Delete also pages into language subdirectories
2523 if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
2524 $dirname = dirname($fileoldalias);
2525 $filename = basename($fileoldalias);
2526 $sublangs = explode(',', $object->otherlang);
2527 foreach ($sublangs as $sublang) {
2528 $fileoldaliassub = $dirname.'/'.$sublang.'/'.$filename;
2529 dol_delete_file($fileoldaliassub);
2530 }
2531 }
2532 }*/
2533
2534 // Save page alias
2535 $result = dolSavePageAlias($filealias, $object, $objectpage);
2536 if (!$result) {
2537 setEventMessages('Failed to write the alias file '.basename($filealias), null, 'errors');
2538 }
2539
2540 // Save page content
2541 $result = dolSavePageContent($filetpl, $object, $objectpage, 1);
2542 if ($result) {
2543 setEventMessages($langs->trans("Saved"), null, 'mesgs');
2544
2545 if (!GETPOSTISSET('updateandstay')) { // If we click on "Save And Stay", we do not make the redirect
2546 if ($backtopage) {
2547 header("Location: ".$backtopage);
2548 exit;
2549 } else {
2550 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2551 exit;
2552 }
2553 } else {
2554 if ($action == 'updatesource') { // Test on permissions already done
2555 $action = 'editsource';
2556 }
2557 if ($action == 'updatecontent') { // Test on permissions already done
2558 $action = 'editcontent';
2559 }
2560 }
2561 } else {
2562 setEventMessages('Failed to write file '.$filetpl, null, 'errors');
2563 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2564 exit;
2565 }
2566 } else {
2567 $db->rollback();
2568 }
2569 } else {
2570 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
2571 exit;
2572 }
2573 } else {
2574 if (!$error) {
2575 if (empty($websitekey) || $websitekey == '-1') {
2576 setEventMessages($langs->trans("NoWebSiteCreateOneFirst"), null, 'warnings');
2577 } else {
2578 setEventMessages($langs->trans("NoPageYet"), null, 'warnings');
2579 setEventMessages($langs->trans("YouCanCreatePageOrImportTemplate"), null, 'warnings');
2580 }
2581 }
2582 }
2583}
2584
2585if ($action == 'deletelang' && $usercanedit) {
2586 $sql = "UPDATE ".MAIN_DB_PREFIX."website_page SET fk_page = NULL";
2587 $sql .= " WHERE rowid = ".GETPOSTINT('deletelangforid');
2588 //$sql .= " AND fk_page = ".((int) $objectpage->id);
2589
2590 $resql = $db->query($sql);
2591 if (!$resql) {
2592 setEventMessages($db->lasterror(), null, 'errors');
2593 } else {
2594 $objectpage->fk_page = null;
2595 }
2596
2597 $action = 'editmeta';
2598}
2599
2600
2601// Export site
2602if ($action == 'exportsite' && $user->hasRight('website', 'export')) {
2603 $fileofzip = $object->exportWebSite();
2604
2605 if ($fileofzip) {
2606 $file_name = basename($fileofzip);
2607 header("Content-Type: application/zip");
2608 header("Content-Disposition: attachment; filename=".$file_name);
2609 header("Content-Length: ".filesize($fileofzip));
2610
2611 readfile($fileofzip);
2612 exit;
2613 } else {
2614 setEventMessages($object->error, $object->errors, 'errors');
2615 $action = 'preview';
2616 }
2617}
2618
2619// Overwrite site
2620if ($action == 'overwritesite' && $user->hasRight('website', 'export')) {
2621 if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) {
2622 // Generate a zip of the website
2623 $fileofzip = $object->exportWebSite();
2624 $pathToExport = GETPOST('export_path');
2625 if ($fileofzip) {
2626 // Uncompress the exported web site into a destination directory
2627 $result = $object->overwriteTemplate($fileofzip, $pathToExport);
2628 if ($result < 0) {
2629 setEventMessages($object->error, $object->errors, 'errors');
2630 $action = 'preview';
2631 }
2632 } else {
2633 setEventMessages($object->error, $object->errors, 'errors');
2634 $action = 'preview';
2635 }
2636 }
2637}
2638// Regenerate site
2639if ($action == 'regeneratesite' && $usercanedit) {
2640 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2641 // Recreate also dir of website if not found.
2642 $pathtomedias = DOL_DATA_ROOT.'/medias';
2643 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2644 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2645 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2646 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure that the directory for website exists
2647 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2648 if (!$result) {
2649 $langs->load("errors");
2650 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2651 $action = 'preview';
2652 }
2653 }
2654
2655 $result = $object->rebuildWebSiteFiles();
2656 if ($result > 0) {
2657 setEventMessages($langs->trans("PagesRegenerated", $result), null, 'mesgs');
2658 $action = 'preview';
2659 } else {
2660 setEventMessages($object->error, $object->errors, 'errors');
2661 $action = 'preview';
2662 }
2663}
2664
2665// Import site
2666if ($action == 'importsiteconfirm' && $usercanedit) {
2667 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
2668 $allowimportsite = true;
2669 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
2670 $allowimportsite = false;
2671 }
2672
2673 if ($allowimportsite) {
2674 if (empty($_FILES) && !GETPOSTISSET('templateuserfile')) {
2675 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
2676 $action = 'importsite';
2677 } else {
2678 if (!empty($_FILES) || GETPOSTISSET('templateuserfile')) {
2679 // Check symlink documents/website/mywebsite/medias to point to documents/medias and restore it if ko.
2680 // Recreate also dir of website if not found.
2681 $pathtomedias = DOL_DATA_ROOT.'/medias';
2682 $pathtomediasinwebsite = $pathofwebsite.'/medias';
2683 if (!is_link(dol_osencode($pathtomediasinwebsite))) {
2684 dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
2685 dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
2686 $result = symlink($pathtomedias, $pathtomediasinwebsite);
2687 if (!$result) {
2688 $langs->load("errors");
2689 setEventMessages($langs->trans("ErrorFailedToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
2690 $action = 'importsite';
2691 }
2692 }
2693
2694 $fileofzip = '';
2695 if (GETPOSTISSET('templateuserfile')) {
2696 // Case we selected one template
2697 $fileofzip = DOL_DATA_ROOT.'/doctemplates/websites/'.GETPOST('templateuserfile', 'alpha'); // $fileofzip will be sanitized later into the importWebSite()
2698 } elseif (!empty($_FILES) && is_array($_FILES['userfile'])) {
2699 // Case we upload a new template
2700 if (is_array($_FILES['userfile']['tmp_name'])) {
2701 $userfiles = $_FILES['userfile']['tmp_name'];
2702 } else {
2703 $userfiles = array($_FILES['userfile']['tmp_name']);
2704 }
2705
2706 // Check if $_FILES is ok
2707 foreach ($userfiles as $key => $userfile) {
2708 if (empty($_FILES['userfile']['tmp_name'][$key])) {
2709 $error++;
2710 if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2) {
2711 setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
2712 $action = 'importsite';
2713 } else {
2714 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
2715 $action = 'importsite';
2716 }
2717 }
2718 }
2719
2720 if (!$error) {
2721 //$upload_dir = $conf->website->dir_temp;
2722 $upload_dir = DOL_DATA_ROOT.'/doctemplates/websites/';
2723 $result = dol_add_file_process($upload_dir, 1, -1, 'userfile', '');
2724 }
2725
2726 // Get name of file (take last one if several name provided)
2727 /*
2728 $fileofzip = $upload_dir.'/unknown';
2729 foreach ($_FILES as $key => $ifile) {
2730 foreach ($ifile['name'] as $key2 => $ifile2) {
2731 $fileofzip = $upload_dir.'/'.$ifile2;
2732 }
2733 }
2734 */
2735
2736 $action = 'importsite';
2737 }
2738
2739 if (!$error && GETPOSTISSET('templateuserfile')) {
2740 $templatewithoutzip = preg_replace('/\.zip$/i', '', GETPOST('templateuserfile'));
2741 $object->setTemplateName($templatewithoutzip);
2742
2743 $result = $object->importWebSite($fileofzip);
2744
2745 if ($result < 0) {
2746 setEventMessages($object->error, $object->errors, 'errors');
2747 $action = 'importsite';
2748 } else {
2749 // Force mode dynamic on
2750 dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1, 'chaine', 0, '', $conf->entity);
2751
2752 header("Location: ".$_SERVER["PHP_SELF"].'?website='.$object->ref);
2753 exit();
2754 }
2755 }
2756 }
2757 }
2758 } else {
2759 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
2760 // Show clean corporate message
2761 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
2762 } else {
2763 // Show technical generic message
2764 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
2765 }
2766 setEventMessages($message, null, 'errors');
2767 }
2768}
2769
2770$domainname = '0.0.0.0:8080';
2771$tempdir = $conf->website->dir_output.'/'.$websitekey.'/';
2772
2773// Generate web site sitemaps
2774if ($action == 'generatesitemaps' && $usercanedit) {
2775 // Define $domainname
2776 if ($website->virtualhost) {
2777 $domainname = $website->virtualhost;
2778 }
2779 if (! preg_match('/^http/i', $domainname)) {
2780 $domainname = 'https://'.$domainname;
2781 }
2782
2783 $domtree = new DOMDocument('1.0', 'UTF-8');
2784
2785 $root = $domtree->createElementNS('http://www.sitemaps.org/schemas/sitemap/0.9', 'urlset');
2786 $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
2787
2788 $domtree->formatOutput = true;
2789
2790 $addrsswrapper = 0;
2791 $xmlname = 'sitemap.xml';
2792
2793 $sql = "SELECT wp.rowid, wp.type_container , wp.pageurl, wp.lang, wp.fk_page, wp.tms as tms,";
2794 $sql .= " w.virtualhost, w.fk_default_home";
2795 $sql .= " FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
2796 $sql .= " WHERE wp.type_container IN ('page', 'blogpost')";
2797 $sql .= " AND wp.fk_website = w.rowid";
2798 $sql .= " AND wp.status = ".WebsitePage::STATUS_VALIDATED;
2799 $sql .= " AND wp.pageurl NOT IN ('404', '500', '501', '503')";
2800 $sql .= " AND w.ref = '".dol_escape_json($websitekey)."'";
2801 $sql .= " ORDER BY wp.tms DESC, wp.rowid DESC";
2802 $resql = $db->query($sql);
2803 if ($resql) {
2804 $num_rows = $db->num_rows($resql);
2805 if ($num_rows > 0) {
2806 $i = 0;
2807 while ($i < $num_rows) {
2808 $objp = $db->fetch_object($resql);
2809 $url = $domtree->createElement('url');
2810
2811 $shortlangcode = '';
2812 if ($objp->lang) {
2813 $shortlangcode = substr($objp->lang, 0, 2); // en_US or en-US -> en
2814 }
2815 if (empty($shortlangcode)) {
2816 $shortlangcode = substr($object->lang, 0, 2); // Use short lang code of website
2817 }
2818
2819 // Is it a blog post for the RSS wrapper ?
2820 if ($objp->type_container == 'blogpost') {
2821 $addrsswrapper = 1;
2822 }
2823
2824 // Forge $pageurl, adding language prefix if it is an alternative language
2825 $pageurl = $objp->pageurl.'.php';
2826 if ($objp->fk_default_home == $objp->rowid) {
2827 $pageurl = '';
2828 } else {
2829 if ($shortlangcode != substr($object->lang, 0, 2)) {
2830 $pageurl = $shortlangcode.'/'.$pageurl;
2831 }
2832 }
2833
2834 //$pathofpage = $dolibarr_main_url_root.'/'.$pageurl.'.php';
2835
2836 // URL of sitemaps must end with trailing slash if page is ''
2837 $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl);
2838 $lastmod = $domtree->createElement('lastmod', dol_print_date($db->jdate($objp->tms), 'dayrfc', 'gmt'));
2839 $priority = $domtree->createElement('priority', '1');
2840
2841 $url->appendChild($loc);
2842 $url->appendChild($lastmod);
2843 // Add suggested frequency for refresh
2844 if (getDolGlobalString('WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ')) {
2845 $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values
2846 $url->appendChild($changefreq);
2847 }
2848 // Add higher priority for home page
2849 if ($objp->fk_default_home == $objp->rowid) {
2850 $url->appendChild($priority);
2851 }
2852
2853 // Now add alternate language entries
2854 if ($object->isMultiLang()) {
2855 $alternatefound = 0;
2856
2857 // Add page "translation of"
2858 $translationof = $objp->fk_page;
2859 if ($translationof) {
2860 $tmppage = new WebsitePage($db);
2861 $tmppage->fetch($translationof);
2862 if ($tmppage->id > 0) {
2863 $tmpshortlangcode = '';
2864 if ($tmppage->lang) {
2865 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en
2866 }
2867 if (empty($tmpshortlangcode)) {
2868 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $object->lang); // en_US or en-US -> en
2869 }
2870 if ($tmpshortlangcode != $shortlangcode) {
2871 $xhtmllink = $domtree->createElement('xhtml:link', '');
2872 $xhtmllink->setAttribute("rel", "alternate");
2873 $xhtmllink->setAttribute("hreflang", $tmpshortlangcode);
2874 $xhtmllink->setAttribute("href", $domainname.($objp->fk_default_home == $tmppage->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2)) ? '/'.$tmpshortlangcode : '').'/'.$tmppage->pageurl.'.php'));
2875 $url->appendChild($xhtmllink);
2876
2877 $alternatefound++;
2878 }
2879 }
2880 }
2881
2882 // Add "has translation pages"
2883 $sql = 'SELECT rowid as id, lang, pageurl from '.MAIN_DB_PREFIX.'website_page';
2884 $sql .= " WHERE status = ".((int) WebsitePage::STATUS_VALIDATED).' AND fk_page IN ('.$db->sanitize($objp->rowid.($translationof ? ", ".$translationof : "")).")";
2885 $resqlhastrans = $db->query($sql);
2886 if ($resqlhastrans) {
2887 $num_rows_hastrans = $db->num_rows($resqlhastrans);
2888 if ($num_rows_hastrans > 0) {
2889 while ($objhastrans = $db->fetch_object($resqlhastrans)) {
2890 $tmpshortlangcode = '';
2891 if ($objhastrans->lang) {
2892 $tmpshortlangcode = preg_replace('/[_-].*$/', '', $objhastrans->lang); // en_US or en-US -> en
2893 }
2894 if ($tmpshortlangcode != $shortlangcode) {
2895 $xhtmllink = $domtree->createElement('xhtml:link', '');
2896 $xhtmllink->setAttribute("rel", "alternate");
2897 $xhtmllink->setAttribute("hreflang", $tmpshortlangcode);
2898 $xhtmllink->setAttribute("href", $domainname.($objp->fk_default_home == $objhastrans->id ? '/' : (($tmpshortlangcode != substr($object->lang, 0, 2) ? '/'.$tmpshortlangcode : '')).'/'.$objhastrans->pageurl.'.php'));
2899 $url->appendChild($xhtmllink);
2900
2901 $alternatefound++;
2902 }
2903 }
2904 }
2905 } else {
2906 dol_print_error($db);
2907 }
2908
2909 if ($alternatefound) {
2910 // Add myself
2911 $xhtmllink = $domtree->createElement('xhtml:link', '');
2912 $xhtmllink->setAttribute("rel", "alternate");
2913 $xhtmllink->setAttribute("hreflang", $shortlangcode);
2914 $xhtmllink->setAttribute("href", $domainname.'/'.$pageurl);
2915 $url->appendChild($xhtmllink);
2916 }
2917 }
2918
2919 // Now add sitempas extension for news
2920 // TODO When adding and when not ?
2921 /*<news:news>
2922 <news:publication>
2923 <news:name>The Example Times</news:name>
2924 <news:language>en</news:language>
2925 </news:publication>
2926 <news:publication_date>2008-12-23</news:publication_date>
2927 <news:title>Companies A, B in Merger Talks</news:title>
2928 </news:news>
2929 */
2930
2931 $root->appendChild($url);
2932 $i++;
2933 }
2934
2935 // Adding a RSS feed into a sitemap should not be required. The RSS contains pages that are already included into
2936 // the sitemap and RSS feeds are not shown into index.
2937 if ($addrsswrapper && getDolGlobalInt('WEBSITE_ADD_RSS_FEED_INTO_SITEMAP')) {
2938 $url = $domtree->createElement('url');
2939
2940 $pageurl = 'wrapper.php?rss=1';
2941
2942 // URL of sitemaps must end with trailing slash if page is ''
2943 $loc = $domtree->createElement('loc', $domainname.'/'.$pageurl);
2944 $lastmod = $domtree->createElement('lastmod', dol_print_date(dol_now(), 'dayrfc', 'gmt'));
2945
2946 $url->appendChild($loc);
2947 $url->appendChild($lastmod);
2948 // Add suggested frequency for refresh
2949 if (getDolGlobalString('WEBSITE_SITEMAPS_ADD_WEEKLY_FREQ')) {
2950 $changefreq = $domtree->createElement('changefreq', 'weekly'); // TODO Manage other values
2951 $url->appendChild($changefreq);
2952 }
2953
2954 $root->appendChild($url);
2955 }
2956
2957 $domtree->appendChild($root);
2958
2959 if ($domtree->save($tempdir.$xmlname)) {
2960 dolChmod($tempdir.$xmlname);
2961 setEventMessages($langs->trans("SitemapGenerated", $xmlname), null, 'mesgs');
2962 } else {
2963 setEventMessages($object->error, $object->errors, 'errors');
2964 }
2965 }
2966 } else {
2967 dol_print_error($db);
2968 }
2969
2970 // Add the entry Sitemap: into the robot.txt file.
2971 $robotcontent = @file_get_contents($filerobot);
2972 $result = preg_replace('/<?php \/\/ BEGIN PHP[^?]END PHP ?>\n/ims', '', $robotcontent);
2973 if ($result) {
2974 $robotcontent = $result;
2975 }
2976 $robotsitemap = "Sitemap: ".$domainname."/".$xmlname;
2977 $result = strpos($robotcontent, 'Sitemap: ');
2978 if ($result) {
2979 $result = preg_replace('/Sitemap:.*/', $robotsitemap, $robotcontent);
2980 $robotcontent = $result ? $result : $robotcontent;
2981 } else {
2982 $robotcontent .= $robotsitemap."\n";
2983 }
2984 $result = dolSaveRobotFile($filerobot, $robotcontent);
2985 if (!$result) {
2986 $error++;
2987 setEventMessages('Failed to write file '.$filerobot, null, 'errors');
2988 }
2989 $action = 'preview';
2990}
2991
2992if ($action == 'removecspsource' && $usercanedit) {
2993 $db->begin();
2994 $sourcetype = "";
2995 $sourcecsp = explode("_", GETPOST("sourcecsp"));
2996 $directive = $sourcecsp[0];
2997 $sourcekey = isset($sourcecsp[1]) ? $sourcecsp[1] : null;
2998 $sourcedata = isset($sourcecsp[2]) ? $sourcecsp[2] : null;
2999 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
3000 $directivesarray = websiteGetContentPolicyDirectives();
3001 $sourcesarray = websiteGetContentPolicySources();
3002 if (empty($directive)) {
3003 $error++;
3004 }
3005
3006 if (!empty($directivesarray[$directive])) {
3007 $directivetype = (string) $directivesarray[$directive]["data-directivetype"];
3008 if (isset($sourcekey)) {
3009 $sourcetype = $sourcesarray[$directivetype][$sourcekey]["data-sourcetype"];
3010 }
3011 }
3012
3013 $securityspstring = "";
3014 if (!$error && !empty($forceCSPArr)) {
3015 if (isset($sourcekey) && !empty($forceCSPArr[$directive][$sourcekey])) {
3016 unset($forceCSPArr[$directive][$sourcekey]);
3017 }
3018 if (count($forceCSPArr[$directive]) == 0) {
3019 unset($forceCSPArr[$directive]);
3020 }
3021 foreach ($forceCSPArr as $directive => $sourcekeys) {
3022 if ($securityspstring != "") {
3023 $securityspstring .= "; ";
3024 }
3025 $sourcestring = "";
3026 foreach ($sourcekeys as $key => $source) {
3027 $directivetype = $directivesarray[$directive]["data-directivetype"];
3028 $sourcetype = $sourcesarray[$directivetype][$source]["data-sourcetype"];
3029 if ($sourcetype == "quoted") {
3030 $sourcestring .= " '".$source."'";
3031 } else {
3032 $sourcestring .= " ".$source;
3033 }
3034 }
3035 $securityspstring .= $directive . $sourcestring;
3036 }
3037 $res = dolibarr_set_const($db, 'WEBSITE_'.$object->id.'_SECURITY_FORCECSP', $securityspstring, 'chaine', 0, '', $conf->entity);
3038 if ($res <= 0) {
3039 $error++;
3040 }
3041 }
3042
3043 if (!$error) {
3044 $db->commit();
3045 setEventMessages($langs->trans("SecurityPolicySucesfullyRemoved"), null, 'mesgs');
3046 } else {
3047 $db->rollback();
3048 setEventMessages($langs->trans("ErrorRemovingSecurityPolicy"), null, 'errors');
3049 }
3050
3051 header("Location: ".$_SERVER["PHP_SELF"].'?websiteid='.$websiteid."&action=editsecurity");
3052 exit();
3053}
3054
3055
3056/*
3057 * View
3058 */
3059
3060$form = new Form($db);
3061$formadmin = new FormAdmin($db);
3062$formwebsite = new FormWebsite($db);
3063$formother = new FormOther($db);
3064$formconfirm = "";
3065
3066// Confirm generation of website sitemaps
3067if ($action == 'confirmgeneratesitemaps') {
3068 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.urlencode($website->ref), $langs->trans('ConfirmSitemapsCreation'), $langs->trans('ConfirmGenerateSitemaps', $object->ref), 'generatesitemaps', '', "yes", 1);
3069 $action = 'preview';
3070}
3071$helpurl = 'EN:Module_Website|FR:Module_Website_FR|ES:M&oacute;dulo_Website';
3072
3073$arrayofjs = array(
3074 '/includes/ace/src/ace.js',
3075 '/includes/ace/src/ext-statusbar.js',
3076 '/includes/ace/src/ext-language_tools.js',
3077 //'/includes/ace/src/ext-chromevox.js'
3078);
3079$arrayofcss = array();
3080
3081if (!getDolGlobalString('MAIN_ECM_DISABLE_JS')) {
3082 $arrayofjs[] = "public/includes/jquery/plugins/jqueryFileTree/jqueryFileTree.js";
3083}
3084
3085llxHeader('', $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" spellcheck="false">');
3086
3087print "\n";
3088print '<!-- Open form common to all pages generated by website/index.php -->'."\n";
3089print '<form action="'.$_SERVER["PHP_SELF"].($action == 'file_manager' ? '?uploadform=1' : '').'" method="POST" enctype="multipart/form-data" class="websiteformtoolbar">'."\n";
3090print '<input type="hidden" name="token" value="'.newToken().'">';
3091print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
3092print '<input type="hidden" name="dol_openinpopup" value="'.$dol_openinpopup.'">';
3093
3094if ($action == 'createsite') {
3095 print '<input type="hidden" name="action" value="addsite">';
3096}
3097if ($action == 'createcontainer') {
3098 print '<input type="hidden" name="action" value="addcontainer">';
3099}
3100if ($action == 'editcss') {
3101 print '<input type="hidden" name="action" value="updatecss">';
3102}
3103if ($action == 'editmenu') {
3104 print '<input type="hidden" name="action" value="updatemenu">';
3105}
3106if ($action == 'setashome') {
3107 print '<input type="hidden" name="action" value="updateashome">';
3108}
3109if ($action == 'editmeta') {
3110 print '<input type="hidden" name="action" value="updatemeta">';
3111}
3112if ($action == 'editsource') {
3113 print '<input type="hidden" name="action" value="updatesource">';
3114}
3115if ($action == 'editcontent') {
3116 print '<input type="hidden" name="action" value="updatecontent">';
3117}
3118if ($action == 'edit') {
3119 print '<input type="hidden" name="action" value="update">';
3120}
3121if ($action == 'importsite') {
3122 print '<input type="hidden" name="action" value="importsiteconfirm">';
3123}
3124if ($action == 'file_manager') {
3125 print '<input type="hidden" name="action" value="file_manager">';
3126}
3127if ($mode) {
3128 print '<input type="hidden" name="mode" value="'.$mode.'">';
3129}
3130if ($action == 'editsecurity') {
3131 print '<input type="hidden" name="action" value="updatesecurity">';
3132}
3133
3134print '<div>'."\n";
3135
3136// Add a margin under toolbar ?
3137$style = '';
3138if ($action != 'preview' && $action != 'editcontent' && $action != 'editsource' && !GETPOST('createpagefromclone', 'alphanohtml')) {
3139 $style = ' margin-bottom: 5px;';
3140}
3141
3142
3143$websitepage = null;
3144$disabled = '';
3145if (!GETPOST('hide_websitemenu')) {
3146 if (!$user->hasRight('website', 'write')) {
3147 $disabled = ' disabled="disabled"';
3148 }
3149 $disabledexport = '';
3150 if (!$user->hasRight('website', 'export')) {
3151 $disabledexport = ' disabled="disabled"';
3152 }
3153
3154 if ($websitekey) {
3155 $virtualurl = '';
3156 $dataroot = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$websitekey;
3157 if (!empty($object->virtualhost)) {
3158 $virtualurl = $object->virtualhost;
3159 }
3160 }
3161
3162 $array = array();
3163 if ($object->id > 0) {
3164 $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
3165 $object->lines = $array;
3166 }
3167 if (!is_array($array) && $array < 0) {
3168 dol_print_error(null, $objectpage->error, $objectpage->errors);
3169 }
3170 $atleastonepage = (is_array($array) && count($array) > 0);
3171
3172 $websitepage = new WebsitePage($db);
3173 if ($pageid > 0) {
3174 $websitepage->fetch($pageid);
3175 }
3176
3177
3178 $disabled = '';
3179 $morecss = '';
3180 if (!$user->hasRight('website', 'write')) {
3181 $disabled = ' disabled="disabled"';
3182 $morecss = 'opacitymedium cursordefault';
3183 }
3184
3185 //var_dump($objectpage);exit;
3186 print '<div class="centpercent websitebar'.(GETPOST('dol_openinpopup', 'aZ09') ? ' hiddenforpopup' : '').'">'."\n";
3187
3188 //
3189 // Toolbar for websites
3190 //
3191
3192 print '<!-- Toolbar for website -->';
3193 if ($action != 'file_manager') {
3194 print '<div class="websiteselection hideonsmartphoneimp minwidth75 tdoverflowmax100 inline-block">';
3195 print $langs->trans("Website").': ';
3196 print '</div>';
3197
3198 // Button Add new website
3199 $urltocreatenewwebsite = $_SERVER["PHP_SELF"].'?action=createsite';
3200 if ($user->hasRight('website', 'write')) {
3201 print '<span class="websiteselection paddingrightonly">';
3202 print '<a href="'.$urltocreatenewwebsite.'" class=""'.$disabled.' title="'.dol_escape_htmltag($langs->trans("AddWebsite")).'"><span class="fa fa-plus-circle valignmiddle btnTitle-icon"><span></a>';
3203 print '</span>';
3204 }
3205
3206 // List of website
3207 print '<span class="websiteselection nopaddingrightimp">';
3208
3209 $out = '';
3210 $out .= '<select name="website" class="minwidth100 width200 maxwidth150onsmartphone" id="website">';
3211 if (empty($listofwebsites)) {
3212 $out .= '<option value="-1">&nbsp;</option>';
3213 }
3214
3215 // Loop on each sites
3216 $i = 0;
3217 foreach ($listofwebsites as $key => $valwebsite) {
3218 if (empty($websitekey)) {
3219 if ($action != 'createsite') {
3220 $websitekey = $valwebsite->ref;
3221 }
3222 }
3223
3224 $out .= '<option value="'.$valwebsite->ref.'"';
3225 if ($websitekey == $valwebsite->ref) {
3226 $out .= ' selected'; // To preselect a value
3227 }
3228 //$outoption = $valwebsite->getLibStatut(3).' '.$valwebsite->ref.' ';
3229 $outoption = (($valwebsite->status == $valwebsite::STATUS_DRAFT) ? '<span class="opacitymedium">' : '').$valwebsite->ref.(($valwebsite->status == $valwebsite::STATUS_DRAFT) ? '</span>' : '');
3230 $out .= ' data-html="'.dol_escape_htmltag($outoption).'"';
3231 $out .= '>';
3232 $out .= $valwebsite->ref;
3233 $out .= '</option>';
3234 $i++;
3235 }
3236 $out .= '</select>';
3237 $out .= ajax_combobox('website');
3238
3239 if (!empty($conf->use_javascript_ajax)) {
3240 $out .= '<script type="text/javascript">';
3241 $out .= 'jQuery(document).ready(function () {';
3242 $out .= ' jQuery("#website").change(function () {';
3243 $out .= ' console.log("We select "+jQuery("#website option:selected").val());';
3244 $out .= ' if (jQuery("#website option:selected").val() == \'-2\') {';
3245 $out .= ' window.location.href = \''.dol_escape_js($urltocreatenewwebsite).'\';';
3246 $out .= ' } else {';
3247 $out .= ' window.location.href = "'.$_SERVER["PHP_SELF"].'?website="+jQuery("#website option:selected").val();';
3248 $out .= ' }';
3249 $out .= ' });';
3250 $out .= '});';
3251 $out .= '</script>';
3252 }
3253 print $out;
3254
3255 print '</span>';
3256
3257 // Switch offline/onine
3258 if (!empty($conf->use_javascript_ajax)) {
3259 print '<span class="websiteselection">';
3260 // Do not use ajax, we need a refresh of full page when we change status of a website
3261 //print '<div class="inline-block marginrightonly">';
3262 //print ajax_object_onoff($object, 'status', 'status', 'Online', 'Offline', array(), 'valignmiddle inline-block', 'statuswebsite');
3263 //print '</div>';
3264 if ($website->status == $website::STATUS_DRAFT) {
3265 $text_off = 'Offline';
3266 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>';
3267 } else {
3268 $text_off = 'Online';
3269 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>';
3270 }
3271 print '</span>';
3272 }
3273
3274 // Refresh / Reload web site (for non javascript browsers)
3275 if (empty($conf->use_javascript_ajax)) {
3276 print '<span class="websiteselection">';
3277 print '<input type="image" class="valignmiddle" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshsite" value="'.$langs->trans("Load").'"'.$disabled.'>';
3278 print '</span>';
3279 }
3280
3281
3282 print '<span class="websiteselection">';
3283
3284 if ($websitekey && $websitekey != '-1' && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3285 // Edit website properties
3286 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.'>';
3287 print img_picto('', 'setup');
3288 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans("EditCss")).'</span>';
3289 print '</a>';
3290
3291 // Import web site
3292 $importlabel = $langs->trans("ImportSite");
3293 $exportlabel = $langs->trans("ExportSite");
3294 if (!empty($conf->dol_optimize_smallscreen)) {
3295 $importlabel = $langs->trans("Import");
3296 $exportlabel = $langs->trans("Export");
3297 }
3298
3299 if ($atleastonepage) {
3300 print '<input type="submit" class="button bordertransp" disabled="disabled" value="'.dol_escape_htmltag($importlabel).'" name="importsite">';
3301 } else {
3302 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($importlabel).'" name="importsite">';
3303 }
3304
3305 // // Export web site
3306 $extraCssClass = getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE') ? 'hideobject' : '';
3307 print '<input type="submit" class="button bordertransp ' . $extraCssClass . '" ' . $disabledexport . ' value="' . dol_escape_htmltag($exportlabel) . '" name="exportsite">';
3308
3309 if (getDolGlobalString('WEBSITE_ALLOW_OVERWRITE_GIT_SOURCE')) {
3310 // Overwrite template in sources
3311 $overwriteGitUrl = $_SERVER["PHP_SELF"] . '?action=overwritesite&website=' . urlencode($website->ref);
3312 print dolButtonToOpenExportDialog('exportpopup', $langs->trans('ExportOptions'), $langs->trans('ExportSite'), 'exportsite', $overwriteGitUrl, $website);
3313 //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>';
3314 }
3315
3316 // Clone web site
3317 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">';
3318
3319 // Delete website
3320 if (!$permissiontodelete) {
3321 $disabled = ' disabled="disabled"';
3322 $title = $langs->trans("NotEnoughPermissions");
3323 $url = '#';
3324 } else {
3325 if ($website->status == $website::STATUS_VALIDATED) {
3326 $disabled = ' disabled="disabled"';
3327 $title = $langs->trans("WebsiteMustBeDisabled", $langs->transnoentitiesnoconv($website->LibStatut(0, 0)));
3328 $url = '#';
3329 } else {
3330 $disabled = '';
3331 $title = $langs->trans("Delete");
3332 $url = $_SERVER["PHP_SELF"].'?action=deletesite&token='.newToken().'&website='.urlencode($website->ref);
3333 }
3334 }
3335 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>';
3336
3337 // Regenerate all pages
3338 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>';
3339
3340 // Generate site map
3341 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>';
3342
3343 // Find / replace tool
3344 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>';
3345 }
3346
3347 print '</span>';
3348
3349 if ($websitekey && $websitekey != '-1' && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3350 print '<span class="websiteselection">';
3351
3352 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);
3353
3354 if (isModEnabled('category')) {
3355 //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>';
3356 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);
3357 }
3358
3359 print '</span>';
3360 }
3361 } else {
3362 print '<input type="hidden" name="website" id="website" value="'.$websitekey.'">';
3363 }
3364
3365
3366 print '<span class="websitetools">';
3367
3368 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite') {
3369 $urlext = $virtualurl;
3370 $urlint = $urlwithroot.'/public/website/index.php?website='.$websitekey;
3371
3372 print '<span class="websiteinputurl valignmiddle" id="websiteinputurl">';
3373 $linktotestonwebserver = '<a href="'.($virtualurl ? $virtualurl : '#').'" class="valignmiddle">';
3374 $linktotestonwebserver .= '<span class="hideonsmartphone paddingrightonly">'.$langs->trans("TestDeployOnWeb", $virtualurl).'</span>'.img_picto('', 'globe');
3375 $linktotestonwebserver .= '</a>';
3376
3377 $htmltext = '';
3378 if (empty($object->fk_default_home)) {
3379 $htmltext .= '<br><span class="error">'.$langs->trans("YouMustDefineTheHomePage").'</span><br><br>';
3380 } elseif (empty($virtualurl)) {
3381 //$htmltext .= '<br><span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span><br><br>';
3382 } else {
3383 $htmltext .= '<br><center>'.$langs->trans("GoTo").' <a href="'.$virtualurl.'" target="_website">'.$virtualurl.' '.img_picto('', 'url').'</a></center><br>';
3384 }
3385 if (getDolGlobalString('WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER')) {
3386 $htmltext .= '<!-- Message defined translate key set into WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER -->';
3387 $htmltext .= '<br>'.$langs->trans(getDolGlobalString('WEBSITE_REPLACE_INFO_ABOUT_USAGE_WITH_WEBSERVER'));
3388 } else {
3389 $htmltext .= $langs->trans("ToDeployYourWebsiteOnLiveYouHave3Solutions").'<br><br>';
3390 $htmltext .= '<div class="titre inline-block">1</div> - '.$langs->trans("SetHereVirtualHost", $dataroot);
3391 $htmltext .= '<br>';
3392 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
3393 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
3394 $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias', $htmltext);
3395
3396 $examplewithapache = "<VirtualHost *:80>\n";
3397 $examplewithapache .= '#php_admin_value open_basedir /tmp/:'.DOL_DOCUMENT_ROOT.':'.DOL_DATA_ROOT.':/dev/urandom'."\n";
3398 //$examplewithapache .= '#php_admin_value disable_functions "exec,passthru,shell_exec,system,popen,proc_open"'."\n"; This is not effective if not in php.ini
3399 $examplewithapache .= "\n";
3400 $examplewithapache .= 'DocumentRoot "'.DOL_DOCUMENT_ROOT.'"'."\n";
3401 $examplewithapache .= "\n";
3402 $examplewithapache .= '<Directory "'.DOL_DOCUMENT_ROOT.'">'."\n";
3403 $examplewithapache .= 'AllowOverride FileInfo Options
3404 Options -Indexes -MultiViews -FollowSymLinks -ExecCGI
3405 Require all granted
3406 </Directory>'."\n".'
3407 <Directory "'.DOL_DATA_ROOT.'/website">
3408 AllowOverride FileInfo Options
3409 Options -Indexes -MultiViews +FollowSymLinks -ExecCGI
3410 Require all granted
3411 </Directory>'."\n".'
3412 <Directory "'.DOL_DATA_ROOT.'/medias">
3413 AllowOverride FileInfo Options
3414 Options -Indexes -MultiViews -FollowSymLinks -ExecCGI
3415 Require all granted
3416 </Directory>'."\n";
3417
3418 $examplewithapache .= "\n";
3419 $examplewithapache .= "#ErrorLog /var/log/apache2/".$websitekey."_error_log\n";
3420 $examplewithapache .= "#TransferLog /var/log/apache2/".$websitekey."_access_log\n";
3421
3422 $examplewithapache .= "\n";
3423 $examplewithapache .= "# If you need include the payment page into a frame of the website,\n";
3424 $examplewithapache .= "# you need to make a proxy redirection of URLs required for the payment to your backoffice pages\n";
3425 $examplewithapache .= "#SSLProxyEngine On\n";
3426 $examplewithapache .= "#SSLProxyVerify none\n";
3427 $examplewithapache .= "#SSLProxyCheckPeerCN off\n";
3428 $examplewithapache .= "#SSLProxyCheckPeerName off\n";
3429 $examplewithapache .= "#ProxyPreserveHost Off\n";
3430 $examplewithapache .= '#ProxyPass "/public/payment/" "'.$urlwithroot.'/public/payment/'."\n";
3431 $examplewithapache .= '#ProxyPassReverse "/public/payment/" "'.$urlwithroot.'/public/payment/'."\n";
3432 $examplewithapache .= '#ProxyPass "/includes/" "'.$urlwithroot.'/includes/'."\n";
3433 $examplewithapache .= '#ProxyPassReverse "/includes/" "'.$urlwithroot.'/includes/'."\n";
3434 $examplewithapache .= '#ProxyPass "/theme/" "'.$urlwithroot.'/theme/'."\n";
3435 $examplewithapache .= '#ProxyPassReverse "/theme/" "'.$urlwithroot.'/theme/'."\n";
3436 $examplewithapache .= '#ProxyPass "/core/js/" "'.$urlwithroot.'/core/js/'."\n";
3437 $examplewithapache .= '#ProxyPassReverse "/core/js/" "'.$urlwithroot.'/core/js/'."\n";
3438 $examplewithapache .= "\n";
3439
3440 $examplewithapache .= "</VirtualHost>\n";
3441
3442 $htmltext .= '<br>'.$langs->trans("ExampleToUseInApacheVirtualHostConfig").':<br>';
3443 $htmltext .= '<div class="quatrevingtpercent exampleapachesetup wordbreak" spellcheck="false">'.dol_nl2br(dol_escape_htmltag($examplewithapache, 1, 1)).'</div>';
3444
3445 $htmltext .= '<br>';
3446 $htmltext .= '<div class="titre inline-block">2</div> - '.$langs->trans("YouCanAlsoTestWithPHPS");
3447 $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>';
3448 $htmltext .= ajax_autoselect("cliphpserver");
3449 $htmltext .= '<br>';
3450 $htmltext .= '<div class="titre inline-block">3</div> - '.$langs->trans("YouCanAlsoDeployToAnotherWHP");
3451 }
3452 print $form->textwithpicto($linktotestonwebserver, $htmltext, 1, 'none', 'valignmiddle', 0, 3, 'helpvirtualhost');
3453 print '</span>';
3454 }
3455
3456 if (in_array($action, array('editcss', 'editmenu', 'file_manager', 'replacesiteconfirm', 'editsecurity')) || in_array($mode, array('replacesite'))) {
3457 if (!$user->hasRight('website', 'write')) {
3458 $disabled = ' disabled';
3459 }
3460 if ($action == 'editcss' || $action == 'editsecurity') {
3461 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">';
3462 }
3463 if (preg_match('/^create/', $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 (preg_match('/^edit/', $action) && $action != 'file_manager' && $action != 'replacesite' && $action != 'replacesiteconfirm') {
3467 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3468 }
3469 if ($action != 'preview') {
3470 print '<input type="submit" class="button button-cancel small" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="cancel">';
3471 }
3472 }
3473
3474 print '</span>';
3475
3476 //
3477 // Toolbar for pages
3478 //
3479
3480 if ($websitekey && $websitekey != '-1' && (!in_array($action, array('editcss', 'editmenu', 'importsite', 'file_manager', 'replacesite', 'replacesiteconfirm', 'editsecurity'))) && (!in_array($mode, array('replacesite'))) && !$file_manager) {
3481 print '</div>'; // Close current websitebar to open a new one
3482
3483 print '<!-- Toolbar for websitepage -->';
3484 print '<div class="centpercent websitebar"'.($style ? ' style="'.$style.'"' : '').'>'."\n";
3485
3486 print '<div class="websiteselection hideonsmartphoneimp minwidth75 tdoverflowmax100 inline-block">';
3487 print $langs->trans("PageContainer").': ';
3488 print '</div>';
3489
3490 // Button Add new web page
3491 if ($user->hasRight('website', 'write')) {
3492 print '<span class="websiteselection paddingrightonly">';
3493 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>';
3494 print '</span>';
3495 }
3496
3497 $out = '';
3498
3499 $s = $formwebsite->selectContainer($website, 'pageid', $pageid, 0, $action, 'minwidth100 maxwidth200onsmartphone');
3500
3501 $out .= '<span class="websiteselection nopaddingrightimp">';
3502 $out .= $s;
3503 $out .= '</span>';
3504
3505 $urltocreatenewpage = $_SERVER["PHP_SELF"].'?action=createcontainer&token='.newToken().'&website='.urlencode($website->ref);
3506
3507 if (!empty($conf->use_javascript_ajax)) {
3508 $out .= '<script type="text/javascript">';
3509 $out .= 'jQuery(document).ready(function () {';
3510 $out .= ' jQuery("#pageid").change(function () {';
3511 $out .= ' console.log("We select "+jQuery("#pageid option:selected").val());';
3512 $out .= ' if (jQuery("#pageid option:selected").val() == \'-2\') {';
3513 $out .= ' window.location.href = "'.$urltocreatenewpage.'";';
3514 $out .= ' } else {';
3515 $out .= ' window.location.href = "'.$_SERVER["PHP_SELF"].'?website='.urlencode($website->ref).'&pageid="+jQuery("#pageid option:selected").val();';
3516 $out .= ' }';
3517 $out .= ' });';
3518 $out .= '});';
3519 $out .= '</script>';
3520 }
3521
3522 print $out;
3523
3524 // Button to switch status
3525 if (!empty($conf->use_javascript_ajax)) {
3526 print '<span class="websiteselection">';
3527 //print '<div class="inline-block marginrightonly">';
3528 if ($object->status == $object::STATUS_DRAFT) { // website is off, we do not allow to change status of page
3529 $text_off = 'SetWebsiteOnlineBefore';
3530 if ($websitepage->status == $websitepage::STATUS_DRAFT) { // page is off
3531 print '<span class="valignmiddle disabled opacitymedium">'.img_picto($langs->trans($text_off), 'switch_off', '', 0, 0, 0, '', $morecss).'</span>';
3532 } else {
3533 print '<span class="valignmiddle disabled opacitymedium">'.img_picto($langs->trans($text_off), 'switch_on', '', 0, 0, 0, '', $morecss).'</span>';
3534 }
3535 } else {
3536 if ($objectpage->type_container != 'setup') { // we do not allow to change status of setup pages
3537 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);
3538 }
3539 }
3540 //print '</div>';
3541 print '</span>';
3542 }
3543
3544 print '<span class="websiteselection">';
3545
3546 print '<input type="image" class="valignmiddle buttonwebsite hideonsmartphone" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'"'.(($action != 'editsource') ? '' : ' disabled="disabled"').'>';
3547
3548 // Print nav arrows
3549 $pagepreviousid = 0;
3550 $pagenextid = 0;
3551 if ($pageid) {
3552 $sql = "SELECT MAX(rowid) as pagepreviousid FROM ".MAIN_DB_PREFIX."website_page WHERE rowid < ".((int) $pageid)." AND fk_website = ".((int) $object->id);
3553 $resql = $db->query($sql);
3554 if ($resql) {
3555 $obj = $db->fetch_object($resql);
3556 if ($obj) {
3557 $pagepreviousid = $obj->pagepreviousid;
3558 }
3559 } else {
3560 dol_print_error($db);
3561 }
3562 $sql = "SELECT MIN(rowid) as pagenextid FROM ".MAIN_DB_PREFIX."website_page WHERE rowid > ".((int) $pageid)." AND fk_website = ".((int) $object->id);
3563 $resql = $db->query($sql);
3564 if ($resql) {
3565 $obj = $db->fetch_object($resql);
3566 if ($obj) {
3567 $pagenextid = $obj->pagenextid;
3568 }
3569 } else {
3570 dol_print_error($db);
3571 }
3572 }
3573
3574 if ($pagepreviousid) {
3575 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>';
3576 } else {
3577 print '<span class="valignmiddle opacitymedium">'.img_previous($langs->trans("PreviousContainer")).'</span>';
3578 }
3579 if ($pagenextid) {
3580 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>';
3581 } else {
3582 print '<span class="valignmiddle opacitymedium">'.img_next($langs->trans("NextContainer")).'</span>';
3583 }
3584
3585 print '</span>';
3586
3587 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite') {
3588 $disabled = '';
3589 if (!$user->hasRight('website', 'write')) {
3590 $disabled = ' disabled="disabled"';
3591 }
3592
3593 // Confirmation delete site
3594 if ($action == 'deletesite') {
3595 // Create an array for form
3596 $formquestion = array(
3597 array('type' => 'checkbox', 'name' => 'delete_also_js', 'label' => $langs->trans("DeleteAlsoJs"), 'value' => 0),
3598 array('type' => 'checkbox', 'name' => 'delete_also_medias', 'label' => $langs->trans("DeleteAlsoMedias"), 'value' => 0),
3599 //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')),
3600 //array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0))
3601 );
3602
3603 if ($atleastonepage) {
3604 $langs->load("errors");
3605 $formquestion[] = array('type' => 'onecolumn', 'value' => '<div class="warning">'.$langs->trans("WarningPagesWillBeDeleted").'</div>');
3606 }
3607
3608 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteWebsite'), '', 'confirm_deletesite', $formquestion, 0, 1, 210 + ($atleastonepage ? 70 : 0), 580);
3609
3610 print $formconfirm;
3611 }
3612
3613 // Confirmation to clone
3614 if ($action == 'createfromclone') {
3615 // Create an array for form
3616 $formquestion = array(
3617 array('type' => 'text', 'name' => 'siteref', 'label' => $langs->trans("WebSite"), 'value' => 'copy_of_'.$object->ref)
3618 );
3619
3620 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('CloneSite'), '', 'confirm_createfromclone', $formquestion, 0, 1, 0);
3621
3622 print $formconfirm;
3623 }
3624
3625 if ($pageid > 0 && $atleastonepage) { // pageid can be set without pages, if homepage of site is set and all pages were removed
3626 // Confirmation to clone
3627 if ($action == 'createpagefromclone') {
3628 // Create an array for form
3629 $preselectedlanguage = GETPOST('newlang', 'aZ09') ? GETPOST('newlang', 'aZ09') : ($objectpage->lang ?: ''); // By default, we do not force any language on pages
3630 $onlylang = array();
3631 if ($website->otherlang) {
3632 if (!empty($website->lang)) {
3633 $onlylang[$website->lang] = $website->lang.' ('.$langs->trans("Default").')';
3634 }
3635 foreach (explode(',', $website->otherlang) as $langkey) {
3636 if (empty(trim($langkey))) {
3637 continue;
3638 }
3639 $onlylang[$langkey] = $langkey;
3640 }
3641 $textifempty = $langs->trans("Default");
3642 } else {
3643 $onlylang['none'] = 'none';
3644 $textifempty = $langs->trans("Default");
3645 }
3646
3647 $formquestion = array(
3648 array('type' => 'hidden', 'name' => 'sourcepageurl', 'value' => $objectpage->pageurl),
3649 array('type' => 'other', 'tdclass' => 'fieldrequired', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite((string) $object->id, 'newwebsite', 0)),
3650 array('type' => 'text', 'tdclass' => 'maxwidth200 fieldrequired', 'moreattr' => 'autofocus="autofocus"', 'name' => 'newtitle', 'label' => $langs->trans("WEBSITE_TITLE"), 'value' => $langs->trans("CopyOf").' '.$objectpage->title),
3651 array('type' => 'text', 'tdclass' => 'maxwidth200', 'name' => 'newpageurl', 'label' => $langs->trans("WEBSITE_PAGENAME"), 'value' => '')
3652 );
3653 if (count($onlylang) > 1) {
3654 $formquestion[] = array('type' => 'checkbox', 'tdclass' => 'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0,
3655 'morecss' => 'margintoponly',
3656 'moreattr' => 'onclick="console.log(\'Click on is_a_translation\'); jQuery(\'#newlang\').val(-1).trigger(\'change\');"'
3657 );
3658 }
3659
3660 $value = $formadmin->select_language($preselectedlanguage, 'newlang', 0, array(), $textifempty, 0, 0, 'minwidth200', 1, 0, 0, $onlylang, 1);
3661 $formquestion[] = array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $value);
3662
3663 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 0, 550);
3664
3665 print $formconfirm;
3666 }
3667
3668 print '<span class="websiteselection">';
3669
3670 // Edit web page properties
3671 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.'>';
3672 print img_picto('', 'setup');
3673 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans("EditPageMeta")).'</span>';
3674 print '</a>';
3675
3676 // Edit HTML content
3677 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid.'&action=editsource&token='.newToken().'" class="button bordertransp"'.$disabled.'>';
3678 print img_picto('', 'code');
3679 print '<span class="hideonsmartphone paddingleft">'.dol_escape_htmltag($langs->trans($conf->dol_optimize_smallscreen ? "HTML" : "EditHTMLSource")).'</span>';
3680 print '</a>';
3681
3682 // Edit CKEditor
3683 if (getDolGlobalInt('WEBSITE_ALLOW_CKEDITOR')) {
3684 print '<a href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid.'&action=editcontent&token='.newToken().'" class="button bordertransp"'.$disabled.'>'.dol_escape_htmltag("CKEditor").'</a>';
3685 } else {
3686 print '<!-- Add option WEBSITE_ALLOW_CKEDITOR to allow ckeditor -->';
3687 }
3688
3689 print '</span>';
3690
3691
3692 // Switch include dynamic content / edit inline
3693 print '<!-- button EditInLine and ShowSubcontainers -->'."\n";
3694 print '<div class="websiteselectionsection inline-block">';
3695
3696 // Force to show subcontainers if we are in setup mode
3697 if ($objectpage->type_container == 'setup') {
3698 dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1);
3699 }
3700
3701 if ($objectpage->type_container != 'setup') {
3702 print '<div class="inline-block marginrightonly">'; // Button includes dynamic content
3703 print $langs->trans("ShowSubcontainers");
3704 if (!getDolGlobalString('WEBSITE_SUBCONTAINERSINLINE')) {
3705 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>';
3706 } else {
3707 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>';
3708 }
3709 print '</div>';
3710 }
3711
3712 print '<div class="inline-block marginrightonly">'; // Button edit inline
3713
3714 print '<span id="switchckeditorinline">'."\n";
3715 // Enable CKEditor inline with js on section and div with conteneditable=true
3716 print '<!-- Code to enabled edit inline ckeditor -->'."\n";
3717 print '<script type="text/javascript">
3718 $(document).ready(function() {
3719 var isEditingEnabled = '.(getDolGlobalString("WEBSITE_EDITINLINE") ? 'true' : 'false').';
3720 if (isEditingEnabled)
3721 {
3722 switchEditorOnline(true);
3723 }
3724
3725 $( "#switchckeditorinline" ).click(function() {
3726 switchEditorOnline();
3727 });
3728
3729 function switchEditorOnline(forceenable)
3730 {
3731 if (! isEditingEnabled || forceenable)
3732 {
3733 console.log("Enable inline edit for some html tags with contenteditable=true attribute");
3734
3735 jQuery(\'section[contenteditable="true"],div[contenteditable="true"],header[contenteditable="true"],main[contenteditable="true"],footer[contenteditable="true"]\').each(function(idx){
3736 var idtouse = $(this).attr(\'id\');
3737 console.log("Enable inline edit for "+idtouse);
3738 if (idtouse !== undefined) {
3739 var inlineditor = CKEDITOR.inline(idtouse, {
3740 // Allow some non-standard markup that we used in the introduction.
3741 // + a[target];div{float,display} ?
3742 extraAllowedContent: \'span(*);cite(*);q(*);dl(*);dt(*);dd(*);ul(*);li(*);header(*);main(*);footer(*);button(*);h1(*);h2(*);h3(*);\',
3743 //extraPlugins: \'sourcedialog\',
3744 removePlugins: \'flash,stylescombo,exportpdf,scayt,wsc,pagebreak,iframe,smiley\',
3745 // Show toolbar on startup (optional).
3746 // startupFocus: true
3747 });
3748
3749 // Custom bar tool
3750 // Note the Source tool does not work on inline
3751 inlineditor.config.toolbar = [
3752 [\'Templates\',\'NewPage\'],
3753 [\'Save\'],
3754 [\'Maximize\',\'Preview\'],
3755 [\'PasteText\'],
3756 [\'Undo\',\'Redo\',\'-\',\'Find\',\'Replace\',\'-\',\'SelectAll\',\'RemoveFormat\'],
3757 [\'CreateDiv\',\'ShowBlocks\'],
3758 [\'Form\', \'Checkbox\', \'Radio\', \'TextField\', \'Textarea\', \'Select\', \'Button\', \'ImageButton\', \'HiddenField\'],
3759 [\'Bold\',\'Italic\',\'Underline\',\'Strike\',\'Superscript\'],
3760 [\'NumberedList\',\'BulletedList\',\'-\',\'Outdent\',\'Indent\',\'Blockquote\'],
3761 [\'JustifyLeft\',\'JustifyCenter\',\'JustifyRight\',\'JustifyBlock\'],
3762 [\'Link\',\'Unlink\'],
3763 [\'Image\',\'Table\',\'HorizontalRule\'],
3764 [\'Styles\',\'Format\',\'Font\',\'FontSize\'],
3765 [\'TextColor\',\'BGColor\']
3766 ];
3767
3768 // Start editor
3769 //inlineditor.on(\'instanceReady\', function () {
3770 // ...
3771 //});
3772
3773 CKEDITOR.instances[idtouse].on(\'change\', function() {
3774 $(this.element.$).addClass(\'modified\');
3775 })
3776 } else {
3777 console.warn("A html section has the contenteditable=true attribute but has no id attribute");
3778 }
3779 })
3780
3781 isEditingEnabled = true;
3782
3783 // Trigger the function when clicking outside the elements with contenteditable=true attribute
3784 // so we can save the change.
3785 $(document).on(\'click\', function(e) {
3786 var target = $(e.target);
3787
3788 // Check if the click is outside the elements with contenteditable=true attribute
3789 if (!target.closest(\'[contenteditable="true"]\').length) {
3790 // Repeat through the elements with contenteditable="true" attribute
3791 $(\'[contenteditable="true"]\').each(function() {
3792 var idToUse = $(this).attr(\'id\');
3793 var elementType = $(this).prop("tagName").toLowerCase(); // Get the tag name (div, section, footer...)
3794 var instance = CKEDITOR.instances[idToUse];
3795
3796 // Check if the element has been modified
3797 if ($(this).hasClass(\'modified\')) {
3798 var content = instance.getData();
3799 content = "\\n" + content;
3800
3801 // Retrieving the content and ID of the element
3802 var elementId = $(this).attr(\'id\');
3803
3804 ';
3805 if (getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) {
3806 print '
3807 console.log("A change has been detected, we send new content for update with ajax");
3808
3809 // Sending data via AJAX to update section
3810 $.ajax({
3811 type: \'POST\',
3812 url: \'' . DOL_URL_ROOT . '/core/ajax/editinline.php\',
3813 data: {
3814 website_ref: \''.dol_escape_js($website->ref).'\',
3815 page_id: \'' . ((int) $websitepage->id) . '\',
3816 content: content,
3817 element_id: elementId,
3818 element_type: elementType,
3819 action: \'updatedElementContent\',
3820 token: \'' . currentToken() . '\'
3821 },
3822 success: function(response) {
3823 console.log(response);
3824 var $lastWebsitebar = $(".websitebar").last();
3825 var $span = $("<span></span>").html("'.$langs->trans("Saved").'").css({
3826 \'display\': \'block\',
3827 \'position\': \'absolute\',
3828 \'margin-top\': \'6px\',
3829 \'right\': \'5px\',
3830 \'background-color\': \'#e3f0db\',
3831 \'color\': \'#446548\',
3832 \'font-size\': \'14px\',
3833 \'padding\': \'0px 5px\',
3834 \'z-index\': 1000
3835 });
3836 $lastWebsitebar.after($span);
3837
3838 // Close message after 2 seconds
3839 setTimeout(function() {
3840 $span.fadeOut(500, function() {
3841 $(this).remove();
3842 });
3843 }, 2000);
3844 }
3845 });
3846 ';
3847 } else {
3848 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");';
3849 }
3850 print '
3851
3852 $(this).removeClass(\'modified\');
3853 }
3854 });
3855 }
3856 });
3857
3858 } else {
3859 console.log("Disable inline edit");
3860 for(name in CKEDITOR.instances) {
3861 CKEDITOR.instances[name].destroy(true);
3862 }
3863 isEditingEnabled = false;
3864 }
3865 }
3866 });
3867 </script>';
3868 print $langs->trans("EditInLine");
3869 print '</span>';
3870
3871 //$disableeditinline = $websitepage->grabbed_from;
3872 $disableeditinline = 0;
3873 if ($disableeditinline) {
3874 //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">';
3875 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>';
3876 } else {
3877 //print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
3878 if (!getDolGlobalString('WEBSITE_EDITINLINE')) {
3879 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>';
3880 } else {
3881 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>';
3882 }
3883 }
3884
3885 print '</div>';
3886
3887 print '</div>';
3888
3889 // Set page as homepage
3890 print '<span class="websiteselection">';
3891 if ($object->fk_default_home > 0 && $pageid == $object->fk_default_home) {
3892 //$disabled=' disabled="disabled"';
3893 //print '<span class="button bordertransp disabled"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'"><span class="fas fa-home"></span></span>';
3894 //print '<input type="submit" class="button bordertransp" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
3895 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>';
3896 } else {
3897 //$disabled='';
3898 //print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
3899 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>';
3900 }
3901 print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ClonePage")).'" name="createpagefromclone">';
3902
3903 // Delete
3904 if ($websitepage->status != $websitepage::STATUS_DRAFT) {
3905 $disabled = ' disabled="disabled"';
3906 $title = $langs->trans("WebpageMustBeDisabled", $langs->transnoentitiesnoconv($websitepage->LibStatut(0, 0)));
3907 $url = '#';
3908 } else {
3909 $disabled = '';
3910 $title = '';
3911 $url = $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&pageid='.((int) $websitepage->id).'&website='.urlencode($website->ref); // action=delete for webpage, deletesite for website
3912 }
3913 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>';
3914 print '</span>';
3915 }
3916 }
3917
3918 //print '</span>'; // end website selection
3919
3920 print '<span class="websitetools">';
3921
3922 if (($pageid > 0 && $atleastonepage) && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) {
3923 $realpage = $urlwithroot.'/public/website/index.php?website='.$websitekey.'&pageref='.$websitepage->pageurl;
3924 $pagealias = $websitepage->pageurl;
3925
3926 $htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $langs->transnoentitiesnoconv("TestDeployOnWeb"));
3927 //$htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), '{s1}');
3928 //$htmltext = str_replace('{s1}', $dataroot.'<br>'.DOL_DATA_ROOT.'/medias<br>'.DOL_DOCUMENT_ROOT, $htmltext);
3929 //$htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
3930 //$htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/medias', $htmltext);
3931
3932 print '<div class="websiteinputurl inline-block paddingright">';
3933 print '<a class="websitebuttonsitepreview inline-block" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
3934 print $form->textwithpicto('', $htmltext, 1, 'preview');
3935 print '</a>'; // View page in new Tab
3936 print '</div>';
3937
3938 /*print '<div class="websiteinputurl inline-block" id="websiteinputpage">';
3939 print '<input type="text" id="previewpageurl" class="minwidth200imp" name="previewsite" value="'.$pagealias.'" disabled="disabled">';
3940 $htmltext = $langs->trans("PageNameAliasHelp", $langs->transnoentitiesnoconv("EditPageMeta"));
3941 print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helppagealias');
3942 print '</div>';*/
3943
3944 /*
3945 $urlext = $virtualurl.'/'.$pagealias.'.php';
3946 $urlint = $urlwithroot.'/public/website/index.php?website='.$websitekey;
3947
3948 $htmltext = $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $virtualurl ? $urlext : '<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>');
3949
3950 print '<a class="websitebuttonsitepreview'.($virtualurl ? '' : ' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($htmltext).'">';
3951 print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
3952 print '</a>';
3953 */
3954 //print '<input type="submit" class="button" name="previewpage" target="tab'.$websitekey.'"value="'.$langs->trans("ViewPageInNewTab").'">';
3955
3956 // TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext
3957 }
3958 if (!in_array($mode, array('replacesite')) && !in_array($action, array('editcss', 'editmenu', 'file_manager', 'replacesiteconfirm', 'createsite', 'createcontainer', 'createfromclone', 'createpagefromclone', 'deletesite', 'editsecurity'))) {
3959 if (!$user->hasRight('website', 'write')) {
3960 $disabled = ' disabled';
3961 }
3962 if ($action == 'editsource' || $action == 'editmeta') {
3963 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">';
3964 }
3965 if (preg_match('/^create/', $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 (preg_match('/^edit/', $action)) {
3969 print '<input type="submit" id="savefile" class="button buttonforacesave button-save small'.$disabled.'" value="'.dol_escape_htmltag($langs->trans("Save")).'" name="update">';
3970 }
3971 if ($action != 'preview') {
3972 print '<input type="submit" class="button button-cancel small" value="'.dol_escape_htmltag($langs->trans("Cancel")).'" name="cancel">';
3973 }
3974 }
3975
3976 print '</span>'; // end websitetools
3977
3978 print '<span class="websitehelp">';
3979 if ($action == 'editsource' || $action == 'editcontent' || GETPOST('editsource', 'alpha') || GETPOST('editcontent', 'alpha')) {
3980 $url = 'https://wiki.dolibarr.org/index.php/Module_Website';
3981
3982 $htmltext = '<small>';
3983 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource", $url);
3984 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceb", $url);
3985 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourcec", $url);
3986 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourced", $url);
3987 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource1", $url);
3988 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource2", $url);
3989 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource3", $url);
3990 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource4", $url);
3991 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceMore", $url);
3992 $htmltext .= '<br>';
3993 $htmltext .= '</small>';
3994 if ($conf->browser->layout == 'phone') {
3995 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
3996 } else {
3997 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
3998 print $form->textwithpicto($langs->trans("SyntaxHelp").' '.img_help(2, $langs->trans("SyntaxHelp")), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
3999 }
4000 }
4001 print '</span>'; // end websitehelp
4002
4003
4004 if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') {
4005 // Adding jquery code to change on the fly url of preview ext
4006 if (!empty($conf->use_javascript_ajax)) {
4007 print '<script type="text/javascript">
4008 jQuery(document).ready(function() {
4009 jQuery("#websiteinputurl").keyup(function() {
4010 console.log("Website external url modified "+jQuery("#previewsiteurl").val());
4011 if (jQuery("#previewsiteurl").val() != "" && jQuery("#previewsiteurl").val().startsWith("http"))
4012 {
4013 jQuery("a.websitebuttonsitepreviewdisabled img").css({ opacity: 1 });
4014 }
4015 else jQuery("a.websitebuttonsitepreviewdisabled img").css({ opacity: 0.2 });
4016 ';
4017 print '
4018 });
4019 jQuery("#previewsiteext,#previewpageext").click(function() {
4020
4021 newurl=jQuery("#previewsiteurl").val();
4022 if (! newurl.startsWith("http"))
4023 {
4024 alert(\''.dol_escape_js($langs->trans("ErrorURLMustStartWithHttp")).'\');
4025 return false;
4026 }
4027
4028 newpage=jQuery("#previewsiteurl").val() + "/" + jQuery("#previewpageurl").val() + ".php";
4029 console.log("Open url "+newurl);
4030 /* Save url */
4031 jQuery.ajax({
4032 method: "POST",
4033 url: "'.DOL_URL_ROOT.'/core/ajax/saveinplace.php",
4034 data: {
4035 token: \''.currentToken().'\',
4036 field: \'editval_virtualhost\',
4037 element: \'website\',
4038 table_element: \'website\',
4039 fk_element: '.((int) $object->id).',
4040 value: newurl,
4041 },
4042 context: document.body
4043 });
4044
4045 jQuery("#previewsiteext").attr("href",newurl);
4046 jQuery("#previewpageext").attr("href",newpage);
4047 });
4048 });
4049 </script>';
4050 }
4051 }
4052 }
4053
4054 print '</div>'."\n"; // end current websitebar
4055}
4056
4057
4058$head = array();
4059
4060
4061/*
4062 * Edit Site HTML header and CSS
4063 */
4064
4065if ($action == 'editcss') {
4066 print '<div class="fiche">';
4067
4068 print '<br>';
4069
4070 if (!GETPOSTISSET('WEBSITE_CSS_INLINE')) {
4071 $csscontent = @file_get_contents($filecss);
4072 // Clean the php css file to remove php code and get only css part
4073 $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $csscontent);
4074 } else {
4075 $csscontent = GETPOST('WEBSITE_CSS_INLINE', 'none');
4076 }
4077 if (!trim($csscontent)) {
4078 $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;}";
4079 }
4080
4081 if (!GETPOSTISSET('WEBSITE_JS_INLINE')) {
4082 $jscontent = @file_get_contents($filejs);
4083 // Clean the php js file to remove php code and get only js part
4084 $jscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $jscontent);
4085 } else {
4086 $jscontent = GETPOST('WEBSITE_JS_INLINE', 'none');
4087 }
4088 if (!trim($jscontent)) {
4089 $jscontent = '/* JS content (all pages) */'."\n";
4090 }
4091
4092 if (!GETPOSTISSET('WEBSITE_HTML_HEADER')) {
4093 $htmlheadercontent = @file_get_contents($filehtmlheader);
4094 // Clean the php htmlheader file to remove php code and get only html part
4095 $htmlheadercontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $htmlheadercontent);
4096 } else {
4097 $htmlheadercontent = GETPOST('WEBSITE_HTML_HEADER', 'none'); // Must accept tags like '<script>' and '<link>'
4098 }
4099 if (!trim($htmlheadercontent)) {
4100 $htmlheadercontent = "<html>\n";
4101 $htmlheadercontent .= $htmlheadercontentdefault;
4102 $htmlheadercontent .= "</html>";
4103 } else {
4104 $htmlheadercontent = preg_replace('/^\s*<html>/ims', '', $htmlheadercontent);
4105 $htmlheadercontent = preg_replace('/<\/html>\s*$/ims', '', $htmlheadercontent);
4106 $htmlheadercontent = '<html>'."\n".trim($htmlheadercontent)."\n".'</html>';
4107 }
4108
4109 if (!GETPOSTISSET('WEBSITE_ROBOT')) {
4110 $robotcontent = @file_get_contents($filerobot);
4111 // Clean the php htmlheader file to remove php code and get only html part
4112 $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $robotcontent);
4113 } else {
4114 $robotcontent = GETPOST('WEBSITE_ROBOT', 'nohtml');
4115 }
4116 if (!trim($robotcontent)) {
4117 $robotcontent .= "# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n";
4118 $robotcontent .= "User-agent: *\n";
4119 $robotcontent .= "Allow: /public/\n";
4120 $robotcontent .= "Disallow: /administrator/\n";
4121 }
4122
4123 if (!GETPOSTISSET('WEBSITE_HTACCESS')) {
4124 $htaccesscontent = @file_get_contents($filehtaccess);
4125 // Clean the php htaccesscontent file to remove php code and get only html part
4126 $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $htaccesscontent);
4127 } else {
4128 $htaccesscontent = GETPOST('WEBSITE_HTACCESS', 'nohtml'); // We must use 'nohtml' and not 'alphanohtml' because we must accept "
4129 }
4130
4131 if (!GETPOSTISSET('WEBSITE_MANIFEST_JSON')) {
4132 $manifestjsoncontent = @file_get_contents($filemanifestjson);
4133 // Clean the manifestjson file to remove php code and get only html part
4134 $manifestjsoncontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $manifestjsoncontent);
4135 } else {
4136 $manifestjsoncontent = trim(GETPOST('WEBSITE_MANIFEST_JSON', 'restricthtmlallowunvalid'));
4137 $manifestjsoncontent = str_replace('<?=', '<?php', $manifestjsoncontent);
4138 }
4139
4140 //if (!trim($manifestjsoncontent)) {
4141 //$manifestjsoncontent.="";
4142 //}
4143
4144 if (!GETPOSTISSET('WEBSITE_README')) {
4145 $readmecontent = @file_get_contents($filereadme);
4146 // Clean the readme file to remove php code and get only html part
4147 $readmecontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $readmecontent);
4148 } else {
4149 $readmecontent = GETPOST('WEBSITE_README', 'restricthtmlallowunvalid');
4150 }
4151 //if (!trim($readmecontent)) {
4152 //$readmecontent.="";
4153 //}
4154
4155 if (!GETPOSTISSET('WEBSITE_LICENSE')) {
4156 $licensecontent = @file_get_contents($filelicense);
4157 // Clean the readme file to remove php code and get only html part
4158 $licensecontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP( \?>)?\n*/ims', '', $licensecontent);
4159 } else {
4160 $licensecontent = GETPOST('WEBSITE_LICENSE', 'restricthtmlallowunvalid');
4161 }
4162 //if (!trim($licensecontent)) {
4163 //$readmecontent.="";
4164 //}
4165
4166 $head = websiteconfigPrepareHead($object);
4167 print dol_get_fiche_head($head, 'general', $langs->trans("General"), 0, 'website');
4168
4169 print '<!-- Edit Website properties (CSS, Language, ...) -->'."\n";
4170 print '<table class="border centpercent">';
4171
4172 // Website
4173 print '<tr><td class="titlefieldcreate fieldrequired">';
4174 print $langs->trans('WebSite');
4175 print '</td><td>';
4176 print $websitekey;
4177 print '</td></tr>';
4178
4179 // Status of web site
4180 if ($action != 'createcontainer') {
4181 if (empty($conf->use_javascript_ajax)) {
4182 print '<!-- Status of web site page -->'."\n";
4183 print '<tr><td class="fieldrequired">';
4184 print $langs->trans('Status');
4185 print '</td><td>';
4186 print $form->selectyesno('status', $object->status);
4187 print '</td></tr>';
4188 }
4189 }
4190
4191 // Main language
4192 print '<tr><td class="tdtop fieldrequired">';
4193 $htmltext = '';
4194 print $form->textwithpicto($langs->trans('MainLanguage'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_LANG');
4195 print '</td><td>';
4196 print img_picto('', 'language', 'class="pictofixedwidth"');
4197 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);
4198 print '</td>';
4199 print '</tr>';
4200
4201 // Other languages
4202 print '<tr><td class="tdtop">';
4203 $htmltext = $langs->trans("Example").': fr,de,sv,it,pt';
4204 print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2);
4205 print '</td><td>';
4206 print img_picto('', 'language', 'class="pictofixedwidth"');
4207 print '<input type="text" class="flat maxwidth200" value="'.(GETPOSTISSET('WEBSITE_OTHERLANG') ? GETPOST('WEBSITE_OTHERLANG', 'alpha') : $object->otherlang).'" name="WEBSITE_OTHERLANG">';
4208 print '</td>';
4209 print '</tr>';
4210
4211 // VirtualHost
4212 print '<tr><td class="tdtop">';
4213
4214 $htmltext = $langs->trans("VirtualhostDesc");
4215 print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'virtualhosttooltip');
4216 print '</td><td>';
4217 print '<input type="text" class="flat minwidth300" value="'.(GETPOSTISSET('virtualhost') ? GETPOST('virtualhost', 'alpha') : $virtualurl).'" name="virtualhost">';
4218 print '</td>';
4219 print '</tr>';
4220
4221 // Favicon
4222 print '<tr><td>';
4223 print $form->textwithpicto($langs->trans('ImportFavicon'), $langs->trans('FaviconTooltip'));
4224 print '</td><td>';
4225 $maxfilesizearray = getMaxFileSizeArray();
4226 $maxmin = $maxfilesizearray['maxmin'];
4227 if ($maxmin > 0) {
4228 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
4229 }
4230 print '<input type="file" class="flat minwidth300" name="addedfile" id="addedfile"/>';
4231
4232 $uploadfolder = $conf->website->dir_output.'/'.$websitekey;
4233 if (dol_is_file($uploadfolder.'/favicon.png')) {
4234 print '<div class="inline-block valignmiddle marginrightonly">';
4235 print '<img style="max-height: 80px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=website&file='.$websitekey.'/favicon.png">';
4236 print '</div>';
4237 }
4238 print '</tr></td>';
4239
4240 // CSS file
4241 print '<tr><td class="tdtop">';
4242 $htmlhelp = $langs->trans("CSSContentTooltipHelp");
4243 print $form->textwithpicto($langs->trans('WEBSITE_CSS_INLINE'), $htmlhelp, 1, 'help', '', 0, 2, 'csstooltip');
4244 print '</td><td>';
4245
4246 $poscursor = array('x' => GETPOST('WEBSITE_CSS_INLINE_x'), 'y' => GETPOST('WEBSITE_CSS_INLINE_y'));
4247 $doleditor = new DolEditor('WEBSITE_CSS_INLINE', $csscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4248 print $doleditor->Create(1, '', true, 'CSS', 'css');
4249
4250 print '</td></tr>';
4251
4252 // JS file
4253 print '<tr><td class="tdtop">';
4254 $textwithhelp = $langs->trans('WEBSITE_JS_INLINE');
4255 $htmlhelp2 = $langs->trans("LinkAndScriptsHereAreNotLoadedInEditor").'<br>';
4256 print $form->textwithpicto($textwithhelp, $htmlhelp2, 1, 'warning', '', 0, 2, 'htmljstooltip2');
4257
4258 print '</td><td>';
4259
4260 $poscursor = array('x' => GETPOST('WEBSITE_JS_INLINE_x'), 'y' => GETPOST('WEBSITE_JS_INLINE_y'));
4261 $doleditor = new DolEditor('WEBSITE_JS_INLINE', $jscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4262 print $doleditor->Create(1, '', true, 'JS', 'javascript');
4263
4264 print '</td></tr>';
4265
4266 // Common HTML header
4267 print '<tr><td class="tdtop">';
4268 print $langs->trans('WEBSITE_HTML_HEADER');
4269 $htmlhelp = $langs->trans("Example").' :<br>';
4270 $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.
4271 $textwithhelp = $form->textwithpicto('', $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
4272 $htmlhelp2 = $langs->trans("LinkAndScriptsHereAreNotLoadedInEditor").'<br>';
4273 print $form->textwithpicto($textwithhelp, $htmlhelp2, 1, 'warning', '', 0, 2, 'htmlheadertooltip2');
4274 print '</td><td>';
4275
4276 $poscursor = array('x' => GETPOST('WEBSITE_HTML_HEADER_x'), 'y' => GETPOST('WEBSITE_HTML_HEADER_y'));
4277 $doleditor = new DolEditor('WEBSITE_HTML_HEADER', $htmlheadercontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4278 print $doleditor->Create(1, '', true, 'HTML Header', 'html');
4279
4280 print '</td></tr>';
4281
4282 // Robot file
4283 print '<tr><td class="tdtop">';
4284 print $langs->trans('WEBSITE_ROBOT');
4285 print '</td><td>';
4286
4287 $poscursor = array('x' => GETPOST('WEBSITE_ROBOT_x'), 'y' => GETPOST('WEBSITE_ROBOT_y'));
4288 $doleditor = new DolEditor('WEBSITE_ROBOT', $robotcontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4289 print $doleditor->Create(1, '', true, 'Robot file', 'text');
4290
4291 print '</td></tr>';
4292
4293 // .htaccess
4294 print '<tr><td class="tdtop">';
4295
4296 $textwithhelp3 = $langs->trans("Example").' :';
4297 $textwithhelp3 .= "<br># Order allow,deny\n";
4298 $textwithhelp3 .= "<br># Deny from all\n";
4299 $textwithhelp3 .= "<br># Require all granted\n";
4300
4301 print $form->textwithpicto($langs->trans('WEBSITE_HTACCESS'), $textwithhelp3, 1, 'help', '', 0, 2, 'htmlheadertooltip3');
4302 print '</td><td>';
4303
4304 $poscursor = array('x' => GETPOST('WEBSITE_HTACCESS_x'), 'y' => GETPOST('WEBSITE_HTACCESS_y'));
4305 $doleditor = new DolEditor('WEBSITE_HTACCESS', $htaccesscontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4306 print $doleditor->Create(1, '', true, $langs->trans("File").' .htaccess', 'text');
4307
4308 print '</td></tr>';
4309
4310 // Manifest.json
4311 print '<tr><td class="tdtop">';
4312 $htmlhelp = $langs->trans("Example").' :<br>';
4313 $htmlhelp .= '<small>'.dol_htmlentitiesbr($manifestjsoncontentdefault).'</small>';
4314 print $form->textwithpicto($langs->trans('WEBSITE_MANIFEST_JSON'), $htmlhelp, 1, 'help', '', 0, 2, 'manifestjsontooltip');
4315 print '</td><td>';
4316 print $langs->trans("UseManifest").': '.$form->selectyesno('use_manifest', $website->use_manifest, 1).'<br>';
4317
4318 $poscursor = array('x' => GETPOST('WEBSITE_MANIFEST_JSON_x'), 'y' => GETPOST('WEBSITE_MANIFEST_JSON_y'));
4319 $doleditor = new DolEditor('WEBSITE_MANIFEST_JSON', $manifestjsoncontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4320 print $doleditor->Create(1, '', true, $langs->trans("File").' manifest.json', 'text');
4321 print '</td></tr>';
4322
4323 // README.md
4324 print '<tr><td class="tdtop">';
4325 $htmlhelp = $langs->trans("EnterHereReadmeInformation");
4326 print $form->textwithpicto($langs->trans("File").' README.md', $htmlhelp, 1, 'help', '', 0, 2, 'readmetooltip');
4327 print '</td><td>';
4328
4329 $poscursor = array('x' => GETPOST('WEBSITE_README_x'), 'y' => GETPOST('WEBSITE_README_y'));
4330 $doleditor = new DolEditor('WEBSITE_README', $readmecontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4331 print $doleditor->Create(1, '', true, $langs->trans("File").' README.md', 'text');
4332
4333 print '</td></tr>';
4334
4335 // LICENSE
4336 print '<tr><td class="tdtop">';
4337 $htmlhelp = $langs->trans("EnterHereLicenseInformation");
4338 print $form->textwithpicto($langs->trans("File").' LICENSE', $htmlhelp, 1, 'help', '', 0, 2, 'licensetooltip');
4339 print '</td><td>';
4340
4341 $poscursor = array('x' => GETPOST('WEBSITE_LICENSE_x'), 'y' => GETPOST('WEBSITE_LICENSE_y'));
4342 $doleditor = new DolEditor('WEBSITE_LICENSE', $licensecontent, '', 220, 'ace', 'In', true, false, 'ace', 0, '100%', 0, $poscursor);
4343 print $doleditor->Create(1, '', true, $langs->trans("File").' LICENSE', 'text');
4344
4345 print '</td></tr>';
4346
4347 // RSS
4348 print '<tr><td class="tdtop">';
4349 $htmlhelp = $langs->trans('RSSFeedDesc');
4350 print $form->textwithpicto($langs->trans('RSSFeed'), $htmlhelp, 1, 'help', '', 0, 2, '');
4351 print '</td><td>';
4352 print '/wrapper.php?rss=1[&l=XX][&limit=99][&cachedelay=99]';
4353 print '</td></tr>';
4354
4355 print '</table>';
4356
4357 print dol_get_fiche_end();
4358
4359 print '</div>';
4360
4361 print '<br>';
4362}
4363
4364if ($action == 'editsecurity') {
4365 $selectarrayCSPDirectives = websiteGetContentPolicyDirectives();
4366 $selectarrayCSPSources = websiteGetContentPolicySources();
4367 $forceCSPArr = websiteGetContentPolicyToArray($forceCSP);
4368 print '<div class="fiche">';
4369 print '<br>';
4370
4371 $head = websiteconfigPrepareHead($object);
4372 print dol_get_fiche_head($head, 'security', $langs->trans("General"), -1, 'website');
4373
4374 print '<span class="opacitymedium">'.$langs->trans("HTTPHeaderEditor").'. '.$langs->trans("ReservedToAdvancedUsers").'.</span><br><br>';
4375
4376 print '<div class="div-table-responsive-no-min">';
4377 print '<table class="noborder centpercent">';
4378 print '<tr class="liste_titre">';
4379 print '<td>'.$langs->trans("HTTPHeader").'</td>';
4380 print '<td></td>'."\n";
4381 print '</tr>';
4382
4383 // Force RP
4384 print '<tr class="oddeven">';
4385 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>';
4386 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>';
4387 print '</tr>';
4388 // Force STS
4389 print '<tr class="oddeven">';
4390 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>';
4391 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>';
4392 print '</tr>';
4393 // Force PP
4394 print '<tr class="oddeven">';
4395 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>';
4396 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>';
4397 print '</tr>';
4398
4399 $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;";
4400
4401 // Force CSP - Content Security Policy
4402 print '<tr class="oddeven nohover">';
4403 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>';
4404 print '<td>';
4405
4406 print '<div class="div-table-responsive-no-min">';
4407
4408 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>';
4409
4410 print '<br class="selectaddcontentsecuritypolicy hidden">';
4411
4412 print '<div id="selectaddcontentsecuritypolicy" class="hidden selectaddcontentsecuritypolicy">';
4413 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');
4414 print ' ';
4415 print '<input type="hidden" id="select_source_WEBSITE_SECURITY_FORCECSP" name="select_source_WEBSITE_SECURITY_FORCECSP">';
4416 foreach ($selectarrayCSPSources as $key => $values) {
4417 print '<div class="div_WEBSITE_SECURITY_FORCECSP hidden inline-block maxwidth350" id="div_'.$key.'_WEBSITE_SECURITY_FORCECSP">';
4418 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');
4419 print '</div>';
4420 }
4421 print ' ';
4422 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>';
4423 print ' ';
4424 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>';
4425 print '<br><br>';
4426 print '</div>';
4427
4428 if (!empty($forceCSP)) {
4429 // Content Security Policy list of selected rules
4430 print '<br>';
4431 print '<div class="div-table-responsive-no-min">';
4432 print img_picto('', 'graph', 'class="pictofixedwidth"').$langs->trans("HierarchicView").'<br>';
4433 print '<ul>';
4434 foreach ($forceCSPArr as $directive => $sources) {
4435 print '<li>';
4436 if (in_array($directive, array_keys($selectarrayCSPDirectives))) {
4437 print '<span>'.$directive.'</span>';
4438 } else {
4439 print $form->textwithpicto($directive, $langs->trans("UnknowContentSecurityPolicyDirective"), 1, 'warning');
4440 }
4441 if (!empty($sources)) {
4442 print '<ul>';
4443 foreach ($sources as $key => $source) {
4444 print '<li><span>'.$source.'</span>&nbsp;<a href="'.$_SERVER["PHP_SELF"].'?websiteid='.$websiteid.'&action=removecspsource&sourcecsp='.$directive.'_'.$key.'&token='.newToken().'">'.img_delete().'</a></li>';
4445 }
4446 print '</ul>';
4447 } else {
4448 print '&nbsp;<a href="'.$_SERVER["PHP_SELF"].'?websiteid='.$websiteid.'&action=removecspsource&sourcecsp='.$directive.'&token='.newToken().'">'.img_delete().'</a>';
4449 }
4450 print '</li>';
4451 }
4452 print '</ul>';
4453 print '</div>';
4454 }
4455 print '</div>';
4456
4457 print '</td>';
4458 print '</tr>';
4459
4460 // Force CSPRO
4461 if (getDolGlobalString("WEBSITE_".$object->id."_SECURITY_FORCECSPRO")) {
4462 print '<tr class="oddeven">';
4463 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>';
4464 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>';
4465 print '</tr>';
4466 }
4467
4468 print '</table>';
4469 print '</div>';
4470
4471
4472 print '<div class="center">';
4473
4474 print '<input type="submit" class="button small" name="updateandstay" value="'.$langs->trans("Save").'">';
4475 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
4476
4477 print '</div>';
4478
4479
4480 print '<script>
4481 $(document).ready(function() {
4482 $("#btnaddcontentsecuritypolicy").on("click", function(){
4483 if($("#selectaddcontentsecuritypolicy").is(":visible")){
4484 console.log("We hide select to add Content Security Policy");
4485 $(".selectaddcontentsecuritypolicy").hide();
4486 } else {
4487 console.log("We show select to add Content Security Policy");
4488 $(".selectaddcontentsecuritypolicy").show();
4489 }
4490 });
4491
4492 $("#select_identifier_WEBSITE_SECURITY_FORCECSP").on("change", function() {
4493 key = $(this).find(":selected").data("directivetype");
4494 console.log("We hide all select div");
4495 $(".div_WEBSITE_SECURITY_FORCECSP").hide();
4496 $(".select_WEBSITE_SECURITY_FORCECSP").val(null).trigger("change");
4497 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").hide();
4498 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4499 if (key == "none"){
4500 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4501 } else {
4502 console.log("We show div select with key "+key);
4503 $("#div_"+key+"_WEBSITE_SECURITY_FORCECSP").css("display", "inline-block");
4504 }
4505 });
4506
4507 $(".select_WEBSITE_SECURITY_FORCECSP").on("change", function() {
4508 keysource = $(this).find(":selected").data("sourcetype");
4509 $("#select_source_WEBSITE_SECURITY_FORCECSP").val($(this).val());
4510 console.log("We hide and show fields");
4511 if (keysource == "data" || keysource == "input") {
4512 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").css("display", "inline-block");
4513 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4514 } else {
4515 $("#input_data_WEBSITE_SECURITY_FORCECSP").val("");
4516 $(".div_input_data_WEBSITE_SECURITY_FORCECSP").hide();
4517 if (keysource != undefined) {
4518 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4519 } else {
4520 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4521 }
4522 }
4523 });
4524
4525 $("#input_data_WEBSITE_SECURITY_FORCECSP").on("change keyup", function(){
4526 if ($(this).val() != "") {
4527 console.log("We show add button");
4528 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",false);
4529 } else {
4530 console.log("We hide add button");
4531 $("#btn_WEBSITE_SECURITY_FORCECSP").prop("disabled",true);
4532 }
4533 });
4534 });
4535 </script>';
4536
4537 print dol_get_fiche_end();
4538 print '</div>';
4539}
4540
4541
4542if ($action == 'createsite') {
4543 print '<div class="fiche">';
4544
4545 print '<br>';
4546
4547 /*$h = 0;
4548 $head = array();
4549
4550 $head[$h][0] = dol_buildpath('/website/index.php',1).'?id='.$object->id;
4551 $head[$h][1] = $langs->trans("AddWebsite");
4552 $head[$h][2] = 'card';
4553 $h++;
4554
4555 print dol_get_fiche_head($head, 'card', '', -1, 'website');
4556 */
4557 if ($action == 'createcontainer') {
4558 print load_fiche_titre($langs->trans("AddWebsite"));
4559 }
4560
4561 print '<!-- Add site -->'."\n";
4562 print '<div class="tabBar tabBarWithBottom">';
4563
4564 print '<table class="border centpercent">';
4565
4566 $siteref = $sitedesc = $sitelang = $siteotherlang = '';
4567 if (GETPOST('WEBSITE_REF')) {
4568 $siteref = GETPOST('WEBSITE_REF', 'aZ09');
4569 }
4570 if (GETPOST('WEBSITE_DESCRIPTION')) {
4571 $sitedesc = GETPOST('WEBSITE_DESCRIPTION', 'alpha');
4572 }
4573 if (GETPOST('WEBSITE_LANG')) {
4574 $sitelang = GETPOST('WEBSITE_LANG', 'aZ09');
4575 }
4576 if (GETPOST('WEBSITE_OTHERLANG')) {
4577 $siteotherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
4578 }
4579
4580 print '<tr><td class="titlefieldcreate fieldrequired">';
4581 print $form->textwithpicto($langs->trans('WebsiteName'), $langs->trans("Example").': MyPortal, www.mywebsite.com, ...');
4582 print '</td><td>';
4583 print '<input type="text" class="flat maxwidth300" name="WEBSITE_REF" value="'.dol_escape_htmltag($siteref).'" autofocus>';
4584 print '</td></tr>';
4585
4586 print '<tr><td class="fieldrequired">';
4587 print $langs->trans('MainLanguage');
4588 print '</td><td>';
4589 $shortlangcode = preg_replace('/[_-].*$/', '', trim($langs->defaultlang));
4590 print img_picto('', 'language', 'class="pictofixedwidth"');
4591 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);
4592 print '</td></tr>';
4593
4594 print '<tr><td>';
4595 $htmltext = $langs->trans("Example").': fr,de,sv,it,pt';
4596 print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2);
4597 print '</td><td>';
4598 print img_picto('', 'language', 'class="pictofixedwidth"');
4599 print '<input type="text" class="flat minwidth300" name="WEBSITE_OTHERLANG" value="'.dol_escape_htmltag($siteotherlang).'">';
4600 print '</td></tr>';
4601
4602 print '<tr><td>';
4603 print $langs->trans('Description');
4604 print '</td><td>';
4605 print '<input type="text" class="flat minwidth500" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($sitedesc).'">';
4606 print '</td></tr>';
4607
4608 print '<tr><td>';
4609
4610 $htmltext = $langs->trans("VirtualhostDesc");
4611 /*$htmltext = str_replace('{s1}', DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/<i>websiteref</i>', $htmltext);
4612 $htmltext .= '<br>';
4613 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
4614 $htmltext .= '<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), '{s1}');
4615 $htmltext = str_replace('{s1}', DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias', $htmltext);*/
4616
4617
4618 print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, '');
4619 print '</td><td>';
4620 print '<input type="text" class="flat minwidth300" name="virtualhost" value="'.dol_escape_htmltag(GETPOST('virtualhost', 'alpha')).'">';
4621 print '</td></tr>';
4622
4623 print '</table>';
4624 print '</div>';
4625
4626 if ($action == 'createsite') {
4627 print '<div class="center">';
4628
4629 print '<input type="submit" class="button small" name="addcontainer" value="'.$langs->trans("Create").'">';
4630 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
4631
4632 print '</div>';
4633 }
4634
4635
4636 //print '</div>';
4637
4638 //print dol_get_fiche_end();
4639
4640 print '</div>';
4641
4642 print '<br>';
4643}
4644
4645// Page view to import a website template
4646if ($action == 'importsite') {
4647 print '<!-- action=importsite -->';
4648 print '<div class="fiche">';
4649
4650 print '<br>';
4651
4652 print load_fiche_titre($langs->trans("ImportSite"));
4653
4654 print dol_get_fiche_head(array(), '0', '', -1);
4655
4656 print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToImport").'</span><br><br>';
4657
4658
4659 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
4660 $allowimportsite = true;
4661 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
4662 $allowimportsite = false;
4663 }
4664
4665 if ($allowimportsite) {
4666 $maxfilesizearray = getMaxFileSizeArray();
4667 $maxmin = $maxfilesizearray['maxmin'];
4668 if ($maxmin > 0) {
4669 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
4670 }
4671 print '<input class="flat minwidth400" type="file" name="userfile[]" accept=".zip">';
4672 print '<input type="submit" class="button small" name="buttonsubmitimportfile" value="'.dol_escape_htmltag($langs->trans("Upload")).'">';
4673 print '<input type="submit" class="button button-cancel small" name="preview" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4674 print '<br><br><br>';
4675 } else {
4676 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
4677 // Show clean corporate message
4678 $message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
4679 } else {
4680 // Show technical generic message
4681 $message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
4682 }
4683 print info_admin($message).'<br><br>';
4684 }
4685
4686
4687 print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToLoad").'</span><br><br>';
4688
4689 // This will scan the dir /doctemplates/websites and show all templates.
4690 showWebsiteTemplates($website, GETPOSTINT('importsite') == 2 ? 1 : 0);
4691
4692 print dol_get_fiche_end();
4693
4694 print '</div>';
4695
4696 print '<br>';
4697}
4698
4699if ($action == 'editmeta' || $action == 'createcontainer') { // Edit properties of a web site OR properties of a web page
4700 print '<div class="fiche">';
4701
4702 print '<br>';
4703
4704 /*$h = 0;
4705 $head = array();
4706
4707 $head[$h][0] = dol_buildpath('/website/index.php',1).'?id='.$object->id;
4708 $head[$h][1] = $langs->trans("AddPage");
4709 $head[$h][2] = 'card';
4710 $h++;
4711
4712 print dol_get_fiche_head($head, 'card', '', -1, 'website');
4713 */
4714 if ($action == 'createcontainer') {
4715 print load_fiche_titre($langs->trans("AddPage"));
4716 }
4717
4718 print '<!-- Edit or create page/container -->'."\n";
4719 //print '<div class="fichecenter">';
4720
4721 $hiddenfromfetchingafterload = ' hideobject';
4722 $hiddenmanuallyafterload = ' hideobject';
4723 if (GETPOST('radiocreatefrom') == 'checkboxcreatefromfetching') {
4724 $hiddenfromfetchingafterload = '';
4725 }
4726 if (GETPOST('radiocreatefrom') == 'checkboxcreatemanually') {
4727 $hiddenmanuallyafterload = '';
4728 }
4729
4730 if ($action == 'editmeta' || empty($conf->use_javascript_ajax)) { // No autohide/show in such case
4731 $hiddenfromfetchingafterload = '';
4732 $hiddenmanuallyafterload = '';
4733 }
4734
4735 if ($action == 'createcontainer') {
4736 print '<br>';
4737
4738 if (!empty($conf->use_javascript_ajax)) {
4739 print '<input type="radio" name="radiocreatefrom" id="checkboxcreatemanually" value="checkboxcreatemanually"'.(GETPOST('radiocreatefrom') == 'checkboxcreatemanually' ? ' checked' : '').'> ';
4740 }
4741 print '<label for="checkboxcreatemanually"><span class="opacitymediumxx">'.$langs->trans("OrEnterPageInfoManually").'</span></label><br>';
4742 print '<hr class="tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
4743 }
4744
4745
4746
4747 print '<table class="border tableforfield nobackground centpercent tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
4748
4749 if ($action != 'createcontainer') {
4750 print '<tr><td class="titlefield fieldrequired">';
4751 print $langs->trans('IDOfPage').' - '.$langs->trans('InternalURLOfPage');
4752 print '</td><td>';
4753 print $pageid;
4754 //print '</td></tr>';
4755
4756 //print '<tr><td class="titlefield fieldrequired">';
4757 //print $langs->trans('InternalURLOfPage');
4758 //print '</td><td>';
4759 print ' &nbsp; - &nbsp; ';
4760 print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode((string) $pageid);
4761 //if ($objectpage->grabbed_from) print ' - <span class="opacitymedium">'.$langs->trans('InitiallyGrabbedFrom').' '.$objectpage->grabbed_from.'</span>';
4762 print '</td></tr>';
4763
4764 $type_container = $objectpage->type_container;
4765 $pageurl = $objectpage->pageurl;
4766 $pagealiasalt = $objectpage->aliasalt;
4767 $pagetitle = $objectpage->title;
4768 $pagedescription = $objectpage->description;
4769 $pageimage = $objectpage->image;
4770 $pagekeywords = $objectpage->keywords;
4771 $pagelang = $objectpage->lang;
4772 $pageallowedinframes = $objectpage->allowed_in_frames;
4773 $pagehtmlheader = $objectpage->htmlheader;
4774 $pagedatecreation = (string) $objectpage->date_creation;
4775 $pagedatemodification = $objectpage->date_modification;
4776 $pageauthorid = $objectpage->fk_user_creat;
4777 $pageusermodifid = $objectpage->fk_user_modif;
4778 $pageauthoralias = $objectpage->author_alias;
4779 $pagestatus = $objectpage->status;
4780 } else { // $action = 'createcontainer'
4781 $type_container = 'page';
4782 $pageurl = '';
4783 $pagealiasalt = '';
4784 $pagetitle = '';
4785 $pagedescription = '';
4786 $pageimage = '';
4787 $pagekeywords = '';
4788 $pagelang = '';
4789 $pageallowedinframes = 0;
4790 $pagehtmlheader = '';
4791 $pagedatecreation = dol_now();
4792 $pagedatemodification = '';
4793 $pageauthorid = $user->id;
4794 $pageusermodifid = 0;
4795 $pageauthoralias = '';
4796 $pagestatus = 1;
4797 }
4798 if (GETPOST('WEBSITE_TITLE', 'alpha')) {
4799 $pagetitle = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
4800 }
4801 if (GETPOST('WEBSITE_PAGENAME', 'alpha')) {
4802 $pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha');
4803 }
4804 if (GETPOST('WEBSITE_ALIASALT', 'alpha')) {
4805 $pagealiasalt = str_replace(array('<', '>'), '', GETPOST('WEBSITE_ALIASALT', 'alphanohtml'));
4806 }
4807 if (GETPOST('WEBSITE_DESCRIPTION', 'alpha')) {
4808 $pagedescription = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
4809 }
4810 if (GETPOST('WEBSITE_IMAGE', 'alpha')) {
4811 $pageimage = GETPOST('WEBSITE_IMAGE', 'alpha');
4812 }
4813 if (GETPOST('WEBSITE_KEYWORDS', 'alpha')) {
4814 $pagekeywords = str_replace(array('<', '>'), '', GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'));
4815 }
4816 if (GETPOST('WEBSITE_LANG', 'aZ09')) {
4817 $pagelang = GETPOST('WEBSITE_LANG', 'aZ09');
4818 }
4819 if (GETPOST('WEBSITE_ALLOWED_IN_FRAMES', 'aZ09')) {
4820 $pageallowedinframes = 1;
4821 }
4822 if (GETPOST('htmlheader', 'restricthtmlallowlinkscript')) { // Must accept tags like '<script>' and '<link>'
4823 $pagehtmlheader = GETPOST('htmlheader', 'restricthtmlallowlinkscript');
4824 }
4825
4826 if ($action != 'createcontainer') {
4827 if (empty($conf->use_javascript_ajax)) {
4828 print '<!-- Status of web site page -->'."\n";
4829 print '<tr><td class="fieldrequired">';
4830 print $langs->trans('Status');
4831 print '</td><td>';
4832 print $form->selectyesno('status', $objectpage->status);
4833 print '</td></tr>';
4834 }
4835 }
4836
4837 // Type of container
4838 print '<tr><td class="titlefield fieldrequired">';
4839 print $langs->trans('WEBSITE_TYPE_CONTAINER');
4840 print '</td><td>';
4841 print img_picto('', 'object_technic', 'class="paddingrightonly"').' ';
4842 print $formwebsite->selectTypeOfContainer('WEBSITE_TYPE_CONTAINER', (GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha') ? GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha') : $type_container), 0, '', 1, 'minwidth300');
4843 print '</td></tr>';
4844
4845 print '<script type="text/javascript">
4846 jQuery(document).ready(function() {
4847 jQuery("#selectWEBSITE_TYPE_CONTAINER").change(function() {
4848 console.log("We change type of page : "+jQuery("#selectWEBSITE_TYPE_CONTAINER").val());
4849 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'blogpost\') {
4850 jQuery(".trpublicauthor").show();
4851 } else {
4852 jQuery(".trpublicauthor").hide();
4853 }
4854 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'service\' || jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'library\') {
4855 $(".spanprefix").html("_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_");
4856 jQuery(".spanprefix").show();
4857 } else {
4858 jQuery(".spanprefix").hide();
4859 }
4860 });
4861
4862 // Force at init execution a first time of the handler change
4863 jQuery("#selectWEBSITE_TYPE_CONTAINER").trigger(\'change\');
4864 });
4865 </script>
4866 ';
4867
4868 // Title
4869 print '<tr><td class="fieldrequired">';
4870 print $langs->trans('WEBSITE_TITLE');
4871 print '</td><td>';
4872 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_TITLE" id="WEBSITE_TITLE" value="'.dol_escape_htmltag($pagetitle).'" autofocus>';
4873 print '</td></tr>';
4874
4875 // Alias page
4876 print '<tr><td class="titlefieldcreate fieldrequired">';
4877 print $langs->trans('WEBSITE_PAGENAME');
4878 print '</td><td>';
4879 print '<span class="opacitymedium spanprefix hidden"></span> ';
4880 print '<input type="text" class="flat minwidth300" name="WEBSITE_PAGENAME" id="WEBSITE_PAGENAME" value="'.dol_escape_htmltag((string) preg_replace('/^_[a-z]+_/', '', (string) $pageurl)).'">';
4881 print '</td></tr>';
4882
4883 print '<script type="text/javascript">
4884 $(document).ready(function() {
4885 console.log("Manage prefix for service or library");
4886 if ($("#selectWEBSITE_TYPE_CONTAINER").val() == "service" || $("#selectWEBSITE_TYPE_CONTAINER").val() == "library") {
4887 $(".spanprefix").html("_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_");
4888 $(".spanprefix").show();
4889 }
4890 $(".websiteformtoolbar").on("submit", function(event) {
4891 if ($("#selectWEBSITE_TYPE_CONTAINER").val() == "service" || $("#selectWEBSITE_TYPE_CONTAINER").val() == "library") {
4892 var prefix = "_" + $("#selectWEBSITE_TYPE_CONTAINER").val() + "_";
4893 var userInput = $("#WEBSITE_PAGENAME").val();
4894 var $inputField = $("#WEBSITE_PAGENAME");
4895 if (userInput.indexOf(prefix) !== 0) {
4896 $inputField.val(prefix + userInput);
4897 }
4898 }
4899 });
4900 });
4901 </script>
4902 ';
4903
4904 print '<tr><td class="titlefieldcreate">';
4905 $htmlhelp = $langs->trans("WEBSITE_ALIASALTDesc");
4906 print $form->textwithpicto($langs->trans('WEBSITE_ALIASALT'), $htmlhelp, 1, 'help', '', 0, 2, 'aliastooltip');
4907 print '</td><td>';
4908 print '<input type="text" class="flat minwidth500" name="WEBSITE_ALIASALT" value="'.dol_escape_htmltag($pagealiasalt).'">';
4909 print '</td></tr>';
4910
4911 print '<tr><td>';
4912 print $langs->trans('WEBSITE_DESCRIPTION');
4913 print '</td><td>';
4914 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_DESCRIPTION" value="'.dol_escape_htmltag($pagedescription).'">';
4915 print '</td></tr>';
4916
4917 // Deprecated. Image for RSS or Thumbs are now taken from the content.
4918 if (getDolGlobalInt('WEBSITE_MANAGE_IMAGE_FOR_PAGES')) {
4919 print '<tr class="trimageforpage hidden"><td>';
4920 $htmlhelp = $langs->trans("WEBSITE_IMAGEDesc");
4921 print $form->textwithpicto($langs->trans('WEBSITE_IMAGE'), $htmlhelp, 1, 'help', '', 0, 2, 'imagetooltip');
4922 print '</td><td>';
4923 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_IMAGE" value="'.dol_escape_htmltag($pageimage).'">';
4924 print '</td></tr>';
4925
4926 print '<script type="text/javascript">
4927 jQuery(document).ready(function() {
4928 jQuery("#selectWEBSITE_TYPE_CONTAINER").change(function() {
4929 console.log("We change type of page : "+jQuery("#selectWEBSITE_TYPE_CONTAINER").val());
4930 if (jQuery("#selectWEBSITE_TYPE_CONTAINER").val() == \'blogpost\') {
4931 jQuery(".trimageforpage").show();
4932 } else {
4933 jQuery(".trimageforpage").hide();
4934 }
4935 });
4936 });
4937 </script>
4938 ';
4939 }
4940
4941 // Keywords
4942 print '<tr><td>';
4943 $htmlhelp = $langs->trans("WEBSITE_KEYWORDSDesc");
4944 print $form->textwithpicto($langs->trans('WEBSITE_KEYWORDS'), $htmlhelp, 1, 'help', '', 0, 2, 'keywordtooltip');
4945 print '</td><td>';
4946 print '<input type="text" class="flat quatrevingtpercent" name="WEBSITE_KEYWORDS" value="'.dol_escape_htmltag($pagekeywords).'">';
4947 print '</td></tr>';
4948
4949 print '<tr><td>';
4950 print $langs->trans('Language');
4951 print '</td><td>';
4952 $onlykeys = array();
4953 if ($object->lang) {
4954 $onlykeys[$object->lang] = $object->lang;
4955 } else {
4956 $onlykeys[$langs->defaultlang] = $langs->defaultlang;
4957 }
4958 if ($object->otherlang) {
4959 $tmparray = explode(',', $object->otherlang);
4960 foreach ($tmparray as $key) {
4961 $tmpkey = trim($key);
4962 if (strlen($key) == 2) {
4963 $tmpkey = strtolower($key);
4964 }
4965 $onlykeys[$tmpkey] = $tmpkey;
4966 }
4967 }
4968 if (empty($object->lang) && empty($object->otherlang)) {
4969 $onlykeys = array(); // We keep full list of languages
4970 }
4971 print img_picto('', 'language', 'class="pictofixedwidth"').$formadmin->select_language($pagelang ? $pagelang : '', 'WEBSITE_LANG', 0, array(), '1', 0, 0, 'minwidth200', 0, 0, 0, $onlykeys, 1);
4972 $htmltext = $langs->trans("AvailableLanguagesAreDefinedIntoWebsiteProperties");
4973 print $form->textwithpicto('', $htmltext);
4974 print '</td></tr>';
4975
4976 // Translation of
4977 $translationof = 0;
4978 $translatedby = 0;
4979 print '<!-- Translation of --><tr><td>';
4980 print $langs->trans('TranslationLinks');
4981 print '</td><td>';
4982 if ($action != 'createcontainer') {
4983 // Has translation pages
4984 $sql = "SELECT rowid, lang from ".MAIN_DB_PREFIX."website_page where fk_page = ".((int) $objectpage->id);
4985 $resql = $db->query($sql);
4986 if ($resql) {
4987 $num_rows = $db->num_rows($resql);
4988 if ($num_rows > 0) {
4989 print '<span class="opacitymedium">'.$langs->trans('ThisPageHasTranslationPages').':</span>';
4990 $i = 0;
4991 $tmppage = new WebsitePage($db);
4992 $tmpstring = '';
4993 while ($obj = $db->fetch_object($resql)) {
4994 $result = $tmppage->fetch($obj->rowid);
4995 if ($result > 0) {
4996 if ($i > 0) {
4997 $tmpstring .= '<br>';
4998 }
4999 $tmpstring .= $tmppage->getNomUrl(1).' '.picto_from_langcode($tmppage->lang).' '.$tmppage->lang;
5000 // Button unlink
5001 $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>';
5002 $translatedby++;
5003 $i++;
5004 }
5005 }
5006 if ($i > 1) {
5007 print '<br>';
5008 } else {
5009 print ' ';
5010 }
5011 print $tmpstring;
5012 }
5013 } else {
5014 dol_print_error($db);
5015 }
5016 }
5017 if ((empty($translatedby) || ($objectpage->lang != $object->lang)) && ($action == 'editmeta' || $action == 'createcontainer' || $objectpage->fk_page > 0)) {
5018 $sourcepage = new WebsitePage($db);
5019 $result = 1;
5020 if ($objectpage->fk_page > 0) {
5021 $result = $sourcepage->fetch($objectpage->fk_page);
5022 if ($result == 0) {
5023 // not found, we can reset value to clean database
5024 // TODO
5025 }
5026 }
5027 if ($result >= 0) {
5028 if ($translatedby) {
5029 print '<br>';
5030 }
5031 $translationof = $objectpage->fk_page;
5032 print '<span class="opacitymedium">'.$langs->trans('ThisPageIsTranslationOf').'</span> ';
5033 print $sourcepage->getNomUrl(2).' '.$formwebsite->selectContainer($website, 'pageidfortranslation', ($translationof ? $translationof : -1), 1, $action, 'minwidth300', array($objectpage->id));
5034 if ($translationof > 0 && $sourcepage->lang) {
5035 print picto_from_langcode($sourcepage->lang).' '.$sourcepage->lang;
5036 // Button unlink
5037 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>';
5038 }
5039 }
5040 }
5041 print '</td></tr>';
5042
5043 // Categories
5044 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5045 $disabled = '';
5046 $langs->load('categories');
5047
5048 print '<tr><td class="toptd">'.$form->editfieldkey('Categories', 'categories', '', $objectpage, 0).'</td><td>';
5049 print $form->selectCategories(Categorie::TYPE_WEBSITE_PAGE, 'categories', $objectpage);
5050 //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);
5051 print "</td></tr>";
5052 }
5053
5054 if (getDolGlobalString('WEBSITE_PAGE_SHOW_INTERNAL_LINKS_TO_OBJECT')) { // TODO Replace this with link into element_element ?
5055 print '<tr><td class="titlefieldcreate">';
5056 print 'ObjectClass';
5057 print '</td><td>';
5058 print '<input type="text" class="flat minwidth300" name="WEBSITE_OBJECTCLASS" placeholder="ClassName::/path/class/ObjectClass.class.php" >';
5059 print '</td></tr>';
5060
5061 print '<tr><td class="titlefieldcreate">';
5062 print 'ObjectID';
5063 print '</td><td>';
5064 print '<input type="text" class="flat minwidth300" name="WEBSITE_OBJECTID" >';
5065 print '</td></tr>';
5066 }
5067
5068 $fuser = new User($db);
5069
5070 // Date last modification
5071 if ($action != 'createcontainer') {
5072 print '<tr><td>';
5073 print $langs->trans('DateLastModification');
5074 print '</td><td>';
5075 print dol_print_date($pagedatemodification, 'dayhour', 'tzuser');
5076 print '</td></tr>';
5077
5078 print '<tr><td>';
5079 print $langs->trans('UserModification');
5080 print '</td><td>';
5081 if ($pageusermodifid > 0) {
5082 $fuser->fetch($pageusermodifid);
5083 print $fuser->getNomUrl(-1);
5084 } else {
5085 print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>';
5086 }
5087 print '</td></tr>';
5088 }
5089
5090 // Content - Example/templates of page
5091 $url = 'https://wiki.dolibarr.org/index.php/Module_Website';
5092 $htmltext = '<small>';
5093 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource", $url);
5094 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource1", $url);
5095 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource2", $url);
5096 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource3", $url);
5097 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSource4", $url);
5098 $htmltext .= $langs->transnoentitiesnoconv("YouCanEditHtmlSourceMore", $url);
5099 $htmltext .= '<br>';
5100 $htmltext .= '</small>';
5101
5102 $formmail = new FormMail($db);
5103 $formmail->withaiprompt = 'html';
5104 $formmail->withlayout = 'websitepage';
5105 $showlinktolayout = $formmail->withlayout;
5106 $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationwebpage' : '';
5107 if (($action == 'createcontainer' && $showlinktolayout) || ($action == 'createcontainer' && $showlinktoai)) {
5108 print '<tr><td class="titlefield tdtop">';
5109 if ($conf->browser->layout == 'phone') {
5110 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
5111 } else {
5112 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
5113 print $form->textwithpicto($langs->trans("PreviewPageContent").' '.img_help(2, $langs->trans("PreviewPageContent")), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
5114 }
5115 print '</td><td class="tdtop">';
5116
5117 $out = '';
5118
5119 $showlinktolayoutlabel = $langs->trans("FillPageWithALayout");
5120 $showlinktoailabel = $langs->trans("FillPageWithAIContent");
5121 $htmlname = 'content';
5122 // Fill $out
5123 include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
5124
5125 print $out;
5126 print '</td></tr>';
5127 }
5128
5129 if ($action == 'createcontainer') {
5130 print '<tr id="pageContent"><td class="tdtop">';
5131 if (!$showlinktolayout || !$showlinktoai) {
5132 if ($conf->browser->layout == 'phone') {
5133 print $form->textwithpicto('', $htmltext, 1, 'help', 'inline-block', 1, 2, 'tooltipsubstitution');
5134 } else {
5135 //img_help(($tooltiptrigger != '' ? 2 : 1), $alt)
5136 print $form->textwithpicto($showlinktolayout ? '' : ($langs->trans("PreviewPageContent").' '.img_help(2, $langs->trans("PreviewPageContent"))), $htmltext, 1, 'none', 'inline-block', 1, 2, 'tooltipsubstitution');
5137 }
5138 }
5139 print '</td><td>';
5140 //$doleditor = new DolEditor('content', GETPOST('content', 'restricthtmlallowunvalid'), '', 200, 'dolibarr_mailings', 'In', true, true, true, 40, '90%');
5141 $doleditor = new DolEditor('content', GETPOST('content', 'none'), '', 200, 'dolibarr_mailings', 'In', true, true, true, 40, '90%');
5142 $doleditor->Create();
5143 print '</div>';
5144 print '</td></tr>';
5145 }
5146
5147 // Date creation
5148 print '<tr><td>';
5149 print $langs->trans('DateCreation');
5150 print '</td><td>';
5151 print $form->selectDate($pagedatecreation, 'datecreation', 1, 1, 0, '', 1, 1);
5152 //print dol_print_date($pagedatecreation, 'dayhour');
5153 print '</td></tr>';
5154
5155 // Author
5156 print '<tr><td>';
5157 print $langs->trans('Author');
5158 print '</td><td>';
5159 if ($pageauthorid > 0) {
5160 $fuser->fetch($pageauthorid);
5161 print $fuser->getNomUrl(-1);
5162 } else {
5163 print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>';
5164 }
5165 print '</td></tr>';
5166
5167 // Author - public alias
5168 print '<tr class="trpublicauthor hidden"><td>';
5169 print $langs->trans('PublicAuthorAlias');
5170 print '</td><td>';
5171 print '<input type="text" class="flat minwidth300" name="WEBSITE_AUTHORALIAS" value="'.dol_escape_htmltag($pageauthoralias).'" placeholder="'.dol_escape_htmltag($langs->trans("Anonymous")).'">';
5172 print '</td></tr>';
5173
5174 // Web page header
5175 print '<tr><td class="tdhtmlheader tdtop">';
5176 $htmlhelp = $langs->trans("EditTheWebSiteForACommonHeader").'<br><br>';
5177 $htmlhelp .= $langs->trans("Examples").' :<br>';
5178 $htmlhelp .= '<span class="small">';
5179 $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.
5180 $htmlhelp .= '</span>';
5181 print $form->textwithpicto($langs->transnoentitiesnoconv('HtmlHeaderPage'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
5182 print '</td><td>';
5183 $poscursor = array('x' => GETPOST('htmlheader_x'), 'y' => GETPOST('htmlheader_y'));
5184 $doleditor = new DolEditor('htmlheader', $pagehtmlheader, '', 160, 'ace', 'In', true, false, 'ace', ROWS_4, '100%', 0, $poscursor);
5185 print $doleditor->Create(1, '', true, 'HTML Header', 'html');
5186 print '</td></tr>';
5187
5188 // Allowed in frames
5189 print '<tr><td>';
5190 print $langs->trans('AllowedInFrames');
5191 //$htmlhelp = $langs->trans("AllowedInFramesDesc");
5192 //print $form->textwithpicto($langs->trans('AllowedInFrames'), $htmlhelp, 1, 'help', '', 0, 2, 'allowedinframestooltip');
5193 print '</td><td>';
5194 print '<input type="checkbox" class="flat" name="WEBSITE_ALLOWED_IN_FRAMES" value="1"'.($pageallowedinframes ? 'checked="checked"' : '').'>';
5195 print '</td></tr>';
5196
5197 print '</table>';
5198
5199
5200 if ($action == 'createcontainer') {
5201 $langs->load("website");
5202
5203 print '<div class="center tablecheckboxcreatemanually'.$hiddenmanuallyafterload.'">';
5204
5205 print '<input type="submit" class="button small buttonforacesave" name="addcontainer" value="'.$langs->trans("Create").'">';
5206 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
5207
5208 print '</div>';
5209
5210 print '<br>';
5211
5212 if (!empty($conf->use_javascript_ajax)) {
5213 print '<input type="radio" name="radiocreatefrom" id="checkboxcreatefromfetching" value="checkboxcreatefromfetching"'.(GETPOST('radiocreatefrom') == 'checkboxcreatefromfetching' ? ' checked' : '').'> ';
5214 }
5215 print '<label for="checkboxcreatefromfetching"><span class="opacitymediumxx">'.$langs->trans("CreateByFetchingExternalPage").'</span> <span class="small opacitymedium">('.$langs->trans("ForAdvancedWebmastersOnly").')</small></label><br>';
5216 print '<hr class="tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload.'">';
5217
5218 print info_admin($langs->trans("OnlyEditionOfSourceForGrabbedContentFuture"), 0, 0, 'warning tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload);
5219 print '<br>';
5220
5221 print '<table class="tableforfield centpercent tablecheckboxcreatefromfetching'.$hiddenfromfetchingafterload.'">';
5222 print '<tr><td class="titlefield tdtop">';
5223 print $langs->trans("URL");
5224 print '</td><td>';
5225 print '<input class="flat minwidth500 marginbottomonly" type="text" name="externalurl" value="'.dol_escape_htmltag(GETPOST('externalurl', 'alpha')).'" placeholder="https://externalsite/pagetofetch"> ';
5226 print '<br>';
5227 print '<div class="paddingtop">';
5228 print '<input class="flat paddingtop paddingright" type="checkbox" name="grabimages" value="1" checked="checked">';
5229 print '<span class="valignmiddle">'.$langs->trans("GrabImagesInto");
5230 print ' ';
5231 print $langs->trans("ImagesShouldBeSavedInto").' ';
5232 print '</span>';
5233 $arraygrabimagesinto = array('root' => $langs->trans("WebsiteRootOfImages"), 'subpage' => $langs->trans("SubdirOfPage"));
5234 print $form->selectarray('grabimagesinto', $arraygrabimagesinto, GETPOSTISSET('grabimagesinto') ? GETPOST('grabimagesinto') : 'root', 0, 0, 0, '', 0, 0, 0, '', 'minwidth75 valignmiddle', 1);
5235 print '</div>';
5236
5237 print '<input class="button small" style="margin-top: 5px" type="submit" name="fetchexternalurl" value="'.dol_escape_htmltag($langs->trans("FetchAndCreate")).'">';
5238 print '<input class="button button-cancel small" type="submit" name="preview" value="'.$langs->trans("Cancel").'">';
5239
5240 print '</td></tr>';
5241 print '</table>';
5242 }
5243
5244 if ($action == 'createcontainer') {
5245 print '<script type="text/javascript">
5246 jQuery(document).ready(function() {
5247 var disableautofillofalias = 0;
5248 var selectedm = \'\';
5249 var selectedf = \'\';
5250
5251 jQuery("#WEBSITE_TITLE").keyup(function() {
5252 if (disableautofillofalias == 0) {
5253 var valnospecial = jQuery("#WEBSITE_TITLE").val();
5254 valnospecial = valnospecial.replace(/[éèê]/g, \'e\').replace(/[à]/g, \'a\').replace(/[ù]/g, \'u\').replace(/[î]/g, \'i\');
5255 valnospecial = valnospecial.replace(/[ç]/g, \'c\').replace(/[ö]/g, \'o\');
5256 valnospecial = valnospecial.replace(/[^\w]/gi, \'-\').toLowerCase();
5257 valnospecial = valnospecial.replace(/\-+/g, \'-\').replace(/\-$/, \'\');
5258 console.log("disableautofillofalias=0 so we replace WEBSITE_TITLE with "+valnospecial);
5259 jQuery("#WEBSITE_PAGENAME").val(valnospecial);
5260 }
5261 });
5262 jQuery("#WEBSITE_PAGENAME").keyup(function() {
5263 if (jQuery("#WEBSITE_PAGENAME").val() == \'\') {
5264 disableautofillofalias = 0;
5265 } else {
5266 disableautofillofalias = 1;
5267 }
5268 });
5269 jQuery("#WEBSITE_PAGENAME").blur(function() {
5270 if (jQuery("#WEBSITE_PAGENAME").val() == \'\') {
5271 disableautofillofalias = 0;
5272 jQuery("#WEBSITE_TITLE").trigger(\'keyup\');
5273 }
5274 });
5275
5276 jQuery("#checkboxcreatefromfetching,#checkboxcreatemanually").click(function() {
5277 console.log("we select a method to create a new container "+jQuery("#checkboxcreatefromfetching:checked").val())
5278 jQuery(".tablecheckboxcreatefromfetching").hide();
5279 jQuery(".tablecheckboxcreatemanually").hide();
5280 if (typeof(jQuery("#checkboxcreatefromfetching:checked").val()) != \'undefined\') {
5281 console.log("show create from spider form");
5282 if (selectedf != \'createfromfetching\') {
5283 jQuery(".tablecheckboxcreatefromfetching").show();
5284 selectedf = \'createfromfetching\';
5285 selectedm = \'\';
5286 } else {
5287 jQuery(".tablecheckboxcreatefromfetching").hide();
5288 selectedf = \'\';
5289 }
5290 }
5291 if (typeof(jQuery("#checkboxcreatemanually:checked").val()) != \'undefined\') {
5292 console.log("show create from scratch or template form");
5293 if (selectedm != \'createmanually\') {
5294 jQuery(".tablecheckboxcreatemanually").show();
5295 selectedm = \'createmanually\';
5296 selectedf = \'\';
5297 } else {
5298 jQuery(".tablecheckboxcreatemanually").hide();
5299 selectedm = \'\';
5300 }
5301 }
5302 });
5303 });
5304 </script>';
5305 }
5306
5307 print '</div>';
5308
5309 print '<br>';
5310}
5311
5312
5313// Print formconfirm
5314if ($action == 'preview') {
5315 print $formconfirm;
5316}
5317
5318if ($action == 'editfile' || $action == 'file_manager' || $action == 'convertimgwebp' || $action == 'confirmconvertimgwebp') {
5319 print '<!-- Edit Media -->'."\n";
5320 print '<div class="fichenopadding" style="padding-right: 20px"><br>';
5321
5322 $module = 'medias';
5323 $formalreadyopen = 2; // So the form to submit a new file will not be open another time inside the core/tpl/filemanager.tpl.php
5324 if (empty($url)) {
5325 $url = DOL_URL_ROOT.'/website/index.php'; // Must be an url without param
5326 }
5327 include DOL_DOCUMENT_ROOT.'/core/tpl/filemanager.tpl.php';
5328
5329 print '</div>';
5330}
5331
5332if ($action == 'editmenu') {
5333 print '<!-- Edit Menu -->'."\n";
5334 print '<div class="center">'.$langs->trans("FeatureNotYetAvailable").'</center>';
5335}
5336
5337if ($action == 'editsource') {
5338 // Editing with source editor
5339
5340 $contentforedit = '';
5341 //$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers
5342 //$contentforedit.=$csscontent;
5343 //$contentforedit.='</style>'."\n";
5344 $contentforedit .= $objectpage->content;
5345
5346 // We set maxheightwin in px. We take the height of screen in px and we remove a part for the top banner and more
5347 $maxheightwin = 480;
5348 if (isset($_SESSION["dol_screenheight"])) {
5349 if ($_SESSION["dol_screenheight"] > 680) {
5350 $maxheightwin = (int) $_SESSION["dol_screenheight"] - 300; // We remove a height for header
5351 }
5352 if ($_SESSION["dol_screenheight"] > 800) {
5353 $maxheightwin = (int) $_SESSION["dol_screenheight"] - 250; // We remove a height for header (on large width, risk to have header on 2 lines is lower)
5354 }
5355 }
5356
5357 $poscursor = array('x' => GETPOST('PAGE_CONTENT_x'), 'y' => GETPOST('PAGE_CONTENT_y'));
5358 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
5359 $doleditor = new DolEditor('PAGE_CONTENT', $contentforedit, '', $maxheightwin, 'Full', '', true, true, 'ace', ROWS_5, '40%', 0, $poscursor);
5360 $doleditor->Create(0, '', false, 'HTML Source', 'php');
5361}
5362
5363if ($action == 'editcontent') {
5364 // Editing with default ckeditor
5365
5366 $contentforedit = '';
5367 //$contentforedit.='<style scoped>'."\n"; // "scoped" means "apply to parent element only". Not yet supported by browsers
5368 //$contentforedit.=$csscontent;
5369 //$contentforedit.='</style>'."\n";
5370 $contentforedit .= $objectpage->content;
5371
5372 $nbrep = array();
5373 // If contentforedit has a string <img src="xxx", we replace the xxx with /viewimage.php?modulepart=medias&file=xxx except if xxx starts
5374 // with http, /viewimage.php or DOL_URL_ROOT./viewimage.phps
5375 $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);
5376
5377 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
5378 $poscursor = array('x' => GETPOST('PAGE_CONTENT_x'), 'y' => GETPOST('PAGE_CONTENT_y'));
5379 $doleditor = new DolEditor('PAGE_CONTENT', $contentforedit, '', 500, 'Full', '', true, true, true, ROWS_5, '90%', 0, $poscursor);
5380 $doleditor->Create(0, '', false);
5381}
5382
5383print "</div>\n";
5384print "</form>\n";
5385print '<!-- Now, output content of page ID='.($websitepage->id??'NULL').', mode= '.$mode.' WEBSITE_SUBCONTAINERSINLINE='.getDolGlobalString('WEBSITE_SUBCONTAINERSINLINE').' WEBSITE_EDITINLINE='.getDolGlobalString('WEBSITE_EDITINLINE').' -->'."\n";
5386
5387
5388if ($mode == 'replacesite' || $massaction == 'replace') {
5389 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5390 print '<input type="hidden" name="token" value="'.newToken().'">';
5391 print '<input type="hidden" name="action" value="replacesiteconfirm">';
5392 print '<input type="hidden" name="mode" value="replacesite">';
5393 print '<input type="hidden" name="website" value="'.$website->ref.'">';
5394
5395
5396 print '<!-- Search page and replace string -->'."\n";
5397 print '<div class="fiche"><br>';
5398
5399 print load_fiche_titre($langs->trans("ReplaceWebsiteContent"), '', 'search');
5400
5401 print '<div class="neutral">';
5402
5403 print '<div class="display-flex"><div class="flex-item">';
5404
5405 print '<div class="tagtable">';
5406
5407 print '<div class="tagtr">';
5408 print '<div class="tagtd paddingrightonly opacitymedium">';
5409 print $langs->trans("SearchReplaceInto");
5410 print '</div>';
5411 print '<div class="tagtd">';
5412 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>';
5413 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>';
5414 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>';
5415 print '</div>';
5416 print '</div>';
5417
5418 print '<div class="tagtr">';
5419 print '<div class="tagtd paddingrightonly opacitymedium" style="padding-right: 10px !important">';
5420 print $langs->trans("SearchString");
5421 print '</div>';
5422 print '<div class="tagtd">';
5423 print '<input type="text" name="searchstring" value="'.dol_escape_htmltag($searchkey, 0, 0, '', 1).'" autofocus>';
5424 print '</div>';
5425 print '</div>';
5426
5427 print '</div>';
5428
5429 print '</div><div class="flex-item">';
5430
5431 print '<div class="tagtable">';
5432
5433 print '<div class="tagtr">';
5434 print '<div class="tagtd paddingrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5435 print $langs->trans("WEBSITE_TYPE_CONTAINER");
5436 print '</div>';
5437 print '<div class="tagtd">';
5438 print img_picto('', 'object_technic', 'class="pictofixedwidth"').' ';
5439 print $formwebsite->selectTypeOfContainer('optioncontainertype', (GETPOST('optioncontainertype', 'alpha') ? GETPOST('optioncontainertype', 'alpha') : ''), 1, '', 1, 'minwidth125 maxwidth400 widthcentpercentminusx');
5440 print '</div>';
5441 print '</div>';
5442
5443 print '<div class="tagtr">';
5444 print '<div class="tagtd paddingrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5445 print $langs->trans("Language");
5446 print '</div>';
5447 print '<div class="tagtd">';
5448 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);
5449 print '</div>';
5450 print '</div>';
5451
5452 // Categories
5453 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5454 print '<div class="tagtr">';
5455 print '<div class="tagtd paddingrightonly marginrightonly opacitymedium tdoverflowmax100onsmartphone" style="padding-right: 10px !important">';
5456 print $langs->trans("Category");
5457 print '</div>';
5458 print '<div class="tagtd">';
5459 //print $form->selectCategories(Categorie::TYPE_WEBSITE_PAGE, 'optioncategory', $object);
5460 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');
5461 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
5462 print ajax_combobox('optioncategory');
5463 print '</div>';
5464 print '</div>';
5465 }
5466
5467 print '</div>';
5468
5469 print '</div></div>';
5470
5471 print '<center>';
5472 print '<input type="submit" class="button margintoponly" name="buttonreplacesitesearch" value="'.dol_escape_htmltag($langs->trans("Search")).'">';
5473 print '</center>';
5474
5475 print '</div>';
5476
5477
5478 if ($mode == 'replacesite') {
5479 print '<!-- List of search result -->'."\n";
5480 print '<div class="rowsearchresult clearboth">';
5481
5482 print '<br>';
5483 print '<br>';
5484
5485 if ($listofpages['code'] == 'OK') {
5486 $arrayofselected = is_array($toselect) ? $toselect : array();
5487 $param = '';
5488 $nbtotalofrecords = count($listofpages['list']);
5489 $num = $limit;
5490 $permissiontodelete = $user->hasRight('website', 'delete');
5491
5492 // List of mass actions available
5493 $arrayofmassactions = array();
5494 if ($user->hasRight('website', 'writephp') && $searchkey) {
5495 $arrayofmassactions['replace'] = img_picto('', 'replacement', 'class="pictofixedwidth"').$langs->trans("Replace");
5496 }
5497 if ($user->hasRight('website', 'write')) {
5498 $langs->load("categories");
5499 $arrayofmassactions['setcategory'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("ClassifyInCategory");
5500 }
5501 if ($user->hasRight('website', 'write')) {
5502 $langs->load("categories");
5503 $arrayofmassactions['delcategory'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("RemoveCategory");
5504 }
5505 if ($permissiontodelete) {
5506 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
5507 }
5508 if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
5509 $arrayofmassactions = array();
5510 }
5511
5512 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
5513 $massactionbutton .= '<div class="massactionother massactionreplace hidden">';
5514 $massactionbutton .= $langs->trans("ReplaceString");
5515 $massactionbutton .= ' <input type="text" name="replacestring" value="'.dol_escape_htmltag(GETPOST('replacestring', 'none')).'">';
5516 $massactionbutton .= '</div>';
5517 $massactionbutton .= '<div class="massactionother massactionsetcategory massactiondelcategory hidden">';
5518 $massactionbutton .= img_picto('', 'category', 'class="pictofixedwidth"');
5519 $massactionbutton .= $form->select_all_categories(Categorie::TYPE_WEBSITE_PAGE, GETPOSTISSET('setcategory') ? GETPOST('setcategory') : '', 'setcategory', 64, 0, 0, 0, 'minwidth300 alignstart');
5520 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
5521 $massactionbutton .= ajax_combobox('setcategory');
5522 $massactionbutton .= '</div>';
5523
5524 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
5525
5526 //$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields
5527 $selectedfields = '';
5528 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
5529
5530 print_barre_liste($langs->trans("Results"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit, 1, 1, 1);
5531
5532 $topicmail = "WebsitePageRef";
5533 $modelmail = "websitepage_send";
5534 $objecttmp = new WebsitePage($db);
5535 $trackid = 'wsp'.$object->id;
5536 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
5537
5538 $param = 'mode=replacesite&website='.urlencode($website->ref);
5539 $param .= '&searchstring='.urlencode($searchkey);
5540 if (GETPOST('optionpcontent')) {
5541 $param .= '&optionpcontent=content';
5542 }
5543 if (GETPOST('optionmeta')) {
5544 $param .= '&optionmeta=meta';
5545 }
5546 if (GETPOST('optionsitefiles')) {
5547 $param .= '&optionsitefiles=optionsitefiles';
5548 }
5549 if (GETPOST('optioncontainertype')) {
5550 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5551 }
5552 if (GETPOST('optionlanguage')) {
5553 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5554 }
5555 if (GETPOST('optioncategory')) {
5556 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5557 }
5558
5559 print '<div class="div-table-responsive-no-min">';
5560 print '<table class="noborder centpercent">';
5561 print '<tr class="liste_titre">';
5562 // Action column
5563 if ($conf->main_checkbox_left_column) {
5564 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
5565 }
5566 print getTitleFieldOfList("Type", 0, $_SERVER['PHP_SELF'], 'type_container', '', $param, '', $sortfield, $sortorder, '')."\n";
5567 print getTitleFieldOfList("Page", 0, $_SERVER['PHP_SELF'], 'pageurl', '', $param, '', $sortfield, $sortorder, '')."\n";
5568 print getTitleFieldOfList("Language", 0, $_SERVER['PHP_SELF'], 'lang', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
5569 print getTitleFieldOfList("Categories", 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'center ')."\n";
5570 print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']);
5571 print getTitleFieldOfList("UserCreation", 0, $_SERVER['PHP_SELF'], 'fk_user_creat', '', $param, '', $sortfield, $sortorder, '')."\n";
5572 print getTitleFieldOfList("DateCreation", 0, $_SERVER['PHP_SELF'], 'date_creation', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; // Date creation
5573 print getTitleFieldOfList("DateLastModification", 0, $_SERVER['PHP_SELF'], 'tms', '', $param, '', $sortfield, $sortorder, 'center ')."\n"; // Date last modif
5574 print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']);
5575 // Action column
5576 if (!$conf->main_checkbox_left_column) {
5577 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
5578 }
5579 print '</tr>';
5580
5581 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
5582 $c = new Categorie($db);
5583
5584 $totalnbwords = 0;
5585
5586 foreach ($listofpages['list'] as $answerrecord) {
5587 if (is_object($answerrecord) && get_class($answerrecord) == 'WebsitePage') {
5588 $param = '?mode=replacesite';
5589 $param .= '&websiteid='.$website->id;
5590 $param .= '&optionpcontent='.GETPOST('optionpcontent', 'aZ09');
5591 $param .= '&optionmeta='.GETPOST('optionmeta', 'aZ09');
5592 $param .= '&optionsitefiles='.GETPOST('optionsitefiles', 'aZ09');
5593 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5594 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5595 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5596 $param .= '&searchstring='.urlencode($searchkey);
5597
5598 print '<tr>';
5599
5600 // Action column
5601 if ($conf->main_checkbox_left_column) {
5602 print '<td class="nowrap center">';
5603
5604 print '<!-- Status of page -->'."\n";
5605 if ($massactionbutton || $massaction) {
5606 $selected = 0;
5607 if (in_array($answerrecord->id, $arrayofselected)) {
5608 $selected = 1;
5609 }
5610 print '<input id="'.$answerrecord->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$answerrecord->id.'"'.($selected ? ' checked="checked"' : '').'>';
5611 }
5612 print '</td>';
5613 }
5614
5615 // Type of container
5616 print '<td class="nowraponall">';
5617 //print $langs->trans("Container").'<br>';
5618 if (!empty($conf->cache['type_of_container'][$answerrecord->type_container])) {
5619 print $langs->trans($conf->cache['type_of_container'][$answerrecord->type_container]);
5620 } else {
5621 print $langs->trans($answerrecord->type_container);
5622 }
5623 print '</td>';
5624
5625 // Container url and label
5626 $titleofpage = ($answerrecord->title ? $answerrecord->title : $langs->trans("NoTitle"));
5627 print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($titleofpage).'">';
5628 print $answerrecord->getNomUrl(1);
5629 print ' <span class="opacitymedium">('.dol_escape_htmltag($titleofpage).')</span>';
5630 //print '</td>';
5631 //print '<td class="tdoverflow100">';
5632 print '<br>';
5633 print '<span class="opacitymedium">'.dol_escape_htmltag($answerrecord->description ? $answerrecord->description : $langs->trans("NoDescription")).'</span>';
5634 print '</td>';
5635
5636 // Language
5637 print '<td class="center">';
5638 print picto_from_langcode($answerrecord->lang, $answerrecord->lang);
5639 print '</td>';
5640
5641 // Categories - Tags
5642 print '<td class="center">';
5643 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
5644 // Get current categories
5645 $existing = $c->containing($answerrecord->id, Categorie::TYPE_WEBSITE_PAGE, 'object');
5646 if (is_array($existing)) {
5647 foreach ($existing as $tmpcategory) {
5648 //var_dump($tmpcategory);
5649 print img_object($langs->trans("Category").' : '.$tmpcategory->label, 'category', 'style="padding-left: 2px; padding-right: 2px; color: #'.($tmpcategory->color != '' ? $tmpcategory->color : '888').'"');
5650 }
5651 }
5652 }
5653 //var_dump($existing);
5654 print '</td>';
5655
5656 // Number of words
5657 print '<td class="center nowraponall">';
5658 $textwithouthtml = dol_string_nohtmltag(dolStripPhpCode($answerrecord->content));
5659 $characterMap = 'áàéèëíóúüñùç0123456789';
5660 $nbofwords = str_word_count($textwithouthtml, 0, $characterMap);
5661 if ($nbofwords) {
5662 print $nbofwords.' '.$langs->trans("words");
5663 $totalnbwords += $nbofwords;
5664 }
5665 print '</td>';
5666
5667 // Author
5668 print '<td class="tdoverflowmax125">';
5669 if (!empty($answerrecord->fk_user_creat)) {
5670 if (empty($conf->cache['user'][$answerrecord->fk_user_creat])) {
5671 $tmpuser = new User($db);
5672 $tmpuser->fetch($answerrecord->fk_user_creat);
5673 $conf->cache['user'][$answerrecord->fk_user_creat] = $tmpuser;
5674 } else {
5675 $tmpuser = $conf->cache['user'][$answerrecord->fk_user_creat];
5676 }
5677 print $tmpuser->getNomUrl(-1, '', 0, 0, 0, 0, 'login');
5678 }
5679 print '</td>';
5680
5681 // Date creation
5682 print '<td class="center nowraponall">';
5683 print dol_print_date($answerrecord->date_creation, 'dayhour');
5684 print '</td>';
5685
5686 // Date last modification
5687 print '<td class="center nowraponall">';
5688 print dol_print_date($answerrecord->date_modification, 'dayhour');
5689 print '</td>';
5690
5691 // Edit properties, HTML sources, status
5692 print '<td class="tdwebsitesearchresult right nowraponall">';
5693 $disabled = '';
5694 $urltoedithtmlsource = $_SERVER["PHP_SELF"].'?action=editmeta&token='.newToken().'&websiteid='.$website->id.'&pageid='.$answerrecord->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].$param);
5695 if (!$user->hasRight('website', 'write')) {
5696 $disabled = ' disabled';
5697 $urltoedithtmlsource = '';
5698 }
5699 print '<a class="editfielda marginleftonly marginrightonly '.$disabled.'" href="'.$urltoedithtmlsource.'" title="'.$langs->trans("EditPageMeta").'">'.img_picto($langs->trans("EditPageMeta"), 'pencil-ruler').'</a>';
5700
5701 $disabled = '';
5702 $urltoedithtmlsource = $_SERVER["PHP_SELF"].'?action=editsource&token='.newToken().'&websiteid='.$website->id.'&pageid='.$answerrecord->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].$param);
5703 if (!$user->hasRight('website', 'write')) {
5704 $disabled = ' disabled';
5705 $urltoedithtmlsource = '';
5706 }
5707 print '<a class="editfielda marginleftonly marginrightonly '.$disabled.'" href="'.$urltoedithtmlsource.'" title="'.$langs->trans("EditHTMLSource").'">'.img_picto($langs->trans("EditHTMLSource"), 'edit').'</a>';
5708
5709 print '<span class="marginleftonly marginrightonly"></span>';
5710 print ajax_object_onoff($answerrecord, 'status', 'status', 'Enabled', 'Disabled', array(), 'valignmiddle inline-block');
5711
5712 print '</td>';
5713
5714 // Action column
5715 if (!$conf->main_checkbox_left_column) {
5716 print '<td class="nowrap center">';
5717
5718 print '<!-- Status of page -->'."\n";
5719 if ($massactionbutton || $massaction) {
5720 $selected = 0;
5721 if (in_array($answerrecord->id, $arrayofselected)) {
5722 $selected = 1;
5723 }
5724 print '<input id="'.$answerrecord->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$answerrecord->id.'"'.($selected ? ' checked="checked"' : '').'>';
5725 }
5726 print '</td>';
5727 }
5728
5729 print '</tr>';
5730 } else {
5731 // $answerrecord is not list of WebsitePage
5732 '@phan-var-force array{type:string} $answerrecord';
5733 $param = '?mode=replacesite';
5734 $param .= '&websiteid='.$website->id;
5735 $param .= '&optionpcontent='.GETPOST('optionpcontent', 'aZ09');
5736 $param .= '&optionmeta='.GETPOST('optionmeta', 'aZ09');
5737 $param .= '&optionsitefiles='.GETPOST('optionsitefiles', 'aZ09');
5738 $param .= '&optioncontainertype='.GETPOST('optioncontainertype', 'aZ09');
5739 $param .= '&optionlanguage='.GETPOST('optionlanguage', 'aZ09');
5740 $param .= '&optioncategory='.GETPOST('optioncategory', 'aZ09');
5741 $param .= '&searchstring='.urlencode($searchkey);
5742
5743 print '<tr>';
5744
5745 // Action column
5746 if ($conf->main_checkbox_left_column) {
5747 print '<td class="nowrap center">';
5748 print '</td>';
5749 }
5750
5751 // Type of container
5752 print '<td>';
5753 $translateofrecordtype = array(
5754 'website_csscontent' => 'WEBSITE_CSS_INLINE',
5755 'website_jscontent' => 'WEBSITE_JS_INLINE',
5756 'website_robotcontent' => 'WEBSITE_ROBOT',
5757 'website_htmlheadercontent' => 'WEBSITE_HTML_HEADER',
5758 'website_htaccess' => 'WEBSITE_HTACCESS',
5759 'website_readme' => 'WEBSITE_README',
5760 'website_manifestjson' => 'WEBSITE_MANIFEST_JSON'
5761 );
5762 print '<span class="opacitymedium">';
5763 if (!empty($translateofrecordtype[$answerrecord['type']])) {
5764 print $langs->trans($translateofrecordtype[$answerrecord['type']]);
5765 } else {
5766 print $answerrecord['type'];
5767 }
5768 print '</span>';
5769 print '</td>';
5770
5771 // Container url and label
5772 print '<td>';
5773 $backtopageurl = $_SERVER["PHP_SELF"].$param;
5774 print '<a href="'.$_SERVER["PHP_SELF"].'?action=editcss&token='.newToken().'&website='.urlencode($website->ref).'&backtopage='.urlencode($backtopageurl).'">'.$langs->trans("EditCss").'</a>';
5775 print '</td>';
5776
5777 // Language
5778 print '<td>';
5779 print '</td>';
5780
5781 // Categories - Tags
5782 print '<td>';
5783 print '</td>';
5784
5785 // Nb of words
5786 print '<td>';
5787 print '</td>';
5788
5789 print '<td>';
5790 print '</td>';
5791
5792 print '<td>';
5793 print '</td>';
5794
5795 // Date last modification
5796 print '<td class="center nowraponall">';
5797 //print dol_print_date(filemtime());
5798 print '</td>';
5799
5800 // Edit properties, HTML sources, status
5801 print '<td>';
5802 print '</td>';
5803
5804 // Action column
5805 if (!$conf->main_checkbox_left_column) {
5806 print '<td class="nowrap center">';
5807 print '</td>';
5808 }
5809
5810 print '</tr>';
5811 }
5812 }
5813
5814 if (count($listofpages['list']) >= 2) {
5815 // Total
5816 print '<tr class="lite_titre">';
5817
5818 // Action column
5819 if ($conf->main_checkbox_left_column) {
5820 print '<td class="nowrap center">';
5821 print '</td>';
5822 }
5823
5824 // Type of container
5825 print '<td>';
5826 print $langs->trans("Total");
5827 print '</td>';
5828
5829 // Container url and label
5830 print '<td>';
5831 print '</td>';
5832
5833 // Language
5834 print '<td>';
5835 print '</td>';
5836
5837 // Categories - Tags
5838 print '<td>';
5839 print '</td>';
5840
5841 // Nb of words
5842 print '<td class="center nowraponall">';
5843 print $totalnbwords.' '.$langs->trans("words");
5844 print '</td>';
5845
5846 print '<td>';
5847 print '</td>';
5848
5849 print '<td>';
5850 print '</td>';
5851
5852 // Date last modification
5853 print '<td>';
5854 print '</td>';
5855
5856 // Edit properties, HTML sources, status
5857 print '<td>';
5858 print '</td>';
5859
5860 // Action column
5861 if (!$conf->main_checkbox_left_column) {
5862 print '<td class="nowrap center">';
5863 print '</td>';
5864 }
5865
5866 print '</tr>';
5867 }
5868
5869 print '</table>';
5870 print '</div>';
5871 print '<br>';
5872 } else {
5873 print '<div class="warning">'.$listofpages['message'].'</div>';
5874 }
5875
5876 print '</div>';
5877 }
5878
5879 print '</form>';
5880}
5881
5882if ((empty($action) || $action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone') && !in_array($mode, array('replacesite'))) {
5883 if ($pageid > 0 && $atleastonepage) {
5884 // $filejs
5885 // $filecss
5886 // $filephp
5887
5888 // Output page under the Dolibarr top menu
5889 $objectpage->fetch($pageid);
5890
5891 $jscontent = @file_get_contents($filejs);
5892
5893 $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";
5894
5895 // Include a html so we can benefit of the header of page.
5896 // Note: We can't use iframe as it can be used to include another external html file
5897 // Note: We can't use frame as it is deprecated.
5898 /*if ($includepageintoaframeoradiv == 'iframe')
5899 {
5900 $out .= "<iframe><body></html>";
5901 }*/
5902 $out .= "\n<html><head>\n";
5903 $out .= "<!-- htmlheader/style of page from database -->\n";
5904 $out .= dolWebsiteReplacementOfLinks($object, $objectpage->htmlheader, 1, 'htmlheader');
5905
5906 $out .= "<!-- htmlheader/style of website from files -->\n";
5907 // TODO Keep only the <link> or the <script> tags
5908 /*
5909 $htmlheadercontent = @file_get_contents($filehtmlheader);
5910 $dom = new DOMDocument;
5911 @$dom->loadHTML($htmlheadercontent);
5912 $styles = $dom->getElementsByTagName('link');
5913 $scripts = $dom->getElementsByTagName('script');
5914 foreach($styles as $stylescursor)
5915 {
5916 $out.=$stylescursor;
5917 }
5918 foreach($scripts as $scriptscursor)
5919 {
5920 $out.=$scriptscursor;
5921 }
5922 */
5923
5924 $out .= "</head>\n";
5925 $out .= "\n";
5926 $out .= "<body>\n";
5927
5928
5929 $out .= '<div id="websitecontentundertopmenu" class="websitecontentundertopmenu boostrap-iso">'."\n";
5930
5931 // REPLACEMENT OF LINKS When page called by website editor
5932
5933 $out .= '<!-- style of website from file -->'."\n";
5934 $out .= '<style scoped>'."\n"; // "scoped" means "apply to parent element only and not grand parent". No more supported by browsers, snif !
5935 $tmpout = '';
5936 $tmpout .= '/* Include website CSS file */'."\n";
5937 //$csscontent = @file_get_contents($filecss);
5938 if (dol_is_file($filecss)) {
5939 ob_start();
5940 include $filecss;
5941 $csscontent = ob_get_contents();
5942 ob_end_clean();
5943 } else {
5944 $csscontent = '';
5945 }
5946 $tmpout .= dolWebsiteReplacementOfLinks($object, $csscontent, 1, 'css');
5947 $tmpout .= '/* Include style from the HTML header of page */'."\n";
5948 // Clean the html header of page to get only <style> content
5949 $tmp = preg_split('(<style[^>]*>|</style>)', $objectpage->htmlheader);
5950 $tmpstyleinheader = '';
5951 $i = 0;
5952 foreach ($tmp as $valtmp) {
5953 $i++;
5954 if ($i % 2 == 0) {
5955 $tmpstyleinheader .= $valtmp."\n";
5956 }
5957 }
5958 $tmpout .= $tmpstyleinheader."\n";
5959 // Clean style that may affect global style of Dolibarr
5960 $tmpout = preg_replace('/}[\s\n]*body\s*{[^}]+}/ims', '}', $tmpout);
5961 $out .= $tmpout;
5962 $out .= '</style>'."\n";
5963
5964 // Note: <div>, <section>, ... with contenteditable="true" inside this can be edited with inline ckeditor
5965
5966 // Do not enable the contenteditable when page was grabbed, ckeditor is removing span and adding borders,
5967 // so editable will be available only from container created from scratch
5968 //$out.='<div id="bodywebsite" class="bodywebsite"'.($objectpage->grabbed_from ? ' contenteditable="true"' : '').'>'."\n";
5969 $out .= '<div id="divbodywebsite" class="bodywebsite bodywebpage-'.$objectpage->ref.'">'."\n";
5970
5971 $newcontent = $objectpage->content;
5972
5973 // If mode WEBSITE_SUBCONTAINERSINLINE is on
5974 if (getDolGlobalString('WEBSITE_SUBCONTAINERSINLINE')) {
5975 // TODO Check file $filephp exists, if not create it.
5976
5977 //var_dump($filetpl);
5978 $filephp = $filetpl;
5979
5980 // Get session info and obfuscate session cookie
5981 $savsessionname = session_name();
5982 $savsessionid = $_COOKIE[$savsessionname];
5983 $_COOKIE[$savsessionname] = 'obfuscatedcookie';
5984
5985 ob_start();
5986 try {
5987 $res = include $filephp; // Note that if file contains a fatal error (Example: declaration of a function that already exists), this may break code here
5988 if (empty($res)) {
5989 print "ERROR: Failed to include file '".$filephp."'. Try to edit and re-save page with this ID.";
5990 }
5991 } catch (Exception $e) {
5992 print $e->getMessage();
5993 }
5994 $newcontent = ob_get_contents();
5995 ob_end_clean();
5996
5997
5998 // Restore data
5999 $_COOKIE[$savsessionname] = $savsessionid;
6000 }
6001
6002 // Change the contenteditable to "true" or "false" when mode Edit Inline is on or off
6003 if (!getDolGlobalString('WEBSITE_EDITINLINE')) {
6004 // Remove the contenteditable="true"
6005 $newcontent = preg_replace('/(div|section|header|main|footer)(\s[^>]*)contenteditable="true"/', '\1\2', $newcontent);
6006 } else {
6007 // Keep the contenteditable="true" when mode Edit Inline is on
6008 }
6009 $out .= dolWebsiteReplacementOfLinks($object, $newcontent, 0, 'html', $objectpage->id)."\n";
6010 //$out.=$newcontent;
6011
6012 $out .= '</div>'."\n";
6013
6014 $out .= '</div> <!-- End div id=websitecontentundertopmenu -->'."\n";
6015
6016 /*if ($includepageintoaframeoradiv == 'iframe')
6017 {
6018 $out .= "</body></html></iframe>";
6019 }*/
6020 $out .= "\n</body></html>\n";
6021
6022 $out .= "\n".'<!-- End page content '.$filetpl.' -->'."\n\n";
6023
6024 print $out;
6025
6026 /*
6027 file_put_contents($filetpl, $out);
6028 dolChmod($filetpl);
6029
6030 // Output file on browser
6031 dol_syslog("index.php include $filetpl $filename content-type=$type");
6032 $original_file_osencoded=dol_osencode($filetpl); // New file name encoded in OS encoding charset
6033
6034 // This test if file exists should be useless. We keep it to find bug more easily
6035 if (! file_exists($original_file_osencoded))
6036 {
6037 dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
6038 exit;
6039 }
6040
6041 //include_once $original_file_osencoded;
6042 */
6043
6044 /*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$pageid.'"/>';
6045 print '</iframe>';*/
6046 } else {
6047 if (empty($websitekey) || $websitekey == '-1') {
6048 print '<br><br><div class="center previewnotyetavailable"><span class="">'.$langs->trans("NoWebSiteCreateOneFirst").'</span></div><br><br><br>';
6049 print '<div class="center"><div class="logo_setup"></div></div>';
6050 } else {
6051 print '<br><br><div class="center previewnotyetavailable"><span class="">'.$langs->trans("PreviewOfSiteNotYetAvailable", $object->ref).'</span></div><br><br><br>';
6052 print '<div class="center"><div class="logo_setup"></div></div>';
6053 }
6054 }
6055}
6056
6057// End of page
6058llxFooter();
6059$db->close();
write(string $newInnerBlock)
Replace the whole permissions block, markers included, in a single write.
$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
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition propal.php:280
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='', $placeholder='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:477
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:812
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:346
$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
if(! $sortfield) if(! $sortorder) $module
Definition list.php:193
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:
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...
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
currentToken()
Return the value of token currently saved into session with name 'token'.
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.
dolChmod($filepath, $newmask='')
Change mod of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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.
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, or into a js string that is a locat...
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_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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).
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.
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)
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).
a disabled
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
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.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
img_previous($titlealt='default', $moreatt='')
Show previous logo.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
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.
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_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
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.