*/ if (!class_exists('instruction_rewriter', false)) { class instruction_rewriter { private $correction; /** * Constructor */ public function __construct() { $this->correction = array(); } /** * */ public function addCorrections($correction) { foreach ($correction as $c) { $this->correction[$c->getIndex()][] = $c; } } /** * */ public function process(&$instruction) { if (count($this->correction) > 0) { $index = $this->getCorrectionIndex(); $corrections = count($index); $instructions = count($instruction); $output = array(); for ($c = 0, $i = 0; $c < $corrections; $c++, $i++) { /* Copy all instructions that are before the next correction */ for ( ; $i < $index[$c]; $i++) { $output[] = $instruction[$i]; } /* Apply the corrections */ $preventDefault = false; foreach ($this->correction[$i] as $correction) { $preventDefault = ($preventDefault || $correction->apply($instruction, $output)); } if (!$preventDefault) { $output[] = $instruction[$i]; } } /* Copy the rest of instructions after the last correction */ for ( ; $i < $instructions; $i++) { $output[] = $instruction[$i]; } /* Handle appends */ if (array_key_exists(-1, $this->correction)) { $this->correction[-1]->apply($instruction, $output); } $instruction = $output; } } /** * */ private function getCorrectionIndex() { $result = array_keys($this->correction); asort($result); /* Remove appends */ if (reset($result) == -1) { unset($result[key($result)]); } return array_values($result); } } class instruction_rewriter_correction { protected $index; /** * Constructor */ public function __construct($index) { $this->index = $index; } /** * */ public function getIndex() { return $this->index; } } class instruction_rewriter_delete extends instruction_rewriter_correction { /** * Constructor */ public function __construct($index) { parent::__construct($index); } /** * */ public function apply($input, &$output) { return true; } } class instruction_rewriter_call_list extends instruction_rewriter_correction { private $call; /** * Constructor */ public function __construct($index) { parent::__construct($index); $this->call = array(); } /** * */ public function addCall($name, $data) { $this->call[] = array($name, $data); } /** * */ public function addPluginCall($name, $data, $state, $text = '') { $this->call[] = array('plugin', array($name, $data, $state, $text)); } /** * */ public function appendCalls(&$output, $position) { foreach ($this->call as $call) { $output[] = array($call[0], $call[1], $position); } } } class instruction_rewriter_insert extends instruction_rewriter_call_list { /** * Constructor */ public function __construct($index) { parent::__construct($index); } /** * */ public function apply($input, &$output) { $this->appendCalls($output, $input[$this->index][2]); return false; } } class instruction_rewriter_append extends instruction_rewriter_call_list { /** * Constructor */ public function __construct() { parent::__construct(-1); } /** * */ public function apply($input, &$output) { $lastCall = end($output); $this->appendCalls($output, $lastCall[2]); return false; } } }