Changeset 1299
- Timestamp:
- 05/12/09 14:40:08 (1 year ago)
- Files:
-
- trunk/lib/Ak.php (modified) (1 diff)
- trunk/lib/AkActionController/AkCacheHandler.php (modified) (1 diff)
- trunk/lib/AkActionView/TemplateEngines/AkSintags/AkSintagsParser.php (modified) (2 diffs)
- trunk/lib/AkActionView/helpers/xml_helper.php (added)
- trunk/lib/AkActiveRecord.php (modified) (6 diffs)
- trunk/lib/AkActiveRecord/AkActiveRecordMock.php (modified) (2 diffs)
- trunk/lib/AkActiveRecord/AkAssociatedActiveRecord.php (modified) (21 diffs)
- trunk/lib/AkInstaller.php (modified) (5 diffs)
- trunk/lib/AkLogger.php (modified) (2 diffs)
- trunk/lib/AkUnitTest.php (modified) (2 diffs)
- trunk/lib/AkUnitTestSuite.php (modified) (5 diffs)
- trunk/script/extras/TPL-ci-config.php (modified) (1 diff)
- trunk/test/fixtures/app/installers/belong_installer.php (added)
- trunk/test/fixtures/app/installers/many_installer.php (added)
- trunk/test/fixtures/app/installers/user_installer.php (modified) (2 diffs)
- trunk/test/fixtures/app/models/belong.php (added)
- trunk/test/fixtures/app/models/many.php (added)
- trunk/test/unit/lib/AkActiveRecord/AkBelongsTo_Find_Include_Owner_belongsTo.php (modified) (4 diffs)
- trunk/test/unit/lib/AkActiveRecord/AkHasAndBelongsToMany.php (modified) (2 diffs)
- trunk/test/unit/lib/AkActiveRecord/_AkActiveRecord_return_types.php (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lib/Ak.php
r1298 r1299 473 473 if (!file_exists($path)){ 474 474 Ak::make_dir(dirname($path), $options); 475 return mkdir($path);475 return @mkdir($path); 476 476 } 477 477 } trunk/lib/AkActionController/AkCacheHandler.php
r1280 r1299 576 576 $res = mkdir(dirname($filename),0755,true); 577 577 } 578 if(!AK_PHP5) { 579 580 Ak::compat('file_put_contents'); 581 582 } 578 583 file_put_contents($filename, $content); 579 584 trunk/lib/AkActionView/TemplateEngines/AkSintags/AkSintagsParser.php
r1250 r1299 683 683 $helper_class_name = AkInflector::camelize($underscored_helper_name); 684 684 if(class_exists($helper_class_name)){ 685 $methods = get_class_methods($helper_class_name); 686 $vars=get_class_vars($helper_class_name); 687 if (AK_PHP5 && isset($vars['dynamic_helpers'])) { 688 $dynamic_helpers = Ak::toArray($vars['dynamic_helpers']); 689 foreach ($dynamic_helpers as $method_name){ 690 $this->dynamic_helpers[$method_name] = $underscored_helper_name; 691 } 692 } 685 693 foreach (get_class_methods($helper_class_name) as $method_name){ 686 694 if($method_name[0] != '_'){ … … 706 714 } 707 715 $this->_getAvailableHelpers(); 708 return empty($this->available_helpers[$method_name]) ? false : $this->available_helpers[$method_name]; 716 //return empty($this->available_helpers[$method_name]) ? false : $this->available_helpers[$method_name]; 717 if(empty($this->available_helpers[$method_name])) { 718 if (!empty($this->dynamic_helpers)) { 719 foreach($this->dynamic_helpers as $regex => $helper) { 720 $regex = trim($regex,'/'); 721 if (@preg_match('/'.$regex.'/', $method_name)) { 722 return $helper; 723 } 724 } 725 } 726 return false; 727 } else { 728 return $this->available_helpers[$method_name]; 729 } 709 730 } 710 731 trunk/lib/AkActiveRecord.php
r1293 r1299 21 21 22 22 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkAssociatedActiveRecord.php'); 23 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkActiveRecordMock.php'); 23 24 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkDbAdapter.php'); 24 25 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkDbSchemaCache.php'); … … 972 973 $sql = array_merge(array($sql),$options['bind']); 973 974 } 974 975 $result =& $this->findBySql($sql); 975 if (!empty($options['returns']) && $options['returns']!='default') { 976 $options['returns'] = in_array($options['returns'],array('simulated','default','array'))?$options['returns']:'default'; 977 if ($options['returns'] == 'simulated' && !AK_PHP5) { 978 trigger_error(Ak::t('In PHP4 you cannot use the return type "simulated" on finders. Return type reset to "default"'),E_USER_WARNING); 979 $options['returns'] = 'default'; 980 } 981 $simulation_class = !empty($options['simulation_class']) && class_exists($options['simulation_class'])?$options['simulation_class']:'AkActiveRecordMock'; 982 $result =& $this->findBySql($sql,null,null,null,$options['returns'],$simulation_class); 983 } else { 984 $result =& $this->findBySql($sql); 985 } 976 986 } 977 987 … … 1060 1070 return false; 1061 1071 } 1062 $valid_keys = array(' returns','load_acts','wrap','conditions', 'include', 'joins', 'limit', 'offset', 'group', 'order', 'sort', 'bind', 'select','select_prefix', 'readonly');1072 $valid_keys = array('simulation_class','returns','load_acts','wrap','conditions', 'include', 'joins', 'limit', 'offset', 'group', 'order', 'sort', 'bind', 'select','select_prefix', 'readonly'); 1063 1073 foreach (array_keys($options) as $key){ 1064 1074 if (!in_array($key,$valid_keys)){ … … 1152 1162 * $Post->findBySql(array("SELECT * FROM posts WHERE author = ? AND created_on > ?", $author_id, $start_date)); 1153 1163 */ 1154 function &findBySql($sql, $limit = null, $offset = null, $bindings = null )1164 function &findBySql($sql, $limit = null, $offset = null, $bindings = null, $returns = 'default', $simulation_class = 'AkActiveRecordMock') 1155 1165 { 1156 1166 if ($limit || $offset){ … … 1164 1174 $records = $this->_db->select ($sql,'selecting'); 1165 1175 foreach ($records as $record){ 1166 $objects[] =& $this->instantiate($this->getOnlyAvailableAttributes($record), false); 1176 if ($returns == 'default') { 1177 $objects[] =& $this->instantiate($this->getOnlyAvailableAttributes($record), false); 1178 } else if ($returns == 'simulated') { 1179 $objects[] = $this->getOnlyAvailableAttributes($record); 1180 } else if ($returns == 'array') { 1181 $objects[] = $this->getOnlyAvailableAttributes($record); 1182 } 1183 } 1184 if ($returns == 'simulated') { 1185 $false = false; 1186 $objects = $this->_generateStdClasses($simulation_class,$objects,$this->getType(),$false,$false,array('__owner'=>array('pk'=>$this->getPrimaryKey(),'class'=>$this->getType()))); 1167 1187 } 1168 1188 return $objects; … … 1845 1865 function getId() 1846 1866 { 1847 return $this->{$this->getPrimaryKey()}; 1867 $pk=$this->getPrimaryKey(); 1868 if(empty($pk)) { 1869 debug_print_backtrace(); 1870 } 1871 return $this->{$pk}; 1848 1872 } 1849 1873 trunk/lib/AkActiveRecord/AkActiveRecordMock.php
r1293 r1299 1 1 <?php 2 class AkActiveRecordMockHandler 3 { 4 var $_parent, $_association_id; 5 function __construct(&$parent, $association_id) 6 { 7 $this->_parent = $parent; 8 $this->_association_id = $association_id; 9 } 10 function load() 11 { 12 if (!empty($this->_parent)) { 13 $assoc = $this->_association_id; 14 return $this->_parent->$assoc; 15 } 16 return false; 17 } 18 19 function __call($name, $args) 20 { 21 $handler = &$this->_parent->_getHandlerForAssociation($this->_association_id); 22 return call_user_func_array(array($handler, $name),$args); 23 } 24 } 2 25 class AkActiveRecordMock 3 26 { 4 27 var $_parent,$_class,$_pkValue,$_handler; 5 28 var $load_acts = false; 29 var $load_associations = true; 30 var $__associations=array(); 31 var $__handlers = array(); 32 var $_dummy_instance; 6 33 function __construct($pk,$class, $handler, &$parent) 7 34 { … … 16 43 return $this->_pkValue; 17 44 } 18 45 function isCallable($method) 46 { 47 return is_callable(array($this->_class,$method)); 48 } 19 49 function get($name) 20 50 { 21 return $this->$name;51 return isset($this->$name)?$this->$name:null; 22 52 } 23 53 24 54 function getAttribute($name) 25 55 { 26 return $this-> $name;56 return $this->get($name); 27 57 } 28 function &_getObject($handler = false) 29 { 30 31 if (!empty($handler) && !empty($this->_parent)) { 32 $object = $this->_parent->_getObject($this->_handler); 33 $object = $object->$handler; 34 if ($object && in_array($object->getType(),array('hasOne','belongsTo'))) { 35 $oclass = $object = &$object->getAssociationOption('class_name'); 36 $object = new $oclass(); 37 } else if ($object && in_array($object->getType(),array('hasMany','hasAndBelongsToMany',))) { 38 $object =$object->getAssociatedModelInstance(); 39 } 40 41 } else if (!empty($handler) && empty($this->_parent)) { 42 $class_name = $this->_class; 43 $obj = new $class_name(); 44 $object = $obj->$handler; 45 if (in_array($object->getType(),array('hasOne','belongsTo'))) { 46 $oclass = $object = &$object->getAssociationOption('class_name'); 47 $object = new $oclass(); 48 } else if ($object && in_array($object->getType(),array('hasMany','hasAndBelongsToMany',))) { 49 $object =$object->getAssociatedModelInstance(); 58 function &_getHandlerForAssociation($association_id) 59 { 60 $false = false; 61 if (isset($this->__handlers[$association_id])) { 62 $class = $this->_class; 63 $obj=&$this->_getObject(); 64 $handler_name = $this->__handlers[$association_id]; 65 $myobj = new $class(); 66 if (isset($myobj->$handler_name)) { 67 $handler = $myobj->$handler_name; 68 $handler->Owner = &$obj; 69 $obj->$handler_name = &$handler; 70 $obj->$handler_name->_loaded=true; 71 return $obj->$handler_name; 50 72 } 51 73 } else { 52 53 if (!empty($this->_parent)) { 54 $object=&$this->_parent->_getObject($this->_handler); 74 $class = $this->_class; 75 $obj=&$this->_getObject(); 76 $handler_name = $obj->getCollectionHandlerName($association_id); 77 if(!$handler_name) { 78 $handler_name = $association_id; 55 79 } 56 80 $myobj = new $class(); 81 if (isset($myobj->$handler_name)) { 82 $handler = &$myobj->$handler_name; 83 $handler->Owner = &$obj; 84 $obj->$handler_name = &$handler; 85 return $obj->$handler_name; 86 } 57 87 } 58 return $ object;88 return $false; 59 89 } 90 function _getAssociationId($handler_name) 91 { 92 return isset($this->__associations[$handler_name])?$this->__associations[$handler_name]:false; 93 } 94 function load() 95 { 96 if (!empty($this->_parent)) { 97 $assoc = $this->_parent->_getAssociationId($this->_handler); 98 return $this->_parent->$assoc; 99 } 100 return false; 101 } 102 function _addAssociation($association_id, $handler_name) 103 { 104 //Ak::getLogger()->message('addAssociation on '.$this->_getClass().' with association_id:'.$association_id.' handler_name:'.$handler_name); 105 if ($association_id != $handler_name) { 106 $this->$handler_name = &new AkActiveRecordMockHandler($this,$association_id); 107 } 108 if(is_object($this->$handler_name)) { 109 $this->$handler_name->_loaded=true; 110 $this->__associations[$handler_name] = $association_id; 111 $this->__handlers[$association_id] = $handler_name; 112 } 113 } 114 function &_getObject() 115 { 116 static $obj; 117 118 if (!empty($obj)) return $obj; 119 $class = $this->_class; 120 $object_vars = get_object_vars($this); 121 $attributes = array(); 122 $associations = array(); 123 foreach($object_vars as $key => $value) { 124 if (!($is_association=in_array($key, $this->__associations)) && is_scalar($value)) { 125 $attributes[$key]=$value; 126 } else if ($is_association) { 127 $associations[]=$key; 128 } 129 } 130 131 $obj =& new $class('attributes', $attributes); 132 133 $obj->_newRecord = false; 134 foreach($associations as $assoc) { 135 136 $handler_name = $this->__handlers[$assoc]; 137 $obj->$handler_name = new AkActiveRecordMockHandler($this, $assoc); 138 $obj->$assoc = &$this->$assoc; 139 } 140 return $obj; 141 } 142 143 60 144 function _getClass() 61 145 { 62 146 return $this->_class; 63 147 } 148 64 149 function __call($name, $args = array()) 65 150 { 66 151 $obj = &$this->_getObject(); 67 68 152 if($obj) { 69 153 //Ak::getLogger()->message('calling '.$name.' on '.$this->_getClass()); 70 154 if (method_exists(&$obj,$name)) { 71 $obj->setAttributes(get_object_vars($this));72 155 return call_user_func_array(array(&$obj,$name),$args); 73 156 } trunk/lib/AkActiveRecord/AkAssociatedActiveRecord.php
r1297 r1299 159 159 { 160 160 $result = false; 161 if(!empty($this->_AssociationHandler)){ 162 $result =& $this->_AssociationHandler->loadAssociated($this->getAssociationId()); 161 $association_id = $this->getAssociationId(); 162 if(!empty($this->_AssociationHandler) && (empty($this->_loaded))){ 163 $result =& $this->_AssociationHandler->loadAssociated($association_id); 164 } else if (!empty($this->_AssociationHandler->Owner->$association_id)) { 165 $result = &$this->_AssociationHandler->Owner->$association_id; 163 166 } 164 167 return $result; … … 255 258 $load_acts = isset($options['load_acts'])?$options['load_acts']:true; 256 259 260 $config = array('__owner'=>array('class'=>$this->getType(),'pk'=>$this->getPrimaryKey())); 261 257 262 $returns = isset($options['returns'])?$options['returns']:'default'; 263 if ($returns == 'simulated' && !AK_PHP5) { 264 trigger_error(Ak::t('In PHP4 you cannot use the return type "simulated" on finders. Return type reset to "default"'),E_USER_WARNING); 265 $returns = 'default'; 266 } 267 $simulation_class = isset($options['simulation_class']) && class_exists($options['simulation_class'])?$options['simulation_class']:'AkActiveRecordMock'; 258 268 if (!in_array($returns,array('default','array','simulated'))) { 259 269 $this->log('option "returns" must be one of default,array,simulated'); … … 281 291 $type =$this->$handler_name->getType(); 282 292 $multi = false; 283 $pk = false;293 284 294 if (in_array($type,array('hasMany','hasAndBelongsToMany'))) { 285 295 $multi = true; 286 296 $instance = $this->$handler_name->getAssociatedModelInstance(); 287 $pk=$instance->getPrimaryKey(); 297 $class = $instance->getType(); 298 $pk_name = $instance->getPrimaryKey(); 288 299 $table_name =$instance->getTableName(); 289 300 } else { … … 292 303 Ak::import($class); 293 304 } 294 $instance = new $class; 295 $table_name =$instance->getTableName(); 296 } 297 305 306 if(is_string($class)) { 307 $instance = new $class; 308 $pk_name = $instance->getPrimaryKey(); 309 $table_name =$instance->getTableName(); 310 } else { 311 312 continue; 313 } 314 } 315 $config['__owner'][$handler_name] = array('class'=>$class,'association_id'=>$association_id,'pk'=>$pk_name); 298 316 $associated_options = $this->$handler_name->getAssociatedFinderSqlOptionsForInclusionChain('owner[@'.$parent_pk.']','__owner',$association_options,$multi); 299 317 … … 319 337 320 338 321 $this->_prepareIncludes('owner[@'.$parent_pk.']',$multi,$this,$available_associated_options,$handler_name,$handler_name,$association_id,$options,$association_options,$replacements );322 323 } 324 339 $this->_prepareIncludes('owner[@'.$parent_pk.']',$multi,$this,$available_associated_options,$handler_name,$handler_name,$association_id,$options,$association_options,$replacements, $config['__owner']); 340 341 } 342 //$this->log('Config:'.var_export($config,true)); 325 343 $replace_regex = array_keys($replacements); 326 344 $replace_value = array_values($replacements); … … 365 383 366 384 if (isset($options['wrap'])) { 385 $addLimit=''; 386 if(preg_match('/LIMIT ([\d]+){1}(,){0,1}(\s*)([\d]+){0,1}/i',$sql,$matches) && strstr($options['wrap'],'{limit}')) { 387 $sql = str_replace($matches[0],'',$sql); 388 $addLimit = $matches[0]; 389 } 367 390 $sql = str_replace('{query}',$sql,$options['wrap']); 391 //if(!empty($addLimit)) { 392 $sql = str_replace('{limit}',$addLimit,$sql); 393 //} 368 394 } 369 395 … … 372 398 } 373 399 374 $result = & $this->_findBySqlWithAssociations($sql, empty($options ['virtual_limit']) ? false : $options ['virtual_limit'], $load_acts, $returns );400 $result = & $this->_findBySqlWithAssociations($sql, empty($options ['virtual_limit']) ? false : $options ['virtual_limit'], $load_acts, $returns,$simulation_class, $config); 375 401 if (empty($result)) { 376 402 $result = false; … … 380 406 381 407 382 function _prepareIncludes($prefix,$parent_is_plural, &$parent,&$available_associated_options,$handler_name,$parent_association_id,$association_id,&$options,&$association_options, &$replacements )408 function _prepareIncludes($prefix,$parent_is_plural, &$parent,&$available_associated_options,$handler_name,$parent_association_id,$association_id,&$options,&$association_options, &$replacements, &$config) 383 409 { 384 410 if (isset($association_options['include'])) { … … 421 447 'hasAndBelongsToMany') { 422 448 $instance=&$sub_association_object->$sub_handler_name->getAssociatedModelInstance(); 449 $class_name = $instance->getType(); 423 450 $table_name = $instance->getTableName(); 424 451 $pk = $instance->getPrimaryKey(); … … 437 464 $pk = $sub_association_object->$sub_handler_name->getPrimaryKey(); 438 465 $instance = &$sub_association_object; 466 $class_name =$instance->getType(); 439 467 $pluralize = false; 440 468 $table_name = $instance->getTableName(); 441 469 } 442 470 $config[$handler_name][$sub_handler_name] = array('association_id'=>$sub_association_id,'class'=>$class_name,'pk'=>$pk); 443 471 $sub_associated_options = $sub_association_object->$sub_handler_name->getAssociatedFinderSqlOptionsForInclusionChain($prefix.'['.$handler_name.']'.($parent_is_plural?'[@'.$pk.']':''),'__owner__'.$parent_association_id, 444 472 $sub_options, $pluralize); … … 472 500 } 473 501 if (!empty($sub_options)) { 474 $this->_prepareIncludes($prefix.'['.$handler_name.']'.($parent_is_plural?'[@'.$pk.']':''),$pluralize,$instance,$available_associated_options,$sub_handler_name,$parent_association_id.'__'.$sub_handler_name,$sub_association_id,$options['include'][$association_id],$association_options['include'][$idx],$replacements );502 $this->_prepareIncludes($prefix.'['.$handler_name.']'.($parent_is_plural?'[@'.$pk.']':''),$pluralize,$instance,$available_associated_options,$sub_handler_name,$parent_association_id.'__'.$sub_handler_name,$sub_association_id,$options['include'][$association_id],$association_options['include'][$idx],$replacements,$config[$handler_name]); 475 503 } 476 504 } … … 503 531 } 504 532 505 function &_findBySqlWithAssociations($sql, $virtual_limit = false, $load_acts = true, $returns = ' ActiveRecord')533 function &_findBySqlWithAssociations($sql, $virtual_limit = false, $load_acts = true, $returns = 'default', $simulation_class = 'AkActiveRecordMock', $config = array()) 506 534 { 507 535 $objects = array(); … … 511 539 } 512 540 513 $result =& $this->_generateObjectGraphFromResultSet($results,$virtual_limit, $load_acts, $returns );541 $result =& $this->_generateObjectGraphFromResultSet($results,$virtual_limit, $load_acts, $returns, $simulation_class, $config); 514 542 return $result; 515 543 … … 526 554 * @return array ObjectGraph as an array 527 555 */ 528 function &_generateObjectGraphFromResultSet($results, $virtual_limit = false, $load_acts=true, $returns = ' ActiveRecord')556 function &_generateObjectGraphFromResultSet($results, $virtual_limit = false, $load_acts=true, $returns = 'default',$simulation_class='AkActiveRecordMock', $config = array()) 529 557 { 530 558 $return = array(); … … 532 560 $keys = array(); 533 561 while ($record = $results->FetchRow()) { 534 562 /** 563 * implement limits here, config should have limits per association 564 * need offset as well 565 */ 535 566 foreach($record as $key=>$value) { 536 567 … … 568 599 } 569 600 570 $this->_addToOwner($owner,str_replace('owner[','[',$key),$value );601 $this->_addToOwner($owner,str_replace('owner[','[',$key),$value, $returns, $config['__owner']); 571 602 572 603 } … … 606 637 } 607 638 } else if ($returns == 'array') { 639 640 $this->_reindexArray($owner); 608 641 $return = $owner; 609 642 } else if ($returns == 'simulated') { 610 include AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkActiveRecordMock.php';643 include_once AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkActiveRecordMock.php'; 611 644 $false = false; 612 $return = &$this->_generateStdClasses($ owner, $this->getType(), $false, $false);645 $return = &$this->_generateStdClasses($simulation_class,$owner, $this->getType(), $false, $false, $config); 613 646 } 614 647 return $return; 615 648 } 616 function _generateStdClasses($owner, $class, $handler_name, &$parent) 617 { 649 function _reindexArray(&$array) 650 { 651 if (is_numeric(key($array))) { 652 $array = array_values($array); 653 } 654 foreach($array as $key => $value) { 655 if (is_array($value)) { 656 $this->_reindexArray($array[$key]); 657 } 658 } 659 } 660 function _generateStdClasses($simulation_class,$owner, $class, $handler_name, &$parent, $config = array(), $config_key = '__owner') 661 { 662 /**echo "<pre>"; 663 var_dump($config_key); 664 var_dump($config); 665 echo "</pre>";*/ 666 618 667 $return = array(); 619 668 $singularize=false; 669 $pk = isset($config[$config_key]['pk'])?$config[$config_key]['pk']:'id'; 620 670 if (!is_numeric(key($owner))) { 621 671 $singularize =true; 622 $key = isset($owner['id'])?$owner['id']:0; 672 673 $key = isset($owner[$pk])?$owner[$pk]:0; 623 674 $owner = array($key=>$owner); 624 675 } 625 676 if(is_array($owner)) 626 677 foreach($owner as $id=>$data) { 627 $obj = &new AkActiveRecordMock($id,$class, $handler_name, $parent); 678 require_once AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkActiveRecordMock.php'; 679 $id = isset($data[$pk])?$data[$pk]:$id; 680 $obj = &new $simulation_class($id,$class, $handler_name, $parent); 628 681 if(is_array($data)) 629 682 foreach($data as $key => $value) { … … 632 685 $obj->$key = $value; 633 686 } else if (is_array($value)) { 634 $assoc = $key; 635 if(is_numeric(key($value))) { 636 $key = AkInflector::pluralize($key); 637 } 638 $obj->$key = &$this->_generateStdClasses($value, $class, $assoc,$obj); 687 //$assoc = $key; 688 $assoc = isset($config[$config_key][$key]['association_id'])?$config[$config_key][$key]['association_id']:false; 689 //if(is_numeric(key($value))) { 690 // $key = AkInflector::pluralize($key); 691 //} 692 /** if ($handler_name!==false) { 693 $config_key = '__owner'; 694 } else { 695 $config_key = $handler_name; 696 }*/ 697 if ($assoc) { 698 $obj->$assoc = &$this->_generateStdClasses($simulation_class,$value, @$config[$config_key][$key]['class'], $key,$obj, @$config[$config_key], $key); 699 //$this->log('setting assoc:'.$assoc); 700 $obj->_addAssociation($assoc, $key); 701 } else { 702 /**$assoc = $key; 703 $obj->$assoc = &$this->_generateStdClasses($simulation_class,$value, @$config[$config_key][$key]['class'], $key,$obj, @$config[$config_key], $key); 704 $this->log('setting assoc with key:'.$assoc); 705 $obj->_addAssociation($assoc, $key);*/ 706 //die('fuck'); 707 /**var_dump($key); 708 var_dump($value); 709 var_dump($config_key); 710 var_dump($config);*/ 711 //var_dump(func_get_args()); 712 } 639 713 } 640 714 } … … 645 719 646 720 647 648 function _addToOwner(&$owner, $key, $value) { 721 function org_addToOwner(&$owner, $key, $value) { 649 722 650 723 if(preg_match_all('/\[(.*?)\]/',$key,$matches)) { … … 652 725 $last = &$owner; 653 726 for($idx=0;$idx<$count;$idx++) { 727 654 728 if (!isset($last[$matches[1][$idx]])) { 655 729 $last[$matches[1][$idx]] = array(); 656 730 } 657 731 $last = &$last[$matches[1][$idx]]; 732 658 733 } 659 734 $last = $value; 660 735 } 736 } 737 function _addToOwner(&$owner, $key, $value, $returns, $config) { 738 739 if(preg_match_all('/\[(.*?)\]/',$key,$matches)) { 740 $count = count($matches[1]); 741 $last = &$owner; 742 for($idx=0;$idx<$count;$idx++) { 743 $key = $matches[1][$idx]; 744 $association = $key; 745 746 if (isset($config[$key]) && $returns == 'array') { 747 $config = $config[$key]; 748 $association = $config['association_id']; 749 //$this->log('using association:'.$association); 750 } 751 if (!isset($last[$association])) { 752 $last[$association] = array(); 753 } 754 $last = &$last[$association]; 755 756 } 757 $last = $value; 758 } 759 //$this->log('owner:'.var_export($owner,true)); 661 760 } 662 761 … … 738 837 } 739 838 $available = @array_merge($data,$nondiff); 740 839 840 if(empty($available[$instance->getPrimaryKey()])) { 841 $parent->$assoc_name->_loaded=true; 842 //return; 843 continue; 844 } 741 845 $available['load_associations'] = false; 742 846 $available['load_acts'] = $load_acts; 743 847 744 848 $obj=&$parent->$assoc_name->build($available,false); 745 849 trunk/lib/AkInstaller.php
r1291 r1299 202 202 203 203 if($this->$method_name($options) === false){ 204 $this->log($this->getInstallerName().': returned false'); 204 205 $this->transactionFail(); 205 206 } 206 207 $success = !$this->transactionHasFailed(); 207 208 $this->transactionComplete(); 208 if($success ){209 if($success || ($version_number==0 && $method_prefix=='down')){ 209 210 $this->setInstalledVersion($version_number, $options); 210 211 } … … 243 244 function getInstalledVersion($options = array()) 244 245 { 246 $this->_createMigrationsTable(); 245 247 $version = $this->db->selectValue(array('SELECT version FROM akelos_migrations WHERE name=?',$this->getInstallerName())); 246 248 247 if( !($tableExists=$this->tableExists('akelos_migrations')) || $version===NULL) {249 if($version==NULL) { 248 250 249 251 $version_file = $this->_versionPath($options); … … 255 257 $this->setInstalledVersion($version, $options); 256 258 } else { 257 $version = Ak::file_get_contents($this->_versionPath($options)); 258 if(!$tableExists) { 259 $this->_createMigrationsTable(); 260 } 261 $this->db->execute(array('INSERT INTO akelos_migrations (name,version,created_at) VALUES (?,?,?)',$this->getInstallerName(),$version,Ak::getDate())); 259 $oldfile=$this->_versionPath($options); 260 $version = Ak::file_get_contents($oldfile); 261 //if(!$tableExists) { 262 // $this->_createMigrationsTable(); 263 //} 264 copy($oldfile,$oldfile.'.backup'); 265 unlink($oldfile); 266 $this->log('message','got old version from file:'.$oldfile.'='.$version.' moved to backup-file:'.$oldfile.'.backup'); 267 $this->setInstalledVersion($version, $options); 268 //$this->db->execute(array('INSERT INTO akelos_migrations (name,version,created_at) VALUES (?,?,?)',$this->getInstallerName(),$version,Ak::getDate())); 262 269 } 263 270 264 }265 $this->log('Installed version of '.$this->getInstallerName().':'.$version);271 } 272 $this->log('Installed version of '.$this->getInstallerName().':'.$version); 266 273 return $version; 267 274 } … … 269 276 function _createMigrationsTable() 270 277 { 271 $this->createTable('akelos_migrations','id, name, version int'); 272 $this->addIndex('akelos_migrations','UNIQUE name','unq_name'); 278 if(!$this->tableExists('akelos_migrations')) { 279 AkDbSchemaCache::clearAll(); 280 $this->data_dictionary =& $this->db->getDictionary(); 281 $this->available_tables = $this->getAvailableTables(); 282 $this->createTable('akelos_migrations','id, name, version int'); 283 $this->addIndex('akelos_migrations','UNIQUE name','unq_name'); 284 } 273 285 } 274 286 275 287 function setInstalledVersion($version, $options = array()) 276 288 { 277 if(!$this->tableExists('akelos_migrations')) {289 //if(!$this->tableExists('akelos_migrations')) { 278 290 $this->_createMigrationsTable(); 279 }291 //} 280 292 /** 281 293 * this will produce an error if the unique index on name is violated, then we update … … 412 424 { 413 425 require_once(AK_LIB_DIR.DS.'AkActiveRecord'.DS.'AkDbSchemaCache.php'); 414 AkDbSchemaCache::clear(AkInflector::classify($table_name)); 415 $result = $this->tableExists($table_name) ? $this->db->execute('DROP TABLE '.$table_name) : true; 426 //AkDbSchemaCache::clear(AkInflector::classify($table_name)); 427 AkDbSchemaCache::clear($table_name); 428 $model_name = AkInflector::classify($table_name); 429 Ak::import($model_name); 430 if (class_exists($model_name)) { 431 $m = new $model_name(); 432 if (method_exists($m,'beforeDropTable')) { 433 $this->log('message','Calling '.$model_name.'::beforeDropTable'); 434 $m->beforeDropTable(); 435 } 436 } 437 $result = $this->tableExists($table_name) ? $this->db->execute('DROP TABLE '.$table_name) : 1; 416 438 if($result){ 417 439 unset($this->available_tables[array_search($table_name, $this->available_tables)]); 418 440 if(!empty($options['sequence'])){ 419 441 $this->dropSequence($table_name); 442 } 443 if($result===true && isset($m)) { 444 445 if (method_exists($m,'afterDropTable')) { 446 $this->log('message','Calling '.$model_name.'::afterDropTable'); 447 $m->afterDropTable(); 448 } 420 449 } 421 450 } trunk/lib/AkLogger.php
r468 r1299 183 183 return empty($details) ? $message.'</div>' : $message."<ul>\n$details\n</ul>\n</div>"; 184 184 } 185 185 function _walkParams($params) 186 { 187 $return = ''; 188 foreach ($params as $k=>$v){ 189 if(is_scalar($v)) { 190 $return .= "\n\t\t- ".$k.": $v"; 191 } else if(is_array($v)){ 192 $return.= "\n\t\t\t- $k:".var_export($v,true); 193 } 194 } 195 return $return; 196 } 186 197 function _getLogFormatedAsString($type, $error_mode, $error_message, $serialized = false) 187 198 { … … 193 204 }else{ 194 205 $details = ''; 195 foreach ($params as $k=>$v){ 196 $details .= "\n\t\t- ".$k.": $v"; 197 } 206 $details.=$this->_walkParams($params); 198 207 $message .= empty($details) ? "\n" : "\n\t".'PARAMS{'.$details."\t\n}\n"; 199 208 } trunk/lib/AkUnitTest.php
r1217 r1299 178 178 } 179 179 } 180 180 function log($message) 181 { 182 if (AK_LOG_EVENTS){ 183 static $logger; 184 if(empty($logger)) { 185 $logger = &Ak::getLogger(); 186 } 187 $logger->log('unit-test',$message); 188 } 189 } 181 190 function _reinstallModel($model, $table_definition = '') 182 191 { 192 $this->log('Reinstalling model:'.$model); 183 193 if (!$this->uninstallAndInstallMigration($model)){ 184 194 $table_name = AkInflector::tableize($model); … … 201 211 function uninstallAndInstallMigration($installer_name) 202 212 { 213 $this->log('Looking for installer:'.AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php'); 203 214 if (file_exists(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php')){ 215 $this->log('found installer:'.AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php'); 204 216 require_once(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php'); 205 217 $installer_class_name = $installer_name.'Installer'; trunk/lib/AkUnitTestSuite.php
r1185 r1299 13 13 { 14 14 $this->_init(); 15 15 16 } 16 17 18 function log($message) { 19 if (AK_LOG_EVENTS){ 20 $this->logger->log('unit-test',$message); 21 } 22 } 17 23 function _includeFiles($files) 18 24 { … … 20 26 if (!is_dir($test)) { 21 27 if (!in_array($test,$this->excludes)) { 28 $this->log('Including testfile:'.$test); 22 29 $this->addTestFile($test); 23 30 } … … 30 37 function _init() 31 38 { 39 $this->logger = &Ak::getLogger(); 32 40 $base = AK_TEST_DIR.DS.'unit'.DS.'lib'.DS; 33 41 $this->GroupTest($this->title); … … 47 55 } else if (is_array($this->partial_tests)){ 48 56 foreach ($this->partial_tests as $test) { 57 //$this->log('Including partial testfile:'.$test); 49 58 $this->addTestFile($base.$this->baseDir.DS.$test.'.php'); 50 59 } … … 54 63 } 55 64 } 65 66 function run(&$reporter) { 67 $reporter->paintGroupStart($this->getLabel(), $this->getSize()); 68 for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) { 69 if (is_string($this->_test_cases[$i])) { 70 $class = $this->_test_cases[$i]; 71 $test = &new $class(); 72 //$this->log('Running test-class:'.$class); 73 $test->run($reporter); 74 } else { 75 //$this->log('Running test-class:'.$this->_test_cases[$i]->_label); 76 $this->_test_cases[$i]->run($reporter); 77 } 78 } 79 $reporter->paintGroupEnd($this->getLabel()); 80 return $reporter->getStatus(); 81 } 56 82 } 57 83 trunk/script/extras/TPL-ci-config.php
r1185 r1299 6 6 defined('AK_LOG_EVENTS') ? null : define('AK_LOG_EVENTS', true); 7 7 8 8 define('AK_ACTIVE_RECORD_VALIDATE_TABLE_NAMES',false); 9 9 include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'boot.php'); 10 10 trunk/test/fixtures/app/installers/user_installer.php
r1251 r1299 3 3 class UserInstaller extends AkInstaller 4 4 { 5 function up_2()5 function xup_2() 6 6 { 7 7 $this->addColumn('users', 'preferences text'); 8 8 } 9 9 10 function down_2()10 function xdown_2() 11 11 { 12 12 $this->removeColumn('users', 'preferences'); … … 15 15 function up_1() 16 16 { 17 $this->createTable('users', 'id,name,email,login,password,is_admin,is_enabled,created_at,last_login_at'); 17 $this->log('up 1 on user'); 18 $this->createTable('users', 'id,name,email,login,password,is_admin,is_enabled,created_at,last_login_at,preferences text'); 18 19 } 19 20 20 21 function down_1() 21 22 { 23 $this->log('down 1 on user'); 22 24 $this->dropTable('users'); 23 25 } trunk/test/unit/lib/AkActiveRecord/AkBelongsTo_Find_Include_Owner_belongsTo.php
r1286 r1299 160 160 { 161 161 $this->installAndIncludeModels(array('User', 'Post','Comment')); 162 $this->User = new User(); 163 if ($this->User->_db->type()=='postgre') { 164 /** 165 * from postgres docs: 166 * 167 * A value of type name is a string of 63 or fewer characters. 168 * A name must start with a letter or an underscore; 169 * the rest of the string can contain letters, digits, and underscores. 170 * 171 * IF a column name here is over 63 characters long, the assoc finder will fail 172 */ 173 $this->assertTrue(true); 174 return; 175 } 176 162 177 $User =& new User(array('name'=>'Arno','email'=>'arno@bermilabs.com')); 163 178 $Post1 =& new Post(array('title'=>'Test1')); … … 167 182 $Comment2_1 =& new Comment(array('name'=>'Comment2_1')); 168 183 $Comment2_2 =& new Comment(array('name'=>'Comment2_2')); 169 170 184 171 185 $User->post->add($Post1); … … 260 274 function test_n_m_n() 261 275 { 276 262 277 $this->installAndIncludeModels(array('User', 'Post','Comment')); 278 $this->User = new User(); 279 if ($this->User->_db->type()=='postgre') { 280 /** 281 * from postgres docs: 282 * 283 * A value of type name is a string of 63 or fewer characters. 284 * A name must start with a letter or an underscore; 285 * the rest of the string can contain letters, digits, and underscores. 286 * 287 * IF a column name here is over 63 characters long, the assoc finder will fail 288 */ 289 $this->assertTrue(true); 290 return; 291 } 292 263 293 $User1 =& new User(array('name'=>'Arno','email'=>'arno@bermilabs.com')); 264 294 $User2 =& new User(array('name'=>'Arno','email'=>'arno2@bermilabs.com')); … … 311 341 } 312 342 /**/ 343 344 function test_belongs_to_has_many() 345 { 346 $this->installAndIncludeModels('Many,Belong'); 347 $hasMany = new Many(); 348 $belongsTo = new Belong(); 349 350 $many = $hasMany->create(array('name'=>'test')); 351 $belongs1 = $belongsTo->create(array('name'=>'belongs1')); 352 $belongs2 = $belongsTo->create(array('name'=>'belongs2')); 353 $array = array($belongs1,$belongs2); 354 $many->belong->set($array); 355 356 $result=$hasMany->findFirstBy('name','test',array('include'=>'belongs')); 357 358 $this->assertEqual(2,count($result->belongs)); 359 } 313 360 } 314 361 trunk/test/unit/lib/AkActiveRecord/AkHasAndBelongsToMany.php
r1286 r1299 16 16 @Ak::file_delete(AK_MODELS_DIR.DS.'post_user.php'); 17 17 @Ak::file_delete(AK_MODELS_DIR.DS.'friend_friend.php'); 18 18 19 19 $this->installAndIncludeModels(array('Post', 'Tag','Picture', 'Thumbnail','Panorama', 'Property', 'PropertyType', 'User')); 20 20 } … … 368 368 @Ak::file_delete(AK_MODELS_DIR.DS.'group_user.php'); 369 369 370 370 371 $this->installAndIncludeModels('User', 'Group', array('instantiate' => true)); 371 372
