Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • Boolean
  • Date
  • DEnum
  • DEnumItem
  • Double
  • Enum
  • Integer
  • Relation
  • RelationLookup
  • Sequence
  • String
  • Text
  • Timestamp
  • Type

Interfaces

  • TypeInterface
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alpha\Model\Type;
  4: 
  5: use Alpha\Model\ActiveRecord;
  6: use Alpha\Model\ActiveRecordProviderFactory;
  7: use Alpha\Exception\FailedLookupCreateException;
  8: use Alpha\Exception\IllegalArguementException;
  9: use Alpha\Exception\AlphaException;
 10: use Alpha\Util\Config\ConfigProvider;
 11: use Alpha\Util\Logging\Logger;
 12: use ReflectionClass;
 13: 
 14: /**
 15:  * The RelationLookup complex data type.  Used to store object2object lookup tables for
 16:  * MANY-TO-MANY relationships between record objects.
 17:  *
 18:  * @since 1.0
 19:  *
 20:  * @author John Collins <dev@alphaframework.org>
 21:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 22:  * @copyright Copyright (c) 2015, John Collins (founder of Alpha Framework).
 23:  * All rights reserved.
 24:  *
 25:  * <pre>
 26:  * Redistribution and use in source and binary forms, with or
 27:  * without modification, are permitted provided that the
 28:  * following conditions are met:
 29:  *
 30:  * * Redistributions of source code must retain the above
 31:  *   copyright notice, this list of conditions and the
 32:  *   following disclaimer.
 33:  * * Redistributions in binary form must reproduce the above
 34:  *   copyright notice, this list of conditions and the
 35:  *   following disclaimer in the documentation and/or other
 36:  *   materials provided with the distribution.
 37:  * * Neither the name of the Alpha Framework nor the names
 38:  *   of its contributors may be used to endorse or promote
 39:  *   products derived from this software without specific
 40:  *   prior written permission.
 41:  *
 42:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 43:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 44:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 45:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 46:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 47:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 48:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 49:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 50:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 51:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 52:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 53:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 54:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 55:  * </pre>
 56:  */
 57: class RelationLookup extends ActiveRecord implements TypeInterface
 58: {
 59:     /**
 60:      * The OID of the left business object in the relation.
 61:      *
 62:      * @var Alpha\Model\Type\Integer
 63:      *
 64:      * @since 1.0
 65:      */
 66:     protected $leftID;
 67: 
 68:     /**
 69:      * The OID of the right business object in the relation.
 70:      *
 71:      * @var Alpha\Model\Type\Integer
 72:      *
 73:      * @since 1.0
 74:      */
 75:     protected $rightID;
 76: 
 77:     /**
 78:      * The name of the left business object class in the relation.
 79:      *
 80:      * @var string
 81:      *
 82:      * @since 1.0
 83:      */
 84:     private $leftClassName;
 85: 
 86:     /**
 87:      * The name of the right business object class in the relation.
 88:      *
 89:      * @var string
 90:      *
 91:      * @since 1.0
 92:      */
 93:     private $rightClassName;
 94: 
 95:     /**
 96:      * Trace logger.
 97:      *
 98:      * @var Alpha\Util\Logging\Logger
 99:      *
100:      * @since 1.0
101:      */
102:     private static $logger = null;
103: 
104:     /**
105:      * an array of data display labels for the class properties.
106:      *
107:      * @var array
108:      *
109:      * @since 1.0
110:      */
111:     protected $dataLabels = array('OID' => 'RelationLookup ID#', 'leftID' => 'Left BO ID#', 'rightID' => 'Right BO ID#');
112: 
113:     /**
114:      * The message to display to the user when validation fails.
115:      *
116:      * @var string
117:      *
118:      * @since 1.0
119:      */
120:     protected $helper = 'Not a valid RelationLookup value!';
121: 
122:     /**
123:      * The constructor.
124:      *
125:      * @throws Alpha\Exception\FailedLookupCreateException
126:      * @throws Alpha\Exception\IllegalArguementException
127:      *
128:      * @since 1.0
129:      */
130:     public function __construct($leftClassName, $rightClassName)
131:     {
132:         self::$logger = new Logger('RelationLookup');
133:         self::$logger->debug('>>__construct(leftClassName=['.$leftClassName.'], rightClassName=['.$rightClassName.'])');
134: 
135:         // ensure to call the parent constructor
136:         parent::__construct();
137: 
138:         if (empty($leftClassName) || empty($rightClassName)) {
139:             throw new IllegalArguementException('Cannot create RelationLookup object without providing the left and right class names!');
140:         }
141: 
142:         $this->leftClassName = $leftClassName;
143:         $this->rightClassName = $rightClassName;
144: 
145:         $this->leftID = new Integer();
146:         $this->rightID = new Integer();
147: 
148:         $this->markTransient('leftClassName');
149:         $this->markTransient('rightClassName');
150:         $this->markTransient('helper');
151:         $this->markTransient('TABLE_NAME');
152: 
153:         // add a unique composite key to these fields
154:         $this->markUnique('leftID', 'rightID');
155: 
156:         // make sure the lookup table exists
157:         if (!$this->checkTableExists() && ActiveRecord::isInstalled()) {
158:             // first make sure that the two BO tables exist before relating them with a lookup table
159:             if (ActiveRecord::checkBOTableExists($leftClassName) && ActiveRecord::checkBOTableExists($rightClassName)) {
160:                 $this->makeTable();
161:             } else {
162:                 throw new FailedLookupCreateException('Error trying to create a lookup table ['.$this->getTableName().'], as tables for BOs ['.$leftClassName.'] or ['.$rightClassName.'] don\'t exist!');
163:             }
164:         }
165: 
166:         self::$logger->debug('<<__construct');
167:     }
168: 
169:     /**
170:      * Get the leftClassName value.
171:      *
172:      * @return string
173:      *
174:      * @since 1.0
175:      */
176:     public function getLeftClassName()
177:     {
178:         return $this->leftClassName;
179:     }
180: 
181:     /**
182:      * Get the rightClassName value.
183:      *
184:      * @return string
185:      *
186:      * @since 1.0
187:      */
188:     public function getRightClassName()
189:     {
190:         return $this->rightClassName;
191:     }
192: 
193:     /**
194:      * Custom getter for the TABLE_NAME, which can't be static in this class due to
195:      * the lookup tablenames being different each time.
196:      *
197:      * @return string
198:      *
199:      * @since 1.0
200:      *
201:      * @throws Alpha\Exception\AlphaException
202:      */
203:     public function getTableName()
204:     {
205:         if (isset($this->leftClassName) && isset($this->rightClassName)) {
206:             $leftClass = new ReflectionClass($this->leftClassName);
207:             $left = $leftClass->getShortname();
208:             $rightClass = new ReflectionClass($this->rightClassName);
209:             $right = $rightClass->getShortname();
210:             self::$logger->debug('Setting table name to ['.$left.'2'.$right.']');
211: 
212:             return $left.'2'.$right;
213:         } else {
214:             throw new AlphaException('No table name set for the class ['.get_class($this).'], left or right class name(s) missing');
215:         }
216:     }
217: 
218:     /**
219:      * This custom version provides the left/right class names to the business object constructor, required
220:      * for RelationLookup objects.
221:      *
222:      * (non-PHPdoc)
223:      *
224:      * @see Alpha\Model\ActiveRecord::loadAllByAttribute()
225:      */
226:     public function loadAllByAttribute($attribute, $value, $start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false, $constructorArgs = array())
227:     {
228:         if (!isset(self::$logger)) {
229:             self::$logger = new Logger('RelationLookup');
230:         }
231: 
232:         self::$logger->debug('>>loadAllByAttribute(attribute=['.$attribute.'], value=['.$value.'], start=['.$start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.'], constructorArgs=['.print_r($constructorArgs, true).']');
233: 
234:         if (method_exists($this, 'before_loadAllByAttribute_callback')) {
235:             $this->before_loadAllByAttribute_callback();
236:         }
237: 
238:         $config = ConfigProvider::getInstance();
239: 
240:         $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
241:         $objects = $provider->loadAllByAttribute($attribute, $value, $start, $limit, $orderBy, $order, $ignoreClassType, array($this->leftClassName, $this->rightClassName));
242: 
243:         if (method_exists($this, 'after_loadAllByAttribute_callback')) {
244:             $this->after_loadAllByAttribute_callback();
245:         }
246: 
247:         self::$logger->debug('<<loadAllByAttribute ['.count($objects).']');
248: 
249:         return $objects;
250:     }
251: 
252:     /**
253:      * This custom version provides the left/right class names to the business object constructor, required
254:      * for RelationLookup objects.
255:      *
256:      * (non-PHPdoc)
257:      *
258:      * @see Alpha\Model\ActiveRecord::loadAllByAttributes()
259:      */
260:     public function loadAllByAttributes($attributes = array(), $values = array(), $start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false)
261:     {
262:         self::$logger->debug('>>loadAllByAttributes(attributes=['.var_export($attributes, true).'], values=['.var_export($values, true).'], start=['.
263:             $start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.']');
264: 
265:         if (method_exists($this, 'before_loadAllByAttributes_callback')) {
266:             $this->before_loadAllByAttributes_callback();
267:         }
268: 
269:         $config = ConfigProvider::getInstance();
270: 
271:         if (!is_array($attributes) || !is_array($values)) {
272:             throw new IllegalArguementException('Illegal arrays attributes=['.var_export($attributes, true).'] and values=['.var_export($values, true).
273:                 '] provided to loadAllByAttributes');
274:         }
275: 
276:         $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
277:         $objects = $provider->loadAllByAttributes($attributes, $values, $start, $limit, $orderBy, $order, $ignoreClassType, array($this->leftClassName, $this->rightClassName));
278: 
279:         if (method_exists($this, 'after_loadAllByAttributes_callback')) {
280:             $this->after_loadAllByAttributes_callback();
281:         }
282: 
283:         self::$logger->debug('<<loadAllByAttributes ['.count($objects).']');
284: 
285:         return $objects;
286:     }
287: 
288:     /**
289:      * Getter for the validation helper string.
290:      *
291:      * @return string
292:      *
293:      * @since 1.0
294:      */
295:     public function getHelper()
296:     {
297:         return $this->helper;
298:     }
299: 
300:     /**
301:      * Set the validation helper text.
302:      *
303:      * @param string $helper
304:      *
305:      * @since 1.0
306:      */
307:     public function setHelper($helper)
308:     {
309:         $this->helper = $helper;
310:     }
311: 
312:     /**
313:      * Returns an array of the OIDs of the related objects.
314:      *
315:      * @return array
316:      *
317:      * @since 1.0
318:      */
319:     public function getValue()
320:     {
321:         return array($this->leftID->getValue(), $this->rightID->getValue());
322:     }
323: 
324:     /**
325:      * Used to set the OIDs of the related objects.  Pass a two-item array of OIDs, the first
326:      * one being the left object OID, the second being the right.
327:      *
328:      * @param array $OIDs
329:      *
330:      * @since 1.0
331:      *
332:      * @throws Alpha\Exception\IllegalArguementException
333:      */
334:     public function setValue($OIDs)
335:     {
336:         try {
337:             $this->leftID->setValue($OIDs[0]);
338:             $this->rightID->setValue($OIDs[1]);
339:         } catch (\Exception $e) {
340:             throw new IllegalArguementException('Array value passed to setValue is not valid ['.var_export($OIDs, true).'], array should contain two OIDs');
341:         }
342:     }
343: 
344:     /**
345:      * Used to convert the object to a printable string.
346:      *
347:      * @return string
348:      *
349:      * @since 1.0
350:      */
351:     public function __toString()
352:     {
353:         return strval($this->getTableName());
354:     }
355: }
356: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0