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