<?php /** * * @copyright (c) 2013 phpBB Group * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ if (php_sapi_name() != 'cli') { die("This program must be run from the command line.\n"); } $phpEx = substr(strrchr(__FILE__, '.'), 1); $phpbb_root_path = __DIR__ . '/../'; function usage() { echo "Usage: export_events_for_wiki.php COMMAND\n"; echo "\n"; echo "acp:\n"; echo " Export all events for files in the acp style.\n"; echo "\n"; echo "styles:\n"; echo " Export all events for files in the prosilver and subsilver2 styles.\n"; echo "\n"; echo "php:\n"; echo " Export all events for php-files.\n"; exit(2); } function export_from_eventsmd($phpbb_root_path, $filter) { $file_content = file_get_contents($phpbb_root_path . 'docs/events.md'); $events = explode("\n\n", $file_content); foreach ($events as $event) { // Last row of the file if (strpos($event, "\n===\n") === false) continue; list($event_name, $details) = explode("\n===\n", $event); if ($filter == 'acp' && strpos($event_name, 'acp_') !== 0) continue; if ($filter == 'styles' && strpos($event_name, 'acp_') === 0) continue; list($file_details, $details) = explode("\n* Since: ", $details); list($version, $explanition) = explode("\n* Purpose: ", $details); echo "|- id=\"{$event_name}\"\n"; echo "| [[#{$event_name}|{$event_name}]] || "; if (strpos($file_details, "* Locations:\n + ") === 0) { $file_details = substr($file_details, strlen("* Locations:\n + ")); $files = explode("\n + ", $file_details); $prosilver = $subsilver2 = array(); foreach ($files as $file) { if (strpos($file, 'styles/prosilver/template/') === 0) { $prosilver[] = substr($file, strlen('styles/prosilver/template/')); } if (strpos($file, 'styles/subsilver2/template/') === 0) { $subsilver2[] = substr($file, strlen('styles/subsilver2/template/')); } } echo implode(', ', $prosilver) . ' || ' . implode(', ', $subsilver2); } else if ($filter == 'acp') { echo substr($file_details, strlen("* Location: adm/style/")); } echo " || {$version} || " . str_replace("\n", ' ', $explanition) . "\n"; } } function export_from_php($phpbb_root_path) { $files = get_file_list($phpbb_root_path); $events = array(); foreach ($files as $file) { $file_events = check_for_events($phpbb_root_path, $file); if (!empty($file_events)) { $events = array_merge($events, $file_events); } } ksort($events); foreach ($events as $event) { echo '|- id="' . $event['event'] . '"' . "\n"; echo '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n"; } } function check_for_events($phpbb_root_path, $file) { $events = array(); $content = file_get_contents($phpbb_root_path . $file); if (strpos($content, "phpbb_dispatcher->trigger_event('") || strpos($content, "phpbb_dispatcher->dispatch('")) { $lines = explode("\n", $content); for ($i = 0, $num_lines = sizeof($lines); $i < $num_lines; $i++) { $event_line = 0; if ($found_trigger_event = strpos($lines[$i], "phpbb_dispatcher->trigger_event('")) { $event_line = $i; $event_name = $lines[$event_line]; $event_name = substr($event_name, $found_trigger_event + strlen("phpbb_dispatcher->trigger_event('")); $event_name = substr($event_name, 0, strpos($event_name, "'")); // Find $vars array lines $find_varsarray_line = 1; while (strpos($lines[$event_line - $find_varsarray_line], "vars = array('") === false) { $find_varsarray_line++; if ($find_varsarray_line > min(50, $event_line)) { throw new LogicException('Can not find "$vars = array()"-line for event "' . $event_name . '" in file "' . $file . '"'); } } $varsarray = substr(trim($lines[$event_line - $find_varsarray_line]), strlen("\$vars = array('"), -3); $arguments = explode("', '", $varsarray); // Validate $vars array with @var $find_vars_line = 3; $doc_vars = array(); while (strpos(trim($lines[$event_line - $find_vars_line]), '*') === 0) { $var_line = trim($lines[$event_line - $find_vars_line]); $var_line = preg_replace('!\s+!', ' ', $var_line); if (strpos($var_line, '* @var ') === 0) { $doc_line = explode(' ', $var_line); if (isset($doc_line[3])) { $doc_vars[] = $doc_line[3]; } } $find_vars_line++; } if (sizeof($arguments) !== sizeof($doc_vars) && array_intersect($arguments, $doc_vars)) { throw new LogicException('$vars array does not match the list of @var tags for event "' . $event_name . '" in file "' . $file . '"'); } } else if ($found_trigger_event = strpos($lines[$i], "phpbb_dispatcher->dispatch('")) { $event_line = $i; $event_name = $lines[$event_line]; $event_name = substr($event_name, $found_trigger_event + strlen("phpbb_dispatcher->dispatch('")); $event_name = substr($event_name, 0, strpos($event_name, "'")); $arguments = array(); } if ($event_line) { // Validate @event name $find_event_line = 1; while (strpos($lines[$event_line - $find_event_line], '* @event ') === false) { $find_event_line++; if ($find_event_line > min(50, $event_line)) { throw new LogicException('Can not find @event tag for event "' . $event_name . '" in file "' . $file . '"'); } } $event_name_tag = substr(trim($lines[$event_line - $find_event_line]), strlen('* @event ')); if ($event_name_tag !== $event_name) { throw new LogicException('Event name does not match @event tag for event "' . $event_name . '" in file "' . $file . '"'); } // Find @since $find_since_line = 1; while (strpos($lines[$event_line - $find_since_line], '* @since ') === false) { $find_since_line++; if ($find_since_line > min(50, $event_line)) { throw new LogicException('Can not find @since tag for event "' . $event_name . '" in file "' . $file . '"'); } } $since = substr(trim($lines[$event_line - $find_since_line]), strlen('* @since ')); $since = ($since == '3.1-A1') ? '3.1.0-a1' : $since; // Find event description line $find_description_line = 3; while (strpos(trim($lines[$event_line - $find_description_line]), '*') === 0) { $find_description_line++; if ($find_description_line > min(50, $event_line)) { throw new LogicException('Can not find description-line for event "' . $event_name . '" in file "' . $file . '"'); } } $description = substr(trim($lines[$event_line - $find_description_line + 1]), strlen('* ')); $events[$event_name] = array( 'event' => $event_name, 'file' => $file, 'arguments' => $arguments, 'since' => $since, 'description' => $description, ); } } } return $events; } /** * Returns a list of files in that directory * * Works recursive with any depth * * @param string $dir Directory to go through * @return array List of files (including directories from within $dir */ function get_file_list($dir, $path = '') { try { $iterator = new \DirectoryIterator($dir); } catch (Exception $e) { return array(); } $files = array(); foreach ($iterator as $file_info) { if ($file_info->isDot()) { continue; } // Do not scan some directories if ($file_info->isDir() && ( ($path == '' && in_array($file_info->getFilename(), array('cache', 'develop', 'ext', 'files', 'language', 'store', 'vendor'))) || ($path == '/includes' && in_array($file_info->getFilename(), array('utf'))) || ($path == '/phpbb/db/migration' && in_array($file_info->getFilename(), array('data'))) || ($path == '/phpbb' && in_array($file_info->getFilename(), array('event'))) )) { continue; } else if ($file_info->isDir()) { $sub_dir = get_file_list($file_info->getPath() . '/' . $file_info->getFilename(), $path . '/' . $file_info->getFilename()); foreach ($sub_dir as $file) { $files[] = $file_info->getFilename() . '/' . $file; } } else if ($file_info->getExtension() == 'php') { $files[] = $file_info->getFilename(); } } return $files; } function validate_argument_count($arguments, $count) { if ($arguments <= $count) { usage(); } } validate_argument_count($argc, 1); $action = $argv[1]; switch ($action) { case 'acp': export_from_eventsmd($phpbb_root_path, 'acp'); break; case 'styles': export_from_eventsmd($phpbb_root_path, 'styles'); break; case 'php': export_from_php($phpbb_root_path); break; default: usage(); }