Issues (1686)

sources/ElkArte/BBC/Autolink.php (1 issue)

Severity
1
<?php
2
3
/**
4
 *
5
 * @package   ElkArte Forum
6
 * @copyright ElkArte Forum contributors
7
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
8
 *
9
 * This file contains code covered by:
10
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
11
 *
12
 * @version 2.0 dev
13
 *
14
 */
15
16
namespace BBC;
17
18
/**
19
 * Class Autolink
20
 *
21
 * Class to change url and email text to BBC link codes [url] [email]
22
 *
23
 * @package BBC
24
 */
25
class Autolink
26
{
27
	/** @var Codes */
28
	protected $bbc;
29
30
	/** @var bool */
31
	protected $url_enabled;
32
33
	/** @var bool */
34
	protected $email_enabled;
35
36
	/** @var bool */
37
	protected $possible_link;
38
39
	/** @var bool */
40
	protected $possible_email;
41
42
	/** @var array of search regex for urls */
43
	protected $search;
44
45
	/** @var array of bbc url coded links */
46
	protected $replace;
47
48
	/** @var array of search regex for email */
49
	protected $email_search;
50
51 4
	/** @var array of bbc email coded links */
52
	protected $email_replace;
53 4
54
	/**
55 4
	 * Autolink constructor.
56 4
	 */
57
	public function __construct(Codes $bbc)
58 4
	{
59 4
		$this->bbc = $bbc;
60
61
		$this->url_enabled = !$this->bbc->isDisabled('url');
62
		$this->email_enabled = !$this->bbc->isDisabled('email');
63
64 4
		$this->load();
65
	}
66
67 4
	/**
68
	 * Load the autolink regular expressions to be used in autoLink()
69
	 */
70
	protected function load()
71
	{
72
		$search_url = array(
73 4
			'~(?<=[\s>\.(;\'"]|^)((?:http|https)://[\w\-_%@:|]+(?:\.[\w\-_%]+)*(?::\d+)?(?:/[\p{L}\p{N}\-_\~%\.@!,\?&;=*#(){}+:\'\\\\]*)*[/\p{L}\p{N}\-_\~%@\?;=#}\\\\])~ui',
74
			'~(?<=[\s>(\'<]|^)(www(?:\.[\w\-_]+)+(?::\d+)?(?:/[\p{L}\p{N}\-_\~%\.@!,\?&;=#(){}+:\'\\\\]*)*[/\p{L}\p{N}\-_\~%@\?;=#}\\\\])~ui'
75
		);
76
		$replace_url = array(
77
			//'[url_auto=$1]$1[/url_auto]',
78 4
			//'[url_auto=$1]$1[/url_auto]',
79
			'[url]$1[/url]',
80
			'[url=https://$1]$1[/url]',
81
		);
82
83
		$search_email = array(
84 4
			'~(?<=[\?\s\x{A0}\[\]()*\\\;>]|^)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?,\s\x{A0}\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;|\.(?:\.|;|&nbsp;|\s|$|<br />))~u',
85
			'~(?<=<br />)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?\.,;\s\x{A0}\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;)~u',
86
		);
87
		$replace_email = array(
88
			//'[email_auto]$1[/email_auto]',
89 4
			//'[email_auto]$1[/email_auto]',
90
			'[email]$1[/email]',
91
			'[email]$1[/email]',
92 4
		);
93 4
94
		// Allow integration an option to add / remove linking code
95 4
		call_integration_hook('integrate_autolink_load', array(&$search_url, &$replace_url, &$search_email, &$replace_email, $this->bbc));
96
97
		// Load them to the class
98
		$this->search = $search_url;
99
		$this->replace = $replace_url;
100 4
101 4
		if (empty($search_url) || empty($replace_url))
102
		{
103 4
			$this->url_enabled = false;
104
		}
105
106
		$this->email_search = $search_email;
107 4
		$this->email_replace = $replace_email;
108
109
		if (empty($search_email) || empty($replace_email))
110
		{
111
			$this->email_enabled = false;
112
		}
113
	}
114
115
	/**
116 14
	 * Parse links and emails in the data
117
	 *
118 14
	 * @param string $data
119
	 *
120 4
	 * @return null|string|string[]
121
	 */
122
	public function parse($data)
123 14
	{
124
		if ($this->hasLinks($data))
125
		{
126
			$data = $this->parseLinks($data);
127
		}
128 14
129
		if ($this->hasEmails($data))
130 14
		{
131
			$data = $this->parseEmails($data);
132
		}
133
134
		call_integration_hook('integrate_autolink_area', array(&$data, $this->bbc));
135
136
		return $data;
137
	}
138
139
	/**
140 14
	 * Checks if the string has links of any form, http:// www.xxx
141
	 *
142 14
	 * @param string $data
143
	 *
144
	 * @return bool
145
	 */
146
	public function hasLinks($data)
147
	{
148
		return $this->hasPossibleLink() && (strpos($data, '://') !== false || strpos($data, 'www.') !== false);
149
	}
150 28
151
	/**
152 28
	 * Return if the message has possible urls to autolink
153
	 *
154
	 * @return bool
155
	 */
156
	public function hasPossibleLink()
157
	{
158
		return $this->possible_link;
159
	}
160
161
	/**
162
	 * Parse any URLs found in the data
163
	 *
164 4
	 * - Have to get rid of the @ problems some things cause... stupid email addresses.
165
	 *
166
	 * @param $data
167 4
	 *
168
	 * @return string
169 4
	 */
170
	public function parseLinks($data)
171
	{
172 4
		// Switch out quotes really quick because they can cause problems.
173
		$data = strtr($data, array('&#039;' => "'", '&nbsp;' => "\xC2\xA0", '&quot;' => '>">', '"' => '<"<', '&lt;' => '<lt<'));
174 4
175
		$result = preg_replace($this->search, $this->replace, $data);
176
177
		// Only do this if the preg survives.
178 4
		if (is_string($result))
0 ignored issues
show
The condition is_string($result) is always true.
Loading history...
179
		{
180
			$data = $result;
181
		}
182
183
		// Switch those quotes back
184
		return strtr($data, array("'" => '&#039;', "\xC2\xA0" => '&nbsp;', '>">' => '&quot;', '<"<' => '"', '<lt<' => '&lt;'));
185
	}
186
187
	/**
188 14
	 * Validates if the data contains email address that need to be parsed
189
	 *
190 14
	 * @param string $data
191
	 *
192
	 * @return bool
193
	 */
194
	public function hasEmails($data)
195
	{
196
		return $this->hasPossibleEmail() && strpos($data, '@') !== false;
197
	}
198 28
199
	/**
200 28
	 * Return if the message has possible emails to autolink
201
	 *
202
	 * @return bool
203
	 */
204
	public function hasPossibleEmail()
205
	{
206
		return $this->possible_email;
207
	}
208
209
	/**
210
	 * Search and replace plain email address with bbc [email][/email]
211
	 *
212
	 * @param string $data
213
	 *
214
	 * @return null|string|string[]
215
	 */
216
	public function parseEmails($data)
217
	{
218
		// Next, emails...
219
		return preg_replace($this->email_search, $this->email_replace, $data);
220
	}
221 28
222
	/**
223 28
	 * Quickly determine if the supplied message has potential linking code
224 28
	 *
225
	 * @param string $message
226
	 */
227 28
	public function setPossibleAutolink($message)
228
	{
229 28
		$possible_link = $this->url_enabled && (strpos($message, '://') !== false || strpos($message, 'www.') !== false);
230 28
		$possible_email = $this->email_enabled && strpos($message, '@') !== false;
231 28
232
		// Your autolink integration might use something like tel.123456789.call. This makes that possible.
233
		call_integration_hook('integrate_possible_autolink', array(&$possible_link, &$possible_email));
234
235
		$this->possible_link = $possible_link;
236
		$this->possible_email = $possible_email;
237
	}
238 28
239
	/**
240 28
	 * Return if the message has any possible links (email or url)
241
	 *
242
	 * @return bool
243
	 */
244
	public function hasPossible()
245
	{
246
		if ($this->hasPossibleLink())
247
		{
248
			return true;
249
		}
250
251
		return $this->hasPossibleEmail();
252
	}
253
}
254