link::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 17
Ratio 100 %

Importance

Changes 0
Metric Value
dl 17
loc 17
rs 9.7
c 0
b 0
f 0
cc 1
nc 1
nop 14

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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