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