Completed
Push — master ( e866d6...19d1cc )
by Erwan
03:14
created

link::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 1
eloc 12
nc 1
nop 11

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