ok - up for comments is the kQuery class itself (partial, but at least working):
I'm developing the data model base class that supports the expected kQuery interface (as well as auto-saving) now.
Comments? Suggestions?
Code: Select all
class kQuery{
/*
METHODS SO FAR:
add() // adds objects that match somehow
attr('name') // returns the value for the "name" attribute in the first object
attr('name','val') // sets 'name' to 'val' for ALL matched objects
size() // returns the number of objects
eq() // shrinks the kQuery object to the numbered object
gt() // shrinks the kQuery object to the numbered object UP
lt() // shrinks the kQuery object UP TO the numbered object
get() // returns a new kQuery object with the object at that position
end() // will break out of the last get() scope change
each('func_name'); // executes a function with the object as an argument
each('echo $this->value'); // creates a lambda function and executes it
each(create_function('$this','echo "this is a lambda function"')); // executes the lambda function
USAGE:
$bob = $k('dataType #id')->attr('name','bob')->attr('age','old');
// this could have been chained above as well... but whatever.
$bob->add('dataType #id2')->attr('group','seniors')->get(1)->attr('name','frank')->end()->attr('favorite food','tapioca');
// caching in the $bob variable is just a handy tool for future reference, but not necessary.
$k('dataType #id','dataType #id2')->attr('group','old fogeys')->each(create_function('','if($this->age <= 60){$this->age = "65"}'))->each('$this->age++;');
(check out those lambda functions in action!)
*/
private $_ = array();
private $__, $__parent;
function __construct(){
// no arguments? return a blank kQuery object
if(func_num_args()==0) return $this;
$a = func_get_args();
call_user_func_array(array($this,'add'),$a);
return $this;
}
public function add(){
$args = func_get_args();
foreach($args as $a){
// object (wrapping the object)
if(is_object($a)){
$this->_[] = $a;
}
// string (query)
if(is_string($a)){
// parse the query
call_user_func(array($this,'query'),$a);
}
}
return $this;
}
public function attr(){
if( func_num_args()==1 ) {
$k = func_get_arg(0);
return $this->_[0]->$k;
}else if( func_num_args()==2 ){
$k = func_get_arg(0);
$v = func_get_arg(1);
foreach((array)$this->_ as $o){
$o->$k = $v;
}
return $this;
}
}
public function size(){
return sizeof($this->_);
}
public function eq(){
$pos = func_get_arg(0);
if(!is_numeric($pos)) return false;
if( isset($this->_[$pos]) ) $this->_ = array($this->_[$pos]);
return $this;
}
public function gt(){
$pos = func_get_arg(0);
if(!is_numeric($pos)) return false;
if( isset($this->_[$pos]) ) $this->_ = array_slice($this->_,$pos);
return $this;
}
public function lt(){
$pos = func_get_arg(0);
if(!is_numeric($pos)) return false;
if( isset($this->_[$pos]) ) $this->_ = array_slice($this->_,0,$pos+1);
return $this;
}
public function get(){ // must be non-destructive
$pos = func_get_arg(0);
if(!is_numeric($pos)) return false;
if( isset($this->_[$pos]) ) $this->__ = new kQuery($this->_[$pos]);
$this->__->__parent = &$this;
return $this->__;
}
public function end(){
if($this->__parent) return $this->__parent;
return false;
}
public function each(){ // object is passed as the only argument
$args = func_get_args();
foreach((array)$this->_ as $o){
echo '<br/>';
foreach($args as $a){
// if it's a lambda function
if(strpos($a,'lambda_')=='1'){
$a($o);
continue;
}
// if it's a string of a function (ends in ; or } )
$a = trim($a);
if(strpos($a,';')==strlen($a)-1 || strpos($a,'}')==strlen($a)-1){
$a = create_function('$this',$a);
$a($o);
continue;
}
// must be the name of a function
call_user_func($a,$o);
}
}
}
/* private methods */
private function query(){
$a = func_get_arg(0);
preg_match('#(\w+)\s?(?:\#(\w+))?\s?(?:(\w*)=?(\w*))?#i',$a,$q);
//outputs:
// [0] => full string
// [1] => ThingType
// [2] => id (if any)
// [3] => attr (if any)
// [4] => val (if any)
if(empty($q[1])) dier(__FILE__.'->'.__LINE__."\n",$q);
// return a blank object of type ThingType
if(empty($q[2]) && empty($q[3]) && empty($q[4])){
$this->_[] = new $q[1];
}
// get by ID
if(!empty($q[2]) && empty($q[3]) && empty($q[4])){
$this->_[] = new $q[1]($q[2]);
}
// STILL TO IMPLEMENT (as I need them):
//
// get by attibute
// get by value
// get by attibute=value
// get by attibute!=value
// get by attibute<=value... (and others)
}
}
$k = create_function('','$args=func_get_args(); return call_user_func_array(array(new kQuery(),"__construct"),$args);');
EDITED to fix the call_user_func() error in the ->add() method...