Completed
Push — 3.3.x ( 74c83f...d2eb4d )
by Erwan
02:36
created

link::auto_check()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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