Exemple #1
0
function parseBoardMod($file, $testing = true, $undo = false, $theme_paths = array())
{
    global $boarddir, $sourcedir, $settings, $txt, $modSettings;
    @set_time_limit(600);
    $file = strtr($file, array("\r" => ''));
    $working_file = null;
    $working_search = null;
    $working_data = '';
    $replace_with = null;
    $actions = array();
    $everything_found = true;
    // This holds all the template changes in the standard mod file.
    $template_changes = array();
    // This is just the temporary file.
    $temp_file = $file;
    // This holds the actual changes on a step counter basis.
    $temp_changes = array();
    $counter = 0;
    $step_counter = 0;
    // Before we do *anything*, let's build a list of what we're editing, as it's going to be used for other theme edits.
    while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $temp_file, $code_match) != 0) {
        $counter++;
        // Get rid of the old stuff.
        $temp_file = substr_replace($temp_file, '', strpos($temp_file, $code_match[0]), strlen($code_match[0]));
        // No interest to us?
        if ($code_match[1] != 'edit file' && $code_match[1] != 'file') {
            // It's a step, let's add that to the current steps.
            if (isset($temp_changes[$step_counter])) {
                $temp_changes[$step_counter]['changes'][] = $code_match[0];
            }
            continue;
        }
        // We've found a new edit - let's make ourself heard, kind of.
        $step_counter = $counter;
        $temp_changes[$step_counter] = array('title' => $code_match[0], 'changes' => array());
        $filename = parse_path($code_match[2]);
        // Now, is this a template file, and if so, which?
        foreach ($theme_paths as $id => $theme) {
            // If this filename is relative, if so take a guess at what it should be.
            if (strpos($filename, 'Themes') === 0) {
                $filename = $boarddir . '/' . $filename;
            }
            if (strpos($filename, $theme['theme_dir']) === 0) {
                $template_changes[$id][$counter] = substr($filename, strlen($theme['theme_dir']) + 1);
            }
        }
    }
    // Anything above $counter must be for custom themes.
    $custom_template_begin = $counter;
    // Reference for what theme ID this action belongs to.
    $theme_id_ref = array();
    // Now we know what templates we need to touch, cycle through each theme and work out what we need to edit.
    if (!empty($template_changes[1])) {
        foreach ($theme_paths as $id => $theme) {
            // Don't do default, it means nothing to me.
            if ($id == 1) {
                continue;
            }
            // Now, for each file do we need to edit it?
            foreach ($template_changes[1] as $pos => $template_file) {
                // It does? Add it to the list darlin'.
                if (file_exists($theme['theme_dir'] . '/' . $template_file) && (!isset($template_changes[$id][$pos]) || !in_array($template_file, $template_changes[$id][$pos]))) {
                    // Actually add it to the mod file too, so we can see that it will work ;)
                    if (!empty($temp_changes[$pos]['changes'])) {
                        $file .= "\n\n" . '<edit file>' . "\n" . $theme['theme_dir'] . '/' . $template_file . "\n" . '</edit file>' . "\n\n" . implode("\n\n", $temp_changes[$pos]['changes']);
                        $theme_id_ref[$counter] = $id;
                        $counter += 1 + count($temp_changes[$pos]['changes']);
                    }
                }
            }
        }
    }
    $counter = 0;
    $is_custom = 0;
    while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $file, $code_match) != 0) {
        // This is for working out what we should be editing.
        $counter++;
        // Edit a specific file.
        if ($code_match[1] == 'file' || $code_match[1] == 'edit file') {
            // Backup the old file.
            if ($working_file !== null) {
                package_chmod($working_file);
                // Don't even dare.
                if (basename($working_file) == 'Settings_bak.php') {
                    continue;
                }
                if (!is_writable($working_file)) {
                    $actions[] = array('type' => 'chmod', 'filename' => $working_file);
                }
                if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) {
                    if (basename($working_file) == 'Settings.php') {
                        @copy($working_file, dirname($working_file) . '/Settings_bak.php');
                    } else {
                        @copy($working_file, $working_file . '~');
                    }
                }
                package_put_contents($working_file, $working_data, $testing);
            }
            if ($working_file !== null) {
                $actions[] = array('type' => 'saved', 'filename' => $working_file, 'is_custom' => $is_custom);
            }
            // Is this "now working on" file a theme specific one?
            $is_custom = isset($theme_id_ref[$counter - 1]) ? $theme_id_ref[$counter - 1] : 0;
            // Make sure the file exists!
            $working_file = parse_path($code_match[2]);
            if ($working_file[0] != '/' && $working_file[1] != ':') {
                trigger_error('parseBoardMod(): The filename \'' . $working_file . '\' is not a full path!', E_USER_WARNING);
                $working_file = $boarddir . '/' . $working_file;
            }
            if (!file_exists($working_file)) {
                $places_to_check = array($boarddir, $sourcedir, $settings['default_theme_dir'], $settings['default_theme_dir'] . '/languages');
                foreach ($places_to_check as $place) {
                    if (file_exists($place . '/' . $working_file)) {
                        $working_file = $place . '/' . $working_file;
                        break;
                    }
                }
            }
            if (file_exists($working_file)) {
                // Load the new file.
                $working_data = str_replace("\r", '', package_get_contents($working_file));
                $actions[] = array('type' => 'opened', 'filename' => $working_file);
            } else {
                $actions[] = array('type' => 'missing', 'filename' => $working_file);
                $working_file = null;
                $everything_found = false;
            }
            // Can't be searching for something...
            $working_search = null;
        } elseif (($code_match[1] == 'search' || $code_match[1] == 'search for') && $working_file !== null) {
            if ($working_search !== null) {
                $actions[] = array('type' => 'error', 'filename' => $working_file);
                $everything_found = false;
            }
            $working_search = $code_match[2];
        } elseif ($working_search !== null) {
            // This is the base string....
            $replace_with = $code_match[2];
            // Add this afterward...
            if ($code_match[1] == 'add' || $code_match[1] == 'add after') {
                $replace_with = $working_search . "\n" . $replace_with;
            } elseif ($code_match[1] == 'before' || $code_match[1] == 'add before' || $code_match[1] == 'above' || $code_match[1] == 'add above') {
                $replace_with .= "\n" . $working_search;
            }
            // Otherwise.. replace with $replace_with ;).
        }
        // If we have a search string, replace string, and open file..
        if ($working_search !== null && $replace_with !== null && $working_file !== null) {
            // Make sure it's somewhere in the string.
            if ($undo) {
                $temp = $replace_with;
                $replace_with = $working_search;
                $working_search = $temp;
            }
            if (strpos($working_data, $working_search) !== false) {
                $working_data = str_replace($working_search, $replace_with, $working_data);
                $actions[] = array('type' => 'replace', 'filename' => $working_file, 'search' => $working_search, 'replace' => $replace_with, 'search_original' => $working_search, 'replace_original' => $replace_with, 'position' => $code_match[1] == 'replace' ? 'replace' : ($code_match[1] == 'add' || $code_match[1] == 'add after' ? 'before' : 'after'), 'is_custom' => $is_custom, 'failed' => false);
            } else {
                $actions[] = array('type' => 'failure', 'filename' => $working_file, 'search' => $working_search, 'is_custom' => $is_custom, 'search_original' => $working_search, 'replace_original' => $replace_with, 'position' => $code_match[1] == 'replace' ? 'replace' : ($code_match[1] == 'add' || $code_match[1] == 'add after' ? 'before' : 'after'), 'is_custom' => $is_custom, 'failed' => true);
                $everything_found = false;
            }
            // These don't hold any meaning now.
            $working_search = null;
            $replace_with = null;
        }
        // Get rid of the old tag.
        $file = substr_replace($file, '', strpos($file, $code_match[0]), strlen($code_match[0]));
    }
    // Backup the old file.
    if ($working_file !== null) {
        package_chmod($working_file);
        if (!is_writable($working_file)) {
            $actions[] = array('type' => 'chmod', 'filename' => $working_file);
        }
        if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) {
            if (basename($working_file) == 'Settings.php') {
                @copy($working_file, dirname($working_file) . '/Settings_bak.php');
            } else {
                @copy($working_file, $working_file . '~');
            }
        }
        package_put_contents($working_file, $working_data, $testing);
    }
    if ($working_file !== null) {
        $actions[] = array('type' => 'saved', 'filename' => $working_file, 'is_custom' => $is_custom);
    }
    $actions[] = array('type' => 'result', 'status' => $everything_found);
    return $actions;
}
Exemple #2
0
function parseBoardMod($file, $testing = true, $undo = false)
{
    global $boarddir, $sourcedir, $settings, $txt, $modSettings;
    @set_time_limit(600);
    $file = strtr($file, array("\r" => ''));
    $working_file = null;
    $working_search = null;
    $working_data = '';
    $replace_with = null;
    $actions = array();
    $everything_found = true;
    while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $file, $code_match) != 0) {
        // Edit a specific file.
        if ($code_match[1] == 'file' || $code_match[1] == 'edit file') {
            // Backup the old file.
            if ($working_file !== null) {
                package_chmod($working_file);
                // Don't even dare.
                if (basename($working_file) == 'Settings_bak.php') {
                    continue;
                }
                if (!is_writable($working_file)) {
                    $actions[] = array('type' => 'chmod', 'filename' => $working_file);
                }
                if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) {
                    if (basename($working_file) == 'Settings.php') {
                        @copy($working_file, dirname($working_file) . '/Settings_bak.php');
                    } else {
                        @copy($working_file, $working_file . '~');
                    }
                }
                package_put_contents($working_file, $working_data, $testing);
            }
            if ($working_file !== null) {
                $actions[] = array('type' => 'saved', 'filename' => $working_file);
            }
            // Make sure the file exists!
            $working_file = parse_path($code_match[2]);
            if ($working_file[0] != '/' && $working_file[1] != ':') {
                trigger_error('parseBoardMod(): The filename \'' . $working_file . '\' is not a full path!', E_USER_WARNING);
                $working_file = $boarddir . '/' . $working_file;
            }
            if (!file_exists($working_file)) {
                $places_to_check = array($boarddir, $sourcedir, $settings['default_theme_dir'], $settings['default_theme_dir'] . '/languages');
                foreach ($places_to_check as $place) {
                    if (file_exists($place . '/' . $working_file)) {
                        $working_file = $place . '/' . $working_file;
                        break;
                    }
                }
            }
            if (file_exists($working_file)) {
                // Load the new file.
                $working_data = str_replace("\r", '', package_get_contents($working_file));
                $actions[] = array('type' => 'opened', 'filename' => $working_file);
            } else {
                $actions[] = array('type' => 'missing', 'filename' => $working_file);
                $working_file = null;
                $everything_found = false;
            }
            // Can't be searching for something...
            $working_search = null;
        } elseif (($code_match[1] == 'search' || $code_match[1] == 'search for') && $working_file !== null) {
            if ($working_search !== null) {
                $actions[] = array('type' => 'error', 'filename' => $working_file);
                $everything_found = false;
            }
            $working_search = $code_match[2];
        } elseif ($working_search !== null) {
            // This is the base string....
            $replace_with = $code_match[2];
            // Add this afterward...
            if ($code_match[1] == 'add' || $code_match[1] == 'add after') {
                $replace_with = $working_search . "\n" . $replace_with;
            } elseif ($code_match[1] == 'before' || $code_match[1] == 'add before' || $code_match[1] == 'above' || $code_match[1] == 'add above') {
                $replace_with .= "\n" . $working_search;
            }
            // Otherwise.. replace with $replace_with ;).
        }
        // If we have a search string, replace string, and open file..
        if ($working_search !== null && $replace_with !== null && $working_file !== null) {
            // Make sure it's somewhere in the string.
            if ($undo) {
                $temp = $replace_with;
                $replace_with = $working_search;
                $working_search = $temp;
            }
            if (strpos($working_data, $working_search) !== false) {
                $working_data = str_replace($working_search, $replace_with, $working_data);
                $actions[] = array('type' => 'replace', 'filename' => $working_file, 'search' => $working_search, 'replace' => $replace_with);
            } else {
                $actions[] = array('type' => 'failure', 'filename' => $working_file, 'search' => $working_search);
                $everything_found = false;
            }
            // These don't hold any meaning now.
            $working_search = null;
            $replace_with = null;
        }
        // Get rid of the old tag.
        $file = substr_replace($file, '', strpos($file, $code_match[0]), strlen($code_match[0]));
    }
    // Backup the old file.
    if ($working_file !== null) {
        package_chmod($working_file);
        if (!is_writable($working_file)) {
            $actions[] = array('type' => 'chmod', 'filename' => $working_file);
        }
        if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) {
            if (basename($working_file) == 'Settings.php') {
                @copy($working_file, dirname($working_file) . '/Settings_bak.php');
            } else {
                @copy($working_file, $working_file . '~');
            }
        }
        package_put_contents($working_file, $working_data, $testing);
    }
    if ($working_file !== null) {
        $actions[] = array('type' => 'saved', 'filename' => $working_file);
    }
    $actions[] = array('type' => 'result', 'status' => $everything_found);
    return $actions;
}