'left','mapping',$nid)) * or a more complex: * $relation_signature=RFS('node_node', * array('arg'=>array('name'=>'nn.left','mapping','nu.nid'), * RFS('node_user',array('name'=>'nu.uid','mapping'=>$uid)); * */ function RFS($relation_name ) { $f=$relation_name.'_relation_signature'; $sig=$f(); $nargs=func_num_args(); $args=func_get_args(); //skip the first argument - it is the relation name for($i=1;$i<$nargs;$i++){ $arg=$args[$i]; $arguments=explode(',',$arg['arg']['name']); $mapping=explode(',',$arg['arg']['mapping']); foreach($arguments as $key=>$param) { //assign the mappings for the parameters from the arguments, the alias collisons are handled later $temp_param[$param]=$mapping[$key]; } if(is_array($arg)&&!empty($arg['aliases'])) { //this is actually a relation signature //check for alias clashes foreach($arg['aliases'] as $alias=>$table){ $new_alias=$alias; if(array_key_exists($alias,$sig['aliases'])) { //alias collision, change the bastard //change fields while(array_key_exists($new_alias.='_',$sig['aliases'])) {}; // create a unique alias if(!empty( $arg['fields'] )) { $arg['fields'][$new_alias]=$arg['fields'][$alias];//change the fields unset($arg['fields'][$alias]); //remove the redundant fields } if(!empty( $arg['field_functions'] )) { $arg['field_functions'][$new_alias]=$arg['field_functions'][$alias];//change the fields unset($arg['field_functions'][$alias]); //remove the redundant fields } if(!empty( $arg['conditions'] )) { foreach($arg['conditions'] as $key=>$condition ) { //modify the conditions $arg['conditions'][$key]=preg_replace($alias.'\.',$new_alias.'\.',$condition); } } //not sure if this is required, needs more thought if(!empty($arg['groups'])){ foreach($arg['groups'] as $key=>$group ) { //modify the conditions $arg['groups'][$key]=preg_replace($alias.'\.',$new_alias.'\.',$group); } } //THERE ARE PROBLEMS WITH JOINS, CAN BE DONE IN A SIMILAR FASHION TO THE REST, ie aliases + conditions foreach($temp_param as $key=>$param ) { $temp_param[$key]=preg_replace($alias.'\.',$new_alias.'\.',$param); } } $aliases[$new_alias]=$table; //prep the new aliases table } $arg['aliases']=$aliases;//update the aliases to reflect the possible alias updates //aliases } if(!empty($sig['param'])) { $sig['param']=array_merge($sig['param'],$temp_param); } $sig=array_merge_recursive($sig,$arg); } return $sig; } /**generates an SQL SELECT statement from a relation signature * * no JOIN or GROUP statements yet */ function RSQL($sig) { $query='SELECT '; if(!empty($sig['field_functions'])) { foreach($sig['field_functions'] as $alias=>$fs) { foreach($fs as $func) { unset($sig['fields'][$alias][$func['field']]); $functions[]=$func['func'].'('.$alias.'.'.$func['field'].')' . (empty($func['alias'])?' ':' AS '.$func['alias'].' '); } } } foreach($sig['fields'] as $alias=>$fs) { foreach($fs as $field) { $fields[]=$alias.'.'.$field; } } $query .= implode(' , ', $fields); if(!empty($functions)) { $query .= ', '.implode(' , ', $functions); } $query .= ' FROM '; foreach($sig['aliases'] as $alias=>$table) { $tables[]=$table .' AS '.$alias; } $query .= implode(' , ', $tables); if(!empty($sig['conditions'])){ $query .= ' WHERE '. implode(' ',$sig['conditions']); } if(!empty($sig['param'])){ $query .= (empty($sig['conditions'])?' WHERE ':' AND '). implode(' ',$sig['param']); } if(!empty($sig['order'])){ $query .= ' ORDER BY '.implode(', ',$sig['order']); } if(!empty($sig['groups'])){ $query .= ' GROUP BY '.implode(', ',$sig['groups']); } return $query; }; if(DEBUG_RELATIONS){ var_dump($test=RFS('node')); var_dump($test=RSQL(RFS('node', RFS('node_revisions')))); var_dump($test=RSQL(RFS('node', array_merge_recursive(RFS('node_revisions'), array('conditions'=>array('n.nid=r.nid','AND','n.nid=1'),'order'=>array('n.nid DESC','n.sticky ASC')))))); var_dump($test=RSQL($t=RFS('node', array_merge_recursive(RFS('node_revisions'), array('conditions'=>array('n.nid=r.nid','AND','n.nid=1'),'order'=>array('n.nid DESC','n.sticky ASC'),'field_functions'=>array('n'=>array(array('field'=>'nid','func'=>'count','alias'=>'metric')))))))); $sig['n'][]= 'nid'; $sig['n'][]= 'vid'; $sig['n'][]= 'type'; $sig['n'][]= 'title'; $sig['n'][]= 'uid'; var_dump(RSQL(relation_fields_filter($t,$sig))); //if the 'node author' relation has rid=1000 $node_authors=RFS('user',RFS('node',RFS('node_user',array('conditions'=>array('nu.nid=n.nid','AND','u.uid=nu.uid','AND','nu.rid=1000'))))); $authors_sig['u'][]= 'uid'; $authors_sig['u'][]= 'name'; $authors_sig['u'][]= 'mail'; var_dump(RSQL(relation_fields_filter($node_authors,$authors_sig))); var_dump($test=RSQL(RFS('node', RFS('node_revisions'),array('param'=>array('n.nid=%d','n.uid=%d'))))); $node_authors=RFS('user',RFS('node', array('param'=>array('nu.nid=%d',' AND ','nu.uid=%d')),RFS('node_user',array('conditions'=>array('nu.nid=n.nid','AND','u.uid=nu.uid','AND','nu.rid=1000'))))); var_dump(RSQL(relation_fields_filter($node_authors,$authors_sig))); } ?>