Bugfixes
[AOOS.git] / AOOSModel.php
blob6bea0ed43b3afcc23502c1c003ddcb0f0d5193c3
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 * @param int $cutoff If set to true the $end row will be adjusted to fit within the number of rows if the given $end is bigger.
306 * @return array
308 public function getRows($start = null, $end = null, $cutoff = false)
310 $data = $this->data();
311 $count = count($data);
312 $rows = array();
314 if ($this->rows() == 0)
316 throw new AOOSException($this->core(), $this->tr("model_empty"), "", true, 2);
317 return false;
320 if ($cutoff && $end > $this->rows())
322 $end = $this->rows();
325 $this->_fixRange($start, $end, $count);
327 for ($i = $start; $i <= $end; $i++)
329 $rows[] = $data[$i];
332 return $rows;
336 * Returns a single row
337 * @param int $id Row id
338 * @return array
340 public function getRow($id)
342 $tmp = $this->getRows($id, $id);
343 return $tmp[0];
348 * Returns the column index
349 * @return array
351 public function columnIndex()
353 return $this->_columnIndex;
357 * Returns the row count
358 * @return int
360 public function rows()
362 return $this->_rows;
366 * Returns the column count
367 * @return int
369 public function columns()
371 return count($this->_columnIndex);
375 * Is the given value in the given column?
376 * @param string $col Column id
377 * @param value $val Value
378 * @return bool
380 public function inColumn($col, $val)
382 $c = $this->getColumn($col);
383 if (!in_array($val, $c))
385 return false;
387 return true;
391 * Is the given value a column index?
392 * @param string $name
393 * @return bool
395 public function inColumnIndex($name)
397 if (!in_array($name, $this->columnIndex()))
399 return false;
401 return true;
405 * Appends given values to the end of the model. The number of keys is the number of values added.
406 * @param array $values Values to append.
407 * @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).
408 * @return bool
410 public function append($values, $key = null)
412 $keys = array();
413 $c = 0;
415 if (!is_array($values))
417 throw new AOOSException($this->core(), $this->tr("not_array"));
418 return false;
421 if ($key == "auto")
423 $keys = $this->columnIndex();
425 else
427 $keys = array_keys($values);
428 $values = array_values($values);
431 $this->addRow();
432 $c = count($keys);
433 for ($i=0; $i<$c; $i++)
435 $this->setData($values[$i], -1, $keys[$i]);
437 return true;
441 * Returns the row index in which the given field has the given value. Returns false if none is found
442 * @param string $name Field name
443 * @param string $value Field value
444 * @return int|false
446 public function getRowFromValue($name, $value)
448 if (!$this->inColumnIndex($name))
450 throw new AOOSException($this->core(), $this->tr("not_in_column_index"), "", true, 2);
451 return false;
454 $c = $this->getColumn($name);
455 $r = null;
456 for($i = 0; $i < count($c); $i++)
458 if ($c[$i] == $value)
460 $r = $i;
464 if ($r === null)
466 throw new AOOSException($this->core(), $this->tr("value_not_in_row"), "", true, 2);
467 return false;
470 return $r;
474 * Returns a given field. Calls getColum.
475 * @param int $row The row
476 * @param string $column Column index
477 * @return value|false
479 public function getField($row, $column)
481 return $this->getColumn($column, $row, $row);
485 * 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.
486 * Default is true.
487 * @param bool $state Should data be escaped or not?
488 * @return bool
490 public function setEscape($state)
492 if (!is_bool($state))
494 throw new AOOSException($this->core(), $this->tr("not_bool"));
495 return false;
497 $this->_escape = $state;
498 $this->_updated = false;
499 return true;
503 * Is data being escaped?
504 * @return bool
506 public function escape()
508 return $this->_escape;
512 * 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.
513 * Default is false.
514 * @param bool $state Should data have quotes or not?
515 * @return bool
517 public function setQuote($state)
519 if (!is_bool($state))
521 throw new AOOSException($this->core(), $this->tr("not_bool"));
522 return false;
524 $this->_quote = $state;
525 $this->_updated = false;
526 return true;
530 * Is data being quoted?
531 * @return bool
533 public function quote()
535 return $this->_quote;
538 /**
539 * Sort using mergesort
540 * @param string $name The column the data should be sorted by.
541 * @param ASC|DESC $order Should data be sorting in ascending or descending order?
542 * @return bool
544 public function sort($name, $order)
546 return true;