Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
Highlight
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
56
0.00% covered (danger)
0.00%
0 / 1
 __invoke
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3/**
4 * Highlight view helper
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2010.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  View_Helpers
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org/wiki/development Wiki
28 */
29
30namespace VuFind\View\Helper\Root;
31
32use Laminas\View\Helper\AbstractHelper;
33
34use function is_array;
35
36/**
37 * Highlight view helper
38 *
39 * @category VuFind
40 * @package  View_Helpers
41 * @author   Demian Katz <demian.katz@villanova.edu>
42 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
43 * @link     https://vufind.org/wiki/development Wiki
44 */
45class Highlight extends AbstractHelper
46{
47    /**
48     * Start tag for highlighting
49     *
50     * @var string
51     */
52    protected $startTag = '<span class="highlight">';
53
54    /**
55     * End tag for highlighting
56     *
57     * @var string
58     */
59    protected $endTag = '</span>';
60
61    /**
62     * Adds a span tag with class "highlight" around a specific phrase for
63     * highlighting
64     *
65     * @param string $haystack String to highlight
66     * @param mixed  $needle   Array of words to highlight (null for none)
67     * @param bool   $clear    Should we dehighlight (true) rather than highlight
68     * (false)?
69     * @param bool   $escape   Should we HTML encode the results?
70     *
71     * @return string          Highlighted, HTML encoded string
72     */
73    public function __invoke(
74        $haystack,
75        $needle = null,
76        $clear = false,
77        $escape = true
78    ) {
79        // Normalize value to an array so we can loop through it; this saves us from
80        // writing the highlighting code twice, once for arrays, once for non-arrays.
81        // Also make sure our generated array is empty if needle itself is empty --
82        // if $haystack already has highlighting markers in it, we may want to send
83        // in a blank needle.
84        if (!is_array($needle)) {
85            $needle = empty($needle) ? [] : [$needle];
86        }
87
88        // Highlight search terms one phrase at a time; we just put in placeholders
89        // for the start and end span tags at this point so we can do proper URL
90        // encoding later.
91        foreach ($needle as $phrase) {
92            $phrase = trim(str_replace(['"', '*', '?'], '', $phrase));
93            if ($phrase != '') {
94                $phrase = preg_quote($phrase, '/');
95                $haystack = preg_replace(
96                    "/($phrase)/iu",
97                    '{{{{START_HILITE}}}}$1{{{{END_HILITE}}}}',
98                    $haystack
99                );
100            }
101        }
102
103        // URL encode the string, then put in the highlight spans:
104        $haystack = str_replace(
105            ['{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'],
106            $clear ? '' : [$this->startTag, $this->endTag],
107            $escape ? htmlspecialchars($haystack) : $haystack
108        );
109
110        return $haystack;
111    }
112}