Source for file RelationLookup.inc
Documentation is available at RelationLookup.inc
require_once $config->get('sysRoot'). 'alpha/model/types/AlphaTypeInterface.inc';
* The RelationLookup complex data type. Used to store object2object lookup tables for
* MANY-TO-MANY relationships between business objects
* @package alpha::model::types
* @author John Collins <dev@alphaframework.org>
* @version $Id: RelationLookup.inc 1341 2011-03-17 15:02:02Z johnc $
* @license http://www.opensource.org/licenses/bsd-license.php The BSD License
* @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* * Neither the name of the Alpha Framework nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The OID of the left business object in the relation
* The OID of the right business object in the relation
* The name of the left business object class in the relation
* The name of the right business object class in the relation
private static $logger = null;
* an array of data display labels for the class properties
protected $dataLabels = array("OID"=> "RelationLookup ID#","leftID"=> "Left BO ID#","rightID"=> "Right BO ID#");
* The message to display to the user when validation fails
protected $helper = 'Not a valid RelationLookup value!';
* @throws FailedLookupCreateException
* @throws IllegalArguementException
public function __construct($leftClassName, $rightClassName) {
self::$logger = new Logger('RelationLookup');
self::$logger->debug('>>__construct(leftClassName=['. $leftClassName. '], rightClassName=['. $rightClassName. '])');
// ensure to call the parent constructor
if(empty($leftClassName) || empty($rightClassName)) {
throw new IllegalArguementException('Cannot create RelationLookup object without providing the left and right class names!');
$this->leftClassName = $leftClassName;
$this->rightClassName = $rightClassName;
// add a unique composite key to these fields
// make sure the lookup table exists
// first make sure that the two BO tables exist before relating them with a lookup table
self::$logger->debug('<<__construct');
* Get the leftClassName value
return $this->leftClassName;
* Get the rightClassName value
return $this->rightClassName;
* Custom getter for the TABLE_NAME, which can't be static in this class due to
* the lookup tablenames being different each time.
if(isset ($this->leftClassName) && isset ($this->rightClassName)) {
$left = rtrim($this->leftClassName, "Object");
$right = rtrim($this->rightClassName, "Object");
self::$logger->debug('Setting table name to ['. $left. '2'. $right. ']');
throw new AlphaException('No table name set for the class ['. get_class($this). '], left or right class name(s) missing');
* Loads all of the objects of this class by the specified attribute into an array which is returned.
* This custom version provides the left/right class names to the business object constructor, required
* for RelationLookup objects.
* @param string $atribute The attribute to load the objects by.
* @param string $value The value of the attribute to load the objects by.
* @param integer $start The start of the SQL LIMIT clause, useful for pagination.
* @param integer $limit The amount (limit) of objects to load, useful for pagination.
* @param string $orderBy The name of the field to sort the objects by.
* @param string $order The order to sort the objects by.
* @return array An array containing objects of this type of business object.
* @throws BONotFoundException
public function loadAllByAttribute($attribute, $value, $start= 0, $limit= 0, $orderBy= "OID", $order= "ASC") {
self::$logger->debug('>>loadAllByAttribute(attribute=['. $attribute. '], value=['. $value. '], start=['. $start. '], limit=['. $limit. '], orderBy=['. $orderBy. '], order=['. $order. ']');
if(method_exists($this, 'before_loadAllByAttribute_callback'))
$this->before_loadAllByAttribute_callback();
if ($start != 0 && $limit != 0)
$limit = ' LIMIT '. $start. ', '. $limit. ';';
$sqlQuery = "SELECT OID FROM ". $this->getTableName(). " WHERE $attribute = ? ORDER BY ". $orderBy. " ". $order. $limit;
$sqlQuery = "SELECT OID FROM ". $this->getTableName(). " WHERE $attribute = ? AND classname = ? ORDER BY ". $orderBy. " ". $order. $limit;
if($stmt->prepare($sqlQuery)) {
if($this->$attribute instanceof Integer) {
$stmt->bind_param('is', $value, get_class($this));
$stmt->bind_param('i', $value);
$stmt->bind_param('ss', $value, get_class($this));
$stmt->bind_param('s', $value);
self::$logger->warn('The following query caused an unexpected result ['. $sqlQuery. ']');
throw new BONotFoundException('Failed to load objects by attribute ['. $attribute. '] and value ['. $value. '], table did not exist so had to create!');
self::$logger->debug('<<loadAllByAttribute []');
// now build an array of objects to be returned
$BO_Class = get_class($this);
foreach($result as $row) {
$obj = new $BO_Class($this->leftClassName, $this->rightClassName);
// the resource not allowed will be absent from the list
$this->after_loadAllByAttribute_callback();
self::$logger->debug('<<loadAllByAttribute ['. count($objects). ']');
* Getter for the validation helper string
* Set the validation helper text
* Returns an array of the OIDs of the related objects
* Used to set the OIDs of the related objects. Pass a two-item array of OIDs, the first
* one being the left object OID, the second being the right.
* @throws IllegalArguementException
* Used to convert the object to a printable string
|