1: <?php
2:
3: /**
4: * The DEnum (Dynamic Enum) complex data type. Similiar to Enum,
5: * except list items are stored in a database table and are editable.
6: *
7: * @package alpha::model::types
8: * @since 1.0
9: * @author John Collins <dev@alphaframework.org>
10: * @version $Id: DEnum.inc 1600 2012-12-10 10:51:41Z alphadevx $
11: * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
12: * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
13: * All rights reserved.
14: *
15: * <pre>
16: * Redistribution and use in source and binary forms, with or
17: * without modification, are permitted provided that the
18: * following conditions are met:
19: *
20: * * Redistributions of source code must retain the above
21: * copyright notice, this list of conditions and the
22: * following disclaimer.
23: * * Redistributions in binary form must reproduce the above
24: * copyright notice, this list of conditions and the
25: * following disclaimer in the documentation and/or other
26: * materials provided with the distribution.
27: * * Neither the name of the Alpha Framework nor the names
28: * of its contributors may be used to endorse or promote
29: * products derived from this software without specific
30: * prior written permission.
31: *
32: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
33: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
34: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
35: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45: * </pre>
46: *
47: */
48: class DEnum extends AlphaDAO implements AlphaTypeInterface{
49: /**
50: * An array of valid DEnum options
51: *
52: * @var array
53: * @since 1.0
54: */
55: protected $options = array();
56:
57: /**
58: * The currently selected DEnum option
59: *
60: * @var integer
61: * @since 1.0
62: */
63: protected $value;
64:
65: /**
66: * The name of the DEnum used in the database
67: *
68: * @var String
69: * @since 1.0
70: */
71: protected $name;
72:
73: /**
74: * The name of the database table for the class
75: *
76: * @var string
77: * @since 1.0
78: */
79: const TABLE_NAME = 'DEnum';
80:
81: /**
82: * An array of data display labels for the class properties
83: *
84: * @var array
85: * @since 1.0
86: */
87: protected $dataLabels = array("OID"=>"DEnum ID#","name"=>"Name");
88:
89: /**
90: * The message to display to the user when validation fails
91: *
92: * @var string
93: * @since 1.0
94: */
95: protected $helper = 'Not a valid denum option!';
96:
97: /**
98: * Trace logger
99: *
100: * @var Logger
101: * @since 1.2
102: */
103: private static $logger = null;
104:
105: /**
106: * Constructor that sets up the DEnum options
107: *
108: * @param String $name
109: */
110: public function __construct($name=null) {
111: self::$logger = new Logger('DEnum');
112:
113: // ensure to call the parent constructor
114: parent::__construct();
115:
116: $this->markTransient('options');
117: $this->markTransient('value');
118: $this->markTransient('helper');
119:
120: $this->name = new String($name);
121:
122: if(isset($name) && $this->checkTableExists()) {
123: try {
124: $this->loadByAttribute('name',$name);
125: }catch(BONotFoundException $e) {
126: // DEnum does not exist so create it
127: $this->save();
128: }
129:
130: try{
131: $this->getOptions();
132: }catch(AlphaException $e) {
133: self::$logger->warn($e->getMessage());
134: }
135: }
136: }
137:
138: /**
139: * Setter for the name of the DEnum used in the database
140: *
141: * @param string $name
142: * @since 1.0
143: */
144: public function setName($name) {
145: $this->name->setValue($name);
146: }
147:
148: /**
149: * Get the array of DEnum options from the database
150: *
151: * @param boolean $alphaSort
152: * @return array
153: * @since 1.0
154: * throws AlphaException
155: */
156: public function getOptions($alphaSort = false) {
157: try {
158: $options = new DEnum();
159: $options->loadByAttribute('name', $this->name->getValue());
160: }catch (BONotFoundException $e) {
161: throw new AlphaException('Failed to load DEnum '.$this->name->getValue().', not found in database.');
162: }
163:
164: // now build an array of item indexes to be returned
165: $count = 0;
166: $this->options = array();
167:
168: $tmp = new DEnumItem();
169:
170: foreach($tmp->loadItems($options->getOID()) as $DEnumItem) {
171: $this->options[$DEnumItem->getID()] = $DEnumItem->getValue();
172: $count++;
173: }
174:
175: if($alphaSort)
176: asort($this->options, SORT_STRING);
177: return $this->options;
178: }
179:
180: /**
181: * Getter for the validation helper string
182: *
183: * @return string
184: * @since 1.0
185: */
186: public function getHelper() {
187: return $this->helper;
188: }
189:
190: /**
191: * Set the validation helper text
192: *
193: * @param string $helper
194: * @since 1.0
195: */
196: public function setHelper($helper) {
197: $this->helper = $helper;
198: }
199:
200: /**
201: * Getter for the name
202: *
203: * @return String
204: * @since 1.0
205: */
206: public function getName() {
207: return $this->name;
208: }
209:
210: /**
211: * Used to get the current DEnum item selected index value
212: *
213: * @return integer
214: * @since 1.0
215: */
216: public function getValue() {
217: return $this->value;
218: }
219:
220: /**
221: * Used to get the current DEnum item string value
222: *
223: * @return string
224: * @since 1.0
225: */
226: public function getDisplayValue() {
227: // check to see if the options have already been loaded from the DB
228: if(empty($this->options))
229: $this->getOptions();
230:
231: $val = Integer::zeroPad($this->value);
232: if(isset($this->options[$val]))
233: return $this->options[$val];
234: else
235: return 'Unknown';
236: }
237:
238: /**
239: * Used to select the current DEnum item
240: *
241: * @param string $item
242: * @since 1.0
243: */
244: public function setValue($item) {
245: // check to see if the options have already been loaded from the DB
246: if(empty($this->options))
247: $this->getOptions();
248:
249: // confirm that the item ID provided is a valid key for the options array
250: if (in_array($item, array_keys($this->options))) {
251: $this->value = $item;
252: }else{
253: throw new IllegalArguementException($this->getHelper());
254: }
255: }
256:
257: /**
258: * Gets the count from the database of the DEnumItems associated with this object
259: *
260: * @return integer
261: * @since 1.0
262: * @throws AlphaException
263: */
264: public function getItemCount() {
265:
266: global $config;
267:
268: $provider = AlphaDAOProviderFactory::getInstance($config->get('db.provider.name'), $this);
269:
270: $sqlQuery = 'SELECT COUNT(OID) AS item_count FROM DEnumItem WHERE DEnumID = \''.$this->getID().'\';';
271:
272: $this->setLastQuery($sqlQuery);
273:
274: $result = $provider->query($sqlQuery);
275:
276: if (count($result) > 0 && isset($result[0]['item_count'])) {
277: return $result[0]['item_count'];
278: }else{
279: throw new AlphaException('Failed to get the item count for the DEnum. Database error string is ['.$provider->getLastDatabaseError().']');
280: }
281: }
282:
283: /**
284: * Used to get the DenumItem ID for the given option name
285: *
286: * @param string $optionName
287: * @return integer
288: * @since 1.0
289: */
290: public function getOptionID($optionName) {
291: $denumItem = new DEnumItem();
292: $denumItem->loadByAttribute('value', $optionName);
293: $id = $denumItem->getID();
294:
295: if(!empty($id))
296: return $id;
297: else
298: return 0;
299: }
300:
301: /**
302: * Used to convert the object to a printable string
303: *
304: * @return string
305: * @since 1.0
306: */
307: public function __toString() {
308: return strval($this->value);
309: }
310: }
311:
312: ?>