Framework  3.9
related_item_checklist_field_renderer.inc
Go to the documentation of this file.
1 <?php
6 /**************************************************************
7 
8 Copyright (c) 2007-2010 Sonjara, Inc
9 
10 Permission is hereby granted, free of charge, to any person
11 obtaining a copy of this software and associated documentation
12 files (the "Software"), to deal in the Software without
13 restriction, including without limitation the rights to use,
14 copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the
16 Software is furnished to do so, subject to the following
17 conditions:
18 
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21 
22 Except as contained in this notice, the name(s) of the above
23 copyright holders shall not be used in advertising or otherwise
24 to promote the sale, use or other dealings in this Software
25 without prior written authorization.
26 
27 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
29 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
32 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
34 OTHER DEALINGS IN THE SOFTWARE.
35 
36 *****************************************************************/
37 
38 require_once realpath(dirname(__FILE__))."/../field_renderers.inc";
39 
52 {
56  var $field;
57  var $label;
58  var $options;
59  var $groupBy;
60 
62  {
63  $this->field = $field;
64  $this->label = $label;
65  $this->nameField = $nameField;
66  $this->relatedClass = $relatedClass;
67  $this->constraint = $constraint;
68  $this->options = $this->getRelatedItems();
69 
70  $this->FieldRenderer($form);
71 
72  if ($form->data->hasField($field))
73  {
74  $form->override($field, $label, $this);
75  }
76  else
77  {
78  $form->add($this, $field);
79  $form->overrides[$field]['label'] = $label;
80  }
81  }
82 
83  function setSize($width, $height)
84  {
85  $this->width = $width;
86  $this->height = $height;
87  }
88 
89  function groupBy($groupBy, $format = "")
90  {
91  $this->groupBy = $groupBy;
92  $this->groupByFormat = $format;
93  }
94 
106  function getMatchingPK($relatedClass, $obj)
107  {
108  $pks = $obj->getPrimaryKeyList();
109  foreach($pks as $pk)
110  {
111  if ($relatedClass->hasField($pk)) return $pk;
112  }
113 
114  throw new DataItemException("No matching foreign key in related table {$relatedClass->table}");
115  }
116 
117  function renderField($field = "")
118  {
119  if (count($this->options) == 0) return;
120 
122 
123  $this->_startField($field);
124 
125  $obj = $this->parent->data;
126 
127  if (is_array($this->groupBy) && count($this->groupBy) > 0)
128  {
129  $keys = array_keys($this->options);
130  }
131 
132  $itempk = $this->getMatchingPK($this->options[0], $obj);
133  $related_pk = $this->options[0]->getPrimaryKey();
134  $selected = $this->getSelected($obj, $itempk, $related_pk);
135 
136  if ($this->width && $this->height)
137  {
138  echo "<div id='{$this->parent->id}_{$field}_container' class='selectbox scrollbox{$resizable}{$dropdown}' style='width: {$this->width}px; height: {$this->height}px; overflow: auto'>\n";
139  }
140  else
141  {
142  echo "<div class='selectbox'>\n";
143  }
144  $countOptions = count($this->options);
145 
146  if (is_array($this->groupBy) && count($this->groupBy) > 0)
147  {
148  $gpk = $this->groupBy[0]->getPrimaryKey();
149 
150  foreach($this->groupBy as $group)
151  {
152  if (array_key_exists($group->get($gpk), $this->options))
153  {
154  echo $group->format($this->groupByFormat);
155  $this->renderCheckboxes($field, $this->options[$group->get($gpk)], $related_pk, $selected);
156  }
157  }
158  }
159  else if (is_string($this->groupBy))
160  {
161  $options = regroupList($this->options, $this->groupBy);
162 
163  foreach($options as $group => $choices)
164  {
165  echo "<br/><h4>$group</h4>";
166  $this->renderCheckboxes($field, $choices, $related_pk, $selected);
167  }
168  }
169  else
170  {
171  $this->renderCheckBoxes($field, $this->options, $related_pk, $selected);
172  }
173 
174  echo "</div>\n";
175 
176  // Save this count to loop through checkboxes on required validation
177  echo "<input type=\"hidden\" name=\"count_{$field}\" value=\"$countOptions\">";
178 
179  $this->_endField($field);
180  }
181 
182  function getRelatedItems()
183  {
184  return Query::create($this->relatedClass, $this->constraint)->execute();
185  }
186 
194  function getSelected($obj, $itempk, $pk)
195  {
196  return IndexedQuery::create($this->relatedClass, "WHERE {$itempk}=:{$itempk}", $pk)
197  ->bind("{$itempk}", $obj->get($itempk))
198  ->execute();
199  }
200 
201  function renderCheckboxes($field, $items, $pk, $selected)
202  {
203  foreach($items as $item)
204  {
205  $item_id = $item->$pk;
206 
207  echo "<input type='checkbox' class='checkbox' name='{$field}[$item_id]' id='checkbox_{$field}_$item_id' value='1'";
208  if (array_key_exists($item_id, $selected))
209  {
210  echo " checked";
211  }
212  echo ">&nbsp;";
213 
214  echo "<label for='checkbox_{$field}_$item_id'>".$this->formatName($item, $this->nameField)."</label>";
215  echo "<br/>";
216  }
217  }
218 
219  function renderReadOnly($field = "")
220  {
221  if (count($this->options) == 0) return;
222 
223  $obj = $this->parent->data;
224  $itempk = $this->getMatchingPK($this->options[0], $obj);
225  $related_pk = $this->options[0]->getPrimaryKey();
226  $selected = $this->getSelected($obj, $itempk, $related_pk);
227 
228 
229  $this->_startField($field);
230 
231  foreach($this->options as $item)
232  {
233  if (array_key_exists($item->$related_pk, $selected))
234  {
235  echo $this->formatName($item, $this->nameField)."<br/>";
236  }
237  }
238 
239  $this->_endField($field);
240  }
241 
242  function postProcess($field = "")
243  {
244  if (count($this->options) == 0) return;
245 
246  $option_pk = $this->options[0]->getPrimaryKey();
247  $obj_pk = $this->parent->data->getPrimaryKey();
248  $obj_id = $this->parent->data->$obj_pk;
249 
250  $items = reindexList($this->options, $option_pk);
251 
252  $selected = $_POST[$this->field];
253 
258  foreach($selected as $selected_pk => $value)
259  {
260  if(!array_key_exists($selected_pk, $items)) continue;
261 
262  $item = $items[$selected_pk];
263  $item->filter = new InclusionFilter($obj_pk);
264  $item->$obj_pk= $obj_id;
265  $item->save();
266  }
267 
272  foreach($items as $item_id => $item)
273  {
274  if($item->$obj_pk == $obj_id && !array_key_exists($item->$option_pk, $selected))
275  {
276  $item->filter = new InclusionFilter($obj_pk);
277  $item->$obj_pk = 0;
278  $item->save();
279  }
280  }
281  }
282 }
283 
FieldRenderer is the abstract base class for all FieldRenderers.
_startField($field, $styles="")
Internal method to generate the starting HTML for the field (including the label)
formatName($item, $name)
Formats the given DataItem based on the supplied format string.
_endField($field)
Internal method to generate the closing HTML for the field.
FieldRenderer($parent)
Constructor.
Used to place a filter on the contents of a DataItem-derived object.
static create($class, $constraints="", $indexBy="")
static create($class, $constraints="")
Static factory method to create a new Query.
Definition: query.inc:358
reindexList($list, $field, $autoPromote=true)
Reindex an indexed or grouped query result by a different field.
Definition: data_item.inc:1898
regroupList($list, $field)
Regroup an indexed or grouped query result by a different field.
Definition: data_item.inc:1948