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