-
Notifications
You must be signed in to change notification settings - Fork 345
/
ViewHelper.php
154 lines (130 loc) · 5.54 KB
/
ViewHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php
namespace helpers;
/**
* Helper class for loading extern items
*
* @copyright Copyright (c) Tobias Zeising (http://www.aditu.de)
* @license GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html)
* @author Tobias Zeising <[email protected]>
*/
class ViewHelper {
/** @var Configuration configuration */
private $configuration;
public function __construct(Configuration $configuration) {
$this->configuration = $configuration;
}
/**
* Enclose all searchWords with <span class="found">$word</span>
* for later highlighing with CSS
*
* @param string $content which contains words
* @param string $searchWords words for highlighting
*
* @return string with highlited words
*/
public static function highlight($content, $searchWords) {
if (strlen(trim($searchWords)) === 0) {
return $content;
}
if (preg_match('#^/(?P<regex>.+)/$#', $searchWords, $matches)) {
return preg_replace('/(?!<[^<>])(' . $matches[1] . ')(?![^<>]*>)/', '<span class="found">$0</span>', $content);
}
$searchWords = \helpers\Search::splitTerms($searchWords);
foreach ($searchWords as $word) {
$content = preg_replace('/(?!<[^<>])(' . preg_quote($word, '/') . ')(?![^<>]*>)/i', '<span class="found">$0</span>', $content);
}
return $content;
}
/**
* removes img src attribute and saves the value in data attribute for
* loading it later
*
* @param string $content which contains img tags
*
* @return string with replaced img tags
*/
public static function lazyimg($content) {
return preg_replace_callback("/<img(?P<pre>[^<]+)src=(?:['\"])(?P<src>[^\"']*)(?:['\"])(?P<post>[^<]*)>/i", function(array $matches) {
$width = null;
$height = null;
$attrs = "{$matches['pre']} {$matches['post']}";
if (preg_match('/\bwidth=([\'"]?)(?P<width>[0-9]+)\1/i', $attrs, $widthAttr)) {
$width = (int) $widthAttr['width'];
}
if (preg_match('/\bheight=([\'"]?)(?P<height>[0-9]+)\1/i', $attrs, $heightAttr)) {
$height = (int) $heightAttr['height'];
}
if ($width === null && $height === null) {
// no dimensions provided, assume a 4:3 photo
$width = 800;
$height = 600;
} else {
// assume a 4:3 photo
$width = $width === null ? $height * 4 / 3 : $width;
$height = $height === null ? $width * 3 / 4 : $height;
}
$placeholder = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='$width' height='$height'><rect fill='%2395c9c5' width='100%' height='100%'/></svg>";
return "<img src=\"$placeholder\"{$matches['pre']}data-selfoss-src=\"{$matches['src']}\"{$matches['post']}>";
}, $content);
}
/**
* Return ISO8601 formatted date
*
* @param string $datestr sql date
*
* @return string
*/
public static function date_iso8601($datestr) {
$date = new \DateTime($datestr);
return $date->format(\DateTime::ATOM);
}
/**
* Proxify imgs through atmos/camo when not https
*
* @param string $content item content
*
* @return string item content
*/
public function camoflauge($content) {
if (empty($content)) {
return $content;
}
$camo = new \WillWashburn\Phpamo\Phpamo($this->configuration->camoKey, $this->configuration->camoDomain);
return preg_replace_callback("/<img([^<]+)src=(['\"])([^\"']*)(['\"])([^<]*)>/i", function(array $matches) use ($camo) {
return '<img' . $matches[1] . 'src=' . $matches[2] . $camo->camoHttpOnly($matches[3]) . $matches[4] . $matches[5] . '>';
}, $content);
}
/**
* Prepare entry as expected by the client.
*
* @param array $item item to modify
* @param \controllers\Tags $tagsController tags controller
* @param ?array $tags list of tags
* @param ?string $search search query
*
* @return array modified item
*/
public function preprocessEntry(array $item, \controllers\Tags $tagsController, array $tags = null, $search = null) {
// parse tags and assign tag colors
$item['tags'] = $tagsController->tagsAddColors($item['tags'], $tags);
$item['content'] = str_replace('"', '"', $item['content']);
// highlight search results
if (isset($search)) {
$item['sourcetitle'] = ViewHelper::highlight($item['sourcetitle'], $search);
$item['title'] = ViewHelper::highlight($item['title'], $search);
$item['content'] = ViewHelper::highlight($item['content'], $search);
}
if ($this->configuration->camoKey != '') {
$item['content'] = $this->camoflauge($item['content']);
}
$item['title'] = ViewHelper::lazyimg($item['title']);
$item['strippedTitle'] = htmLawed(htmlspecialchars_decode($item['title']), ['deny_attribute' => '*', 'elements' => '-*']);
$item['content'] = ViewHelper::lazyimg($item['content']);
$contentWithoutTags = strip_tags($item['content']);
$item['wordCount'] = str_word_count($contentWithoutTags);
$item['datetime'] = $item['datetime']->format(\DateTime::ATOM);
$item['updatetime'] = $item['updatetime']->format(\DateTime::ATOM);
$item['lengthWithoutTags'] = strlen($contentWithoutTags);
return $item;
}
}