Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.43% covered (success)
91.43%
32 / 35
85.71% covered (warning)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
utils
91.43% covered (success)
91.43%
32 / 35
85.71% covered (warning)
85.71%
6 / 7
19.23
0.00% covered (danger)
0.00%
0 / 1
 clean_formatting
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 format_attribute_value
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 generate_quote
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
7
 get_outermost_quote_authors
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 remove_bbcode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 unparse
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_empty
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\textformatter\s9e;
15
16/**
17* Text manipulation utilities
18*
19* In this implementation, "plain text" refers to regular text as it would be inputted by a user.
20* "Parsed text" is XML suitable to be reinserted into the database.
21*/
22class utils implements \phpbb\textformatter\utils_interface
23{
24    /**
25    * Replace BBCodes and other formatting elements with whitespace
26    *
27    * NOTE: preserves smilies as text
28    *
29    * @param  string $text Parsed text
30    * @return string      Plain text
31    */
32    public function clean_formatting($text)
33    {
34        // Insert a space before <s> and <e> then remove formatting
35        $text = preg_replace('#<[es]>#', ' $0', $text);
36
37        return \s9e\TextFormatter\Utils::removeFormatting($text);
38    }
39
40    /**
41    * Format given string to be used as an attribute value
42    *
43    * Will return the string as-is if it can be used in a BBCode without quotes. Otherwise,
44    * it will use either single- or double- quotes depending on whichever requires less escaping.
45    * Quotes and backslashes are escaped with backslashes where necessary
46    *
47    * @param  string $str Original string
48    * @return string      Same string if possible, escaped string within quotes otherwise
49    */
50    protected function format_attribute_value($str)
51    {
52        if (!preg_match('/[ "\'\\\\\\]]/', $str))
53        {
54            // Return as-is if it contains none of: space, ' " \ or ]
55            return $str;
56        }
57        $singleQuoted = "'" . addcslashes($str, "\\'") . "'";
58        $doubleQuoted = '"' . addcslashes($str, '\\"') . '"';
59
60        return (strlen($singleQuoted) < strlen($doubleQuoted)) ? $singleQuoted : $doubleQuoted;
61    }
62
63    /**
64    * {@inheritdoc}
65    */
66    public function generate_quote($text, array $attributes = array())
67    {
68        $text = trim($text);
69        $quote = '[quote';
70        if (isset($attributes['author']))
71        {
72            // Add the author as the BBCode's default attribute
73            $quote .= '=' . $this->format_attribute_value($attributes['author']);
74            unset($attributes['author']);
75        }
76
77        if (isset($attributes['user_id']) && $attributes['user_id'] == ANONYMOUS)
78        {
79            unset($attributes['user_id']);
80        }
81
82        ksort($attributes);
83        foreach ($attributes as $name => $value)
84        {
85            $quote .= ' ' . $name . '=' . $this->format_attribute_value($value);
86        }
87        $quote .= ']';
88        $newline = (strlen($quote . $text . '[/quote]') > 80 || strpos($text, "\n") !== false) ? "\n" : '';
89        $quote .= $newline . $text . $newline . '[/quote]';
90
91        return $quote;
92    }
93
94    /**
95    * Get a list of quote authors, limited to the outermost quotes
96    *
97    * @param  string   $text Parsed text
98    * @return string[]      List of authors
99    */
100    public function get_outermost_quote_authors($text)
101    {
102        $authors = array();
103        if (strpos($text, '<QUOTE ') === false)
104        {
105            return $authors;
106        }
107
108        $dom = new \DOMDocument;
109        $dom->loadXML($text);
110        $xpath = new \DOMXPath($dom);
111        foreach ($xpath->query('//QUOTE[not(ancestor::QUOTE)]/@author') as $author)
112        {
113            $authors[] = $author->textContent;
114        }
115
116        return $authors;
117    }
118
119    /**
120    * Remove given BBCode and its content, at given nesting depth
121    *
122    * @param  string  $text         Parsed text
123    * @param  string  $bbcode_name BBCode's name
124    * @param  integer $depth       Minimum nesting depth (number of parents of the same name)
125    * @return string               Parsed text
126    */
127    public function remove_bbcode($text, $bbcode_name, $depth = 0)
128    {
129        return \s9e\TextFormatter\Utils::removeTag($text, strtoupper($bbcode_name), $depth);
130    }
131
132    /**
133    * Return a parsed text to its original form
134    *
135    * @param  string $text Parsed text
136    * @return string      Original plain text
137    */
138    public function unparse($text)
139    {
140        return \s9e\TextFormatter\Unparser::unparse($text);
141    }
142
143    /**
144     * {@inheritdoc}
145     */
146    public function is_empty($text)
147    {
148        if ($text === null || $text === '')
149        {
150            return true;
151        }
152
153        return trim($this->unparse($text)) === '';
154    }
155}