Completed
Push — master ( b05d49...46e7ff )
by Erwan
02:47
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
			return !($parts[1] == '404');
332
		}
333
		return false;
334
	}
335
336
	/**
337
	* Delete the final '/', if no path
338
	*
339
	* @param	string	$url	URL to clean
340
	* @return	string	$url	The correct string.
341
	*/
342
	public function clean_url($url)
343
	{
344
		$details = parse_url($url);
345
346
		if (isset($details['path']) && $details['path'] == '/' && !isset($details['query']))
347
		{
348
			return substr($url, 0, -1);
349
		}
350
		return $url;
351
	}
352
353
	/**
354
	* Display a flag
355
	*
356
	* @param	array	$data	Link's data from db
357
	* @return	string			Flag path.
358
	*/
359
	public function display_flag($data)
360
	{
361
		global $phpbb_extension_manager;
362
363
		$ext_path = $phpbb_extension_manager->get_extension_path('ernadoo/phpbbdirectory', false);
364
		$flag_path = $ext_path.'images/flags/';
365
		$img_flag = 'no_flag.png';
366
367
		if ($this->config['dir_activ_flag'] && !empty($data['link_flag']) && file_exists($flag_path . $data['link_flag']))
368
		{
369
			$img_flag = $data['link_flag'];
370
		}
371
372
		return $this->dir_helper->get_img_path('flags', $img_flag);
373
	}
374
375
	/**
376
	* Calculate the link's note
377
	*
378
	* @param	int		$total_note		Sum of all link's notes
379
	* @param	int		$nb_vote		Number of votes
380
	* @param	bool	$votes_status	Votes are enable in this category?
381
	* @return	string	$note			The calculated note.
382
	*/
383
	public function display_note($total_note, $nb_vote, $votes_status)
384
	{
385
		if (!$votes_status)
386
		{
387
			return;
388
		}
389
390
		$note = ($nb_vote < 1) ? '' : $total_note / $nb_vote;
391
		$note = (strlen($note) > 2) ? number_format($note, 1) : $note;
392
393
		return ($nb_vote) ? $this->user->lang('DIR_FROM_TEN', $note) : $this->user->lang['DIR_NO_NOTE'];
394
	}
395
396
	/**
397
	* Display the vote form for auth users
398
	*
399
	* @param	array	$data	Link's data from db
400
	* @return	null|string		Html combo list or nothing if votes are not available.
401
	*/
402
	public function display_vote($data)
403
	{
404
		if ($this->user->data['is_registered'] && $this->auth->acl_get('u_vote_dir') && empty($data['vote_user_id']))
405
		{
406
			$list = '<select name="vote">';
407
			for ($i = 0; $i <= 10; $i++)
408
			{
409
				$list .= '<option value="' . $i . '"' . (($i == 5) ? ' selected="selected"' : '') . '>' . $i . '</option>';
410
			}
411
			$list .= '</select>';
412
413
			return $list;
414
		}
415
	}
416
417
	/**
418
	* Display the RSS icon
419
	*
420
	* @param	array	$data	Link's data from db
421
	* @return	null|string		RSS feed URL or nothing.
422
	*/
423
	public function display_rss($data)
424
	{
425
		if ($this->config['dir_activ_rss'] && !empty($data['link_rss']))
426
		{
427
				return $data['link_rss'];
428
		}
429
	}
430
431
	/**
432
	* Display link's thumb if thumb service enabled.
433
	* if thumb don't exists in db or if a new service was choosen in acp
434
	* thumb is research
435
	*
436
	* @param	array		$data	Link's data from db
437
	* @return	string|null			Thumb or null.
438
	*/
439
	public function display_thumb($data)
440
	{
441
		if ($this->config['dir_activ_thumb'])
442
		{
443
			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'])))))
444
			{
445
				$thumb = $this->thumb_process($data['link_url']);
446
447
				$sql = 'UPDATE ' . DIR_LINK_TABLE . '
448
					SET link_thumb = "' . $this->db->sql_escape($thumb) . '"
449
					WHERE link_id = ' . (int) $data['link_id'];
450
				$this->db->sql_query($sql);
451
452
				return $thumb;
453
			}
454
			return $data['link_thumb'];
455
		}
456
	}
457
458
	/**
459
	* Display and calculate PageRank if needed
460
	*
461
	* @param	array	$data	Link's data from db
462
	* @return	string			Pagerank, 'n/a' or false
463
	*/
464
	public function display_pagerank($data)
465
	{
466
		if ($this->config['dir_activ_pagerank'])
467
		{
468
			if ($data['link_pagerank'] == '')
469
			{
470
				$pagerank = $this->pagerank_process($data['link_url']);
471
472
				$sql = 'UPDATE ' . DIR_LINK_TABLE . '
473
					SET link_pagerank = ' . (int) $pagerank . '
474
					WHERE link_id = ' . (int) $data['link_id'];
475
				$this->db->sql_query($sql);
476
			}
477
			else
478
			{
479
				$pagerank = (int) $data['link_pagerank'];
480
			}
481
482
			$prpos=40*$pagerank/10;
483
			$prneg=40-$prpos;
484
			$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.'" /> ';
485
486
			$pagerank = $pagerank == '-1' ? $this->user->lang['DIR_PAGERANK_NOT_AVAILABLE'] : $this->user->lang('DIR_FROM_TEN', $pagerank);
487
			return $html.$pagerank;
488
		}
489
		return false;
490
	}
491
492
	/**
493
	* Display and resize a banner
494
	*
495
	* @param	array	$data		link's data from db
496
	* @return	string	$s_banner	html code.
497
	*/
498
	public function display_bann($data)
499
	{
500
		$s_banner = '';
501
502
		if (!empty($data['link_banner']))
503
		{
504
			if (!preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $data['link_banner']))
505
			{
506
				$img_src = $this->helper->route('ernadoo_phpbbdirectory_banner_controller', array('banner_img' => $data['link_banner']));
507
				$physical_path = $this->dir_helper->get_banner_path($data['link_banner']);
508
			}
509
			else
510
			{
511
				$img_src = $physical_path = $data['link_banner'];
512
			}
513
514
			list($width, $height) = @getimagesize($physical_path);
515
			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)
516
			{
517
				$coef_w = $width / $this->config['dir_banner_width'];
518
				$coef_h = $height / $this->config['dir_banner_height'];
519
				$coef_max = max($coef_w, $coef_h);
520
				$width /= $coef_max;
521
				$height /= $coef_max;
522
			}
523
524
			$s_banner = '<img src="' . $img_src . '" width="' . $width . '" height="' . $height . '" alt="'.$data['link_name'].'" title="'.$data['link_name'].'" />';
525
		}
526
527
		return $s_banner;
528
	}
529
530
	/**
531
	* Add a vote in db, for a specifi link
532
	*
533
	* @param	int		$link_id	Link_id from db
534
	* @return	null
535
	*/
536
	public function add_vote($link_id)
537
	{
538
		$data = array(
539
			'vote_link_id' 		=> (int) $link_id,
540
			'vote_user_id' 		=> $this->user->data['user_id'],
541
			'vote_note'			=> $this->request->variable('vote', 0),
542
		);
543
544
		$this->db->sql_transaction('begin');
545
546
		$sql = 'INSERT INTO ' . DIR_VOTE_TABLE . ' ' . $this->db->sql_build_array('INSERT', $data);
547
		$this->db->sql_query($sql);
548
549
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
550
			SET link_vote = link_vote + 1,
551
			link_note = link_note + ' . (int) $data['vote_note'] . '
552
		WHERE link_id = ' . (int) $link_id;
553
		$this->db->sql_query($sql);
554
555
		$this->db->sql_transaction('commit');
556
557
		if ($this->request->is_ajax())
558
		{
559
			$sql= 'SELECT link_vote, link_note FROM ' . DIR_LINK_TABLE . ' WHERE link_id = ' . (int) $link_id;
560
			$result = $this->db->sql_query($sql);
561
			$data = $this->db->sql_fetchrow($result);
562
563
			$note = $this->display_note($data['link_note'], $data['link_vote'], true);
564
565
			$json_response = new \phpbb\json_response;
566
			$json_response->send(array(
567
				'success' => true,
568
569
				'MESSAGE_TITLE'	=> $this->user->lang['INFORMATION'],
570
				'MESSAGE_TEXT'	=> $this->user->lang['DIR_VOTE_OK'],
571
				'NOTE'			=> $note,
572
				'NB_VOTE'		=> $this->user->lang('DIR_NB_VOTES', (int) $data['link_vote']),
573
				'LINK_ID'		=> $link_id
574
			));
575
		}
576
	}
577
578
	/**
579
	* Search an appropriate thumb for url
580
	*
581
	* @param	string	$url	Link's url
582
	* @return	string			The thumb url
583
	*/
584
	public function thumb_process($url)
585
	{
586
		if (!$this->config['dir_activ_thumb'])
587
		{
588
			return $this->root_path.'images/directory/nothumb.gif';
589
		}
590
591
		$details = parse_url($url);
592
593
		$root_url		= $details['scheme'].'://'.$details['host'];
594
		$absolute_url	= isset($details['path']) ? $root_url.$details['path'] : $root_url;
595
596
		if ($this->config['dir_activ_thumb_remote'] && $this->_ascreen_exist($details['scheme'], $details['host']))
597
		{
598
			return $root_url.'/ascreen.jpg';
599
		}
600
		return $this->config['dir_thumb_service'].$absolute_url;
601
	}
602
603
	/**
604
	* Check if ascreen thumb exists
605
	*
606
	* @param	string	$protocol	The protocol
607
	* @param	string	$host		The hostname
608
	* @return	bool				True if ascreen file exixts, else false
609
	*/
610
	private function _ascreen_exist($protocol, $host)
611
	{
612
		if ($thumb_info = @getimagesize($protocol.'://'.$host.'/ascreen.jpg'))
613
		{
614
			// Obviously this is an image, we did some additional tests
615
			if ($thumb_info[0] == '120' && $thumb_info[1] == '90' && $thumb_info['mime'] == 'image/jpeg')
616
			{
617
				return true;
618
			}
619
		}
620
		return false;
621
	}
622
623
	/**
624
	* Primary work on banner, can edit, copy or check a banner
625
	*
626
	* @param	string	$banner	The banner's remote url
627
	* @param	array	$error	The array error, passed by reference
628
	* @return	null
629
	*/
630
	public function banner_process(&$banner, &$error)
631
	{
632
		$old_banner = $this->request->variable('old_banner', '');
633
634
		$destination = $this->dir_helper->get_banner_path();
635
636
		// Can we upload?
637
		$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;
638
639
		if ($banner && $can_upload)
640
		{
641
			$file = $this->_banner_upload($banner, $error);
642
		}
643
		else if ($banner)
644
		{
645
			$file = $this->_banner_remote($banner, $error);
646
		}
647
		else if ($this->request->is_set_post('delete_banner') && $old_banner)
648
		{
649
			$this->_banner_delete($old_banner);
650
			return;
651
		}
652
653
		if (!sizeof($error))
654
		{
655
			if ($banner && $old_banner && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $old_banner))
656
			{
657
				$this->_banner_delete($old_banner);
658
			}
659
660
			$banner = !empty($file) ? $file : '';
661
		}
662
	}
663
664
	/**
665
	* Copy a remonte banner to server.
666
	* called by banner_process()
667
	*
668
	* @param	string	$banner The anner's remote url
669
	* @param	array	$error	The array error, passed by reference
670
	* @return	false|string	String if no errors, else false
671
	*/
672
	private function _banner_upload($banner, &$error)
673
	{
674
		// Init upload class
675
		if (!class_exists('fileupload'))
676
		{
677
			include($this->root_path . 'includes/functions_upload.' . $this->php_ext);
678
		}
679
		$upload = new \fileupload('DIR_BANNER_', array('jpg', 'jpeg', 'gif', 'png'), $this->config['dir_banner_filesize']);
680
681
		$file = $upload->remote_upload($banner);
682
683
		$prefix = unique_id() . '_';
684
		$file->clean_filename('real', $prefix);
685
686
		$destination = $this->dir_helper->get_banner_path();
687
688
		// Move file and overwrite any existing image
689
		$file->move_file($destination, true);
690
691
		if (sizeof($file->error))
692
		{
693
			$file->remove();
694
			$error = array_merge($error, $file->error);
695
			return false;
696
		}
697
698
		return $prefix .strtolower($file->uploadname);
699
	}
700
701
	/**
702
	* Check than remote banner exists
703
	* called by banner_process()
704
	*
705
	* @param	string	$banner	The banner's remote url
706
	* @param	array	$error	The array error, passed by reference
707
	* @return	false|string	String if no errors, else false
708
	*/
709
	private function _banner_remote($banner, &$error)
710
	{
711
		if (!preg_match('#^(http|https|ftp)://#i', $banner))
712
		{
713
			$banner = 'http://' . $banner;
714
		}
715
		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))
716
		{
717
			$error[] = $this->user->lang['DIR_BANNER_URL_INVALID'];
718
			return false;
719
		}
720
721
		// Make sure getimagesize works...
722
		if (($image_data = @getimagesize($banner)) === false)
723
		{
724
			$error[] = $this->user->lang['DIR_BANNER_UNABLE_GET_IMAGE_SIZE'];
725
			return false;
726
		}
727
728
		if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2))
729
		{
730
			$error[] = $this->user->lang['DIR_BANNER_UNABLE_GET_IMAGE_SIZE'];
731
			return false;
732
		}
733
734
		$width = $image_data[0];
735
		$height = $image_data[1];
736
737
		// Check image type
738
		if (!class_exists('fileupload'))
739
		{
740
			include($this->root_path . 'includes/functions_upload.' . $this->php_ext);
741
		}
742
743
		$types		= \fileupload::image_types();
744
		$extension	= strtolower(\filespec::get_extension($banner));
745
746
		// Check if this is actually an image
747
		if ($file_stream = @fopen($banner, 'r'))
748
		{
749
			// Timeout after 1 second
750
			stream_set_timeout($file_stream, 1);
751
			// read some data to ensure headers are present
752
			fread($file_stream, 1024);
753
			$meta = stream_get_meta_data($file_stream);
754
			if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers']))
755
			{
756
				$headers = $meta['wrapper_data']['headers'];
757
			}
758
			else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data']))
759
			{
760
				$headers = $meta['wrapper_data'];
761
			}
762
			else
763
			{
764
				$headers = array();
765
			}
766
767
			foreach ($headers as $header)
768
			{
769
				$header = preg_split('/ /', $header, 2);
770
				if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type')
771
				{
772
					if (strpos($header[1], 'image/') !== 0)
773
					{
774
						$error[] = 'DIR_BANNER_URL_INVALID';
775
						fclose($file_stream);
776
						return false;
777
					}
778
					else
779
					{
780
						fclose($file_stream);
781
						break;
782
					}
783
				}
784
			}
785
		}
786
		else
787
		{
788
			$error[] = 'DIR_BANNER_URL_INVALID';
789
			return false;
790
		}
791
792
		if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])))
793
		{
794
			if (!isset($types[$image_data[2]]))
795
			{
796
				$error[] = $this->user->lang['UNABLE_GET_IMAGE_SIZE'];
797
			}
798
			else
799
			{
800
				$error[] = $this->user->lang('DIR_BANNER_IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension);
801
			}
802
			return false;
803
		}
804
805
		if (($this->config['dir_banner_width'] || $this->config['dir_banner_height']) && ($width > $this->config['dir_banner_width'] || $height > $this->config['dir_banner_height']))
806
		{
807
			$error[] = $this->user->lang('DIR_BANNER_WRONG_SIZE', $this->config['dir_banner_width'], $this->config['dir_banner_height'], $width, $height);
808
			return false;
809
		}
810
811
		return $banner;
812
	}
813
814
	/**
815
	* Delete a banner from server
816
	*
817
	* @param	string	$file	The file's name
818
	* @return	bool			True if delete success, else false
819
	*/
820
	private function _banner_delete($file)
821
	{
822
		if (file_exists($this->dir_helper->get_banner_path($file)))
823
		{
824
			@unlink($this->dir_helper->get_banner_path($file));
825
			return true;
826
		}
827
828
		return false;
829
	}
830
831
	/**
832
	* PageRank Lookup (Based on Google Toolbar for Mozilla Firefox)
833
	*
834
	* @copyright 2012 HM2K <[email protected]>
835
	* @link http://pagerank.phurix.net/
836
	* @author James Wade <[email protected]>
837
	* @version $Revision: 2.1 $
838
	* @require PHP 4.3.0 (file_get_contents)
839
	* @updated 06/10/11
840
	*
841
	* @param	string		$q	The website URL
842
	* @return	string			The calculated pagerank, or -1
843
	*/
844
	public function pagerank_process($q)
845
	{
846
		$googleDomains	= array('.com', '.com.tr', '.de', '.fr', '.be', '.ca', '.ro', '.ch');
847
		$seed			= $this->user->lang['SEED'];
848
		$result			= 0x01020345;
849
		$len			= strlen($q);
850
851
		for ($i=0; $i<$len; $i++)
852
		{
853
			$result ^= ord($seed{$i%strlen($seed)}) ^ ord($q{$i});
854
			$result = (($result >> 23) & 0x1ff) | $result << 9;
855
		}
856
857
		if (PHP_INT_MAX != 2147483647)
858
		{
859
			$result = -(~($result & 0xFFFFFFFF) + 1);
860
		}
861
862
		$ch		= sprintf('8%x', $result);
863
		$url	= 'http://%s/tbr?client=navclient-auto&ch=%s&features=Rank&q=info:%s';
864
		$host	= 'toolbarqueries.google'.$googleDomains[mt_rand(0,count($googleDomains)-1)];
865
866
		$url	= sprintf($url,$host,$ch,$q);
867
		@$pr	= trim(file_get_contents($url,false));
868
869
		if (is_numeric(substr(strrchr($pr, ':'), 1)))
870
		{
871
			return substr(strrchr($pr, ':'), 1);
872
		}
873
		return '-1';
874
	}
875
876
	/**
877
	* List flags
878
	*
879
	* @param	string	$flag_path	The flag directory path
880
	* @param	string	$value		Selected flag
881
	* @return	string	$list		Html code
882
	*/
883
	public function get_dir_flag_list($flag_path, $value)
884
	{
885
		$list = '';
886
887
		$this->user->add_lang_ext('ernadoo/phpbbdirectory', 'directory_flags');
888
889
		$flags = $this->dir_helper->preg_grep_keys('/^DIR_FLAG_CODE_/i', $this->user->lang);
890
891
		if (extension_loaded('intl'))
892
		{
893
			$locale = $this->user->lang['USER_LANG'];
894
895
			$col = new \Collator($locale);
896
			$col->asort($flags);
897
		}
898
		else
899
		{
900
			asort($flags);
901
		}
902
903
		foreach ($flags as $file => $name)
904
		{
905
			$img_file = strtolower(substr(strrchr($file, '_'), 1)).'.png';
906
907
			if (file_exists($flag_path.$img_file))
908
			{
909
				$list .= '<option value="' . $img_file . '" ' . (($img_file == $value) ? 'selected="selected"' : '') . '>' . $name . '</option>';
910
			}
911
		}
912
913
		return $list;
914
	}
915
916
	/**
917
	* Display recents links added
918
	*
919
	* @return	null
920
	*/
921
	public function recents()
922
	{
923
		if ($this->config['dir_recent_block'])
924
		{
925
			$limit_sql		= $this->config['dir_recent_rows'] * $this->config['dir_recent_columns'];
926
			$exclude_array	= explode(',', str_replace(' ', '', $this->config['dir_recent_exclude']));
927
928
			$sql_array = array(
929
				'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',
930
				'FROM'		=> array(
931
						DIR_LINK_TABLE	=> 'l'),
932
				'LEFT_JOIN'	=> array(
933
						array(
934
							'FROM'	=> array(USERS_TABLE	=> 'u'),
935
							'ON'	=> 'l.link_user_id = u.user_id'
936
						),
937
						array(
938
							'FROM'	=> array(DIR_CAT_TABLE => 'c'),
939
							'ON'	=> 'l.link_cat = c.cat_id'
940
						)
941
				),
942
				'WHERE'		=> $this->db->sql_in_set('l.link_cat', $exclude_array, true).' AND l.link_active = 1',
943
				'ORDER_BY'	=> 'l.link_time DESC, l.link_id DESC');
944
945
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
946
			$result = $this->db->sql_query_limit($sql, $limit_sql, 0);
947
			$num = 0;
948
			$rowset = array();
949
950
			while ($site = $this->db->sql_fetchrow($result))
951
			{
952
				$rowset[$site['link_id']] = $site;
953
			}
954
			$this->db->sql_freeresult($result);
955
956
			if (sizeof($rowset))
957
			{
958
				$this->template->assign_block_vars('block', array(
959
					'S_COL_WIDTH'			=> (100 / $this->config['dir_recent_columns']) . '%',
960
				));
961
962
				foreach ($rowset as $row)
963
				{
964
					if (($num % $this->config['dir_recent_columns']) == 0)
965
					{
966
						$this->template->assign_block_vars('block.row', array());
967
					}
968
969
					$this->template->assign_block_vars('block.row.col', array(
970
						'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>',
971
						'NAME'                    => $row['link_name'],
972
						'USER'                    => get_username_string('full', $row['link_user_id'], $row['username'], $row['user_colour']),
973
						'TIME'                    => ($row['link_time']) ? $this->user->format_date($row['link_time']) : '',
974
						'CAT'                     => $row['cat_name'],
975
						'COUNT'					  => $row['link_view'],
976
						'COMMENT'                 => $row['link_comment'],
977
978
						'U_CAT'                   => $this->helper->route('ernadoo_phpbbdirectory_page_controller', array('cat_id' => (int) $row['link_cat'])),
979
						'U_COMMENT'               => $this->helper->route('ernadoo_phpbbdirectory_comment_view_controller', array('link_id' => (int) $row['link_id'])),
980
981
						'L_DIR_SEARCH_NB_CLICKS'	=> $this->user->lang('DIR_SEARCH_NB_CLICKS', (int) $row['link_view']),
982
						'L_DIR_SEARCH_NB_COMMS'		=> $this->user->lang('DIR_SEARCH_NB_COMMS', (int) $row['link_comment']),
983
					));
984
					$num++;
985
				}
986
987
				while (($num % $this->config['dir_recent_columns']) != 0)
988
				{
989
					$this->template->assign_block_vars('block.row.col2', array());
990
					$num++;
991
				}
992
			}
993
		}
994
	}
995
996
	/**
997
	* Validate back link
998
	*
999
	* @param	string		$remote_url	Page URL contains the backlink
1000
	* @param	bool		$optional	Link back is optional in this category?
1001
	* @param	bool		$cron		This methos is called by con process?
1002
	* @return	false|string			Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1003
	*/
1004
	public function validate_link_back($remote_url, $optional, $cron = false)
1005
	{
1006
		if (!$cron)
1007
		{
1008
			if (empty($remote_url) && $optional)
1009
			{
1010
				return false;
1011
			}
1012
1013
			if (!preg_match('#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i', $remote_url))
1014
			{
1015
				return 'DIR_ERROR_WRONG_DATA_BACK';
1016
			}
1017
		}
1018
1019
		if (false === ($handle = @fopen($remote_url, 'r')))
1020
		{
1021
			return 'DIR_ERROR_NOT_FOUND_BACK';
1022
		}
1023
1024
		$buff = '';
1025
1026
		// Read by packet, faster than file_get_contents()
1027
		while (!feof($handle))
1028
		{
1029
			$buff .= fgets($handle, 256);
1030
1031
			if (stristr($buff, $this->config['server_name']))
1032
			{
1033
				@fclose($handle);
1034
				return false;
1035
			}
1036
		}
1037
		@fclose($handle);
1038
1039
		return 'DIR_ERROR_NO_LINK_BACK';
1040
	}
1041
1042
	/**
1043
	* Check, for website with backlink specified, if backlink is always here.
1044
	* After $nb_check verification, website is deleted, otherwise, a notification is send to poster
1045
	*
1046
	* @param	int		$cat_id		The categoryID
1047
	* @param	int		$nb_check	Number of check before demete a website
1048
	* @param	int		$next_prune	Date of next auto check
1049
	* @return	null
1050
	*/
1051
	private function _check($cat_id, $nb_check, $next_prune)
1052
	{
1053
		$del_array = $update_array = array();
1054
1055
		$sql_array = array(
1056
			'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',
1057
			'FROM'		=> array(
1058
					DIR_LINK_TABLE	=> 'l'),
1059
			'LEFT_JOIN'	=> array(
1060
					array(
1061
						'FROM'	=> array(USERS_TABLE	=> 'u'),
1062
						'ON'	=> 'l.link_user_id = u.user_id'
1063
					)
1064
			),
1065
			'WHERE'		=> 'l.link_back <> "" AND l.link_active = 1 AND l.link_cat = '  . (int) $cat_id);
1066
1067
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
1068
		$result = $this->db->sql_query($sql);
1069
1070
		while ($row = $this->db->sql_fetchrow($result))
1071
		{
1072
			if ($this->validate_link_back($row['link_back'], false, true) !== false)
1073
			{
1074
				if (!$nb_check || ($row['link_nb_check']+1) >= $nb_check)
1075
				{
1076
					$del_array[] = $row['link_id'];
1077
				}
1078
				else
1079
				{
1080
					// A first table containing links ID to update
1081
					$update_array[$row['link_id']] = $row;
1082
				}
1083
			}
1084
		}
1085
		$this->db->sql_freeresult($result);
1086
1087
		if (sizeof($del_array))
1088
		{
1089
			$this->del($cat_id, $del_array);
1090
		}
1091
		if (sizeof($update_array))
1092
		{
1093
			$this->_update_check($update_array, $next_prune);
1094
		}
1095
	}
1096
1097
	/**
1098
	* Method called by cron task.
1099
	*
1100
	* @param	array	$cat_data	Information about category, from db
1101
	* @return	null
1102
	*/
1103
	public function auto_check($cat_data)
1104
	{
1105
		global $phpbb_log;
1106
1107
		$sql = 'SELECT cat_name
1108
			FROM ' . DIR_CAT_TABLE . '
1109
			WHERE cat_id = ' . (int) $cat_data['cat_id'];
1110
		$result = $this->db->sql_query($sql);
1111
		$row = $this->db->sql_fetchrow($result);
1112
		$this->db->sql_freeresult($result);
1113
1114
		if ($row)
1115
		{
1116
			$next_prune = time() + ($cat_data['cat_cron_freq'] * 86400);
1117
1118
			$this->_check($cat_data['cat_id'], $cat_data['cat_cron_nb_check'], $next_prune);
1119
1120
			$sql = 'UPDATE ' . DIR_CAT_TABLE . "
1121
				SET cat_cron_next = $next_prune
1122
				WHERE cat_id = " . (int) $cat_data['cat_id'];
1123
			$this->db->sql_query($sql);
1124
1125
			$phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_AUTO_PRUNE', time(), array($row['cat_name']));
1126
		}
1127
1128
		return;
1129
	}
1130
1131
	/**
1132
	* Update website verification number after a missing backlink, and send notificaton
1133
	*
1134
	* @param	array	$u_array	Information about website
1135
	* @param	int		$next_prune	Date of next auto check
1136
	* @return	null
1137
	*/
1138
	private function _update_check($u_array, $next_prune)
1139
	{
1140
		if (!class_exists('messenger'))
1141
		{
1142
			include($this->root_path . 'includes/functions_messenger.' . $this->php_ext);
1143
		}
1144
1145
		$messenger = new \messenger(false);
1146
1147
		// cron.php don't call $user->setup(), so $this->timezone is unset.
1148
		// We need to define it, because we use user->format_date below
1149
		$this->user->timezone = new \DateTimeZone($this->config['board_timezone']);
1150
1151
		$sql = 'UPDATE ' . DIR_LINK_TABLE . '
1152
			SET link_nb_check = link_nb_check + 1
1153
			WHERE ' . $this->db->sql_in_set('link_id', array_keys($u_array));
1154
		$this->db->sql_query($sql);
1155
1156
		foreach ($u_array as $data)
1157
		{
1158
			strip_bbcode($data['link_description']);
1159
1160
			$notification_data = array(
1161
					'cat_name'			=> \ernadoo\phpbbdirectory\core\categorie::getname((int) $data['link_cat']),
1162
					'link_id'			=> $data['link_id'],
1163
					'link_name'			=> $data['link_name'],
1164
					'link_url'			=> $data['link_url'],
1165
					'link_description'	=> $data['link_description'],
1166
					'next_cron' 		=> $this->user->format_date($next_prune, $data['user_dateformat']),
1167
			);
1168
1169
			if ($data['link_nb_check'])
1170
			{
1171
				$this->notification->delete_notifications('ernadoo.phpbbdirectory.notification.type.directory_website_error_cron', $notification_data);
1172
			}
1173
1174
			// New notification system can't send mail to an anonymous user with an email address stored in another table than phpbb_users
1175
			if ($data['link_user_id'] == ANONYMOUS)
1176
			{
1177
				$username = $email = $data['link_guest_email'];
1178
1179
				$messenger->template('@ernadoo_phpbbdirectory/directory_website_error_cron', $data['user_lang']);
1180
				$messenger->to($email, $username);
1181
1182
				$messenger->assign_vars(array(
1183
					'USERNAME'			=> htmlspecialchars_decode($username),
1184
					'LINK_NAME'			=> $data['link_name'],
1185
					'LINK_URL'			=> $data['link_url'],
1186
					'LINK_DESCRIPTION'	=> $data['link_description'],
1187
					'NEXT_CRON' 		=> $this->user->format_date($next_prune, $data['user_dateformat']),
1188
				));
1189
1190
				$messenger->send(NOTIFY_EMAIL);
1191
			}
1192
			else
1193
			{
1194
				$this->notification->add_notifications('ernadoo.phpbbdirectory.notification.type.directory_website_error_cron', $notification_data);
1195
			}
1196
		}
1197
	}
1198
}
1199