diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-10-13 12:07:13 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-10-13 12:07:13 +0200 |
commit | d9f6275ebca035fec8331652c677981056793ccc (patch) | |
tree | 37a64baf4f0eba6b781040605965383d8aded2cc /application/LinkUtils.php | |
parent | 38672ba0d1c722e5d6d33a58255ceb55e9410e46 (diff) | |
parent | d63ff87a009313141ae684ec447b902562ff6ee7 (diff) | |
download | Shaarli-stable.tar.gz Shaarli-stable.tar.zst Shaarli-stable.zip |
Merge branch 'v0.11' into stablestable
Diffstat (limited to 'application/LinkUtils.php')
-rw-r--r-- | application/LinkUtils.php | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/application/LinkUtils.php b/application/LinkUtils.php deleted file mode 100644 index d56e019f..00000000 --- a/application/LinkUtils.php +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Get cURL callback function for CURLOPT_WRITEFUNCTION | ||
5 | * | ||
6 | * @param string $charset to extract from the downloaded page (reference) | ||
7 | * @param string $title to extract from the downloaded page (reference) | ||
8 | * @param string $curlGetInfo Optionnaly overrides curl_getinfo function | ||
9 | * | ||
10 | * @return Closure | ||
11 | */ | ||
12 | function get_curl_download_callback(&$charset, &$title, $curlGetInfo = 'curl_getinfo') | ||
13 | { | ||
14 | $isRedirected = false; | ||
15 | /** | ||
16 | * cURL callback function for CURLOPT_WRITEFUNCTION (called during the download). | ||
17 | * | ||
18 | * While downloading the remote page, we check that the HTTP code is 200 and content type is 'html/text' | ||
19 | * Then we extract the title and the charset and stop the download when it's done. | ||
20 | * | ||
21 | * @param resource $ch cURL resource | ||
22 | * @param string $data chunk of data being downloaded | ||
23 | * | ||
24 | * @return int|bool length of $data or false if we need to stop the download | ||
25 | */ | ||
26 | return function (&$ch, $data) use ($curlGetInfo, &$charset, &$title, &$isRedirected) { | ||
27 | $responseCode = $curlGetInfo($ch, CURLINFO_RESPONSE_CODE); | ||
28 | if (!empty($responseCode) && in_array($responseCode, [301, 302])) { | ||
29 | $isRedirected = true; | ||
30 | return strlen($data); | ||
31 | } | ||
32 | if (!empty($responseCode) && $responseCode !== 200) { | ||
33 | return false; | ||
34 | } | ||
35 | // After a redirection, the content type will keep the previous request value | ||
36 | // until it finds the next content-type header. | ||
37 | if (! $isRedirected || strpos(strtolower($data), 'content-type') !== false) { | ||
38 | $contentType = $curlGetInfo($ch, CURLINFO_CONTENT_TYPE); | ||
39 | } | ||
40 | if (!empty($contentType) && strpos($contentType, 'text/html') === false) { | ||
41 | return false; | ||
42 | } | ||
43 | if (!empty($contentType) && empty($charset)) { | ||
44 | $charset = header_extract_charset($contentType); | ||
45 | } | ||
46 | if (empty($charset)) { | ||
47 | $charset = html_extract_charset($data); | ||
48 | } | ||
49 | if (empty($title)) { | ||
50 | $title = html_extract_title($data); | ||
51 | } | ||
52 | // We got everything we want, stop the download. | ||
53 | if (!empty($responseCode) && !empty($contentType) && !empty($charset) && !empty($title)) { | ||
54 | return false; | ||
55 | } | ||
56 | |||
57 | return strlen($data); | ||
58 | }; | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * Extract title from an HTML document. | ||
63 | * | ||
64 | * @param string $html HTML content where to look for a title. | ||
65 | * | ||
66 | * @return bool|string Extracted title if found, false otherwise. | ||
67 | */ | ||
68 | function html_extract_title($html) | ||
69 | { | ||
70 | if (preg_match('!<title.*?>(.*?)</title>!is', $html, $matches)) { | ||
71 | return trim(str_replace("\n", '', $matches[1])); | ||
72 | } | ||
73 | return false; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Extract charset from HTTP header if it's defined. | ||
78 | * | ||
79 | * @param string $header HTTP header Content-Type line. | ||
80 | * | ||
81 | * @return bool|string Charset string if found (lowercase), false otherwise. | ||
82 | */ | ||
83 | function header_extract_charset($header) | ||
84 | { | ||
85 | preg_match('/charset="?([^; ]+)/i', $header, $match); | ||
86 | if (! empty($match[1])) { | ||
87 | return strtolower(trim($match[1])); | ||
88 | } | ||
89 | |||
90 | return false; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * Extract charset HTML content (tag <meta charset>). | ||
95 | * | ||
96 | * @param string $html HTML content where to look for charset. | ||
97 | * | ||
98 | * @return bool|string Charset string if found, false otherwise. | ||
99 | */ | ||
100 | function html_extract_charset($html) | ||
101 | { | ||
102 | // Get encoding specified in HTML header. | ||
103 | preg_match('#<meta .*charset=["\']?([^";\'>/]+)["\']? */?>#Usi', $html, $enc); | ||
104 | if (!empty($enc[1])) { | ||
105 | return strtolower($enc[1]); | ||
106 | } | ||
107 | |||
108 | return false; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * Count private links in given linklist. | ||
113 | * | ||
114 | * @param array|Countable $links Linklist. | ||
115 | * | ||
116 | * @return int Number of private links. | ||
117 | */ | ||
118 | function count_private($links) | ||
119 | { | ||
120 | $cpt = 0; | ||
121 | foreach ($links as $link) { | ||
122 | if ($link['private']) { | ||
123 | $cpt += 1; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return $cpt; | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * In a string, converts URLs to clickable links. | ||
132 | * | ||
133 | * @param string $text input string. | ||
134 | * @param string $redirector if a redirector is set, use it to gerenate links. | ||
135 | * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not. | ||
136 | * | ||
137 | * @return string returns $text with all links converted to HTML links. | ||
138 | * | ||
139 | * @see Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722 | ||
140 | */ | ||
141 | function text2clickable($text, $redirector = '', $urlEncode = true) | ||
142 | { | ||
143 | $regex = '!(((?:https?|ftp|file)://|apt:|magnet:)\S+[a-z0-9\(\)]/?)!si'; | ||
144 | |||
145 | if (empty($redirector)) { | ||
146 | return preg_replace($regex, '<a href="$1">$1</a>', $text); | ||
147 | } | ||
148 | // Redirector is set, urlencode the final URL. | ||
149 | return preg_replace_callback( | ||
150 | $regex, | ||
151 | function ($matches) use ($redirector, $urlEncode) { | ||
152 | $url = $urlEncode ? urlencode($matches[1]) : $matches[1]; | ||
153 | return '<a href="' . $redirector . $url .'">'. $matches[1] .'</a>'; | ||
154 | }, | ||
155 | $text | ||
156 | ); | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * Auto-link hashtags. | ||
161 | * | ||
162 | * @param string $description Given description. | ||
163 | * @param string $indexUrl Root URL. | ||
164 | * | ||
165 | * @return string Description with auto-linked hashtags. | ||
166 | */ | ||
167 | function hashtag_autolink($description, $indexUrl = '') | ||
168 | { | ||
169 | /* | ||
170 | * To support unicode: http://stackoverflow.com/a/35498078/1484919 | ||
171 | * \p{Pc} - to match underscore | ||
172 | * \p{N} - numeric character in any script | ||
173 | * \p{L} - letter from any language | ||
174 | * \p{Mn} - any non marking space (accents, umlauts, etc) | ||
175 | */ | ||
176 | $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; | ||
177 | $replacement = '$1<a href="'. $indexUrl .'?addtag=$2" title="Hashtag $2">#$2</a>'; | ||
178 | return preg_replace($regex, $replacement, $description); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * This function inserts where relevant so that multiple spaces are properly displayed in HTML | ||
183 | * even in the absence of <pre> (This is used in description to keep text formatting). | ||
184 | * | ||
185 | * @param string $text input text. | ||
186 | * | ||
187 | * @return string formatted text. | ||
188 | */ | ||
189 | function space2nbsp($text) | ||
190 | { | ||
191 | return preg_replace('/(^| ) /m', '$1 ', $text); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * Format Shaarli's description | ||
196 | * | ||
197 | * @param string $description shaare's description. | ||
198 | * @param string $redirector if a redirector is set, use it to gerenate links. | ||
199 | * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not. | ||
200 | * @param string $indexUrl URL to Shaarli's index. | ||
201 | |||
202 | * @return string formatted description. | ||
203 | */ | ||
204 | function format_description($description, $redirector = '', $urlEncode = true, $indexUrl = '') | ||
205 | { | ||
206 | return nl2br(space2nbsp(hashtag_autolink(text2clickable($description, $redirector, $urlEncode), $indexUrl))); | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * Generate a small hash for a link. | ||
211 | * | ||
212 | * @param DateTime $date Link creation date. | ||
213 | * @param int $id Link ID. | ||
214 | * | ||
215 | * @return string the small hash generated from link data. | ||
216 | */ | ||
217 | function link_small_hash($date, $id) | ||
218 | { | ||
219 | return smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id); | ||
220 | } | ||