Completed
Push — 3.2.x ( be9360...c8dee9 )
by Erwan
12:34
created

link::recents()   C

Complexity

Conditions 9
Paths 29

Size

Total Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 76
rs 6.968
c 0
b 0
f 0
cc 9
nc 29
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
*
4
* phpBB Directory extension for the phpBB Forum Software package.
5
*
6
* @copyright (c) 2014 ErnadoO <http://www.phpbb-services.com>
7
* @license GNU General Public License, version 2 (GPL-2.0)
8
*
9
*/
10
11
namespace ernadoo\phpbbdirectory\core;
12
13
class link extends helper
14
{
15
	/** @var \phpbb\db\driver\driver_interface */
16
	protected $db;
17
18
	/** @var \phpbb\config\config */
19
	protected $config;
20
21
	/** @var \phpbb\language\language */
22
	protected $language;
23
24
	/** @var \phpbb\template\template */
25
	protected $template;
26
27
	/** @var \phpbb\user */
28
	protected $user;
29
30
	/** @var \phpbb\controller\helper */
31
	protected $helper;
32
33
	/** @var \phpbb\request\request */
34
	protected $request;
35
36
	/** @var \phpbb\auth\auth */
37
	protected $auth;
38
39
	/** @var \phpbb\notification\manager */
40
	protected $notification;
41
42
	/** @var \phpbb\filesystem\filesystem_interface */
43
	protected $filesystem;
44
45
	/** @var \FastImageSize\FastImageSize */
46
	protected $imagesize;
47
48
	/** @var \phpbb\files\upload */
49
	protected $files_upload;
50
51
	/** @var string phpBB root path */
52
	protected $root_path;
53
54
	/** @var string phpEx */
55
	protected $php_ext;
56
57
	/**
58
	* Constructor
59
	*
60
	* @param \phpbb\db\driver\driver_interface 					$db					Database object
61
	* @param \phpbb\config\config 								$config				Config object
62
	* @param \phpbb\language\language							$language			Language object
63
	* @param \phpbb\template\template 							$template			Template object
64
	* @param \phpbb\user 										$user				User object
65
	* @param \phpbb\controller\helper 							$helper				Controller helper object
66
	* @param \phpbb\request\request 							$request			Request object
67
	* @param \phpbb\auth\auth 									$auth				Auth object
68
	* @param \phpbb\notification\manager						$notification		Notification object
69
	* @param \phpbb\filesystem\filesystem_interface				$filesystem			phpBB filesystem helper
70
	* @param \FastImageSize\FastImageSize						$imagesize 			FastImageSize class
71
	* @param \phpbb\files\upload								$files_upload		Upload object
72
	* @param string         									$root_path			phpBB root path
73
	* @param string         									$php_ext			phpEx
74
	*/
75 View Code Duplication
	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\request\request $request, \phpbb\auth\auth $auth, \phpbb\notification\manager $notification, \phpbb\filesystem\filesystem_interface $filesystem, \FastImageSize\FastImageSize $imagesize, \phpbb\files\upload $files_upload, $root_path, $php_ext)
76
	{
77
		$this->db				= $db;
78
		$this->config			= $config;
79
		$this->language			= $language;
80
		$this->template			= $template;
81
		$this->user				= $user;
82
		$this->helper			= $helper;
83
		$this->request			= $request;
84
		$this->auth				= $auth;
85
		$this->notification		= $notification;
86
		$this->filesystem		= $filesystem;
87
		$this->imagesize		= $imagesize;
88
		$this->files_upload 	= $files_upload;
89
		$this->root_path		= $root_path;
90
		$this->php_ext			= $php_ext;
91
	}
92
93
	/**
94
	* Add a link into db
95
	*
96
	* @param	array	$data			Contains all data to insert in db
97
	* @param	bool	$need_approval	Links needs to be approved?
98
	* @return	null
99
	*/
100
	public function add($data, $need_approval)
101
	{
102
		$notification_data = array();
103
104
		$this->db->sql_transaction('begin');
105
106
		$sql = 'INSERT INTO ' . $this->links_table . ' ' . $this->db->sql_build_array('INSERT', $data);
107
		$this->db->sql_query($sql);
108
		$notification_data['link_id'] = $this->db->sql_nextid();
109
110
		if (!$need_approval || $this->auth->acl_get('a_') || $this->auth->acl_get('m_'))
111
		{
112
			$sql = 'UPDATE ' . $this->categories_table . '
113
				SET cat_links = cat_links + 1
114
				WHERE cat_id = ' . (int) $data['link_cat'];
115
			$this->db->sql_query($sql);
116
117
			$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website';
118
		}
119
		else if ($this->config['dir_mail'])
120
		{
121
			$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue';
122
		}
123
124
		$this->db->sql_transaction('commit');
125
126
		if (isset($notification_type))
127
		{
128
			$notification_data = array_merge($notification_data,
129
				array(
130
					'user_from'			=> (int) $data['link_user_id'],
131
					'link_name'			=> $data['link_name'],
132
					'link_url'			=> $data['link_url'],
133
					'link_description'	=> $data['link_description'],
134
					'cat_id'			=> (int) $data['link_cat'],
135
					'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
136
				)
137
			);
138
139
			$this->notification->add_notifications($notification_type, $notification_data);
140
		}
141
	}
142
143
	/**
144
	* Edit a link of the db
145
	*
146
	* @param	array	$data			Contains all data to edit in db
147
	* @param	int		$link_id		is link's id, for WHERE clause
148
	* @param	bool	$need_approval	Links needs to be approved?
149
	* @return	null
150
	*/
151
	public function edit($data, $link_id, $need_approval)
152
	{
153
		$notification_data = array(
154
			'link_id'			=> (int) $link_id,
155
			'user_from'			=> (int) $data['link_user_id'],
156
			'link_name'			=> $data['link_name'],
157
			'link_description'	=> $data['link_description'],
158
			'cat_id'			=> (int) $data['link_cat'],
159
			'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
160
		);
161
162
		$old_cat = array_pop($data);
163
164
		if ($old_cat != $data['link_cat'] || $need_approval)
165
		{
166
			$this->notification->delete_notifications('ernadoo.phpbbdirectory.notification.type.directory_website', (int) $link_id);
167
168
			$this->db->sql_transaction('begin');
169
170
			$sql = 'UPDATE ' . $this->categories_table . '
171
				SET cat_links = cat_links - 1
172
				WHERE cat_id = ' . (int) $old_cat;
173
			$this->db->sql_query($sql);
174
175
			if (!$need_approval)
176
			{
177
				$sql = 'UPDATE ' . $this->categories_table . '
178
					SET cat_links = cat_links + 1
179
					WHERE cat_id = ' . (int) $data['link_cat'];
180
				$this->db->sql_query($sql);
181
182
				$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website';
183
			}
184
			else
185
			{
186
				$data['link_active'] = false;
187
				$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue';
188
			}
189
190
			$this->db->sql_transaction('commit');
191
192
			$this->notification->add_notifications($notification_type, $notification_data);
193
		}
194
195
		$sql = 'UPDATE ' . $this->links_table . '
196
			SET ' . $this->db->sql_build_array('UPDATE', $data) . '
197
			WHERE link_id = ' . (int) $link_id;
198
		$this->db->sql_query($sql);
199
	}
200
201
	/**
202
	* Delete a link of the db
203
	*
204
	* @param	int 	$cat_id		The category ID
205
	* @param	mixed 	$link_id	Link's id, for WHERE clause
206
	* @return	null
207
	*/
208
	public function del($cat_id, $link_id)
209
	{
210
		$this->db->sql_transaction('begin');
211
212
		$url_array = is_array($link_id) ? $link_id : array($link_id);
213
214
		// Delete links datas
215
		$link_datas_ary = array(
216
			$this->links_table		=> 'link_id',
217
			$this->comments_table	=> 'comment_link_id',
218
			$this->votes_table		=> 'vote_link_id',
219
		);
220
221
		$sql = 'SELECT link_banner
222
			FROM ' . $this->links_table . '
223
			WHERE '. $this->db->sql_in_set('link_id', $url_array);
224
		$result = $this->db->sql_query($sql);
225
226
		while ($row = $this->db->sql_fetchrow($result))
227
		{
228 View Code Duplication
			if ($row['link_banner'] && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $row['link_banner']))
229
			{
230
				$banner_img = $this->root_path . $this->get_banner_path(basename($row['link_banner']));
231
232
				if (file_exists($banner_img))
233
				{
234
					@unlink($banner_img);
235
				}
236
			}
237
		}
238
239
		foreach ($link_datas_ary as $table => $field)
240
		{
241
			$this->db->sql_query("DELETE FROM $table WHERE ".$this->db->sql_in_set($field, $url_array));
242
		}
243
244
		$sql = 'UPDATE ' . $this->categories_table . '
245
			SET cat_links = cat_links - '.sizeof($url_array).'
246
			WHERE cat_id = ' . (int) $cat_id;
247
		$this->db->sql_query($sql);
248
249
		$this->db->sql_transaction('commit');
250
251
		foreach ($url_array as $link_id)
252
		{
253
			$this->notification->delete_notifications(array(
254
				'ernadoo.phpbbdirectory.notification.type.directory_website',
255
				'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue'
256
			), $link_id);
257
		}
258
259 View Code Duplication
		if ($this->request->is_ajax())
260
		{
261
			$sql = 'SELECT cat_links
262
				FROM ' . $this->categories_table . '
263
				WHERE cat_id = ' . (int) $cat_id;
264
			$result = $this->db->sql_query($sql);
265
			$data = $this->db->sql_fetchrow($result);
266
267
			$json_response = new \phpbb\json_response;
268
			$json_response->send(array(
269
				'success' => true,
270
271
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
272
				'MESSAGE_TEXT'	=> $this->language->lang('DIR_DELETE_OK'),
273
				'LINK_ID'		=> $link_id,
274
				'TOTAL_LINKS'	=> $this->language->lang('DIR_NB_LINKS', (int) $data['cat_links']),
275
			));
276
		}
277
	}
278
279
	/**
280
	* Increments link view counter
281
	*
282
	* @param	int		$link_id	Link's id, for WHERE clause
283
	* @return	null
284
	* @throws	\phpbb\exception\http_exception
285
	*/
286
	public function view($link_id)
287
	{
288
		$sql = 'SELECT link_id, link_url
289
			FROM ' . $this->links_table . '
290
			WHERE link_id = ' . (int) $link_id;
291
		$result = $this->db->sql_query($sql);
292
		$data = $this->db->sql_fetchrow($result);
293
294
		if (empty($data['link_id']))
295
		{
296
			throw new \phpbb\exception\http_exception(404, 'DIR_ERROR_NO_LINKS');
297
		}
298
299
		$sql = 'UPDATE ' . $this->links_table . '
300
			SET link_view = link_view + 1
301
			WHERE link_id = ' . (int) $link_id;
302
		$this->db->sql_query($sql);
303
304
		redirect($data['link_url'], false, true);
305
		return;
306
	}
307
308
	/**
309
	* Verify that an URL exist before add into db
310
	*
311
	* @param	string	$url	The URL to check
312
	* @return	bool			True if url is reachable, else false.
313
	*/
314
	public function checkurl($url)
315
	{
316
		$details = parse_url($url);
317
318
		$default_port = 80;
319
		$hostname = $details['host'];
320
321
		if ($details['scheme'] == 'https')
322
		{
323
			$default_port = 443;
324
			$hostname = 'ssl://' . $details['host'];
325
		}
326
327
		if (!isset($details['path']))
328
		{
329
			$details['path'] = '/';
330
		}
331
332
		$port = (isset($details['port']) && !empty($details['port'])) ? (int) $details['port'] : $default_port;
333
334
		if ($sock = @fsockopen($hostname, $port, $errno, $errstr, 1))
335
		{
336
			$requete = 'GET '.$details['path']." HTTP/1.1\r\n";
337
			$requete .= 'Host: '.$details['host']."\r\n\r\n";
338
339
			// Send a HTTP GET header
340
			fputs($sock, $requete);
341
			// answer from server
342
			$str = fgets($sock, 1024);
343
			preg_match("'HTTP/1\.. (.*) (.*)'U", $str, $parts);
344
			fclose($sock);
345
346
			return !($parts[1] == '404');
347
		}
348
		return false;
349
	}
350
351
	/**
352
	* Delete the final '/', if no path
353
	*
354
	* @param	string	$url	URL to clean
355
	* @return	string	$url	The correct string.
356
	*/
357
	public function clean_url($url)
358
	{
359
		$details = parse_url($url);
360
361
		if (isset($details['path']) && $details['path'] == '/' && !isset($details['query']))
362
		{
363
			return substr($url, 0, -1);
364
		}
365
		return $url;
366
	}
367
368
	/**
369
	* Display a flag
370
	*
371
	* @param	array	$data	Link's data from db
372
	* @return	string			Flag path.
373
	*/
374
	public function display_flag($data)
375
	{
376
		global $phpbb_extension_manager;
377
378
		$ext_path = $phpbb_extension_manager->get_extension_path('ernadoo/phpbbdirectory', true);
379
		$flag_path = $ext_path.'images/flags/';
380
		$img_flag = 'no_flag.png';
381
382
		if ($this->config['dir_activ_flag'] && !empty($data['link_flag']) && file_exists($flag_path . $data['link_flag']))
383
		{
384
			$img_flag = $data['link_flag'];
385
		}
386
387
		return $this->get_img_path('flags', $img_flag);
388
	}
389
390
	/**
391
	* Calculate the link's note
392
	*
393
	* @param	int		$total_note		Sum of all link's notes
394
	* @param	int		$nb_vote		Number of votes
395
	* @param	bool	$votes_status	Votes are enable in this category?
396
	* @return	string	$note			The calculated note.
397
	*/
398
	public function display_note($total_note, $nb_vote, $votes_status)
399
	{
400
		if (!$votes_status)
401
		{
402
			return;
403
		}
404
405
		$note = ($nb_vote < 1) ? '' : $total_note / $nb_vote;
406
		$note = (strlen($note) > 2) ? number_format($note, 1) : $note;
407
408
		return ($nb_vote) ? $this->language->lang('DIR_FROM_TEN', $note) : $this->language->lang('DIR_NO_NOTE');
409
	}
410
411
	/**
412
	* Display the vote form for auth users
413
	*
414
	* @param	array	$data	Link's data from db
415
	* @return	null|string		Html combo list or nothing if votes are not available.
416
	*/
417
	public function display_vote($data)
418
	{
419
		if ($this->user->data['is_registered'] && $this->auth->acl_get('u_vote_dir') && empty($data['vote_user_id']))
420
		{
421
			$list = '<select name="vote">';
422
			for ($i = 0; $i <= 10; $i++)
423
			{
424
				$list .= '<option value="' . $i . '"' . (($i == 5) ? ' selected="selected"' : '') . '>' . $i . '</option>';
425
			}
426
			$list .= '</select>';
427
428
			return $list;
429
		}
430
	}
431
432
	/**
433
	* Display the RSS icon
434
	*
435
	* @param	array	$data	Link's data from db
436
	* @return	null|string		RSS feed URL or nothing.
437
	*/
438
	public function display_rss($data)
439
	{
440
		if ($this->config['dir_activ_rss'] && !empty($data['link_rss']))
441
		{
442
				return $data['link_rss'];
443
		}
444
	}
445
446
	/**
447
	* Display link's thumb if thumb service enabled.
448
	* if thumb don't exists in db or if a new service was choosen in acp
449
	* thumb is research
450
	*
451
	* @param	array		$data	Link's data from db
452
	* @return	string|null			Thumb or null.
453
	*/
454
	public function display_thumb($data)
455
	{
456
		if ($this->config['dir_activ_thumb'])
457
		{
458
			if (!$data['link_thumb'] || ($this->config['dir_thumb_service_reverse'] && (!strstr($data['link_thumb'], 'ascreen.jpg') && (!strstr($data['link_thumb'], $this->config['dir_thumb_service'])))))
459
			{
460
				$thumb = $this->thumb_process($data['link_url']);
461
462
				$sql = 'UPDATE ' . $this->links_table . "
463
					SET link_thumb = '" . $this->db->sql_escape($thumb) . "'
464
					WHERE link_id = " . (int) $data['link_id'];
465
				$this->db->sql_query($sql);
466
467
				return $thumb;
468
			}
469
			return $data['link_thumb'];
470
		}
471
	}
472
473
	/**
474
	* Display and resize a banner
475
	*
476
	* @param	array	$data		link's data from db
477
	* @return	string	$s_banner	html code.
478
	*/
479
	public function display_bann($data)
480
	{
481
		if (!empty($data['link_banner']))
482
		{
483
			if (!preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $data['link_banner']))
484
			{
485
				$img_src = $this->helper->route('ernadoo_phpbbdirectory_banner_controller', array('banner_img' => $data['link_banner']));
486
				$physical_path = $this->get_banner_path($data['link_banner']);
487
			}
488
			else
489
			{
490
				$img_src = $physical_path = $data['link_banner'];
491
			}
492
493
			if (($image_data = $this->imagesize->getImageSize($physical_path)) === false)
494
			{
495
				return '';
496
			}
497
498
			$width = $image_data['width'];
499
			$height = $image_data['height'];
500
501
			if (($width > $this->config['dir_banner_width'] || $height > $this->config['dir_banner_height']) && $this->config['dir_banner_width'] > 0 && $this->config['dir_banner_height'] > 0)
502
			{
503
				$coef_w = $width / $this->config['dir_banner_width'];
504
				$coef_h = $height / $this->config['dir_banner_height'];
505
				$coef_max = max($coef_w, $coef_h);
506
				$width /= $coef_max;
507
				$height /= $coef_max;
508
			}
509
510
			return '<img src="' . $img_src . '" width="' . $width . '" height="' . $height . '" alt="'.$data['link_name'].'" title="'.$data['link_name'].'" />';
511
		}
512
		return '';
513
	}
514
515
	/**
516
	* Add a vote in db, for a specifi link
517
	*
518
	* @param	int		$link_id	Link_id from db
519
	* @param	int		$note		Note submeted
520
	* @return	null
521
	*/
522
	public function add_vote($link_id, $note)
523
	{
524
		$data = array(
525
			'vote_link_id' 		=> (int) $link_id,
526
			'vote_user_id' 		=> $this->user->data['user_id'],
527
			'vote_note'			=> (int) $note,
528
		);
529
530
		$this->db->sql_transaction('begin');
531
532
		$sql = 'INSERT INTO ' . $this->votes_table . ' ' . $this->db->sql_build_array('INSERT', $data);
533
		$this->db->sql_query($sql);
534
535
		$sql = 'UPDATE ' . $this->links_table . '
536
			SET link_vote = link_vote + 1,
537
			link_note = link_note + ' . (int) $data['vote_note'] . '
538
		WHERE link_id = ' . (int) $link_id;
539
		$this->db->sql_query($sql);
540
541
		$this->db->sql_transaction('commit');
542
543
		if ($this->request->is_ajax())
544
		{
545
			$sql= 'SELECT link_vote, link_note FROM ' . $this->links_table . ' WHERE link_id = ' . (int) $link_id;
546
			$result = $this->db->sql_query($sql);
547
			$data = $this->db->sql_fetchrow($result);
548
549
			$note = $this->display_note($data['link_note'], $data['link_vote'], true);
550
551
			$json_response = new \phpbb\json_response;
552
			$json_response->send(array(
553
				'success' => true,
554
555
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
556
				'MESSAGE_TEXT'	=> $this->language->lang('DIR_VOTE_OK'),
557
				'NOTE'			=> $note,
558
				'NB_VOTE'		=> $this->language->lang('DIR_NB_VOTES', (int) $data['link_vote']),
559
				'LINK_ID'		=> $link_id
560
			));
561
		}
562
	}
563
564
	/**
565
	* Search an appropriate thumb for url
566
	*
567
	* @param	string	$url	Link's url
568
	* @return	string			The thumb url
569
	*/
570
	public function thumb_process($url)
571
	{
572
		if (!$this->config['dir_activ_thumb'])
573
		{
574
			return $this->root_path.'images/directory/nothumb.gif';
575
		}
576
577
		$details = parse_url($url);
578
579
		$root_url		= $details['scheme'].'://'.$details['host'];
580
		$absolute_url	= isset($details['path']) ? $root_url.$details['path'] : $root_url;
581
582
		if ($this->config['dir_activ_thumb_remote'] && $this->_ascreen_exist($details['scheme'], $details['host']))
583
		{
584
			return $root_url.'/ascreen.jpg';
585
		}
586
		return $this->config['dir_thumb_service'].$absolute_url;
587
	}
588
589
	/**
590
	* Check if ascreen thumb exists
591
	*
592
	* @param	string	$protocol	The protocol
593
	* @param	string	$host		The hostname
594
	* @return	bool				True if ascreen file exixts, else false
595
	*/
596
	private function _ascreen_exist($protocol, $host)
597
	{
598
		if (($thumb_info = $this->imagesize->getImageSize($protocol.'://'.$host.'/ascreen.jpg')) !== false)
599
		{
600
			// Obviously this is an image, we did some additional tests
601
			if ($thumb_info['width'] == '120' && $thumb_info['height'] == '90' && $thumb_info['type'] == 2)
602
			{
603
				return true;
604
			}
605
		}
606
		return false;
607
	}
608
609
	/**
610
	* Primary work on banner, can edit, copy or check a banner
611
	*
612
	* @param	string	$banner	The banner's remote url
613
	* @param	array	$error	The array error, passed by reference
614
	* @return	null
615
	*/
616
	public function banner_process(&$banner, &$error)
617
	{
618
		$old_banner = $this->request->variable('old_banner', '');
619
620
		$destination = $this->root_path . $this->get_banner_path();
621
622
		// Can we upload?
623
		$can_upload = ($this->config['dir_storage_banner'] && $this->filesystem->exists($destination) && $this->filesystem->is_writable($destination) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
624
625
		if ($banner && $can_upload)
626
		{
627
			$file = $this->_banner_upload($banner, $error);
628
		}
629
		else if ($banner)
630
		{
631
			$file = $this->_banner_remote($banner, $error);
632
		}
633
		else if ($this->request->is_set_post('delete_banner') && $old_banner)
634
		{
635
			$this->_banner_delete($old_banner);
636
			return;
637
		}
638
639
		if (!sizeof($error))
640
		{
641
			if ($banner && $old_banner && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $old_banner))
642
			{
643
				$this->_banner_delete($old_banner);
644
			}
645
646
			$banner = !empty($file) ? $file : '';
647
		}
648
	}
649
650
	/**
651
	* Copy a remonte banner to server.
652
	* called by banner_process()
653
	*
654
	* @param	string	$banner The banner's remote url
655
	* @param	array	$error	The array error, passed by reference
656
	* @return	false|string	String if no errors, else false
657
	*/
658
	private function _banner_upload($banner, &$error)
659
	{
660
		/** @var \phpbb\files\upload $upload */
661
		$upload = $this->files_upload
662
			->set_error_prefix('DIR_BANNER_')
663
			->set_allowed_extensions(array('jpg', 'jpeg', 'gif', 'png'))
664
			->set_max_filesize($this->config['dir_banner_filesize'])
665
			->set_disallowed_content((isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false));
666
667
		$file = $upload->handle_upload('files.types.remote', $banner);
668
669
		$prefix = unique_id() . '_';
670
		$file->clean_filename('real', $prefix);
671
672
		if (sizeof($file->error))
673
		{
674
			$file->remove();
675
			$error = array_merge($error, $file->error);
676
			$error = array_map(array($this->language, 'lang'), $error);
677
			return false;
678
		}
679
680
		$destination = $this->get_banner_path();
681
682
		// Move file and overwrite any existing image
683
		$file->move_file($destination, true);
684
685
		return strtolower($file->get('realname'));
686
	}
687
688
	/**
689
	* Check than remote banner exists
690
	* called by banner_process()
691
	*
692
	* @param	string	$banner	The banner's remote url
693
	* @param	array	$error	The array error, passed by reference
694
	* @return	false|string	String if no errors, else false
695
	*/
696
	private function _banner_remote($banner, &$error)
697
	{
698
		if (!preg_match('#^(http|https|ftp)://#i', $banner))
699
		{
700
			$banner = 'http://' . $banner;
701
		}
702
		if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $banner))
703
		{
704
			$error[] = $this->language->lang('DIR_BANNER_URL_INVALID');
705
			return false;
706
		}
707
708
		// Get image dimensions
709
		if (($image_data = $this->imagesize->getImageSize($banner)) === false)
710
		{
711
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
712
			return false;
713
		}
714
715
		if (!empty($image_data) && ($image_data['width'] < 2 || $image_data['height'] < 2))
716
		{
717
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
718
			return false;
719
		}
720
721
		$width = $image_data['width'];
722
		$height = $image_data['height'];
723
724
		if ($width <= 0 || $height <= 0)
725
		{
726
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
727
			return false;
728
		}
729
730
		// Check image type
731
		$types		= \phpbb\files\upload::image_types();
732
		$extension	= strtolower(\phpbb\files\filespec::get_extension($banner));
733
734
		// Check if this is actually an image
735
		if ($file_stream = @fopen($banner, 'r'))
736
		{
737
			// Timeout after 1 second
738
			stream_set_timeout($file_stream, 1);
739
			// read some data to ensure headers are present
740
			fread($file_stream, 1024);
741
			$meta = stream_get_meta_data($file_stream);
742
			if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers']))
743
			{
744
				$headers = $meta['wrapper_data']['headers'];
745
			}
746
			else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data']))
747
			{
748
				$headers = $meta['wrapper_data'];
749
			}
750
			else
751
			{
752
				$headers = array();
753
			}
754
755
			foreach ($headers as $header)
756
			{
757
				$header = preg_split('/ /', $header, 2);
758
				if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type')
759
				{
760
					if (strpos($header[1], 'image/') !== 0)
761
					{
762
						$error[] = 'DIR_BANNER_URL_INVALID';
763
						fclose($file_stream);
764
						return false;
765
					}
766
					else
767
					{
768
						fclose($file_stream);
769
						break;
770
					}
771
				}
772
			}
773
		}
774
		else
775
		{
776
			$error[] = 'DIR_BANNER_URL_INVALID';
777
			return false;
778
		}
779
780
		if (!empty($image_data) && (!isset($types[$image_data['type']]) || !in_array($extension, $types[$image_data['type']])))
781
		{
782
			if (!isset($types[$image_data['type']]))
783
			{
784
				$error[] = $this->language->lang('UNABLE_GET_IMAGE_SIZE');
785
			}
786
			else
787
			{
788
				$error[] = $this->language->lang('DIR_BANNER_IMAGE_FILETYPE_MISMATCH', $types[$image_data['type']][0], $extension);
789
			}
790
			return false;
791
		}
792
793
		if (($this->config['dir_banner_width'] || $this->config['dir_banner_height']) && ($width > $this->config['dir_banner_width'] || $height > $this->config['dir_banner_height']))
794
		{
795
			$error[] = $this->language->lang('DIR_BANNER_WRONG_SIZE', $this->config['dir_banner_width'], $this->config['dir_banner_height'], $width, $height);
796
			return false;
797
		}
798
799
		return $banner;
800
	}
801
802
	/**
803
	* Delete a banner from server
804
	*
805
	* @param	string	$file	The file's name
806
	* @return	bool			True if delete success, else false
807
	*/
808
	private function _banner_delete($file)
809
	{
810
		$old_banner = $this->root_path  . $this->get_banner_path($file);
811
812
		if (file_exists($old_banner))
813
		{
814
			@unlink($old_banner);
815
			return true;
816
		}
817
818
		return false;
819
	}
820
821
	/**
822
	* List flags
823
	*
824
	* @param	string	$flag_path	The flag directory path
825
	* @param	string	$value		Selected flag
826
	* @return	string	$list		Html code
827
	*/
828
	public function get_dir_flag_list($flag_path, $value)
829
	{
830
		$list = '';
831
832
		$this->language->add_lang('directory_flags', 'ernadoo/phpbbdirectory');
833
834
		$flags = $this->preg_grep_keys('/^DIR_FLAG_CODE_/i', $this->language->get_lang_array());
835
836
		if (extension_loaded('intl'))
837
		{
838
			$locale = $this->language->lang('USER_LANG');
839
840
			$col = new \Collator($locale);
841
			$col->asort($flags);
842
		}
843
		else
844
		{
845
			asort($flags);
846
		}
847
848
		foreach ($flags as $file => $name)
849
		{
850
			$img_file = strtolower(substr(strrchr($file, '_'), 1)).'.png';
851
852
			if (file_exists($flag_path.$img_file))
853
			{
854
				$list .= '<option value="' . $img_file . '" ' . (($img_file == $value) ? 'selected="selected"' : '') . '>' . $name . '</option>';
855
			}
856
		}
857
858
		return $list;
859
	}
860
861
	/**
862
	* Display recents links added
863
	*
864
	* @return	null
865
	*/
866
	public function recents()
867
	{
868
		if ($this->config['dir_recent_block'])
869
		{
870
			$limit_sql		= $this->config['dir_recent_rows'] * $this->config['dir_recent_columns'];
871
			$exclude_array	= array_filter(explode(',', str_replace(' ', '', $this->config['dir_recent_exclude'])));
872
873
			$sql_array = array(
874
				'SELECT'	=> 'l.link_id, l.link_cat, l.link_url, l.link_user_id, l.link_comment, l. link_description, l.link_vote, l.link_note, l.link_view, l.link_time, l.link_name, l.link_thumb, u.user_id, u.username, u.user_colour, c.cat_name',
875
				'FROM'		=> array(
876
						$this->links_table	=> 'l'),
877
				'LEFT_JOIN'	=> array(
878
						array(
879
							'FROM'	=> array(USERS_TABLE	=> 'u'),
880
							'ON'	=> 'l.link_user_id = u.user_id'
881
						),
882
						array(
883
							'FROM'	=> array($this->categories_table => 'c'),
884
							'ON'	=> 'l.link_cat = c.cat_id'
885
						)
886
				),
887
				'WHERE'		=> 'l.link_active = 1' . (sizeof($exclude_array) ? ' AND ' . $this->db->sql_in_set('l.link_cat', $exclude_array, true) : ''),
888
				'ORDER_BY'	=> 'l.link_time DESC, l.link_id DESC');
889
890
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
891
			$result = $this->db->sql_query_limit($sql, $limit_sql, 0);
892
			$num = 0;
893
			$rowset = array();
894
895
			while ($site = $this->db->sql_fetchrow($result))
896
			{
897
				$rowset[$site['link_id']] = $site;
898
			}
899
			$this->db->sql_freeresult($result);
900
901
			if (sizeof($rowset))
902
			{
903
				$this->template->assign_block_vars('block', array(
904
					'S_COL_WIDTH'			=> (100 / $this->config['dir_recent_columns']) . '%',
905
				));
906
907
				foreach ($rowset as $row)
908
				{
909
					if (($num % $this->config['dir_recent_columns']) == 0)
910
					{
911
						$this->template->assign_block_vars('block.row', array());
912
					}
913
914
					$this->template->assign_block_vars('block.row.col', array(
915
						'NAME'						=> $row['link_name'],
916
						'USER'						=> get_username_string('full', $row['link_user_id'], $row['username'], $row['user_colour']),
917
						'TIME'						=> ($row['link_time']) ? $this->user->format_date($row['link_time']) : '',
918
						'CAT'						=> $row['cat_name'],
919
						'COUNT'						=> $row['link_view'],
920
						'COMMENT'					=> $row['link_comment'],
921
922
						'U_CAT'						=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $row['link_cat']),
923
						'U_COMMENT'					=> $this->helper->route('ernadoo_phpbbdirectory_comment_view_controller', array('link_id' => (int) $row['link_id'])),
924
						'U_LINK'					=> $row['link_url'],
925
						'U_THUMB'					=> $this->display_thumb($row),
926
						'U_VIEW'					=> $this->helper->route('ernadoo_phpbbdirectory_view_controller', array('link_id' => (int) $row['link_id'])),
927
928
						'L_DIR_SEARCH_NB_CLICKS'	=> $this->language->lang('DIR_SEARCH_NB_CLICKS', (int) $row['link_view']),
929
						'L_DIR_SEARCH_NB_COMMS'		=> $this->language->lang('DIR_SEARCH_NB_COMMS', (int) $row['link_comment']),
930
					));
931
					$num++;
932
				}
933
934
				while (($num % $this->config['dir_recent_columns']) != 0)
935
				{
936
					$this->template->assign_block_vars('block.row.col2', array());
937
					$num++;
938
				}
939
			}
940
		}
941
	}
942
943
	/**
944
	* Validate back link
945
	*
946
	* @param	string		$remote_url	Page URL contains the backlink
947
	* @param	bool		$optional	Link back is optional in this category?
948
	* @param	bool		$cron		This methos is called by con process?
949
	* @return	false|string			Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
950
	*/
951
	public function validate_link_back($remote_url, $optional, $cron = false)
952
	{
953
		if (!$cron)
954
		{
955
			if (empty($remote_url) && $optional)
956
			{
957
				return false;
958
			}
959
960
			if (!preg_match('#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i', $remote_url))
961
			{
962
				return 'DIR_ERROR_WRONG_DATA_BACK';
963
			}
964
		}
965
966
		if (false === ($handle = @fopen($remote_url, 'r')))
967
		{
968
			return 'DIR_ERROR_NOT_FOUND_BACK';
969
		}
970
971
		$buff = '';
972
973
		// Read by packet, faster than file_get_contents()
974
		while (!feof($handle))
975
		{
976
			$buff .= fgets($handle, 256);
977
978
			if (stristr($buff, $this->config['server_name']))
979
			{
980
				@fclose($handle);
981
				return false;
982
			}
983
		}
984
		@fclose($handle);
985
986
		return 'DIR_ERROR_NO_LINK_BACK';
987
	}
988
}
989