      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: ?>