DB_DataObject
[ class tree: DB_DataObject ] [ index: DB_DataObject ] [ all elements ]

Source for file Links.php

Documentation is available at Links.php

  1. <?php
  2. /**
  3.  * Link tool for DB_DataObject
  4.  *
  5.  * PHP versions 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.01 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   Database
  14.  * @package    DB_DataObject
  15.  * @author     Alan Knowles <alan@akbkhome.com>
  16.  * @copyright  1997-2006 The PHP Group
  17.  * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
  18.  * @version    : FIXME
  19.  * @link       http://pear.php.net/package/DB_DataObject
  20.  */
  21.  
  22.  
  23. /**
  24.  *
  25.  * Example of how this could be used..
  26.  * 
  27.  * The lind method are now in here.
  28.  *
  29.  * Currenly only supports existing methods, and new 'link()' method
  30.  *
  31.  */
  32.   
  33.   
  34. /**
  35.  * Links class
  36.  *
  37.  * @package DB_DataObject
  38.  */
  39. {
  40.      /**
  41.      * @property {DB_DataObject}      do   DataObject to apply this to.
  42.      */
  43.     var $do = false;
  44.     
  45.     
  46.     /**
  47.      * @property {Array|String}load    What to load, 'all' or an array of properties. (default all)
  48.      */
  49.     var $load = 'all';
  50.     /**
  51.      * @property {String|Boolean}      scanf   use part of column name as resulting
  52.      *                                           property name. (default false)
  53.      */
  54.     var $scanf = false;
  55.     /**
  56.      * @property {String|Boolean}      printf  use column name as sprintf for resulting property name..
  57.      *                                      (default %s_link if apply is true, otherwise it is %s)
  58.      */
  59.     var $printf = false;
  60.     /**
  61.      * @property {Boolean}      cached  cache the result, so future queries will use cache rather
  62.      *                                   than running the expensive sql query.
  63.      */
  64.     var $cached = false;
  65.     /**
  66.      * @property {Boolean}      apply   apply the result to this object, (default true)
  67.      */
  68.     var $apply = true;
  69.    
  70.     
  71.     //------------------------- RETURN ------------------------------------
  72.     /**
  73.      * @property {Array}      links    key value associative array of links.
  74.      */
  75.     var $links;
  76.     
  77.     
  78.     /**
  79.      * Constructor
  80.      *   -- good ole style..
  81.      *  @param {DB_DataObject}           do  DataObject to apply to.
  82.      *  @param {Array}           cfg  Configuration (basically properties of this object)
  83.      */
  84.     
  85.     function DB_DataObject_Links($do,$cfg= array())
  86.     {
  87.         // check if do is set!!!?
  88.         $this->do = $do;
  89.         
  90.         foreach($cfg as $k=>$v{
  91.             $this->$k $v;
  92.         }
  93.        
  94.         
  95.     }
  96.      
  97.     /**
  98.      * return name from related object
  99.      *
  100.      * The relies on  a <dbname>.links.ini file, unless you specify the arguments.
  101.      * 
  102.      * you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName')
  103.      *
  104.      *
  105.      * @param string $field|array    either row or row.xxxxx or links spec.
  106.      * @param string|DB_DataObject$table  (optional) name of table to look up value in
  107.      * @param string $link   (optional)  name of column in other table to match
  108.      * @author Tim White <tim@cyface.com>
  109.      * @access public
  110.      * @return mixed object on success false on failure or '0' when not linked
  111.      */
  112.     function getLink($field$table= false$link='')
  113.     {
  114.         
  115.         static $cache = array();
  116.         
  117.         // GUESS THE LINKED TABLE.. (if found - recursevly call self)
  118.         
  119.         if ($table == false{
  120.             
  121.             
  122.             $info $this->linkInfo($field);
  123.             
  124.             if ($info{
  125.                 return $this->getLink($field$info[0],  $link === false ? $info[1$link );
  126.             }
  127.             
  128.             // no links defined.. - use borked BC method...
  129.                   // use the old _ method - this shouldnt happen if called via getLinks()
  130.             if (!($p = strpos($field'_'))) {
  131.                 return false;
  132.             }
  133.             $table substr($field0$p);
  134.             return $this->getLink($field$table);
  135.             
  136.             
  137.  
  138.         }
  139.          
  140.         $tn is_string($table$table $table->tableName();
  141.          
  142.             
  143.  
  144.         if (!isset($this->do->$field)) {
  145.             $this->do->raiseError("getLink: row not set $field"DB_DATAOBJECT_ERROR_NODATA);
  146.             return false;
  147.         }
  148.         
  149.         // check to see if we know anything about this table..
  150.         
  151.       
  152.         if (empty($this->do->$field|| $this->do->$field < 0{
  153.             return 0; // no record. 
  154.         }
  155.         
  156.         if ($this->cached && isset($cache[$tn.':'$link .':'$this->do->$field])) {
  157.             return $cache[$tn.':'$link .':'$this->do->$field];    
  158.         }
  159.         
  160.         $obj is_string($table$this->do->factory($tn$table;;
  161.         
  162.         if (!is_a($obj,'DB_DataObject')) {
  163.             $this->do->raiseError(
  164.                 "getLink:Could not find class for row $field, table $tn"
  165.                 DB_DATAOBJECT_ERROR_INVALIDCONFIG);
  166.             return false;
  167.         }
  168.         // -1 or 0 -- no referenced record..
  169.        
  170.         $ret = false;
  171.         if ($link{
  172.             
  173.             if ($obj->get($link$this->do->$field)) {
  174.                 $ret $obj;
  175.             }
  176.             
  177.             
  178.         // this really only happens when no link config is set (old BC stuff)    
  179.         else if ($obj->get($this->do->$field)) {
  180.             $ret$obj;
  181.              
  182.         }
  183.         if ($this->cached{
  184.             $cache[$tn.':'$link .':'$this->do->$field$ret;
  185.         }
  186.         return $ret;
  187.         
  188.     }
  189.     /**
  190.      * get link information for a field or field specification
  191.      *
  192.      * alll link (and join methods accept the 'link' info ) in various ways
  193.      * string : 'field' = which field to get (uses ???.links.ini to work out what)
  194.      * array(2) : 'field', 'table:remote_col' << just like the links.ini def.
  195.      * array(3) : 'field', $dataobject, 'remote_col'  (handy for joinAdd to do nested joins.)
  196.      *
  197.      * @param string|array$field or link spec to use.
  198.      * @return (false|array)array of dataobject and linked field or false.
  199.      *
  200.      *
  201.      */
  202.     
  203.     function linkInfo($field)
  204.     {
  205.          
  206.         if (is_array($field)) {
  207.             if (count($field== 3{
  208.                 // array with 3 args:
  209.                 // local_col , dataobject, remote_col
  210.                 return array(
  211.                     $field[1],
  212.                     $field[2],
  213.                     $field[0]
  214.                 );
  215.                 
  216.             
  217.             list($table,$linkexplode(':'$field[1]);
  218.             
  219.             return array(
  220.                 $this->do->factory($table),
  221.                 $link,
  222.                 $field[0]
  223.             );
  224.             
  225.         }
  226.         // work out the link.. (classic way)
  227.         
  228.         $links $this->do->links();
  229.         
  230.         if (empty($links|| !is_array($links)) {
  231.              
  232.             return false;
  233.         }
  234.             
  235.             
  236.         if (!isset($links[$field])) {
  237.             
  238.             return false;
  239.         }
  240.         list($table,$linkexplode(':'$links[$field]);
  241.     
  242.         
  243.         //??? needed???
  244.         if ($p strpos($field,".")) {
  245.             $field substr($field,0,$p);
  246.         }
  247.         
  248.         return array(
  249.             $this->do->factory($table),
  250.             $link,
  251.             $field
  252.         );
  253.         
  254.         
  255.          
  256.         
  257.     }
  258.     
  259.     
  260.         
  261.     /**
  262.      *  a generic geter/setter provider..
  263.      *
  264.      *  provides a generic getter setter for the referenced object
  265.      *  eg.
  266.      *  $link->link('company_id') returns getLink for the object
  267.      *  if nothing is linked (it will return an empty dataObject)
  268.      *  $link->link('company_id', array(1)) - just sets the
  269.      *
  270.      *  also array as the field speck supports
  271.      *      $link->link(array('company_id', 'company:id'))
  272.      *  
  273.      *
  274.      *  @param  string|array  $field   the field to fetch or link spec.
  275.      *  @params array          $args    the arguments sent to the getter setter
  276.      *  @return mixed true of false on set, the object on getter.
  277.      *
  278.      */
  279.     function link($field$args = array())
  280.     {
  281.         $info $this->linkInfo($field);
  282.          
  283.         if (!$info{
  284.             $this->do->raiseError(
  285.                 "getLink:Could not find link for row $field"
  286.                 DB_DATAOBJECT_ERROR_INVALIDCONFIG);
  287.             return false;
  288.         }
  289.         $field $info[2];
  290.         
  291.         
  292.         if (empty($args)) // either an empty array or really empty....
  293.             
  294.             if (!isset($this->do->$field)) {
  295.                 return $info[0]// empty dataobject.
  296.             }
  297.             
  298.             $ret $this->getLink($field);
  299.             // nothing linked -- return new object..
  300.             return ($ret === 0$info[0$ret;
  301.             
  302.         }
  303.         $assign is_array($args$args[0$args;
  304.          
  305.         // otherwise it's a set call..
  306.         if (!is_a($assign 'DB_DataObject')) {
  307.             
  308.             if (is_numeric($assign&& is_integer($assign * 1)) {
  309.                 if ($assign  > 0{
  310.                     
  311.                     if (!$info{
  312.                         return false;
  313.                     }
  314.                     // check that record exists..
  315.                     if (!$info[0]->get($info[1]$assign )) {
  316.                         return false;
  317.                     }
  318.                     
  319.                 }
  320.                 
  321.                 $this->do->$field $assign ;
  322.                 return true;
  323.             }
  324.             
  325.             return false;
  326.         }
  327.         
  328.         // otherwise we are assigning it ...
  329.         
  330.         $this->do->$field $assign->{$info[1]};
  331.         return true;
  332.         
  333.         
  334.     }
  335.     /**
  336.      * load related objects
  337.      *
  338.      * Generally not recommended to use this.
  339.      * The generator should support creating getter_setter methods which are better suited.
  340.      *
  341.      * Relies on  <dbname>.links.ini
  342.      *
  343.      * Sets properties on the calling dataobject  you can change what
  344.      * object vars the links are stored in by  changeing the format parameter
  345.      *
  346.      *
  347.      * @param  string format (default _%s) where %s is the table name.
  348.      * @author Tim White <tim@cyface.com>
  349.      * @access public
  350.      * @return boolean , true on success
  351.      */
  352.     
  353.     function applyLinks($format '_%s')
  354.     {
  355.          
  356.         // get table will load the options.
  357.         if ($this->do->_link_loaded{
  358.             return true;
  359.         }
  360.         
  361.         $this->do->_link_loaded = false;
  362.         $cols  $this->do->table();
  363.         $links $this->do->links();
  364.          
  365.         $loaded = array();
  366.         
  367.         if ($links{   
  368.             foreach($links as $key => $match{
  369.                 list($table,$linkexplode(':'$match);
  370.                 $k sprintf($formatstr_replace('.''_'$key));
  371.                 // makes sure that '.' is the end of the key;
  372.                 if ($p strpos($key,'.')) {
  373.                       $key substr($key0$p);
  374.                 }
  375.                 
  376.                 $this->do->$k $this->getLink($key$table$link);
  377.                 
  378.                 if (is_object($this->do->$k)) {
  379.                     $loaded[$k
  380.                 }
  381.             }
  382.             $this->do->_link_loaded = $loaded;
  383.             return true;
  384.         }
  385.         // this is the autonaming stuff..
  386.         // it sends the column name down to getLink and lets that sort it out..
  387.         // if there is a links file then it is not used!
  388.         // IT IS DEPRECATED!!!! - DO NOT USE 
  389.         if (!is_null($links)) {    
  390.             return false;
  391.         }
  392.         
  393.         
  394.         foreach (array_keys($colsas $key{
  395.             if (!($p strpos($key'_'))) {
  396.                 continue;
  397.             }
  398.             // does the table exist.
  399.             $k =sprintf($format$key);
  400.             $this->do->$k $this->getLink($key);
  401.             if (is_object($this->do->$k)) {
  402.                 $loaded[$k
  403.             }
  404.         }
  405.         $this->do->_link_loaded = $loaded;
  406.         return true;
  407.     }
  408.     
  409.     /**
  410.      * getLinkArray
  411.      * Fetch an array of related objects. This should be used in conjunction with a
  412.      * <dbname>.links.ini file configuration (see the introduction on linking for details on this).
  413.      *
  414.      * You may also use this with all parameters to specify, the column and related table.
  415.      * 
  416.      * @access public
  417.      * @param string $field- either column or column.xxxxx
  418.      * @param string $table (optional) name of table to look up value in
  419.      * @param string $fkey (optional) fetchall key see DB_DataObject::fetchAll()
  420.      * @param string $fval (optional)fetchall val DB_DataObject::fetchAll()
  421.      * @param string $fval (optional) fetchall method DB_DataObject::fetchAll()
  422.      * @return array - array of results (empty array on failure)
  423.      * 
  424.      *  Example - Getting the related objects
  425.      * 
  426.      *  $person = new DataObjects_Person;
  427.      *  $person->get(12);
  428.      *  $children = $person->getLinkArray('children');
  429.      * 
  430.      *  echo 'There are ', count($children), ' descendant(s):<br />';
  431.      *  foreach ($children as $child) {
  432.      *      echo $child->name, '<br />';
  433.      *  }
  434.      * 
  435.      */
  436.     function getLinkArray($field$table = null$fkey = false$fval = false$fmethod = false)
  437.     {
  438.         
  439.         $ret = array();
  440.         if (!$table)  {
  441.             
  442.             
  443.             $links $this->do->links();
  444.             
  445.             if (is_array($links)) {
  446.                 if (!isset($links[$field])) {
  447.                     // failed..
  448.                     return $ret;
  449.                 }
  450.                 list($table,$linkexplode(':',$links[$field]);
  451.                 return $this->getLinkArray($field,$table);
  452.             
  453.             if (!($p strpos($field,'_'))) {
  454.                 return $ret;
  455.             }
  456.             return $this->getLinkArray($field,substr($field,0,$p));
  457.  
  458.  
  459.         }
  460.         
  461.         $c  $this->do->factory($table);
  462.         
  463.         if (!is_object($c|| !is_a($c,'DB_DataObject')) {
  464.             $this->do->raiseError(
  465.                 "getLinkArray:Could not find class for row $field, table $table"
  466.                 DB_DATAOBJECT_ERROR_INVALIDCONFIG
  467.             );
  468.             return $ret;
  469.         }
  470.  
  471.         // if the user defined method list exists - use it...
  472.         if (method_exists($c'listFind')) {
  473.             $c->listFind($this->id);
  474.             while ($c->fetch()) {
  475.                 $ret[= clone($c);
  476.             }
  477.             return $ret;
  478.         
  479.         return $c->fetchAll($fkey$fval$fmethod);
  480.         
  481.         
  482.     }
  483.  
  484. }

Documentation generated on Fri, 05 Apr 2013 09:00:16 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.