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