*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* \file htdocs/website/index.php
* \ingroup website
* \brief Page to website view/edit
*/
define('NOSCANPOSTFORINJECTION', 1);
define('NOSTYLECHECK', 1);
define('USEDOLIBARREDITOR', 1);
define('FORCE_CKEDITOR', 1); // We need CKEditor, even if module is off.
//header('X-XSS-Protection:0'); // Disable XSS filtering protection of some browsers (note: use of Content-Security-Policy is more efficient). Disabled as deprecated.
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/website2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formwebsite.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
$langs->loadLangs(array("admin","other","website","errors"));
if (! $user->rights->website->read) accessforbidden();
$conf->dol_hide_leftmenu = 1; // Force hide of left menu.
$error=0;
$websiteid=GETPOST('websiteid', 'int');
$websitekey=GETPOST('website', 'alpha');
$page=GETPOST('page', 'alpha');
$pageid=GETPOST('pageid', 'int');
$pageref=GETPOST('pageref', 'aZ09');
$action=GETPOST('action', 'aZ09');
$confirm=GETPOST('confirm', 'alpha');
$cancel=GETPOST('cancel', 'alpha');
$contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'bomlist'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$type_container=GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha');
$section_dir = GETPOST('section_dir', 'alpha');
$file_manager = GETPOST('file_manager', 'alpha');
$replacesite = GETPOST('replacesite', 'alpha');
if (GETPOST('deletesite', 'alpha')) { $action='deletesite'; }
if (GETPOST('delete', 'alpha')) { $action='delete'; }
if (GETPOST('preview', 'alpha')) $action='preview';
if (GETPOST('createsite', 'alpha')) { $action='createsite'; }
if (GETPOST('createcontainer', 'alpha')) { $action='createcontainer'; }
if (GETPOST('editcss', 'alpha')) { $action='editcss'; }
if (GETPOST('editmenu', 'alpha')) { $action='editmenu'; }
if (GETPOST('setashome', 'alpha')) { $action='setashome'; }
if (GETPOST('editmeta', 'alpha')) { $action='editmeta'; }
if (GETPOST('editsource', 'alpha')) { $action='editsource'; }
if (GETPOST('editcontent', 'alpha')) { $action='editcontent'; }
if (GETPOST('exportsite', 'alpha')) { $action='exportsite'; }
if (GETPOST('importsite', 'alpha')) { $action='importsite'; }
if (GETPOST('createfromclone', 'alpha')) { $action='createfromclone'; }
if (GETPOST('createpagefromclone', 'alpha')) { $action='createpagefromclone'; }
if (empty($action) && $file_manager) $action='file_manager';
if (empty($action) && $replacesite) $action='replacesite';
if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x')) $pageid = 0;
// Load variable for pagination
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
$page = GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
//if (! $sortfield) $sortfield='name';
//if (! $sortorder) $sortorder='ASC';
if (empty($action)) $action = 'preview';
$object = new Website($db);
$objectpage = new WebsitePage($db);
$object->fetchAll(); // Init $object->records with list of websites
// If website not defined, we take first found
if (!($websiteid > 0) && empty($websitekey))
{
foreach ($object->records as $key => $valwebsite)
{
$websitekey = $valwebsite->ref;
break;
}
}
if ($websiteid > 0 || $websitekey)
{
$res = $object->fetch($websiteid, $websitekey);
$websitekey = $object->ref;
}
$website = $object;
// Check pageid received as aprameter
if ($pageid < 0) $pageid = 0;
if (($pageid > 0 || $pageref) && $action != 'addcontainer')
{
$res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), $pageref);
if ($res == 0)
{
$res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), null, $pageref);
}
// Check if pageid is inside the new website, if not we reset param pageid
if ($res >= 0 && $object->id > 0)
{
if ($objectpage->fk_website != $object->id) // We have a bad page that does not belong to web site
{
if ($object->fk_default_home > 0)
{
$res = $objectpage->fetch($object->fk_default_home, $object->id, ''); // We search first page of web site
if ($res > 0) $pageid = $object->fk_default_home;
}
else
{
$res = $objectpage->fetch(0, $object->id, ''); // We search first page of web site
if ($res == 0) // Page was not found, we reset it
{
$objectpage = new WebsitePage($db);
}
else // We found a page, we set pageid to it.
{
$pageid = $objectpage->id;
}
}
}
else // We have a valid page. We force pageid for the case we got the page with a fetch on ref.
{
$pageid = $objectpage->id;
}
}
}
// Define pageid if pageid and pageref not received as parameter or was wrong
if (empty($pageid) && empty($pageref) && $object->id > 0 && $action != 'createcontainer')
{
$pageid = $object->fk_default_home;
if (empty($pageid))
{
$array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
if (!is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors);
$atleastonepage = (is_array($array) && count($array) > 0);
$firstpageid = 0; $homepageid = 0;
foreach ($array as $key => $valpage)
{
if (empty($firstpageid)) $firstpageid = $valpage->id;
if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid = $valpage->id;
}
$pageid = ($homepageid ? $homepageid : $firstpageid); // We choose home page and if not defined yet, we take first page
}
}
global $dolibarr_main_data_root;
$pathofwebsite = $dolibarr_main_data_root.'/website/'.$websitekey;
$filehtmlheader = $pathofwebsite.'/htmlheader.html';
$filecss = $pathofwebsite.'/styles.css.php';
$filejs = $pathofwebsite.'/javascript.js.php';
$filerobot = $pathofwebsite.'/robots.txt';
$filehtaccess = $pathofwebsite.'/.htaccess';
$filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php';
$fileindex = $pathofwebsite.'/index.php';
$filewrapper = $pathofwebsite.'/wrapper.php';
$filemanifestjson = $pathofwebsite.'/manifest.json.php';
$filereadme = $pathofwebsite.'/README.md';
// Define $urlwithroot
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
$permtouploadfile = $user->rights->website->write;
$diroutput = $conf->medias->multidir_output[$conf->entity];
$relativepath = $section_dir;
$upload_dir = $diroutput.'/'.$relativepath;
$htmlheadercontentdefault = '';
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$htmlheadercontentdefault .= ''."\n";
$manifestjsoncontentdefault = '';
$manifestjsoncontentdefault .= '{
"name": "MyWebsite",
"short_name": "MyWebsite",
"start_url": "/",
"lang": "en-US",
"display": "standalone",
"background_color": "#fff",
"description": "A simple Web app.",
"icons": [{
"src": "images/'.$website->ref.'/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "image/'.$website->ref.'/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "image/'.$website->ref.'/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "image/'.$website->ref.'/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "image/'.$website->ref.'/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
}, {
"src": "image/'.$website->ref.'/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}],
"related_applications": [{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=com.nltechno.dolidroidpro"
}]
}';
/*
* Actions
*/
// Protections
if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x'))
{
$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.
}
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.
{
if ($action == 'addsite') $action = 'preview';
if ($action == 'updatesource') $action = 'preview';
$pageid = $object->fk_default_home;
if (empty($pageid))
{
$array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors);
$atleastonepage=(is_array($array) && count($array) > 0);
$firstpageid=0; $homepageid=0;
foreach($array as $key => $valpage)
{
if (empty($firstpageid)) $firstpageid=$valpage->id;
if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid=$valpage->id;
}
$pageid=($homepageid?$homepageid:$firstpageid); // We choose home page and if not defined yet, we take first page
}
}
if (GETPOST('refreshpage', 'alpha') && ! in_array($action, array('updatecss'))) $action='preview';
// Cancel
if ($cancel)
{
$action = 'preview';
if ($backtopage)
{
header("Location: ".$backtopage);
exit;
}
}
$savbacktopage = $backtopage;
$backtopage = $_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid.(GETPOST('section_dir', 'alpha') ? '§ion_dir='.urlencode(GETPOST('section_dir', 'alpha')) : ''); // used after a confirm_deletefile into actions_linkedfiles.inc.php
include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
$backtopage = $savbacktopage;
if ($action == 'renamefile') $action = 'file_manager'; // After actions_linkedfiles, if action were renamefile, we set it to 'file_manager'
if ($action == 'seteditinline')
{
dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 1);
setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 0); // Force disable of 'Include dynamic content'
header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website', 'alphanohtml').'&pageid='.GETPOST('pageid', 'int'));
exit;
}
if ($action == 'unseteditinline')
{
dolibarr_del_const($db, 'WEBSITE_EDITINLINE');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website', 'alphanohtml').'&pageid='.GETPOST('pageid', 'int'));
exit;
}
if ($action == 'setshowsubcontainers')
{
dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1);
dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 0); // Force disable of edit inline
header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website', 'alphanohtml').'&pageid='.GETPOST('pageid', 'int'));
exit;
}
if ($action == 'unsetshowsubcontainers')
{
dolibarr_del_const($db, 'WEBSITE_SUBCONTAINERSINLINE');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website', 'alphanohtml').'&pageid='.GETPOST('pageid', 'int'));
exit;
}
if (($action == 'replacesite' || $action == 'replacesiteconfirm') && empty(GETPOST('searchstring')))
{
$action = 'replacesite';
}
// Add directory
/*
if ($action == 'adddir' && $permtouploadfile)
{
$ecmdir->ref = 'NOTUSEDYET';
$ecmdir->label = GETPOST("label");
$ecmdir->description = GETPOST("desc");
//$id = $ecmdir->create($user);
if ($id > 0)
{
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
}
else
{
setEventMessages('Error '.$langs->trans($ecmdir->error), null, 'errors');
$action = "createcontainer";
}
clearstatcache();
}
*/
// Add site
if ($action == 'addsite')
{
$db->begin();
if (GETPOST('virtualhost', 'alpha') && !preg_match('/^http/', GETPOST('virtualhost', 'alpha')))
{
$error++;
setEventMessages($langs->trans('ErrorURLMustStartWithHttp', $langs->transnoentitiesnoconv("VirtualHost")), null, 'errors');
}
if (!$error && !GETPOST('WEBSITE_REF', 'alpha'))
{
$error++;
$langs->load("errors");
setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
}
if (!$error && !preg_match('/^[a-z0-9_\-\.]+$/i', GETPOST('WEBSITE_REF', 'alpha')))
{
$error++;
$langs->load("errors");
setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("Ref")), null, 'errors');
}
if (!$error)
{
$tmpobject = new Website($db);
$tmpobject->ref = GETPOST('WEBSITE_REF', 'alpha');
$tmpobject->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha');
$tmpobject->virtualhost = GETPOST('virtualhost', 'alpha');
$result = $tmpobject->create($user);
if ($result <= 0)
{
$error++;
setEventMessages($tmpobject->error, $tmpobject->errors, 'errors');
}
}
if (!$error)
{
$db->commit();
setEventMessages($langs->trans("SiteAdded", $object->ref), null, 'mesgs');
$action = '';
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$tmpobject->ref);
exit;
}
else
{
$db->rollback();
$action = 'createsite';
}
if (!$error)
{
$action = 'preview';
$id = $object->id;
}
}
// Add page/container
if ($action == 'addcontainer')
{
dol_mkdir($pathofwebsite);
$db->begin();
$objectpage->fk_website = $object->id;
if (GETPOSTISSET('fetchexternalurl'))
{
$urltograb = GETPOST('externalurl', 'alpha');
$grabimages = GETPOST('grabimages', 'alpha');
$grabimagesinto = GETPOST('grabimagesinto', 'alpha');
//var_dump($grabimages);exit;
}
if (GETPOSTISSET('fetchexternalurl'))
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
if (empty($urltograb))
{
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("URL")), null, 'errors');
$action = 'createcontainer';
}
elseif (!preg_match('/^http/', $urltograb))
{
$error++;
$langs->load("errors");
setEventMessages('Error URL must start with http:// or https://', null, 'errors');
$action = 'createcontainer';
}
if (!$error)
{
// Clean url to grab, so url can be
// http://www.example.com/ or http://www.example.com/dir1/ or http://www.example.com/dir1/aaa
$urltograbwithoutdomainandparam = preg_replace('/^https?:\/\/[^\/]+\/?/i', '', $urltograb);
//$urltograbwithoutdomainandparam = preg_replace('/^file:\/\/[^\/]+\/?/i', '', $urltograb);
$urltograbwithoutdomainandparam = preg_replace('/\?.*$/', '', $urltograbwithoutdomainandparam);
if (empty($urltograbwithoutdomainandparam) && !preg_match('/\/$/', $urltograb))
{
$urltograb .= '/';
}
$pageurl = dol_sanitizeFileName(preg_replace('/[\/\.]/', '-', preg_replace('/\/+$/', '', $urltograbwithoutdomainandparam)));
$urltograbdirwithoutslash = dirname($urltograb.'.');
$urltograbdirrootwithoutslash = getRootURLFromURL($urltograbdirwithoutslash);
// Exemple, now $urltograbdirwithoutslash is https://www.dolimed.com/screenshots
// and $urltograbdirrootwithoutslash is https://www.dolimed.com
}
// Check pageurl is not already used
if ($pageurl)
{
$tmpwebsitepage = new WebsitePage($db);
$result = $tmpwebsitepage->fetch(0, $object->id, $pageurl);
if ($result > 0)
{
setEventMessages($langs->trans("AliasPageAlreadyExists", $pageurl), null, 'errors');
$error++;
$action = 'createcontainer';
}
}
if (!$error)
{
$tmp = getURLContent($urltograb);
if ($tmp['curl_error_no'])
{
$error++;
setEventMessages('Error getting '.$urltograb.': '.$tmp['curl_error_msg'], null, 'errors');
$action = 'createcontainer';
}
elseif ($tmp['http_code'] != '200')
{
$error++;
setEventMessages('Error getting '.$urltograb.': '.$tmp['http_code'], null, 'errors');
$action = 'createcontainer';
}
else
{
// Remove comments
$tmp['content'] = removeHtmlComment($tmp['content']);
$regs = array();
preg_match('/
(.*)<\/head>/ims', $tmp['content'], $regs);
$head = $regs[1];
$objectpage->type_container = 'page';
$objectpage->pageurl = $pageurl;
if (empty($objectpage->pageurl))
{
$tmpdomain = getDomainFromURL($urltograb);
$objectpage->pageurl = $tmpdomain.'-home';
}
$objectpage->aliasalt = '';
if (preg_match('/^(\d+)\-/', basename($urltograb), $regs)) $objectpage->aliasalt = $regs[1];
$regtmp = array();
if (preg_match('/(.*)<\/title>/ims', $head, $regtmp))
{
$objectpage->title = $regtmp[1];
}
if (preg_match('/title)) $objectpage->title = $regtmp[1]; // If title not found into , we get it from
}
if (preg_match('/description = $regtmp[1];
}
if (preg_match('/keywords = $regtmp[1];
}
if (preg_match('/lang = $tmplang[0].($tmplang[1] ? '_'.strtoupper($tmplang[1]) : '');
}
$tmp['content'] = preg_replace('/\s*/ims', '', $tmp['content']);
$objectpage->content = $tmp['content'];
$objectpage->content = preg_replace('/^.*]*)*>/ims', '', $objectpage->content);
$objectpage->content = preg_replace('/<\/body(\s[^>]*)*>.*$/ims', '', $objectpage->content);
$absoluteurlinaction = $urltograbdirwithoutslash;
// TODO Replace 'action="$urltograbdirwithoutslash' into action="/"
// TODO Replace 'action="$urltograbdirwithoutslash..."' into action="..."
// TODO Replace 'a href="$urltograbdirwithoutslash' into a href="/"
// TODO Replace 'a href="$urltograbdirwithoutslash..."' into a href="..."
// Now loop to fetch all css files. Include them inline into header of page
$objectpage->htmlheader = $tmp['content'];
$objectpage->htmlheader = preg_replace('/^.*]*)*>/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/<\/head(\s[^>]*)*>.*$/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*)*>\n*/ims', '', $objectpage->htmlheader);
//$objectpage->htmlheader = preg_replace('/]*>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader);
$objectpage->htmlheader = preg_replace('/]*rel="canonical[^>]*>\n/ims', '', $objectpage->htmlheader);
// Now loop to fetch JS
$tmp = $objectpage->htmlheader;
preg_match_all('/'."\n";
llxHeader($moreheadcss.$moreheadjs, $langs->trans("WebsiteSetup"), $help_url, '', 0, 0, $arrayofjs, $arrayofcss, '', '', ''."\n".'