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

link::__construct()   A

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
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