Source for file jDaoMethod.class.php

Documentation is available at jDaoMethod.class.php

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

Documentation generated on Thu, 22 Mar 2012 22:14:54 +0100 by phpDocumentor 1.4.3