From c9e6ba18e5042d0672e2160755391a0d77a200d8 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Mon, 27 Apr 2015 08:50:21 -0500 Subject: [PATCH] orm: Fix incorrect queries in InstrumentedLists If a relationship has more than one field in the constraint, then the InstrumentedList query generated would not be correct. This happens often in osTicket for the join foreign key fields `object_type` and `object_id`. This patch addresses the issue by sending all the fields in the foreign key to the InstrumentedList constructor. --- assets/default/css/theme.css | 2 +- include/class.dept.php | 1 + include/class.orm.php | 29 ++++++++++++++++++----------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css index 97703547a..f3b1290f8 100644 --- a/assets/default/css/theme.css +++ b/assets/default/css/theme.css @@ -414,7 +414,7 @@ body { .front-page-button { } .main-content { - width: 560px; + width: 565px; } #landing_page #new_ticket { margin-top: 40px; diff --git a/include/class.dept.php b/include/class.dept.php index 8343d6f66..4e42d9335 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -159,6 +159,7 @@ implements TemplateVariable { if (!$this->_members || $criteria) { $members = Staff::objects() + ->distinct('staff_id') ->filter(Q::any(array( 'dept_id' => $this->getId(), new Q(array( diff --git a/include/class.orm.php b/include/class.orm.php index 818d33be9..8c149318a 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -47,10 +47,10 @@ class ModelMeta implements ArrayAccess { if (!$meta['table']) throw new OrmConfigurationException( - __('Model does not define meta.table'), $model); + sprintf(__('%s: Model does not define meta.table'), $model)); elseif (!$meta['pk']) throw new OrmConfigurationException( - __('Model does not define meta.pk'), $model); + sprintf(__('%s: Model does not define meta.pk'), $model)); // Ensure other supported fields are set and are arrays foreach (array('pk', 'ordering', 'defer') as $f) { @@ -185,10 +185,17 @@ class VerySimpleModel { $j = static::$meta['joins'][$field]; // Support instrumented lists and such if (isset($j['list']) && $j['list']) { - $fkey = $j['fkey']; + $class = $j['fkey'][0]; + $fkey = array(); + // Localize the foreign key constraint + foreach ($j['constraint'] as $local=>$foreign) { + list($_klas,$F) = $foreign; + $fkey[$F ?: $_klas] = ($local[0] == "'") + ? trim($local, "'") : $this->ht[$local]; + } $v = $this->ht[$field] = new InstrumentedList( - // Send Model, Foriegn-Field, Local-Id - array($fkey[0], $fkey[1], $this->get($j['local'])) + // Send Model, [Foriegn-Field => Local-Id] + array($class, $fkey) ); return $v; } @@ -1362,24 +1369,22 @@ class HashArrayIterator extends ResultSet { class InstrumentedList extends ModelInstanceManager { var $key; - var $id; var $model; function __construct($fkey, $queryset=false) { - list($model, $this->key, $this->id) = $fkey; + list($model, $this->key) = $fkey; if (!$queryset) - $queryset = $model::objects()->filter(array($this->key=>$this->id)); + $queryset = $model::objects()->filter($this->key); parent::__construct($queryset); $this->model = $model; - if (!$this->id) - $this->resource = null; } function add($object, $at=false) { if (!$object || !$object instanceof $this->model) throw new Exception(__('Attempting to add invalid object to list')); - $object->set($this->key, $this->id); + foreach ($this->key as $field=>$value) + $object->set($field, $value); if (!$object->__new__) $object->save(); @@ -1388,6 +1393,8 @@ class InstrumentedList extends ModelInstanceManager { $this->cache[$at] = $object; else $this->cache[] = $object; + + return $object; } function remove($object, $delete=true) { if ($delete) -- GitLab