Completed
Push — 3.2.x ( 2e2541...0c5ab2 )
by Erwan
02:58
created

link::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 16

Duplication

Lines 18
Ratio 100 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
dl 18
loc 18
rs 9.4285
cc 1
eloc 16
nc 1
nop 15

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
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\factory */
49
	protected $files_factory;
50
51
	/** @var \ernadoo\phpbbdirectory\core\helper */
52
	protected $dir_helper;
53
54
	/** @var string phpBB root path */
55
	protected $root_path;
56
57
	/** @var string phpEx */
58
	protected $php_ext;
59
60
	/**
61
	* Constructor
62
	*
63
	* @param \phpbb\db\driver\driver_interface 					$db					Database object
64
	* @param \phpbb\config\config 								$config				Config object
65
	* @param \phpbb\language\language							$language			Language object
66
	* @param \phpbb\template\template 							$template			Template object
67
	* @param \phpbb\user 										$user				User object
68
	* @param \phpbb\controller\helper 							$helper				Controller helper object
69
	* @param \phpbb\request\request 							$request			Request object
70
	* @param \phpbb\auth\auth 									$auth				Auth object
71
	* @param \phpbb\notification\manager						$notification		Notification object
72
	* @param \phpbb\filesystem\filesystem_interface				$filesystem			phpBB filesystem helper
73
	* @param \FastImageSize\FastImageSize						$imagesize 			FastImageSize class
74
	* @param \phpbb\files\factory								$files_factory		File classes factory
75
	* @param \ernadoo\phpbbdirectory\core\helper				$dir_helper			PhpBB Directory extension helper object
76
	* @param string         									$root_path			phpBB root path
77
	* @param string         									$php_ext			phpEx
78
	*/
79 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\factory $files_factory, \ernadoo\phpbbdirectory\core\helper $dir_helper, $root_path, $php_ext)
80
	{
81
		$this->db				= $db;
82
		$this->config			= $config;
83
		$this->language			= $language;
84
		$this->template			= $template;
85
		$this->user				= $user;
86
		$this->helper			= $helper;
87
		$this->request			= $request;
88
		$this->auth				= $auth;
89
		$this->notification		= $notification;
90
		$this->filesystem		= $filesystem;
91
		$this->imagesize		= $imagesize;
92
		$this->files_factory 	= $files_factory;
93
		$this->dir_helper		= $dir_helper;
94
		$this->root_path		= $root_path;
95
		$this->php_ext			= $php_ext;
96
	}
97
98
	/**
99
	* Add a link into db
100
	*
101
	* @param	array	$data			Contains all data to insert in db
102
	* @param	bool	$need_approval	Links needs to be approved?
103
	* @return	null
104
	*/
105
	public function add($data, $need_approval)
106
	{
107
		$notification_data = array();
108
109
		$this->db->sql_transaction('begin');
110
111
		$sql = 'INSERT INTO ' . DIR_LINK_TABLE . ' ' . $this->db->sql_build_array('INSERT', $data);
112
		$this->db->sql_query($sql);
113
		$notification_data['link_id'] = $this->db->sql_nextid();
114
115
		if (!$need_approval || $this->auth->acl_get('a_') || $this->auth->acl_get('m_'))
116
		{
117
			$sql = 'UPDATE ' . DIR_CAT_TABLE . '
118
				SET cat_links = cat_links + 1
119
				WHERE cat_id = ' . (int) $data['link_cat'];
120
			$this->db->sql_query($sql);
121
122
			$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website';
123
		}
124
		else if ($this->config['dir_mail'])
125
		{
126
			$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue';
127
		}
128
129
		$this->db->sql_transaction('commit');
130
131
		if (isset($notification_type))
132
		{
133
			$notification_data = array_merge($notification_data,
134
				array(
135
					'user_from'			=> (int) $data['link_user_id'],
136
					'link_name'			=> $data['link_name'],
137
					'link_url'			=> $data['link_url'],
138
					'link_description'	=> $data['link_description'],
139
					'cat_id'			=> (int) $data['link_cat'],
140
					'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
141
				)
142
			);
143
144
			$this->notification->add_notifications($notification_type, $notification_data);
145
		}
146
	}
147
148
	/**
149
	* Edit a link of the db
150
	*
151
	* @param	array	$data			Contains all data to edit in db
152
	* @param	int		$link_id		is link's id, for WHERE clause
153
	* @param	bool	$need_approval	Links needs to be approved?
154
	* @return	null
155
	*/
156
	public function edit($data, $link_id, $need_approval)
157
	{
158
		$notification_data = array(
159
			'link_id'			=> (int) $link_id,
160
			'user_from'			=> (int) $data['link_user_id'],
161
			'link_name'			=> $data['link_name'],
162
			'link_description'	=> $data['link_description'],
163
			'cat_id'			=> (int) $data['link_cat'],
164
			'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
165
		);
166
167
		$old_cat = array_pop($data);
168
169
		if ($old_cat != $data['link_cat'] || $need_approval)
170
		{
171
			$this->notification->delete_notifications('ernadoo.phpbbdirectory.notification.type.directory_website', (int) $link_id);
172
173
			$this->db->sql_transaction('begin');
174
175
			$sql = 'UPDATE ' . DIR_CAT_TABLE . '
176
				SET cat_links = cat_links - 1
177
				WHERE cat_id = ' . (int) $old_cat;
178
			$this->db->sql_query($sql);
179
180
			if (!$need_approval)
181
			{
182
				$sql = 'UPDATE ' . DIR_CAT_TABLE . '
183
					SET cat_links = cat_links + 1
184
					WHERE cat_id = ' . (int) $data['link_cat'];
185
				$this->db->sql_query($sql);
186
187
				$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website';
188
			}
189
			else
190
			{
191
				$data['link_active'] = false;
192
				$notification_type = 'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue';
193
			}
194
195
			$this->db->sql_transaction('commit');
196
197
			$this->notification->add_notifications($notification_type, $notification_data);
198
		}
199
200
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
201
			SET ' . $this->db->sql_build_array('UPDATE', $data) . '
202
			WHERE link_id = ' . (int) $link_id;
203
		$this->db->sql_query($sql);
204
	}
205
206
	/**
207
	* Delete a link of the db
208
	*
209
	* @param	int 	$cat_id		The category ID
210
	* @param	mixed 	$link_id	Link's id, for WHERE clause
211
	* @return	null
212
	*/
213
	public function del($cat_id, $link_id)
214
	{
215
		$this->db->sql_transaction('begin');
216
217
		$url_array = is_array($link_id) ? $link_id : array($link_id);
218
219
		// Delete links datas
220
		$link_datas_ary = array(
221
			DIR_LINK_TABLE		=> 'link_id',
222
			DIR_COMMENT_TABLE	=> 'comment_link_id',
223
			DIR_VOTE_TABLE		=> 'vote_link_id',
224
		);
225
226
		$sql = 'SELECT link_banner
227
			FROM ' . DIR_LINK_TABLE . '
228
			WHERE '. $this->db->sql_in_set('link_id', $url_array);
229
		$result = $this->db->sql_query($sql);
230
231
		while ($row = $this->db->sql_fetchrow($result))
232
		{
233 View Code Duplication
			if ($row['link_banner'] && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $row['link_banner']))
234
			{
235
				$banner_img = $this->dir_helper->get_banner_path(basename($row['link_banner']));
236
237
				if (file_exists($banner_img))
238
				{
239
					@unlink($banner_img);
240
				}
241
			}
242
		}
243
244
		foreach ($link_datas_ary as $table => $field)
245
		{
246
			$this->db->sql_query("DELETE FROM $table WHERE ".$this->db->sql_in_set($field, $url_array));
247
		}
248
249
		$sql = 'UPDATE ' . DIR_CAT_TABLE . '
250
			SET cat_links = cat_links - '.sizeof($url_array).'
251
			WHERE cat_id = ' . (int) $cat_id;
252
		$this->db->sql_query($sql);
253
254
		$this->db->sql_transaction('commit');
255
256
		foreach ($url_array as $link_id)
257
		{
258
			$this->notification->delete_notifications(array(
259
				'ernadoo.phpbbdirectory.notification.type.directory_website',
260
				'ernadoo.phpbbdirectory.notification.type.directory_website_in_queue'
261
			), $link_id);
262
		}
263
264 View Code Duplication
		if ($this->request->is_ajax())
265
		{
266
			$sql = 'SELECT cat_links
267
				FROM ' . DIR_CAT_TABLE . '
268
				WHERE cat_id = ' . (int) $cat_id;
269
			$result = $this->db->sql_query($sql);
270
			$data = $this->db->sql_fetchrow($result);
271
272
			$json_response = new \phpbb\json_response;
273
			$json_response->send(array(
274
				'success' => true,
275
276
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
277
				'MESSAGE_TEXT'	=> $this->language->lang('DIR_DELETE_OK'),
278
				'LINK_ID'		=> $link_id,
279
				'TOTAL_LINKS'	=> $this->language->lang('DIR_NB_LINKS', (int) $data['cat_links']),
280
			));
281
		}
282
	}
283
284
	/**
285
	* Increments link view counter
286
	*
287
	* @param	int		$link_id	Link's id, for WHERE clause
288
	* @return	null
289
	* @throws	\phpbb\exception\http_exception
290
	*/
291
	public function view($link_id)
292
	{
293
		$sql = 'SELECT link_id, link_url
294
			FROM ' . DIR_LINK_TABLE . '
295
			WHERE link_id = ' . (int) $link_id;
296
		$result = $this->db->sql_query($sql);
297
		$data = $this->db->sql_fetchrow($result);
298
299
		if (empty($data['link_id']))
300
		{
301
			throw new \phpbb\exception\http_exception(404, 'DIR_ERROR_NO_LINKS');
302
		}
303
304
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
305
			SET link_view = link_view + 1
306
			WHERE link_id = ' . (int) $link_id;
307
		$this->db->sql_query($sql);
308
309
		redirect($data['link_url'], false, true);
310
		return;
311
	}
312
313
	/**
314
	* Verify that an URL exist before add into db
315
	*
316
	* @param	string	$url	The URL to check
317
	* @return	bool			True if url is reachable, else false.
318
	*/
319
	public function checkurl($url)
320
	{
321
		$details = parse_url($url);
322
323
		$default_port = 80;
324
		$hostname = $details['host'];
325
326
		if ($details['scheme'] == 'https')
327
		{
328
			$default_port = 443;
329
			$hostname = 'tls://' . $details['host'];
330
		}
331
332
		if (!isset($details['path']))
333
		{
334
			$details['path'] = '/';
335
		}
336
337
		$port = (isset($details['port']) && !empty($details['port'])) ? (int) $details['port'] : $default_port;
338
339
		if ($sock = @fsockopen($hostname, $port, $errno, $errstr, 1))
340
		{
341
			$requete = 'GET '.$details['path']." HTTP/1.1\r\n";
342
			$requete .= 'Host: '.$details['host']."\r\n\r\n";
343
344
			// Send a HTTP GET header
345
			fputs($sock, $requete);
346
			// answer from server
347
			$str = fgets($sock, 1024);
348
			preg_match("'HTTP/1\.. (.*) (.*)'U", $str, $parts);
349
			fclose($sock);
350
351
			return !($parts[1] == '404');
352
		}
353
		return false;
354
	}
355
356
	/**
357
	* Delete the final '/', if no path
358
	*
359
	* @param	string	$url	URL to clean
360
	* @return	string	$url	The correct string.
361
	*/
362
	public function clean_url($url)
363
	{
364
		$details = parse_url($url);
365
366
		if (isset($details['path']) && $details['path'] == '/' && !isset($details['query']))
367
		{
368
			return substr($url, 0, -1);
369
		}
370
		return $url;
371
	}
372
373
	/**
374
	* Display a flag
375
	*
376
	* @param	array	$data	Link's data from db
377
	* @return	string			Flag path.
378
	*/
379
	public function display_flag($data)
380
	{
381
		global $phpbb_extension_manager;
382
383
		$ext_path = $phpbb_extension_manager->get_extension_path('ernadoo/phpbbdirectory', false);
384
		$flag_path = $ext_path.'images/flags/';
385
		$img_flag = 'no_flag.png';
386
387
		if ($this->config['dir_activ_flag'] && !empty($data['link_flag']) && file_exists($flag_path . $data['link_flag']))
388
		{
389
			$img_flag = $data['link_flag'];
390
		}
391
392
		return $this->dir_helper->get_img_path('flags', $img_flag);
393
	}
394
395
	/**
396
	* Calculate the link's note
397
	*
398
	* @param	int		$total_note		Sum of all link's notes
399
	* @param	int		$nb_vote		Number of votes
400
	* @param	bool	$votes_status	Votes are enable in this category?
401
	* @return	string	$note			The calculated note.
402
	*/
403
	public function display_note($total_note, $nb_vote, $votes_status)
404
	{
405
		if (!$votes_status)
406
		{
407
			return;
408
		}
409
410
		$note = ($nb_vote < 1) ? '' : $total_note / $nb_vote;
411
		$note = (strlen($note) > 2) ? number_format($note, 1) : $note;
412
413
		return ($nb_vote) ? $this->language->lang('DIR_FROM_TEN', $note) : $this->language->lang('DIR_NO_NOTE');
414
	}
415
416
	/**
417
	* Display the vote form for auth users
418
	*
419
	* @param	array	$data	Link's data from db
420
	* @return	null|string		Html combo list or nothing if votes are not available.
421
	*/
422
	public function display_vote($data)
423
	{
424
		if ($this->user->data['is_registered'] && $this->auth->acl_get('u_vote_dir') && empty($data['vote_user_id']))
425
		{
426
			$list = '<select name="vote">';
427
			for ($i = 0; $i <= 10; $i++)
428
			{
429
				$list .= '<option value="' . $i . '"' . (($i == 5) ? ' selected="selected"' : '') . '>' . $i . '</option>';
430
			}
431
			$list .= '</select>';
432
433
			return $list;
434
		}
435
	}
436
437
	/**
438
	* Display the RSS icon
439
	*
440
	* @param	array	$data	Link's data from db
441
	* @return	null|string		RSS feed URL or nothing.
442
	*/
443
	public function display_rss($data)
444
	{
445
		if ($this->config['dir_activ_rss'] && !empty($data['link_rss']))
446
		{
447
				return $data['link_rss'];
448
		}
449
	}
450
451
	/**
452
	* Display link's thumb if thumb service enabled.
453
	* if thumb don't exists in db or if a new service was choosen in acp
454
	* thumb is research
455
	*
456
	* @param	array		$data	Link's data from db
457
	* @return	string|null			Thumb or null.
458
	*/
459
	public function display_thumb($data)
460
	{
461
		if ($this->config['dir_activ_thumb'])
462
		{
463
			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'])))))
464
			{
465
				$thumb = $this->thumb_process($data['link_url']);
466
467
				$sql = 'UPDATE ' . DIR_LINK_TABLE . '
468
					SET link_thumb = "' . $this->db->sql_escape($thumb) . '"
469
					WHERE link_id = ' . (int) $data['link_id'];
470
				$this->db->sql_query($sql);
471
472
				return $thumb;
473
			}
474
			return $data['link_thumb'];
475
		}
476
	}
477
478
	/**
479
	* Display and calculate PageRank if needed
480
	*
481
	* @param	array	$data	Link's data from db
482
	* @return	string			Pagerank, 'n/a' or false
483
	*/
484
	public function display_pagerank($data)
485
	{
486
		if ($this->config['dir_activ_pagerank'])
487
		{
488
			if ($data['link_pagerank'] == '')
489
			{
490
				$pagerank = $this->pagerank_process($data['link_url']);
491
492
				$sql = 'UPDATE ' . DIR_LINK_TABLE . '
493
					SET link_pagerank = ' . (int) $pagerank . '
494
					WHERE link_id = ' . (int) $data['link_id'];
495
				$this->db->sql_query($sql);
496
			}
497
			else
498
			{
499
				$pagerank = (int) $data['link_pagerank'];
500
			}
501
502
			$prpos=40*$pagerank/10;
503
			$prneg=40-$prpos;
504
			$html='<img src="http://www.google.com/images/pos.gif" width="'.$prpos.'" height="4" alt="'.$pagerank.'" /><img src="http://www.google.com/images/neg.gif" width="'.$prneg.'" height="4" alt="'.$pagerank.'" /> ';
505
506
			$pagerank = $pagerank == '-1' ? $this->language->lang('DIR_PAGERANK_NOT_AVAILABLE') : $this->language->lang('DIR_FROM_TEN', $pagerank);
507
			return $html.$pagerank;
508
		}
509
		return false;
510
	}
511
512
	/**
513
	* Display and resize a banner
514
	*
515
	* @param	array	$data		link's data from db
516
	* @return	string	$s_banner	html code.
517
	*/
518
	public function display_bann($data)
519
	{
520
		if (!empty($data['link_banner']))
521
		{
522
			if (!preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $data['link_banner']))
523
			{
524
				$img_src = $this->helper->route('ernadoo_phpbbdirectory_banner_controller', array('banner_img' => $data['link_banner']));
525
				$physical_path = $this->dir_helper->get_banner_path($data['link_banner']);
526
			}
527
			else
528
			{
529
				$img_src = $physical_path = $data['link_banner'];
530
			}
531
532
			if (($image_data = $this->imagesize->getImageSize($physical_path)) === false)
533
			{
534
				return '';
535
			}
536
537
			$width = $image_data['width'];
538
			$height = $image_data['height'];
539
540
			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)
541
			{
542
				$coef_w = $width / $this->config['dir_banner_width'];
543
				$coef_h = $height / $this->config['dir_banner_height'];
544
				$coef_max = max($coef_w, $coef_h);
545
				$width /= $coef_max;
546
				$height /= $coef_max;
547
			}
548
549
			return '<img src="' . $img_src . '" width="' . $width . '" height="' . $height . '" alt="'.$data['link_name'].'" title="'.$data['link_name'].'" />';
550
		}
551
		return '';
552
	}
553
554
	/**
555
	* Add a vote in db, for a specifi link
556
	*
557
	* @param	int		$link_id	Link_id from db
558
	* @return	null
559
	*/
560
	public function add_vote($link_id)
561
	{
562
		$data = array(
563
			'vote_link_id' 		=> (int) $link_id,
564
			'vote_user_id' 		=> $this->user->data['user_id'],
565
			'vote_note'			=> $this->request->variable('vote', 0),
566
		);
567
568
		$this->db->sql_transaction('begin');
569
570
		$sql = 'INSERT INTO ' . DIR_VOTE_TABLE . ' ' . $this->db->sql_build_array('INSERT', $data);
571
		$this->db->sql_query($sql);
572
573
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
574
			SET link_vote = link_vote + 1,
575
			link_note = link_note + ' . (int) $data['vote_note'] . '
576
		WHERE link_id = ' . (int) $link_id;
577
		$this->db->sql_query($sql);
578
579
		$this->db->sql_transaction('commit');
580
581
		if ($this->request->is_ajax())
582
		{
583
			$sql= 'SELECT link_vote, link_note FROM ' . DIR_LINK_TABLE . ' WHERE link_id = ' . (int) $link_id;
584
			$result = $this->db->sql_query($sql);
585
			$data = $this->db->sql_fetchrow($result);
586
587
			$note = $this->display_note($data['link_note'], $data['link_vote'], true);
588
589
			$json_response = new \phpbb\json_response;
590
			$json_response->send(array(
591
				'success' => true,
592
593
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
594
				'MESSAGE_TEXT'	=> $this->language->lang('DIR_VOTE_OK'),
595
				'NOTE'			=> $note,
596
				'NB_VOTE'		=> $this->language->lang('DIR_NB_VOTES', (int) $data['link_vote']),
597
				'LINK_ID'		=> $link_id
598
			));
599
		}
600
	}
601
602
	/**
603
	* Search an appropriate thumb for url
604
	*
605
	* @param	string	$url	Link's url
606
	* @return	string			The thumb url
607
	*/
608
	public function thumb_process($url)
609
	{
610
		if (!$this->config['dir_activ_thumb'])
611
		{
612
			return $this->root_path.'images/directory/nothumb.gif';
613
		}
614
615
		$details = parse_url($url);
616
617
		$root_url		= $details['scheme'].'://'.$details['host'];
618
		$absolute_url	= isset($details['path']) ? $root_url.$details['path'] : $root_url;
619
620
		if ($this->config['dir_activ_thumb_remote'] && $this->_ascreen_exist($details['scheme'], $details['host']))
621
		{
622
			return $root_url.'/ascreen.jpg';
623
		}
624
		return $this->config['dir_thumb_service'].$absolute_url;
625
	}
626
627
	/**
628
	* Check if ascreen thumb exists
629
	*
630
	* @param	string	$protocol	The protocol
631
	* @param	string	$host		The hostname
632
	* @return	bool				True if ascreen file exixts, else false
633
	*/
634
	private function _ascreen_exist($protocol, $host)
635
	{
636
		if (($thumb_info = $this->imagesize->getImageSize($protocol.'://'.$host.'/ascreen.jpg')) !== false)
637
		{
638
			// Obviously this is an image, we did some additional tests
639
			if ($thumb_info['width'] == '120' && $thumb_info['height'] == '90' && $thumb_info['type'] == 2)
640
			{
641
				return true;
642
			}
643
		}
644
		return false;
645
	}
646
647
	/**
648
	* Primary work on banner, can edit, copy or check a banner
649
	*
650
	* @param	string	$banner	The banner's remote url
651
	* @param	array	$error	The array error, passed by reference
652
	* @return	null
653
	*/
654
	public function banner_process(&$banner, &$error)
655
	{
656
		$old_banner = $this->request->variable('old_banner', '');
657
658
		$destination = $this->dir_helper->get_banner_path();
659
660
		// Can we upload?
661
		$can_upload = ($this->config['dir_storage_banner'] && $this->filesystem->exists($this->root_path . $destination) && $this->filesystem->is_writable($this->root_path . $destination) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
662
663
		if ($banner && $can_upload)
664
		{
665
			$file = $this->_banner_upload($banner, $error);
666
		}
667
		else if ($banner)
668
		{
669
			$file = $this->_banner_remote($banner, $error);
670
		}
671
		else if ($this->request->is_set_post('delete_banner') && $old_banner)
672
		{
673
			$this->_banner_delete($old_banner);
674
			return;
675
		}
676
677
		if (!sizeof($error))
678
		{
679
			if ($banner && $old_banner && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $old_banner))
680
			{
681
				$this->_banner_delete($old_banner);
682
			}
683
684
			$banner = !empty($file) ? $file : '';
685
		}
686
	}
687
688
	/**
689
	* Copy a remonte banner to server.
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_upload($banner, &$error)
697
	{
698
		/** @var \phpbb\files\upload $upload */
699
		$upload = $this->files_factory->get('upload')
700
			->set_error_prefix('DIR_BANNER_')
701
			->set_allowed_extensions(array('jpg', 'jpeg', 'gif', 'png'))
702
			->set_max_filesize($this->config['dir_banner_filesize'])
703
			->set_disallowed_content((isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false));
704
705
		$file = $upload->handle_upload('files.types.remote', $banner);
706
707
		$prefix = unique_id() . '_';
708
		$file->clean_filename('real', $prefix);
709
710
		if (sizeof($file->error))
711
		{
712
			$file->remove();
713
			$error = array_merge($error, $file->error);
714
			return false;
715
		}
716
717
		$destination = $this->dir_helper->get_banner_path();
718
719
		// Move file and overwrite any existing image
720
		$file->move_file($destination, true);
721
722
		return strtolower($file->get('realname'));
723
	}
724
725
	/**
726
	* Check than remote banner exists
727
	* called by banner_process()
728
	*
729
	* @param	string	$banner	The banner's remote url
730
	* @param	array	$error	The array error, passed by reference
731
	* @return	false|string	String if no errors, else false
732
	*/
733
	private function _banner_remote($banner, &$error)
734
	{
735
		if (!preg_match('#^(http|https|ftp)://#i', $banner))
736
		{
737
			$banner = 'http://' . $banner;
738
		}
739
		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))
740
		{
741
			$error[] = $this->language->lang('DIR_BANNER_URL_INVALID');
742
			return false;
743
		}
744
745
		// Get image dimensions
746
		if (($image_data = $this->imagesize->getImageSize($banner)) === false)
747
		{
748
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
749
			return false;
750
		}
751
752
		if (!empty($image_data) && ($image_data['width'] < 2 || $image_data['height'] < 2))
753
		{
754
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
755
			return false;
756
		}
757
758
		$width = $image_data['width'];
759
		$height = $image_data['height'];
760
761
		if ($width <= 0 || $height <= 0)
762
		{
763
			$error[] = $this->language->lang('DIR_BANNER_UNABLE_GET_IMAGE_SIZE');
764
			return false;
765
		}
766
767
		// Check image type
768
		$types		= \phpbb\files\upload::image_types();
769
		$extension	= strtolower(\phpbb\files\filespec::get_extension($banner));
770
771
		// Check if this is actually an image
772
		if ($file_stream = @fopen($banner, 'r'))
773
		{
774
			// Timeout after 1 second
775
			stream_set_timeout($file_stream, 1);
776
			// read some data to ensure headers are present
777
			fread($file_stream, 1024);
778
			$meta = stream_get_meta_data($file_stream);
779
			if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers']))
780
			{
781
				$headers = $meta['wrapper_data']['headers'];
782
			}
783
			else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data']))
784
			{
785
				$headers = $meta['wrapper_data'];
786
			}
787
			else
788
			{
789
				$headers = array();
790
			}
791
792
			foreach ($headers as $header)
793
			{
794
				$header = preg_split('/ /', $header, 2);
795
				if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type')
796
				{
797
					if (strpos($header[1], 'image/') !== 0)
798
					{
799
						$error[] = 'DIR_BANNER_URL_INVALID';
800
						fclose($file_stream);
801
						return false;
802
					}
803
					else
804
					{
805
						fclose($file_stream);
806
						break;
807
					}
808
				}
809
			}
810
		}
811
		else
812
		{
813
			$error[] = 'DIR_BANNER_URL_INVALID';
814
			return false;
815
		}
816
817
		if (!empty($image_data) && (!isset($types[$image_data['type']]) || !in_array($extension, $types[$image_data['type']])))
818
		{
819
			if (!isset($types[$image_data['type']]))
820
			{
821
				$error[] = $this->language->lang('UNABLE_GET_IMAGE_SIZE');
822
			}
823
			else
824
			{
825
				$error[] = $this->language->lang('DIR_BANNER_IMAGE_FILETYPE_MISMATCH', $types[$image_data['type']][0], $extension);
826
			}
827
			return false;
828
		}
829
830
		if (($this->config['dir_banner_width'] || $this->config['dir_banner_height']) && ($width > $this->config['dir_banner_width'] || $height > $this->config['dir_banner_height']))
831
		{
832
			$error[] = $this->language->lang('DIR_BANNER_WRONG_SIZE', $this->config['dir_banner_width'], $this->config['dir_banner_height'], $width, $height);
833
			return false;
834
		}
835
836
		return $banner;
837
	}
838
839
	/**
840
	* Delete a banner from server
841
	*
842
	* @param	string	$file	The file's name
843
	* @return	bool			True if delete success, else false
844
	*/
845
	private function _banner_delete($file)
846
	{
847
		if (file_exists($this->dir_helper->get_banner_path($file)))
848
		{
849
			@unlink($this->dir_helper->get_banner_path($file));
850
			return true;
851
		}
852
853
		return false;
854
	}
855
856
	/**
857
	* PageRank Lookup (Based on Google Toolbar for Mozilla Firefox)
858
	*
859
	* @copyright 2012 HM2K <[email protected]>
860
	* @link http://pagerank.phurix.net/
861
	* @author James Wade <[email protected]>
862
	* @version $Revision: 2.1 $
863
	* @require PHP 4.3.0 (file_get_contents)
864
	* @updated 06/10/11
865
	*
866
	* @param	string		$q	The website URL
867
	* @return	string			The calculated pagerank, or -1
868
	*/
869
	public function pagerank_process($q)
870
	{
871
		$googleDomains	= array('.com', '.com.tr', '.de', '.fr', '.be', '.ca', '.ro', '.ch');
872
		$seed			= $this->language->lang('SEED');
873
		$result			= 0x01020345;
874
		$len			= strlen($q);
875
876
		for ($i=0; $i<$len; $i++)
877
		{
878
			$result ^= ord($seed{$i%strlen($seed)}) ^ ord($q{$i});
879
			$result = (($result >> 23) & 0x1ff) | $result << 9;
880
		}
881
882
		if (PHP_INT_MAX != 2147483647)
883
		{
884
			$result = -(~($result & 0xFFFFFFFF) + 1);
885
		}
886
887
		$ch		= sprintf('8%x', $result);
888
		$url	= 'http://%s/tbr?client=navclient-auto&ch=%s&features=Rank&q=info:%s';
889
		$host	= 'toolbarqueries.google'.$googleDomains[mt_rand(0,count($googleDomains)-1)];
890
891
		$url	= sprintf($url,$host,$ch,$q);
892
		@$pr	= trim(file_get_contents($url,false));
893
894
		if (is_numeric(substr(strrchr($pr, ':'), 1)))
895
		{
896
			return substr(strrchr($pr, ':'), 1);
897
		}
898
		return '-1';
899
	}
900
901
	/**
902
	* List flags
903
	*
904
	* @param	string	$flag_path	The flag directory path
905
	* @param	string	$value		Selected flag
906
	* @return	string	$list		Html code
907
	*/
908
	public function get_dir_flag_list($flag_path, $value)
909
	{
910
		$list = '';
911
912
		$this->language->add_lang('directory_flags', 'ernadoo/phpbbdirectory');
913
914
		$flags = $this->dir_helper->preg_grep_keys('/^DIR_FLAG_CODE_/i', $this->language->get_lang_array());
915
916
		if (extension_loaded('intl'))
917
		{
918
			$locale = $this->language->lang('USER_LANG');
919
920
			$col = new \Collator($locale);
921
			$col->asort($flags);
922
		}
923
		else
924
		{
925
			asort($flags);
926
		}
927
928
		foreach ($flags as $file => $name)
929
		{
930
			$img_file = strtolower(substr(strrchr($file, '_'), 1)).'.png';
931
932
			if (file_exists($flag_path.$img_file))
933
			{
934
				$list .= '<option value="' . $img_file . '" ' . (($img_file == $value) ? 'selected="selected"' : '') . '>' . $name . '</option>';
935
			}
936
		}
937
938
		return $list;
939
	}
940
941
	/**
942
	* Display recents links added
943
	*
944
	* @return	null
945
	*/
946
	public function recents()
947
	{
948
		if ($this->config['dir_recent_block'])
949
		{
950
			$limit_sql		= $this->config['dir_recent_rows'] * $this->config['dir_recent_columns'];
951
			$exclude_array	= explode(',', str_replace(' ', '', $this->config['dir_recent_exclude']));
952
953
			$sql_array = array(
954
				'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',
955
				'FROM'		=> array(
956
						DIR_LINK_TABLE	=> 'l'),
957
				'LEFT_JOIN'	=> array(
958
						array(
959
							'FROM'	=> array(USERS_TABLE	=> 'u'),
960
							'ON'	=> 'l.link_user_id = u.user_id'
961
						),
962
						array(
963
							'FROM'	=> array(DIR_CAT_TABLE => 'c'),
964
							'ON'	=> 'l.link_cat = c.cat_id'
965
						)
966
				),
967
				'WHERE'		=> $this->db->sql_in_set('l.link_cat', $exclude_array, true).' AND l.link_active = 1',
968
				'ORDER_BY'	=> 'l.link_time DESC, l.link_id DESC');
969
970
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
971
			$result = $this->db->sql_query_limit($sql, $limit_sql, 0);
972
			$num = 0;
973
			$rowset = array();
974
975
			while ($site = $this->db->sql_fetchrow($result))
976
			{
977
				$rowset[$site['link_id']] = $site;
978
			}
979
			$this->db->sql_freeresult($result);
980
981
			if (sizeof($rowset))
982
			{
983
				$this->template->assign_block_vars('block', array(
984
					'S_COL_WIDTH'			=> (100 / $this->config['dir_recent_columns']) . '%',
985
				));
986
987
				foreach ($rowset as $row)
988
				{
989
					if (($num % $this->config['dir_recent_columns']) == 0)
990
					{
991
						$this->template->assign_block_vars('block.row', array());
992
					}
993
994
					$this->template->assign_block_vars('block.row.col', array(
995
						'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>',
996
						'NAME'                    => $row['link_name'],
997
						'USER'                    => get_username_string('full', $row['link_user_id'], $row['username'], $row['user_colour']),
998
						'TIME'                    => ($row['link_time']) ? $this->user->format_date($row['link_time']) : '',
999
						'CAT'                     => $row['cat_name'],
1000
						'COUNT'					  => $row['link_view'],
1001
						'COMMENT'                 => $row['link_comment'],
1002
1003
						'U_CAT'                   => $this->helper->route('ernadoo_phpbbdirectory_page_controller', array('cat_id' => (int) $row['link_cat'])),
1004
						'U_COMMENT'               => $this->helper->route('ernadoo_phpbbdirectory_comment_view_controller', array('link_id' => (int) $row['link_id'])),
1005
1006
						'L_DIR_SEARCH_NB_CLICKS'	=> $this->language->lang('DIR_SEARCH_NB_CLICKS', (int) $row['link_view']),
1007
						'L_DIR_SEARCH_NB_COMMS'		=> $this->language->lang('DIR_SEARCH_NB_COMMS', (int) $row['link_comment']),
1008
					));
1009
					$num++;
1010
				}
1011
1012
				while (($num % $this->config['dir_recent_columns']) != 0)
1013
				{
1014
					$this->template->assign_block_vars('block.row.col2', array());
1015
					$num++;
1016
				}
1017
			}
1018
		}
1019
	}
1020
1021
	/**
1022
	* Validate back link
1023
	*
1024
	* @param	string		$remote_url	Page URL contains the backlink
1025
	* @param	bool		$optional	Link back is optional in this category?
1026
	* @param	bool		$cron		This methos is called by con process?
1027
	* @return	false|string			Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1028
	*/
1029
	public function validate_link_back($remote_url, $optional, $cron = false)
1030
	{
1031
		if (!$cron)
1032
		{
1033
			if (empty($remote_url) && $optional)
1034
			{
1035
				return false;
1036
			}
1037
1038
			if (!preg_match('#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i', $remote_url))
1039
			{
1040
				return 'DIR_ERROR_WRONG_DATA_BACK';
1041
			}
1042
		}
1043
1044
		if (false === ($handle = @fopen($remote_url, 'r')))
1045
		{
1046
			return 'DIR_ERROR_NOT_FOUND_BACK';
1047
		}
1048
1049
		$buff = '';
1050
1051
		// Read by packet, faster than file_get_contents()
1052
		while (!feof($handle))
1053
		{
1054
			$buff .= fgets($handle, 256);
1055
1056
			if (stristr($buff, $this->config['server_name']))
1057
			{
1058
				@fclose($handle);
1059
				return false;
1060
			}
1061
		}
1062
		@fclose($handle);
1063
1064
		return 'DIR_ERROR_NO_LINK_BACK';
1065
	}
1066
1067
	/**
1068
	* Check, for website with backlink specified, if backlink is always here.
1069
	* After $nb_check verification, website is deleted, otherwise, a notification is send to poster
1070
	*
1071
	* @param	int		$cat_id		The categoryID
1072
	* @param	int		$nb_check	Number of check before demete a website
1073
	* @param	int		$next_prune	Date of next auto check
1074
	* @return	null
1075
	*/
1076
	private function _check($cat_id, $nb_check, $next_prune)
1077
	{
1078
		$del_array = $update_array = array();
1079
1080
		$sql_array = array(
1081
			'SELECT'	=> 'link_id, link_cat, link_back, link_guest_email, link_nb_check, link_user_id, link_name, link_url, link_description, u.user_lang, u.user_dateformat',
1082
			'FROM'		=> array(
1083
					DIR_LINK_TABLE	=> 'l'),
1084
			'LEFT_JOIN'	=> array(
1085
					array(
1086
						'FROM'	=> array(USERS_TABLE	=> 'u'),
1087
						'ON'	=> 'l.link_user_id = u.user_id'
1088
					)
1089
			),
1090
			'WHERE'		=> 'l.link_back <> "" AND l.link_active = 1 AND l.link_cat = '  . (int) $cat_id);
1091
1092
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
1093
		$result = $this->db->sql_query($sql);
1094
1095
		while ($row = $this->db->sql_fetchrow($result))
1096
		{
1097
			if ($this->validate_link_back($row['link_back'], false, true) !== false)
1098
			{
1099
				if (!$nb_check || ($row['link_nb_check']+1) >= $nb_check)
1100
				{
1101
					$del_array[] = $row['link_id'];
1102
				}
1103
				else
1104
				{
1105
					// A first table containing links ID to update
1106
					$update_array[$row['link_id']] = $row;
1107
				}
1108
			}
1109
		}
1110
		$this->db->sql_freeresult($result);
1111
1112
		if (sizeof($del_array))
1113
		{
1114
			$this->del($cat_id, $del_array);
1115
		}
1116
		if (sizeof($update_array))
1117
		{
1118
			$this->_update_check($update_array, $next_prune);
1119
		}
1120
	}
1121
1122
	/**
1123
	* Method called by cron task.
1124
	*
1125
	* @param	array	$cat_data	Information about category, from db
1126
	* @return	null
1127
	*/
1128
	public function auto_check($cat_data)
1129
	{
1130
		global $phpbb_log;
1131
1132
		$sql = 'SELECT cat_name
1133
			FROM ' . DIR_CAT_TABLE . '
1134
			WHERE cat_id = ' . (int) $cat_data['cat_id'];
1135
		$result = $this->db->sql_query($sql);
1136
		$row = $this->db->sql_fetchrow($result);
1137
		$this->db->sql_freeresult($result);
1138
1139
		if ($row)
1140
		{
1141
			$next_prune = time() + ($cat_data['cat_cron_freq'] * 86400);
1142
1143
			$this->_check($cat_data['cat_id'], $cat_data['cat_cron_nb_check'], $next_prune);
1144
1145
			$sql = 'UPDATE ' . DIR_CAT_TABLE . "
1146
				SET cat_cron_next = $next_prune
1147
				WHERE cat_id = " . (int) $cat_data['cat_id'];
1148
			$this->db->sql_query($sql);
1149
1150
			$phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_AUTO_PRUNE', time(), array($row['cat_name']));
1151
		}
1152
1153
		return;
1154
	}
1155
1156
	/**
1157
	* Update website verification number after a missing backlink, and send notificaton
1158
	*
1159
	* @param	array	$u_array	Information about website
1160
	* @param	int		$next_prune	Date of next auto check
1161
	* @return	null
1162
	*/
1163
	private function _update_check($u_array, $next_prune)
1164
	{
1165
		if (!class_exists('messenger'))
1166
		{
1167
			include($this->root_path . 'includes/functions_messenger.' . $this->php_ext);
1168
		}
1169
1170
		$messenger = new \messenger(false);
1171
1172
		// cron.php don't call $user->setup(), so $this->timezone is unset.
1173
		// We need to define it, because we use user->format_date below
1174
		$this->user->timezone = new \DateTimeZone($this->config['board_timezone']);
1175
1176
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
1177
			SET link_nb_check = link_nb_check + 1
1178
			WHERE ' . $this->db->sql_in_set('link_id', array_keys($u_array));
1179
		$this->db->sql_query($sql);
1180
1181
		foreach ($u_array as $data)
1182
		{
1183
			strip_bbcode($data['link_description']);
1184
1185
			$notification_data = array(
1186
					'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
1187
					'link_id'			=> $data['link_id'],
1188
					'link_user_id'		=> $data['link_user_id'],
1189
					'link_name'			=> $data['link_name'],
1190
					'link_url'			=> $data['link_url'],
1191
					'link_description'	=> $data['link_description'],
1192
					'next_cron' 		=> $this->user->format_date($next_prune, $data['user_dateformat']),
1193
			);
1194
1195
			if ($data['link_nb_check'])
1196
			{
1197
				$this->notification->delete_notifications('ernadoo.phpbbdirectory.notification.type.directory_website_error_cron', $notification_data);
1198
			}
1199
1200
			// New notification system can't send mail to an anonymous user with an email address stored in another table than phpbb_users
1201
			if ($data['link_user_id'] == ANONYMOUS)
1202
			{
1203
				$username = $email = $data['link_guest_email'];
1204
1205
				$messenger->template('@ernadoo_phpbbdirectory/directory_website_error_cron', $data['user_lang']);
1206
				$messenger->to($email, $username);
1207
1208
				$messenger->assign_vars(array(
1209
					'USERNAME'			=> htmlspecialchars_decode($username),
1210
					'LINK_NAME'			=> $data['link_name'],
1211
					'LINK_URL'			=> $data['link_url'],
1212
					'LINK_DESCRIPTION'	=> $data['link_description'],
1213
					'NEXT_CRON' 		=> $this->user->format_date($next_prune, $data['user_dateformat']),
1214
				));
1215
1216
				$messenger->send(NOTIFY_EMAIL);
1217
			}
1218
			else
1219
			{
1220
				$this->notification->add_notifications('ernadoo.phpbbdirectory.notification.type.directory_website_error_cron', $notification_data);
1221
			}
1222
		}
1223
	}
1224
}
1225