A lot of improvements on the module loading side + some other fixes.
[AOOS.git] / AOOSModel.php
blob1f7ec7707b9b11eef40013a305c2d05bd9875382
1 <?php
2 require_once("AOOSException.php");
3 require_once("AOOSModule.php");
5 /**
6 * AOOSModel
7 * @author Sebastian Skejø
8 */
10 class AOOSModel extends AOOSModule
12 private $_rows = 0;
13 private $_data = array();
14 private $_model = array();
15 private $_updated = false;
16 private $_columnIndex = array();
17 private $_escape = true;
18 private $_quote = false;
20 private function _fixRange(&$start, &$end, $count)
22 if ($start === null) { $start = 0; }
23 if ($end === null) { $end = $count-1; }
25 if (!is_int($start) || !is_int($end))
27 throw new AOOSException($this->core(), $this->tr("not_int"), "", true, 1);
28 return false;
31 if ($start >= $count || $end >= $count)
33 throw new AOOSException($this->core(), $this->tr("row_out_of_bounds"), "", true, 1);
34 return false;
37 if ($start > $end && !($end < 0))
39 throw new AOOSException($this->core(), $this->tr("start_bigger_than_end"), "", true, 1);
40 return false;
43 // If start is > 0 we count from the end
44 if ($start < 0)
46 $start = $count + $start;
48 // Same goes for end
49 if ($end < 0)
51 $end = $count + $end;
54 return true;
57 /**
58 * Adds a row before $row.
59 * @param int $row The row which the new row should be inserted before. If given -1 it will be inserted at the end of the model.
60 * @return bool
62 public function addRow($row = -1)
64 if ($row > count($this->_data) || $row < -1)
66 throw new AOOSException($this->core(), $this->tr("row_out_of_bounds"), "", true, 1);
67 return false;
70 if ($row == -1 || count($this->_data) == 0)
72 $this->_data[] = null;
74 else
76 $tmp = $this->_data;
77 $this->_data[$row] = null;
79 $count = count($this->_data);
80 while ($row < $count)
82 $val = $tmp[$row];
83 $row++;
84 $this->_data[$row] = $val;
87 $this->_updated = false;
88 $this->_rows++;
89 return true;
92 /**
93 * Removes a row from the model.
94 * @param int $row The row to remove. Given -1 the last row is removed.
95 * @return bol
97 public function removeRow($row = -1)
99 if ($row < -1 || $row >= count($this->_data))
101 throw new AOOSException($this->core(), $this->tr("row_out_of_bounds"), "", true, 2);
102 return false;
105 if ($row == -1)
107 $row = count($this->_data) - 1;
109 $tmp = $this->_data;
110 $this->_data = array();
112 // Reinsert rows before $row
113 for ($i = 0; $i < $row; $i++)
115 $this->_data[] = $tmp[$i];
118 $row++;
120 // Reinsert rows after $row
121 for ($c = count($tmp); $row < $c; $row++)
123 $this->_data[] = $tmp[$row];
126 $this->_updated = false;
127 $this->_rows--;
128 return true;
132 * Sets the data of a specified row and column.
133 * @param int $row The row in which the column is selected from
134 * @param int|string $col The column in which the data should be added
135 * @param $data The data that should be added.
136 * @return bool
138 public function setData($data, $row = -1, $col = -1)
140 if ($row >= count($this->_data))
142 throw new AOOSException($this->core(), $this->tr("row_out_of_bounds"), "", true, 1);
143 return false;
145 if ($row == -1)
147 $row = count($this->_data) - 1;
150 if ($col >= count($this->_data[$row]) || $col == -1)
152 $col = count($this->_data[$row]);
154 if (is_string($col))
156 $i = 0;
157 foreach ($this->_columnIndex as $index)
159 if ($index == $col)
161 $col = $i;
162 break;
164 $i++;
168 $this->_data[$row][$col] = $data;
169 $this->_updated = false;
170 return true;
174 * Sets column index
175 * @param int $col Column
176 * @param string $index Column index
177 * @return bool
179 public function setColumnIndex()
181 $count = func_num_args();
182 $arg1 = func_get_arg(0);
183 switch ($count)
185 case (2):
186 $arg2 = func_get_arg(1);
187 $this->_setColumnIndexSingle($arg1, $arg2);
188 break;
189 case(1):
190 $this->_setColumnIndexArray($arg1);
191 break;
193 $this->_updated = false;
196 private function _setColumnIndexSingle($col, $index)
198 if (!is_int($col))
200 throw new AOOSException($this->core(), $this->tr("not_integer"), "", true, 1);
201 return false;
203 if (!is_string($index))
205 throw new AOOSException($this->core(), $this->tr("not_string"), "", true, 1);
206 return false;
208 $this->_columnIndex[$col] = $index;
211 private function _setColumnIndexArray($index)
213 if (!is_array($index))
215 throw new AOOSException($this->core(), $this->tr("not_array"), "", true, 1);
216 return false;
219 $c = 0;
220 foreach ($index as $i)
222 $this->_columnIndex[$c] = $i;
223 $c++;
228 * Returns everything in the model
229 * @return data|false
231 public function data()
233 $data = array();
234 $rowIndex = 0;
236 if ($this->_updated) // If the model is updated we don't need to iterate through the data
238 return $this->_model;
241 foreach ($this->_data as $row)
243 $index = 0;
244 foreach ($this->_columnIndex as $colIndex)
246 if ($index >= count($row))
248 $row[$index] = "";
251 $col = $row[$index];
252 if ($this->escape())
254 $col = mysql_real_escape_string($col);
257 if ($this->quote())
259 $col = "\"".$col."\"";
262 $data[$rowIndex][$colIndex] = $col;
263 $index++;
265 $rowIndex++;
267 $this->_updated = true;
268 $this->_model = $data;
269 return $this->_model;
273 * Returns a given column
274 * @param string $index The column index
275 * @param int $start "From row"
276 * @param int $end "To row". Inclusive.
277 * @return array
279 public function getColumn($index, $start = null, $end = null)
281 $data = $this->data();
282 $count = count($data);
283 $column = array();
285 if (!in_array($index, $this->_columnIndex))
287 throw new AOOSException($this->core(), $this->tr("not_in_column_index"), "", true, 1);
288 return false;
291 $this->_fixRange($start, $end, $count);
293 for ($i = $start; $i <= $end; $i++)
295 $column[] = $data[$i][$index];
298 return $column;
302 * Returns rows
303 * @param int $start "From row"
304 * @param int $end "To row". Inclusive.
305 * @return array
307 public function getRows($start = null, $end = null)
309 $data = $this->data();
310 $count = count($data);
311 $rows = array();
313 $this->_fixRange($start, $end, $count);
315 for ($i = $start; $i <= $end; $i++)
317 $rows[] = $data[$i];
320 return $rows;
324 * Returns a single row
325 * @param int $id Row id
326 * @return array
328 public function getRow($id)
330 $tmp = $this->getRows($id, $id);
331 return $tmp[0];
336 * Returns the column index
337 * @return array
339 public function columnIndex()
341 return $this->_columnIndex;
345 * Returns the row count
346 * @return int
348 public function rows()
350 return $this->_rows;
354 * Returns the column count
355 * @return int
357 public function columns()
359 return count($this->_columnIndex);
363 * Is the given value in the given column?
364 * @param string $col Column id
365 * @param value $val Value
366 * @return bool
368 public function inColumn($col, $val)
370 $c = $this->getColumn($col);
371 if (!in_array($val, $c))
373 return false;
375 return true;
379 * Is the given value a column index?
380 * @param string $name
381 * @return bool
383 public function inColumnIndex($name)
385 if (!in_array($name, $this->columnIndex()))
387 return false;
389 return true;
393 * Appends given values to the end of the model. The number of keys is the number of values added.
394 * @param array $values Values to append.
395 * @param auto|null $key If "auto" is given the column ids we be determined automatically. If not the function expects the array to be a hash which keys is used as column indexes(default).
396 * @return bool
398 public function append($values, $key = null)
400 $keys = array();
401 $c = 0;
403 if (!is_array($values))
405 throw new AOOSException($this->core(), $this->tr("not_array"));
406 return false;
409 if ($key == "auto")
411 $keys = $this->columnIndex();
413 else
415 $keys = array_keys($values);
416 $values = array_values($values);
419 $this->addRow();
420 $c = count($keys);
421 for ($i=0; $i<$c; $i++)
423 $this->setData($values[$i], -1, $keys[$i]);
425 return true;
429 * Returns the row index in which the given field has the given value. Returns false if none is found
430 * @param string $name Field name
431 * @param string $value Field value
432 * @return int|false
434 public function getRowFromValue($name, $value)
436 if (!$this->inColumnIndex($name))
438 throw new AOOSException($this->core(), $this->tr("not_in_column_index"), "", true, 2);
439 return false;
442 $c = $this->getColumn($name);
443 $r = null;
444 for($i = 0; $i < count($c); $i++)
446 if ($c[$i] == $value)
448 $r = $i;
452 if ($r === null)
454 throw new AOOSException($this->core(), $this->tr("value_not_in_row"), "", true, 2);
455 return false;
458 return $r;
462 * Returns a given field. Calls getColum.
463 * @param int $row The row
464 * @param string $column Column index
465 * @return value|false
467 public function getField($row, $column)
469 return $this->getColumn($column, $row, $row);
473 * When set to true all data is escaped. Escaping is done in the data() call, which means *all* data is escaped, not only newly added data.
474 * Default is true.
475 * @param bool $state Should data be escaped or not?
476 * @return bool
478 public function setEscape($state)
480 if (!is_bool($state))
482 throw new AOOSException($this->core(), $this->tr("not_bool"));
483 return false;
485 $this->_escape = $state;
486 $this->_updated = false;
487 return true;
491 * Is data being escaped?
492 * @return bool
494 public function escape()
496 return $this->_escape;
500 * When set to true all data have quotes around it. Like setEscape(), quotes are added during the data() call. This means that all data, and not only newly added data, is quoted.
501 * Default is false.
502 * @param bool $state Should data have quotes or not?
503 * @return bool
505 public function setQuote($state)
507 if (!is_bool($state))
509 throw new AOOSException($this->core(), $this->tr("not_bool"));
510 return false;
512 $this->_quote = $state;
513 $this->_updated = false;
514 return true;
518 * Is data being quoted?
519 * @return bool
521 public function quote()
523 return $this->_quote;