1<?php 2 3/** 4 * Instruction re-writer 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Mykola Ostrovskyy <dwpforge@gmail.com> 8 */ 9 10if (!class_exists('instruction_rewriter', false)) { 11 12class instruction_rewriter { 13 14 private $correction; 15 16 /** 17 * Constructor 18 */ 19 public function __construct() { 20 $this->correction = array(); 21 } 22 23 /** 24 * 25 */ 26 public function addCorrections($correction) { 27 foreach ($correction as $c) { 28 $this->correction[$c->getIndex()][] = $c; 29 } 30 } 31 32 /** 33 * 34 */ 35 public function process(&$instruction) { 36 if (count($this->correction) > 0) { 37 $index = $this->getCorrectionIndex(); 38 $corrections = count($index); 39 $instructions = count($instruction); 40 $output = array(); 41 for ($c = 0, $i = 0; $c < $corrections; $c++, $i++) { 42 /* Copy all instructions that are before the next correction */ 43 for ( ; $i < $index[$c]; $i++) { 44 $output[] = $instruction[$i]; 45 } 46 /* Apply the corrections */ 47 $preventDefault = false; 48 foreach ($this->correction[$i] as $correction) { 49 $preventDefault = ($preventDefault || $correction->apply($instruction, $output)); 50 } 51 if (!$preventDefault) { 52 $output[] = $instruction[$i]; 53 } 54 } 55 /* Copy the rest of instructions after the last correction */ 56 for ( ; $i < $instructions; $i++) { 57 $output[] = $instruction[$i]; 58 } 59 /* Handle appends */ 60 if (array_key_exists(-1, $this->correction)) { 61 $this->correction[-1]->apply($instruction, $output); 62 } 63 $instruction = $output; 64 } 65 } 66 67 /** 68 * 69 */ 70 private function getCorrectionIndex() { 71 $result = array_keys($this->correction); 72 asort($result); 73 /* Remove appends */ 74 if (reset($result) == -1) { 75 unset($result[key($result)]); 76 } 77 return array_values($result); 78 } 79} 80 81class instruction_rewriter_correction { 82 83 protected $index; 84 85 /** 86 * Constructor 87 */ 88 public function __construct($index) { 89 $this->index = $index; 90 } 91 92 /** 93 * 94 */ 95 public function getIndex() { 96 return $this->index; 97 } 98} 99 100class instruction_rewriter_delete extends instruction_rewriter_correction { 101 102 /** 103 * Constructor 104 */ 105 public function __construct($index) { 106 parent::__construct($index); 107 } 108 109 /** 110 * 111 */ 112 public function apply($input, &$output) { 113 return true; 114 } 115} 116 117class instruction_rewriter_call_list extends instruction_rewriter_correction { 118 119 private $call; 120 121 /** 122 * Constructor 123 */ 124 public function __construct($index) { 125 parent::__construct($index); 126 $this->call = array(); 127 } 128 129 /** 130 * 131 */ 132 public function addCall($name, $data) { 133 $this->call[] = array($name, $data); 134 } 135 136 /** 137 * 138 */ 139 public function addPluginCall($name, $data, $state, $text = '') { 140 $this->call[] = array('plugin', array($name, $data, $state, $text)); 141 } 142 143 /** 144 * 145 */ 146 public function appendCalls(&$output, $position) { 147 foreach ($this->call as $call) { 148 $output[] = array($call[0], $call[1], $position); 149 } 150 } 151} 152 153class instruction_rewriter_insert extends instruction_rewriter_call_list { 154 155 /** 156 * Constructor 157 */ 158 public function __construct($index) { 159 parent::__construct($index); 160 } 161 162 /** 163 * 164 */ 165 public function apply($input, &$output) { 166 $this->appendCalls($output, $input[$this->index][2]); 167 return false; 168 } 169} 170 171class instruction_rewriter_append extends instruction_rewriter_call_list { 172 173 /** 174 * Constructor 175 */ 176 public function __construct() { 177 parent::__construct(-1); 178 } 179 180 /** 181 * 182 */ 183 public function apply($input, &$output) { 184 $lastCall = end($output); 185 $this->appendCalls($output, $lastCall[2]); 186 return false; 187 } 188} 189 190} 191