[Customisation Database Commits] r909 [2/2] - in /trunk/titania: includes/library/automod/ includes/tools/ includes/tools/automod/ store/phpbb_packages/ store/phpbb_packages/extracted/
Nathan Guse
exreaction at phpbb.com
Sat Mar 27 17:24:58 GMT 2010
Added: trunk/titania/includes/library/automod/editor.php
==============================================================================
*** trunk/titania/includes/library/automod/editor.php (added)
--- trunk/titania/includes/library/automod/editor.php Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,1278 ----
+ <?php
+ /**
+ *
+ * @package automod
+ * @version $Id$
+ * @copyright (c) 2008 phpBB Group
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
+ *
+ */
+
+ /**
+ */
+ if (!defined('IN_PHPBB'))
+ {
+ exit;
+ }
+
+ // Constant Defines for actions
+ //define('AFTER', 1);
+ //define('BEFORE', 2);
+
+ /**
+ * Editor Class
+ * Runs through file sequential, ie new finds must come after previous finds
+ * Handles placing the files after being edited
+ * @package automod
+ * @todo: implement some string checkin, way too much can go wild here
+ */
+ class editor
+ {
+ /**
+ * Holds contents of file
+ */
+ var $file_contents = '';
+
+ /**
+ * Holds the filename of the currently open file
+ */
+ var $open_filename = '';
+
+ /**
+ * Full action array with complete finds
+ */
+ var $mod_actions = array();
+
+ /**
+ * One of the three constants defined in functions_mods.php
+ */
+ var $write_method = 0;
+
+ /**
+ * Keeps finds sequential, plus loop optimization
+ */
+ var $start_index = 0;
+
+ /*
+ * Keeps inline find sequential
+ */
+ var $last_string_offset = 0;
+
+ /*
+ * Only apply string offset to the line to which it belongs
+ */
+ var $last_inline_ary_offset = 0;
+
+ /**
+ * Time when MOD was installed
+ */
+ var $install_time = 0;
+
+ /**
+ * Only used when board has templates stored in the database
+ */
+ var $template_id = 0;
+
+ /**
+ * Store the current action & most recent action to aid the uninstall building process
+ */
+ var $last_action = array();
+ var $curr_action = array();
+
+ /**
+ * Constructor method
+ * This is not called directly in AutoMOD
+ */
+ function editor()
+ {
+
+ }
+
+ /**
+ * Make all line endings the same - UNIX
+ */
+ function normalize($string)
+ {
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ return $string;
+ }
+
+ /**
+ * Open a file with IO, for processing
+ *
+ * @param string $filename - relative path from phpBB Root to the file to open
+ * e.g. viewtopic.php, styles/prosilver/templates/index_body.html
+ */
+ function open_file($filename, $backup_path)
+ {
+ global $phpbb_root_path, $db, $user;
+
+ $this->file_contents = @file($phpbb_root_path . $filename);
+
+ if ($this->file_contents === false)
+ {
+ return $user->lang['FILE_EMPTY'];
+ }
+
+ $this->file_contents = $this->normalize($this->file_contents);
+
+ // Check for file contents in the database if this is a template file
+ // this will overwrite the @file call if it exists in the DB.
+ if (strpos($filename, 'template/') !== false)
+ {
+ // grab template name and filename
+ preg_match('#styles/([a-z0-9_]+)/template/([a-z0-9_]+.[a-z]+)#i', $filename, $match);
+
+ $sql = 'SELECT d.template_data, d.template_id
+ FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' d, ' . STYLES_TEMPLATE_TABLE . " t
+ WHERE d.template_filename = '" . $db->sql_escape($match[2]) . "'
+ AND t.template_id = d.template_id
+ AND t.template_storedb = 1
+ AND t.template_name = '" . $db->sql_escape($match[1]) . "'";
+ $result = $db->sql_query($sql);
+
+ if ($row = $db->sql_fetchrow($result))
+ {
+ $this->file_contents = explode("\n", $this->normalize($row['template_data']));
+
+ // emulate the behavior of file()
+ $lines = sizeof($this->file_contents);
+ for ($i = 0; $i < $lines; $i++)
+ {
+ $this->file_contents[$i] .= "\n";
+ }
+
+ $this->template_id = $row['template_id'];
+ }
+ else
+ {
+ $this->template_id = 0;
+ }
+ }
+
+ /*
+ * If the file does not exist, or is empty, die.
+ * Non existant files cannot be edited, and empty files will have no
+ * finds
+ */
+ if (!sizeof($this->file_contents))
+ {
+ global $user;
+ trigger_error(sprintf($user->lang['MOD_OPEN_FILE_FAIL'], "$phpbb_root_path$filename"), E_USER_WARNING);
+ }
+
+ $this->start_index = 0;
+ $this->open_filename = $filename;
+
+ // Make a backup of this file
+ $this->backup_file($backup_path);
+ }
+
+ /**
+ * Checks if a find is present
+ * Keep in mind partial finds and multi-line finds
+ *
+ * @param string $find - string to find
+ * @return mixed : array with position information if $find is found; false otherwise
+ */
+ function find($find)
+ {
+ $find_success = 0;
+
+ $find = $this->normalize($find);
+ $find_ary = explode("\n", $find);
+
+ $total_lines = sizeof($this->file_contents);
+ $find_lines = sizeof($find_ary);
+
+ $mode = array('', 'trim');
+
+ foreach ($mode as $function)
+ {
+ // we process the file sequentially ... so we keep track of indices
+ for ($i = $this->start_index; $i < $total_lines; $i++)
+ {
+ for ($j = 0; $j < $find_lines; $j++)
+ {
+ if ($function)
+ {
+ $find_ary[$j] = $function($find_ary[$j]);
+ }
+
+ // if we've reached the EOF, the find failed.
+ if (!isset($this->file_contents[$i + $j]))
+ {
+ return false;
+ }
+
+ if (!trim($find_ary[$j]))
+ {
+ // line is blank. Assume we can find a blank line, and continue on
+ $find_success += 1;
+ }
+ // using $this->file_contents[$i + $j] to keep the array pointer where I want it
+ // if the first line of the find (index 0) is being looked at, $i + $j = $i.
+ // if $j is > 0, we look at the next line of the file being inspected
+ // hopefully, this is a decent performer.
+ else if (strpos($this->file_contents[$i + $j], $find_ary[$j]) !== false)
+ {
+ // we found this part of the find
+ $find_success += 1;
+ }
+ // we might have an increment operator, which requires a regular expression match
+ else if (strpos($find_ary[$j], '{%:') !== false)
+ {
+ $regex = preg_replace('#{%:(\d+)}#', '(\d+)', $find_ary[$j]);
+
+ if (preg_match('#' . $regex . '#is', $this->file_contents[$i + $j]))
+ {
+ $find_success += 1;
+ }
+ else
+ {
+ $find_success = 0;
+ }
+ }
+ else
+ {
+ // the find failed. Reset $find_success
+ $find_success = 0;
+
+ // skip to next iteration of outer loop, that is, skip to the next line
+ break;
+ }
+
+ if ($find_success == $find_lines)
+ {
+ // we found the proper number of lines
+ $this->start_index = $i;
+
+ // return our array offsets
+ return array(
+ 'start' => $i,
+ 'end' => $i + $j,
+ );
+ }
+
+ }
+ }
+ }
+
+ // if return has not been previously invoked, the find failed.
+ return false;
+ }
+
+ /**
+ * This function is used to determine when an edit has ended, so we know that
+ * the current line will not be looked at again. This fixes some former bugs.
+ */
+ function close_edit()
+ {
+ $this->start_index++;
+ $this->last_action = array();
+ $this->last_string_offset = 0;
+ }
+
+ /*
+ * In-line analog to close_edit(), above.
+ * Advance the pointer one character
+ */
+ function close_inline_edit()
+ {
+ $this->last_string_offset++;
+ }
+
+ /**
+ * Find a string within a given line
+ *
+ * @param string $find Complete find - narrows the scope of the inline search
+ * @param string $inline_find - the substring to find
+ * @param int $start_offset - the line number where $find starts
+ * @param int $end_offset - the line number where $find ends
+ *
+ * @return mixed array on success or false on failure of find
+ */
+ function inline_find($find, $inline_find, $start_offset = false, $end_offset = false)
+ {
+ $find = $this->normalize($find);
+
+ if ($start_offset === false || $end_offset === false)
+ {
+ $offsets = $this->find($find);
+
+ if (!$offsets)
+ {
+ // the find failed, so no further action can occur.
+ return false;
+ }
+
+ $start_offset = $offsets['start'];
+ $end_offset = $offsets['end'];
+
+ unset($offsets);
+ }
+
+ // cast is required in case someone tries to find a number
+ // Often done in colspan="7" type inline operations
+ $inline_find = (string) $inline_find;
+
+ // similar method to find(). Just much more limited scope
+ for ($i = $start_offset; $i <= $end_offset; $i++)
+ {
+ if ($this->last_string_offset > 0 && ($this->last_inline_ary_offset == 0 || $this->last_inline_ary_offset == $i))
+ {
+ $string_offset = strpos(substr($this->file_contents[$i], $this->last_string_offset), $inline_find);
+
+ if ($string_offset !== false)
+ {
+ $string_offset += $this->last_string_offset;
+ }
+ }
+ else
+ {
+ $string_offset = strpos($this->file_contents[$i], $inline_find);
+ }
+
+ if ($string_offset !== false)
+ {
+ $this->last_string_offset = $string_offset;
+ $this->last_inline_ary_offset = $i;
+
+ // if we find something, return the line number, string offset, and find length
+ return array(
+ 'array_offset' => $i,
+ 'string_offset' => $string_offset,
+ 'find_length' => strlen($inline_find),
+ );
+ }
+ }
+
+ // if the previous failed, trim() the find and try again
+ for ($i = $start_offset; $i <= $end_offset; $i++)
+ {
+ $inline_find = trim($inline_find);
+ if ($this->last_string_offset > 0 && ($this->last_inline_ary_offset == 0 || $this->last_inline_ary_offset == $i))
+ {
+ $string_offset = strpos(substr($this->file_contents[$i], $this->last_string_offset), $inline_find);
+
+ if ($string_offset !== false)
+ {
+ $string_offset += $this->last_string_offset;
+ }
+ }
+ else
+ {
+ $string_offset = strpos($this->file_contents[$i], $inline_find);
+ }
+
+ if ($string_offset !== false)
+ {
+ $this->last_string_offset = $string_offset;
+
+ // if we find something, return the line number, string offset, and find length
+ return array(
+ 'array_offset' => $i,
+ 'string_offset' => $string_offset,
+ 'find_length' => strlen($inline_find),
+ );
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Add a string to the file, BEFORE/AFTER the given find string
+ * @param string $find - Complete find - narrows the scope of the inline search
+ * @param string $add - The string to be added before or after $find
+ * @param string $pos - BEFORE or AFTER
+ * @param int $start_offset - First line in the FIND
+ * @param int $end_offset - Last line in the FIND
+ *
+ * @return bool success or failure of add
+ */
+ function add_string($find, $add, $pos, $start_offset = false, $end_offset = false)
+ {
+ // this seems pretty simple...throughly test
+ $add = $this->normalize($add);
+
+ if ($start_offset === false || $end_offset === false)
+ {
+ $offsets = $this->find($find);
+
+ if (!$offsets)
+ {
+ // the find failed, so the add cannot occur.
+ return false;
+ }
+
+ $start_offset = $offsets['start'];
+ $end_offset = $offsets['end'];
+
+ unset($offsets);
+ }
+
+ $full_find = array();
+ for ($i = $start_offset; $i <= $end_offset; $i++)
+ {
+ $full_find[] = $this->file_contents[$i];
+ }
+
+ $full_find[0] = ltrim($full_find[0], "\n");
+ $full_find[sizeof($full_find) - 1] = rtrim($full_find[sizeof($full_find) - 1], "\n");
+
+ // make sure our new lines are correct
+ $add = "\n" . trim($add, "\n") . "\n";
+
+ if ($pos == 'AFTER')
+ {
+ $this->file_contents[$end_offset] = rtrim($this->file_contents[$end_offset], "\n") . $add;
+ }
+
+ if ($pos == 'BEFORE')
+ {
+ $this->file_contents[$start_offset] = $add . ltrim($this->file_contents[$start_offset], "\n");
+ }
+
+ $this->curr_action = func_get_args();
+ $this->build_uninstall(implode("", $full_find), NULL, strtolower($pos) . ' add', $add);
+
+ return true;
+ }
+
+ /**
+ * Increment (or perform other mathematical operation) on the given wildcard
+ * Support multiple wildcards {%:1}, {%:2} etc...
+ * This method is a variation on the inline find and replace methods
+ *
+ * @param string $find - Complete find - contains $inline_find
+ * @param string $inline_find - contains tokens to be replaced
+ * @param string $operation - tokens to do some math
+ * @param int $start_offset - First line in the FIND
+ * @param int $end_offset - Last line in the FIND
+ *
+ * @return bool
+ */
+ function inc_string($find, $inline_find, $operation, $start_offset = false, $end_offset = false)
+ {
+ if ($start_offset === false || $end_offset === false)
+ {
+ $offsets = $this->find($find);
+
+ if (!$offsets)
+ {
+ // the find failed, so the add cannot occur.
+ return false;
+ }
+
+ $start_offset = $offsets['start'];
+ $end_offset = $offsets['end'];
+
+ unset($offsets);
+ }
+
+ // $inline_find is optional
+ if (!$inline_find)
+ {
+ $inline_find = $find;
+ }
+
+ // parse the MODX operator
+ // let's explain this regex a bit:
+ // - literal %: followed by a number. optional space
+ // - plus or minus operator. optional space
+ // - number to increment by. optional
+ preg_match('#{%:(\d+)} ?([+-]) ?(\d*)#', $operation, $action);
+ // make sure there is actually a number here
+ $action[2] = (isset($action[2])) ? $action[2] : '+';
+ $action[3] = (isset($action[3])) ? $action[3] : 1;
+
+ $matches = 0;
+ // $start_offset _should_ equal $end_offset, but we allow other cases
+ for ($i = $start_offset; $i <= $end_offset; $i++)
+ {
+ // This is intended. We turn the MODX token into something PCRE can
+ // understand.
+ $inline_find = preg_replace('#{%:(\d+)}#', '(\d+)', $inline_find);
+
+ if (preg_match('#' . $inline_find . '#is', $this->file_contents[$i], $find_contents))
+ {
+ // now we can do some math
+ // $find_contents[1] is the original number, $action[2] is the operator
+ $new_number = eval('return ' . ((int) $find_contents[1]) . $action[2] . ((int) $action[3]) . ';');
+
+ // now we replace
+ $new_contents = str_replace($find_contents[1], $new_number, $find_contents[0]);
+
+ $this->file_contents[$i] = str_replace($find_contents[0], $new_contents, $this->file_contents[$i]);
+
+ $matches += 1;
+ }
+ }
+
+ if (!$matches)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Replace a string - replaces the entirety of $find with $replace
+ *
+ * @param string $find - Complete find - contains $inline_find
+ * @param string $replace - Will replace $find
+ * @param int $start_offset - First line in the FIND
+ * @param int $end_offset - Last line in the FIND
+ *
+ * @return bool
+ */
+ function replace_string($find, $replace, $start_offset = false, $end_offset = false)
+ {
+ $replace = $this->normalize($replace);
+
+ if ($start_offset === false || $end_offset === false)
+ {
+ $offsets = $this->find($find);
+
+ if (!$offsets)
+ {
+ return false;
+ }
+
+ $start_offset = $offsets['start'];
+ $end_offset = $offsets['end'];
+ unset($offsets);
+ }
+
+ // remove each line from the file, but add it to $full_find
+ $full_find = array();
+ for ($i = $start_offset; $i <= $end_offset; $i++)
+ {
+ $full_find[] = $this->file_contents[$i];
+ $this->file_contents[$i] = '';
+ }
+
+ $this->file_contents[$start_offset] = rtrim($replace) . "\n";
+
+ $this->curr_action = func_get_args();
+ $this->build_uninstall(implode("", $full_find), NULL, 'replace-with', $replace);
+
+ return true;
+ }
+
+ /*
+ * Replace $inline_find with $inline_replace
+ * Arguments are very similar to inline_add, below
+ */
+ function inline_replace($find, $inline_find, $inline_replace, $array_offset = false, $string_offset = false, $length = false)
+ {
+ if ($string_offset === false || $length === false)
+ {
+ // look for the inline find
+ $inline_offsets = $this->inline_find($find, $inline_find);
+
+ if (!$inline_offsets)
+ {
+ return false;
+ }
+
+ $array_offset = $inline_offsets['array_offset'];
+ $string_offset = $inline_offsets['string_offset'];
+ $length = $inline_offsets['find_length'];
+ unset($inline_offsets);
+ }
+
+ $this->file_contents[$array_offset] = substr_replace($this->file_contents[$array_offset], $inline_replace, $string_offset, $length);
+
+ $this->last_string_offset += strlen($inline_replace) - 1;
+
+ $this->curr_action = func_get_args();
+
+ // This isn't a full find, but it is the closest we can get
+ $this->build_uninstall($this->file_contents[$array_offset], $inline_find, 'in-line-replace', $inline_replace);
+
+ return true;
+ }
+
+ /**
+ * Adds a string inline before or after a given find
+ *
+ * @param string $find Complete find - narrows the scope of the inline search
+ * @param string $inline_find - the string to add before or after
+ * @param string $inline_add - added before or after $inline_find
+ * @param string $pos - 'BEFORE' or 'AFTER'
+ * @param int $array_offset - line number where $inline_find may be found (optional)
+ * @param int $string_offset - location within the line where $inline_find begins (optional)
+ * @param int $length - essentially strlen($inline_find) (optional)
+ *
+ * @return bool success or failure of action
+ */
+ function inline_add($find, $inline_find, $inline_add, $pos, $array_offset = false, $string_offset = false, $length = false)
+ {
+ if ($string_offset === false || $length === false)
+ {
+ // look for the inline find
+ $inline_offsets = $this->inline_find($find, $inline_find);
+
+ if (!$inline_offsets)
+ {
+ return false;
+ }
+
+ $array_offset = $inline_offsets['array_offset'];
+ $string_offset = $inline_offsets['string_offset'];
+ $length = $inline_offsets['find_length'];
+ unset($inline_offsets);
+ }
+
+ if ($string_offset + $length > strlen($this->file_contents[$array_offset]))
+ {
+ // we have an invalid string offset. rats.
+ return false;
+ }
+
+ if ($pos == 'AFTER')
+ {
+ $this->file_contents[$array_offset] = substr_replace($this->file_contents[$array_offset], $inline_add, $string_offset + $length, 0);
+ $this->last_string_offset += strlen($inline_add) + $length - 1;
+ }
+ else if ($pos == 'BEFORE')
+ {
+ $this->file_contents[$array_offset] = substr_replace($this->file_contents[$array_offset], $inline_add, $string_offset, 0);
+ $this->last_string_offset += $length;
+ }
+
+ $this->curr_action = func_get_args();
+
+ $this->build_uninstall($this->file_contents[$array_offset], $inline_find, 'in-line-' . strtolower($pos) . '-add', $inline_add);
+
+ return true;
+ }
+
+ /**
+ * Function to build full edits such that uninstall will work more often
+ *
+ * @param $find - The largest find we can put together -- sometimes this
+ * comes from the file itself, other times from the MODX file
+ * @param $inline_find - Subset of $find or NULL
+ * @param $action_type - Name of the MODX action being taken
+ * @param $action - The code which is being inserted into the file
+ * @return void
+ */
+ function build_uninstall($find, $inline_find, $action_type, $action)
+ {
+ $find = trim($find);
+ $inline_find = trim($inline_find);
+ $action = trim($action);
+
+ /*
+ * This if statement finds out if we are in the special case where
+ * a MOD specifies a before action and an after action on the same
+ * find. If this is the case, the uninstaller must see a replace
+ * rather than an add
+ */
+ if (!empty($this->last_action) && $this->last_action[0] == $this->curr_action[0] &&
+ (($this->last_action[2] == 'AFTER' && $this->curr_action[2] == 'BEFORE')
+ || ($this->last_action[2] == 'BEFORE' && $this->curr_action[2] == 'AFTER')))
+ {
+ $last_action_index = sizeof($this->mod_actions[$this->open_filename]) - 1;
+ unset($this->mod_actions[$this->open_filename][$last_action_index]);
+
+ // Re-index the array to start at zero and go sequentially
+ $this->mod_actions[$this->open_filename] = array_merge($this->mod_actions[$this->open_filename]);
+
+ $action_type = 'REPLACE';
+
+ // Remove the add from the find -- this is an effect of the way the
+ // add method works, putting the new lines in the same array element
+ // as the find
+ if (!empty($this->last_action))
+ {
+ $find = str_replace(trim($this->last_action[1]), '', $find);
+ }
+
+ if ($this->last_action[2] == 'AFTER')
+ {
+ $action = $this->curr_action[1] . "\n" . $this->curr_action[0] . "\n" . $this->last_action[1];
+ }
+ else // implicit if ($this->last_action[2] == 'BEFORE')
+ {
+ $action = $this->last_action[1] . "\n" . $this->curr_action[0] . "\n" . $this->curr_action[1];
+ }
+ }
+
+ // Build another complex array of MOD Actions
+ // This approach is rather memory-intensive ... it might behoove us
+ // to think of something else
+ if (!$inline_find)
+ {
+ $this->mod_actions[$this->open_filename][] = array(
+ $find => array(
+ $action_type => $action,
+ )
+ );
+ }
+ else
+ {
+ $this->mod_actions[$this->open_filename][] = array(
+ $find => array(
+ 'in-line-edit' => array(
+ $inline_find => array(
+ $action_type => array($action),
+ ),
+ ),
+ ),
+ );
+ }
+
+ $this->last_action = $this->curr_action;
+ }
+
+ function clear_actions()
+ {
+ // free some memory
+ $this->mod_actions = array();
+ }
+ }
+
+ /**
+ * @package automod
+ * class editor_direct will alter files by using the local file access functions
+ * such as fopen and fwrite. This is typically only useful in Windows environments
+ * due to permissions settings.
+ */
+ class editor_direct extends editor
+ {
+ function editor_direct()
+ {
+ $this->write_method = WRITE_DIRECT;
+ $this->install_time = time();
+ }
+
+ /**
+ * Moves files or complete directories
+ *
+ * @param $from string Can be a file or a directory. Will move either the file or all files within the directory
+ * @param $to string Where to move the file(s) to. If not specified then will get moved to the root folder
+ * @param $strip Used for FTP only
+ * @return mixed: Bool true on success, error string on failure, NULL if no action was taken
+ *
+ * NOTE: function should preferably not return in case of failure on only one file.
+ * The current method makes error handling difficult
+ */
+ function copy_content($from, $to = '', $strip = '')
+ {
+ global $phpbb_root_path, $user, $config;
+
+ if (strpos($from, $phpbb_root_path) !== 0)
+ {
+ $from = $phpbb_root_path . $from;
+ }
+
+ // When installing a MODX 1.2.0 MOD, this happens once in a long while.
+ // Not sure why yet.
+ if (is_array($to))
+ {
+ return NULL;
+ }
+
+ if (strpos($to, $phpbb_root_path) !== 0)
+ {
+ $to = $phpbb_root_path . $to;
+ }
+
+ $files = array();
+ if (is_dir($from))
+ {
+ // get all of the files within the directory
+ $files = find_files($from, '.*');
+ }
+ else if (is_file($from))
+ {
+ $files = array($from);
+ }
+
+ if (empty($files))
+ {
+ return false;
+ }
+
+ // Look at the last character of $to and compare it to '/'
+ if ($to[strlen($to) - 1] == '/')
+ {
+ $dirname_check = $to;
+ }
+ else
+ {
+ $dirname_check = dirname($to);
+ }
+
+ if (!is_dir($dirname_check))
+ {
+ if ($this->recursive_mkdir($dirname_check) === false)
+ {
+ return sprintf($user->lang['MODS_MKDIR_FAILURE'], $dirname_check);
+ }
+ }
+
+ foreach ($files as $file)
+ {
+ if (is_dir($to))
+ {
+ $dest = str_replace($from, $to, $file);
+
+ if (!file_exists($dest))
+ {
+ $this->recursive_mkdir(dirname($dest));
+ }
+ }
+ else
+ {
+ $dest = $to;
+ }
+
+ if (!@copy($file, $dest))
+ {
+ return sprintf($user->lang['MODS_COPY_FAILURE'], $dest);
+ }
+ @chmod($dest, octdec($config['am_file_perms']));
+ }
+
+ return true;
+ }
+
+ function close_file($new_filename)
+ {
+ global $phpbb_root_path, $config, $mod_installed, $mod_uninstalled, $force_install;
+ global $db, $user;
+
+ if (!is_dir($new_filename) && !file_exists(dirname($new_filename)))
+ {
+ if ($this->recursive_mkdir(dirname($new_filename)) === false)
+ {
+ return sprintf($user->lang['MODS_MKDIR_FAILED'], dirname($new_filename));
+ }
+ }
+
+ $file_contents = implode('', $this->file_contents);
+
+ if (file_exists($new_filename) && !is_writable($new_filename))
+ {
+ return sprintf($user->lang['WRITE_DIRECT_FAIL'], $new_filename);
+ }
+
+ if ($this->template_id && ($mod_installed || $mod_uninstalled || $force_install))
+ {
+ update_database_template($new_filename, $this->template_id, $file_contents, $this->install_time);
+ }
+
+ // If we are not looking at a file stored in the database, use local file functions
+ $fr = @fopen($new_filename, 'wb');
+ $length_written = @fwrite($fr, $file_contents);
+ @chmod($new_filename, octdec($config['am_file_perms']));
+
+ // This appears to be correct even with multibyte encodings. strlen and
+ // fwrite both return the number of bytes written, not the number of chars
+ if ($length_written < strlen($file_contents))
+ {
+ return sprintf($user->lang['WRITE_DIRECT_TOO_SHORT'], $new_filename);
+ }
+
+ if (!@fclose($fr))
+ {
+ return sprintf($user->lang['WRITE_DIRECT_FAIL'], $new_filename);
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a backup of the currently open file before AutoMOD makes any changes
+ */
+ function backup_file($backup_dir)
+ {
+ if (!$backup_dir)
+ {
+ return;
+ }
+
+ return $this->close_file($backup_dir . $this->open_filename);
+ }
+
+ /**
+ * @author Michal Nazarewicz (from the php manual)
+ * Creates all non-existant directories in a path
+ * @param $path - path to create
+ * @param $mode - CHMOD the new dir to these permissions
+ * @return bool
+ */
+ function recursive_mkdir($path, $mode = false)
+ {
+ if (!$mode)
+ {
+ global $config;
+ $mode = octdec($config['am_dir_perms']);
+ }
+
+ $dirs = explode('/', $path);
+ $count = sizeof($dirs);
+ $path = '.';
+ for ($i = 0; $i < $count; $i++)
+ {
+ $path .= '/' . $dirs[$i];
+
+ if (!is_dir($path))
+ {
+ @mkdir($path, $mode);
+ @chmod($path, $mode);
+
+ if (!is_dir($path))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ function commit_changes($source, $destination)
+ {
+ return $this->copy_content($source, $destination, $source);
+ }
+
+ function commit_changes_final($source, $destination)
+ {
+ return NULL;
+ }
+
+ function create_edited_root($dir)
+ {
+ return $this->recursive_mkdir($dir);
+ }
+ }
+
+ class editor_ftp extends editor
+ {
+ var $transfer;
+
+ function editor_ftp()
+ {
+ global $config, $user;
+
+ $this->write_method = WRITE_FTP;
+ $this->install_time = time();
+
+ if (!class_exists('transfer'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
+ }
+
+ $this->transfer = new $config['ftp_method']($config['ftp_host'], $config['ftp_username'], request_var('password', ''), $config['ftp_root_path'], $config['ftp_port'], $config['ftp_timeout']);
+ $error = $this->transfer->open_session();
+
+ // Use the permissions settings specified in the AutoMOD configuration
+ $this->transfer->dir_perms = octdec($config['am_dir_perms']);
+ $this->transfer->file_perms = octdec($config['am_file_perms']);
+
+ if (is_string($error))
+ {
+ // FTP login failed
+ trigger_error(sprintf($user->lang['MODS_FTP_CONNECT_FAILURE'], $user->lang[$error]), E_USER_ERROR);
+ }
+ }
+
+ /**
+ * Moves files or complete directories
+ *
+ * @param $from string Can be a file or a directory. Will move either the file or all files within the directory
+ * @param $to string Where to move the file(s) to. If not specified then will get moved to the root folder
+ * @param $strip Used for FTP only
+ * @return mixed: Bool true on success, error string on failure, NULL if no action was taken
+ *
+ * NOTE: function should preferably not return in case of failure on only one file.
+ * The current method makes error handling difficult
+ */
+ function copy_content($from, $to = '', $strip = '')
+ {
+ global $phpbb_root_path, $user;
+
+ if (strpos($from, $phpbb_root_path) !== 0)
+ {
+ $from = $phpbb_root_path . $from;
+ }
+
+ // When installing a MODX 1.2.0 MOD, this happens once in a long while.
+ // Not sure why yet.
+ if (is_array($to))
+ {
+ return NULL;
+ }
+
+ if (strpos($to, $phpbb_root_path) !== 0)
+ {
+ $to = $phpbb_root_path . $to;
+ }
+
+ $files = array();
+ if (is_dir($from))
+ {
+ // get all of the files within the directory
+ $files = find_files($from, '.*');
+ }
+ else if (is_file($from))
+ {
+ $files = array($from);
+ }
+
+ if (empty($files))
+ {
+ return false;
+ }
+
+ // ftp
+ foreach ($files as $file)
+ {
+ if (is_dir($to))
+ {
+ $to_file = str_replace(array($phpbb_root_path, $strip), '', $file);
+ }
+ else
+ {
+ $to_file = str_replace($phpbb_root_path, '', $to);
+ }
+
+ $this->recursive_mkdir(dirname($to_file));
+
+ if (!$this->transfer->overwrite_file($file, $to_file))
+ {
+ // may as well return ... the MOD is likely dependent upon
+ // the file that is being copied
+ return sprintf($user->lang['MODS_FTP_FAILURE'], $to_file);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Write & close file
+ */
+ function close_file($new_filename)
+ {
+ global $phpbb_root_path, $edited_root, $mod_installed, $mod_uninstalled, $force_install;
+ global $db, $user;
+
+ if (!is_dir($new_filename) && !file_exists(dirname($new_filename)))
+ {
+ if ($this->recursive_mkdir(dirname($new_filename)) === false)
+ {
+ return sprintf($user->lang['MODS_MKDIR_FAILED'], dirname($new_filename));
+ }
+ }
+
+ $file_contents = implode('', $this->file_contents);
+
+ if ($this->template_id && ($mod_installed || $mod_uninstalled || $force_install))
+ {
+ update_database_template($new_filename, $this->template_id, $file_contents, $this->install_time);
+ }
+
+ if (!$this->transfer->write_file($new_filename, $file_contents))
+ {
+ return sprintf($user->lang['MODS_FTP_FAILURE'], $new_filename);
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a backup of the currently open file before AutoMOD makes any changes
+ */
+ function backup_file($backup_dir)
+ {
+ return $this->close_file($backup_dir . $this->open_filename);
+ }
+
+ /**
+ * @ignore
+ */
+ function recursive_mkdir($path, $mode = 0777)
+ {
+ return $this->transfer->make_dir($path);
+ }
+
+ function commit_changes($source, $destination)
+ {
+ // Move edited files back
+ return $this->copy_content($source, $destination, $source);
+ }
+
+ function commit_changes_final($source, $destionation)
+ {
+ return NULL;
+ }
+
+ function create_edited_root($dir)
+ {
+ return $this->recursive_mkdir($dir);
+ }
+ }
+
+ class editor_manual extends editor
+ {
+ function editor_manual()
+ {
+ global $config, $phpbb_root_path;
+
+ $this->write_method = WRITE_MANUAL;
+ $this->install_time = time();
+
+ if (!class_exists('compress'))
+ {
+ global $phpEx;
+ include($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
+ }
+
+ // Ugly regular expression to extract "tar" from "tar.gz" or "tar.bz2"
+ // Made ugly because it does nothing with "zip"
+ preg_match('#\.(\w{3})\.?.*#', $config['compress_method'], $match);
+ $class = 'compress_' . $match[1];
+
+ $this->compress = new $class('w', $phpbb_root_path . 'store/mod_' . $this->install_time . $config['compress_method'], $config['compress_method']);
+ }
+
+ function copy_content($from, $to = '', $strip = '')
+ {
+ global $phpbb_root_path, $user;
+
+ if (strpos($from, $phpbb_root_path) !== 0)
+ {
+ $from = $phpbb_root_path . $from;
+ }
+
+ if (strpos($to, $phpbb_root_path) !== 0)
+ {
+ $to = $phpbb_root_path . $to;
+ }
+
+ // Note: phpBB's compression class does support adding a whole directory at a time.
+ // However, I chose not to use that function because it would not allow AutoMOD's
+ // error handling to work the same as for FTP & Direct methods.
+ $files = array();
+ if (is_dir($from))
+ {
+ // get all of the files within the directory
+ $files = find_files($from, '.*');
+ }
+ else if (is_file($from))
+ {
+ $files = array($from);
+ }
+
+ if (empty($files))
+ {
+ return false;
+ }
+
+ foreach ($files as $file)
+ {
+ if (is_dir($to))
+ {
+ $to_file = str_replace(array($phpbb_root_path, $strip), '', $file);
+ }
+ else
+ {
+ $to_file = str_replace($phpbb_root_path, '', $to);
+ }
+
+ // filename calculation is involved here: be sure to remove "store/mods/foo"
+ // and prepend the "files" directory
+ if (!$this->compress->add_file($to_file, substr($to_file, 0, strpos($to_file, 'root/') + 5), 'files'))
+ {
+ return sprintf($user->lang['WRITE_MANUAL_FAIL'], $new_filename);
+ }
+ }
+
+ // return true since we are now taking an action - NULL implies no action
+ return true;
+ }
+
+ /**
+ * Write & close file
+ */
+ function close_file($new_filename)
+ {
+ global $phpbb_root_path, $edited_root, $mod_installed, $mod_uninstalled, $force_install;
+ global $db, $user;
+
+ $file_contents = implode('', $this->file_contents);
+
+ if ($this->template_id && ($mod_installed || $mod_uninstalled || $force_install))
+ {
+ update_database_template($new_filename, $this->template_id, $file_contents, $this->install_time);
+ }
+
+ // don't include extra dirs in zip file
+ $strip_position = strpos($new_filename, '_edited') + 8; // want the end of the string
+ if (!$strip_position)
+ {
+ $strip_position = strpos($new_filename, '_uninst') + 7;
+ }
+
+ $new_filename = 'files/' . substr($new_filename, $strip_position);
+
+ if (!$this->compress->add_data($file_contents, $new_filename))
+ {
+ return sprintf($user->lang['WRITE_MANUAL_FAIL'], $new_filename);
+ }
+
+ return true;
+ }
+
+ /**
+ * Backup is undefined when creating a compressed file.
+ */
+ function backup_file($backup_dir)
+ {
+ return NULL;
+ }
+
+ function recursive_mkdir($path, $mode = 0777)
+ {
+ return NULL;
+ }
+
+ function commit_changes($source, $destination)
+ {
+ global $template, $user, $phpbb_admin_path;
+
+ $download_url = append_sid("{$phpbb_admin_path}index.php", 'i=mods&mode=frontend&action=download&time=' . $this->install_time);
+
+ $template->assign_vars(array(
+ 'S_MANUAL_INSTRUCTIONS' => true,
+ 'L_AM_MANUAL_INSTRUCTIONS' => sprintf($user->lang['AM_MANUAL_INSTRUCTIONS'], '<a href="' . $download_url . '">', '</a>'),
+ ));
+
+ meta_refresh(3, $download_url);
+
+ $this->compress->close();
+ return true;
+ }
+
+ function commit_changes_final($source, $destination)
+ {
+ return NULL;
+ }
+
+ function create_edited_root($dir)
+ {
+ return NULL;
+ }
+ }
+
+ ?>
\ No newline at end of file
Propchange: trunk/titania/includes/library/automod/editor.php
------------------------------------------------------------------------------
svn:keywords = Revision Author Date Id
Added: trunk/titania/includes/library/automod/functions_mods.php
==============================================================================
*** trunk/titania/includes/library/automod/functions_mods.php (added)
--- trunk/titania/includes/library/automod/functions_mods.php Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,321 ----
+ <?php
+ /**
+ *
+ * @package automod
+ * @version $Id$
+ * @copyright (c) 2008 phpBB Group
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
+ *
+ */
+
+ /**
+ * @ignore
+ */
+ if (!defined('IN_PHPBB'))
+ {
+ exit;
+ }
+
+ global $table_prefix;
+ define('MODS_TABLE', $table_prefix . 'mods');
+
+ define('WRITE_DIRECT', 1);
+ define('WRITE_FTP', 2);
+ define('WRITE_MANUAL', 3);
+
+ function test_ftp_connection($method, &$test_ftp_connection, &$test_connection)
+ {
+ global $phpbb_root_path, $phpEx;
+
+ $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
+
+ $test_connection = $transfer->open_session();
+
+ // Make sure that the directory is correct by checking for the existence of common.php
+ if ($test_connection === true)
+ {
+ // Check for common.php file
+ if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx))
+ {
+ $test_connection = 'ERR_WRONG_PATH_TO_PHPBB';
+ }
+ }
+
+ $transfer->close_session();
+
+ // Make sure the login details are correct before continuing
+ if ($test_connection !== true)
+ {
+ $test_ftp_connection = true;
+ }
+
+ return;
+ }
+
+ /**
+ * Helper function
+ * Runs basename() on $path, then trims the extension from it
+ * @param string $path - path to be basenamed
+ */
+ function core_basename($path)
+ {
+ $path = basename($path);
+ $path = substr($path, 0, strrpos($path, '.'));
+
+ $parts = explode('-', $path);
+ return end($parts);
+ }
+
+ /**
+ * Helper function for matching languages
+ * This is a fairly dumb function because it ignores dialects. But I have
+ * not seen any MODs that specify more than one dialect of the same language
+ * @param string $user_language - ISO language code of the current user
+ * @param string $xml_language - ISO language code of the MODX tag
+ * @return bool Whether or not this is a match
+ */
+ function match_language($user_language, $xml_language)
+ {
+ return strtolower(substr($user_language, 0, 2)) == strtolower(substr($xml_language, 0, 2));
+ }
+
+ /**
+ * Easy method to grab localisable tags from the XML array
+ * @param $header - variable holding all relevant tag information
+ * @param $tagname - tag name to fetch
+ * @param $index - Index number to pull. Not required.
+ * @return $output - Localised contents of the tag in question
+ */
+ function localise_tags($header, $tagname, $index = false)
+ {
+ global $user;
+
+ $output = '';
+
+ if (isset($header[$tagname]) && is_array($header[$tagname]))
+ {
+ foreach ($header[$tagname] as $i => $void)
+ {
+ // Ugly.
+ if ($index !== false && $index != $i)
+ {
+ continue;
+ }
+
+ if (!isset($header[$tagname][$i]['attrs']['LANG']))
+ {
+ // avoid notice...although, if we get here, MODX is invalid.
+ continue;
+ }
+
+ if (match_language($user->data['user_lang'], $header[$tagname][$i]['attrs']['LANG']))
+ {
+ $output = isset($header[$tagname][$i]['data']) ? htmlspecialchars(trim($header[$tagname][$i]['data'])) : '';
+ }
+ }
+
+ // If there was no language match, put something out there
+ // This is probably fairly common for non-English users of the MODs Manager
+ if (!$output)
+ {
+ $output = isset($header[$tagname][0]['data']) ? htmlspecialchars(trim($header[$tagname][0]['data'])) : '';
+ }
+ }
+
+ if (!$output)
+ {
+ // Should never happen. If it does, either the MOD is not valid MODX
+ // or the tag being localised is optional
+ $output = isset($user->lang['UNKNOWN_MOD_' . $tagname]) ? $user->lang['UNKNOWN_MOD_' . $tagname] : 'UNKNOWN_MOD_' .$tagname;
+ }
+
+ return $output;
+ }
+
+ /**
+ * List files matching specified PCRE pattern.
+ *
+ * @access public
+ * @param string Relative or absolute path to the directory to be scanned.
+ * @param string Search pattern (perl compatible regular expression).
+ * @param integer Number of subdirectory levels to scan (set to 1 to scan only current).
+ * @param integer This one is used internally to control recursion level.
+ * @return array List of all files found matching the specified pattern.
+ */
+ function find_files($directory, $pattern, $max_levels = 20, $_current_level = 1)
+ {
+ if ($_current_level <= 1)
+ {
+ if (strpos($directory, '\\') !== false)
+ {
+ $directory = str_replace('\\', '/', $directory);
+ }
+ if (empty($directory))
+ {
+ $directory = './';
+ }
+ else if (substr($directory, -1) != '/')
+ {
+ $directory .= '/';
+ }
+ }
+
+ $files = array();
+ $subdir = array();
+ if (is_dir($directory))
+ {
+ $handle = @opendir($directory);
+ while (($file = @readdir($handle)) !== false)
+ {
+ if ($file == '.' || $file == '..')
+ {
+ continue;
+ }
+
+ $fullname = $directory . $file;
+
+ if (is_dir($fullname))
+ {
+ if ($_current_level < $max_levels)
+ {
+ $subdir = array_merge($subdir, find_files($fullname . '/', $pattern, $max_levels, $_current_level + 1));
+ }
+ }
+ else
+ {
+ if (preg_match('/^' . $pattern . '$/i', $file))
+ {
+ $files[] = $fullname;
+ }
+ }
+ }
+ @closedir($handle);
+ sort($files);
+ }
+
+ return array_merge($files, $subdir);
+ }
+
+ /**
+ * This function is common to all editor classes, so it is pulled out from them
+ * @param $filename - The filename to update
+ * @param $template_id - The template set to update
+ * @param $file_contents - The data to write
+ * @param $install_time - Essentially the current time
+ * @return bool true
+ */
+ function update_database_template($filename, $template_id, $file_contents, $install_time)
+ {
+ global $db;
+
+ // grab filename
+ preg_match('#styles/[a-z0-9_]+/template/([a-z0-9_]+.html)#i', $filename, $match);
+
+ if (empty($match[1]))
+ {
+ return false;
+ }
+
+ $sql = 'UPDATE ' . STYLES_TEMPLATE_DATA_TABLE . "
+ SET template_data = '" . $db->sql_escape($file_contents) . "', template_mtime = " . (int) $install_time . '
+ WHERE template_id = ' . (int) $template_id . "
+ AND template_filename = '" . $db->sql_escape($match[1]) . "'";
+ $db->sql_query($sql);
+
+ // if something failed, sql_query will error out
+ return true;
+ }
+
+ function determine_write_method($pre_install = false)
+ {
+ global $phpbb_root_path, $config;
+
+ // to be truly correct, we should scan all files ...
+ if ((is_writable($phpbb_root_path) && $config['write_method'] == WRITE_DIRECT) || $pre_install)
+ {
+ $write_method = 'direct';
+ }
+ // FTP Method is now auto-detected
+ else if ($config['write_method'] == WRITE_FTP)
+ {
+ $write_method = 'ftp';
+ }
+ // or zip or tarballs
+ else if ($config['compress_method'])
+ {
+ $write_method = 'manual';
+ }
+ else
+ {
+ // We cannot go on without a write method set up.
+ trigger_error('MODS_SETUP_INCOMPLETE', E_USER_ERROR);
+ }
+
+ return $write_method;
+ }
+
+ function handle_ftp_details($method, $test_ftp_connection, $test_connection)
+ {
+ global $config, $template, $user;
+
+ $s_hidden_fields = build_hidden_fields(array('method' => $method));
+
+ if (!class_exists($method))
+ {
+ trigger_error('Method does not exist.', E_USER_ERROR);
+ }
+
+ $requested_data = call_user_func(array($method, 'data'));
+ foreach ($requested_data as $data => $default)
+ {
+ $default = (!empty($config['ftp_' . $data])) ? $config['ftp_' . $data] : $default;
+
+ $template->assign_block_vars('data', array(
+ 'DATA' => $data,
+ 'NAME' => $user->lang[strtoupper($method . '_' . $data)],
+ 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'],
+ 'DEFAULT' => (!empty($_REQUEST[$data])) ? request_var($data, '') : $default
+ ));
+ }
+
+ $template->assign_vars(array(
+ 'S_CONNECTION_SUCCESS' => ($test_ftp_connection && $test_connection === true) ? true : false,
+ 'S_CONNECTION_FAILED' => ($test_ftp_connection && $test_connection !== true) ? true : false,
+ 'ERROR_MSG' => ($test_ftp_connection && $test_connection !== true) ? $user->lang[$test_connection] : '',
+
+ 'S_FTP_UPLOAD' => true,
+ 'UPLOAD_METHOD' => $method,
+ 'S_HIDDEN_FIELDS_FTP' => $s_hidden_fields,
+ ));
+ }
+
+ /**
+ * PHP 5 Wrapper - simulate scandir, but only those features that we actually need
+ * NB: The third parameter of PHP5 native scandir is _not_ present in this wrapper
+ */
+ if (!function_exists('scandir'))
+ {
+ function scandir($directory, $sorting_order = false)
+ {
+ $files = array();
+
+ $dp = opendir($directory);
+ while (($filename = readdir($dp)) !== false)
+ {
+ $files[] = $filename;
+ }
+
+ if ($sorting_order)
+ {
+ rsort($files);
+ }
+ else
+ {
+ sort($files);
+ }
+
+ return $files;
+ }
+ }
+
+ ?>
\ No newline at end of file
Propchange: trunk/titania/includes/library/automod/functions_mods.php
------------------------------------------------------------------------------
svn:keywords = Revision Author Date Id
Added: trunk/titania/includes/library/automod/mod_parser.php
==============================================================================
*** trunk/titania/includes/library/automod/mod_parser.php (added)
--- trunk/titania/includes/library/automod/mod_parser.php Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,730 ----
+ <?php
+ /**
+ *
+ * @package automod
+ * @version $Id$
+ * @copyright (c) 2008 phpBB Group
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
+ *
+ */
+ /**
+ */
+ if (!defined('IN_PHPBB'))
+ {
+ exit;
+ }
+
+ /**
+ * MOD Parser class
+ * Basic wrapper to run individual parser functions
+ * Also contains some parsing functions that are global (i.e. needed for all parsers)
+ * @package automod
+ *
+ * Each parser requires the following functions:
+ * ~ set_file($path_to_mod_file)
+ * ~ a means of setting the data to be acted upon
+ * ~ get_details()
+ * ~ returns an array of information about the MOD
+ * ~ get_actions()
+ * ~ returns an array of the MODs actions
+ * ~ get_modx_version
+ * ~ returns the MODX version of the MOD being looked at
+ *
+ */
+ class parser
+ {
+ var $parser;
+
+ /**
+ * constructor, sets type of parser
+ */
+ function parser($ext)
+ {
+ switch ($ext)
+ {
+ case 'xml':
+ default:
+ $this->parser = new parser_xml();
+ break;
+ }
+ }
+
+ function set_file($file)
+ {
+ $this->parser->set_file($file);
+ }
+
+ function get_details()
+ {
+ return $this->parser->get_details();
+ }
+
+ function get_actions()
+ {
+ return $this->parser->get_actions();
+ }
+
+ function get_modx_version()
+ {
+ if (!$this->parser->modx_version)
+ {
+ $this->get_details();
+ }
+
+ return $this->parser->modx_version;
+ }
+
+ /**
+ * Returns the needed sql query to reverse the actions taken by the given query
+ * @todo: Add more
+ */
+ function reverse_query($orig_query)
+ {
+ if (preg_match('#ALTER TABLE\s([a-z_]+)\sADD(COLUMN|)\s([a-z_]+)#i', $orig_query, $matches))
+ {
+ return "ALTER TABLE {$matches[1]} DROP COLUMN {$matches[3]};";
+ }
+ else if (preg_match('#CREATE TABLE\s([a-z_])+#i', $orig_query, $matches))
+ {
+ return "DROP TABLE {$matches[1]};";
+ }
+
+ return false;
+ }
+
+ /**
+ * Parse sql
+ *
+ * @param array $sql_query
+ */
+ function parse_sql(&$sql_query)
+ {
+ global $dbms, $table_prefix;
+
+ if (!function_exists('get_available_dbms'))
+ {
+ global $phpbb_root_path, $phpEx;
+
+ include($phpbb_root_path . 'includes/functions_install.' . $phpEx);
+ }
+
+ static $available_dbms;
+
+ if (!isset($available_dbms))
+ {
+ $available_dbms = get_available_dbms($dbms);
+ }
+
+ $remove_remarks = $available_dbms[$dbms]['COMMENTS'];
+ $delimiter = $available_dbms[$dbms]['DELIM'];
+
+ if (sizeof($sql_query) == 1)
+ {
+ // do some splitting here
+ $sql_query = preg_replace('#phpbb_#i', $table_prefix, $sql_query);
+ $remove_remarks($sql_query[0]);
+ $sql_query = split_sql_file($sql_query[0], $delimiter);
+ }
+ else
+ {
+ $query_count = sizeof($sql_query);
+ for ($i = 0; $i < $query_count; $i++)
+ {
+ $sql_query[$i] = preg_replace('#phpbb_#i', $table_prefix, $sql_query[$i]);
+ $remove_remarks($sql_query[$i]);
+ }
+ }
+
+ //return $sql_query;
+ }
+
+ /**
+ * Returns the edits array, but now filled with edits to reverse the given array
+ * @todo: Add more
+ */
+ function reverse_edits($actions)
+ {
+ $reverse_edits = array();
+
+ foreach ($actions['EDITS'] as $file => $edit_ary)
+ {
+ foreach ($edit_ary as $edit_id => $edit)
+ {
+ foreach ($edit as $find => $action_ary)
+ {
+ foreach ($action_ary as $type => $command)
+ {
+ // it is possible for a single edit in the install process
+ // to become more than one in the uninstall process
+ while (isset($reverse_edits['EDITS'][$file][$edit_id]))
+ {
+ $edit_id++;
+ }
+
+ switch (strtoupper($type))
+ {
+ // for before and after adds, we use the find as a tool for more precise finds
+ // this isn't perfect, but it seems better than having
+ // finds of only a couple characters, like "/*"
+ case 'AFTER ADD':
+ $total_find = rtrim($find, "\n") . "\n" . trim($command, "\n");
+
+ $reverse_edits['EDITS'][$file][$edit_id][$total_find]['replace with'] = $find;
+ break;
+
+ case 'BEFORE ADD':
+ $total_find = rtrim($command, "\n") . "\n" . trim($find, "\n");
+
+ // replace with the find
+ $reverse_edits['EDITS'][$file][$edit_id][$total_find]['replace with'] = $find;
+ break;
+
+ case 'REPLACE WITH':
+ case 'REPLACE, WITH':
+ case 'REPLACE-WITH':
+ case 'REPLACE':
+ // replace $command (new code) with $find (original code)
+ $reverse_edits['EDITS'][$file][$edit_id][$command]['replace with'] = $find;
+ break;
+
+ case 'IN-LINE-EDIT':
+ // build the reverse just like the normal action
+ foreach ($command as $inline_find => $inline_action_ary)
+ {
+ foreach ($inline_action_ary as $inline_action => $inline_command)
+ {
+ $inline_command = $inline_command[0];
+
+ switch (strtoupper($inline_action))
+ {
+ case 'IN-LINE-AFTER-ADD':
+ case 'IN-LINE-BEFORE-ADD':
+ // Replace with a blank string
+ $reverse_edits['EDITS'][$file][$edit_id][$find]['in-line-edit'][$inline_command]['in-line-replace'][] = '';
+ break;
+
+ case 'IN-LINE-REPLACE':
+ // replace with the inline find
+ $reverse_edits['EDITS'][$file][$edit_id][$find]['in-line-edit'][$inline_command][$inline_action][] = $inline_find;
+ break;
+
+ default:
+ // For the moment, we do nothing. What about increment?
+ break;
+ }
+ }
+ }
+ break;
+
+ case 'SQL':
+ $reverse_edits['SQL'][] = $this->reverse_query($command);
+ break;
+
+ default:
+ // again, increment
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return $reverse_edits;
+ }
+ }
+
+ /**
+ * XML parser
+ * @package automod
+ */
+ class parser_xml
+ {
+ var $data;
+ var $file;
+ var $modx_version;
+
+ /**
+ * set data to read from
+ */
+ function set_file($file)
+ {
+ // Shouldn't ever happen since the master class reads file names from
+ // the file system and lists them
+ if (!file_exists($file))
+ {
+ trigger_error('Cannot locate File: ' . $file);
+ }
+
+ $this->file = $file;
+ $this->data = trim(@file_get_contents($file));
+ $this->data = str_replace(array("\r\n", "\r"), "\n", $this->data);
+
+ $XML = new xml_array();
+ $this->data = $XML->parse($this->file, $this->data);
+
+ return;
+ }
+
+ /**
+ * 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;
+ }
+
+ $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)),
+ // 'MOD_DEPENDENCIES' => (isset($header['TITLE'][0]['data'])) ? htmlspecialchars(trim($header['TITLE'][0]['data'])) : '',
+
+ '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 complex array containing all mod actions
+ */
+ function get_actions()
+ {
+ global $db, $user;
+
+ $actions = array();
+
+ $xml_actions = $this->data[0]['children']['ACTION-GROUP'][0]['children'];
+
+ // sql
+ $actions['SQL'] = array();
+ $sql_info = (!empty($xml_actions['SQL'])) ? $xml_actions['SQL'] : array();
+
+ $match_dbms = array();
+ switch ($db->sql_layer)
+ {
+ case 'firebird':
+ case 'oracle':
+ case 'postgres':
+ case 'sqlite':
+ case 'mssql':
+ case 'db2':
+ $match_dbms = array($db->sql_layer);
+ break;
+
+ case 'mssql_odbc':
+ $match_dbms = array('mssql');
+ break;
+
+ // and now for the MySQL fun
+ // This will generate an array of things we can probably use, but
+ // will not have any priority
+ case 'mysqli':
+ $match_dbms = array('mysql_41', 'mysqli', 'mysql');
+ break;
+
+ case 'mysql4':
+ case 'mysql':
+ if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
+ {
+ $match_dbms = array('mysql_41', 'mysql4', 'mysql', 'mysqli');
+ }
+ else if (version_compare($db->sql_server_info(true), '4.0.0', '>='))
+ {
+ $match_dbms = array('mysql_40', 'mysql4', 'mysql', 'mysqli');
+ }
+ else
+ {
+ $match_dbms = array('mysql');
+ }
+ break;
+
+ // Should never happen
+ default:
+ break;
+ }
+
+ for ($i = 0; $i < sizeof($sql_info); $i++)
+ {
+ if ($this->modx_version == 1.0)
+ {
+ $actions['SQL'][] = (!empty($sql_info[$i]['data'])) ? trim($sql_info[$i]['data']) : '';
+ }
+ else if ($this->modx_version == 1.2)
+ {
+ // Make a slightly shorter name.
+ $xml_dbms = &$sql_info[$i]['attrs']['DBMS'];
+
+ if (!isset($sql_info[$i]['attrs']['DBMS']) || in_array($xml_dbms, $match_dbms))
+ {
+ $actions['SQL'][] = (!empty($sql_info[$i]['data'])) ? trim($sql_info[$i]['data']) : '';
+ }
+ else
+ {
+ // NOTE: skipped SQL is not currently useful
+ $sql_skipped = true;
+ }
+ }
+ }
+
+ // new files
+ $new_files_info = (!empty($xml_actions['COPY'])) ? $xml_actions['COPY'] : array();
+ for ($i = 0; $i < sizeof($new_files_info); $i++)
+ {
+ $new_files = $new_files_info[$i]['children']['FILE'];
+ for ($j = 0; $j < sizeof($new_files); $j++)
+ {
+ $from = str_replace('\\', '/', $new_files[$j]['attrs']['FROM']);
+ $to = str_replace('\\', '/', $new_files[$j]['attrs']['TO']);
+ $actions['NEW_FILES'][$from] = $to;
+ }
+ }
+
+ // open
+ $open_info = (!empty($xml_actions['OPEN'])) ? $xml_actions['OPEN'] : array();
+ for ($i = 0; $i < sizeof($open_info); $i++)
+ {
+ $current_file = str_replace('\\', '/', trim($open_info[$i]['attrs']['SRC']));
+ $actions['EDITS'][$current_file] = array();
+
+ $edit_info = (!empty($open_info[$i]['children']['EDIT'])) ? $open_info[$i]['children']['EDIT'] : array();
+ // find, after add, before add, replace with
+ for ($j = 0; $j < sizeof($edit_info); $j++)
+ {
+ $action_info = (!empty($edit_info[$j]['children'])) ? $edit_info[$j]['children'] : array();
+
+ // store some array information to help decide what kind of operation we're doing
+ $action_count = $total_action_count = 0;
+ if (isset($action_info['ACTION']))
+ {
+ $action_count += sizeof($action_info['ACTION']);
+ }
+
+ if (isset($action_info['INLINE-EDIT']))
+ {
+ $total_action_count += sizeof($action_info['INLINE-EDIT']);
+ }
+
+ $find_count = sizeof($action_info['FIND']);
+ // first we try all the possibilities for a FIND/ACTION combo, then look at inline possibilities.
+
+ if (isset($action_info['ACTION']))
+ {
+ for ($k = 0; $k < $find_count; $k++)
+ {
+ // is this anything but the last iteration of the loop?
+ if ($k < ($find_count - 1))
+ {
+ // NULL has special meaning for an action ... no action to be taken; advance pointer
+ $actions['EDITS'][$current_file][$j][$action_info['FIND'][$k]['data']] = NULL;
+ }
+ else
+ {
+ // this is the last iteration, assign the action tags
+
+ for ($l = 0; $l < $action_count; $l++)
+ {
+ $type = str_replace('-', ' ', $action_info['ACTION'][$l]['attrs']['TYPE']);
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'], "\n\r")][$type] = (isset($action_info['ACTION'][$l]['data'])) ? preg_replace("#^(\s)+\n#", '', rtrim(trim($action_info['ACTION'][$l]['data'], "\n"))) : '';
+ }
+ }
+ }
+ }
+
+ // add comment to the actions array
+ $actions['EDITS'][$current_file][$j]['comment'] = localise_tags($action_info, 'COMMENT');
+
+ // inline
+ if (isset($action_info['INLINE-EDIT']))
+ {
+ $inline_info = (!empty($action_info['INLINE-EDIT'])) ? $action_info['INLINE-EDIT'] : array();
+
+ if ($find_count > $total_action_count)
+ {
+ // Yeah, $k is used more than once for different information
+ for ($k = 0; $k < $find_count; $k++)
+ {
+ // is this anything but the last iteration of the loop?
+ if ($k < ($find_count - 1))
+ {
+ // NULL has special meaning for an action ... no action to be taken; advance pointer
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$k]['data'], "\r\n")] = NULL;
+ }
+ }
+ }
+
+ /*
+ * This loop attaches the in-line information to the _last
+ * find_ in the <edit> tag. This is the intended behavior
+ * Any additional finds ought to be in a different edit tag
+ */
+ for ($k = 0; $k < sizeof($inline_info); $k++)
+ {
+ $inline_data = (!empty($inline_info[$k]['children'])) ? $inline_info[$k]['children'] : array();
+
+ $inline_find_count = sizeof($inline_data['INLINE-FIND']);
+
+ $inline_comment = localise_tags($inline_data, 'INLINE-COMMENT');
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit']['inline-comment'] = $inline_comment;
+
+ $inline_actions = (!empty($inline_data['INLINE-ACTION'])) ? $inline_data['INLINE-ACTION'] : array();
+ for ($l = 0; $l < $inline_find_count; $l++)
+ {
+ $inline_find = $inline_data['INLINE-FIND'][$l]['data'];
+
+ // trying to reduce the levels of arrays without impairing features.
+ // need to keep the "full" edit intact.
+ //
+ // inline actions must be trimmed in case the MOD author
+ // inserts a new line by mistake
+ if ($l < ($inline_find_count - 1))
+ {
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-'][] = null;
+ }
+ else
+ {
+ for ($m = 0; $m < sizeof($inline_actions); $m++)
+ {
+ $type = str_replace(',', '-', str_replace(' ', '', $inline_actions[$m]['attrs']['TYPE']));
+ if (!empty($inline_actions[$m]['data']))
+ {
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-' . $type][] = trim($inline_actions[$m]['data'], "\n");
+ }
+ else
+ {
+ $actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count - 1]['data'], "\r\n")]['in-line-edit'][$k][$inline_find]['in-line-' . $type][] = '';
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!empty($xml_actions['DIY-INSTRUCTIONS']))
+ {
+ $actions['DIY_INSTRUCTIONS'] = localise_tags($xml_actions, 'DIY-INSTRUCTIONS');
+ }
+
+ return $actions;
+ }
+ }
+
+ /**
+ * XML processing
+ * @package automod
+ */
+ class xml_array
+ {
+ var $output = array();
+ var $parser;
+ var $XML;
+
+ function parse($file, $XML)
+ {
+ $this->parser = xml_parser_create();
+ xml_set_object($this->parser, $this);
+ xml_set_element_handler($this->parser, "tag_open", "tag_closed");
+ xml_set_character_data_handler($this->parser, "tag_data");
+
+ $this->XML = xml_parse($this->parser, $XML);
+ if (!$this->XML)
+ {
+ die(sprintf("<strong>XML error</strong>: %s at line %d. View the file %s in a web browser for a more detailed error message.",
+ xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser), $file));
+ }
+
+ xml_parser_free($this->parser);
+
+ return $this->output;
+ }
+
+ function tag_open($parser, $name, $attrs)
+ {
+ $tag = array("name" => $name, "attrs" => $attrs);
+ array_push($this->output, $tag);
+ }
+
+ function tag_data($parser, $tag_data)
+ {
+ if ($tag_data)
+ {
+ if (isset($this->output[sizeof($this->output) - 1]['data']))
+ {
+ $this->output[sizeof($this->output) - 1]['data'] .= $tag_data;
+ }
+ else
+ {
+ $this->output[sizeof($this->output) - 1]['data'] = $tag_data;
+ }
+ }
+ }
+
+ function tag_closed($parser, $name)
+ {
+ $this->output[sizeof($this->output) - 2]['children'][$name][] = $this->output[sizeof($this->output) - 1];
+ array_pop($this->output);
+ }
+ }
+
+ ?>
\ No newline at end of file
Propchange: trunk/titania/includes/library/automod/mod_parser.php
------------------------------------------------------------------------------
svn:keywords = Revision Author Date Id
Modified: trunk/titania/includes/tools/contrib_tools.php
==============================================================================
*** trunk/titania/includes/tools/contrib_tools.php (original)
--- trunk/titania/includes/tools/contrib_tools.php Sat Mar 27 17:24:58 2010
***************
*** 394,418 ****
/**
* Prepare the files to test automod with
*
! * @param string $version Version string of the revision (30 for 3.0.x, 32 for 3.2.x, etc)
*/
public function automod_phpbb_files($version)
{
! $version = titania::$config->phpbb_versions[$version];
! $phpbb_root = titania::$config->contrib_temp_path . 'phpbb/' . $version . '/';
! if (!file_exists($phpbb_root))
{
// Need to unzip
phpbb::_include('functions_compress', false, 'compress_zip');
// Unzip to our temp directory
! $zip = new compress_zip('r', TITANIA_ROOT . 'includes/tools/automod/phpbb/phpBB-' . $version . '.zip');
$zip->extract($phpbb_root);
$zip->close();
// Find the phpBB root
! $package_root = $this->find_root($phpbb_root, array(array('common.php')));
// Move it to the correct location
if ($package_root != '')
--- 394,419 ----
/**
* Prepare the files to test automod with
*
! * @param string $version the full phpBB version number. Ex: 2.0.23, 3.0.1, 3.0.7-pl1
*/
public function automod_phpbb_files($version)
{
! $version = preg_replace('#[^a-zA-Z0-9\.\-]+#', '', $version);
! $phpbb_root = TITANIA_ROOT . 'store/phpbb_packages/extracted/' . $version . '/';
!
! if (!file_exists($phpbb_root . 'common.php'))
{
// Need to unzip
phpbb::_include('functions_compress', false, 'compress_zip');
// Unzip to our temp directory
! $zip = new compress_zip('r', TITANIA_ROOT . 'store/phpbb_packages/phpBB-' . $version . '.zip');
$zip->extract($phpbb_root);
$zip->close();
// Find the phpBB root
! $package_root = $this->find_root($phpbb_root, 'common.php');
// Move it to the correct location
if ($package_root != '')
***************
*** 466,475 ****
{
phpbb::_include('functions_transfer', false, 'transfer');
phpbb::_include('functions_admin', 'recalc_nested_sets');
! titania::_include('tools/automod/acp_mods', false, 'acp_mods');
! titania::_include('tools/automod/editor', false, 'editor');
! titania::_include('tools/automod/mod_parser', false, 'parser');
! titania::_include('tools/automod/functions_mods', 'test_ftp_connection');
titania::add_lang('automod');
--- 467,476 ----
{
phpbb::_include('functions_transfer', false, 'transfer');
phpbb::_include('functions_admin', 'recalc_nested_sets');
! titania::_include('library/automod/acp_mods', false, 'acp_mods');
! titania::_include('library/automod/editor', false, 'editor');
! titania::_include('library/automod/mod_parser', false, 'parser');
! titania::_include('library/automod/functions_mods', 'test_ftp_connection');
titania::add_lang('automod');
***************
*** 484,490 ****
// Find the first item with install in the name
foreach (scandir($modx_file) as $item)
{
! if (strpos($item, 'install') !== false && strpos($item, '.xml') !== false)
{
$modx_file .= $item;
break;
--- 485,491 ----
// Find the first item with install in the name
foreach (scandir($modx_file) as $item)
{
! if (strpos($item, 'install') !== false && strpos($item, '.xml'))
{
$modx_file .= $item;
break;
Added: trunk/titania/store/phpbb_packages/extracted/index.htm
==============================================================================
*** trunk/titania/store/phpbb_packages/extracted/index.htm (added)
--- trunk/titania/store/phpbb_packages/extracted/index.htm Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,10 ----
+ <html>
+ <head>
+ <title></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ </head>
+
+ <body bgcolor="#FFFFFF" text="#000000">
+
+ </body>
+ </html>
Added: trunk/titania/store/phpbb_packages/index.htm
==============================================================================
*** trunk/titania/store/phpbb_packages/index.htm (added)
--- trunk/titania/store/phpbb_packages/index.htm Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,10 ----
+ <html>
+ <head>
+ <title></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ </head>
+
+ <body bgcolor="#FFFFFF" text="#000000">
+
+ </body>
+ </html>
Added: trunk/titania/store/phpbb_packages/read me.txt
==============================================================================
*** trunk/titania/store/phpbb_packages/read me.txt (added)
--- trunk/titania/store/phpbb_packages/read me.txt Sat Mar 27 17:24:58 2010
***************
*** 0 ****
--- 1,9 ----
+ All files must be named like the following:
+
+ phpBB-(full version).zip
+
+ Example:
+
+ phpBB-2.0.23.zip
+ phpBB-3.0.0.zip
+ phpBB-3.0.7-pl1.zip
\ No newline at end of file
More information about the customisationdb-commits
mailing list