Your IP : 216.73.216.240
<?php
/**
* @copyright
* @package Easybook Reloaded - EBR for Joomla! 3.x
* @author Viktor Vogel <admin@kubik-rubik.de>
* @version 3.4.1.1-FREE - 2021-08-29
* @link https://kubik-rubik.de/ebr-easybook-reloaded
*
* @license GNU/GPL
* 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 <http://www.gnu.org/licenses/>.
*/
namespace EasybookReloaded;
defined('_JEXEC') || die('Restricted access');
use Exception;
use GeSHi;
use Joomla\CMS\{Factory, Plugin\PluginHelper, Cache\Cache, Uri\Uri, Language\Text};
/**
* Class Content
*
* @package EasybookReloaded
*
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
class Content
{
/**
* Parses the content and comment of the entries
*
* @param string $message
*
* @return null|string|string[]
* @throws Exception
* @since 3.4.0-FREE
*/
public static function parse(string $message)
{
// Convert CR and LF to HTML BR command
$message = preg_replace('@(\015\012)|(\015)|(\012)@', '<br />', $message);
if (Helper::getParams('supportSmilie', true)) {
static::replaceSmilies($message);
}
if (Helper::getParams('supportBbCode', true)) {
static::convertBbCode($message);
}
if (Helper::getParams('wordWrap', true)) {
static::wordwrap($message);
}
return $message;
}
/**
* Replaces all smilies with the corresponding images
*
* @param string $message
*
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
public static function replaceSmilies(string &$message): void
{
$smiley = Smilie::getSmilies();
// Save code blocks temporarily in an array to avoid replacement
preg_match_all('@\[code=?(.*?)\](<br />)*(.*?)(<br />)*\[/code\]@si', $message, $matches);
$i = 0;
foreach ($matches[0] as $match) {
$message = str_replace($match, '[codetemp' . $i . ']', $message);
$i++;
}
foreach ($smiley as $i => $sm) {
if ((int)Helper::getParams('smilieSet') === 0) {
$message = str_replace($i, '<img src="' . Uri::base() . 'components/com_easybookreloaded/images/smilies/' . $sm . '" alt="' . $i . '" title="' . $i . '" />', $message);
} else {
$message = str_replace($i, '<img src="' . Uri::base() . 'components/com_easybookreloaded/images/smilies2/' . $sm . '" alt="' . $i . '" title="' . $i . '" />', $message);
}
}
// Reset all code blocks
$i = 0;
foreach ($matches[0] as $match) {
$message = str_replace('[codetemp' . $i . ']', $match, $message);
$i++;
}
}
/**
* Converts all supported BBCode to correct HTML output
*
* @param string $message
*
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
public static function convertBbCode(string &$message): void
{
$message = preg_replace('@\[quote\](.*?)\[/quote]@si', '<strong>Quote:</strong><br /><blockquote>\\1</blockquote>', $message);
$message = preg_replace('@\[b\](.*?)\[/b\]@si', '<strong>\\1</strong>', $message);
$message = preg_replace('@\[i\](.*?)\[/i\]@si', '<i>\\1</i>', $message);
$message = preg_replace('@\[u\](.*?)\[/u\]@si', '<u>\\1</u>', $message);
$message = preg_replace('@\[center\](.*)\[/center\]@siU', '<p class="easy_center">\\1</p>', $message);
if (Helper::getParams('supportLink', false)) {
$message = preg_replace('@\[url=(http://)?(.*?)\](.*?)\[/url\]@si', '<a href="http://\\2" title="\\3" rel="nofollow" target="_blank">\\3</a>', $message);
}
if (Helper::getParams('supportCode', false)) {
$message = preg_replace('@\[CODE=?(.*?)\](<br />)*(.*?)(<br />)*\[/code\]@si', '<pre xml:\\1>\\3</pre>', $message);
$regex = '@<pre xml:s*(.*?)>(.*?)</pre>@s';
$message = preg_replace_callback($regex, ['self', 'geshiReplacer'], $message);
}
if (Helper::getParams('supportMail', true) && preg_match_all('@\[email\](.*?)\[/email\]@si', $message, $matches)) {
foreach ($matches[1] as $value) {
$message = preg_replace('@\[email\](.*?)\[/email\]@si', static::cloak($value), $message);
}
}
if (Helper::getParams('supportPictures', false)) {
$message = preg_replace('@\[img\](.*)\[/img\]@siU', '<img src="\\1" alt="\\1" title="\\1" />', $message);
$message = preg_replace('@\[imglink=(http://)?(.*?)\](.*?)\[/imglink\]@si', '<a href="http://\\2" title="\\2" rel="nofollow" target="_blank"><img src="\\3" alt="\\3" /></a>', $message);
}
if (Helper::getParams('supportYoutube', false)) {
preg_match_all('@\[youtube\](.*)\[/youtube\]@siU', $message, $matches);
if (!empty($matches[1])) {
$count = 0;
foreach ($matches[1] as $match) {
if (preg_match('@v=([^&]+)&?.*@', $match, $videoId)) {
$match = $videoId[1];
}
$message = str_replace($matches[0][$count], '[youtube]' . $match . '[/youtube]', $message);
$count++;
}
$message = preg_replace('@\[youtube\](.*)\[/youtube\]@siU', '<p class="easy_center"><iframe width="640" height="360" src="https://www.youtube.com/embed/\\1" frameborder="0" allowfullscreen></iframe></p>', $message);
}
}
$matchCount = preg_match_all('@\[list\](.*?)\[/list\]@si', $message, $matches);
for ($i = 0; $i < $matchCount; $i++) {
$currMatchTextBefore = preg_quote($matches[1][$i], '@');
$currMatchTextAfter = preg_replace('@\[\*\]@si', '<li>', $matches[1][$i]);
$message = preg_replace('@\[list\]' . $currMatchTextBefore . '\[/list\]@si', '<ul>' . $currMatchTextAfter . '</ul>', $message);
}
$matchCount = preg_match_all('@\[list=([a1])\](.*?)\[/list\]@si', $message, $matches);
for ($i = 0; $i < $matchCount; $i++) {
$currMatchTextBefore = preg_quote($matches[2][$i], '@');
$currMatchTextAfter = preg_replace('@\[\*\]@si', '<li>', $matches[2][$i]);
$message = preg_replace('@\[list=([a1])\]' . $currMatchTextBefore . '\[/list\]@si', '<ol type=\\1>' . $currMatchTextAfter . '</ol>', $message);
}
}
/**
* Simple JavaScript email cloaker
*
* By default replaces an email with a mailto link with email cloaked
*
* @param string $mail
* @param bool $mailto
* @param string $text
* @param bool $email
*
* @return string
* @throws Exception
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
public static function cloak(string $mail, bool $mailto = true, string $text = '', bool $email = true): string
{
// Convert text
$mail = self::convertEncoding($mail);
// Split email by @ symbol
$mail = explode('@', $mail);
$mailParts = explode('.', $mail[1]);
// Random number
$rand = random_int(1, 100000);
$replacement = "<script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n var prefix = 'ma' + 'il' + 'to';";
$replacement .= "\n var path = 'hr' + 'ef' + '=';";
$replacement .= "\n var addy" . $rand . " = '" . @$mail[0] . "' + '@';";
$replacement .= "\n addy" . $rand . " = addy" . $rand . " + '" . implode("' + '.' + '", $mailParts) . "';";
if ($mailto) {
// Special handling when mail text is different from mail address
if ($text) {
if ($email) {
// Convert text - here is the right place
$text = self::convertEncoding($text);
// Split email by @ symbol
$text = explode('@', $text);
$textParts = explode('.', $text[1]);
$replacement .= "\n var addy_text" . $rand . " = '" . @$text[0] . "' + '@' + '" . implode("' + '.' + '", @$textParts) . "';";
} else {
$replacement .= "\n var addy_text" . $rand . " = '" . $text . "';";
}
$replacement .= "\n document.write('<a ' + path + '\'' + prefix + ':' + addy" . $rand . " + '\'>');";
$replacement .= "\n document.write(addy_text" . $rand . ");";
$replacement .= "\n document.write('<\/a>');";
} else {
$replacement .= "\n document.write('<a ' + path + '\'' + prefix + ':' + addy" . $rand . " + '\'>');";
$replacement .= "\n document.write(addy" . $rand . ");";
$replacement .= "\n document.write('<\/a>');";
}
} else {
$replacement .= "\n document.write(addy" . $rand . ");";
}
$replacement .= "\n //-->";
$replacement .= '\n </script>';
// XHTML compliance no Javascript text handling
$replacement .= "<script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n document.write('<span style=\'display: none;\'>');";
$replacement .= "\n //-->";
$replacement .= "\n </script>";
$replacement .= Text::_('JLIB_HTML_CLOAKING');
$replacement .= "\n <script type='text/javascript'>";
$replacement .= "\n <!--";
$replacement .= "\n document.write('</');";
$replacement .= "\n document.write('span>');";
$replacement .= "\n //-->";
$replacement .= "\n </script>";
return $replacement;
}
/**
* Converts encoded text
*
* @param string $text
*
* @return string
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
protected static function convertEncoding(string $text): string
{
// Replace vowels with character encoding
return str_replace(['a', 'e', 'i', 'o', 'u'], ['a', 'e', 'i', 'o', 'u'], $text);
}
/**
* Wraps the text to a given number of characters
*
* @param string $message
*
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
public static function wordwrap(string &$message): void
{
$size = (int)Helper::getParams('maxlength', 75);
$words = explode(' ', strip_tags($message));
foreach ($words as $value) {
if (strlen($value) > $size) {
$message = str_replace($value, wordwrap($value, $size, ' ', true), $message);
}
}
}
/**
* Replaces code blocks into formatted blocks with the help of GeSHi
*
* @param array $matches
*
* @return mixed|null|string|string[]
* @throws Exception
* @since 3.4.0-FREE
*/
public static function geshiReplacer(array $matches)
{
$lang = $matches[1];
$text = $matches[2];
if ($lang === '') {
$lang = 'html5';
}
if ($lang === 'html') {
$lang = 'html5';
} elseif ($lang === 'js') {
$lang = 'javascript';
}
$htmlEntitiesMatch = ["@<br />@", '@&@', "@<@", "@>@", "@'@", '@"@', '@ @'];
$htmlEntitiesReplace = ["\n", '&', '<', '>', "'", '"', ' '];
$text = preg_replace($htmlEntitiesMatch, $htmlEntitiesReplace, $text);
$text = str_replace(['<', '>', "\t"], ['<', '>', ' '], $text);
$geshi = new GeSHi($text, $lang);
$geshi->enable_keyword_links(false);
if ((bool)Helper::getParams('geshiLines', true)) {
$geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
}
return $geshi->parse_code();
}
/**
* Determines correct IP address (correct usage also with a proxy)
*
* @return mixed
* @since 3.4.0-FREE
*/
public static function getIpAddress()
{
$headers = self::getHeadersData();
$ipAddress = filter_var($headers['IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6);
// Get the forwarded IP if it exists
if (array_key_exists('X-Forwarded-For', $headers) && filter_var($headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
$ipAddress = $headers['X-Forwarded-For'];
} elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $headers) && filter_var($headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
$ipAddress = $headers['HTTP_X_FORWARDED_FOR'];
}
return $ipAddress;
}
/**
* Get all required data from the HTTP headers of the request
*
* @return array
* @since 3.4.0-FREE
*/
private static function getHeadersData(): array
{
$headers = ['IP' => $_SERVER['REMOTE_ADDR'], 'UA' => $_SERVER['HTTP_USER_AGENT']];
if (function_exists('apache_request_headers')) {
$headersRequest = apache_request_headers();
if (!empty($headers) && is_array($headers)) {
return array_merge($headers, $headersRequest);
}
}
return $headers;
}
/**
* Gets the user agent of the client
*
* @return string
* @since 3.4.0-FREE
*/
public static function getUserAgent(): string
{
$headers = self::getHeadersData();
if (!empty($headers['User-Agent'])) {
return $headers['User-Agent'];
}
if (!empty($headers['UA'])) {
return $headers['UA'];
}
return 'unknown';
}
/**
* Cleans the cached pages of the component by the system Page Cache plugin
*
* @param int $gbId
*
* @return bool
* @throws Exception
* @since 3.4.0-FREE
* @version 3.4.1.0-FREE
*/
public static function cleanCache(int $gbId = 0): bool
{
if (empty($gbId)) {
$gbId = Route::getGbId();
}
if ($gbId === 0) {
return false;
}
if (PluginHelper::isEnabled('system', 'cache')) {
$cacheId = Uri::getInstance()->toString();
$cacheId = md5(serialize([$cacheId]));
$cache = Cache::getInstance('page');
$cache->remove($cacheId, 'page');
return true;
}
return false;
}
}