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