Source for file jDaoMethod.class.php

Documentation is available at jDaoMethod.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  dao
  5. @author      GĂ©rald Croes, Laurent Jouanneau
  6. @contributor Laurent Jouanneau
  7. @contributor Olivier Demah
  8. @copyright   2001-2005 CopixTeam, 2005-2009 Laurent Jouanneau, 2010 Olivier Demah
  9. *  This class was get originally from the Copix project (CopixDAODefinitionV1, Copix 2.3dev20050901, http://www.copix.org)
  10. *  Few lines of code are still copyrighted 2001-2005 CopixTeam (LGPL licence).
  11. *  Initial authors of this Copix class are Gerald Croes and Laurent Jouanneau,
  12. *  and this class was adapted/improved for Jelix by Laurent Jouanneau
  13. *
  14. @link        http://www.jelix.org
  15. @licence  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  16. */
  17.  
  18. /**
  19.  * containers for properties of dao method
  20.  * @package  jelix
  21.  * @subpackage dao
  22.  */
  23. class jDaoMethod {
  24.     public $name;
  25.     public $type;
  26.     public $distinct=false;
  27.     public $eventBeforeEnabled = false;
  28.     public $eventAfterEnabled = false;
  29.     private $_conditions null;
  30.     private $_parameters   array();
  31.     private $_parametersDefaultValues array();
  32.     private $_limit null;
  33.     private $_values array();
  34.     private $_parser null;
  35.     private $_procstock=null;
  36.     private $_body=null;
  37.     private $_groupBy=null;
  38.  
  39.     /**
  40.      * @param simpleXmlElement $method  the xml element describing the method to generate
  41.      * @param jDaoParser  $parser the parser on a dao file
  42.     */
  43.     function __construct ($method$parser){
  44.         $this->_parser $parser;
  45.  
  46.         $params $parser->getAttr($methodarray('name''type''call','distinct',
  47.                                                   'eventbefore''eventafter''groupby'));
  48.  
  49.         if ($params['name']===null){
  50.             throw new jDaoXmlException ($this->_parser->selector'missing.attr'array('name''method'));
  51.         }
  52.  
  53.         $this->name = $params['name'];
  54.         $this->type = $params['type'strtolower($params['type']'select';
  55.  
  56.         if (isset ($method->parameter)){
  57.             foreach ($method->parameter as $param){
  58.                 $attr $param->attributes();
  59.                 if (strpos($attr['name'],'$'!== false{
  60.                     throw new jDaoXmlException($this->_parser->selector,'method.parameter.invalidname',array($method->name,$attr['name']));
  61.                 }
  62.                 if (!isset ($attr['name'])){
  63.                     throw new jDaoXmlException ($this->_parser->selector'method.parameter.unknowname'array($this->name));
  64.                 }
  65.                 $this->_parameters[]=(string)$attr['name'];
  66.                 if (isset ($attr['default'])){
  67.                     $this->_parametersDefaultValues[(string)$attr['name']]=(string)$attr['default'];
  68.                 }
  69.             }
  70.         }
  71.  
  72.         if($this->type == 'sql'){
  73.             if($params['call'=== null){
  74.                 throw new jDaoXmlException ($this->_parser->selector'method.procstock.name.missing');
  75.             }
  76.             $this->_procstock=$params['call'];
  77.             return;
  78.         }
  79.  
  80.         if($this->type == 'php'){
  81.             if (isset ($method->body)){
  82.                 $this->_body = (string)$method->body;
  83.             }else{
  84.                 throw new jDaoXmlException ($this->_parser->selector'method.body.missing');
  85.             }
  86.             return;
  87.         }
  88.  
  89.         $this->_conditions new jDaoConditions();
  90.         if (isset ($method->conditions)){
  91.             $this->_parseConditions($method->conditions[0],false);
  92.         }
  93.  
  94.         if ($this->type == 'update' || $this->type == 'delete'{
  95.             if ($params['eventbefore'== 'true')
  96.                 $this->eventBeforeEnabled = true;
  97.             if ($params['eventafter'== 'true')
  98.                 $this->eventAfterEnabled = true;
  99.         }
  100.  
  101.         if($this->type == 'update'){
  102.             if($this->_parser->hasOnlyPrimaryKeys)
  103.                 throw new jDaoXmlException ($this->_parser->selector'method.update.forbidden',array($this->name));
  104.  
  105.             if(isset($method->values&& isset($method->values[0]->value)){
  106.                 foreach ($method->values[0]->value as $val){
  107.                     $this->_addValue($val);
  108.                 }
  109.             }else{
  110.                 throw new jDaoXmlException ($this->_parser->selector'method.values.undefine',array($this->name));
  111.             }
  112.             return;
  113.         }
  114.  
  115.         if(strlen($params['distinct'])){
  116.             if($this->type == 'select'){
  117.                 $this->distinct=$this->_parser->getBool($params['distinct']);
  118.             }elseif($this->type == 'count'){
  119.                 $props $this->_parser->getProperties();
  120.                 if (!isset ($props[$params['distinct']])){
  121.                     throw new jDaoXmlException ($this->_parser->selector'method.property.unknown'array($this->name$params['distinct']));
  122.                 }
  123.                 $this->distinct=$params['distinct'];
  124.             }else{
  125.                 throw new jDaoXmlException ($this->_parser->selector'forbidden.attr.context'array('distinct''<method name="'.$this->name.'"'));
  126.             }
  127.         }
  128.  
  129.         if($this->type == 'count')
  130.             return;
  131.  
  132.         if (isset ($method->order&& isset($method->order[0]->orderitem)){
  133.             foreach($method->order[0]->orderitem as $item){
  134.                 $this->_addOrder ($item);
  135.             }
  136.         }
  137.  
  138.         if(strlen($params['groupby'])){
  139.             if($this->type == 'select' || $this->type == 'selectfirst'){
  140.                 $this->_groupBy preg_split("/[\s,]+/"$params['groupby']);
  141.                 $props $this->_parser->getProperties();
  142.                 foreach($this->_groupBy as $p){
  143.                     if (!isset ($props[$p])) {
  144.                         throw new jDaoXmlException ($this->_parser->selector'method.property.unknown'array($this->name$p));
  145.                     }
  146.                 }
  147.             }else{
  148.                 throw new jDaoXmlException ($this->_parser->selector'forbidden.attr.context'array('groupby''<method name="'.$this->name.'"'));
  149.             }
  150.         }
  151.  
  152.         if (isset($method->limit)){
  153.             if(isset($method->limit[1])){
  154.                 throw new jDaoXmlException ($this->_parser->selector'tag.duplicate'array('limit'$this->name));
  155.             }
  156.             if($this->type == 'select'){
  157.                 $this->_addLimit($method->limit[0]);
  158.             }else{
  159.                 throw new jDaoXmlException ($this->_parser->selector'method.limit.forbidden'$this->name);
  160.             }
  161.         }
  162.     }
  163.  
  164.     public function getConditions ()return $this->_conditions;}
  165.     public function getParameters ()return $this->_parameters;}
  166.     public function getParametersDefaultValues ()return $this->_parametersDefaultValues;}
  167.     public function getLimit ()return $this->_limit;}
  168.     public function getValues ()return $this->_values;}
  169.     public function getProcStock ()return $this->_procstock;}
  170.     public function getBody ()return $this->_body;}
  171.     public function getGroupBy(return $this->_groupBy;}
  172.  
  173.     private function _parseConditions($conditions$subcond=true){
  174.         if (isset ($conditions['logic'])){
  175.             $kind strtoupper((string)$conditions['logic']);
  176.         }else{
  177.             $kind 'AND';
  178.         }
  179.  
  180.         if ($subcond){
  181.             $this->_conditions->startGroup ($kind);
  182.         }else{
  183.             $this->_conditions->condition->glueOp =$kind;
  184.         }
  185.  
  186.         foreach($conditions->children(as $op=>$cond){
  187.             if($op !='conditions')
  188.                 $this->_addCondition ($op,$cond);
  189.             else
  190.                 $this->_parseConditions ($cond);
  191.         }
  192.  
  193.         if ($subcond{
  194.             $this->_conditions->endGroup();
  195.         }
  196.  
  197.     }
  198.  
  199.     private $_op array('eq'=>'=''neq'=>'<>''lt'=>'<''gt'=>'>''lteq'=>'<=''gteq'=>'>=',
  200.         'like'=>'LIKE''notlike'=>'NOT LIKE''isnull'=>'IS NULL''isnotnull'=>'IS NOT NULL','in'=>'IN''notin'=>'NOT IN',
  201.         'binary_op'=>'dummy');
  202.       // 'between'=>'BETWEEN',  'notbetween'=>'NOT BETWEEN',
  203.  
  204.     private $_attrcond array('property''expr''operator''driver')//, 'min', 'max', 'exprmin', 'exprmax'
  205.  
  206.     private function _addCondition($op$cond){
  207.  
  208.         $attr $this->_parser->getAttr($cond$this->_attrcond);
  209.  
  210.         $field_id ($attr['property']!==null$attr['property']:'');
  211.  
  212.         if(!isset($this->_op[$op])){
  213.             throw new jDaoXmlException ($this->_parser->selector'method.condition.unknown'array($this->name$op));
  214.         }
  215.  
  216.         $operator $this->_op[$op];
  217.  
  218.         $props $this->_parser->getProperties();
  219.  
  220.         if (!isset ($props[$field_id])){
  221.             throw new jDaoXmlException ($this->_parser->selector'method.property.unknown'array($this->name$field_id));
  222.         }
  223.  
  224.         if($this->type=='update'){
  225.             if($props[$field_id]->table != $this->_parser->getPrimaryTable()){
  226.                 throw new jDaoXmlException ($this->_parser->selector'method.property.forbidden'array($this->name$field_id));
  227.             }
  228.         }
  229.  
  230.         if(isset($cond['value']))
  231.             $value=(string)$cond['value'];
  232.         else
  233.             $value null;
  234.  
  235.         if($value!==null && $attr['expr']!==null){
  236.             throw new jDaoXmlException ($this->_parser->selector'method.condition.valueexpr.together'array($this->name$op));
  237.         }else if($value!==null){
  238.             if($op == 'isnull' || $op =='isnotnull'){
  239.                 throw new jDaoXmlException ($this->_parser->selector'method.condition.valueexpr.notallowed'array($this->name$op,$field_id));
  240.             }
  241.             if($op == 'binary_op'{
  242.                 if (!isset($attr['operator']|| empty($attr['operator'])) {
  243.                     throw new jDaoXmlException ($this->_parser->selector'method.condition.operator.missing'array($this->name$op,$field_id));
  244.                 }
  245.                 if (isset($attr['driver']&& !empty($attr['driver'])) {
  246.                     if ($this->_parser->selector->driver != $attr['driver']{
  247.                         throw new jDaoXmlException ($this->_parser->selector'method.condition.driver.notallowed'array($this->name$op,$field_id));
  248.                     }
  249.                 }
  250.                 $operator $attr['operator'];
  251.             }
  252.             $this->_conditions->addCondition ($field_id$operator$value);
  253.         }else if($attr['expr']!==null){
  254.             if($op == 'isnull' || $op =='isnotnull'){
  255.                 throw new jDaoXmlException ($this->_parser->selector'method.condition.valueexpr.notallowed'array($this->name$op$field_id));
  256.             }
  257.             if(($op == 'in' || $op =='notin')&& !preg_match('/^\$[a-zA-Z0-9_]+$/'$attr['expr'])){
  258.                 throw new jDaoXmlException ($this->_parser->selector'method.condition.innotin.bad.expr'array($this->name$op$field_id));
  259.             }
  260.             if($op == 'binary_op'{
  261.                 if (!isset($attr['operator']|| empty($attr['operator'])) {
  262.                     throw new jDaoXmlException ($this->_parser->selector'method.condition.operator.missing'array($this->name$op,$field_id));
  263.                 }
  264.                 if (isset($attr['driver']&& !empty($attr['driver'])) {
  265.                     if ($this->_parser->selector->driver != $attr['driver']{
  266.                         throw new jDaoXmlException ($this->_parser->selector'method.condition.driver.notallowed'array($this->name$op,$field_id));
  267.                     }
  268.                 }
  269.                 $operator $attr['operator'];
  270.             }
  271.             $this->_conditions->addCondition ($field_id$operator$attr['expr']true);
  272.         }else{
  273.             if($op != 'isnull' && $op !='isnotnull'){
  274.                 throw new jDaoXmlException ($this->_parser->selector'method.condition.valueexpr.missing'array($this->name$op$field_id));
  275.             }
  276.             $this->_conditions->addCondition ($field_id$operator''false);
  277.         }
  278.     }
  279.  
  280.     private function _addOrder($order){
  281.         $attr $this->_parser->getAttr($orderarray('property','way'));
  282.  
  283.         $way  ($attr['way'!== null $attr['way']:'ASC');
  284.  
  285.         if(substr ($way,0,1== '$'){
  286.             if(!in_array (substr ($way,1),$this->_parameters)){
  287.                 throw new jDaoXmlException ($this->_parser->selector'method.orderitem.parameter.unknown'array($this->name$way));
  288.             }
  289.         }
  290.  
  291.         if ($attr['property'!= ''){
  292.             $prop =$this->_parser->getProperties();
  293.             if(isset($prop[$attr['property']])){
  294.                 $this->_conditions->addItemOrder($attr['property']$way);
  295.             }elseif(substr ($attr['property'],0,1== '$'){
  296.                 if(!in_array (substr ($attr['property'],1),$this->_parameters)){
  297.                     throw new jDaoXmlException ($this->_parser->selector'method.orderitem.parameter.unknown'array($this->name$way));
  298.                 }
  299.                 $this->_conditions->addItemOrder($attr['property']$way);
  300.             }else{
  301.                 throw new jDaoXmlException ($this->_parser->selector'method.orderitem.bad'array($attr['property']$this->name));
  302.             }
  303.         }else{
  304.             throw new jDaoXmlException ($this->_parser->selector'method.orderitem.property.missing'array($this->name));
  305.         }
  306.     }
  307.  
  308.     private function _addValue($attr){
  309.         if(isset($attr['value']))
  310.             $value=(string)$attr['value'];
  311.         else
  312.             $value null;
  313.  
  314.         $attr $this->_parser->getAttr($attrarray('property','expr'));
  315.  
  316.         $prop $attr['property'];
  317.         $props =$this->_parser->getProperties();
  318.  
  319.         if ($prop === null){
  320.             throw new jDaoXmlException ($this->_parser->selector'method.values.property.unknown'array($this->name$prop));
  321.         }
  322.  
  323.         if(!isset($props[$prop])){
  324.             throw new jDaoXmlException ($this->_parser->selector'method.values.property.unknown'array($this->name$prop));
  325.         }
  326.  
  327.         if($props[$prop]->table != $this->_parser->getPrimaryTable()){
  328.             throw new jDaoXmlException ($this->_parser->selector'method.values.property.bad'array($this->name,$prop ));
  329.         }
  330.  
  331.         if($props[$prop]->isPK){
  332.             throw new jDaoXmlException ($this->_parser->selector'method.values.property.pkforbidden'array($this->name,$prop ));
  333.         }
  334.  
  335.         if($value!==null && $attr['expr']!==null){
  336.             throw new jDaoXmlException ($this->_parser->selector'method.values.valueexpr'array($this->name$prop));
  337.         }else if($value!==null){
  338.             $this->_values [$prop]array$valuefalse);
  339.         }else if($attr['expr']!==null){
  340.             $this->_values [$prop]array$attr['expr']true);
  341.         }else{
  342.             $this->_values [$prop]array''false);
  343.         }
  344.     }
  345.  
  346.     private function _addLimit($limit){
  347.         $attr $this->_parser->getAttr($limitarray('offset','count'));
  348.  
  349.         extract($attr);
  350.  
  351.         if$offset === null){
  352.             throw new jDaoXmlException ($this->_parser->selector'missing.attr',array('offset','limit'));
  353.         }
  354.         if($count === null){
  355.             throw new jDaoXmlException ($this->_parser->selector'missing.attr',array('count','limit'));
  356.         }
  357.  
  358.         if(substr ($offset,0,1== '$'){
  359.             if(in_array (substr ($offset,1),$this->_parameters)){
  360.                 $offsetparam=true;
  361.             }else{
  362.                 throw new jDaoXmlException ($this->_parser->selector'method.limit.parameter.unknown'array($this->name$offset));
  363.             }
  364.         }else{
  365.             if(is_numeric ($offset)){
  366.                 $offsetparam=false;
  367.                 $offset intval ($offset);
  368.             }else{
  369.                 throw new jDaoXmlException ($this->_parser->selector'method.limit.badvalue'array($this->name$offset));
  370.             }
  371.         }
  372.  
  373.         if(substr ($count,0,1== '$'){
  374.             if(in_array (substr ($count,1),$this->_parameters)){
  375.                 $countparam=true;
  376.             }else{
  377.                 throw new jDaoXmlException ($this->_parser->selector'method.limit.parameter.unknown'array($this->name$count));
  378.             }
  379.         }else{
  380.             if(is_numeric($count)){
  381.                 $countparam=false;
  382.                 $count=intval($count);
  383.             }else{
  384.                 throw new jDaoXmlException ($this->_parser->selector'method.limit.badvalue'array($this->name$count));
  385.             }
  386.         }
  387.         $this->_limitcompact('offset''count''offsetparam','countparam');
  388.     }
  389. }

Documentation generated on Mon, 19 Sep 2011 14:12:18 +0200 by phpDocumentor 1.4.3