[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 namespace phpbb\module; 15 16 use phpbb\module\exception\module_exception; 17 use phpbb\module\exception\module_not_found_exception; 18 19 class module_manager 20 { 21 /** 22 * @var \phpbb\cache\driver\driver_interface 23 */ 24 protected $cache; 25 26 /** 27 * @var \phpbb\db\driver\driver_interface 28 */ 29 protected $db; 30 31 /** 32 * @var \phpbb\extension\manager 33 */ 34 protected $extension_manager; 35 36 /** 37 * @var string 38 */ 39 protected $modules_table; 40 41 /** 42 * @var string 43 */ 44 protected $phpbb_root_path; 45 46 /** 47 * @var string 48 */ 49 protected $php_ext; 50 51 /** 52 * Constructor 53 * 54 * @param \phpbb\cache\driver\driver_interface $cache Cache driver 55 * @param \phpbb\db\driver\driver_interface $db Database driver 56 * @param \phpbb\extension\manager $ext_manager Extension manager 57 * @param string $modules_table Module database table's name 58 * @param string $phpbb_root_path Path to phpBB's root 59 * @param string $php_ext Extension of PHP files 60 */ 61 public function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\extension\manager $ext_manager, $modules_table, $phpbb_root_path, $php_ext) 62 { 63 $this->cache = $cache; 64 $this->db = $db; 65 $this->extension_manager = $ext_manager; 66 $this->modules_table = $modules_table; 67 $this->phpbb_root_path = $phpbb_root_path; 68 $this->php_ext = $php_ext; 69 } 70 71 /** 72 * Get row for specified module 73 * 74 * @param int $module_id ID of the module 75 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 76 * 77 * @return array Array of data fetched from the database 78 * 79 * @throws \phpbb\module\exception\module_not_found_exception When there is no module with $module_id 80 */ 81 public function get_module_row($module_id, $module_class) 82 { 83 $module_id = (int) $module_id; 84 85 $sql = 'SELECT * 86 FROM ' . $this->modules_table . " 87 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 88 AND module_id = $module_id"; 89 $result = $this->db->sql_query($sql); 90 $row = $this->db->sql_fetchrow($result); 91 $this->db->sql_freeresult($result); 92 93 if (!$row) 94 { 95 throw new module_not_found_exception('NO_MODULE'); 96 } 97 98 return $row; 99 } 100 101 /** 102 * Get available module information from module files 103 * 104 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 105 * @param string $module ID of module 106 * @param bool $use_all_available Use all available instead of just all 107 * enabled extensions 108 * 109 * @return array Array with module information gathered from module info files. 110 */ 111 public function get_module_infos($module_class, $module = '', $use_all_available = false) 112 { 113 $directory = $this->phpbb_root_path . 'includes/' . $module_class . '/info/'; 114 $fileinfo = array(); 115 116 $finder = $this->extension_manager->get_finder($use_all_available); 117 118 $modules = $finder 119 ->extension_suffix('_module') 120 ->extension_directory("/$module_class") 121 ->core_path("includes/$module_class/info/") 122 ->core_prefix($module_class . '_') 123 ->get_classes(true); 124 125 foreach ($modules as $cur_module) 126 { 127 // Skip entries we do not need if we know the module we are 128 // looking for 129 if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module) 130 { 131 continue; 132 } 133 134 $info_class = preg_replace('/_module$/', '_info', $cur_module); 135 136 // If the class does not exist it might be following the old 137 // format. phpbb_acp_info_acp_foo needs to be turned into 138 // acp_foo_info and the respective file has to be included 139 // manually because it does not support auto loading 140 $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module); 141 $old_info_class = $old_info_class_file . '_info'; 142 143 if (class_exists($old_info_class)) 144 { 145 $info_class = $old_info_class; 146 } 147 else if (!class_exists($info_class)) 148 { 149 $info_class = $old_info_class; 150 151 // need to check class exists again because previous checks triggered autoloading 152 if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $this->php_ext)) 153 { 154 include($directory . $old_info_class_file . '.' . $this->php_ext); 155 } 156 } 157 158 if (class_exists($info_class)) 159 { 160 $info = new $info_class(); 161 $module_info = $info->module(); 162 163 $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module; 164 165 $fileinfo[$main_class] = $module_info; 166 } 167 } 168 169 ksort($fileinfo); 170 171 return $fileinfo; 172 } 173 174 /** 175 * Get module branch 176 * 177 * @param int $module_id ID of the module 178 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 179 * @param string $type Type of branch (Expected values: all, parents or children) 180 * @param bool $include_module Whether or not to include the specified module with $module_id 181 * 182 * @return array Returns an array containing the modules in the specified branch type. 183 */ 184 public function get_module_branch($module_id, $module_class, $type = 'all', $include_module = true) 185 { 186 $module_id = (int) $module_id; 187 188 switch ($type) 189 { 190 case 'parents': 191 $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id'; 192 break; 193 194 case 'children': 195 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id'; 196 break; 197 198 default: 199 $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id'; 200 break; 201 } 202 203 $rows = array(); 204 205 $sql = 'SELECT m2.* 206 FROM ' . $this->modules_table . ' m1 207 LEFT JOIN ' . $this->modules_table . " m2 ON ($condition) 208 WHERE m1.module_class = '" . $this->db->sql_escape($module_class) . "' 209 AND m2.module_class = '" . $this->db->sql_escape($module_class) . "' 210 AND m1.module_id = $module_id 211 ORDER BY m2.left_id"; 212 $result = $this->db->sql_query($sql); 213 214 while ($row = $this->db->sql_fetchrow($result)) 215 { 216 if (!$include_module && $row['module_id'] == $module_id) 217 { 218 continue; 219 } 220 221 $rows[] = $row; 222 } 223 $this->db->sql_freeresult($result); 224 225 return $rows; 226 } 227 228 /** 229 * Remove modules cache file 230 * 231 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 232 */ 233 public function remove_cache_file($module_class) 234 { 235 // Sanitise for future path use, it's escaped as appropriate for queries 236 $cache_class = str_replace(array('.', '/', '\\'), '', basename($module_class)); 237 $this->cache->destroy('_modules_' . $cache_class); 238 $this->cache->destroy('sql', $this->modules_table); 239 } 240 241 /** 242 * Update/Add module 243 * 244 * @param array &$module_data The module data 245 * 246 * @throws \phpbb\module\exception\module_not_found_exception When parent module or the category is not exist 247 */ 248 public function update_module_data(&$module_data) 249 { 250 if (!isset($module_data['module_id'])) 251 { 252 // no module_id means we're creating a new category/module 253 if ($module_data['parent_id']) 254 { 255 $sql = 'SELECT left_id, right_id 256 FROM ' . $this->modules_table . " 257 WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "' 258 AND module_id = " . (int) $module_data['parent_id']; 259 $result = $this->db->sql_query($sql); 260 $row = $this->db->sql_fetchrow($result); 261 $this->db->sql_freeresult($result); 262 263 if (!$row) 264 { 265 throw new module_not_found_exception('PARENT_NOT_EXIST'); 266 } 267 268 // Workaround 269 $row['left_id'] = (int) $row['left_id']; 270 $row['right_id'] = (int) $row['right_id']; 271 272 $sql = 'UPDATE ' . $this->modules_table . " 273 SET left_id = left_id + 2, right_id = right_id + 2 274 WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "' 275 AND left_id > {$row['right_id']}"; 276 $this->db->sql_query($sql); 277 278 $sql = 'UPDATE ' . $this->modules_table . " 279 SET right_id = right_id + 2 280 WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "' 281 AND {$row['left_id']} BETWEEN left_id AND right_id"; 282 $this->db->sql_query($sql); 283 284 $module_data['left_id'] = (int) $row['right_id']; 285 $module_data['right_id'] = (int) $row['right_id'] + 1; 286 } 287 else 288 { 289 $sql = 'SELECT MAX(right_id) AS right_id 290 FROM ' . $this->modules_table . " 291 WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'"; 292 $result = $this->db->sql_query($sql); 293 $row = $this->db->sql_fetchrow($result); 294 $this->db->sql_freeresult($result); 295 296 $module_data['left_id'] = (int) $row['right_id'] + 1; 297 $module_data['right_id'] = (int) $row['right_id'] + 2; 298 } 299 300 $sql = 'INSERT INTO ' . $this->modules_table . ' ' . $this->db->sql_build_array('INSERT', $module_data); 301 $this->db->sql_query($sql); 302 303 $module_data['module_id'] = $this->db->sql_nextid(); 304 } 305 else 306 { 307 $row = $this->get_module_row($module_data['module_id'], $module_data['module_class']); 308 309 if ($module_data['module_basename'] && !$row['module_basename']) 310 { 311 // we're turning a category into a module 312 $branch = $this->get_module_branch($module_data['module_id'], $module_data['module_class'], 'children', false); 313 314 if (count($branch)) 315 { 316 throw new module_not_found_exception('NO_CATEGORY_TO_MODULE'); 317 } 318 } 319 320 if ($row['parent_id'] != $module_data['parent_id']) 321 { 322 $this->move_module($module_data['module_id'], $module_data['parent_id'], $module_data['module_class']); 323 } 324 325 $update_ary = $module_data; 326 unset($update_ary['module_id']); 327 328 $sql = 'UPDATE ' . $this->modules_table . ' 329 SET ' . $this->db->sql_build_array('UPDATE', $update_ary) . " 330 WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "' 331 AND module_id = " . (int) $module_data['module_id']; 332 $this->db->sql_query($sql); 333 } 334 } 335 336 /** 337 * Move module around the tree 338 * 339 * @param int $from_module_id ID of the current parent module 340 * @param int $to_parent_id ID of the target parent module 341 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 342 * 343 * @throws \phpbb\module\exception\module_not_found_exception If the module specified to move modules from does not 344 * have any children. 345 */ 346 public function move_module($from_module_id, $to_parent_id, $module_class) 347 { 348 $moved_modules = $this->get_module_branch($from_module_id, $module_class, 'children'); 349 350 if (empty($moved_modules)) 351 { 352 throw new module_not_found_exception(); 353 } 354 355 $from_data = $moved_modules[0]; 356 $diff = count($moved_modules) * 2; 357 358 $moved_ids = array(); 359 for ($i = 0, $size = count($moved_modules); $i < $size; ++$i) 360 { 361 $moved_ids[] = $moved_modules[$i]['module_id']; 362 } 363 364 // Resync parents 365 $sql = 'UPDATE ' . $this->modules_table . " 366 SET right_id = right_id - $diff 367 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 368 AND left_id < " . (int) $from_data['right_id'] . ' 369 AND right_id > ' . (int) $from_data['right_id']; 370 $this->db->sql_query($sql); 371 372 // Resync righthand side of tree 373 $sql = 'UPDATE ' . $this->modules_table . " 374 SET left_id = left_id - $diff, right_id = right_id - $diff 375 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 376 AND left_id > " . (int) $from_data['right_id']; 377 $this->db->sql_query($sql); 378 379 if ($to_parent_id > 0) 380 { 381 $to_data = $this->get_module_row($to_parent_id, $module_class); 382 383 // Resync new parents 384 $sql = 'UPDATE ' . $this->modules_table . " 385 SET right_id = right_id + $diff 386 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 387 AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id 388 AND ' . $this->db->sql_in_set('module_id', $moved_ids, true); 389 $this->db->sql_query($sql); 390 391 // Resync the righthand side of the tree 392 $sql = 'UPDATE ' . $this->modules_table . " 393 SET left_id = left_id + $diff, right_id = right_id + $diff 394 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 395 AND left_id > " . (int) $to_data['right_id'] . ' 396 AND ' . $this->db->sql_in_set('module_id', $moved_ids, true); 397 $this->db->sql_query($sql); 398 399 // Resync moved branch 400 $to_data['right_id'] += $diff; 401 if ($to_data['right_id'] > $from_data['right_id']) 402 { 403 $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1); 404 } 405 else 406 { 407 $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1); 408 } 409 } 410 else 411 { 412 $sql = 'SELECT MAX(right_id) AS right_id 413 FROM ' . $this->modules_table . " 414 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 415 AND " . $this->db->sql_in_set('module_id', $moved_ids, true); 416 $result = $this->db->sql_query($sql); 417 $row = $this->db->sql_fetchrow($result); 418 $this->db->sql_freeresult($result); 419 420 $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1); 421 } 422 423 $sql = 'UPDATE ' . $this->modules_table . " 424 SET left_id = left_id $diff, right_id = right_id $diff 425 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 426 AND " . $this->db->sql_in_set('module_id', $moved_ids); 427 $this->db->sql_query($sql); 428 } 429 430 /** 431 * Remove module from tree 432 * 433 * @param int $module_id ID of the module to delete 434 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 435 * 436 * @throws \phpbb\module\exception\module_exception When the specified module cannot be removed 437 */ 438 public function delete_module($module_id, $module_class) 439 { 440 $module_id = (int) $module_id; 441 442 $row = $this->get_module_row($module_id, $module_class); 443 444 $branch = $this->get_module_branch($module_id, $module_class, 'children', false); 445 446 if (count($branch)) 447 { 448 throw new module_exception('CANNOT_REMOVE_MODULE'); 449 } 450 451 // If not move 452 $diff = 2; 453 $sql = 'DELETE FROM ' . $this->modules_table . " 454 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 455 AND module_id = $module_id"; 456 $this->db->sql_query($sql); 457 458 $row['right_id'] = (int) $row['right_id']; 459 $row['left_id'] = (int) $row['left_id']; 460 461 // Resync tree 462 $sql = 'UPDATE ' . $this->modules_table . " 463 SET right_id = right_id - $diff 464 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 465 AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}"; 466 $this->db->sql_query($sql); 467 468 $sql = 'UPDATE ' . $this->modules_table . " 469 SET left_id = left_id - $diff, right_id = right_id - $diff 470 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 471 AND left_id > {$row['right_id']}"; 472 $this->db->sql_query($sql); 473 } 474 475 /** 476 * Move module position by $steps up/down 477 * 478 * @param array $module_row Array of module data 479 * @param string $module_class Class of the module (acp, ucp, mcp etc...) 480 * @param string $action Direction of moving (valid values: move_up or move_down) 481 * @param int $steps Number of steps to move module 482 * 483 * @return string Returns the language name of the module 484 * 485 * @throws \phpbb\module\exception\module_not_found_exception When the specified module does not exists 486 */ 487 public function move_module_by($module_row, $module_class, $action = 'move_up', $steps = 1) 488 { 489 /** 490 * Fetch all the siblings between the module's current spot 491 * and where we want to move it to. If there are less than $steps 492 * siblings between the current spot and the target then the 493 * module will move as far as possible 494 */ 495 $sql = 'SELECT module_id, left_id, right_id, module_langname 496 FROM ' . $this->modules_table . " 497 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 498 AND parent_id = " . (int) $module_row['parent_id'] . ' 499 AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC'); 500 $result = $this->db->sql_query_limit($sql, $steps); 501 502 $target = array(); 503 while ($row = $this->db->sql_fetchrow($result)) 504 { 505 $target = $row; 506 } 507 $this->db->sql_freeresult($result); 508 509 if (!count($target)) 510 { 511 // The module is already on top or bottom 512 throw new module_not_found_exception(); 513 } 514 515 /** 516 * $left_id and $right_id define the scope of the nodes that are affected by the move. 517 * $diff_up and $diff_down are the values to substract or add to each node's left_id 518 * and right_id in order to move them up or down. 519 * $move_up_left and $move_up_right define the scope of the nodes that are moving 520 * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down. 521 */ 522 if ($action == 'move_up') 523 { 524 $left_id = (int) $target['left_id']; 525 $right_id = (int) $module_row['right_id']; 526 527 $diff_up = (int) ($module_row['left_id'] - $target['left_id']); 528 $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); 529 530 $move_up_left = (int) $module_row['left_id']; 531 $move_up_right = (int) $module_row['right_id']; 532 } 533 else 534 { 535 $left_id = (int) $module_row['left_id']; 536 $right_id = (int) $target['right_id']; 537 538 $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); 539 $diff_down = (int) ($target['right_id'] - $module_row['right_id']); 540 541 $move_up_left = (int) ($module_row['right_id'] + 1); 542 $move_up_right = (int) $target['right_id']; 543 } 544 545 // Now do the dirty job 546 $sql = 'UPDATE ' . $this->modules_table . " 547 SET left_id = left_id + CASE 548 WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} 549 ELSE {$diff_down} 550 END, 551 right_id = right_id + CASE 552 WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} 553 ELSE {$diff_down} 554 END 555 WHERE module_class = '" . $this->db->sql_escape($module_class) . "' 556 AND left_id BETWEEN {$left_id} AND {$right_id} 557 AND right_id BETWEEN {$left_id} AND {$right_id}"; 558 $this->db->sql_query($sql); 559 560 $this->remove_cache_file($module_class); 561 562 return $target['module_langname']; 563 } 564 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |