*
* 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/core/lib/website.lib.php
* \ingroup website
* \brief Library for website module
*/
/**
* Remove PHP code part from a string.
*
* @param string $str String to clean
* @param string $replacewith String to use as replacement
* @return string Result string without php code
* @see dolKeepOnlyPhpCode()
*/
function dolStripPhpCode($str, $replacewith = '')
{
$str = str_replace('=', '', $part);
if (!empty($partlings)) {
//$phppart = $partlings[0];
//remove content before closing tag
if (count($partlings) > 1) {
$partlings[0] = ''; // Todo why a count > 1 and not >= 1 ?
}
//append to out string
//$newstr .= ''.$replacewith.''.implode('', $partlings);
//$newstr .= ''.$replacewith.''.implode('', $partlings);
$newstr .= ''.$replacewith.''.implode('', $partlings);
//$newstr .= $replacewith.implode('', $partlings);
}
}
}
return $newstr;
}
/**
* Keep only PHP code part from a HTML string page.
*
* @param string $str String to clean
* @return string Result string with php code only
* @see dolStripPhpCode(), checkPHPCode()
*/
function dolKeepOnlyPhpCode($str)
{
$str = str_replace('=', '', $part, 2);
if (!empty($partlings)) {
$newstr .= $partlings[0].'?>';
} else {
$newstr .= $part.'?>';
}
}
}
return $newstr;
}
/**
* Convert a page content to have correct links (based on DOL_URL_ROOT) into an html content. It replaces also dynamic content with '...php...'
* Used to ouput the page on the Preview from backoffice.
*
* @param Website $website Web site object
* @param string $content Content to replace
* @param int $removephppart 0=Replace PHP sections with a PHP badge. 1=Remove completely PHP sections.
* @param string $contenttype Content type
* @param int $containerid Contenair id
* @return boolean True if OK
* @see dolWebsiteOutput() for function used to replace content in a web server context
*/
function dolWebsiteReplacementOfLinks($website, $content, $removephppart = 0, $contenttype = 'html', $containerid = '')
{
$nbrep = 0;
dol_syslog('dolWebsiteReplacementOfLinks start (contenttype='.$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR') ? '1' : '')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER') ? '1' : '').')', LOG_DEBUG);
//if ($contenttype == 'html') { print $content;exit; }
// Replace php code. Note $content may come from database and does not contain body tags.
$replacewith = '...php...';
if ($removephppart) {
$replacewith = '';
}
$content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="'.$replacewith.'"', $content);
$replacewith = '"callto=#';
if ($removephppart) {
$replacewith = '';
}
$content = preg_replace('/"callto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
$replacewith = '"mailto=#';
if ($removephppart) {
$replacewith = '';
}
$content = preg_replace('/"mailto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
$replacewith = 'src="php';
if ($removephppart) {
$replacewith = '';
}
$content = preg_replace('/src="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
$replacewith = 'href="php';
if ($removephppart) {
$replacewith = '';
}
$content = preg_replace('/href="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
//$replacewith='...php...';
$replacewith = '...php...';
if ($removephppart) {
$replacewith = '';
}
//$content = preg_replace('/<\?php((?!\?toremove>).)*\?toremove>\n*/ims', $replacewith, $content);
/*if ($content === null) {
if (preg_last_error() == PREG_JIT_STACKLIMIT_ERROR) $content = 'preg_replace error (when removing php tags) PREG_JIT_STACKLIMIT_ERROR';
}*/
$content = dolStripPhpCode($content, $replacewith);
// Protect the link styles.css.php to any replacement that we make after.
$content = str_replace('href="styles.css.php', 'href="!~!~!~styles.css.php', $content);
$content = str_replace('src="javascript.js.php', 'src="!~!~!~javascript.js.php', $content);
$content = str_replace('href="http', 'href="!~!~!~http', $content);
$content = str_replace('xlink:href="', 'xlink:href="!~!~!~', $content);
$content = str_replace('href="//', 'href="!~!~!~//', $content);
$content = str_replace('src="//', 'src="!~!~!~//', $content);
$content = str_replace('src="viewimage.php', 'src="!~!~!~/viewimage.php', $content);
$content = str_replace('src="/viewimage.php', 'src="!~!~!~/viewimage.php', $content);
$content = str_replace('src="'.DOL_URL_ROOT.'/viewimage.php', 'src="!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content);
$content = str_replace('href="document.php', 'href="!~!~!~/document.php', $content);
$content = str_replace('href="/document.php', 'href="!~!~!~/document.php', $content);
$content = str_replace('href="'.DOL_URL_ROOT.'/document.php', 'href="!~!~!~'.DOL_URL_ROOT.'/document.php', $content);
// Replace relative link '/' with dolibarr URL
$content = preg_replace('/(href=")\/(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'\2"', $content, -1, $nbrep);
// Replace relative link /xxx.php#aaa or /xxx.php with dolibarr URL (we discard param ?...)
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2\3"', $content, -1, $nbrep);
// Replace relative link /xxx.php?a=b&c=d#aaa or /xxx.php?a=b&c=d with dolibarr URL
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php\?([^#\"<>]*)(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2&\3\4"', $content, -1, $nbrep);
// Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/
$content = preg_replace('/url\((["\']?)\/?medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
$content = preg_replace('/data-slide-bg=(["\']?)\/?medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
// ]*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;
}
/**
* Converts smiley string into the utf8 sequence.
* @param string $content Content to replace
* @return string Replacement of all smiley strings with their utf8 code
* @see dolWebsiteOutput()
*/
function dolReplaceSmileyCodeWithUTF8($content)
{
$map = array(
":face_with_tears_of_joy:" => "\xF0\x9F\x98\x82",
":grinning_face_with_smiling_eyes:" => "\xF0\x9F\x98\x81",
":smiling_face_with_open_mouth:" => "\xF0\x9F\x98\x83",
":smiling_face_with_open_mouth_and_cold_sweat:" => "\xF0\x9F\x98\x85",
":smiling_face_with_open_mouth_and_tightly_closed_eyes:" => "\xF0\x9F\x98\x86",
":winking_face:" => "\xF0\x9F\x98\x89",
":smiling_face_with_smiling_eyes:" => "\xF0\x9F\x98\x8A",
":face_savouring_delicious_food:" => "\xF0\x9F\x98\x8B",
":relieved_face:" => "\xF0\x9F\x98\x8C",
":smiling_face_with_heart_shaped_eyes:" => "\xF0\x9F\x98\x8D",
":smiling_face_with_sunglasses:" => "\xF0\x9F\x98\x8E",
":smirking_face:" => "\xF0\x9F\x98\x8F",
":neutral_face:" => "\xF0\x9F\x98\x90",
":expressionless_face:" => "\xF0\x9F\x98\x91",
":unamused_face:" => "\xF0\x9F\x98\x92",
":face_with_cold_sweat:" => "\xF0\x9F\x98\x93",
":pensive_face:" => "\xF0\x9F\x98\x94",
":confused_face:" => "\xF0\x9F\x98\x95",
":confounded_face:" => "\xF0\x9F\x98\x96",
":kissing_face:" => "\xF0\x9F\x98\x97",
":face_throwing_a_kiss:" => "\xF0\x9F\x98\x98",
":kissing_face_with_smiling_eyes:" => "\xF0\x9F\x98\x99",
":kissing_face_with_closed_eyes:" => "\xF0\x9F\x98\x9A",
":face_with_stuck_out_tongue:" => "\xF0\x9F\x98\x9B",
":face_with_stuck_out_tongue_and_winking_eye:" => "\xF0\x9F\x98\x9C",
":face_with_stuck_out_tongue_and_tightly_closed_eyes:" => "\xF0\x9F\x98\x9D",
":disappointed_face:" => "\xF0\x9F\x98\x9E",
":worried_face:" => "\xF0\x9F\x98\x9F",
":angry_face:" => "\xF0\x9F\x98\xA0",
":face_with_symbols_on_mouth:" => "\xF0\x9F\x98\xA1",
);
foreach ($map as $key => $value) {
$content = str_replace($key, $value, $content);
}
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
part of content
if ($contenttype == 'html') {
$content = preg_replace('/.*<\/head>/ims', '', $content);
$content = preg_replace('/^.*]*)*>/ims', '', $content);
$content = preg_replace('/<\/body(\s[^>]*)*>.*$/ims', '', $content);
}
} elseif (defined('USEDOLIBARRSERVER')) { // REPLACEMENT OF LINKS When page called from Dolibarr server
$content = str_replace('ref.'"', $content, -1, $nbrep);
// Replace relative link /xxx.php#aaa or /xxx.php with dolibarr URL: ...href="....php" (we discard param ?...)
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2\3"', $content, -1, $nbrep);
// Replace relative link /xxx.php?a=b&c=d#aaa or /xxx.php?a=b&c=d with dolibarr URL
// Warning: we may replace twice if href="..." was inside an include (dolWebsiteOutput called by include and the by final page), that's why
// at end we replace the '!~!~!~' only if we are in final parent page.
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php\?([^#\"<>]*)(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2&\3\4"', $content, -1, $nbrep);
// Replace relative link without .php like /xxx#aaa or /xxx with dolibarr URL: ...href="....php"
$content = preg_replace('/(href=")\/?([a-zA-Z0-9\-_#]+)(\"|\?)/', '\1!~!~!~'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2\3', $content, -1, $nbrep);
// Fix relative link /document.php with correct URL after the DOL_URL_ROOT: href="/document.php?modulepart=" => href="/dolibarr/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=" => href="/dolibarr/viewimage.php?modulepart="
$content = preg_replace('/(href=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
$content = preg_replace('/(src=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
$content = preg_replace('/(url\(")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
// Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/
$content = preg_replace('/url\((["\']?)\/?medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
$content = preg_replace('/data-slide-bg=(["\']?)\/?medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
// ]*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 .= '