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