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