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