function handle_language_prompt(&$children, &$elements, $action) { global $db, $template, $parent_id, $phpbb_root_path; if (isset($children['language']) && sizeof($children['language'])) { // additional languages are available...find out which ones we may want to apply $sql = 'SELECT lang_id, lang_iso FROM ' . LANG_TABLE; $result = $db->sql_query($sql); $installed_languages = array(); while ($row = $db->sql_fetchrow($result)) { $installed_languages[$row['lang_id']] = $row['lang_iso']; } $db->sql_freeresult($result); foreach ($children['language'] as $key => $tag) { // remove useless title from MODX 1.2.0 tags $children['language'][$key] = is_array($tag) ? $tag['href'] : $tag; } $children['language'] = array_unique($children['language']); // We _must_ have language xml files that are named "nl.xml" or "en-US.xml" for this to work // it appears that the MODX packaging standards call for this anyway $available_languages = array_map('core_basename', $children['language']); $process_languages = $elements['language'] = array_intersect($available_languages, $installed_languages); // $unknown_languages are installed on the board, but not provied for by the MOD $unknown_languages = array_diff($available_languages, $installed_languages); // there are langauges which are installed, but not provided for by the MOD // Inform the user. if (sizeof($unknown_languages) && $action == 'details') { // get full names from the DB $sql = 'SELECT lang_english_name, lang_local_name, lang_iso FROM ' . LANG_TABLE . ' WHERE ' . $db->sql_in_set('lang_iso', $unknown_languages); $result = $db->sql_query($sql); // alert the user. while ($row = $db->sql_fetchrow($result)) { if ($parent_id) { // first determine which file we want to direct them to foreach ($children['language'] as $file) { if (core_basename($file) == $row['lang_iso']) { $xml_file = urlencode($file); break; } } } $template->assign_block_vars('unknown_lang', array('ENGLISH_NAME' => $row['lang_english_name'], 'LOCAL_NAME' => $row['lang_local_name'], 'U_INSTALL' => $parent_id ? $this->u_action . "&action=install&parent={$parent_id}&mod_path={$xml_file}" : '')); // may wish to rename away from "unknown" for our details mode $template->assign_var('S_UNKNOWN_LANGUAGES', true); } $db->sql_freeresult($result); } return $process_languages; } }
/** * return array of the basic MOD details */ function get_details() { global $user; if (empty($this->data)) { $this->set_file($this->file); } $header = array('MOD-VERSION' => array(0 => array('children' => array())), 'INSTALLATION' => array(0 => array('children' => array('TARGET-VERSION' => array(0 => array('data' => ''))))), 'AUTHOR-GROUP' => array(0 => array('children' => array('AUTHOR' => array()))), 'HISTORY' => array(0 => array('children' => array('ENTRY' => array())))); $version = $phpbb_version = ''; $header = $this->data[0]['children']['HEADER'][0]['children']; // get MOD version information // This is also our first opportunity to differentiate MODX 1.0.x from // MODX 1.2.0. if (isset($header['MOD-VERSION'][0]['children'])) { $this->modx_version = 1.0; $version_info = $header['MOD-VERSION'][0]['children']; $version = isset($version_info['MAJOR'][0]['data']) ? trim($version_info['MAJOR'][0]['data']) : 0; $version .= '.' . (isset($version_info['MINOR'][0]['data']) ? trim($version_info['MINOR'][0]['data']) : 0); $version .= '.' . (isset($version_info['REVISION'][0]['data']) ? trim($version_info['REVISION'][0]['data']) : 0); $version .= isset($version_info['RELEASE'][0]['data']) ? trim($version_info['RELEASE'][0]['data']) : ''; } else { $this->modx_version = 1.2; $version = trim($header['MOD-VERSION'][0]['data']); } // get phpBB version recommendation switch ($this->modx_version) { case 1.0: if (isset($header['INSTALLATION'][0]['children']['TARGET-VERSION'][0]['children'])) { $version_info = $header['INSTALLATION'][0]['children']['TARGET-VERSION'][0]['children']; $phpbb_version = isset($version_info['MAJOR'][0]['data']) ? trim($version_info['MAJOR'][0]['data']) : 0; $phpbb_version .= '.' . (isset($version_info['MINOR'][0]['data']) ? trim($version_info['MINOR'][0]['data']) : 0); $phpbb_version .= '.' . (isset($version_info['REVISION'][0]['data']) ? trim($version_info['REVISION'][0]['data']) : 0); $phpbb_version .= isset($version_info['RELEASE'][0]['data']) ? trim($version_info['RELEASE'][0]['data']) : ''; } break; case 1.2: default: $phpbb_version = isset($header['INSTALLATION'][0]['children']['TARGET-VERSION'][0]['data']) ? $header['INSTALLATION'][0]['children']['TARGET-VERSION'][0]['data'] : 0; break; } $author_info = $header['AUTHOR-GROUP'][0]['children']['AUTHOR']; $author_details = array(); for ($i = 0; $i < sizeof($author_info); $i++) { $author_details[] = array('AUTHOR_NAME' => isset($author_info[$i]['children']['USERNAME'][0]['data']) ? trim($author_info[$i]['children']['USERNAME'][0]['data']) : '', 'AUTHOR_EMAIL' => isset($author_info[$i]['children']['EMAIL'][0]['data']) ? trim($author_info[$i]['children']['EMAIL'][0]['data']) : '', 'AUTHOR_REALNAME' => isset($author_info[$i]['children']['REALNAME'][0]['data']) ? trim($author_info[$i]['children']['REALNAME'][0]['data']) : '', 'AUTHOR_WEBSITE' => isset($author_info[$i]['children']['HOMEPAGE'][0]['data']) ? trim($author_info[$i]['children']['HOMEPAGE'][0]['data']) : ''); } // history $history_info = !empty($header['HISTORY'][0]['children']['ENTRY']) ? $header['HISTORY'][0]['children']['ENTRY'] : array(); $history_size = sizeof($history_info); $mod_history = array(); for ($i = 0; $i < $history_size; $i++) { $changes = array(); $entry = $history_info[$i]['children']; $changelog = isset($entry['CHANGELOG']) ? $entry['CHANGELOG'] : array(); $changelog_size = sizeof($changelog); $changelog_id = 0; for ($j = 0; $j < $changelog_size; $j++) { // Ignore changelogs in foreign languages except in the case that there is no // match for the current user's language // TODO: Look at modifying localise_tags() for use here. if (match_language($user->data['user_lang'], $changelog[$j]['attrs']['LANG'])) { $changelog_id = $j; } } $change_count = isset($changelog[$changelog_id]['children']['CHANGE']) ? sizeof($changelog[$changelog_id]['children']['CHANGE']) : 0; for ($j = 0; $j < $change_count; $j++) { $changes[] = $changelog[$changelog_id]['children']['CHANGE'][$j]['data']; } switch ($this->modx_version) { case 1.0: $changelog_version_ary = isset($entry['REV-VERSION'][0]['children']) ? $entry['REV-VERSION'][0]['children'] : array(); $changelog_version = isset($changelog_version_ary['MAJOR'][0]['data']) ? trim($changelog_version_ary['MAJOR'][0]['data']) : 0; $changelog_version .= '.' . (isset($changelog_version_ary['MINOR'][0]['data']) ? trim($changelog_version_ary['MINOR'][0]['data']) : 0); $changelog_version .= '.' . (isset($changelog_version_ary['REVISION'][0]['data']) ? trim($changelog_version_ary['REVISION'][0]['data']) : 0); $changelog_version .= isset($changelog_version_ary['RELEASE'][0]['data']) ? trim($changelog_version_ary['RELEASE'][0]['data']) : ''; break; case 1.2: default: $changelog_version = isset($entry['REV-VERSION'][0]['data']) ? $entry['REV-VERSION'][0]['data'] : '0.0.0'; break; } $mod_history[] = array('DATE' => $entry['DATE'][0]['data'], 'VERSION' => $changelog_version, 'CHANGES' => $changes); } $children = array(); // Parse links if ($this->modx_version == 1.2) { $link_group = isset($header['LINK-GROUP'][0]['children']) ? $header['LINK-GROUP'][0]['children'] : array(); if (isset($link_group['LINK'])) { for ($i = 0, $size = sizeof($link_group['LINK']); $i <= $size; $i++) { // do some stuff with attrs // commented out due to a possible PHP bug. When using this, // sizeof($link_group) changed each time ... // $attrs = &$link_group[$i]['attrs']; if (!isset($link_group['LINK'][$i])) { continue; } if ($link_group['LINK'][$i]['attrs']['TYPE'] == 'text') { continue; } $children[$link_group['LINK'][$i]['attrs']['TYPE']][] = array('href' => $link_group['LINK'][$i]['attrs']['HREF'], 'realname' => isset($link_group['LINK'][$i]['attrs']['REALNAME']) ? $link_group['LINK'][$i]['attrs']['REALNAME'] : core_basename($link_group['LINK'][$i]['attrs']['HREF']), 'title' => localise_tags($link_group, 'LINK', $i)); } } } // try not to hardcode schema? $details = array('MOD_PATH' => $this->file, 'MOD_NAME' => localise_tags($header, 'TITLE'), 'MOD_DESCRIPTION' => nl2br(localise_tags($header, 'DESCRIPTION')), 'MOD_VERSION' => htmlspecialchars(trim($version)), 'AUTHOR_DETAILS' => $author_details, 'AUTHOR_NOTES' => nl2br(localise_tags($header, 'AUTHOR-NOTES')), 'MOD_HISTORY' => $mod_history, 'PHPBB_VERSION' => $phpbb_version, 'CHILDREN' => $children); return $details; }
/** * Returns array of available mod install files in dir (Recursive) * @param $dir string - dir to search * @param $recurse int - number of levels to recurse */ function find_mods($dir, $recurse = false) { if ($recurse === false) { $mods = array('main' => array(), 'contrib' => array(), 'template' => array(), 'language' => array()); $recurse = 0; } else { static $mods = array('main' => array(), 'contrib' => array(), 'template' => array(), 'language' => array()); } // ltrim shouldn't be needed, but some users had problems. See #44305 $dir = ltrim($dir, '/'); if (!file_exists($dir)) { return array(); } $dp = opendir($dir); while (($file = readdir($dp)) !== false) { if ($file[0] != '.' && strpos("{$dir}/{$file}", '_edited') === false && strpos("{$dir}/{$file}", '_backups') === false) { // recurse - we don't want anything within the MODX "root" though if ($recurse && !is_file("{$dir}/{$file}") && strpos("{$dir}/{$file}", 'root') === false) { $mods = array_merge($mods, $this->find_mods("{$dir}/{$file}", $recurse - 1)); } else { if (preg_match('#.*install.*xml$#i', $file) || preg_match('#(contrib|templates|languages)#i', $dir, $match) || $recurse === 0 && strpos($file, '.xml') !== false) { // if this is an "extra" MODX file, make a record of it as such // we are assuming the MOD follows MODX packaging standards here if (strpos($file, '.xml') !== false && preg_match('#(contrib|templates|languages)#i', $dir, $match)) { // Get rid of the S. This is a side effect of understanding // MODX 1.0.x and 1.2.x. $match[1] = rtrim($match[1], 's'); $mods[$match[1]][] = array('href' => "{$dir}/{$file}", 'realname' => core_basename($file), 'title' => core_basename($file)); } else { $check = end($mods['main']); $check = $check['href']; // we take the first file alphabetically with install in the filename if (!$check || dirname($check) == $dir) { if (preg_match('#.*install.*xml$#i', $file) && preg_match('#.*install.*xml$#i', $check) && strnatcasecmp(basename($check), $file) > 0) { $index = max(0, sizeof($mods['main']) - 1); $mods['main'][$index] = array('href' => "{$dir}/{$file}", 'realname' => core_basename($file), 'title' => core_basename($file)); break; } else { if (preg_match('#.*install.*xml$#i', $file) && !preg_match('#.*install.*xml$#i', $check)) { $index = max(0, sizeof($mods['main']) - 1); $mods['main'][$index] = array('href' => "{$dir}/{$file}", 'realname' => core_basename($file), 'title' => core_basename($file)); break; } } } else { if (strpos($file, '.xml') !== false) { $mods['main'][] = array('href' => "{$dir}/{$file}", 'realname' => core_basename($file), 'title' => core_basename($file)); } } } } } } } closedir($dp); return $mods; }