[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/pkg/vtiger/extensions/Webservices/ -> VTQL_parser.y (source)

   1  %name VTQL_Parser
   2  //%left EQ LT GT LTE GTE NE IN LIKE.
   3  
   4  sql ::= select_statement.
   5  select_statement ::= SELECT(SEL) selectcol_list FRM(F) table_list where_condition order_clause limit_clause end_stmt. { 
   6  if(SEL){
   7  $this->out['select'] = SEL;
   8  }
   9  if(F){
  10  $this->out['from'] = F ;
  11  }
  12  if(SEMI){
  13  $this->out['semi_colon'] = SEMI;
  14  }
  15  if($this->out['select']){
  16  $this->buildSelectStmt($this->out);
  17  }
  18  }
  19  selectcol_list ::= selectcolumn_exp COLUMNNAME(CNAME). { 
  20  $this->out['column_list'][] = CNAME;
  21  }
  22  selectcol_list ::= ASTERISK(A). {
  23  $this->out['column_list'][] = A;
  24  }
  25  selectcol_list ::= COUNT PARENOPEN ASTERISK PARENCLOSE. {
  26  $this->out['column_list'][] = 'count(*)';
  27  }
  28  selectcolumn_exp ::= selectcol_list COMMA. 
  29  selectcolumn_exp ::= . 
  30  table_list ::= TABLENAME(TNAME). {
  31  if(!in_array($this->out["column_list"], "*") && !in_array(array_map(strtolower, $this->out["column_list"]), "count(*)")){
  32  if(!in_array("id",$this->out["column_list"])){
  33      $this->out["column_list"][] = "id";
  34  }
  35  }
  36  $moduleName = TNAME;
  37  if(!$moduleName){
  38      $this->syntax_error = true;
  39      throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "There is an syntax error in query");
  40  }
  41  global $adb;
  42  $handler = vtws_getModuleHandlerFromName($moduleName,$this->user);
  43  $objectMeta = $handler->getMeta();
  44  $this->out['moduleName'] = $moduleName;
  45  $this->out['tableName'] = implode(',',$objectMeta->getEntityTableList());
  46  }
  47  where_condition ::= WHERE(Wh) condition.
  48  where_condition ::= . 
  49  condition ::= expr_set expr(E).
  50  expr_set ::= condition LOGICAL_AND(LAND). {
  51  $this->out['where_condition']['operators'][] = LAND;
  52  }
  53  expr_set ::= condition LOGICAL_OR(LOR). {
  54  $this->out['where_condition']['operators'][] = LOR;
  55  }
  56  expr_set ::= .
  57  expr ::= COLUMNNAME(ECNAME) logical_term valuelist.{
  58  $this->out['columnDone']=true;
  59  $this->out['where_condition']['column_names'][] = ECNAME;
  60  if(strcmp(ECNAME, 'id')===0){
  61  $prev = $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1];
  62  if(is_array($prev)){
  63  $new = array();
  64  foreach($prev as $ind=>$val){
  65  $val = trim($val,'\'"');
  66  $value = vtws_getIdComponents($val);
  67  $new[] = $value[1];
  68  }
  69  $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $new;
  70  }else{
  71  $prev = trim($prev,'\'"');
  72  $value = vtws_getIdComponents($prev);
  73  if(strcasecmp($this->out['where_condition']['column_operators'][sizeof($this->out['where_condition']['column_operators'])-1],'like')===0){
  74  $value[1] = "'".$value[1]."'";
  75  }
  76  $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $value[1];
  77  }
  78  }
  79  }
  80  valuelist ::= PARENOPEN valueref PARENCLOSE.
  81  valuelist ::= valueref.
  82  valueref ::= value_exp VALUE(VAL).{
  83  $length = sizeof($this->out['where_condition']['column_values']);
  84  $pos = $length - 1;
  85  if($pos < 0){
  86  $pos = 0;
  87  }
  88  if(strcasecmp($this->out['where_condition']['column_operators'][$pos],"in")===0 && 
  89      !empty($this->out['where_condition']['column_values'][$pos]) && !$this->out['columnDone']){
  90  if(!is_array($this->out['where_condition']['column_values'][$pos])){
  91  $prev = $this->out['where_condition']['column_values'][$pos];
  92  $this->out['where_condition']['column_values'][$pos] = array();
  93  $this->out['where_condition']['column_values'][$pos][] = $prev;
  94  }
  95  $this->out['where_condition']['column_values'][$pos][] = VAL;
  96  }else{
  97  $this->out['columnDone'] = false;
  98  $this->out['where_condition']['column_values'][] = VAL;
  99  }
 100  }
 101  value_exp ::= valueref COMMA.
 102  value_exp ::= .
 103  logical_term ::= EQ. {
 104  $this->out['where_condition']['column_operators'][] = '=';
 105  }
 106  logical_term ::= LT. {
 107  $this->out['where_condition']['column_operators'][] = '<';
 108  }
 109  logical_term ::= GT. {
 110  $this->out['where_condition']['column_operators'][] = '>';
 111  }
 112  logical_term ::= LTE. {
 113  $this->out['where_condition']['column_operators'][] = '<=';
 114  }
 115  logical_term ::= GTE. {
 116  $this->out['where_condition']['column_operators'][] = '>=';
 117  }
 118  logical_term ::= NE. {
 119  $this->out['where_condition']['column_operators'][] = '!=';
 120  }
 121  logical_term ::= IN. {
 122  $this->out['where_condition']['column_operators'][] = 'IN';
 123  }
 124  logical_term ::= LIKE. {
 125  $this->out['where_condition']['column_operators'][] = 'LIKE';
 126  }
 127  order_clause ::= ORDERBY column_group clause. 
 128  order_clause ::= . 
 129  column_group ::= column_list .
 130  column_list ::= column_exp COLUMNNAME(CN). {
 131  $this->out['orderby'][] = CN;
 132  }
 133  column_exp ::= column_list COMMA. 
 134  column_exp ::= .
 135  clause ::= ASC. {
 136  $this->out['sortOrder'] = 'ASC';
 137  }
 138  clause ::= DESC. {
 139  $this->out['sortOrder'] = 'DESC';
 140  }
 141  clause ::= .
 142  limit_clause ::= LIMIT limit_set. 
 143  limit_clause ::= . 
 144  limit_set ::= VALUE(LV). {
 145  $this->out['limit'][] = LV;
 146  }
 147  limit_set ::= VALUE(LV) COMMA VALUE(LV2). {
 148  $this->out['limit'][] = LV;
 149  $this->out['limit'][] = LV2;
 150  }
 151  end_stmt ::= SEMICOLON(SEMI). {
 152  global $adb;
 153  if(!$this->out['meta']){
 154  $module = $this->out['moduleName'];
 155  $handler = vtws_getModuleHandlerFromName($module,$this->user);
 156  $objectMeta = $handler->getMeta();
 157  $this->out['meta'] = $objectMeta;
 158  $meta = $this->out['meta'];
 159  $fieldcol = $meta->getFieldColumnMapping();
 160  $columns = array();
 161  if(in_array($this->out['column_list'],'*')){
 162  $columns = array_values($fieldcol);
 163  }else if( !in_array(array_map(strcmp, $this->out['column_list']),'count(*)')){
 164  foreach($this->out['column_list'] as $ind=>$field){
 165  $columns[] = $fieldcol[$field];
 166  }
 167  }
 168  if($this->out['where_condition']){
 169  foreach($this->out['where_condition']['column_names'] as $ind=>$field){
 170  $columns[] = $fieldcol[$field];
 171  }
 172  }
 173  $tables = $this->getTables($this->out, $columns);
 174  if(!in_array($objectMeta->getEntityBaseTable(), $tables)){
 175  $tables[] = $objectMeta->getEntityBaseTable();
 176  }
 177  $defaultTableList = $objectMeta->getEntityDefaultTableList();
 178  foreach($defaultTableList as $tableName){
 179  if(!in_array($tableName,$tables)){
 180  array_push($tables,$tableName);
 181  }
 182  }
 183  $firstTable = $objectMeta->getEntityBaseTable();
 184  $tabNameIndex = $objectMeta->getEntityTableIndexList();
 185  $firstIndex = $tabNameIndex[$firstTable];
 186  foreach($tables as $ind=>$table){
 187  if($firstTable!=$table){
 188      if(!isset($tabNameIndex[$table]) && $table == "vtiger_crmentity"){
 189          $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.crmid";
 190      }else{
 191          $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.{$tabNameIndex[$table]}";
 192      }
 193  }else{
 194      $this->out['tableName'] = $table;
 195  }
 196  }
 197  }
 198  }
 199  %include_class {
 200  /*
 201  add this rule to add parenthesis support.
 202  condition ::= PARENOPEN expr_set expr(E) PARENCLOSE.
 203  sample format(for contacts) for generated sql object 
 204  Array ( 
 205      [column_list] => c4,c3,c2,c1 
 206      [tableName] => vtiger_crmentity,vtiger_contactdetails,vtiger_contactaddress,vtiger_contactsubdetails,vtiger_contactscf,vtiger_customerdetails 
 207      [where_condition] => Array ( 
 208          [column_operators] => Array ( 
 209              [0] => = 
 210              [1] => = 
 211              [2] => = 
 212              ) 
 213          [column_names] => Array ( 
 214              [0] => c1 
 215              [1] => c2 
 216              [2] => c3 
 217              ) 
 218          [column_values] => Array ( 
 219              [0] => 'llet me' 
 220              [1] => 45 
 221              [2] => -1 
 222              ) 
 223          //TO BE DONE
 224          [grouping] => Array (
 225              [0] => Array (
 226                  [0] => 1
 227                  [1] => 2
 228                  )
 229              )
 230          [operators] => Array ( 
 231              [0] => and 
 232              [1] => or 
 233              )
 234          )
 235      [orderby] => Array ( 
 236          [0] => c4 
 237          [1] => c5 
 238          )
 239      [select] => SELECT 
 240      [from] => from 
 241      [semi_colon] => ; 
 242  )*/
 243      private $out;
 244      public $lex;
 245      private $success ;
 246      private $query ;
 247      private $error_msg;
 248      private $syntax_error;
 249      private $user;
 250  function __construct($user, $lex,$out){
 251      if(!is_array($out)){
 252          $out = array();
 253      }
 254      $this->out = &$out;
 255      $this->lex = $lex;
 256      $this->success = false;
 257      $this->error_msg ='';
 258      $this->query = '';
 259      $this->syntax_error = false;
 260      $this->user = $user;
 261  }
 262  
 263  function __toString(){
 264      return $this->value."";
 265  }
 266  function buildSelectStmt($sqlDump){
 267      $meta = $sqlDump['meta'];
 268      $fieldcol = $meta->getFieldColumnMapping();
 269      $columnTable = $meta->getColumnTableMapping();
 270      $this->query = 'SELECT ';
 271      if(in_array($sqlDump['column_list'],'*')){
 272          $i=0;
 273          foreach($fieldcol as $field=>$col){
 274              if($i===0){
 275                  $this->query = $this->query.$columnTable[$col].'.'.$col;
 276                  $i++;
 277              }else{
 278                  $this->query = $this->query.','.$columnTable[$col].'.'.$col;
 279              }
 280          }
 281      }else if(in_array($sqlDump['column_list'],'count(*)')){
 282          $this->query = $this->query." COUNT(*)";
 283      }else{
 284          $i=0;
 285          foreach($sqlDump['column_list'] as $ind=>$field){
 286              if(!$fieldcol[$field]){
 287                  throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access '.$field.' attribute denied.");
 288              }
 289              if($i===0){
 290                  $this->query = $this->query.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field];
 291                  $i++;
 292              }else{
 293                  $this->query = $this->query.','.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field];
 294              }
 295          }
 296      }
 297      $this->query = $this->query.' FROM '.$sqlDump['tableName'].$sqlDump['defaultJoinConditions'];
 298      $deletedQuery = $meta->getEntityDeletedQuery();
 299      $accessControlQuery = $meta->getEntityAccessControlQuery();
 300      $this->query = $this->query.' '.$accessControlQuery;
 301      if($sqlDump['where_condition']){
 302          if((sizeof($sqlDump['where_condition']['column_names']) == 
 303          sizeof($sqlDump['where_condition']['column_values'])) && 
 304          (sizeof($sqlDump['where_condition']['column_operators']) == sizeof($sqlDump['where_condition']['operators'])+1)){
 305              $this->query = $this->query.' WHERE (';
 306              $i=0;
 307              $referenceFields = $meta->getReferenceFieldDetails();
 308              $ownerFields = $meta->getOwnerFields();
 309              for(;$i<sizeof($sqlDump['where_condition']['column_values']);++$i){
 310                  if(!$fieldcol[$sqlDump['where_condition']['column_names'][$i]]){
 311                      throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access ".$sqlDump['where_condition']['column_names'][$i]." attribute denied.");
 312                  }
 313                  $whereField = $sqlDump['where_condition']['column_names'][$i];
 314                  $whereOperator = $sqlDump['where_condition']['column_operators'][$i];
 315                  $whereValue = $sqlDump['where_condition']['column_values'][$i];
 316                  if(in_array($whereField,array_keys($referenceFields))){
 317                      if(is_array($whereValue)){
 318                          foreach($whereValue as $index=>$value){
 319                              if(strpos($value,'x')===false){
 320                                  throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
 321                              }
 322                          }
 323                          $whereValue = array_map(array($this, 'getReferenceValue'),$whereValue);
 324                      }else if(strpos($whereValue,'x')!==false){
 325                          $whereValue = $this->getReferenceValue($whereValue);
 326                          if(strcasecmp($whereOperator,'like')===0){
 327                              $whereValue = "'".$whereValue."'";
 328                          }
 329                      }else{
 330                          throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
 331                      }
 332                  }else if(in_array($whereField,$ownerFields)){
 333                      if(is_array($whereValue)){
 334                          $groupId = array_map(array($this, 'getOwner'),$whereValue);
 335                      }else{
 336                          $groupId = $this->getOwner($whereValue);
 337                          if(strcasecmp($whereOperator,'like')===0){
 338                              $groupId = "'$groupId'";
 339                          }
 340                      }
 341                      $whereValue = $groupId;
 342                  }
 343                  if(is_array($whereValue)){
 344                      $whereValue = "(".implode(',',$whereValue).")";
 345                  }elseif(strcasecmp($whereOperator, 'in') === 0){
 346                      $whereValue = "($whereValue)";
 347                  }
 348                  $this->query = $this->query.$columnTable[$fieldcol[$whereField]].'.'.
 349                                      $fieldcol[$whereField]." ".$whereOperator." ".$whereValue;
 350                  if($i <sizeof($sqlDump['where_condition']['column_values'])-1){
 351                      $this->query = $this->query.' ';
 352                      $this->query = $this->query.$sqlDump['where_condition']['operators'][$i].' ';
 353                  }
 354              }
 355          }else{
 356              throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "columns data inappropriate");
 357          }
 358          $this->query = $this->query.")";
 359          $nextToken = ' AND ';
 360      }else{
 361          if(!empty($deletedQuery)){
 362              $nextToken = " WHERE ";
 363          }
 364      }
 365      if(strcasecmp('calendar',$this->out['moduleName'])===0){
 366          $this->query = $this->query." $nextToken activitytype='Task' AND ";
 367      }elseif(strcasecmp('events',$this->out['moduleName'])===0){
 368          $this->query = $this->query."$nextToken activitytype!='Emails' AND activitytype!='Task' AND ";
 369      }else if(strcasecmp('emails',$this->out['moduleName'])===0){
 370          $this->query = $this->query."$nextToken activitytype='Emails' AND ";
 371      }elseif(!empty($deletedQuery)){
 372          $this->query = $this->query.$nextToken;
 373      }
 374      
 375      $this->query = $this->query.' '.$deletedQuery;
 376      
 377      if($sqlDump['orderby']){
 378          $i=0;
 379          $this->query = $this->query.' ORDER BY ';
 380          foreach($sqlDump['orderby'] as $ind=>$field){
 381              if($i===0){
 382                  $this->query = $this->query.$columnTable[$fieldcol[$field]].".".$fieldcol[$field];
 383                  $i++;
 384              }else{
 385                  $this->query = $this->query.','.$columnTable[$fieldcol[$field]].".".$fieldcol[$field];
 386              }
 387          }
 388          if($sqlDump['sortOrder']) {
 389              $this->query .= ' '.$sqlDump['sortOrder'];
 390          }
 391      }
 392      if($sqlDump['limit']){
 393          $i=0;
 394          $offset =false;
 395          if(sizeof($sqlDump['limit'])>1){
 396              $offset = true;
 397          }
 398          $this->query = $this->query.' LIMIT ';
 399          foreach($sqlDump['limit'] as $ind=>$field){
 400              if(!$offset){
 401                  $field = ($field>100)? 100: $field;
 402              }
 403              if($i===0){
 404                  $this->query = $this->query.$field;
 405                  $i++;
 406                  $offset = false;
 407              }else{
 408                  $this->query = $this->query.','.$field;
 409              }
 410          }
 411      }else{
 412          $this->query = $this->query.' LIMIT 100';
 413      }
 414      $this->query = $this->query.';';
 415  }
 416  function getTables($sqlDump,$columns){
 417      $meta = $sqlDump['meta'];
 418      $coltable = $meta->getColumnTableMapping();
 419      $tables = array();
 420      foreach($columns as $ind=>$col){
 421          $tables[$coltable[$col]] = $coltable[$col];
 422      }
 423      $tables = array_keys($tables);
 424      return ($tables);
 425  }
 426  function getReferenceValue($whereValue){
 427      $whereValue = trim($whereValue,'\'"');
 428      $whereValue = vtws_getIdComponents($whereValue);
 429      $whereValue = $whereValue[1];
 430      return $whereValue;    
 431  }
 432  function getOwner($whereValue){
 433      $whereValue = trim($whereValue,'\'"');
 434      $whereValue = vtws_getIdComponents($whereValue);
 435      $whereValue = $whereValue[1];
 436      return $whereValue;
 437  }
 438  function isSuccess(){
 439      return $this->success;
 440  }
 441  function getErrorMsg(){
 442      return $this->error_msg;
 443  }
 444  function getQuery(){
 445      return $this->query;
 446  }
 447  function getObjectMetaData(){
 448      return $this->out['meta'];
 449  }
 450  }
 451  //%token_prefix    VTQL_
 452  %declare_class {class VTQL_Parser}
 453  %parse_accept {
 454          $this->success = true;
 455      }
 456  
 457  %parse_failure {
 458      if(!$this->syntax_error){
 459          throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parsing failed");
 460      }
 461  }
 462  
 463  %stack_overflow {
 464      throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parser stack overflow");
 465  }
 466  
 467  %syntax_error {
 468      $synMsg = "Syntax Error on line " . $this->lex->linenum . ": token '" .$this->lex->value."' ";
 469      $expect = array();
 470      foreach ($this->yy_get_expected_tokens($yymajor) as $token) {
 471          $expect[] = self::$yyTokenName[$token];
 472      }
 473      $synMsg =$synMsg.('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN
 474          . '), expected one of: ' . implode(',', $expect));
 475      
 476      throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, $synMsg);
 477  }
 478  


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1