• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

timber / timber / 5690057835

pending completion
5690057835

push

github

nlemoine
Merge branch '2.x' of github.com:timber/timber into 2.x-refactor-file-models

# Conflicts:
#	src/Attachment.php
#	src/ExternalImage.php
#	src/FileSize.php
#	src/URLHelper.php

1134 of 1134 new or added lines in 55 files covered. (100.0%)

3923 of 4430 relevant lines covered (88.56%)

59.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.48
/src/TextHelper.php
1
<?php
2

3
namespace Timber;
4

5
/**
6
 * Class TextHelper
7
 *
8
 * Class provides different text-related functions commonly used in WordPress development
9
 *
10
 * @api
11
 */
12
class TextHelper
13
{
14
    /**
15
     * Trims text to a certain number of characters.
16
     * This function can be useful for excerpt of the post
17
     * As opposed to wp_trim_words trims characters that makes text to
18
     * take the same amount of space in each post for example
19
     *
20
     * @api
21
     * @since   1.2.0
22
     * @author  @CROSP
23
     *
24
     * @param   string $text      Text to trim.
25
     * @param   int    $num_chars Number of characters. Default is 60.
26
     * @param   string $more      What to append if $text needs to be trimmed. Defaults to '&hellip;'.
27
     * @return  string trimmed text.
28
     */
29
    public static function trim_characters($text, $num_chars = 60, $more = '&hellip;')
30
    {
31
        $text = \wp_strip_all_tags($text);
9✔
32
        $text = \mb_strimwidth($text, 0, $num_chars, $more);
9✔
33
        return $text;
9✔
34
    }
35

36
    /**
37
     * @api
38
     * @param string  $text
39
     * @param int     $num_words
40
     * @param string|null|false  $more text to appear in "Read more...". Null to use default, false to hide
41
     * @param string  $allowed_tags
42
     * @return string
43
     */
44
    public static function trim_words($text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br blockquote')
45
    {
46
        if (null === $more) {
32✔
47
            $more = \__('&hellip;');
3✔
48
        }
49
        $original_text = $text;
32✔
50

51
        /**
52
         * Filters allowed tags for `trim_words()` helper.
53
         *
54
         * The `trim_words()` helper strips all HTML tags from a text it trims, except for a list of
55
         * allowed tags. Instead of passing the allowed tags every time you use `trim_words()` (or `{{ text|truncate }}`
56
         * in Twig), you can use this filter to set the allowed tags.
57
         *
58
         * @see \Timber\TextHelper::trim_words()
59
         * @since 0.21.9
60
         *
61
         * @param string $allowed_tags Allowed tags, separated by one whitespace.
62
         *                             Default `p a span b i br blockquote`.
63
         */
64
        $allowed_tags_array = \explode(' ', \apply_filters('timber/trim_words/allowed_tags', $allowed_tags));
32✔
65
        $allowed_tags_array = \array_filter($allowed_tags_array, function ($value) {
32✔
66
            return $value !== '';
32✔
67
        });
32✔
68
        $allowed_tag_string = '<' . \implode('><', $allowed_tags_array) . '>';
32✔
69

70
        $text = \strip_tags($text, $allowed_tag_string);
32✔
71
        /*
72
        * translators: If your word count is based on single characters (e.g. East Asian characters),
73
        * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
74
        * Do not translate into your own language.
75
        */
76
        if ('characters' == \_x('words', 'Word count type. Do not translate!') && \preg_match('/^utf\-?8$/i', \get_option('blog_charset'))) {
32✔
77
            $text = \trim(\preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
×
78
            \preg_match_all('/./u', $text, $words_array);
×
79
            $words_array = \array_slice($words_array[0], 0, $num_words + 1);
×
80
            $sep = '';
×
81
        } else {
82
            $words_array = \preg_split("/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY);
32✔
83
            $sep = ' ';
32✔
84
        }
85
        if (\count($words_array) > $num_words) {
32✔
86
            \array_pop($words_array);
17✔
87
            $text = \implode($sep, $words_array);
17✔
88
            $text = $text . $more;
17✔
89
        } else {
90
            $text = \implode($sep, $words_array);
15✔
91
        }
92
        $text = self::close_tags($text);
32✔
93
        return \apply_filters('wp_trim_words', $text, $num_words, $more, $original_text);
32✔
94
    }
95

96
    /**
97
     * @api
98
     *
99
     * @param       $string
100
     * @param array $tags
101
     *
102
     * @return null|string|string[]
103
     */
104
    public static function remove_tags($string, $tags = [])
105
    {
106
        return \preg_replace('#<(' . \implode('|', $tags) . ')(?:[^>]+)?>.*?</\1>#s', '', $string);
16✔
107
    }
108

109
    /**
110
     *
111
     *
112
     * @param string  $html
113
     * @return string
114
     */
115
    public static function close_tags($html)
116
    {
117
        //put all opened tags into an array
118
        \preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
34✔
119
        $openedtags = $result[1];
34✔
120
        //put all closed tags into an array
121
        \preg_match_all('#</([a-z]+)>#iU', $html, $result);
34✔
122
        $closedtags = $result[1];
34✔
123
        $len_opened = \count($openedtags);
34✔
124
        // all tags are closed
125
        if (\count($closedtags) == $len_opened) {
34✔
126
            return $html;
24✔
127
        }
128
        $openedtags = \array_reverse($openedtags);
10✔
129
        // close tags
130
        for ($i = 0; $i < $len_opened; $i++) {
10✔
131
            if (!\in_array($openedtags[$i], $closedtags)) {
10✔
132
                $html .= '</' . $openedtags[$i] . '>';
10✔
133
            } else {
134
                unset($closedtags[\array_search($openedtags[$i], $closedtags)]);
2✔
135
            }
136
        }
137
        $html = \str_replace(['</br>', '</hr>', '</wbr>'], '', $html);
10✔
138
        $html = \str_replace(['<br>', '<hr>', '<wbr>'], ['<br />', '<hr />', '<wbr />'], $html);
10✔
139
        return $html;
10✔
140
    }
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc