*
* 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
]*src=")\/?medias\//', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
//
]*src=")\/?([^:\"\!]+)\"/', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=\2"', $content, -1, $nbrep);
//
]*src=")(\/?viewimage\.php)/', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content, -1, $nbrep);
// action="newpage.php" => action="dolibarr/website/index.php?website=...&pageref=newpage
$content = preg_replace('/(action=")\/?([^:\"]*)(\.php\")/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep);
// Fix relative link /document.php with correct URL after the DOL_URL_ROOT: ...href="/document.php?modulepart="
$content = preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
$content = preg_replace('/(src=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
// Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: ...href="/viewimage.php?modulepart="
$content = preg_replace('/(url\(")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
// Fix relative URL
$content = str_replace('src="!~!~!~/viewimage.php', 'src="!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content);
$content = str_replace('href="!~!~!~/document.php', 'href="!~!~!~'.DOL_URL_ROOT.'/document.php', $content);
// Remove the protection tag !~!~!~
$content = str_replace('!~!~!~', '', $content);
dol_syslog('dolWebsiteReplacementOfLinks end', LOG_DEBUG);
//if ($contenttype == 'html') { print $content;exit; }
return $content;
}
/**
* Render a string of an HTML content and output it.
* Used to ouput the page when viewed from a server (Dolibarr or Apache).
*
* @param string $content Content string
* @param string $contenttype Content type
* @param int $containerid Contenair id
* @return void
* @see dolWebsiteReplacementOfLinks() for function used to replace content in the backoffice context.
*/
function dolWebsiteOutput($content, $contenttype = 'html', $containerid = '')
{
global $db, $langs, $conf, $user;
global $dolibarr_main_url_root, $dolibarr_main_data_root;
global $website;
global $includehtmlcontentopened;
$nbrep = 0;
dol_syslog("dolWebsiteOutput start - contenttype=".$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR') ? '1' : '')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER') ? '1' : '').' includehtmlcontentopened='.$includehtmlcontentopened);
//print $containerid.' '.$content;
// 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
if (defined('USEDOLIBARREDITOR')) { // REPLACEMENT OF LINKS When page called from Dolibarr editor
// We remove the
]*src=")\/?medias\//', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
//
]*src=")\/?([^:\"\!]+)\"/', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=\2"', $content, -1, $nbrep);
//
]*src=")(\/?viewimage\.php)/', '\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content, -1, $nbrep);
// action="newpage.php" => action="dolibarr/website/index.php?website=...&pageref=newpage
$content = preg_replace('/(action=")\/?([^:\"]*)(\.php\")/', '\1!~!~!~'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep);
// Fix relative URL
$content = str_replace('src="!~!~!~/viewimage.php', 'src="!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content);
$content = str_replace('href="!~!~!~/document.php', 'href="!~!~!~'.DOL_URL_ROOT.'/document.php', $content);
// Remove the protection tag !~!~!~, but only if this is the parent page and not an include
if (empty($includehtmlcontentopened)) {
$content = str_replace('!~!~!~', '', $content);
}
} else // REPLACEMENT OF LINKS When page called from virtual host web server
{
$symlinktomediaexists = 1;
if ($website->virtualhost) {
$content = preg_replace('/^(]*rel="canonical" href=")\//m', '\1'.$website->virtualhost.'/', $content, -1, $nbrep);
}
//print 'rrrrrrrrr'.$website->virtualhost.$content;
// Make a change into HTML code to allow to include images from medias directory correct with direct link for virtual server
//
// become
//
if (!$symlinktomediaexists) {
//
]*src=")\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
$content = preg_replace('/(url\(["\']?)\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
$content = preg_replace('/('."\n";
} elseif ($type == 'organization') {
$companyname = $mysoc->name;
$url = $mysoc->url;
$ret = ''."\n";
$ret .= ''."\n";
} elseif ($type == 'blogpost') {
if (!empty($websitepage->author_alias)) {
//include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
//$tmpuser = new User($db);
//$restmpuser = $tmpuser->fetch($websitepage->fk_user_creat);
$pageurl = $websitepage->pageurl;
$title = $websitepage->title;
$image = $websitepage->image;
$companyname = $mysoc->name;
$description = $websitepage->description;
$pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl);
$title = str_replace('__WEBSITE_KEY__', $website->ref, $title);
$image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image);
$companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname);
$description = str_replace('__WEBSITE_KEY__', $website->ref, $description);
$ret = ''."\n";
$ret .= ''."\n";
} else {
$ret .= ''."\n";
}
} elseif ($type == 'product') {
$ret = ''."\n";
$ret .= ''."\n";
} elseif ($type == 'qa') {
$ret = ''."\n";
$ret .= ''."\n";
}
return $ret;
}
/**
* Return HTML content to add as header card for an article, news or Blog Post or home page.
*
* @param array $params Array of parameters
* @return string HTML content
*/
function getSocialNetworkHeaderCards($params = null)
{
global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
$out = '';
if ($website->virtualhost) {
$pageurl = $websitepage->pageurl;
$title = $websitepage->title;
$image = $websitepage->image;
$companyname = $mysoc->name;
$description = $websitepage->description;
$pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl);
$title = str_replace('__WEBSITE_KEY__', $website->ref, $title);
$image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image);
$companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname);
$description = str_replace('__WEBSITE_KEY__', $website->ref, $description);
$shortlangcode = '';
if ($websitepage->lang) {
$shortlangcode = substr($websitepage->lang, 0, 2); // en_US or en-US -> en
}
if (empty($shortlangcode)) {
$shortlangcode = substr($website->lang, 0, 2); // en_US or en-US -> en
}
$fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
$canonicalurl = $website->virtualhost.(($websitepage->id == $website->fk_default_home) ? '/' : (($shortlangcode != substr($website->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$websitepage->pageurl.'.php'));
$hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
// Open Graph
$out .= ''."\n"; // TODO If blogpost, use type article
$out .= ''."\n";
if ($websitepage->image) {
$out .= ''."\n";
}
$out .= ''."\n";
// Twitter
$out .= ''."\n";
if (!empty($params) && !empty($params['twitter_account'])) {
$out .= ''."\n";
$out .= ''."\n";
}
$out .= ''."\n";
if ($websitepage->description) {
$out .= ''."\n";
}
if ($websitepage->image) {
$out .= ''."\n";
}
//$out .= '';
/*
$out .= '';
$out .= '';
$out .= '';
$out .= '';
$out .= '';
$out .= '';
$out .= '';
$out .= '';
$out .= '';
*/
}
return $out;
}
/**
* Return HTML content to add structured data for an article, news or Blog Post.
*
* @return string HTML content
*/
function getSocialNetworkSharingLinks()
{
global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
$out = ''."\n";
if ($website->virtualhost) {
$fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
$hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
$out .= '\n";
} else {
$out .= ''."\n";
}
$out .= ''."\n";
return $out;
}
/**
* Return list of containers object that match a criteria.
* WARNING: This function can be used by websites.
*
* @param string $type Type of container to search into (Example: '', 'page', 'blogpost', 'page,blogpost', ...)
* @param string $algo Algorithm used for search (Example: 'meta' is searching into meta information like title and description, 'content', 'sitefiles', or any combination 'meta,content,...')
* @param string $searchstring Search string
* @param int $max Max number of answers
* @param string $sortfield Sort Fields
* @param string $sortorder Sort order ('DESC' or 'ASC')
* @param string $langcode Language code ('' or 'en', 'fr', 'es', ...)
* @param array $otherfilters Other filters
* @param int $status 0 or 1, or -1 for both
* @return string HTML content
*/
function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25, $sortfield = 'date_creation', $sortorder = 'DESC', $langcode = '', $otherfilters = 'null', $status = 1)
{
global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
$error = 0;
$arrayresult = array('code'=>'', 'list'=>array());
if (!is_object($weblangs)) {
$weblangs = $langs;
}
if (empty($searchstring) && empty($type) && empty($langcode) && empty($otherfilters)) {
$error++;
$arrayresult['code'] = 'KO';
$arrayresult['message'] = $weblangs->trans("EmptySearchString");
} elseif ($searchstring && dol_strlen($searchstring) < 2) {
$weblangs->load("errors");
$error++;
$arrayresult['code'] = 'KO';
$arrayresult['message'] = $weblangs->trans("ErrorSearchCriteriaTooSmall");
} else {
$tmparrayoftype = explode(',', $type);
/*foreach ($tmparrayoftype as $tmptype) {
if (!in_array($tmptype, array('', 'page', 'blogpost'))) {
$error++;
$arrayresult['code'] = 'KO';
$arrayresult['message'] = 'Bad value for parameter type';
break;
}
}*/
}
$searchdone = 0;
$found = 0;
if (!$error && (empty($max) || ($found < $max)) && (preg_match('/meta/', $algo) || preg_match('/content/', $algo))) {
$sql = 'SELECT wp.rowid FROM '.MAIN_DB_PREFIX.'website_page as wp';
if (is_array($otherfilters) && !empty($otherfilters['category'])) {
$sql .= ', '.MAIN_DB_PREFIX.'categorie_website_page as cwp';
}
$sql .= " WHERE wp.fk_website = ".((int) $website->id);
if ($status >= 0) {
$sql .= " AND wp.status = ".((int) $status);
}
if ($langcode) {
$sql .= " AND wp.lang ='".$db->escape($langcode)."'";
}
if ($type) {
$tmparrayoftype = explode(',', $type);
$typestring = '';
foreach ($tmparrayoftype as $tmptype) {
$typestring .= ($typestring ? ", " : "")."'".$db->escape(trim($tmptype))."'";
}
$sql .= " AND wp.type_container IN (".$db->sanitize($typestring, 1).")";
}
$sql .= " AND (";
$searchalgo = '';
if (preg_match('/meta/', $algo)) {
$searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'";
$searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeunderscore($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeunderscore($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords
}
if (preg_match('/content/', $algo)) {
$searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'";
}
$sql .= $searchalgo;
if (is_array($otherfilters) && !empty($otherfilters['category'])) {
$sql .= ' AND cwp.fk_website_page = wp.rowid AND cwp.fk_categorie = '.((int) $otherfilters['category']);
}
$sql .= ")";
$sql .= $db->order($sortfield, $sortorder);
$sql .= $db->plimit($max);
//print $sql;
$resql = $db->query($sql);
if ($resql) {
$i = 0;
while (($obj = $db->fetch_object($resql)) && ($i < $max || $max == 0)) {
if ($obj->rowid > 0) {
$tmpwebsitepage = new WebsitePage($db);
$tmpwebsitepage->fetch($obj->rowid);
if ($tmpwebsitepage->id > 0) {
$arrayresult['list'][$obj->rowid] = $tmpwebsitepage;
}
$found++;
}
$i++;
}
} else {
$error++;
$arrayresult['code'] = $db->lasterrno();
$arrayresult['message'] = $db->lasterror();
}
$searchdone = 1;
}
if (!$error && (empty($max) || ($found < $max)) && (preg_match('/sitefiles/', $algo))) {
global $dolibarr_main_data_root;
$pathofwebsite = $dolibarr_main_data_root.'/website/'.$website->ref;
$filehtmlheader = $pathofwebsite.'/htmlheader.html';
$filecss = $pathofwebsite.'/styles.css.php';
$filejs = $pathofwebsite.'/javascript.js.php';
$filerobot = $pathofwebsite.'/robots.txt';
$filehtaccess = $pathofwebsite.'/.htaccess';
$filemanifestjson = $pathofwebsite.'/manifest.json.php';
$filereadme = $pathofwebsite.'/README.md';
$filecontent = file_get_contents($filehtmlheader);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent)) {
$arrayresult['list'][] = array('type'=>'website_htmlheadercontent');
}
$filecontent = file_get_contents($filecss);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent)) {
$arrayresult['list'][] = array('type'=>'website_csscontent');
}
$filecontent = file_get_contents($filejs);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent)) {
$arrayresult['list'][] = array('type'=>'website_jscontent');
}
$filerobot = file_get_contents($filerobot);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent)) {
$arrayresult['list'][] = array('type'=>'website_robotcontent');
}
$searchdone = 1;
}
if (!$error) {
if ($searchdone) {
$arrayresult['code'] = 'OK';
if (empty($arrayresult['list'])) {
$arrayresult['code'] = 'KO';
$arrayresult['message'] = $weblangs->trans("NoRecordFound");
}
} else {
$error++;
$arrayresult['code'] = 'KO';
$arrayresult['message'] = 'No supported algorithm found';
}
}
return $arrayresult;
}
/**
* Download all images found into page content $tmp.
* If $modifylinks is set, links to images will be replace with a link to viewimage wrapper.
*
* @param Website $object Object website
* @param WebsitePage $objectpage Object website page
* @param string $urltograb URL to grab (exemple: http://www.nltechno.com/ or http://www.nltechno.com/dir1/ or http://www.nltechno.com/dir1/mapage1)
* @param string $tmp Content to parse
* @param string $action Var $action
* @param string $modifylinks 0=Do not modify content, 1=Replace links with a link to viewimage
* @param int $grabimages 0=Do not grab images, 1=Grab images
* @param string $grabimagesinto 'root' or 'subpage'
* @return void
*/
function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modifylinks = 0, $grabimages = 1, $grabimagesinto = 'subpage')
{
global $conf;
$error = 0;
dol_syslog("Call getAllImages with grabimagesinto=".$grabimagesinto);
$alreadygrabbed = array();
if (preg_match('/\/$/', $urltograb)) {
$urltograb .= '.';
}
$urltograb = dirname($urltograb); // So urltograb is now http://www.nltechno.com or http://www.nltechno.com/dir1
// Search X in "img...src=X"
$regs = array();
preg_match_all('/