function
pagecom_string_truncate(
$text
,
$allowed_symbols_in_str
= 100,
$considerhtml
= true,
$exact
= false,
$Output_Ending
=
''
,
$str_amount_required
= 3 )
{
$looking_for
= [
'<br>'
,
'<br />'
,
'<br/>'
];
$looking_for2
= [
'<a href='
];
$looking_for3
= [
'<p>'
];
$looking_for4
= [
'<h1>'
,
'<h2>'
,
'<h3>'
,
'</h1>'
,
'</h2>'
,
'</h3>'
];
$str_amount_required
< 1 ?
$str_amount_required
= 1 :
$str_amount_required
;
$No_BR
= 0;
$total_symbols_amount
=
$str_amount_required
*
$allowed_symbols_in_str
;
$Output
=
''
;
$No_Output_Ending
= false;
$Required_output_ending
= false;
$str_amount_ready
= 0;
$str_symbols_ready
= 0;
$link_replaced
= false;
$visible_length
= mb_strlen(preg_replace(
'/<.*?>/'
,
''
,
$text
));
$Output_Ending_size
=
strlen
(
$Output_Ending
) + 1;
$truncate
=
''
;
$truncate_required
= false;
$add_one_BR
= false;
$truncated_by_space
= false;
$plain_mode
= false;
$open_tags
= [];
$total_length
= 0;
$plain_tag
= false;
$long_str_found
= false;
$text
=
str_replace
(
$looking_for4
,
''
,
$text
);
for
(
$index
=
count
(
$looking_for
) - 1;
$index
>= 0; --
$index
)
{
$No_BR
+= substr_count (
$text
,
$looking_for
[
$index
] );
}
if
(
empty
(
$text
)) {
$truncate
.=
$Output_Ending
;
$truncate
.=
"<br><br>"
;
goto
Inject_New_Lines;
}
if
(!
$considerhtml
)
{
if
(mb_strlen(
$text
) <=
$total_symbols_amount
)
{
$truncate
=
$text
;
goto
Inject_New_Lines;
}
else
$truncate
= mb_substr(
$text
, 0,
$total_symbols_amount
);
}
else
{
$temp
= mb_strlen(preg_replace(
'/<.*?>/'
,
''
,
$text
));
if
( !preg_match(
'/<\s*(pre|plaintext)/'
,
$text
) &&
$temp
<=
$total_symbols_amount
)
{
if
(
$No_BR
> 0 )
{
}
else
{
if
(
$visible_length
<
$allowed_symbols_in_str
)
{
$offset
= 0;
$offset1
=
''
;
$offset1
=
strpos
(
$text
,
$looking_for3
[0],
$offset
);
if
(
$offset1
==
''
)
{
$truncate
=
$text
;
goto
Inject_New_Lines;
}
}
}
}
preg_match_all(
'/(<.+?>)?([^<>]*)/s'
,
$text
,
$lines
, PREG_SET_ORDER);
foreach
(
$lines
as
$line_matchings
) {
if
(!
empty
(
$line_matchings
[1])) {
if
(
preg_match(
'/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is'
,
$line_matchings
[1]
)
) {
$str_symbols_ready
= 0;
}
elseif
(preg_match(
'/^<\s*\/([^\s]+?)\s*>$/s'
,
$line_matchings
[1],
$tag_matchings
)) {
$tag
= false;
if
(
strtolower
(
$tag_matchings
[1]) ==
$plain_mode
) {
$plain_mode
= false;
}
else
{
$pos
=
array_search
(
$tag_matchings
[1],
$open_tags
);
if
(
$pos
!== false) {
unset(
$open_tags
[
$pos
]);
}
}
}
elseif
(preg_match(
'/^<\s*([^\s>!]+).*?>$/s'
,
$line_matchings
[1],
$tag_matchings
)) {
$tag
=
strtolower
(
$tag_matchings
[1]);
$plain_tag
= in_array(
$tag
,
array
(
'pre'
,
'plaintext'
)) ?
$tag
: false;
if
(!
$plain_mode
&& !
$plain_tag
) {
array_unshift
(
$open_tags
, mb_strtolower(
$tag
));
}
}
if
(!
$plain_mode
)
{
if
(
$str_amount_ready
>
$str_amount_required
)
break
;
if
(
$line_matchings
[1] ==
'</li>'
)
{
if
(
$str_amount_ready
<
$str_amount_required
)
{
++
$str_amount_ready
;
$str_symbols_ready
= 0;
}
else
{
break
;
}
}
if
(
$line_matchings
[1] ==
'</p>'
)
{
if
(
$str_amount_ready
<
$str_amount_required
)
{
++
$str_amount_ready
;
$str_symbols_ready
= 0;
$long_str_found
== true ?
$long_str_found
= false :
$long_str_found
;
}
else
{
break
;
}
}
if
(
$line_matchings
[1] ==
'</li>'
&&
$str_amount_ready
>=
$str_amount_required
)
{
$No_Output_Ending
= true;
$truncate
.=
$Output_Ending
;
$truncate
.=
$line_matchings
[1];
break
;
}
if
(
$line_matchings
[1] ==
'<p>'
&&
$str_amount_ready
>=
$str_amount_required
)
{
break
;
}
else
{
$truncate
.=
$line_matchings
[1];
}
if
(
$line_matchings
[1] ==
'<p>'
&&
$str_symbols_ready
> 0 &&
$long_str_found
)
{
++
$str_amount_ready
;
$str_symbols_ready
= 0;
$long_str_found
= false;
}
if
(
$line_matchings
[1] ==
'</p>'
&&
$str_amount_ready
==
$str_amount_required
)
{
break
;
}
if
(
$line_matchings
[1] ==
'<br>'
||
$line_matchings
[1] ==
'<br />'
||
$line_matchings
[1] ==
'<br/>'
)
{
if
(
$str_amount_ready
>=
$str_amount_required
)
{
break
;
}
else
{
++
$str_amount_ready
;
$str_symbols_ready
= 0;
if
(
$str_amount_ready
>=
$str_amount_required
)
{
$No_Output_Ending
= true;
$truncate
.=
$Output_Ending
;
break
;
}
}
}
}
}
$left
=
$total_symbols_amount
-
$total_length
;
if
(
$plain_mode
|| (
$plain_tag
&&
$tag
)) {
$content
=
$plain_mode
?
$line_matchings
[0] :
$line_matchings
[2];
if
(mb_strlen(
$content
) <=
$left
) {
$truncate
.=
$content
;
$total_length
+= mb_strlen(
$content
);
}
else
{
$truncate
.= mb_substr(
$content
, 0,
$left
);
$total_length
+=
$left
;
}
if
(
$plain_tag
&& !
$plain_mode
) {
$plain_mode
=
$plain_tag
;
}
}
else
{
$content_length
= mb_strlen(preg_replace(
'/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};|[\r\n\s]{2,}/i'
,
' '
,
$line_matchings
[2]));
$offset1
=
strpos
(
$line_matchings
[1],
$looking_for2
[0], 0 );
if
(
$total_length
+
$content_length
>
$total_symbols_amount
&&
$offset1
==
''
) {
$entities_length
= 0;
$Big_str
= (int)(
$content_length
/
$allowed_symbols_in_str
);
$New_str_sym_amount
=
$content_length
-
$allowed_symbols_in_str
;
if
(
$New_str_sym_amount
< 0 )
{
$New_str_sym_amount
= 0;
}
$str_amount_ready
+=
$Big_str
;
if
(
$str_amount_ready
>=
$str_amount_required
)
{
$offset1
=
strpos
(
$line_matchings
[1],
$looking_for2
[0], 0 );
if
(
$offset1
!=
''
)
{
$truncate
.=
'...'
;
}
else
{
$truncate_required
= true;
if
(
$left
<
$allowed_symbols_in_str
)
{
$truncate
.= mb_substr(
$line_matchings
[2], 0,
$left
);
}
if
(
$New_str_sym_amount
<
$allowed_symbols_in_str
)
{
$truncate
.= mb_substr(
$line_matchings
[2], 0,
$allowed_symbols_in_str
);
$Required_output_ending
= true;
}
if
(
$New_str_sym_amount
>
$allowed_symbols_in_str
&&
$left
>
$allowed_symbols_in_str
)
{
$truncate
.= mb_substr(
$line_matchings
[2], 0,
$left
-
$Output_Ending_size
* 3 );
}
}
$offset1
=
strpos
(
$truncate
,
$looking_for3
[0], 0 );
if
(
$offset1
==
''
)
{
$add_one_BR
= true;
}
else
{
$add_one_BR
= false;
}
}
if
(
preg_match_all(
'/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};|[\r\n\s]{2,}/i'
,
$line_matchings
[2],
$entities
,
PREG_OFFSET_CAPTURE
)
) {
foreach
(
$entities
[0]
as
$entity
) {
if
(
$entity
[1]+1-
$entities_length
<=
$left
) {
$left
--;
$entities_length
+= mb_strlen(
$entity
[0]);
}
else
{
break
;
}
}
}
$truncated_by_space
= preg_match(
'/[\r\n\s]/'
, mb_substr(
$line_matchings
[2],
$left
+
$entities_length
, 1));
break
;
}
else
{
$offset1
=
strpos
(
$line_matchings
[1],
$looking_for2
[0], 0 );
if
(
$offset1
!=
''
)
{
$truncate
.=
'...'
;
$No_Output_Ending
= true;
$total_length
+=
$content_length
;
$link_replaced
= true;
}
else
{
$truncate
.=
$line_matchings
[2];
$total_length
+=
$content_length
;
}
if
(
$link_replaced
)
{
$link_replaced
= false;
$str_symbols_ready
+= 3;
}
else
{
$str_symbols_ready
+=
$content_length
;
}
if
(
$str_symbols_ready
>=
$allowed_symbols_in_str
&&
$str_amount_ready
<
$str_amount_required
)
{
$long_str_found
= true;
do
{
++
$str_amount_ready
;
if
(
$str_amount_ready
>
$str_amount_required
)
break
;
if
(
$str_amount_ready
==
$str_amount_required
&&
$str_symbols_ready
>
$allowed_symbols_in_str
)
{
$truncate
= mb_substr(
$truncate
, 0, -(
$str_symbols_ready
-
$allowed_symbols_in_str
+
$Output_Ending_size
) );
break
;
}
$str_symbols_ready
=
$str_symbols_ready
-
$allowed_symbols_in_str
;
}
while
(
$str_symbols_ready
>=
$allowed_symbols_in_str
);
}
}
}
if
(
$total_length
>=
$total_symbols_amount
||
$str_symbols_ready
>=
$allowed_symbols_in_str
) {
break
;
}
}
if
( ((
$total_length
+
$Output_Ending_size
) <
$total_symbols_amount
) && ((
$content_length
+
$Output_Ending_size
) <
$total_symbols_amount
) &&
(
$str_symbols_ready
+
$Output_Ending_size
) <
$allowed_symbols_in_str
)
{
$No_Output_Ending
= true;
}
if
(
$Required_output_ending
)
{
$No_Output_Ending
= false;
}
}
if
(
$truncate_required
|| ( !
$exact
&& !
$truncated_by_space
&& !
$plain_mode
&& ( (
$str_symbols_ready
>=
$allowed_symbols_in_str
) || (
$content_length
>=
$total_symbols_amount
)) )
) {
if
(mb_strrpos(
$truncate
,
' '
) > 0) {
$pos1
= mb_strrpos(
$truncate
,
' '
);
$pos2
= mb_strrpos(
$truncate
,
'>'
);
$spos
= (
$pos2
<
$pos1
) ?
$pos1
: (
$pos2
+1);
if
(isset(
$spos
)) {
$truncate
= mb_substr(
$truncate
, 0,
$spos
);
}
}
}
if
( !
$No_Output_Ending
)
{
$truncate
.=
$Output_Ending
;
}
if
(
$considerhtml
) {
if
(
$plain_mode
) {
$truncate
.=
'</'
.
$plain_mode
.
'>'
;
}
foreach
(
$open_tags
as
$tag
) {
$truncate
.=
'</'
.
$tag
.
'>'
;
if
(
$tag
==
'p'
)
++
$str_amount_ready
;
}
}
Inject_New_Lines:
if
(
$add_one_BR
)
{
$truncate
.=
"<br>"
;
}
for
(
$count
=
$str_amount_ready
;
$count
<
$str_amount_required
; ++
$count
)
{
$truncate
.=
"<br>"
;
}
return
$truncate
;
}