PageRenderTime 60ms CodeModel.GetById 32ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/web/concrete/core/models/attribute/types/select.php

https://github.com/glockops/concrete5
PHP | 714 lines | 592 code | 83 blank | 39 comment | 102 complexity | adae88948690f8bd96168eadb1b3b954 MD5 | raw file
  1<?php defined('C5_EXECUTE') or die("Access Denied.");
  2
  3class Concrete5_Controller_AttributeType_Select extends AttributeTypeController  {
  4
  5	private $akSelectAllowMultipleValues;
  6	private $akSelectAllowOtherValues;
  7	private $akSelectOptionDisplayOrder;
  8
  9	protected $searchIndexFieldDefinition = 'X NULL';
 10	
 11	public function type_form() {
 12		$path1 = $this->getView()->getAttributeTypeURL('type_form.js');
 13		$path2 = $this->getView()->getAttributeTypeURL('type_form.css');
 14		$this->addHeaderItem(Loader::helper('html')->javascript($path1));
 15		$this->addHeaderItem(Loader::helper('html')->css($path2));
 16		$this->set('form', Loader::helper('form'));		
 17		$this->load();
 18		//$akSelectValues = $this->getSelectValuesFromPost();
 19		//$this->set('akSelectValues', $akSelectValues);
 20		
 21		if ($this->isPost()) {
 22			$akSelectValues = $this->getSelectValuesFromPost();
 23			$this->set('akSelectValues', $akSelectValues);
 24		} else if (isset($this->attributeKey)) {
 25			$options = $this->getOptions();
 26			$this->set('akSelectValues', $options);
 27		} else {
 28			$this->set('akSelectValues', array());
 29		}
 30	}
 31	
 32	protected function load() {
 33		$ak = $this->getAttributeKey();
 34		if (!is_object($ak)) {
 35			return false;
 36		}
 37		
 38		$db = Loader::db();
 39		$row = $db->GetRow('select akSelectAllowMultipleValues, akSelectOptionDisplayOrder, akSelectAllowOtherValues from atSelectSettings where akID = ?', $ak->getAttributeKeyID());
 40		$this->akSelectAllowMultipleValues = $row['akSelectAllowMultipleValues'];
 41		$this->akSelectAllowOtherValues = $row['akSelectAllowOtherValues'];
 42		$this->akSelectOptionDisplayOrder = $row['akSelectOptionDisplayOrder'];
 43
 44		$this->set('akSelectAllowMultipleValues', $this->akSelectAllowMultipleValues);
 45		$this->set('akSelectAllowOtherValues', $this->akSelectAllowOtherValues);			
 46		$this->set('akSelectOptionDisplayOrder', $this->akSelectOptionDisplayOrder);			
 47	}
 48
 49	public function duplicateKey($newAK) {
 50		$this->load();
 51		$db = Loader::db();
 52		$db->Execute('insert into atSelectSettings (akID, akSelectAllowMultipleValues, akSelectOptionDisplayOrder, akSelectAllowOtherValues) values (?, ?, ?, ?)', array($newAK->getAttributeKeyID(), $this->akSelectAllowMultipleValues, $this->akSelectOptionDisplayOrder, $this->akSelectAllowOtherValues));	
 53		$r = $db->Execute('select value, displayOrder, isEndUserAdded from atSelectOptions where akID = ?', $this->getAttributeKey()->getAttributeKeyID());
 54		while ($row = $r->FetchRow()) {
 55			$db->Execute('insert into atSelectOptions (akID, value, displayOrder, isEndUserAdded) values (?, ?, ?, ?)', array(
 56				$newAK->getAttributeKeyID(),
 57				$row['value'],
 58				$row['displayOrder'],
 59				$row['isEndUserAdded']
 60			));
 61		}
 62	}
 63	
 64	public function exportKey($akey) {
 65		$this->load();
 66		$db = Loader::db();
 67		$type = $akey->addChild('type');
 68		$type->addAttribute('allow-multiple-values', $this->akSelectAllowMultipleValues);
 69		$type->addAttribute('display-order', $this->akSelectOptionDisplayOrder);
 70		$type->addAttribute('allow-other-values', $this->akSelectAllowOtherValues);
 71		$r = $db->Execute('select value, displayOrder, isEndUserAdded from atSelectOptions where akID = ? order by displayOrder asc', $this->getAttributeKey()->getAttributeKeyID());
 72		$options = $type->addChild('options');
 73		while ($row = $r->FetchRow()) {
 74			$opt = $options->addChild('option');
 75			$opt->addAttribute('value', $row['value']);
 76			$opt->addAttribute('is-end-user-added', $row['isEndUserAdded']);
 77		}
 78		return $akey;
 79	}
 80	
 81	public function exportValue($akn) {
 82		$list = $this->getSelectedOptions();
 83		if ($list->count() > 0) {
 84			$av = $akn->addChild('value');
 85			foreach($list as $l) {
 86				$av->addChild('option', (string) $l);
 87			}
 88		}
 89	}
 90	
 91	public function importValue(SimpleXMLElement $akv) {
 92		if (isset($akv->value)) {
 93			$vals = array();
 94			foreach($akv->value->children() as $ch) {
 95				$vals[] = (string) $ch;
 96			}
 97			return $vals;
 98		}
 99	}
100	
101	public function importKey($akey) {
102		if (isset($akey->type)) {
103			$akSelectAllowMultipleValues = $akey->type['allow-multiple-values'];
104			$akSelectOptionDisplayOrder = $akey->type['display-order'];
105			$akSelectAllowOtherValues = $akey->type['allow-other-values'];
106			$db = Loader::db();
107			$db->Replace('atSelectSettings', array(
108				'akID' => $this->attributeKey->getAttributeKeyID(), 
109				'akSelectAllowMultipleValues' => $akSelectAllowMultipleValues, 
110				'akSelectAllowOtherValues' => $akSelectAllowOtherValues,
111				'akSelectOptionDisplayOrder' => $akSelectOptionDisplayOrder
112			), array('akID'), true);
113
114			if (isset($akey->type->options)) {
115				foreach($akey->type->options->children() as $option) {
116					SelectAttributeTypeOption::add($this->attributeKey, $option['value'], $option['is-end-user-added']);
117				}
118			}
119		}
120	}
121	
122	private function getSelectValuesFromPost() {
123		$options = new SelectAttributeTypeOptionList();
124		$displayOrder = 0;		
125		foreach($_POST as $key => $value) {
126			if( !strstr($key,'akSelectValue_') || $value=='TEMPLATE' ) continue; 
127			$opt = false;
128			// strip off the prefix to get the ID
129			$id = substr($key, 14);
130			// now we determine from the post whether this is a new option
131			// or an existing. New ones have this value from in the akSelectValueNewOption_ post field
132			if ($_POST['akSelectValueNewOption_' . $id] == $id) {
133				$opt = new SelectAttributeTypeOption(0, $value, $displayOrder);
134				$opt->tempID = $id;
135			} else if ($_POST['akSelectValueExistingOption_' . $id] == $id) {
136				$opt = new SelectAttributeTypeOption($id, $value, $displayOrder);
137			}
138			
139			if (is_object($opt)) {
140				$options->add($opt);
141				$displayOrder++;
142			}
143		}
144		
145		return $options;
146	}
147	
148	public function form() {
149		$this->load();
150		$options = $this->getSelectedOptions();
151		$selectedOptions = array();
152		foreach($options as $opt) {
153			$selectedOptions[] = $opt->getSelectAttributeOptionID();
154			$selectedOptionValues[$opt->getSelectAttributeOptionID()] = $opt->getSelectAttributeOptionValue();
155		}
156		$this->set('selectedOptionValues',$selectedOptionValues);
157		$this->set('selectedOptions', $selectedOptions);
158		$this->addFooterItem(Loader::helper('html')->javascript('jquery.ui.js'));
159		$this->addHeaderItem(Loader::helper('html')->css('jquery.ui.css'));
160	}
161	
162	public function search() {
163		$this->load();	
164		$selectedOptions = $this->request('atSelectOptionID');
165		if (!is_array($selectedOptions)) {
166			$selectedOptions = array();
167		}
168		$this->set('selectedOptions', $selectedOptions);
169	}
170	
171	public function deleteValue() {
172		$db = Loader::db();
173		$db->Execute('delete from atSelectOptionsSelected where avID = ?', array($this->getAttributeValueID()));
174	}
175
176	public function deleteKey() {
177		$db = Loader::db();
178		$db->Execute('delete from atSelectSettings where akID = ?', array($this->attributeKey->getAttributeKeyID()));
179		$r = $db->Execute('select ID from atSelectOptions where akID = ?', array($this->attributeKey->getAttributeKeyID()));
180		while ($row = $r->FetchRow()) {
181			$db->Execute('delete from atSelectOptionsSelected where atSelectOptionID = ?', array($row['ID']));
182		}
183		$db->Execute('delete from atSelectOptions where akID = ?', array($this->attributeKey->getAttributeKeyID()));
184	}
185
186	public function saveForm($data) {
187		$this->load();
188		
189		if ($this->akSelectAllowOtherValues && is_array($data['atSelectNewOption'])) {
190			$options = $this->getOptions();
191						
192			foreach($data['atSelectNewOption'] as $newoption) {
193				// check for duplicates
194				$existing = false;
195				foreach($options as $opt) {
196					if(strtolower(trim($newoption)) == strtolower(trim($opt->getSelectAttributeOptionValue(false)))) {
197						$existing = $opt;
198						break;
199					}
200				}
201				if($existing instanceof SelectAttributeTypeOption) {
202					$data['atSelectOptionID'][] = $existing->getSelectAttributeOptionID();
203				} else {
204					$optobj = SelectAttributeTypeOption::add($this->attributeKey, $newoption, 1);
205					$data['atSelectOptionID'][] = $optobj->getSelectAttributeOptionID();
206				}
207			}
208		}
209
210		if(is_array($data['atSelectOptionID'])) {
211			$data['atSelectOptionID'] = array_unique($data['atSelectOptionID']);
212		}		
213		$db = Loader::db();
214		$db->Execute('delete from atSelectOptionsSelected where avID = ?', array($this->getAttributeValueID()));
215		if (is_array($data['atSelectOptionID'])) {
216			foreach($data['atSelectOptionID'] as $optID) {
217				if ($optID > 0) {
218					$db->Execute('insert into atSelectOptionsSelected (avID, atSelectOptionID) values (?, ?)', array($this->getAttributeValueID(), $optID));
219					if ($this->akSelectAllowMultipleValues == false) {
220						break;
221					}
222				}
223			}
224		}
225	}
226	
227	// Sets select options for a particular attribute
228	// If the $value == string, then 1 item is selected
229	// if array, then multiple, but only if the attribute in question is a select multiple
230	// Note, items CANNOT be added to the pool (even if the attribute allows it) through this process.
231	// Items should now be added to the database if they don't exist already & if the allow checkbox is checked under the attribute settings
232	// Code from this bug - http://www.concrete5.org/index.php?cID=595692
233	public function saveValue($value) {
234		$db = Loader::db();
235		$this->load();
236		$options = array();		
237		
238		if (is_array($value) && $this->akSelectAllowMultipleValues) {
239			foreach($value as $v) {
240				$opt = SelectAttributeTypeOption::getByValue($v, $this->attributeKey);
241				if (is_object($opt)) {
242					$options[] = $opt;	
243				}else if ($this->akSelectAllowOtherValues) {
244			        $options[] = SelectAttributeTypeOption::add($this->attributeKey, $v, true);
245			    }
246			}
247		} else {
248			if (is_array($value)) {
249				$value = $value[0];
250			}
251			
252			$opt = SelectAttributeTypeOption::getByValue($value, $this->attributeKey);
253			if (is_object($opt)) {
254				$options[] = $opt;	
255			}
256		}
257		
258		$db->Execute('delete from atSelectOptionsSelected where avID = ?', array($this->getAttributeValueID()));
259		if (count($options) > 0) {
260			foreach($options as $opt) {
261				$db->Execute('insert into atSelectOptionsSelected (avID, atSelectOptionID) values (?, ?)', array($this->getAttributeValueID(), $opt->getSelectAttributeOptionID()));
262				if ($this->akSelectAllowMultipleValues == false) {
263					break;
264				}
265			}
266		}
267	}
268
269	
270	public function getDisplayValue() {
271		$list = $this->getSelectedOptions();
272		$html = '';
273		foreach($list as $l) {
274			$html .= $l->getSelectAttributeOptionDisplayValue() . '<br/>';
275		}
276		return $html;
277	}
278
279	public function getDisplaySanitizedValue() {
280		return $this->getDisplayValue();
281	}
282	
283	public function validateForm($p) {
284		$this->load();
285		$options = $this->request('atSelectOptionID');
286		if ($this->akSelectAllowOtherValues) {
287			$options = array_filter((Array) $this->request('atSelectNewOption'));
288			if (is_array($options) && count($options) > 0) {
289				return true;
290			} else if (array_shift($this->request('atSelectOptionID')) != null) {
291				return true;
292			}
293		}
294		if ($this->akSelectAllowMultipleValues) {
295			return count($options) > 0;
296		} else {
297			if ($options[0] != false) {
298				return $options[0] > 0;
299			}
300		}
301		return false;
302	}
303	
304	public function searchForm($list) {
305		$options = $this->request('atSelectOptionID');
306		$db = Loader::db();
307		$tbl = $this->attributeKey->getIndexedSearchTable();
308		if (!is_array($options)) {
309			return $list;
310		}
311		$optionQuery = array();
312		foreach($options as $id) {
313			if ($id > 0) {
314				$opt = SelectAttributeTypeOption::getByID($id);
315				if (is_object($opt)) {
316					$optionQuery[] = $opt->getSelectAttributeOptionValue(false);
317				}
318			}
319		}
320		if (count($optionQuery) == 0) {
321			return false;
322		}
323		
324		$i = 0;
325		foreach($optionQuery as $val) {
326			$val = $db->quote('%||' . $val . '||%');
327			$multiString .= 'REPLACE(' . $tbl . '.ak_' . $this->attributeKey->getAttributeKeyHandle() . ', "\n", "||") like ' . $val . ' ';
328			if (($i + 1) < count($optionQuery)) {
329				$multiString .= 'OR ';
330			}
331			$i++;
332		}
333		$list->filter(false, '(' . $multiString . ')');
334		return $list;
335	}
336	
337	public function getValue() {
338		$list = $this->getSelectedOptions();
339		return $list;	
340	}
341	
342    public function getSearchIndexValue() {
343        $str = "\n";
344        $list = $this->getSelectedOptions();
345        foreach($list as $l) {
346            $l = (is_object($l) && method_exists($l,'__toString')) ? $l->__toString() : $l;
347            $str .= $l . "\n";
348        }
349        // remove line break for empty list
350        if ($str == "\n") {
351            return '';
352        }
353        return $str;
354    }
355	
356	public function getSelectedOptions() {
357		if (!isset($this->akSelectOptionDisplayOrder)) {
358			$this->load();
359		}
360		$db = Loader::db();
361		$sortByDisplayName = false;
362		switch($this->akSelectOptionDisplayOrder) {
363			case 'popularity_desc':
364				$options = $db->GetAll("select ID, value, displayOrder, (select count(s2.atSelectOptionID) from atSelectOptionsSelected s2 where s2.atSelectOptionID = ID) as total from atSelectOptionsSelected inner join atSelectOptions on atSelectOptionsSelected.atSelectOptionID = atSelectOptions.ID where avID = ? order by total desc, value asc", array($this->getAttributeValueID()));
365				break;
366			case 'alpha_asc':
367				$options = $db->GetAll("select ID, value, displayOrder from atSelectOptionsSelected inner join atSelectOptions on atSelectOptionsSelected.atSelectOptionID = atSelectOptions.ID where avID = ?", array($this->getAttributeValueID()));
368				$sortByDisplayName = true;
369				break;
370			default:
371				$options = $db->GetAll("select ID, value, displayOrder from atSelectOptionsSelected inner join atSelectOptions on atSelectOptionsSelected.atSelectOptionID = atSelectOptions.ID where avID = ? order by displayOrder asc", array($this->getAttributeValueID()));
372				break;
373		}
374		$db = Loader::db();
375		$list = new SelectAttributeTypeOptionList();
376		foreach($options as $row) {
377			$opt = new SelectAttributeTypeOption($row['ID'], $row['value'], $row['displayOrder']);
378			$list->add($opt);
379		}
380		if($sortByDisplayName) {
381			$list->sortByDisplayName();
382		}
383		return $list;
384	}
385	
386	public function action_load_autocomplete_values() {
387		$this->load();
388		$values = array();
389			// now, if the current instance of the attribute key allows us to do autocomplete, we return all the values
390		if ($this->akSelectAllowMultipleValues && $this->akSelectAllowOtherValues) {
391			$options = $this->getOptions($_GET['term'] . '%');
392			foreach($options as $opt) {
393				$values[] = $opt->getSelectAttributeOptionValue(false);
394			}
395		}
396		print Loader::helper('json')->encode($values);
397	}
398	
399	public function getOptionUsageArray($parentPage = false, $limit = 9999) {
400		$db = Loader::db();
401		$q = "select atSelectOptions.value, atSelectOptionID, count(atSelectOptionID) as total from Pages inner join CollectionVersions on (Pages.cID = CollectionVersions.cID and CollectionVersions.cvIsApproved = 1) inner join CollectionAttributeValues on (CollectionVersions.cID = CollectionAttributeValues.cID and CollectionVersions.cvID = CollectionAttributeValues.cvID) inner join atSelectOptionsSelected on (atSelectOptionsSelected.avID = CollectionAttributeValues.avID) inner join atSelectOptions on atSelectOptionsSelected.atSelectOptionID = atSelectOptions.ID where Pages.cIsActive = 1 and CollectionAttributeValues.akID = ? ";
402		$v = array($this->attributeKey->getAttributeKeyID());
403		if (is_object($parentPage)) {
404			$v[] = $parentPage->getCollectionID();
405			$q .= "and cParentID = ?";
406		}
407		$q .= " group by atSelectOptionID order by total desc limit " . $limit;
408		$r = $db->Execute($q, $v);
409		$list = new SelectAttributeTypeOptionList();
410		$i = 0;
411		while ($row = $r->FetchRow()) {
412			$opt = new SelectAttributeTypeOption($row['atSelectOptionID'], $row['value'], $i, $row['total']);
413			$list->add($opt);
414			$i++;
415		}		
416		return $list;
417	}
418	
419	/**
420	 * returns a list of available options optionally filtered by an sql $like statement ex: startswith%
421	 * @param string $like
422	 * @return SelectAttributeTypeOptionList
423	 */
424	public function getOptions($like = NULL) {
425		if (!isset($this->akSelectOptionDisplayOrder)) {
426			$this->load();
427		}
428		$db = Loader::db();
429		switch($this->akSelectOptionDisplayOrder) {
430			case 'popularity_desc':
431				if(isset($like) && strlen($like)) {
432					$r = $db->Execute('select ID, value, displayOrder, count(atSelectOptionsSelected.atSelectOptionID) as total 
433						from atSelectOptions left join atSelectOptionsSelected on (atSelectOptions.ID = atSelectOptionsSelected.atSelectOptionID) 
434						where akID = ? AND atSelectOptions.value LIKE ? group by ID order by total desc, value asc', array($this->attributeKey->getAttributeKeyID(),$like));
435				} else {
436					$r = $db->Execute('select ID, value, displayOrder, count(atSelectOptionsSelected.atSelectOptionID) as total 
437						from atSelectOptions left join atSelectOptionsSelected on (atSelectOptions.ID = atSelectOptionsSelected.atSelectOptionID) 
438						where akID = ? group by ID order by total desc, value asc', array($this->attributeKey->getAttributeKeyID()));
439				}
440				break;
441			case 'alpha_asc':
442				if(isset($like) && strlen($like)) {
443					$r = $db->Execute('select ID, value, displayOrder from atSelectOptions where akID = ? AND atSelectOptions.value LIKE ? order by value asc', array($this->attributeKey->getAttributeKeyID(),$like));
444				} else {
445					$r = $db->Execute('select ID, value, displayOrder from atSelectOptions where akID = ? order by value asc', array($this->attributeKey->getAttributeKeyID()));
446				}
447				break;
448			default:
449				if(isset($like) && strlen($like)) {
450					$r = $db->Execute('select ID, value, displayOrder from atSelectOptions where akID = ? AND atSelectOptions.value LIKE ? order by displayOrder asc', array($this->attributeKey->getAttributeKeyID(),$like));
451				} else {
452					$r = $db->Execute('select ID, value, displayOrder from atSelectOptions where akID = ? order by displayOrder asc', array($this->attributeKey->getAttributeKeyID()));
453				}
454				break;
455		}
456		$options = new SelectAttributeTypeOptionList();
457		while ($row = $r->FetchRow()) {
458			$opt = new SelectAttributeTypeOption($row['ID'], $row['value'], $row['displayOrder']);
459			$options->add($opt);
460		}
461		return $options;
462	}
463		
464	public function saveKey($data) {
465		$ak = $this->getAttributeKey();
466		
467		$db = Loader::db();
468
469		$initialOptionSet = $this->getOptions();
470		$selectedPostValues = $this->getSelectValuesFromPost();
471		
472		$akSelectAllowMultipleValues = $data['akSelectAllowMultipleValues'];
473		$akSelectAllowOtherValues = $data['akSelectAllowOtherValues'];
474		$akSelectOptionDisplayOrder = $data['akSelectOptionDisplayOrder'];
475		
476		if ($data['akSelectAllowMultipleValues'] != 1) {
477			$akSelectAllowMultipleValues = 0;
478		}
479		if ($data['akSelectAllowOtherValues'] != 1) {
480			$akSelectAllowOtherValues = 0;
481		}
482		if (!in_array($data['akSelectOptionDisplayOrder'], array('display_asc', 'alpha_asc', 'popularity_desc'))) {
483			$akSelectOptionDisplayOrder = 'display_asc';
484		}
485				
486		// now we have a collection attribute key object above.
487		$db->Replace('atSelectSettings', array(
488			'akID' => $ak->getAttributeKeyID(), 
489			'akSelectAllowMultipleValues' => $akSelectAllowMultipleValues, 
490			'akSelectAllowOtherValues' => $akSelectAllowOtherValues,
491			'akSelectOptionDisplayOrder' => $akSelectOptionDisplayOrder
492		), array('akID'), true);
493		
494		// Now we add the options
495		$newOptionSet = new SelectAttributeTypeOptionList();
496		$displayOrder = 0;
497		foreach($selectedPostValues as $option) {
498			$opt = $option->saveOrCreate($ak);
499			if ($akSelectOptionDisplayOrder == 'display_asc') {
500				$opt->setDisplayOrder($displayOrder);
501			}
502			$newOptionSet->add($opt);
503			$displayOrder++;
504		}
505		
506		// Now we remove all options that appear in the 
507		// old values list but not in the new
508		foreach($initialOptionSet as $iopt) {
509			if (!$newOptionSet->contains($iopt)) {
510				$iopt->delete();
511			}
512		}
513	}
514
515	/**
516	 * Convenience methods to retrieve a select attribute key's settings
517	 */
518	public function getAllowMultipleValues() {
519		if (is_null($this->akSelectAllowMultipleValues)) {
520			$this->load();
521		}
522		return $this->akSelectAllowMultipleValues;
523	}
524	
525	public function getAllowOtherValues() {
526		if (is_null($this->akSelectAllowOtherValues)) {
527			$this->load();
528		}
529		return $this->akSelectAllowOtherValues;
530	}
531	
532	public function getOptionDisplayOrder() {
533		if (is_null($this->akSelectOptionDisplayOrder)) {
534			$this->load();
535		}
536		return $this->akSelectOptionDisplayOrder;
537	}
538	
539}
540
541class Concrete5_Model_SelectAttributeTypeOption extends Object {
542
543	public function __construct($ID, $value, $displayOrder, $usageCount = false) {
544		$this->ID = $ID;
545		$this->value = $value;
546		$this->th = Loader::helper('text');
547		$this->displayOrder = $displayOrder;	
548		$this->usageCount = $usageCount;	
549	}
550	
551	public function getSelectAttributeOptionID() {return $this->ID;}
552	public function getSelectAttributeOptionUsageCount() {return $this->usageCount;}
553	public function getSelectAttributeOptionValue($sanitize = true) {
554		if (!$sanitize) {
555			return $this->value;
556		} else {
557			return $this->th->specialchars($this->value);
558		}
559	}
560	/** Returns the display name for this select option value (localized and escaped accordingly to $format)
561	* @param string $format = 'html'
562	*	Escape the result in html format (if $format is 'html').
563	*	If $format is 'text' or any other value, the display name won't be escaped.
564	* @return string
565	*/
566	public function getSelectAttributeOptionDisplayValue($format = 'html') {
567		$value = tc('SelectAttributeValue', $this->getSelectAttributeOptionValue(false));
568		switch($format) {
569			case 'html':
570				return h($value);
571			case 'text':
572			default:
573				return $value;
574		}
575	}
576	public function getSelectAttributeOptionDisplayOrder() {return $this->displayOrder;}
577	public function getSelectAttributeOptionTemporaryID() {return $this->tempID;}
578	
579	public function __toString() {return $this->value;}
580	
581	public static function add($ak, $option, $isEndUserAdded = 0) {
582		$db = Loader::db();
583		$th = Loader::helper('text');
584		// this works because displayorder starts at zero. So if there are three items, for example, the display order of the NEXT item will be 3.
585		$displayOrder = $db->GetOne('select count(ID) from atSelectOptions where akID = ?', array($ak->getAttributeKeyID()));			
586
587		$v = array($ak->getAttributeKeyID(), $displayOrder, $th->sanitize($option), $isEndUserAdded);
588		$db->Execute('insert into atSelectOptions (akID, displayOrder, value, isEndUserAdded) values (?, ?, ?, ?)', $v);
589		
590		return SelectAttributeTypeOption::getByID($db->Insert_ID());
591	}
592	
593	public function setDisplayOrder($num) {
594		$db = Loader::db();
595		$db->Execute('update atSelectOptions set displayOrder = ? where ID = ?', array($num, $this->ID));
596	}
597	
598	public static function getByID($id) {
599		$db = Loader::db();
600		$row = $db->GetRow("select ID, displayOrder, value from atSelectOptions where ID = ?", array($id));
601		if (isset($row['ID'])) {
602			$obj = new SelectAttributeTypeOption($row['ID'], $row['value'], $row['displayOrder']);
603			return $obj;
604		}
605	}
606	
607	public static function getByValue($value, $ak = false) {
608		$db = Loader::db();
609		if (is_object($ak)) {
610			$row = $db->GetRow("select ID, displayOrder, value from atSelectOptions where value = ? and akID = ?", array($value, $ak->getAttributeKeyID()));
611		} else {
612			$row = $db->GetRow("select ID, displayOrder, value from atSelectOptions where value = ?", array($value));
613		}
614		if (isset($row['ID'])) {
615			$obj = new SelectAttributeTypeOption($row['ID'], $row['value'], $row['displayOrder']);
616			return $obj;
617		}
618	}
619	
620	public function delete() {
621		$db = Loader::db();
622		$db->Execute('delete from atSelectOptions where ID = ?', array($this->ID));
623		$db->Execute('delete from atSelectOptionsSelected where atSelectOptionID = ?', array($this->ID));
624	}
625	
626	public function saveOrCreate($ak) {
627		if ($this->tempID != false || $this->ID==0) {
628			return SelectAttributeTypeOption::add($ak, $this->value);
629		} else {
630			$db = Loader::db();
631			$th = Loader::helper('text');
632			$db->Execute('update atSelectOptions set value = ? where ID = ?', array($th->sanitize($this->value), $this->ID));
633			return SelectAttributeTypeOption::getByID($this->ID);
634		}
635	}
636	
637}
638
639class Concrete5_Model_SelectAttributeTypeOptionList extends Object implements Iterator {
640
641	private $options = array();
642	
643	public function add(SelectAttributeTypeOption $opt) {
644		$this->options[] = $opt;
645	}
646	
647	public function rewind() {
648		reset($this->options);
649	}
650	
651	public function current() {
652		return current($this->options);
653	}
654	
655	public function key() {
656		return key($this->options);
657	}
658	
659	public function next() {
660		next($this->options);
661	}
662	
663	public function valid() {
664		return $this->current() !== false;
665	}
666	
667	public function count() {return count($this->options);}
668	
669	public function contains(SelectAttributeTypeOption $opt) {
670		foreach($this->options as $o) {
671			if ($o->getSelectAttributeOptionID() == $opt->getSelectAttributeOptionID()) {
672				return true;
673			}
674		}
675		
676		return false;
677	}
678	
679	public function get($index) {
680		return $this->options[$index];
681	}
682	
683	public function getOptions() {
684		return $this->options;
685	}
686
687	/** Sort the options by their display value. */
688	public function sortByDisplayName() {
689		usort($this->options, array(__CLASS__, 'displayValueSorter'));
690	}
691	/**
692	* @param SelectAttributeTypeOption $a
693	* @param SelectAttributeTypeOption $b
694	* @return int
695	*/
696	protected static function displayValueSorter($a, $b) {
697		return strcasecmp($a->getSelectAttributeOptionDisplayValue('text'), $b->getSelectAttributeOptionDisplayValue('text'));
698	}
699
700	public function __toString() {
701		$str = '';
702		$i = 0;
703		foreach($this->options as $opt) {
704			$str .= $opt->getSelectAttributeOptionValue();
705			$i++;
706			if ($i < count($this->options)) {
707				$str .= "\n";
708			}
709		}
710		return $str;
711	}
712
713
714}