<?php
/**
* [PHPFOX_HEADER]
*/
defined('PHPFOX') or exit('NO DICE!');
/**
* Cleans text added to the database and already parsed/cleaned via Parse_Input.
* This is the last attempt to clean out any invalid tags, usually fix invalid HTML tags.
* Anything that needs to be removed should have already been removed with Parse_Input to save
* on running such a heavy routine for each item. We also parse naughty words here as
* this information needs to be checked each time in case new words are added by an Admin.
*
* @see Parse_Input
* @see Parse_Bbcode
* @copyright [PHPFOX_COPYRIGHT]
* @author Raymond Benc
* @package Phpfox
* @version $Id: output.class.php 7308 2014-05-08 14:55:48Z Fern $
*/
class Phpfox_Parse_Output
{
/**
* Regex used to convert URL and emails.
*
* @deprecated 2.0.0rc1
* @var array
*/
private $_aRegEx = array(
'url_to_link' => '~(?>[a-z+]{2,}://|www\.)(?:[a-z0-9]+(?:\.[a-z0-9]+)?@)?(?:(?:[a-z](?:[a-z0-9]|(?<!-)-)*[a-z0-9])(?:\.[a-z](?:[a-z0-9]|(?<!-)-)*[a-z0-9])+|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?:/[^\\/:?*"<>|\n]*[a-z0-9])*/?(?:\?[a-z0-9_.%]+(?:=[a-z0-9_.%:/+-]*)?(?:&[a-z0-9_.%]+(?:=[a-z0-9_.%:/+-]*)?)*)?(?:#[a-z0-9_%.]+)?~is',
'email' => '/[-a-zA-Z0-9._]+@[-a-zA-Z0-9._]+(\.[-a-zA-Z0-9._]+)/is'
);
private $_regex = [
'hash_tags' => '/[^\w](#[\wa-zA-Z0-9\[\]\/]+)/u',
'mentions' => '/[^\w](@[\wa-zA-Z0-9-\[\]\/]+)/u'
];
/**
* Parsing settings for images.
*
* @var array
*/
private $_aImageParams = array();
/**
* Parsing settings for video embeds.
*
* @var array
*/
private $_aEmbedParams = array();
/**
* Defines if the string has been shortened or not.
*
* @var bool
*/
private $_bIsShortened = false;
/**
* Defines if the string has reached the maximum break lines or not
*
* @var bool
*/
private $_bIsMaxLine = false;
/**
* Class Constructor.
*
*/
public function __construct()
{
}
/**
* @return $this;
*/
public static function instance() {
return Phpfox::getLib('parse.output');
}
/**
* Text we need to parse, usually text added via a <textarea>.
*
* @param string $sTxt is the string we need to parse
* @return string Parsed string
*/
public function parse($sTxt, $bParseNewLine = true)
{
if (empty($sTxt))
{
return $sTxt;
}
$sTxt = ' ' . $sTxt;
(($sPlugin = Phpfox_Plugin::get('parse_output_parse')) ? eval($sPlugin) : null);
if (isset($override) && is_callable($override)) {
$sTxt = call_user_func($override, $sTxt);
}
elseif (!Phpfox::getParam('core.allow_html')) {
$sTxt = $this->htmlspecialchars($sTxt);
}
$sTxt = Ban_Service_Word::instance()->clean($sTxt);
$sTxt = $this->parseUrls($sTxt);
$sTxt = preg_replace_callback('/\[PHPFOX_PHRASE\](.*?)\[\/PHPFOX_PHRASE\]/i', array($this, '_getPhrase'), $sTxt);
$sTxt = ' ' . $sTxt;
$sTxt = Phpfox_Parse_Bbcode::instance()->parse($sTxt);
if (Phpfox::getParam('tag.enable_hashtag_support'))
{
$sTxt = $this->replaceHashTags($sTxt);
}
$sTxt = str_replace("\n\r\n\r", "", $sTxt);
$sTxt = str_replace("\n\r", "", $sTxt);
$sTxt = preg_replace('/>([\s]+)</m', "><", $sTxt);
if($bParseNewLine) {
$sTxt = str_replace("\n", "<div class=\"newline\"></div>", $sTxt);
}
$sTxt = $this->replaceUserTag($sTxt);
$sTxt = trim($sTxt);
return $sTxt;
}
/**
* @param $str
* @return \Api\User\Object[]
*/
public function mentionsRegex($str) {
$users = '';
$return = [];
preg_match_all($this->_regex['mentions'], $str, $matches);
if (isset($matches[1]) && is_array($matches[1])) {
foreach ($matches[1] as $match) {
$users .= '\'' . str_replace('@', '', $match) . '\',';
}
}
$users = rtrim($users, ',');
if ($users) {
$search = Phpfox_Database::instance()->select('*')->from(':user')->where(['user_name' => ['in' => $users]])->all();
foreach ($search as $user) {
$return[] = new \Api\User\Object($user);
}
}
return $return;
}
private function _clean($str) {
$str = strip_tags($str);
$str = str_replace(array('"', "'", ' '), '', $str);
return $str;
}
private function _replaceHashTags($aMatches)
{
$sTagSearch = substr_replace(strip_tags($aMatches[0]), '', 0, 1);
$sTagSearch = preg_replace('/\[UNICODE\]([0-9]+)\[\/UNICODE\]/', '&#\\1;', $sTagSearch);
$sTagSearch = html_entity_decode($sTagSearch, null, 'UTF-8');
$sTagSearch = urlencode($sTagSearch);
$sTxt = '<a href="' . Phpfox_Url::instance()->makeUrl('hashtag', array($sTagSearch)) . '" class="site_hash_tag">' . strip_tags($aMatches[0]) . '</a>';
return $sTxt;
}
private function _replaceHexColor($aMatches)
{
// after change to check whether "color" is in the string or not, this if is incorrect
if(strlen($aMatches[2]) == 3) {
$r = hexdec(substr($aMatches[2],0,1).substr($aMatches[2],0,1));
$g = hexdec(substr($aMatches[2],1,1).substr($aMatches[2],1,1));
$b = hexdec(substr($aMatches[2],2,1).substr($aMatches[2],2,1));
}
else
{
$r = hexdec(substr($aMatches[2],0,2));
$g = hexdec(substr($aMatches[2],2,2));
$b = hexdec(substr($aMatches[2],4,2));
}
$sRGB = "rgb(" . $r . "," . $g . ",". $b . ")";
return " color:" . $sRGB;
}
public function _replaceUnicode($aMatches)
{
return '[UNICODE]' . (int) str_replace(array('&#', ';'), '', $aMatches[0]) . '[/UNICODE]';
}
public function replaceHashTags($sTxt)
{
$sTxt = preg_replace_callback("/<a.*?<\/a>(*SKIP)(*F)|(&#+[0-9+]+;)/", array($this, '_replaceUnicode'), $sTxt);
$sTxt = preg_replace_callback("/<a.*?<\/a>(*SKIP)(*F)|(\-?color:)\s*#([A-F0-9]{3,6})/i", array($this, '_replaceHexColor'), $sTxt);
$sTxt = preg_replace_callback("/<a.*?<\/a>(*SKIP)(*F)|(#[^\s]+)/iu", array($this, '_replaceHashTags'), $sTxt);
$sTxt = preg_replace('/\[UNICODE\]([0-9]+)\[\/UNICODE\]/', '&#\\1;', $sTxt);
return $sTxt;
}
public function getHashTags($sTxt)
{
$aTags = array();
$sTxt = str_replace(array('<br >', '<br />', '<p>', '</p>'), ' ', $sTxt);
$sTxt = preg_replace_callback("/(&#+[0-9+]+;)/", array($this, '_replaceUnicode'), $sTxt);
$sTxt = preg_replace("/#([A-F0-9]{6})/i", "", $sTxt);
$sTxt = preg_replace("/(http[s]?:\/\/(www\.)?|ftp:\/\/(www\.)?|www\.){1}([0-9A-Za-z-\-\.@:%_\+~#=]+)+((\.[a-zA-Z]{2,3})+)(\/([0-9A-Za-z-\-\.@:%_\+~#=\?])*)*/i", "", $sTxt);
preg_match_all("/(#[^\s]*)/iu", $sTxt, $aMatches);
if (is_array($aMatches) && count($aMatches))
{
foreach ($aMatches as $aSubTags)
{
foreach ($aSubTags as $sTag)
{
$sTag = preg_replace('/\[UNICODE\]([0-9]+)\[\/UNICODE\]/', '&#\\1;', $sTag);
$aTags[] = substr_replace($sTag, '', 0, 1);
}
break;
}
}
return $aTags;
}
public function parseUrls($sTxt)
{
if (Phpfox::getParam('core.disable_all_external_emails'))
{
$sTxt = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', array(&$this, '_replaceEmails'), $sTxt);
}
if (Phpfox::getParam('core.disable_all_external_urls'))
{
$sTxt = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', array(&$this, '_replaceLinks'), $sTxt);
$sTxt = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', array(&$this, '_replaceLinks'), $sTxt);
}
if (Phpfox::getParam('core.warn_on_external_links'))
{
$sTxt = preg_replace_callback('/<a\s(.*?)>/i', array(&$this, '_warnOnExtLink'), $sTxt);
}
$sTxt = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', array(&$this, '_urlToLink'), $sTxt);
$sTxt = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', array(&$this, '_urlToLink'), $sTxt);
if (Phpfox::getParam('core.no_follow_on_external_links'))
{
$sTxt = preg_replace('/<a\s(.*?)>/is', '<a \\1 rel="nofollow">', $sTxt);
}
$sTxt = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $sTxt);
$sTxt = trim($sTxt);
return $sTxt;
}
private function _warnOnExtLink($aMatches)
{
if (!isset($aMatches[1]))
{
return '';
}
$sHref = '';
$aParts = explode(' ', $aMatches[1]);
foreach ($aParts as $sPart)
{
if (substr($sPart, 0, 5) == 'href=')
{
$sHref = $sPart;
if (!preg_match('/' . preg_quote(Phpfox::getParam('core.host')) . '/i', $sHref))
{
$sHref = str_replace(array('"', "'"), '', $sHref);
$sHref = substr_replace($sHref, '', 0, 5);
$sHref = 'href="' . Phpfox_Url::instance()->makeUrl('core.redirect', array('url' => Phpfox_Url::instance()->encode($sHref))) . '"';
}
return '<a ' . $sHref . '>';
break;
}
}
if (empty($sHref))
{
return '<a ' . $aMatches[1] . '>';
}
}
public function parseUserTagged($iUser)
{
return $this->_parseUserTagged($iUser);
}
/**
* Parses users from tags by querying the DB and getting their full name.
*/
private function _parseUserTagged($iUser)
{
if (is_array($iUser)) $iUser = $iUser[1];
static $aCache = array();
if (!isset($aCache[$iUser]))
{
$oDb = Phpfox_Database::instance();
$aUser = $oDb->select('up.user_value, u.full_name, user_name')
->from(Phpfox::getT('user'), 'u')
->leftJoin(Phpfox::getT('user_privacy'), 'up', 'up.user_id = u.user_id AND up.user_privacy = \'user.can_i_be_tagged\'')
->where('u.user_id = ' . (int) $iUser)
->execute('getSlaveRow');
$sOut = '';
if (isset($aUser['user_value']) && !empty($aUser['user_value']) && $aUser['user_value'] > 2)
{
$sOut = $aUser['full_name'];
}
else
{
if (isset($aUser['user_name']))
{
$sOut = '<a class="test" id="'.json_encode($iUser).'" href="' . Phpfox_Url::instance()->makeUrl($aUser['user_name']) .'">' . $aUser['full_name'] .'</a>';
}
}
$aCache[$iUser] = $sOut;
return $sOut;
}
else
{
return $aCache[$iUser];
}
}
public function feedStrip($sStr)
{
return $this->parse(strip_tags($sStr));
}
public function maxLine($sStr)
{
if (!$this->isShortened() && Phpfox::getParam('core.activity_feed_line_breaks') > 0)
{
$aLines = explode("<br />", $sStr);
if (count($aLines) > Phpfox::getParam('core.activity_feed_line_breaks'))
{
$sLines = '<span class="js_read_more_parent_main">';
$iLineCnt = 0;
foreach ($aLines as $sLine)
{
$iLineCnt++;
if ($iLineCnt > Phpfox::getParam('core.activity_feed_line_breaks'))
{
$this->_bIsMaxLine = true;
$sLines .= '<span class="js_read_more_parent" style="display:none;">';
$sLines .= $sLine . '<br />';
$sLines .= '</span>';
}
else
{
$sLines .= $sLine . '<br />';
}
}
if (isset($this->_bIsMaxLine))
{
$sLines .= '<div><a href="#" onclick="$(this).parents(\'.js_read_more_parent_main:first\').find(\'.js_read_more_parent\').show(); $(this).hide(); return false;">' . _p('view_more') . '</a></div>';
}
$sLines .= '</span>';
return $sLines;
}
}
return $sStr;
}
public function replaceUserTag($sStr)
{
$sStr = preg_replace_callback('/\[user=(\d+)\].+?\[\/user\]/u', array($this, '_parseUserTagged'), $sStr);
return $sStr;
}
/**
* Set image parser settings.
*
* @param array $aParams ARRAY of settings.
*/
public function setImageParser($aParams)
{
if (isset($aParams['clear']))
{
$this->_aImageParams = array();
}
else
{
$this->_aImageParams = $aParams;
}
}
/**
* Set video embed settings.
*
* @param array $aParams ARRAY of settings.
*/
public function setEmbedParser($aParams = null)
{
if ($aParams == null)
{
$this->_aEmbedParams = array('width' => Phpfox::getParam('feed.width_for_resized_videos'), 'height' => Phpfox::getParam('feed.height_for_resized_videos'));
}
elseif (isset($aParams['clear']))
{
$this->_aEmbedParams = array();
}
else
{
$this->_aEmbedParams = $aParams;
}
}
/**
* Clean input text, usually used within HTML <input>
*
* @param string $sTxt is the string we need to clean
* @param bool $bHtmlChar TRUE to convert HTML characters or FALSE to not convert.
* @return string Cleaned string
*/
public function clean($sTxt, $bHtmlChar = true)
{
if (!defined('PHPFOX_INSTALLER'))
{
$sTxt = Ban_Service_Word::instance()->clean($sTxt);
}
$sTxt = ($bHtmlChar ? $this->htmlspecialchars($sTxt) : $sTxt);
$sTxt = str_replace(' ', '', $sTxt);
return $sTxt;
}
/**
* Our method of PHP htmlspecialchars().
*
* @see htmlspecialchars()
* @param string $sTxt String to convert.
* @return string Converted string.
*/
public function htmlspecialchars($sTxt)
{
$sTxt = preg_replace('/&(?!(#[0-9]+|[a-z]+);)/si', '&', $sTxt);
$sTxt = str_replace(array(
'"',
"'",
'<',
'>'
),
array(
'"',
''',
'<',
'>'
), $sTxt);
return $sTxt;
}
/**
* Clean text when being sent back via AJAX.
* Usually this is used to send back to an HTML <textarea>
*
* @param string $sTxt is the text we need to clean
* @return string Cleaned Text
*/
public function ajax($sTxt)
{
$sTxt = Ban_Service_Word::instance()->clean($sTxt);
$sTxt = str_replace("\r", "", $sTxt);
return $sTxt;
}
public function truncate($text, $length){
$html = true;
$ending = '';
$exact = true;
if ($html) {
if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
return $text;
}
$totalLength = mb_strlen(strip_tags($ending));
$openTags = array();
$truncate = '';
preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
foreach ($tags as $tag) {
if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
array_unshift($openTags, $tag[2]);
} else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
$pos = array_search($closeTag[1], $openTags);
if ($pos !== false) {
array_splice($openTags, $pos, 1);
}
}
}
$truncate .= $tag[1];
$contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
if ($contentLength + $totalLength > $length) {
$left = $length - $totalLength;
$entitiesLength = 0;
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
foreach ($entities[0] as $entity) {
if ($entity[1] + 1 - $entitiesLength <= $left) {
$left--;
$entitiesLength += mb_strlen($entity[0]);
} else {
break;
}
}
}
$truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
break;
} else {
$truncate .= $tag[3];
$totalLength += $contentLength;
}
if ($totalLength >= $length) {
break;
}
}
} else {
if (mb_strlen($text) <= $length) {
return $text;
} else {
$truncate = mb_substr($text, 0, $length - mb_strlen($ending));
}
}
if (!$exact) {
$spacepos = mb_strrpos($truncate, ' ');
if (isset($spacepos)) {
if ($html) {
$bits = mb_substr($truncate, $spacepos);
preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
if (!empty($droppedTags)) {
foreach ($droppedTags as $closingTag) {
if (!in_array($closingTag[1], $openTags)) {
array_unshift($openTags, $closingTag[1]);
}
}
}
}
$truncate = mb_substr($truncate, 0, $spacepos);
}
}
$truncate .= $ending;
if ($html) {
foreach ($openTags as $tag) {
$truncate .= '</'.$tag.'>';
}
}
return $truncate;
}
/**
* Shortens a string.
*
* @param string $html String to shorten.
* @param int $maxLength Max length.
* @param string $sSuffix Optional suffix to add.
* @param bool $bHide TRUE to hide the shortened string, FALSE to remove it.
* @return string Returns the new shortened string.
*/
public function shorten($html, $maxLength, $sSuffix = null, $bHide = false)
{
mb_internal_encoding('UTF-8');
if (defined('PHPFOX_LANGUAGE_SHORTEN_BYPASS') || $maxLength === 0 || $this->hasReachedMaxLine() || Phpfox::getParam('language.no_string_restriction'))
{
return $html;
}
$sNewString = $this->truncate($html, $maxLength) ;
if ($sSuffix !== null)
{
$sCountHtml = strip_tags($html);
$sCountHtml = preg_replace('/&#?[a-zA-Z0-9]+;/i', 'A', $sCountHtml);
if (strlen($sCountHtml) > $maxLength)
{
if (preg_match('/^(.*)\.(.*)$/', $sSuffix, $aMatches) && count($aMatches) === 3 && Phpfox::isModule($aMatches[1]))
{
$sSuffix = _p($sSuffix);
}
$this->_bIsShortened = true;
if ($bHide === true)
{
if (defined('PHPFOX_IS_THEATER_MODE'))
{
$sNewString = '<span class="js_view_more_parent"><span class="js_view_more_part">' . $this->closeAllHtmlTags($sNewString) . '...<span class="item_view_more"><a href="#" onclick="$(this).parents(\'.js_view_more_parent:first\').find(\'.js_view_more_part\').hide(); $(this).parents(\'.js_view_more_parent:first\').find(\'.js_view_more_full\').show(); return false;">' . $sSuffix . '</a></span></span>';
$sNewString .= '<span class="js_view_more_full" style="display:none; position:absolute; z-index:10000; background:#fff; border:1px #dfdfdf solid;">';
$sNewString .= '<div style="max-height:200px; overflow:auto; padding:5px;">' . $html . '</div>';
$sNewString .= '</span>';
$sNewString .= '</span>';
}
else
{
$sNewString = '<span class="js_view_more_parent"><span class="js_view_more_part">' . $this->closeAllHtmlTags($sNewString) . '...<span class="item_view_more"><a href="#" onclick="$(this).parents(\'.js_view_more_parent:first\').find(\'.js_view_more_part\').hide(); $(this).parents(\'.js_view_more_parent:first\').find(\'.js_view_more_full\').show(); return false;">' . $sSuffix . '</a></span></span>';
$sNewString .= '<span class="js_view_more_full" style="display:none;">';
$sNewString .= $html;
$sNewString .= '</span>';
$sNewString .= '</span>';
}
}
else
{
$sNewString .= $sSuffix;
}
}
}
return $sNewString;
}
/**
* Return if the last string we checked was shortened.
*
* @return bool TRUE it was shortened, FALSE if was not.
*/
public function isShortened()
{
$bLastCheck = $this->_bIsShortened;
$this->_bIsShortened = false;
return $bLastCheck;
}
/**
* Return if the last string we checked reached the max number of lines.
*
* @return bool TRUE it was reached, FALSE if was not.
*/
public function hasReachedMaxLine()
{
$bLastCheck = $this->_bIsMaxLine;
$this->_bIsMaxLine = false;
return $bLastCheck;
}
/**
* Split a string at a specified location. This allows for browsers to
* automatically add breaks or wrap long text strings.
*
* @param string $sString Text string you want to split.
* @param int $iCount How many characters to wait until we need to perform the split.
* @param bool $bBreak FALSE will just add a space and TRUE will add an HTML <br />.
* @return string Converted string with splits included.
*/
public function split($sString, $iCount, $bBreak = false)
{
if ($sString == '0' || Phpfox::getParam('language.no_string_restriction')) {
return $sString;
}
$sNewString = '';
$aString = explode('>', $sString);
$iSizeOf = sizeof($aString);
$bHasNonAscii = false;
for ($i=0; $i < $iSizeOf; ++$i)
{
$aChar = explode('<', $aString[$i]);
if (!empty($aChar[0]))
{
if (preg_match('/&#?[a-zA-Z0-9]+;/', $aChar[0]))
{
$aChar[0] = str_replace('<', '[PHPFOX_START]', $aChar[0]);
$aChar[0] = str_replace('>', '[PHPFOX_END]', $aChar[0]);
$aChar[0] = html_entity_decode($aChar[0], null, 'UTF-8');
$bHasNonAscii = true;
}
if ($iCount > 9999)
{
$iCount = 9999;
}
$sNewString .= preg_replace('#([^\n\r(?!PHPFOX_) ]{'. $iCount .'})#iu', '\\1 ' . ($bBreak ? '<br />' : ''), $aChar[0]);
}
if (!empty($aChar[1]))
{
$sNewString .= '<' . $aChar[1] . '>';
}
}
$sOut = ($bHasNonAscii === true ? str_replace(array('[PHPFOX_START]', '[PHPFOX_END]'), array('<', '>'), Phpfox::getLib('parse.input')->convert($sNewString)) : $sNewString);
return $sOut;
}
public function closeAllHtmlTags($html) {
#put all opened tags into an array
preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
$openedtags = $result[1]; #put all closed tags into an array
preg_match_all('#</([a-z]+)>#iU', $html, $result);
$closedtags = $result[1];
$len_opened = count($openedtags);
# all tags are closed
if (count($closedtags) == $len_opened) {
return $html;
}
$openedtags = array_reverse($openedtags);
# close tags
for ($i=0; $i < $len_opened; $i++) {
if (!in_array($openedtags[$i], $closedtags)){
$html .= '</'.$openedtags[$i].'>';
} else {
unset($closedtags[array_search($openedtags[$i], $closedtags)]);
}
}
return $html;
}
/**
* Replace unwanted emails on the site. We also take into account emails
* that are added into the "white" list.
*
* @param array $aMatches ARRAY matches from preg_match.
* @return string Returns replaced emails.
*/
private function _replaceEmails($aMatches)
{
static $aSites = null;
if ($aSites === null)
{
$aSites = explode(',', trim(Phpfox::getParam('core.email_white_list')));
}
foreach ($aSites as $sSite)
{
$sSite = trim($sSite);
$sSite = str_replace(array('.', '*'), array('\.', '(.*?)'), $sSite);
if (preg_match('/' . $sSite . '/is', $aMatches[0]))
{
return $aMatches[0];
}
}
}
/**
* Replace unwanted links on the site. We also take into account links
* that are added into the "white" list.
*
* @param array $aMatches ARRAY matches from preg_match.
* @return string Returns replaced links.
*/
private function _replaceLinks($aMatches)
{
static $aSites = null;
if ($aSites === null)
{
$aSites = explode(',', trim(Phpfox::getParam('core.url_spam_white_list')) . ',' . Phpfox::getParam('core.host'));
}
foreach ($aSites as $sSite)
{
$sSite = trim($sSite);
$sSite = str_replace(array('.', '*'), array('\.', '(.*?)'), $sSite);
if (preg_match('/' . str_replace('/','\/',$sSite) . '/is', $aMatches[0]))
{
return $aMatches[0];
}
}
}
/**
* Converts a URL into a HTML anchor.
*
* @param array $aMatches ARRAY matches from preg_match.
* @return string Converted URL.
*/
private function _urlToLink($aMatches)
{
$aMatches[2] = trim($aMatches[2]);
if (empty($aMatches[2]))
{
return '';
}
$sHref = $aMatches[2];
if ($sHref == 'ftp.')
{
return ' ' . $sHref;
}
if (!preg_match("/^(http|https|ftp):\/\/(.*?)$/i", $sHref))
{
$sHref = 'http://' . $sHref;
}
$sName = $aMatches[2];
if (Phpfox::getParam('core.shorten_parsed_url_links') > 0)
{
$sName = substr($sName, 0, Phpfox::getParam('core.shorten_parsed_url_links')) . (strlen($sName) > Phpfox::getParam('core.shorten_parsed_url_links') ? '...' : '');
}
if (Phpfox::getParam('core.warn_on_external_links'))
{
if (!preg_match('/' . preg_quote(Phpfox::getParam('core.host')) . '/i', $sHref))
{
$sHref = Phpfox_Url::instance()->makeUrl('core.redirect', array('url' => Phpfox_Url::instance()->encode($sHref)));
}
}
return $aMatches[1] . "<a href=\"" . $sHref . "\" target=\"_blank\" rel=\"nofollow\">" . $sName . "</a> ";
}
/**
* Gets a phrase from the language package.
*
* @param string $aMatches ARRAY matches from preg_match.
* @return string Returns the phrase if we can find it.
*/
private function _getPhrase($aMatches)
{
return (isset($aMatches[1]) ? _p($aMatches[1]) : $aMatches[0]);
}
/**
* Fixes image widths.
*
* @param array $aMatches ARRAY of matches from a preg_match.
* @return string Returns the image with max-width and max-height included.
*/
private function _fixImageWidth($aMatches)
{
$aParts = Phpfox::getLib('parse.input')->getParams($aMatches[1]);
$iWidth = (isset($this->_aImageParams['width']) ? (int) $this->_aImageParams['width'] : 400);
$iHeight = (isset($this->_aImageParams['height']) ? (int) $this->_aImageParams['height'] : 400);
(($sPlugin = Phpfox_Plugin::get('parse_output_fiximagewidth')) ? eval($sPlugin) : false);
return '<img style="max-width:' . $iWidth . 'px; max-height:' . $iHeight . '" ' . $aMatches[1] . '>';
}
}