Alpha Framework alpha--model--types
[ class tree: alpha--model--types ] [ index: alpha--model--types ] [ all elements ]

Source for file RelationLookup.inc

Documentation is available at RelationLookup.inc

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

Documentation generated on Thu, 17 Mar 2011 16:44:43 +0000 by phpDocumentor 1.4.3