mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-03 09:54:27 +02:00
Rewrote remaining plugins to PSR-4, plugins dir is now gone.
This commit is contained in:
@@ -1,110 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Smarty plugin to format text blocks
|
|
||||||
*
|
|
||||||
* @package Smarty
|
|
||||||
* @subpackage PluginsBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
use Smarty\Template;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smarty {textformat}{/textformat} block plugin
|
|
||||||
* Type: block function
|
|
||||||
* Name: textformat
|
|
||||||
* Purpose: format text a certain way with preset styles
|
|
||||||
* or custom wrap/indent settings
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* - style - string (email)
|
|
||||||
* - indent - integer (0)
|
|
||||||
* - wrap - integer (80)
|
|
||||||
* - wrap_char - string ("\n")
|
|
||||||
* - indent_char - string (" ")
|
|
||||||
* - wrap_boundary - boolean (true)
|
|
||||||
*
|
|
||||||
* @link https://www.smarty.net/manual/en/language.function.textformat.php {textformat}
|
|
||||||
* (Smarty online manual)
|
|
||||||
*
|
|
||||||
* @param array $params parameters
|
|
||||||
* @param string $content contents of the block
|
|
||||||
* @param Template $template template object
|
|
||||||
* @param boolean &$repeat repeat flag
|
|
||||||
*
|
|
||||||
* @return string content re-formatted
|
|
||||||
* @author Monte Ohrt <monte at ohrt dot com>
|
|
||||||
* @throws \Smarty\Exception
|
|
||||||
*/
|
|
||||||
function smarty_block_textformat($params, $content, Template $template, &$repeat)
|
|
||||||
{
|
|
||||||
if (is_null($content)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$style = null;
|
|
||||||
$indent = 0;
|
|
||||||
$indent_first = 0;
|
|
||||||
$indent_char = ' ';
|
|
||||||
$wrap = 80;
|
|
||||||
$wrap_char = "\n";
|
|
||||||
$wrap_cut = false;
|
|
||||||
$assign = null;
|
|
||||||
foreach ($params as $_key => $_val) {
|
|
||||||
switch ($_key) {
|
|
||||||
case 'style':
|
|
||||||
case 'indent_char':
|
|
||||||
case 'wrap_char':
|
|
||||||
case 'assign':
|
|
||||||
$$_key = (string)$_val;
|
|
||||||
break;
|
|
||||||
case 'indent':
|
|
||||||
case 'indent_first':
|
|
||||||
case 'wrap':
|
|
||||||
$$_key = (int)$_val;
|
|
||||||
break;
|
|
||||||
case 'wrap_cut':
|
|
||||||
$$_key = (bool)$_val;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
trigger_error("textformat: unknown attribute '{$_key}'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($style === 'email') {
|
|
||||||
$wrap = 72;
|
|
||||||
}
|
|
||||||
// split into paragraphs
|
|
||||||
$_paragraphs = preg_split('![\r\n]{2}!', $content);
|
|
||||||
foreach ($_paragraphs as &$_paragraph) {
|
|
||||||
if (!$_paragraph) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// convert mult. spaces & special chars to single space
|
|
||||||
$_paragraph =
|
|
||||||
preg_replace(
|
|
||||||
array(
|
|
||||||
'!\s+!' . \Smarty::$_UTF8_MODIFIER,
|
|
||||||
'!(^\s+)|(\s+$)!' . \Smarty::$_UTF8_MODIFIER
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
' ',
|
|
||||||
''
|
|
||||||
),
|
|
||||||
$_paragraph
|
|
||||||
);
|
|
||||||
// indent first line
|
|
||||||
if ($indent_first > 0) {
|
|
||||||
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
|
|
||||||
}
|
|
||||||
// wordwrap sentences
|
|
||||||
$_paragraph = smarty_modifier_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
|
||||||
// indent lines
|
|
||||||
if ($indent > 0) {
|
|
||||||
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
|
|
||||||
if ($assign) {
|
|
||||||
$template->assign($assign, $_output);
|
|
||||||
} else {
|
|
||||||
return $_output;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,89 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Smarty plugin
|
|
||||||
*
|
|
||||||
* @package Smarty
|
|
||||||
* @subpackage PluginsFilter
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Smarty trimwhitespace outputfilter plugin
|
|
||||||
* Trim unnecessary whitespace from HTML markup.
|
|
||||||
*
|
|
||||||
* @author Rodney Rehm
|
|
||||||
*
|
|
||||||
* @param string $source input string
|
|
||||||
*
|
|
||||||
* @return string filtered output
|
|
||||||
* @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
|
|
||||||
*/
|
|
||||||
function smarty_outputfilter_trimwhitespace($source)
|
|
||||||
{
|
|
||||||
$store = array();
|
|
||||||
$_store = 0;
|
|
||||||
$_offset = 0;
|
|
||||||
// Unify Line-Breaks to \n
|
|
||||||
$source = preg_replace('/\015\012|\015|\012/', "\n", $source);
|
|
||||||
// capture Internet Explorer and KnockoutJS Conditional Comments
|
|
||||||
if (preg_match_all(
|
|
||||||
'#<!--((\[[^\]]+\]>.*?<!\[[^\]]+\])|(\s*/?ko\s+.+))-->#is',
|
|
||||||
$source,
|
|
||||||
$matches,
|
|
||||||
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
$store[] = $match[ 0 ][ 0 ];
|
|
||||||
$_length = strlen($match[ 0 ][ 0 ]);
|
|
||||||
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
|
||||||
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
|
||||||
$_offset += $_length - strlen($replace);
|
|
||||||
$_store++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Strip all HTML-Comments
|
|
||||||
// yes, even the ones in <script> - see https://stackoverflow.com/a/808850/515124
|
|
||||||
$source = preg_replace('#<!--.*?-->#ms', '', $source);
|
|
||||||
// capture html elements not to be messed with
|
|
||||||
$_offset = 0;
|
|
||||||
if (preg_match_all(
|
|
||||||
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
|
|
||||||
$source,
|
|
||||||
$matches,
|
|
||||||
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
$store[] = $match[ 0 ][ 0 ];
|
|
||||||
$_length = strlen($match[ 0 ][ 0 ]);
|
|
||||||
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
|
||||||
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
|
||||||
$_offset += $_length - strlen($replace);
|
|
||||||
$_store++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$expressions = array(// replace multiple spaces between tags by a single space
|
|
||||||
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
|
|
||||||
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
|
|
||||||
// remove spaces between attributes (but not in attribute values!)
|
|
||||||
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
|
||||||
// note: for some very weird reason trim() seems to remove spaces inside attributes.
|
|
||||||
// maybe a \0 byte or something is interfering?
|
|
||||||
'#^\s+<#Ss' => '<',
|
|
||||||
'#>\s+$#Ss' => '>',
|
|
||||||
);
|
|
||||||
$source = preg_replace(array_keys($expressions), array_values($expressions), $source);
|
|
||||||
// note: for some very weird reason trim() seems to remove spaces inside attributes.
|
|
||||||
// maybe a \0 byte or something is interfering?
|
|
||||||
// $source = trim( $source );
|
|
||||||
$_offset = 0;
|
|
||||||
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
$_length = strlen($match[ 0 ][ 0 ]);
|
|
||||||
$replace = $store[ $match[ 1 ][ 0 ] ];
|
|
||||||
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
|
|
||||||
$_offset += strlen($replace) - $_length;
|
|
||||||
$_store++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $source;
|
|
||||||
}
|
|
9
src/BlockHandler/BlockHandlerInterface.php
Normal file
9
src/BlockHandler/BlockHandlerInterface.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Smarty\BlockHandler;
|
||||||
|
|
||||||
|
use Smarty\Template;
|
||||||
|
|
||||||
|
interface BlockHandlerInterface {
|
||||||
|
public function handle($params, $content, Template $template, &$repeat);
|
||||||
|
}
|
109
src/BlockHandler/TextFormat.php
Normal file
109
src/BlockHandler/TextFormat.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Smarty\BlockHandler;
|
||||||
|
|
||||||
|
use Smarty\Template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty {textformat}{/textformat} block plugin
|
||||||
|
* Type: block function
|
||||||
|
* Name: textformat
|
||||||
|
* Purpose: format text a certain way with preset styles
|
||||||
|
* or custom wrap/indent settings
|
||||||
|
* Params:
|
||||||
|
*
|
||||||
|
* - style - string (email)
|
||||||
|
* - indent - integer (0)
|
||||||
|
* - wrap - integer (80)
|
||||||
|
* - wrap_char - string ("\n")
|
||||||
|
* - indent_char - string (" ")
|
||||||
|
* - wrap_boundary - boolean (true)
|
||||||
|
*
|
||||||
|
* @link https://www.smarty.net/manual/en/language.function.textformat.php {textformat}
|
||||||
|
* (Smarty online manual)
|
||||||
|
*
|
||||||
|
* @param array $params parameters
|
||||||
|
* @param string $content contents of the block
|
||||||
|
* @param Template $template template object
|
||||||
|
* @param boolean &$repeat repeat flag
|
||||||
|
*
|
||||||
|
* @return string content re-formatted
|
||||||
|
* @author Monte Ohrt <monte at ohrt dot com>
|
||||||
|
* @throws \Smarty\Exception
|
||||||
|
*/
|
||||||
|
class TextFormat implements BlockHandlerInterface {
|
||||||
|
|
||||||
|
public function handle($params, $content, Template $template, &$repeat) {
|
||||||
|
if (is_null($content)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$style = null;
|
||||||
|
$indent = 0;
|
||||||
|
$indent_first = 0;
|
||||||
|
$indent_char = ' ';
|
||||||
|
$wrap = 80;
|
||||||
|
$wrap_char = "\n";
|
||||||
|
$wrap_cut = false;
|
||||||
|
$assign = null;
|
||||||
|
foreach ($params as $_key => $_val) {
|
||||||
|
switch ($_key) {
|
||||||
|
case 'style':
|
||||||
|
case 'indent_char':
|
||||||
|
case 'wrap_char':
|
||||||
|
case 'assign':
|
||||||
|
$$_key = (string)$_val;
|
||||||
|
break;
|
||||||
|
case 'indent':
|
||||||
|
case 'indent_first':
|
||||||
|
case 'wrap':
|
||||||
|
$$_key = (int)$_val;
|
||||||
|
break;
|
||||||
|
case 'wrap_cut':
|
||||||
|
$$_key = (bool)$_val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trigger_error("textformat: unknown attribute '{$_key}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($style === 'email') {
|
||||||
|
$wrap = 72;
|
||||||
|
}
|
||||||
|
// split into paragraphs
|
||||||
|
$_paragraphs = preg_split('![\r\n]{2}!', $content);
|
||||||
|
foreach ($_paragraphs as &$_paragraph) {
|
||||||
|
if (!$_paragraph) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// convert mult. spaces & special chars to single space
|
||||||
|
$_paragraph =
|
||||||
|
preg_replace(
|
||||||
|
array(
|
||||||
|
'!\s+!' . \Smarty::$_UTF8_MODIFIER,
|
||||||
|
'!(^\s+)|(\s+$)!' . \Smarty::$_UTF8_MODIFIER
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
' ',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
$_paragraph
|
||||||
|
);
|
||||||
|
// indent first line
|
||||||
|
if ($indent_first > 0) {
|
||||||
|
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
|
||||||
|
}
|
||||||
|
// wordwrap sentences
|
||||||
|
$_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
||||||
|
// indent lines
|
||||||
|
if ($indent > 0) {
|
||||||
|
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
|
||||||
|
if ($assign) {
|
||||||
|
$template->assign($assign, $_output);
|
||||||
|
} else {
|
||||||
|
return $_output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -22,8 +22,7 @@ class WordWrapModifierCompiler extends Base {
|
|||||||
if (!isset($params[ 3 ])) {
|
if (!isset($params[ 3 ])) {
|
||||||
$params[ 3 ] = 'false';
|
$params[ 3 ] = 'false';
|
||||||
}
|
}
|
||||||
$function = $compiler->getPlugin('mb_wordwrap', 'modifier');
|
return 'smarty_mb_wordwrap(' . $params[ 0 ] . ',' . $params[ 1 ] . ',' . $params[ 2 ] . ',' . $params[ 3 ] . ')';
|
||||||
return $function . '(' . $params[ 0 ] . ',' . $params[ 1 ] . ',' . $params[ 2 ] . ',' . $params[ 3 ] . ')';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -18,7 +18,16 @@ class Base implements ExtensionInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getBlockHandler(string $functionName): ?\Smarty\FunctionHandler\BlockHandlerInterface {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getModifierCallback(string $modifierName) {
|
public function getModifierCallback(string $modifierName) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOutputFilters(): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -124,6 +124,19 @@ class Core extends Base {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getBlockHandler(string $blockTagName): ?\Smarty\FunctionHandler\BlockHandlerInterface {
|
||||||
|
switch ($blockTagName) {
|
||||||
|
case 'textformat': return new \Smarty\BlockHandler\TextFormat();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOutputFilters(): array {
|
||||||
|
return [
|
||||||
|
new \Smarty\Filter\Output\TrimWhitespace(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty spacify modifier plugin
|
* Smarty spacify modifier plugin
|
||||||
* Type: modifier
|
* Type: modifier
|
||||||
@@ -560,51 +573,7 @@ class Core extends Base {
|
|||||||
*/
|
*/
|
||||||
private function smarty_modifier_mb_wordwrap($str, $width = 75, $break = "\n", $cut = false)
|
private function smarty_modifier_mb_wordwrap($str, $width = 75, $break = "\n", $cut = false)
|
||||||
{
|
{
|
||||||
// break words into tokens using white space as a delimiter
|
return smarty_mb_wordwrap($str, $width, $break, $cut);
|
||||||
$tokens = preg_split('!(\s)!S' . \Smarty\Smarty::$_UTF8_MODIFIER, $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
|
|
||||||
$length = 0;
|
|
||||||
$t = '';
|
|
||||||
$_previous = false;
|
|
||||||
$_space = false;
|
|
||||||
foreach ($tokens as $_token) {
|
|
||||||
$token_length = mb_strlen($_token, \Smarty\Smarty::$_CHARSET);
|
|
||||||
$_tokens = array($_token);
|
|
||||||
if ($token_length > $width) {
|
|
||||||
if ($cut) {
|
|
||||||
$_tokens = preg_split(
|
|
||||||
'!(.{' . $width . '})!S' . \Smarty\Smarty::$_UTF8_MODIFIER,
|
|
||||||
$_token,
|
|
||||||
-1,
|
|
||||||
PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($_tokens as $token) {
|
|
||||||
$_space = !!preg_match('!^\s$!S' . \Smarty\Smarty::$_UTF8_MODIFIER, $token);
|
|
||||||
$token_length = mb_strlen($token, \Smarty\Smarty::$_CHARSET);
|
|
||||||
$length += $token_length;
|
|
||||||
if ($length > $width) {
|
|
||||||
// remove space before inserted break
|
|
||||||
if ($_previous) {
|
|
||||||
$t = mb_substr($t, 0, -1, \Smarty\Smarty::$_CHARSET);
|
|
||||||
}
|
|
||||||
if (!$_space) {
|
|
||||||
// add the break before the token
|
|
||||||
if (!empty($t)) {
|
|
||||||
$t .= $break;
|
|
||||||
}
|
|
||||||
$length = $token_length;
|
|
||||||
}
|
|
||||||
} elseif ($token === "\n") {
|
|
||||||
// hard break must reset counters
|
|
||||||
$length = 0;
|
|
||||||
}
|
|
||||||
$_previous = $_space;
|
|
||||||
// add the token
|
|
||||||
$t .= $token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -10,6 +10,10 @@ interface ExtensionInterface {
|
|||||||
|
|
||||||
public function getFunctionHandler(string $functionName): ?\Smarty\FunctionHandler\FunctionHandlerInterface;
|
public function getFunctionHandler(string $functionName): ?\Smarty\FunctionHandler\FunctionHandlerInterface;
|
||||||
|
|
||||||
|
public function getBlockHandler(string $blockTagName): ?\Smarty\FunctionHandler\BlockHandlerInterface;
|
||||||
|
|
||||||
public function getModifierCallback(string $modifierName);
|
public function getModifierCallback(string $modifierName);
|
||||||
|
|
||||||
|
public function getOutputFilters(): array;
|
||||||
|
|
||||||
}
|
}
|
9
src/Filter/FilterInterface.php
Normal file
9
src/Filter/FilterInterface.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Smarty\Filter;
|
||||||
|
|
||||||
|
interface FilterInterface {
|
||||||
|
|
||||||
|
public function filter($code, \Smarty\Template $template);
|
||||||
|
|
||||||
|
}
|
92
src/Filter/Output/TrimWhitespace.php
Normal file
92
src/Filter/Output/TrimWhitespace.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Smarty\Filter\Output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty trimwhitespace outputfilter plugin
|
||||||
|
* Trim unnecessary whitespace from HTML markup.
|
||||||
|
*
|
||||||
|
* @author Rodney Rehm
|
||||||
|
*
|
||||||
|
* @param string $source input string
|
||||||
|
*
|
||||||
|
* @return string filtered output
|
||||||
|
* @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
|
||||||
|
*/
|
||||||
|
class TrimWhitespace implements \Smarty\Filter\FilterInterface {
|
||||||
|
|
||||||
|
public function filter($code, \Smarty\Template $template) {
|
||||||
|
|
||||||
|
$source = $code;
|
||||||
|
|
||||||
|
$store = array();
|
||||||
|
$_store = 0;
|
||||||
|
$_offset = 0;
|
||||||
|
// Unify Line-Breaks to \n
|
||||||
|
$source = preg_replace('/\015\012|\015|\012/', "\n", $source);
|
||||||
|
// capture Internet Explorer and KnockoutJS Conditional Comments
|
||||||
|
if (preg_match_all(
|
||||||
|
'#<!--((\[[^\]]+\]>.*?<!\[[^\]]+\])|(\s*/?ko\s+.+))-->#is',
|
||||||
|
$source,
|
||||||
|
$matches,
|
||||||
|
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$store[] = $match[ 0 ][ 0 ];
|
||||||
|
$_length = strlen($match[ 0 ][ 0 ]);
|
||||||
|
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
||||||
|
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
||||||
|
$_offset += $_length - strlen($replace);
|
||||||
|
$_store++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Strip all HTML-Comments
|
||||||
|
// yes, even the ones in <script> - see https://stackoverflow.com/a/808850/515124
|
||||||
|
$source = preg_replace('#<!--.*?-->#ms', '', $source);
|
||||||
|
// capture html elements not to be messed with
|
||||||
|
$_offset = 0;
|
||||||
|
if (preg_match_all(
|
||||||
|
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
|
||||||
|
$source,
|
||||||
|
$matches,
|
||||||
|
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$store[] = $match[ 0 ][ 0 ];
|
||||||
|
$_length = strlen($match[ 0 ][ 0 ]);
|
||||||
|
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
||||||
|
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
||||||
|
$_offset += $_length - strlen($replace);
|
||||||
|
$_store++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$expressions = array(// replace multiple spaces between tags by a single space
|
||||||
|
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
|
||||||
|
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
|
||||||
|
// remove spaces between attributes (but not in attribute values!)
|
||||||
|
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
||||||
|
// note: for some very weird reason trim() seems to remove spaces inside attributes.
|
||||||
|
// maybe a \0 byte or something is interfering?
|
||||||
|
'#^\s+<#Ss' => '<',
|
||||||
|
'#>\s+$#Ss' => '>',
|
||||||
|
);
|
||||||
|
$source = preg_replace(array_keys($expressions), array_values($expressions), $source);
|
||||||
|
// note: for some very weird reason trim() seems to remove spaces inside attributes.
|
||||||
|
// maybe a \0 byte or something is interfering?
|
||||||
|
// $source = trim( $source );
|
||||||
|
$_offset = 0;
|
||||||
|
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$_length = strlen($match[ 0 ][ 0 ]);
|
||||||
|
$replace = $store[ $match[ 1 ][ 0 ] ];
|
||||||
|
$source = substr_replace($source, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
|
||||||
|
$_offset += strlen($replace) - $_length;
|
||||||
|
$_store++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $source;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -187,3 +187,67 @@ function smarty_function_escape_special_chars($string)
|
|||||||
}
|
}
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty wordwrap supporting multibyte
|
||||||
|
* Name: smarty_mb_wordwrap
|
||||||
|
* Purpose: Wrap a string to a given number of characters
|
||||||
|
*
|
||||||
|
* @link https://php.net/manual/en/function.wordwrap.php for similarity
|
||||||
|
*
|
||||||
|
* @param string $str the string to wrap
|
||||||
|
* @param int $width the width of the output
|
||||||
|
* @param string $break the character used to break the line
|
||||||
|
* @param boolean $cut ignored parameter, just for the sake of
|
||||||
|
*
|
||||||
|
* @return string wrapped string
|
||||||
|
* @author Rodney Rehm
|
||||||
|
*/
|
||||||
|
function smarty_mb_wordwrap($str, $width = 75, $break = "\n", $cut = false)
|
||||||
|
{
|
||||||
|
// break words into tokens using white space as a delimiter
|
||||||
|
$tokens = preg_split('!(\s)!S' . \Smarty\Smarty::$_UTF8_MODIFIER, $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
|
||||||
|
$length = 0;
|
||||||
|
$t = '';
|
||||||
|
$_previous = false;
|
||||||
|
$_space = false;
|
||||||
|
foreach ($tokens as $_token) {
|
||||||
|
$token_length = mb_strlen($_token, \Smarty\Smarty::$_CHARSET);
|
||||||
|
$_tokens = array($_token);
|
||||||
|
if ($token_length > $width) {
|
||||||
|
if ($cut) {
|
||||||
|
$_tokens = preg_split(
|
||||||
|
'!(.{' . $width . '})!S' . \Smarty\Smarty::$_UTF8_MODIFIER,
|
||||||
|
$_token,
|
||||||
|
-1,
|
||||||
|
PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($_tokens as $token) {
|
||||||
|
$_space = !!preg_match('!^\s$!S' . \Smarty\Smarty::$_UTF8_MODIFIER, $token);
|
||||||
|
$token_length = mb_strlen($token, \Smarty\Smarty::$_CHARSET);
|
||||||
|
$length += $token_length;
|
||||||
|
if ($length > $width) {
|
||||||
|
// remove space before inserted break
|
||||||
|
if ($_previous) {
|
||||||
|
$t = mb_substr($t, 0, -1, \Smarty\Smarty::$_CHARSET);
|
||||||
|
}
|
||||||
|
if (!$_space) {
|
||||||
|
// add the break before the token
|
||||||
|
if (!empty($t)) {
|
||||||
|
$t .= $break;
|
||||||
|
}
|
||||||
|
$length = $token_length;
|
||||||
|
}
|
||||||
|
} elseif ($token === "\n") {
|
||||||
|
// hard break must reset counters
|
||||||
|
$length = 0;
|
||||||
|
}
|
||||||
|
$_previous = $_space;
|
||||||
|
// add the token
|
||||||
|
$t .= $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $t;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user