From da497a1ee9b844eb6e35839e44acd0c027ecb795 Mon Sep 17 00:00:00 2001 From: Peter Rotich <peter@osticket.com> Date: Fri, 19 Sep 2014 19:23:19 +0000 Subject: [PATCH] Add ListObject utility class This will be useful for maintaining arbitrary list of items. ListObject should be used in the place of ArrayObject --- bootstrap.php | 1 + include/class.dynamic_forms.php | 6 +- include/class.user.php | 38 +------ include/class.util.php | 169 ++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 38 deletions(-) create mode 100644 include/class.util.php diff --git a/bootstrap.php b/bootstrap.php index 03007ba9b..41cd7cf4f 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -179,6 +179,7 @@ class Bootstrap { function loadCode() { #include required files + require_once INCLUDE_DIR.'class.util.php'; require(INCLUDE_DIR.'class.signal.php'); require(INCLUDE_DIR.'class.user.php'); require(INCLUDE_DIR.'class.auth.php'); diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index eaa200679..8637598c2 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -53,11 +53,11 @@ class DynamicForm extends VerySimpleModel { $fields = &$this->_fields; if (!$fields) { - $fields = new ArrayObject(); + $fields = new ListObject(); foreach ($this->getDynamicFields() as $f) - // TODO: Index by field name or id - $fields[$f->get('id')] = $f->getImpl($f); + $fields->append($f->getImpl($f)); } + return $fields; } diff --git a/include/class.user.php b/include/class.user.php index c7c668caf..3c4be441e 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -1089,45 +1089,12 @@ class UserAccountStatus { /* * Generic user list. */ -class UserList implements IteratorAggregate, ArrayAccess { - private $users; - - function __construct($list = array()) { - $this->users = $list; - } - - function add($user) { - $this->offsetSet(null, $user); - } - - function offsetSet($offset, $value) { - - if (is_null($offset)) - $this->users[] = $value; - else - $this->users[$offset] = $value; - } - - function offsetExists($offset) { - return isset($this->users[$offset]); - } - - function offsetUnset($offset) { - unset($this->users[$offset]); - } - - function offsetGet($offset) { - return isset($this->users[$offset]) ? $this->users[$offset] : null; - } - - function getIterator() { - return new ArrayIterator($this->users); - } +class UserList extends ListObject { function __toString() { $list = array(); - foreach($this->users as $user) { + foreach($this->storage as $user) { if (is_object($user)) $list [] = $user->getName(); } @@ -1135,6 +1102,7 @@ class UserList implements IteratorAggregate, ArrayAccess { return $list ? implode(', ', $list) : ''; } } + require_once(INCLUDE_DIR . 'class.organization.php'); User::_inspect(); UserAccount::_inspect(); diff --git a/include/class.util.php b/include/class.util.php new file mode 100644 index 000000000..8fb9b3967 --- /dev/null +++ b/include/class.util.php @@ -0,0 +1,169 @@ +<?php +/** + * Jared Hancock <jared@osticket.com> + * Copyright (c) 2014 + * + * Lightweight implementation of the Python list in PHP. This allows for + * treating an array like a simple list of items. The numeric indexes are + * automatically updated so that the indeces of the list will alway be from + * zero and increasing positively. + * + * Negative indexes are supported which reference from the end of the list. + * Therefore $queue[-1] will refer to the last item in the list. + */ +class ListObject implements IteratorAggregate, ArrayAccess, Serializable, Countable { + + protected $storage = array(); + + function __construct(array $array=array()) { + foreach ($array as $v) + $this->storage[] = $v; + } + + function append($what) { + if (is_array($what)) + return $this->extend($what); + + $this->storage[] = $what; + } + + function add($what) { + $this->append($what); + } + + function extend($iterable) { + foreach ($iterable as $v) + $this->storage[] = $v; + } + + function insert($i, $value) { + array_splice($this->storage, $i, 0, array($value)); + } + + function remove($value) { + if (!($k = $this->index($value))) + throw new OutOfRangeException('No such item in the list'); + unset($this->storage[$k]); + } + + function pop($at=false) { + if ($at === false) + return array_pop($this->storage); + elseif (!isset($this->storage[$at])) + throw new OutOfRangeException('Index out of range'); + else { + $rv = array_splice($this->storage, $at, 1); + return $rv[0]; + } + } + + function slice($offset, $length=null) { + return array_slice($this->storage, $offset, $length); + } + + function splice($offset, $length=0, $replacement=null) { + return array_splice($this->storage, $offset, $length, $replacement); + } + + function index($value) { + return array_search($this->storage, $value); + } + + /** + * Sort the list in place. + * + * Parameters: + * $key - (callable|int) A callable function to produce the sort keys + * or one of the SORT_ constants used by the array_multisort + * function + * $reverse - (bool) true if the list should be sorted descending + */ + function sort($key=false, $reverse=false) { + if (is_callable($key)) { + $keys = array_map($key, $this->storage); + array_multisort($keys, $this->storage, + $reverse ? SORT_DESC : SORT_ASC); + } + elseif ($key) { + array_multisort($this->storage, + $reverse ? SORT_DESC : SORT_ASC, $key); + } + elseif ($reverse) { + rsort($this->storage); + } + else + sort($this->storage); + } + + function reverse() { + return array_reverse($this->storage); + } + + function filter($callable) { + $new = new static(); + foreach ($this->storage as $i=>$v) + if ($callable($v, $i)) + $new[] = $v; + return $new; + } + + // IteratorAggregate + function getIterator() { + return new ArrayIterator($this->storage); + } + + // Countable + function count($mode=COUNT_NORMAL) { + return count($this->storage, $mode); + } + + // ArrayAccess + function offsetGet($offset) { + if (!is_int($offset)) + throw new InvalidArgumentException('List indices should be integers'); + elseif ($offset < 0) + $offset += count($this->storage); + if (!isset($this->storage[$offset])) + throw new OutOfBoundsException('List index out of range'); + return $this->storage[$offset]; + } + function offsetSet($offset, $value) { + if ($offset === null) + return $this->storage[] = $value; + elseif (!is_int($offset)) + throw new InvalidArgumentException('List indices should be integers'); + elseif ($offset < 0) + $offset += count($this->storage); + + if (!isset($this->storage[$offset])) + throw new OutOfBoundsException('List assignment out of range'); + + $this->storage[$offset] = $value; + } + function offsetExists($offset) { + if (!is_int($offset)) + throw new InvalidArgumentException('List indices should be integers'); + elseif ($offset < 0) + $offset += count($this->storage); + return isset($this->storage[$offset]); + } + function offsetUnset($offset) { + if (!is_int($offset)) + throw new InvalidArgumentException('List indices should be integers'); + elseif ($offset < 0) + $offset += count($this->storage); + unset($this->storage[$offset]); + } + + // Serializable + function serialize() { + return serialize($this->storage); + } + function unserialize($what) { + $this->storage = unserialize($what); + } + + function __toString() { + return '['.implode(', ', $this->storage).']'; + } +} -- GitLab