Вход Регистрация
Файл: apwa/includes/mod_parser.php
Строк: 935
<?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':
                
// fix ticket 62689 only enter parser if it is xml
                //http://www.phpbb.com/bugs/modteamtools/62689
                
$this->parser = new parser_xml();
            break;
            default:
        }
    }

    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 TABLEs([a-z_]+)sADD(?:sCOLUMN)?s([a-z_]+)#i'$orig_query$matches))
        {
            return 
"ALTER TABLE {$matches[1]} DROP COLUMN {$matches[2]};";
        }
        else if (
preg_match('#CREATE TABLEs([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();

        if (!empty(
$actions['EDITS']))
        {
            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 $action_id => $inline_edit)
                                    {
                                        foreach (
$inline_edit 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'][$action_id][$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'][$action_id][$inline_command][$inline_action][] = $inline_find;
                                                    break;

                                                    default:
                                                        
// For the moment, we do nothing.  What about increment?
                                                    
break;
                                                }

                                                
$action_id++;
                                            }
                                        }
                                    }
                                break;

                                default:
                                    
// again, increment
                                
break;
                            }
                        }
                    }
                }
            }
        }

        if (!empty(
$actions['NEW_FILES']))
        {
            foreach (
$actions['NEW_FILES'] as $source => $target)
            {
                
$reverse_edits['DELETE_FILES'][$source] = $target;
            }
        }

        if (empty(
$actions['SQL']))
        {
            return 
$reverse_edits;
        }

        if (
sizeof($actions['SQL']) == 1)
        {
            
$actions['SQL'] = explode("n"$actions['SQL'][0]);
        }

        foreach (
$actions['SQL'] as $query)
        {
            
$reverse_edits['SQL'][] = parser::reverse_query($query);
        }

        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("rn""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(=> array('children' => array())),
            
'INSTALLATION'    => array(=> array('children' => array('TARGET-VERSION' => array(=> array('data' => ''))))),
            
'AUTHOR-GROUP'    => array(=> array('children' => array('AUTHOR' => array()))),
            
'HISTORY'        => array(=> 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),
                        
'lang'        => $link_group['LINK'][$i]['attrs']['LANG'],
                    );
                }
            }
        }

        
// try not to hardcode schema?
        
$details = array(
            
'MOD_PATH'         => $this->file,
            
'MOD_NAME'        => get_title($header),
//            '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;
            }
        }

        $delete_files_info = (!empty($xml_actions['
DELETE'])) ? $xml_actions['DELETE'] : array();
        for ($i = 0; $i < sizeof($delete_files_info); $i++)
        {
            $delete_files = $delete_files_info[$i]['
children']['FILE'];
            for ($j = 0; $j < sizeof($delete_files); $j++)
            {
                $name = str_replace('
\', '/', $delete_files[$j]['attrs']['NAME']);
                $actions['
DELETE_FILES'][] = $name;
            }
        }

        // 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 $remove_count $find_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']);
                }

                if (isset(
$action_info['REMOVE']))
                {
                    
$remove_count sizeof($action_info['REMOVE']); // should be an integer bounded between zero and one
                
}

                if (isset(
$action_info['FIND']))
                {
                    
$find_count sizeof($action_info['FIND']);
                }

                
// the basic idea is to transform a "remove" tag into a replace-with action
                
if ($remove_count && !$find_count)
                {
                    
// but we still support it if $remove_count is > 1
                    
for ($k 0$k $remove_count$k++)
                    {
                        
// if there is no find tag associated, handle it directly
                        
$actions['EDITS'][$current_file][$j][trim($action_info['REMOVE'][$k]['data'], "nr")]['replace with'] = '';
                    }
                }
                else if (
$remove_count && $find_count)
                {
                    
// if there is a find and a remove, transform into a replace-with
                    // action, and let the logic below sort out the relationships.
                    
for ($k 0$k $remove_count$k++)
                    {
                        
$insert_index = (isset($action_info['ACTION'])) ? sizeof($action_info['ACTION']) : 0;

                        
$action_info['ACTION'][$insert_index] = array(
                            
'data' => '',
                            
'attrs' => array('TYPE'    => 'replace with'),
                        );
                    }
                }
                else if (!
$find_count)
                {
                    
trigger_error(sprintf($user->lang['INVALID_MOD_NO_FIND'], htmlspecialchars($action_info['ACTION'][0]['data'])), E_USER_WARNING);
                }

                
// 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'], "nr")][$type] = (isset($action_info['ACTION'][$l]['data'])) ? preg_replace("#^(s)+n#"''rtrim(trim($action_info['ACTION'][$l]['data'], "n"))) : '';
                            }
                        }
                    }
                }
                else
                {
                    if (!
$remove_count && !$total_action_count)
                    {
                        
trigger_error(sprintf($user->lang['INVALID_MOD_NO_ACTION'], htmlspecialchars($action_info['FIND'][0]['data'])), E_USER_WARNING);
                    }
                }

                
// 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 (isset(
$inline_info[0]['children']['INLINE-REMOVE']) && sizeof($inline_info[0]['children']['INLINE-REMOVE']))
                    {
                        
// overwrite the existing array with the new one
                        
$inline_info[0]['children'] = array(
                            
'INLINE-FIND'   => $inline_info[0]['children']['INLINE-REMOVE'],
                            
'INLINE-ACTION' => array(
                                
=> array(
                                    
'attrs'    => array('TYPE'    => 'replace-with'),
                                    
'data'    => '',
                                ),
                            ),
                        );
                    }
                    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'], "rn")] = 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 = (isset($inline_data['INLINE-FIND'])) ? sizeof($inline_data['INLINE-FIND']) : 0;

                        
$inline_comment localise_tags($inline_data'INLINE-COMMENT');
                        
$actions['EDITS'][$current_file][$j][trim($action_info['FIND'][$find_count 1]['data'], "rn")]['in-line-edit']['inline-comment'] = $inline_comment;

                        
$inline_actions = (!empty($inline_data['INLINE-ACTION'])) ? $inline_data['INLINE-ACTION'] : array();

                        if (empty(
$inline_actions))
                        {
                            
trigger_error(sprintf($user->lang['INVALID_MOD_NO_ACTION'], htmlspecialchars($inline_data['INLINE-FIND'][0]['data'])), E_USER_WARNING);
                        }
                        if (empty(
$inline_find_count))
                        {
                            
trigger_error(sprintf($user->lang['INVALID_MOD_NO_FIND'], htmlspecialchars($inline_actions[0]['data'])), E_USER_WARNING);
                        }

                        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'], "rn")]['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'], "rn")]['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'], "rn")]['in-line-edit'][$k][$inline_find]['in-line-' $type][] = '';
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        if (!empty(
$xml_actions['PHP-INSTALLER']))
        {
            
$actions['PHP_INSTALLER'] = $xml_actions['PHP-INSTALLER'][0]['data'];
        }

        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)
    {
        
// Should be a string but' let's make sure.
        
$tag_data = (string) $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);
    }
}

?>
Онлайн: 4
Реклама