June 7, 2018♦
<?php
require_once (dirname(__FILE__) . "/fetch.php");
// Move file pointer to the corresponding closing bracket of the current
// element.
function move_to_closing_bracket($fp, &$char)
{
if ($char == CLOSE_ELEMENT_CHAR) return;
$ii = 1;
while (($char = fgetc($fp)) != NULL && !feof($fp))
{
if ($char == OPEN_ELEMENT_CHAR) $ii++;
else
{
if ($char == CLOSE_ELEMENT_CHAR) $ii--;
if ($ii == 0) break;
}
}
}
// Store the file contents as a string, replace the specified string with a new
// string, and re-write the file.
function replace_string_in_file($file_name, $old, $new="")
{
$file_contents = file_get_contents($file_name);
$file_contents = str_replace($old, $new, $file_contents);
$fp = fopen($file_name, 'w');
fwrite($fp, $file_contents);
}
// Erase file contents between and including element's brackets.
function read_raw_element_string($fp, &$char)
{
$element_open_position = ftell($fp)-1;
move_to_closing_bracket($fp, $char);
$element_close_position = ftell($fp);
if (char_is_white_space($char = fgetc($fp)))
{
skip_white_space($fp, $char);
$element_close_position = ftell($fp)-1;
}
$byte_range = $element_close_position - $element_open_position;
fseek($fp, $element_open_position);
$element = fread($fp, $byte_range);
return $element;
}
// If the submitted element points to an object, convert the element to its
// raw string representation. Otherwise, leave the string unchanged.
function convert_element_to_raw($element)
{
if (is_object($element))
{
$element = $element->convert_to_raw_string();
}
return $element;
}
// Replace in a file the element identified by specified ID w/ a new element.
// The new element can be an object, element string, or empty. If empty, the
// old element will be removed and replaced with nothing.
function replace_element_by_id($file_name, $id, $element="")
{
if (file_exists($file_name))
{
$fp = fopen($file_name, 'r+');
move_to_element_by_id($fp, $char, $id);
if (feof($fp)) return;
$old_raw_element = read_raw_element_string($fp, $char, $id);
$new_raw_element = convert_element_to_raw($element);
fclose($fp);
if ($old_raw_element != NULL)
{
replace_string_in_file(
$file_name, $old_raw_element, $new_raw_element);
}
return $old_raw_element;
}
}
// Replace an element with a new element. If the new element is unspecified,
// the old element will be deleted.
function run_replace($file_name, $id, $element)
{
if (!file_exists($file_name)) return;
replace_element_by_id($file_name, $id, $element);
$message = "!! Removing element $id... !!\n\n";
if ($element != NULL)
{
$message .= "Replacing with\n--------------\n";
$message .= convert_element_to_raw($element);
$message .= "\n\n";
}
$message .= "New file\n--------\n";
$message .= run_parse($file_name);
return $message;
}
<?php
require_once (dirname(__FILE__) . "/fetch.php");
require_once (dirname(__FILE__) . "/replace.php");
// Insert a string into the file, leaving the current data intact.
function insert_string_at_cursor($fp, $string)
{
$position = ftell($fp);
$file_meta_data = fstat($fp);
$length = $file_meta_data["size"] - $position;
$tail = fread($fp, $length);
fseek($fp, $position);
$new_content = $string . $tail;
ftruncate($fp, $position);
fwrite($fp, $new_content);
}
// Insert the element data at the end of the file.
function insert_element_into_file($fp, $element)
{
fwrite($fp, $element);
}
// Insert an element into the element referenced by id. This will create a new
// child for the referenced element.
function insert_element_into_element($fp, $element, $id)
{
move_to_element_by_id($fp, $char, $id);
move_to_closing_bracket($fp, $char);
fseek($fp, ftell($fp)-1);
insert_string_at_cursor($fp, $element);
}
// Move to the position either before or after the element currently under the
// cursor.
function move_cursor_based_on_insertion_method($fp, $char, $before)
{
if ($before == False)
{
move_to_closing_bracket($fp, $char);
}
else
{
fseek($fp, ftell($fp)-1);
}
}
// Insert an element before or after the element referenced by id.
function insert_element_at_id($fp, $element, $id, $before=False)
{
move_to_element_by_id($fp, $char, $id);
move_cursor_based_on_insertion_method($fp, $char, $before);
insert_string_at_cursor($fp, $element);
}
// Open file for writing or appending based on where the new element will be
// inserted.
function open_file_based_on_method($file_name, $id)
{
if ($id != NULL)
{
$fp = fopen($file_name, 'r+');
}
else
{
$fp = fopen($file_name, 'a');
}
return $fp;
}
// Choose one of three methods for insertion based on the existence and values
// of the id and child parameters.
function apply_insertion_method($fp, $raw_element, $id, $child, $before)
{
if ($child == True)
{
insert_element_into_element($fp, $raw_element, $id);
}
elseif ($id != NULL)
{
insert_element_at_id($fp, $raw_element, $id, $before);
}
else
{
insert_element_into_file($fp, $raw_element);
}
}
// Insert an element into the specified file. The before parameter indicates
// whether or not the incoming element should be placed before the referenced
// element.
function insert_element(
$file_name, $element, $id=NULL, $child=False, $before=False)
{
$fp = open_file_based_on_method($file_name, $id);
$raw_element = convert_element_to_raw($element);
apply_insertion_method($fp, $raw_element, $id, $child, $before);
}
// Insert an element into the specified file. Return relevant messages for
// verbose output.
function run_insert($file_name, $element, $id=NULL, $child=False, $before=False)
{
$message = "Inserting\n---------\n";
$message .= convert_element_to_raw($element) . "\n\n";
$child = ($child && $child != '0') ? True : False;
$before = ($before && $before != '0') ? True : False;
insert_element($file_name, $element, $id, $child, $before);
$message .= "New File\n--------\n";
$message .= run_parse($file_name);
return $message;
}