Changeset 308

Show
Ignore:
Timestamp:
03/19/09 10:40:34 (3 years ago)
Author:
john
Message:

features and bug fixes from gocoffeego project

Location:
trunk/trax/vendor/trax
Files:
11 modified

Legend:

Unmodified
Added
Removed
  • trunk/trax/vendor/trax/action_controller.php

    r300 r308  
    5656     *  @var string 
    5757     */ 
    58     private $controller; 
     58    protected $controller; 
    5959 
    6060    /** 
     
    6464     *  @var string 
    6565     */ 
    66     private $action; 
    67  
    68     /** 
    69      *  Value of :id parsed from URL then forced to lower case 
     66    protected $action; 
     67 
     68    /** 
     69     *  Path to add to other filesystem paths 
    7070     * 
    7171     *  Set by {@link recognize_route()} 
    7272     *  @var string 
    7373     */ 
    74     private $id; 
    75  
    76     /** 
    77      *  Path to add to other filesystem paths 
    78      * 
    79      *  Set by {@link recognize_route()} 
    80      *  @var string 
    81      */ 
    8274    private $added_path = ''; 
    83       
    84     /** 
    85      *  Parameters for the action routine 
    86      * 
    87      *  Set by {@link recognize_route()}, passed as arguments to the 
    88      *  controller's action routine. 
    89      *  @var string[] 
    90      */ 
    91     private $action_params = array(); 
    9275 
    9376    /** 
     
    201184     *  @var string[] 
    202185     */ 
    203     private $before_filters = array(); 
     186    public $before_filters = array(); 
     187 
     188    public $before_filter_options = array(); 
    204189 
    205190    /** 
     
    211196    private $after_filters = array();      
    212197 
     198    private $after_filter_options = array(); 
     199 
    213200    /** 
    214201     *  @todo Document this attribute 
     
    224211     *  @todo Document this attribute 
    225212     */ 
    226     protected $before_filter = null; 
     213    #protected $before_filter = null; 
    227214 
    228215    /** 
    229216     *  @todo Document this attribute 
    230217     */ 
    231     protected $after_filter = null; 
     218    #protected $after_filter = null; 
    232219 
    233220    /** 
     
    318305     */ 
    319306    function __set($key, $value) { 
    320         //error_log("__set($key, $value)"); 
     307        #if(is_string($value) || is_array($value)) { 
     308            #error_log("__set($key, $value)"); 
     309        #} 
    321310        if($key == "before_filter") { 
    322311            $this->add_before_filter($value); 
     312            unset($this->$key); 
    323313        } elseif($key == "after_filter") { 
    324314            $this->add_after_filter($value); 
     
    396386     *  @uses load_router() 
    397387     *  @uses $action 
    398      *  @uses $action_params 
    399388     *  @uses $application_controller_file 
    400389     *  @uses $controller 
     
    513502 
    514503                    //  ':id' in route params overrides URL 
    515                     $this->id = $route_params[':id']; 
    516                 } elseif(@in_array(":id",$route_path) 
    517                    && array_key_exists(@array_search(":id", $route_path), 
    518                                        $this->url_path)) { 
    519                     $this->id = strtolower($this->url_path[@array_search(":id", $route_path)]); 
    520                     //  Parameters for the action routine. 
    521                     //  FIXME: make more general than just id 
    522                     if($this->id != "") { 
    523                         $this->action_params['id'] = $this->id; 
    524                     } 
     504                    $id = $route_params[':id']; 
     505                } elseif(@in_array(":id",$route_path)) { 
     506                    #print_r($this->url_path); 
     507                    #print_r($route_path); 
     508                    if(count($this->extra_path)) { 
     509                        foreach(array_reverse($this->extra_path) as $extra_path) { 
     510                            #array_unshift($this->url_path, $extra_path); 
     511                        } 
     512                    } 
     513                    #print_r($this->url_path); 
     514 
     515                    $id = strtolower($this->url_path[@array_search(":id", $route_path)]); 
    525516                } 
    526517                //  For historical reasons, continue to pass id 
    527518                //  in $_REQUEST 
    528                 if($this->id != "") { 
    529                     $_REQUEST['id'] = $this->id; 
     519                if($id != "") { 
     520                    $_REQUEST['id'] = $id; 
    530521                } 
    531                 //error_log('id='.$this->id); 
     522                //error_log('id='.$id); 
    532523 
    533524                $this->views_path .= "/" . $this->controller; 
     
    551542     * 
    552543     *  @uses $action 
    553      *  @uses $action_params 
    554544     *  @uses $application_controller_file 
    555545     *  @uses $application_helper_file 
     
    584574        } 
    585575        //error_log('process_route(): controller="'.$this->controller 
    586         //          .'"  action="'.$this->action.'"  id="'.$this->id.'"'); 
     576        //          .'"  action="'.$this->action.'"'); 
    587577 
    588578        # Include main application controller file 
     
    662652                # Call the controller method based on the URL 
    663653                if($this->controller_object->execute_before_filters()) { 
    664                     $controller_layout = null; 
     654                    $controller_layout = null; 
    665655                    if(isset($this->controller_object->layout)) { 
    666656                        $controller_layout = $this->controller_object->layout;        
    667657                    } 
    668                     if(method_exists($this->controller_object, $this->action)) { 
    669                         //error_log('method '.$this->action.' exists, calling it'); 
    670                         $action = $this->action; 
    671                         //error_log('calling action routine ' 
    672                         //          . get_class($this->controller_object) 
    673                         //          .'::'.$action.'() with params ' 
    674                         //          .var_export($this->action_params,true)); 
    675                         $this->controller_object->$action($this->action_params); 
     658 
     659                    #Get PUBLIC methods from controller object 
     660                    $all_methods = get_class_methods($this->controller_object);  
     661 
     662                    # Get Inherited methods from active_controller  
     663                    $inherited_methods = array_merge( 
     664                        get_class_methods(__CLASS__), 
     665                        $this->controller_object->before_filters, 
     666                        $this->controller_object->after_filters 
     667                    ); 
     668 
     669                    # Get non-inherited methods  
     670                    $action_methods = array_diff($all_methods, $inherited_methods); 
     671                    #error_log("available methods:".print_r($action_methods, true)); 
     672 
     673                    if(in_array($this->action, $action_methods)) { 
     674                        #error_log('method '.$this->action.' exists, calling it'); 
     675                        $action = $this->controller_object->called_action = $this->action; 
     676                        #error_log('calling action routine ' 
     677                        #          . get_class($this->controller_object) 
     678                        #          .'::'.$action.'()'); 
     679                        $this->controller_object->$action(); 
    676680                    } elseif(file_exists($this->views_path . "/" . $this->action . "." . Trax::$views_extension)) { 
    677                         //error_log('views file "'.$this->action.'"'); 
    678                         $action = $this->action; 
     681                        #error_log('views file "'.$this->action.'"'); 
     682                        $action = $this->controller_object->called_action = $this->action; 
    679683                    } elseif(method_exists($this->controller_object, "index")) { 
    680                         //error_log('calling action routine ' 
    681                         //          . get_class($this->controller_object) 
    682                         //          .'::index() with params ' 
    683                         //          .var_export($this->action_params,true)); 
    684                         $action = "index"; 
    685                         $this->controller_object->index($this->action_params); 
     684                        #error_log('calling action routine ' 
     685                        #          . get_class($this->controller_object) 
     686                        #          .'::index()'); 
     687                        $action = $this->controller_object->called_action = "index"; 
     688                        $this->controller_object->index(); 
    686689                    } else { 
    687690                        //error_log('no action'); 
     
    799802            } 
    800803            if(isset($extra_path) && is_array($extra_path)) { 
     804                $this->extra_path = $extra_path; 
    801805                $extra_path = implode("/", $extra_path); 
    802806                $this->added_path = $extra_path; 
     
    818822     */ 
    819823    function execute_before_filters() { 
     824     
     825        #if(isset($this->before_filter)) { 
     826            #$this->add_before_filter($this->before_filter); 
     827        #} 
     828        #error_log("before_filters:".print_r($this->before_filters, true)); 
     829        #error_log("before_filter_options:".print_r($this->before_filter_options, true));        
    820830        $return = true; 
    821831        if(count($this->before_filters) > 0) {  
     832            $action = $this->action ? $this->action : "index"; 
    822833            foreach($this->before_filters as $filter_function) { 
     834                if(array_key_exists($filter_function, $this->before_filter_options)) { 
     835                    if(is_array($options = $this->before_filter_options[$filter_function])) { 
     836                        if(array_key_exists('except', $options)) { 
     837                            if(preg_match("/\b$action\b/", $options['except'])) { 
     838                                #error_log("before filter except match: action:{$action} == ".$options['except']); 
     839                                continue;       
     840                            }                        
     841                        } 
     842                        if(array_key_exists('only', $options)) { 
     843                            if(!preg_match("/\b$action\b/", $options['only'])) { 
     844                                #error_log("before filter only non match: action:{$action} == ".$options['only']); 
     845                                continue;       
     846                            }                        
     847                        }                        
     848                    } 
     849                } 
    823850                if(method_exists($this, $filter_function)) { 
    824851                    if(false === $this->$filter_function()) { 
     
    840867     *  @uses $before_filters 
    841868     */ 
    842     function add_before_filter($filter_function_name) { 
     869    function add_before_filter($filter_function_name, $options = array(), $prepend = false) { 
    843870        //error_log("adding before filter: $filter_function_name"); 
    844871        if(is_string($filter_function_name) && !empty($filter_function_name)) { 
    845872            if(!in_array($filter_function_name, $this->before_filters)) { 
    846                 $this->before_filters[] = $filter_function_name; 
     873                if($prepend) { 
     874                    array_unshift($this->before_filters, $filter_function_name); 
     875                } else { 
     876                    array_push($this->before_filters, $filter_function_name); 
     877                } 
     878                if(count($options)) { 
     879                    if(count($this->before_filter_options[$filter_function_name])) { 
     880                        $this->before_filter_options[$filter_function_name] = array_merge($this->before_filter_options[$filter_function_name], $options); 
     881                    } else { 
     882                        $this->before_filter_options[$filter_function_name] = $options; 
     883                    }                                        
     884                } 
    847885            }                         
    848886        } elseif(is_array($filter_function_name)) { 
    849             if(count($this->before_filters) > 0) { 
    850                 $this->before_filters = array_merge($this->before_filters, $filter_function_name); 
    851             } else { 
    852                 $this->before_filters = $filter_function_name; 
    853             } 
    854         } 
    855     } 
     887            foreach($filter_function_name as $filter_name => $options) { 
     888                if(!in_array($filter_name, $this->before_filters)) { 
     889                    if($prepend) { 
     890                        array_unshift($this->before_filters, $filter_name); 
     891                    } else { 
     892                        array_push($this->before_filters, $filter_name); 
     893                    }    
     894                    if(count($options)) { 
     895                        if(count($this->before_filter_options[$filter_name])) { 
     896                            $this->before_filter_options[$filter_name] = array_merge($this->before_filter_options[$filter_name], $options); 
     897                        } else { 
     898                            $this->before_filter_options[$filter_name] = $options; 
     899                        }                                        
     900                    } 
     901                }                
     902            } 
     903        } 
     904    } 
     905 
     906    function prepend_before_filter($filter_function_name, $options = array()) { 
     907        $this->add_before_filter($filter_function_name, $options, true); 
     908    } 
    856909 
    857910    /** 
     
    860913     */ 
    861914    function execute_after_filters() { 
    862         if(count($this->after_filters) > 0) { 
     915     
     916        #if(isset($this->after_filter)) { 
     917            #$this->add_after_filter($this->after_filter); 
     918        #} 
     919        #error_log("after_filters:".print_r($this->after_filters, true)); 
     920        #error_log("after_filter_options:".print_r($this->after_filter_options, true));      
     921        $return = true; 
     922        if(count($this->after_filters) > 0) {  
     923            $action = $this->action ? $this->action : "index"; 
    863924            foreach($this->after_filters as $filter_function) { 
     925                if(array_key_exists($filter_function, $this->after_filter_options)) { 
     926                    if(is_array($options = $this->after_filter_options[$filter_function])) { 
     927                        if(array_key_exists('except', $options)) { 
     928                            if(preg_match("/\b$action\b/", $options['except'])) { 
     929                                #error_log("after filter except match: action:{$action} == ".$options['except']); 
     930                                continue;       
     931                            }                        
     932                        } 
     933                        if(array_key_exists('only', $options)) { 
     934                            if(!preg_match("/\b$action\b/", $options['only'])) { 
     935                                #error_log("after filter only non match: action:{$action} == ".$options['only']); 
     936                                continue;       
     937                            }                        
     938                        }                        
     939                    } 
     940                } 
    864941                if(method_exists($this, $filter_function)) { 
    865                     $this->$filter_function(); 
     942                    if(false === $this->$filter_function()) { 
     943                        //error_log("execute_after_filters(): returning false"); 
     944                        $return = false;     
     945                    } 
    866946                } 
    867947            } 
    868948        } 
    869     } 
    870  
     949        return $return; 
     950    } 
    871951 
    872952    /** 
     
    878958     *  @uses $after_filters 
    879959     */ 
    880     function add_after_filter($filter_function_name) { 
     960    function add_after_filter($filter_function_name, $options = array(), $prepend = false) { 
     961        //error_log("adding after filter: $filter_function_name"); 
    881962        if(is_string($filter_function_name) && !empty($filter_function_name)) { 
    882963            if(!in_array($filter_function_name, $this->after_filters)) { 
    883                 $this->after_filters[] = $filter_function_name; 
    884             } 
     964                if($prepend) { 
     965                    array_unshift($this->after_filters, $filter_function_name); 
     966                } else { 
     967                    array_push($this->after_filters, $filter_function_name); 
     968                } 
     969                if(count($options)) { 
     970                    if(count($this->after_filter_options[$filter_function_name])) { 
     971                        $this->after_filter_options[$filter_function_name] = array_merge($this->after_filter_options[$filter_function_name], $options); 
     972                    } else { 
     973                        $this->after_filter_options[$filter_function_name] = $options; 
     974                    }                                        
     975                } 
     976            }                         
    885977        } elseif(is_array($filter_function_name)) { 
    886             if(count($this->after_filters) > 0) { 
    887                 $this->after_filters = array_merge($this->after_filters, $filter_function_name); 
    888             } else { 
    889                 $this->after_filters = $filter_function_name; 
    890             } 
    891         } 
    892     } 
     978            foreach($filter_function_name as $filter_name => $options) { 
     979                if(!in_array($filter_name, $this->after_filters)) { 
     980                    if($prepend) { 
     981                        array_unshift($this->after_filters, $filter_name); 
     982                    } else { 
     983                        array_push($this->after_filters, $filter_name); 
     984                    }    
     985                    if(count($options)) { 
     986                        if(count($this->after_filter_options[$filter_name])) { 
     987                            $this->after_filter_options[$filter_name] = array_merge($this->after_filter_options[$filter_name], $options); 
     988                        } else { 
     989                            $this->after_filter_options[$filter_name] = $options; 
     990                        }                                        
     991                    } 
     992                }                
     993            } 
     994        } 
     995    } 
     996 
     997    function prepend_after_filter($filter_function_name, $options = array()) { 
     998        $this->add_after_filter($filter_function_name, $options, true); 
     999    } 
    8931000 
    8941001    /** 
  • trunk/trax/vendor/trax/action_view/helpers.php

    r280 r308  
    134134     */ 
    135135    protected function value() { 
    136         if (array_key_exists($this->object_name, $_REQUEST) 
     136        if (array_key_exists($this->object_name, (array)$_REQUEST) 
    137137            && array_key_exists($this->attribute_name, 
    138                                  $_REQUEST[$this->object_name])) { 
     138                                 (array)$_REQUEST[$this->object_name])) { 
    139139            $value = $_REQUEST[$this->object_name][$this->attribute_name]; 
    140140        } else { 
    141  
    142141            //  Attribute value not found in $_REQUEST.  Find the 
    143142            //  ActiveRecord subclass instance and query it. 
  • trunk/trax/vendor/trax/action_view/helpers/active_record_helper.php

    r277 r308  
    138138        $this->object_name = $object_name; 
    139139        $this->attribute_name = $attribute_name; 
    140         $object = $this->controller_object->$object_name; 
    141         if($errors = $object->errors[$attribute_name]) { 
     140        $object = $this->object($object_name); 
     141        if(is_object($object) && $errors = $object->errors_on($attribute_name)) { 
    142142            return $this->content_tag("div", $prepend_text . (is_array($errors) ? current($errors) : $errors) . $append_text, array('class' => $css_class)); 
    143143        } 
     
    164164        } 
    165165        $this->object_name = $object_name; 
    166         $object = $this->controller_object->$object_name; 
    167         if(!empty($object->errors)) { 
     166        $object = $this->object($object_name); 
     167        if(is_object($object) && $errors = $object->errors_full_messages()) { 
    168168            $id = isset($options['id']) ? $options['id'] : "ErrorExplanation"; 
    169169            $class = isset($options['class']) ? $options['class'] : "ErrorExplanation"; 
     
    173173            $header_sub_message = isset($options['header_sub_message']) ? 
    174174                $options['header_sub_message'] : "There were problems with the following fields:"; 
    175                 
     175                 
    176176            return $this->content_tag("div", 
    177177                $this->content_tag( 
    178178                    $header_tag, 
    179                     sprintf($header_message, Inflector::pluralize("error", count($object->errors)), Inflector::humanize($object_name)) 
     179                    sprintf($header_message, Inflector::pluralize("error", count($errors)), Inflector::humanize($object_name)) 
    180180                ) . 
    181181                $this->content_tag("p", $header_sub_message) . 
    182                 $this->content_tag("ul", array_reduce($object->errors, create_function('$v,$w', 'return ($v ? $v : "") . content_tag("li", $w);'), '')), 
     182                $this->content_tag("ul", array_reduce($errors, create_function('$v,$w', 'return ($v ? $v : "") . content_tag("li", $w);'), '')), 
    183183                array("id" => $id, "class" => $class) 
    184184            ); 
     
    482482     *  @todo Document this API 
    483483     */ 
    484     function pagination_limit_select($object_name_or_object, $default_text = "per page:") { 
     484    function pagination_limit_select($object_name_or_object, $options = array()) { 
    485485 
    486486        if(is_object($object_name_or_object)) { 
     
    495495 
    496496        if($object->pages > 0) { 
     497            $base_url = isset($options['base_url']) ? $options['base_url'] : ''; 
     498            $update = isset($options['update']) ? $options['update'] : ''; 
     499            $extra_params = isset($options['extra_params']) ? "&".$options['extra_params'] :  
     500                ($object->paging_extra_params ? "&".$object->paging_extra_params : ''); 
     501            $default_text = isset($options['default_text']) ? $options['default_text'] : "per page:"; 
     502            if($update && $base_url) { 
     503                $on_change = remote_function(array( 
     504                    "update" => $update,  
     505                    "url" => "{$base_url}?per_page=' + this.options[this.selectedIndex].value + '".escape_javascript($extra_params)."'" 
     506                )); 
     507            } else { 
     508                $on_change = "document.location = '{$base_url}?per_page=' + this.options[this.selectedIndex].value + '".escape_javascript($extra_params)."'";                 
     509            }            
    497510            $html .= " 
    498                 <select name=\"per_page\" onChange=\"document.location = '?".escape_javascript($object->paging_extra_params)."&per_page=' + this.options[this.selectedIndex].value;\"> 
     511                <select name=\"per_page\" onChange=\"{$on_change}\"> 
    499512                    <option value=\"$object->rows_per_page\" selected>$default_text</option> 
    500513                    <option value=10>10</option> 
     
    519532     *  @uses rows_per_page 
    520533     */ 
    521     function pagination_links($object_name_or_object) { 
     534    function pagination_links($object_name_or_object, $options = array()) { 
    522535         
    523536        if(is_object($object_name_or_object)) { 
     
    530543            return null;     
    531544        } 
     545 
     546        $first_text = isset($options['first_text']) ? $options['first_text'] : "<<"; 
     547        $last_text = isset($options['last_text']) ? $options['last_text'] : ">>"; 
     548        $prev_text = isset($options['prev_text']) ? $options['prev_text'] : "<"; 
     549        $next_text = isset($options['next_text']) ? $options['next_text'] : ">"; 
     550        $link_class = isset($options['link_class']) ? $options['link_class'] : "pagingLink"; 
     551        $selected_class = isset($options['selected_class']) ? $options['selected_class'] : "pagingSelected"; 
     552        $base_url = isset($options['base_url']) ? $options['base_url'] : ''; 
     553        $update = isset($options['update']) ? $options['update'] : ''; 
     554        $extra_params = isset($options['extra_params']) ? "&".$options['extra_params'] :  
     555            ($object->paging_extra_params ? "&".$object->paging_extra_params : '');  
     556         
     557        $first_width = "width:".(isset($options['first_width']) ? $options['first_width'] : '20')."px;"; # size in pixels 
     558        $first_width = (  
     559            (  isset($options['first_text']) &&  isset($options['first_width']) ) ||  
     560            ( !isset($options['first_text']) && !isset($options['first_width']) )   
     561        ) ? $first_width : ''; 
     562        $last_width = "width:".(isset($options['last_width']) ? $options['last_width'] : '20')."px;"; # size in pixels 
     563        $last_width = (  
     564            (  isset($options['last_text']) &&  isset($options['last_width']) ) ||  
     565            ( !isset($options['last_text']) && !isset($options['last_width']) )   
     566        ) ? $last_width : ''; 
     567        $prev_width = "width:".(isset($options['prev_width']) ? $options['prev_width'] : '10')."px;"; # size in pixels 
     568        $prev_width = (  
     569            (  isset($options['prev_text']) &&  isset($options['prev_width']) ) ||  
     570            ( !isset($options['prev_text']) && !isset($options['prev_width']) )   
     571        ) ? $prev_width : ''; 
     572        $next_width = "width:".(isset($options['next_width']) ? $options['next_width'] : '10')."px;"; # size in pixels 
     573        $next_width = (  
     574            (  isset($options['next_text']) &&  isset($options['next_width']) ) ||  
     575            ( !isset($options['next_text']) && !isset($options['next_width']) )   
     576        ) ? $next_width : ''; 
     577        $pages_width = isset($options['fixed_pages']) ? "width:".$options['fixed_pages']."px;" : ''; # size in pixels 
    532578            
    533         //$html  = "<pre>".print_r($object,1); 
     579 
     580        $html .= "<div class=\"pagingContaniner\" style=\"display:inline\">"; 
     581        $html .= "<div class=\"pagingFirst\" style=\"{$first_width}text-align:left;display:inline;float:left\">"; 
    534582        /* Print the first and previous page links if necessary */ 
    535         if(($object->page != 1) && ($object->page)) { 
    536             $html .= link_to("<<",  
    537                                   "?$object->paging_extra_params&page=1&per_page=$object->rows_per_page", 
    538                                   array( 
    539                                     "class" => "pageList", 
    540                                     "title" => "First page" 
    541                                   ))." "; 
    542         } 
    543         if(($object->page-1) > 0) { 
    544             $html .= link_to("<",  
    545                                   "?$object->paging_extra_params&page=".($object->page-1)."&per_page=$object->rows_per_page", 
    546                                   array( 
    547                                     "class" => "pageList", 
    548                                     "title" => "Previous Page"                                     
    549                                   )); 
    550         } 
    551          
     583        if(($object->page != 1) && ($object->page) && $first_text) { 
     584            if($update && $base_url) { 
     585                $html .= link_to_remote($first_text, array( 
     586                    "update" => $update,  
     587                    "url" => "{$base_url}?page=1&per_page={$object->rows_per_page}{$extra_params}" 
     588                ), array( 
     589                    "class" => $link_class, 
     590                    "title" => "First page"                 
     591                ))." "; 
     592            } else { 
     593                $html .= link_to($first_text, "{$base_url}?page=1&per_page={$object->rows_per_page}{$extra_params}", array( 
     594                    "class" => $link_class, 
     595                    "title" => "First page" 
     596                ))." ";                 
     597            } 
     598        } else { 
     599            $html .= "&nbsp;"; 
     600        } 
     601        $html .= "</div>"; 
     602        $html .= "<div class=\"pagingPrev\" style=\"{$prev_width}text-align:left;display:inline;float:left\">"; 
     603        if(($object->page-1) > 0 && $prev_text) { 
     604            if($update && $base_url) { 
     605                $html .= link_to_remote($prev_text, array( 
     606                    "update" => $update,  
     607                    "url" => "{$base_url}?page=".($object->page-1)."&per_page={$object->rows_per_page}{$extra_params}" 
     608                ), array( 
     609                    "class" => $link_class, 
     610                    "title" => "Previous page"                     
     611                )); 
     612            } else { 
     613                $html .= link_to($prev_text, "{$base_url}?page=".($object->page-1)."&per_page={$object->rows_per_page}{$extra_params}", array( 
     614                    "class" => $link_class, 
     615                    "title" => "Previous page" 
     616                ));                 
     617            }             
     618        } else { 
     619            $html .= "&nbsp;"; 
     620        } 
     621        $html .= "</div>"; 
    552622        if($object->pages < $object->display) { 
    553623            $object->display = $object->pages; 
     
    574644            $end = $object->pages; 
    575645        } 
    576                  
    577         /* Print the numeric page list; make the current page unlinked and bold */ 
     646         
     647        $html .= "<div class=\"pagingPages\" style=\"{$pages_width}text-align:center;display:inline;float:left;padding:0px 5px\">"; 
     648        # Print the numeric page list; make the current page unlinked and bold 
    578649        if($end != 1) { 
     650            $selected_class = $selected_class ? $link_class." ".$selected_class : $selected_class; 
    579651            for($i=$start; $i<=$end; $i++) { 
    580652                if($i == $object->page) { 
    581                     $html .= "<span class=\"pageList\"><b>".$i."</b></span>"; 
     653                    $html .= "<span class=\"{$selected_class}\">".$i."</span>"; 
    582654                } else { 
    583                     $html .= link_to($i, 
    584                                           "?$object->paging_extra_params&page=$i&per_page=$object->rows_per_page", 
    585                                           array( 
    586                                             "class" => "pageList", 
    587                                             "title" => "Page $i"                                            
    588                                           )); 
     655                    if($update && $base_url) { 
     656                        $html .= link_to_remote($i, array( 
     657                            "update" => $update,  
     658                            "url" => "{$base_url}?page={$i}&per_page={$object->rows_per_page}{$extra_params}" 
     659                        ), array( 
     660                            "class" => $link_class, 
     661                            "title" => "Page $i"                     
     662                        )); 
     663                    } else { 
     664                        $html .= link_to($i, "{$base_url}?page={$i}&per_page={$object->rows_per_page}{$extra_params}", array( 
     665                            "class" => $link_class, 
     666                            "title" => "Page $i" 
     667                        ));                 
     668                    }                     
    589669                } 
    590670                $html .= " "; 
    591671            } 
    592672        } 
    593  
    594         /* Print the Next and Last page links if necessary */ 
    595         if(($object->page+1) <= $object->pages) { 
    596             $html .= link_to(">", 
    597                                   "?$object->paging_extra_params&page=".($object->page+1)."&per_page=$object->rows_per_page", 
    598                                   array( 
    599                                     "class" => "pageList", 
    600                                     "title" => "Next Page"                                     
    601                                   )); 
    602         } 
    603         if(($object->page != $object->pages) && ($object->pages != 0)) { 
    604             $html .= link_to(">>", 
    605                                   "?$object->paging_extra_params&page=".$object->pages."&per_page=$object->rows_per_page", 
    606                                   array( 
    607                                     "class" => "pageList", 
    608                                     "title" => "Last Page"                                     
    609                                   )); 
    610         } 
    611         $html .= "\n"; 
     673        $html .= "</div>"; 
     674        $html .= "<div class=\"pagingNext\" style=\"{$next_width}text-align:right;display:inline;float:left\">"; 
     675        # Print the Next and Last page links if necessary 
     676        if(($object->page+1) <= $object->pages && $next_text) { 
     677            if($update && $base_url) { 
     678                $html .= link_to_remote($next_text, array( 
     679                    "update" => $update,  
     680                    "url" => "{$base_url}?page=".($object->page+1)."&per_page={$object->rows_per_page}{$extra_params}" 
     681                ), array( 
     682                    "class" => $link_class, 
     683                    "title" => "Next Page"                     
     684                )); 
     685            } else { 
     686                $html .= link_to($next_text, "{$base_url}?page=".($object->page+1)."&per_page={$object->rows_per_page}{$extra_params}", array( 
     687                    "class" => $link_class, 
     688                    "title" => "Next Page"                                     
     689                ));           
     690            }                    
     691        } else { 
     692            $html .= "&nbsp;"; 
     693        } 
     694        $html .= "</div>"; 
     695        $html .= "<div class=\"pagingLast\" style=\"{$last_width}text-align:right;display:inline;float:left\">"; 
     696        if(($object->page != $object->pages) && ($object->pages != 0) && $last_text) { 
     697            if($update && $base_url) { 
     698                $html .= link_to_remote($last_text, array( 
     699                    "update" => $update,  
     700                    "url" => "{$base_url}?page=".$object->pages."&per_page={$object->rows_per_page}{$extra_params}" 
     701                ), array( 
     702                    "class" => $link_class, 
     703                    "title" => "Last Page"                     
     704                )); 
     705            } else { 
     706                $html .= link_to($last_text, "{$base_url}?page=".$object->pages."&per_page={$object->rows_per_page}{$extra_params}", array( 
     707                    "class" => $link_class, 
     708                    "title" => "Last Page"                                     
     709                ));     
     710            }             
     711        } else { 
     712            $html .= "&nbsp;"; 
     713        } 
     714        $html .= "</div>"; 
     715        $html .= "</div>\n"; 
    612716 
    613717        return $html; 
  • trunk/trax/vendor/trax/action_view/helpers/form_helper.php

    r243 r308  
    131131     */ 
    132132    function add_default_name_and_id($options) {   
    133         $name_option_exists = array_key_exists('name', $options);    
    134         if(array_key_exists("index", $options)) { 
     133        $name_option_exists = array_key_exists('name', (array)$options);     
     134        if(array_key_exists("index", (array)$options)) { 
    135135            $options['name'] = $name_option_exists 
    136136                ? $options['name'] 
    137137                : $this->tag_name_with_index($options['index']); 
    138             $options['id'] = array_key_exists('id', $options) 
     138            $options['id'] = array_key_exists('id', (array)$options) 
    139139                ? $options['id'] 
    140140                : $this->tag_id_with_index($options['index']); 
     
    144144                ? $options['name'] 
    145145                : $this->tag_name_with_index($this->auto_index); 
    146             $options['id'] = array_key_exists('id', $options) 
     146            $options['id'] = array_key_exists('id', (array)$options) 
    147147                ? $options['id'] 
    148148                : $this->tag_id_with_index($this->auto_index); 
     
    151151                ? $options['name'] 
    152152                : $this->tag_name(); 
    153             $options['id'] = array_key_exists('id', $options) 
     153            $options['id'] = array_key_exists('id', (array)$options) 
    154154                ? $options['id'] 
    155155                : $this->tag_id(); 
    156156        } 
    157         if(array_key_exists('multiple', $options) && !$name_option_exists) { 
     157        if(array_key_exists('multiple', (array)$options) && !$name_option_exists) { 
    158158            $options['name'] .= "[]";            
    159159        } 
     
    181181     */ 
    182182    function to_input_field_tag($field_type, $options = array()) { 
    183         $default_size = array_key_exists("maxlength", $options) 
     183        $default_size = array_key_exists("maxlength", (array)$options) 
    184184            ? $options["maxlength"] : $this->default_field_options['size']; 
    185         $options["size"] = array_key_exists("size", $options) 
     185        $options["size"] = array_key_exists("size", (array)$options) 
    186186            ? $options["size"]: $default_size; 
    187         $options = array_merge($this->default_field_options, $options); 
     187        $options = array_merge($this->default_field_options, (array)$options); 
    188188        if($field_type == "hidden") { 
    189189            unset($options["size"]); 
     
    191191        $options["type"] = $field_type; 
    192192        if($field_type != "file") { 
    193             $options["value"] = array_key_exists("value", $options) 
     193            $options["value"] = array_key_exists("value", (array)$options) 
    194194                ? $options["value"] : $this->value(); 
    195195        } 
     
    198198                     $this->tag("input", $options), 
    199199                     @array_key_exists($this->attribute_name, 
    200                                       $this->object()->errors) 
     200                                      (array)$this->object()->errors) 
    201201                     ? true : false); 
    202202    } 
     
    226226     */ 
    227227    function to_text_area_tag($options = array()) { 
    228         if (array_key_exists("size", $options)) { 
     228        if (array_key_exists("size", (array)$options)) { 
    229229            $size = explode('x', $options["size"]); 
    230230            $options["cols"] = reset($size); 
     
    232232            unset($options["size"]); 
    233233        } 
    234         $options = array_merge($this->default_text_area_options, $options); 
     234        $options = array_merge($this->default_text_area_options, (array)$options); 
    235235        $options = $this->add_default_name_and_id($options); 
    236236        return $this->error_wrapping( 
     
    238238                              htmlspecialchars($this->value(), ENT_COMPAT), 
    239239                              $options), 
    240            array_key_exists($this->attribute_name,$this->object()->errors) 
     240           array_key_exists($this->attribute_name, (array)$this->object()->errors) 
    241241           ? $this->object()->errors[$this->attribute_name] : false); 
    242242    } 
  • trunk/trax/vendor/trax/action_view/helpers/form_options_helper.php

    r269 r308  
    226226                                      $html_options) { 
    227227        $html_options = $this->add_default_name_and_id($html_options); 
    228         $value = $this->value(); 
     228        $value = isset($options['selected']) ? $options['selected'] : $this->value(); 
    229229        return $this->error_wrapping( 
    230230            $this->content_tag( 
  • trunk/trax/vendor/trax/action_view/helpers/javascript_helper.php

    r282 r308  
    516516            $options['with'] = "Sortable.serialize('{$element_id}')"; 
    517517        } 
    518         if(!$options['onUpdate']) { 
    519             $options['onUpdate'] = "function(){" . $this->remote_function($options) . "}"; 
     518        if(!$options['onDrop']) { 
     519            $options['onDrop'] = "function(){" . $this->remote_function($options) . "}"; 
    520520        } 
    521521        $options = $this->remove_ajax_options($options); 
  • trunk/trax/vendor/trax/active_record.php

    r307 r308  
    147147     
    148148    /** 
    149      *  Index into the $active_connections array 
     149     *  Index into the $connection_pool array 
    150150     * 
    151151     *  Name of the index to use to return or set the current db connection 
     
    156156    public $connection_name = null; 
    157157 
     158    /** 
     159     *  Index into the $connection_pool_read_only array 
     160     * 
     161     *  Name of the index to use to return or set the current db connection 
     162     *  Mainly used if you want to force all reads(SELECT's) to goto a 
     163     *  specific database server. 
     164     *  @var string 
     165     */     
     166    public $read_only_connection_name = null; 
     167 
     168    /** 
     169     *  Index into the $connection_pool_read_only array 
     170     * 
     171     *  Same as $read_only_connection_name but set for all models globally. 
     172     *  @var string 
     173     */     
     174    public static $global_read_only_connection_name = null; 
     175 
    158176    /** 
    159177     * What environment to run in. 
     
    167185     
    168186    /** 
    169      * Stores the active connections. Indexed on $connection_name. 
     187     * Stores the active read/write connections. Indexed on $connection_name. 
    170188     */ 
    171     public static $active_connections = array(); 
     189    public static $connection_pool = array(); 
     190 
     191    /** 
     192     * Stores the active read only connections. Indexed on $connection_name. 
     193     */  
     194    public static $connection_pool_read_only = array(); 
    172195 
    173196    /** 
     
    344367     *  @var integer 
    345368     */ 
    346     public $rows_per_page_default = 20; 
     369    public static $rows_per_page_default = 20; 
    347370 
    348371    /** 
     
    355378     */     
    356379    public $pagination_count = 0; 
     380 
     381    /** 
     382     *  @todo Document this variable 
     383     */ 
     384    public $page = 0; 
     385 
     386    /** 
     387     * Sets the default options for the model. 
     388     * 
     389     * class Person extends ActiveRecord { 
     390     *     public $default_scope = array( 
     391     *         'order' => 'last_name, first_name' 
     392     *     )); 
     393     * }  
     394     * 
     395     */      
     396    public $default_scope = array(); 
     397     
     398    /** 
     399     * Adds a class method for retrieving and querying objects.  
     400     * A scope represents a narrowing of a database query, such as  
     401     * 'conditions' => "first_name = 'John'" 
     402     * 
     403     * class Person extends ActiveRecord { 
     404     *     public $named_scope = array( 
     405     *         'people_named_john' => array( 
     406     *             'conditions' => "first_name = 'John'",      
     407     *             'order' => 'last_name, first_name' 
     408     *     )); 
     409     * }  
     410     * 
     411     * $person = new Person; 
     412     * $person->people_named_john; # an array of AR objects people first_name = 'John' 
     413     * 
     414     */ 
     415    public $named_scope = array(); 
     416     
    357417 
    358418    /** 
     
    430490     *  This is for transactions only to let query() know that a 'BEGIN' has been executed 
    431491     */ 
    432     private static $begin_executed = false; 
     492    private static $in_transaction = false; 
    433493 
    434494    /** 
     
    436496     *  This will issue a rollback command if any sql fails. 
    437497     */ 
    438     public static $use_transactions = false;  
     498    public static $auto_rollback = false;  
    439499     
    440500    /** 
     
    460520     */ 
    461521    function __construct($attributes = null) {  
    462         # Open the database connection 
    463         $this->establish_connection(); 
     522        # Open the database connection for reads / writes 
     523        self::$db = $this->establish_connection(); 
     524        if($this->read_only_connection_name) { 
     525            # Open database connection for all reads 
     526            $this->establish_connection($this->read_only_connection_name, true); 
     527        } elseif(self::$global_read_only_connection_name) { 
     528            # Open database connection for all reads 
     529            $this->establish_connection(self::$global_read_only_connection_name, true);             
     530        } 
    464531 
    465532        # Set $table_name 
     
    522589                    break;             
    523590            }         
     591        } elseif(array_key_exists($key, $this->named_scope) && is_array($this->named_scope[$key])) { 
     592            $this->$key = $this->find_all($this->named_scope[$key]); 
    524593        } elseif($this->is_composite($key)) {             
    525594            $composite_object = $this->get_composite_object($key); 
     
    598667            switch($association_type) { 
    599668                case "has_many": 
     669                    $parameters = is_array($this->has_many) && @array_key_exists($method_name, $this->has_many) ?  
     670                        array_merge($this->has_many[$method_name], $parameters) : $parameters; 
    600671                    $result = $this->find_all_has_many($method_name, $parameters); 
    601672                    break; 
    602673                case "has_one": 
     674                    $parameters = is_array($this->has_one) && @array_key_exists($method_name, $this->has_one) ?  
     675                        array_merge($this->has_one[$method_name], $parameters) : $parameters; 
    603676                    $result = $this->find_one_has_one($method_name, $parameters); 
    604677                    break; 
    605678                case "belongs_to": 
     679                    $parameters = is_array($this->belongs_to) && @array_key_exists($method_name, $this->belongs_to) ?  
     680                        array_merge($this->belongs_to[$method_name], $parameters) : $parameters; 
    606681                    $result = $this->find_one_belongs_to($method_name, $parameters); 
    607682                    break; 
    608683                case "has_and_belongs_to_many":   
     684                    $parameters = is_array($this->has_and_belongs_to_many) && @array_key_exists($method_name, $this->has_and_belongs_to_many) ?  
     685                        array_merge($this->has_and_belongs_to_many[$method_name], $parameters) : $parameters; 
    609686                    $result = $this->find_all_habtm($method_name, $parameters);  
    610687                    break;             
     
    649726     */ 
    650727    private function find_all_habtm($other_table_name, $parameters = null) { 
    651         $additional_conditions = null; 
     728        $additional_conditions = $additional_joins = null; 
     729        $options = array(); 
    652730        # Use any passed-in parameters 
    653         if(!is_null($parameters)) { 
     731        if(!is_null($parameters)) {   
    654732            if(@array_key_exists("conditions", $parameters)) { 
    655733                $additional_conditions = " AND (".$parameters['conditions'].")"; 
     
    658736            } 
    659737            if(@array_key_exists("order", $parameters)) { 
    660                 $order = $parameters['order']; 
     738                $options['order'] = $parameters['order']; 
    661739            } elseif($parameters[1] != "") { 
    662                 $order = $parameters[1]; 
     740                $options['order'] = $parameters[1]; 
    663741            } 
    664742            if(@array_key_exists("limit", $parameters)) { 
    665                 $limit = $parameters['limit']; 
     743                $options['limit'] = $parameters['limit']; 
    666744            } elseif($parameters[2] != "") { 
    667                 $limit = $parameters[2]; 
    668             }     
     745                $options['limit'] = $parameters[2]; 
     746            } 
     747            if(@array_key_exists("joins", $parameters)) { 
     748                $additional_joins = $parameters['joins']; 
     749            } elseif($parameters[3] != "") { 
     750                $additional_joins = $parameters[3]; 
     751            } 
     752            if(@array_key_exists("page", $parameters)) { 
     753                $options['page'] = $parameters['page']; 
     754            } 
     755            if(@array_key_exists("per_page", $parameters)) { 
     756                $options['per_page'] = $parameters['per_page']; 
     757            } 
    669758            if(@array_key_exists("class_name", $parameters)) { 
    670759                $other_object_name = $parameters['class_name']; 
     
    697786        if(!is_null($finder_sql)) { 
    698787            $conditions = $finder_sql;     
    699             $order = null; 
    700             $limit = null; 
    701             $joins = null; 
    702788        } else { 
    703789            # Prepare the join table name primary keys (fields) to do the join on 
     
    729815            } 
    730816 
     817            if($this->habtm_sort_field) { 
     818                $options['order'] = (isset($options['order']) ? $options['order'].',':'')."{$join_table}.{$this->habtm_sort_field}"; 
     819            }  
     820             
    731821            # Set up the SQL segments 
    732822            $conditions = "{$join_table}.{$this_foreign_key} = {$this_primary_key_value}".$additional_conditions; 
    733             $joins = "LEFT JOIN {$join_table} ON {$other_table_name}.{$other_primary_key} = {$join_table}.{$other_foreign_key}"; 
    734         } 
     823            $options['joins'] = "LEFT JOIN {$join_table} ON {$other_table_name}.{$other_primary_key} = {$join_table}.{$other_foreign_key}".$additional_joins; 
     824        } 
     825        $options['conditions'] = $conditions; 
    735826         
    736827        # Get the list of other_class_name objects 
    737         return $other_class_object->find_all($conditions, $order, $limit, $joins); 
     828        return $other_class_object->find_all($options); 
    738829    } 
    739830 
     
    747838     */ 
    748839    private function find_all_has_many($other_table_name, $parameters = null) { 
    749         $additional_conditions = null; 
     840        $additional_conditions = $order = $limit = null; 
    750841        # Use any passed-in parameters 
    751842        if(is_array($parameters)) { 
     
    756847            } 
    757848            if(@array_key_exists("order", $parameters)) { 
    758                 $order = $parameters['order']; 
     849                $options['order'] = $parameters['order']; 
    759850            } elseif($parameters[1] != "") { 
    760                 $order = $parameters[1]; 
     851                $options['order'] = $parameters[1]; 
    761852            } 
    762853            if(@array_key_exists("limit", $parameters)) { 
    763                 $limit = $parameters['limit']; 
     854                $options['limit'] = $parameters['limit']; 
    764855            } elseif($parameters[2] != "") { 
    765                 $limit = $parameters[2]; 
    766             } 
     856                $options['limit'] = $parameters[2]; 
     857            } 
     858            if(@array_key_exists("joins", $parameters)) { 
     859                $options['joins'] = $parameters['joins']; 
     860            } elseif($parameters[3] != "") { 
     861                $options['joins'] = $parameters[3]; 
     862            } 
     863            if(@array_key_exists("page", $parameters)) { 
     864                $options['page'] = $parameters['page']; 
     865            } 
     866            if(@array_key_exists("per_page", $parameters)) { 
     867                $options['per_page'] = $parameters['per_page']; 
     868            } 
    767869            if(@array_key_exists("foreign_key", $parameters)) { 
    768870                $foreign_key = $parameters['foreign_key']; 
     
    773875            if(@array_key_exists("finder_sql", $parameters)) { 
    774876                $finder_sql = $parameters['finder_sql']; 
    775             } 
     877            }            
    776878        } 
    777879 
     
    788890        if(!is_null($finder_sql)) { 
    789891            $conditions = $finder_sql;   
    790             $order = null; 
    791             $limit = null; 
    792             $joins = null;  
    793892        } else {           
    794893            # This class primary key 
     
    813912            $conditions .= $additional_conditions;  
    814913        } 
    815                           
     914        $options['conditions'] = $conditions; 
     915        #error_log("has_many:".print_r($options, true)); 
    816916        # Get the list of other_class_name objects 
    817         return $other_class_object->find_all($conditions, $order, $limit, $joins); 
     917        return $other_class_object->find_all($options); 
    818918    } 
    819919 
     
    857957        $this_primary_key = $this->primary_keys[0]; 
    858958         
    859         if(!$foreign_key){ 
     959        if(!$foreign_key) { 
    860960            $foreign_key = Inflector::singularize($this->table_name)."_".$this_primary_key; 
    861961        } 
     
    9791079 
    9801080        # echo "$aggregate_type sql:$sql<br>"; 
    981         if($this->is_error($rs = $this->query($sql))) { 
     1081        //print_r($parameters[0]); 
     1082        //echo $sql; 
     1083        if($this->is_error($rs = $this->query($sql, true))) { 
    9821084            $this->raise($rs->getMessage()); 
    9831085        } else { 
     
    10781180        if($this->column_attribute_exists($column) && ($conditions = $this->get_primary_key_conditions())) { 
    10791181            # Run the query to grab a specific columns value. 
    1080             $sql = "SELECT {$column} FROM {$this->table_prefix}{$this->table_name} WHERE {$conditions}"; 
     1182            $sql = "SELECT {$column} FROM {$this->table_prefix}{$this->table_name} WHERE {$conditions} LIMIT 1"; 
    10811183            $this->log_query($sql); 
    1082             $result = self::$db->queryOne($sql); 
     1184            $db = $this->get_connection(true); 
     1185            $result = $db->queryOne($sql); 
    10831186            if($this->is_error($result)) { 
    10841187                $this->raise($result->getMessage()); 
     
    10941197     *  @todo Document this API 
    10951198     */ 
    1096     function begin() { 
    1097         self::$db->query("BEGIN"); 
    1098         $this->begin_executed = true; 
     1199    function begin($save_point = null) { 
     1200        # check if transaction are supported by this driver 
     1201        if(self::$db->supports('transactions')) {         
     1202            $rs = self::$db->beginTransaction(); 
     1203            if($this->is_error($rs)) { 
     1204                $this->raise($rs->getMessage()); 
     1205            }       
     1206            self::$in_transaction = true; 
     1207        } 
     1208    } 
     1209 
     1210    /** 
     1211     * Only used if you want to do transactions and your db supports transactions 
     1212     * 
     1213     *  @uses $db 
     1214     *  @todo Document this API 
     1215     */     
     1216    function save_point($save_point) { 
     1217        if(!is_null($save_point)) { 
     1218            # check if transaction are supported by this driver 
     1219            if(self::$db->supports('transactions')) {             
     1220                # check if we are inside a transaction and if savepoints are supported 
     1221                if(self::$db->inTransaction() && self::$db->supports('savepoints')) { 
     1222                    # Set a savepoint 
     1223                    $rs = self::$db->beginTransaction($save_point);  
     1224                    if($this->is_error($rs)) { 
     1225                        $this->raise($rs->getMessage()); 
     1226                    }                 
     1227                }  
     1228            }           
     1229        }         
    10991230    } 
    11001231 
     
    11051236     *  @todo Document this API 
    11061237     */ 
    1107     function commit() { 
    1108         self::$db->query("COMMIT");  
    1109         $this->begin_executed = false; 
     1238    function commit() {       
     1239        # check if transaction are supported by this driver 
     1240        if(self::$db->supports('transactions')) { 
     1241            # check if we are inside a transaction 
     1242            if(self::$db->inTransaction()) { 
     1243                $rs = self::$db->commit();  
     1244                if($this->is_error($rs)) { 
     1245                    $this->raise($rs->getMessage()); 
     1246                }         
     1247                self::$in_transaction = false; 
     1248            } 
     1249        } 
    11101250    } 
    11111251 
     
    11151255     *  @uses $db 
    11161256     *  @todo Document this API 
    1117      */ 
     1257     */     
    11181258    function rollback() { 
    1119         self::$db->query("ROLLBACK"); 
     1259        # check if transaction are supported by this driver 
     1260        if(self::$db->supports('transactions')) { 
     1261            $rs = self::$db->rollback();  
     1262            if($this->is_error($rs)) { 
     1263                $this->raise($rs->getMessage()); 
     1264            } 
     1265            self::$in_transaction = false; 
     1266        }                
    11201267    } 
    11211268 
     
    11311278     *  @throws {@link ActiveRecordError} 
    11321279     */ 
    1133     function query($sql) { 
     1280    function query($sql, $read_only = false) { 
    11341281        # Run the query 
    11351282        $this->log_query($sql); 
    1136         $rs =& self::$db->query($sql); 
     1283        $db = $this->get_connection($read_only); 
     1284        $rs =& $db->query($sql); 
    11371285        if ($this->is_error($rs)) { 
    1138             if(self::$use_transactions && self::$begin_executed) { 
     1286            if(self::$auto_rollback && self::$in_transaction) { 
    11391287                $this->rollback(); 
    11401288            } 
     
    12411389         
    12421390        $offset = null; 
     1391        $page = null; 
    12431392        $per_page = null; 
    12441393        $select = null; 
     1394        $paginate = false; 
    12451395 
    12461396        # this is if they passed in an associative array to emulate 
     
    12801430            # If conditions specified, include them 
    12811431            if(!is_null($conditions)) { 
     1432                if(array_key_exists('conditions', $this->default_scope)  
     1433                   && !is_null($this->default_scope['conditions'])) { 
     1434                    $conditions = " ({$conditions}) AND (".$this->default_scope['conditions'].") "; 
     1435                } 
    12821436                $sql .= "WHERE $conditions "; 
     1437            } elseif(array_key_exists('conditions', $this->default_scope)  
     1438                     && !is_null($this->default_scope['conditions'])) { 
     1439                $sql .= "WHERE ".$this->default_scope['conditions']." "; 
    12831440            } 
    12841441 
    12851442            # If ordering specified, include it 
    12861443            if(!is_null($order)) { 
     1444                if(array_key_exists('order', $this->default_scope)  
     1445                   && !is_null($this->default_scope['order'])) { 
     1446                    $order = " {$order},".$this->default_scope['order']." "; 
     1447                }                 
    12871448                $sql .= "ORDER BY $order "; 
     1449            } elseif(array_key_exists('order', $this->default_scope)  
     1450                     && !is_null($this->default_scope['order'])) { 
     1451                $sql .= "ORDER BY ".$this->default_scope['order']." "; 
    12881452            } 
    12891453 
    12901454            # Is output to be generated in pages? 
    1291             if(is_numeric($limit) || is_numeric($offset) || is_numeric($per_page)) { 
     1455            if(is_numeric($limit) || is_numeric($offset) || is_numeric($per_page) || is_numeric($page)) { 
     1456                #error_log("limit:$limit offset:$offset per_page:$per_page page:$page"); 
    12921457 
    12931458                if(is_numeric($limit)) {     
    1294                     $this->rows_per_page = $limit;         
     1459                    $this->rows_per_page = (int)$limit;         
    12951460                } 
    12961461                if(is_numeric($per_page)) { 
    1297                     $this->rows_per_page = $per_page;             
     1462                    $this->rows_per_page = (int)$per_page;  
     1463                    $paginate = true; 
    12981464                } 
    12991465                # Default for rows_per_page: 
    13001466                if ($this->rows_per_page <= 0) { 
    1301                     $this->rows_per_page = $this->rows_per_page_default; 
     1467                    $this->rows_per_page = (int)self::$rows_per_page_default; 
    13021468                } 
    13031469                 
    13041470                # Only use request's page if you are calling from find_all_with_pagination() and if it is int 
    1305                 if(strval(intval($_REQUEST['page'])) == $_REQUEST['page']) { 
    1306                     $this->page = $_REQUEST['page']; 
     1471                #if(isset($_REQUEST['page']) && strval(intval($_REQUEST['page'])) == $_REQUEST['page']) { 
     1472                    #$this->page = $_REQUEST['page']; 
     1473                #} 
     1474                if(!is_null($page)) { 
     1475                    $this->page = (int)$page; 
     1476                    $paginate = true; 
    13071477                } 
    13081478                 
     
    13191489                # $sql .= "LIMIT $offset, $this->rows_per_page"; 
    13201490                 
    1321                 # Set number of total pages in result set 
    1322                 if($count = $this->count_all($this->primary_keys[0], $conditions, $joins)) { 
    1323                     $this->pagination_count = $count; 
    1324                     $this->pages = (($count % $this->rows_per_page) == 0) 
    1325                         ? $count / $this->rows_per_page 
    1326                         : floor($count / $this->rows_per_page) + 1;  
     1491                if($paginate) { 
     1492                    #error_log("I am going to paginate."); 
     1493                    # Set number of total pages in result set 
     1494                    if($count = $this->count_all($this->primary_keys[0], $conditions, $joins)) { 
     1495                        $this->pagination_count = $count; 
     1496                        $this->pages = (($count % $this->rows_per_page) == 0) 
     1497                            ? $count / $this->rows_per_page 
     1498                            : floor($count / $this->rows_per_page) + 1;  
     1499                    } 
    13271500                } 
    13281501            } 
     
    13311504        return $sql; 
    13321505    } 
     1506     
     1507    /** 
     1508     *  Returns same as find_all 
     1509     * 
     1510     */ 
     1511    function paginate($page = 1, $per_page = 0, $options = array()) { 
     1512        if(is_array($page)) { 
     1513            $options = $page; 
     1514        } else { 
     1515            $options['page'] = (int)($page > 0 ? $page : 1); 
     1516            $options['per_page'] = (int)($per_page > 0 ? $per_page : self::$rows_per_page_default); 
     1517        } 
     1518        $options['paginate'] = true; 
     1519        return $this->find_all($options); 
     1520    }    
    13331521 
    13341522    /** 
     
    13721560        # echo "query: $sql\n"; 
    13731561        # error_log("ActiveRecord::find_all -> $sql"); 
    1374         if($this->is_error($rs = $this->query($sql))) { 
     1562        if($this->is_error($rs = $this->query($sql, true))) { 
    13751563            $this->raise($rs->getMessage()); 
    13761564        } 
    13771565 
    13781566        $objects = array(); 
    1379         while($row = $rs->fetchRow()) { 
    1380             $class_name = $this->get_class_name(); 
     1567        $class_name = $this->get_class_name(); 
     1568        while($row = $rs->fetchRow()) {     
    13811569            $object = new $class_name(); 
    13821570            $object->new_record = false; 
     
    13861574                if($field == $this->index_on) { 
    13871575                    $objects_key = $value; 
    1388                 }  
    1389             } 
    1390             if(is_null($objects_key)) { 
    1391                 $objects[] = $object; 
     1576                } 
     1577            } 
     1578            if(is_null($objects_key)) { 
     1579                $objects[] = $object; 
    13921580            } else { 
    1393                 $objects[$objects_key] = $object; 
     1581                $objects[$objects_key] = $object;    
    13941582            } 
    13951583            # If callback is defined in model run it. 
     
    17111899         
    17121900        if($this->is_error($result)) { 
    1713             $this->raise($results->getMessage()); 
     1901            $this->raise($result->getMessage()); 
    17141902        } else { 
    17151903            $habtm_result = true; 
     
    17621950        $result = $this->query($sql); 
    17631951        if($this->is_error($result)) { 
    1764             $this->raise($results->getMessage()); 
     1952            $this->raise($result->getMessage()); 
    17651953        } else { 
    17661954            $habtm_result = true; 
     
    19462134 
    19472135        if(is_null($conditions)) { 
    1948             $this->errors[] = "No conditions specified to delete on."; 
     2136            $this->add_error("No conditions specified to delete on."); 
    19492137            return false; 
    19502138        } 
    19512139 
    1952         $this->before_delete();  
    1953         if($result = $this->delete_all($conditions)) { 
    1954             foreach($deleted_ids as $id) { 
    1955                 if($this->auto_delete_habtm && $id != '') { 
    1956                     if(is_string($this->has_and_belongs_to_many)) { 
    1957                         $habtms = explode(",", $this->has_and_belongs_to_many); 
    1958                         foreach($habtms as $other_table_name) { 
    1959                             $this->delete_all_habtm_records(trim($other_table_name), $id);                              
    1960                         } 
    1961                     } elseif(is_array($this->has_and_belongs_to_many)) { 
    1962                         foreach($this->has_and_belongs_to_many as $other_table_name => $values) { 
    1963                             $this->delete_all_habtm_records($other_table_name, $id);                              
    1964                         } 
    1965                     }  
     2140        if($this->before_delete()) { 
     2141            if($result = $this->delete_all($conditions)) { 
     2142                foreach($deleted_ids as $id) { 
     2143                    if($this->auto_delete_habtm && $id != '') { 
     2144                        if(is_string($this->has_and_belongs_to_many)) { 
     2145                            $habtms = explode(",", $this->has_and_belongs_to_many); 
     2146                            foreach($habtms as $other_table_name) { 
     2147                                $this->delete_all_habtm_records(trim($other_table_name), $id);                              
     2148                            } 
     2149                        } elseif(is_array($this->has_and_belongs_to_many)) { 
     2150                            foreach($this->has_and_belongs_to_many as $other_table_name => $values) { 
     2151                                $this->delete_all_habtm_records($other_table_name, $id);                              
     2152                            } 
     2153                        }  
     2154                    } 
    19662155                } 
    1967             } 
    1968             $this->after_delete(); 
    1969         } 
    1970          
     2156                $this->after_delete(); 
     2157            }             
     2158        }         
    19712159        return $result; 
    19722160    } 
     
    19912179    function delete_all($conditions = null) { 
    19922180        if(is_null($conditions)) { 
    1993             $this->errors[] = "No conditions specified to delete on."; 
     2181            $this->add_error("No conditions specified to delete on."); 
    19942182            return false; 
    19952183        } 
     
    20462234            if($this->delete_habtm_records($this_foreign_value)) { 
    20472235                reset($this->habtm_attributes); 
     2236                if($this->habtm_sort_field) { 
     2237                    $sort_field = $this->habtm_sort_field; 
     2238                    $sort_value = 0; 
     2239                } 
    20482240                foreach($this->habtm_attributes as $other_table_name => $other_foreign_values) { 
    20492241                    $table_name = $this->get_join_table_name($this->table_name,$other_table_name); 
     
    20542246                        $attributes[$this_foreign_key] = $this_foreign_value; 
    20552247                        $attributes[$other_foreign_key] = $other_foreign_value; 
     2248                        if($sort_field) { 
     2249                            $attributes[$sort_field] = $sort_value; 
     2250                            $sort_value++; 
     2251                        } 
    20562252                        $attributes = $this->quoted_attributes($attributes); 
    20572253                        $fields = @implode(', ', array_keys($attributes)); 
    20582254                        $values = @implode(', ', array_values($attributes)); 
    20592255                        $sql = "INSERT INTO $table_name ($fields) VALUES ($values)"; 
    2060                         //echo "add_habtm_records: SQL: $sql<br>"; 
     2256                        error_log("add_habtm_records: SQL: $sql"); 
    20612257                        $result = $this->query($sql); 
    20622258                        if ($this->is_error($result)) { 
     
    21932389                } 
    21942390            } 
    2195      
     2391 
    21962392            //  If any date/time fields were found, assign the 
    21972393            //  accumulated values to corresponding attributes 
     2394            //  1i = Year, 2i = Month, 3i = Day, 4i = Hour, 5i = Minute 
    21982395            if(count($datetime_fields)) { 
    21992396                foreach($datetime_fields as $datetime_field) { 
    22002397                    $datetime_format = ''; 
    22012398                    $datetime_value = ''; 
     2399                    # Date Year / Month / Day 
    22022400                    if($attributes[$datetime_field."(1i)"] 
    22032401                        && $attributes[$datetime_field."(2i)"] 
     
    22072405                        . "-" . $attributes[$datetime_field."(3i)"]; 
    22082406                        $datetime_format = $this->date_format; 
    2209                     } 
     2407                    }  
     2408                    # for expiration dates Year & Month 
     2409                    elseif($attributes[$datetime_field."(1i)"] 
     2410                             && $attributes[$datetime_field."(2i)"]) { 
     2411                        $datetime_value = $attributes[$datetime_field."(1i)"] 
     2412                        . "-" . $attributes[$datetime_field."(2i)"];     
     2413                        $datetime_format = $this->date_format;                   
     2414                    } 
    22102415                    $datetime_value .= " "; 
     2416                    # Time Hour & Minutes 
    22112417                    if($attributes[$datetime_field."(4i)"] 
    22122418                        && $attributes[$datetime_field."(5i)"]) { 
     
    24052611    } 
    24062612 
     2613    function human_attribute_name($attribute) { 
     2614        return Inflector::humanize($attribute); 
     2615    } 
     2616 
    24072617    /** 
    24082618     *  Set {@link $table_name} from the class name of this object 
     
    24392649     *  @uses $db 
    24402650     *  @uses $content_columns 
    2441      *  @uses Inflector::humanize() 
     2651     *  @uses human_attribute_name() 
    24422652     *  @see __set() 
    24432653     *  @param string $table_name  Name of table to get information about 
     
    24582668                $i = 0; 
    24592669                foreach($this->content_columns as $column) { 
    2460                     $this->content_columns[$i++]['human_name'] = Inflector::humanize($column['name']); 
     2670                    $this->content_columns[$i++]['human_name'] = $this->human_attribute_name($column['name']); 
    24612671                }                 
    24622672                self::$table_info[$table_name] = $this->content_columns; 
     
    24962706     *   
    24972707     *  If there is a connection now open, as indicated by the saved 
    2498      *  value of a MDB2 object in $active_connections[$connection_name], and 
     2708     *  value of a MDB2 object in $connection_pool[$connection_name], and 
    24992709     *  {@link force_reconnect} is not true, then set the database 
    25002710     *  fetch mode and return. 
    25012711     * 
    25022712     *  If there is no connection, open one and save a reference to 
    2503      *  it in $active_connections[$connection_name]. 
     2713     *  it in $connection_pool[$connection_name]. 
    25042714     * 
    25052715     *  @uses $db 
    25062716     *  @uses $database_name 
    25072717     *  @uses $force_reconnect 
    2508      *  @uses $active_connections 
     2718     *  @uses $connection_pool 
    25092719     *  @uses is_error() 
    25102720     *  @throws {@link ActiveRecordError} 
    25112721     */ 
    2512     function establish_connection() { 
    2513         $this->set_connection_name(); 
    2514         $connection =& self::$active_connections[$this->connection_name]; 
     2722    function establish_connection($connection_name = null, $read_only = false) { 
     2723        $connection_name = $this->get_connection_name($connection_name); 
     2724        if($read_only) {  
     2725            $connection =& self::$connection_pool_read_only[$connection_name]; 
     2726        } else { 
     2727            $connection =& self::$connection_pool[$connection_name]; 
     2728        } 
    25152729        if(!is_object($connection) || $this->force_reconnect) { 
    25162730            $connection_settings = array(); 
    25172731            $connection_options = array(); 
    2518             if(array_key_exists($this->connection_name, self::$database_settings)) { 
     2732            if(array_key_exists($connection_name, self::$database_settings)) { 
    25192733                 # Use a different custom sections settings ? 
    2520                 if(array_key_exists("use", self::$database_settings[$this->connection_name])) { 
    2521                     $connection_settings = self::$database_settings[self::$database_settings[$this->connection_name]['use']]; 
     2734                if(array_key_exists("use", self::$database_settings[$connection_name])) { 
     2735                    $connection_settings = self::$database_settings[self::$database_settings[$connection_name]['use']]; 
    25222736                } else { 
    25232737                    # Custom defined db settings in database.ini  
    2524                     $connection_settings = self::$database_settings[$this->connection_name]; 
     2738                    $connection_settings = self::$database_settings[$connection_name]; 
    25252739                } 
    25262740            } else { 
    25272741                # Just use the current environment's db settings 
    2528                 # $this->connection_name's default value is 'development' so 
    2529                 # if should never really get here unless you override $this->connection_name 
     2742                # $connection_name's default value is 'development' so 
     2743                # it should never really get here unless you override $this->connection_name 
    25302744                # and you define a custom db section in database.ini and it can't find it. 
    2531                 $connection_settings = self::$database_settings[$this->connection_name]; 
     2745                $connection_settings = self::$database_settings[$connection_name]; 
    25322746            } 
    25332747            # Override database name if param is set 
     
    25412755            # Connect to the database and throw an error if the connect fails. 
    25422756            $connection =& MDB2::Connect($connection_settings, $connection_options); 
    2543             //static $connect_cnt;  $connect_cnt++; error_log("connection #".$connect_cnt); 
     2757            #static $connect_cnt;  $connect_cnt++; error_log("establish_connection($connection_name, $read_only) #".$connect_cnt); 
    25442758             
    25452759            # For Postgres schemas (http://www.postgresql.org/docs/8.0/interactive/ddl-schemas.html) 
     
    25532767        } 
    25542768        if(!$this->is_error($connection)) { 
    2555             self::$active_connections[$this->connection_name] =& $connection; 
    2556             self::$db =& $connection; 
    2557             self::$db->setFetchMode($this->fetch_mode); 
     2769            $connection->setFetchMode($this->fetch_mode); 
     2770            if($read_only) { 
     2771                self::$connection_pool_read_only[$connection_name] =& $connection; 
     2772                $this->read_only_connection_name = $connection_name; 
     2773            } else { 
     2774                self::$connection_pool[$connection_name] =& $connection; 
     2775                $this->connection_name = $connection_name; 
     2776            } 
    25582777        } else { 
    25592778            $this->raise($connection->getMessage()); 
    25602779        }       
    2561         return self::$db; 
     2780        return $connection; 
    25622781    } 
    25632782 
     
    25652784     *  Set the name of the database connection to use.  
    25662785     */     
    2567     function set_connection_name() { 
    2568         $connection_name = null; 
    2569         if(!is_null($this->connection_name)) { 
    2570             $connection_name = $this->connection_name;       
    2571         } else { 
    2572             $connection_name = self::$environment ? self::$environment : 'development'; 
    2573         }   
    2574         $this->connection_name = $connection_name; 
     2786    function get_connection_name($connection_name = null) { 
     2787        if(is_null($connection_name)) { 
     2788            if(!is_null($this->connection_name)) { 
     2789                $connection_name = $this->connection_name;       
     2790            } else { 
     2791                $connection_name = self::$environment ? self::$environment : 'development'; 
     2792            }  
     2793        } 
     2794        return $connection_name;  
     2795    } 
     2796    /** 
     2797     *  Gets the database connection whether its read only or read/write     
     2798     */     
     2799    function get_connection($read_only = false) { 
     2800        if($read_only && $this->read_only_connection_name &&  
     2801           array_key_exists($this->read_only_connection_name, self::$connection_pool_read_only)) { 
     2802            $db =& self::$connection_pool_read_only[$this->read_only_connection_name]; 
     2803            #error_log("get_connection($read_only) - using read only:".$this->read_only_connection_name); 
     2804        } elseif(array_key_exists($this->connection_name, self::$connection_pool)) { 
     2805            $db =& self::$connection_pool[$this->connection_name]; 
     2806            #error_log("get_connection($read_only) - using read/write from pool:".$this->connection_name); 
     2807        } else { 
     2808            $db =& self::$db; 
     2809            #error_log("get_connection($read_only) - using read/write default:".$this->connection_name); 
     2810        } 
     2811        return $db; 
    25752812    } 
    25762813 
     
    27032940                            # Mark the corresponding entry in the error array by 
    27042941                            # putting the error message in for the attribute, 
    2705                             #   e.g. $this->errors['name'] = "can't be empty" 
     2942                            #   e.g. $this->add_error("can't be empty", 'name'); 
    27062943                            #   when 'name' was an empty string. 
    2707                             $this->errors[$validate_on_attribute] = $result[1]; 
     2944                            $this->add_error($result[1], $validate_on_attribute); 
    27082945                        } 
    27092946                    } 
     
    27162953    /** 
    27172954     *  Overwrite this method for validation checks on all saves and 
    2718      *  use $this->errors[] = "My error message."; or 
    2719      *  for invalid attributes $this->errors['attribute'] = "Attribute is invalid."; 
     2955     *  use $this->add_error("My error message.", 'attribute'); 
    27202956     *  @todo Document this API 
    27212957     */ 
     
    28103046     *  @todo Document this API 
    28113047     */ 
    2812     function before_delete() {} 
     3048    function before_delete() { return true; } 
    28133049 
    28143050    /** 
     
    28453081            if(method_exists($this, $method_name) && is_array($validation_name)) { 
    28463082                foreach($validation_name as $attribute_name => $options) { 
    2847                     if(!is_array($options)) { 
     3083                    if(is_string($options)) { 
    28483084                        $attribute_name = $options; 
    28493085                        $options = array(); 
    2850                     }                
     3086                    } elseif(!is_array($options)) { 
     3087                        $options = array(); 
     3088                    }                
    28513089                    $attribute_name = trim($attribute_name);      
    28523090                    $parameters = array(); 
    2853                     $on = array_key_exists('on', $options) ?  
    2854                         $options['on'] : 'save'; 
    2855                     $message = array_key_exists('message', $options) ?  
    2856                         $options['message'] : null;                   
     3091                    $on = array_key_exists('on', $options) ? $options['on'] : 'save'; 
     3092                    $message = array_key_exists('message', $options) ? $options['message'] : null;    
    28573093                    switch($method_name) { 
    28583094                        case 'validates_acceptance_of': 
     
    29233159        foreach((array) $attribute_names as $attribute_name) {                   
    29243160            if($this->$attribute_name != $accept) { 
    2925                 $attribute_human = Inflector::humanize($attribute_name); 
    2926                 $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3161                #$attribute_human = $this->human_attribute_name($attribute_name); 
     3162                #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3163                $this->add_error($message, $attribute_name);                 
    29273164            } 
    29283165        } 
     
    29413178            $attribute_confirmation = $attribute_name . '_confirmation'; 
    29423179            if($this->$attribute_confirmation != $this->$attribute_name) { 
    2943                 $attribute_human = Inflector::humanize($attribute_name); 
    2944                 $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3180                #$attribute_human = $this->human_attribute_name($attribute_name); 
     3181                #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3182                $this->add_error($message, $attribute_name); 
    29453183            } 
    29463184        } 
     
    29613199                list($minimum, $maximum) = explode('..', $in); 
    29623200                if($this->$attribute_name >= $minimum && $this->$attribute_name <= $maximum) { 
    2963                     $attribute_human = Inflector::humanize($attribute_name); 
    2964                     $this->add_error("{$attribute_human} {$message}", $attribute_name);         
     3201                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3202                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3203                    $this->add_error($message, $attribute_name);        
    29653204                } 
    29663205            } elseif(is_array($in)) { 
    29673206                if(in_array($this->$attribute_name, $in)) { 
    2968                     $attribute_human = Inflector::humanize($attribute_name); 
    2969                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3207                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3208                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3209                    $this->add_error($message, $attribute_name); 
    29703210                } 
    29713211            }    
     
    29873227            # Was there an error? 
    29883228            if(!preg_match($regex, $value)) { 
    2989                 $attribute_human = Inflector::humanize($attribute_name); 
    2990                 $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3229                #$attribute_human = $this->human_attribute_name($attribute_name); 
     3230                #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3231                $this->add_error($message, $attribute_name); 
    29913232            } 
    29923233        } 
     
    30073248                list($minimum, $maximum) = explode('..', $in); 
    30083249                if(!($this->$attribute_name >= $minimum && $this->$attribute_name <= $maximum)) { 
    3009                     $attribute_human = Inflector::humanize($attribute_name); 
    3010                     $this->add_error("{$attribute_human} {$message}", $attribute_name);         
     3250                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3251                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3252                    $this->add_error($message, $attribute_name);       
    30113253                } 
    30123254            } elseif(is_array($in)) { 
    30133255                if(!in_array($this->$attribute_name, $in)) { 
    3014                     $attribute_human = Inflector::humanize($attribute_name); 
    3015                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3256                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3257                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3258                    $this->add_error($message, $attribute_name); 
    30163259                } 
    30173260            }  
     
    30423285            # Attribute string length 
    30433286            $len = strlen($this->$attribute_name); 
    3044             $attribute_human = Inflector::humanize($attribute_name); 
     3287            #$attribute_human = $this->human_attribute_name($attribute_name); 
    30453288             
    30463289            # If you have set the min length option 
     
    30483291                $message = $this->get_error_message_for_validation($options['too_short'], 'too_short', $options['minimum']); 
    30493292                if($len < $options['minimum']) { 
    3050                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3293                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3294                    $this->add_error($message, $attribute_name);                     
    30513295                } 
    30523296            } 
     
    30563300                $message = $this->get_error_message_for_validation($options['too_long'], 'too_long', $options['maximum']); 
    30573301                if($len > $options['maximum']) { 
    3058                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3302                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3303                    $this->add_error($message, $attribute_name);                     
    30593304                } 
    30603305            } 
     
    30643309                $message = $this->get_error_message_for_validation($options['wrong_length'], 'wrong_length', $options['is']); 
    30653310                if($len != $options['is']) { 
    3066                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3311                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3312                    $this->add_error($message, $attribute_name);                     
    30673313                } 
    30683314            } 
     
    30873333                $message = $this->get_error_message_for_validation($message, 'not_an_integer'); 
    30883334                if(!is_integer($value)) { 
    3089                     $attribute_human = Inflector::humanize($attribute_name); 
    3090                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3335                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3336                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3337                    $this->add_error($message, $attribute_name); 
    30913338                } 
    30923339            } else { 
    30933340                $message = $this->get_error_message_for_validation($message, 'not_a_number'); 
    30943341                if(!is_numeric($value)) { 
    3095                     $attribute_human = Inflector::humanize($attribute_name); 
    3096                     $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3342                    #$attribute_human = $this->human_attribute_name($attribute_name); 
     3343                    #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3344                    $this->add_error($message, $attribute_name); 
    30973345                } 
    30983346            } 
     
    31113359        foreach((array) $attribute_names as $attribute_name) {               
    31123360            if($this->$attribute_name === '' || is_null($this->$attribute_name)) { 
    3113                 $attribute_human = Inflector::humanize($attribute_name); 
    3114                 $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3361                #$attribute_human = $this->human_attribute_name($attribute_name); 
     3362                #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3363                $this->add_error($message, $attribute_name); 
    31153364            } 
    31163365        } 
     
    31363385            }    
    31373386            if($this->find_first($conditions)) { 
    3138                 $attribute_human = Inflector::humanize($attribute_name); 
    3139                 $this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3387                #$attribute_human = $this->human_attribute_name($attribute_name); 
     3388                #$this->add_error("{$attribute_human} {$message}", $attribute_name); 
     3389                $this->add_error($message, $attribute_name);                 
    31403390            } 
    31413391        } 
     
    31843434        throw new ActiveRecordError($error_message, "ActiveRecord Error", "500"); 
    31853435    } 
     3436 
     3437    function errors_full_messages() { 
     3438        $full_messages = array(); 
     3439        foreach((array)$this->errors as $attribute => $message) { 
     3440            if(is_null($message)) { 
     3441                continue; 
     3442            } 
     3443            $full_messages[] = $this->human_attribute_name($attribute) . " " . $message; 
     3444        } 
     3445        return $full_messages; 
     3446    } 
     3447     
     3448    function errors_on($attribute) { 
     3449        $errors = isset($this->errors[$attribute]) ? $this->errors[$attribute] : null; 
     3450        return ((is_array($errors) && count($errors) == 1) ? current($errors) : $errors); 
     3451    }    
    31863452 
    31873453    /** 
  • trunk/trax/vendor/trax/inflections.php

    r201 r308  
    8181Inflections::irregular('sex', 'sexes');  
    8282Inflections::irregular('move', 'moves');  
     83Inflections::irregular('cow', 'kine');  
    8384 
    8485Inflections::uncountable('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'); 
     
    9495class Inflections { 
    9596 
    96     public static $plurals = array(); 
    97  
    98     public static $singulars = array(); 
    99  
    100     public static $uncountables = array(); 
     97    public static  
     98        $plurals = array(), 
     99        $singulars = array(), 
     100        $uncountables = array(), 
     101        $humans = array(); 
    101102 
    102103    # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.  
     
    130131    #   Inflections::uncountable(array("money", "information", "rice")) 
    131132    function uncountable() { 
    132         $args = func_get_args(); 
     133        $args = func_get_args(); 
    133134        if(is_array($args[0])) { 
    134135            $args = $args[0];     
     
    137138            self::$uncountables[] = $word;     
    138139        }      
     140    } 
     141 
     142    # Specifies a humanized form of a string by a regular expression rule or by a string mapping. 
     143    # When using a regular expression based replacement, the normal humanize formatting is called after the replacement. 
     144    # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name') 
     145    # 
     146    # Examples: 
     147    #   Inflections::human("/_cnt$/i", "\1_count") 
     148    #   Inflections::human("legacy_col_person_name", "Name") 
     149    function human($rule, $replacement) { 
     150        array_unshift(self::$humans, array("rule" => $rule, "replacement" => $replacement)); 
    139151    } 
    140152     
     
    147159    function clear($scope = "all") { 
    148160        if($scope == "all") { 
    149             self::$plurals = self::$singulars = self::$uncountables = array(); 
     161            self::$plurals = self::$singulars = self::$uncountables = self::$humans = array(); 
    150162        } else { 
    151163            self::$$scope = array(); 
  • trunk/trax/vendor/trax/inflector.php

    r303 r308  
    4141 */ 
    4242class Inflector { 
     43     
     44    private static $cache = array( 
     45        'plural' => array(),  
     46        'singular' => array() 
     47    ); 
    4348 
    4449    /** 
     
    4853     *  If $count > 0 then prefixes $word with the $count 
    4954     * 
    50      *  @param  string $word  Word to be pluralized 
     55     *  @param  string $singular_word  Word to be pluralized 
    5156     *  @param  int $count How many of these $words are there 
    52      *  @return string  Plural of $word 
    53      */ 
    54     function pluralize($word, $count = 0) { 
    55         if($count == 0 || $count > 1) {           
    56             if(!in_array($word, Inflections::$uncountables)) {  
    57                 $original = $word;    
    58                 foreach(Inflections::$plurals as $plural_rule) { 
    59                     $word = preg_replace($plural_rule['rule'], $plural_rule['replacement'], $word); 
    60                     if($original != $word) break; 
    61                 } 
     57     *  @return string  Plural of $singular_word 
     58     */ 
     59    function pluralize($singular_word, $count = 0, $plural_word = null) { 
     60        if($count != 1) { 
     61            if(is_null($plural_word)) {  
     62                $plural_word = $singular_word;   
     63                if(isset(self::$cache['plural'][$singular_word])) { 
     64                    $plural_word = self::$cache['plural'][$singular_word]; 
     65                } elseif(!in_array($singular_word, Inflections::$uncountables)) {    
     66                    foreach(Inflections::$plurals as $plural_rule) { 
     67                        if(preg_match($plural_rule['rule'], $singular_word)) { 
     68                            $plural_word = preg_replace($plural_rule['rule'], $plural_rule['replacement'], $plural_word); 
     69                            self::$cache['plural'][$singular_word] = $plural_word; 
     70                            break; 
     71                        }    
     72                    } 
     73                }  
     74            } 
     75        } else { 
     76            $plural_word = self::singularize($singular_word); 
     77        } 
     78        return $plural_word; 
     79    } 
     80 
     81    /** 
     82     *  Singularize a word according to English rules  
     83     * 
     84     *  @param  string $plural_word  Word to be singularized 
     85     *  @return string  Singular of $plural_word 
     86     */ 
     87    function singularize($plural_word) { 
     88        $singular_word = $plural_word;   
     89        if(isset(self::$cache['singular'][$plural_word])) { 
     90            $singular_word = self::$cache['singular'][$plural_word]; 
     91        } elseif(!in_array($plural_word, Inflections::$uncountables)) {               
     92            foreach(Inflections::$singulars as $singular_rule) { 
     93                if(preg_match($singular_rule['rule'], $plural_word)) { 
     94                    $singular_word = preg_replace($singular_rule['rule'], $singular_rule['replacement'], $singular_word); 
     95                    self::$cache['singular'][$plural_word] = $singular_word; 
     96                    break; 
     97                }    
    6298            } 
    6399        } 
    64         return ($count >= 1 ? "{$count} {$word}" : $word); 
    65     } 
    66  
    67     /** 
    68      *  Singularize a word according to English rules  
    69      * 
    70      *  @param  string $word  Word to be singularized 
    71      *  @return string  Singular of $word 
    72      */ 
    73     function singularize($word) { 
    74         if(!in_array($word, Inflections::$uncountables)) {  
    75             $original = $word;    
    76             foreach(Inflections::$singulars as $singular_rule) { 
    77                 $word = preg_replace($singular_rule['rule'], $singular_rule['replacement'], $word); 
    78                 if($original != $word) break; 
    79             } 
    80         } 
    81         return $word; 
    82     } 
    83  
    84     /** 
    85      *  Capitalize a word making it all lower case with first letter uppercase  
    86      * 
    87      *  @param  string $word  Word to be capitalized 
    88      *  @return string Capitalized $word 
    89      */ 
    90     function capitalize($word) { 
    91         return ucfirst(strtolower($word));      
     100        return $singular_word; 
    92101    } 
    93102 
     
    104113    } 
    105114 
    106     /** 
    107      *  Convert a phrase from the camel case form to the lower case 
    108      *  and underscored form 
    109      * 
    110      *  @param string $camel_cased_word  Phrase to convert 
    111      *  @return string Lower case and underscored form of the phrase 
    112      */ 
    113     function underscore($camel_cased_word) { 
    114         $camel_cased_word = preg_replace('/([A-Z]+)([A-Z])/','\1_\2',$camel_cased_word); 
    115         return strtolower(preg_replace('/([a-z])([A-Z])/','\1_\2',$camel_cased_word)); 
    116     } 
    117  
    118     /** 
    119      *  Generate a more human version of a lower case underscored word 
    120      * 
    121      *  @param string $lower_case_and_underscored_word  A word or phrase in 
    122      *                                           lower_case_underscore form 
    123      *  @return string The input value with underscores replaced by 
    124      *  blanks and the first letter of each word capitalized 
    125      */ 
    126     function humanize($lower_case_and_underscored_word) { 
    127         return ucwords(str_replace("_"," ",$lower_case_and_underscored_word)); 
    128     } 
    129      
    130115    /** 
    131116     *  Convert a word or phrase into a title format "Welcome To My Site" 
     
    135120     */     
    136121    function titleize($word) { 
    137         return preg_replace('/\b([a-z])/', self::capitalize('$1'), self::humanize(self::underscore($word))); 
     122        return ucwords(self::humanize(self::underscore($word))); 
     123    } 
     124 
     125    /** 
     126     *  Convert a phrase from the camel case form to the lower case 
     127     *  and underscored form 
     128     * 
     129     *  Changes '::' to '/' to convert namespaces to paths. (php 5.3) 
     130     *  
     131     *  Examples: 
     132     *    Inflector::underscore("ActiveRecord") => "active_record" 
     133     *    Inflector::underscore("ActiveRecord::Errors") => active_record/errors 
     134     *  
     135     *  @param string $camel_cased_word  Phrase to convert 
     136     *  @return string Lower case and underscored form of the phrase 
     137     */ 
     138    function underscore($camel_cased_word) { 
     139        $camel_cased_word = str_replace('::','/',$camel_cased_word); 
     140        $camel_cased_word = preg_replace('/([A-Z]+)([A-Z])/','\1_\2',$camel_cased_word); 
     141        return strtolower(preg_replace('/([a-z\d])([A-Z])/','\1_\2',$camel_cased_word)); 
    138142    } 
    139143 
     
    149153 
    150154    /** 
     155     *  Generate a more human version of a lower case underscored word 
     156     * 
     157     *  @param string $lower_case_and_underscored_word  A word or phrase in 
     158     *                                           lower_case_underscore form 
     159     *  @return string The input value with underscores replaced by 
     160     *  blanks and the first letter of each word capitalized 
     161     */ 
     162    function humanize($lower_case_and_underscored_word) { 
     163        if(count(Inflections::$humans) > 0) { 
     164            $original = $lower_case_and_underscored_word;    
     165            foreach(Inflections::$humans as $human_rule) { 
     166                $lower_case_and_underscored_word = preg_replace($human_rule['rule'], $human_rule['replacement'], $word); 
     167                if($original != $lower_case_and_underscored_word) break; 
     168            }    
     169        } 
     170        return self::capitalize(str_replace(array("_","_id"),array(" ",""),$lower_case_and_underscored_word)); 
     171    } 
     172 
     173    /**  
     174     *  Removes the module part from the expression in the string. (php 5.3) 
     175     *  
     176     *  Examples: 
     177     *      Inflector::demodulize("ActiveRecord::CoreExtensions::String::Inflections") => "Inflections" 
     178     *      Inflector::demodulize("Inflections") => "Inflections" 
     179     *  
     180     */ 
     181    function demodulize($class_name_in_module) { 
     182        return preg_replace("/^.*::/", '', $class_name_in_module); 
     183    } 
     184 
     185    /** 
    151186     *  Convert a class name to the corresponding table name 
    152187     * 
     
    172207 
    173208    /** 
     209     *  Capitalize a word making it all lower case with first letter uppercase  
     210     * 
     211     *  @param  string $word  Word to be capitalized 
     212     *  @return string Capitalized $word 
     213     */ 
     214    function capitalize($word) { 
     215        return ucfirst(strtolower($word));      
     216    } 
     217     
     218    /** 
    174219     *  Get foreign key column corresponding to a table name 
    175220     * 
    176      *  @param string $table_name Name of table referenced by foreign 
    177      *    key 
     221     *  @param string $table_name Name of table referenced by foreign key 
    178222     *  @return string Column name of the foreign key column 
    179223     */ 
    180224    function foreign_key($class_name) { 
    181         return self::underscore($class_name) . "_id"; 
     225        return self::underscore(self::demodulize($class_name)) . "_id"; 
    182226    } 
    183227 
     
    186230     *  Add to a number st, nd, rd, th 
    187231     * 
    188      *  @param integer $number Number to append to 
    189      *    key 
     232     *  @param integer $number Number to append to key 
    190233     *  @return string Number formatted with correct st, nd, rd, or th 
    191234     */     
    192235    function ordinalize($number) { 
    193         $test = (intval($number) % 100); 
    194         if($test >= 11 && $test <= 13) { 
     236        $number = intval($number); 
     237        if(in_array(($number % 100), range(11, 13))) { 
    195238            $number = "{$number}th"; 
    196239        } else { 
    197             switch((intval($number) % 10)) { 
     240            switch(($number % 10)) { 
    198241                case 1: 
    199242                    $number = "{$number}st"; 
     
    211254        return $number; 
    212255    } 
     256 
     257    /** 
     258     *  Clears the cached words for pluralize and singularize 
     259     * 
     260     *  @param none 
     261     *  @return nothing 
     262     */ 
     263    function clear_cache() { 
     264        self::$cache = array( 
     265            'plural' => array(),  
     266            'singular' => array() 
     267        );       
     268    } 
    213269     
    214270} 
  • trunk/trax/vendor/trax/php_shell.php

    r244 r308  
    2828  
    2929@ob_end_clean(); 
    30 error_reporting(E_ALL); 
     30error_reporting(E_ALL ^ E_NOTICE); 
    3131set_time_limit(0); 
    3232 
  • trunk/trax/vendor/trax/templates/error.phtml

    r249 r308  
    4545 
    4646<?php if($trace): ?> 
    47 <a href="#" onclick="expandContract('framework_trace')">Show framework trace</a> 
     47<a href="#" onclick="expandContract('framework_trace');return false;">Show framework trace</a> 
    4848<pre id="framework_trace" style="display:none"><code><?php echo $trace ?></code></pre> 
    4949<?php endif; ?> 
    5050 
    5151<?php if(count(ActiveRecord::$query_log)): ?> 
    52 <p><a href="#" onclick="expandContract('sql_trace')">Show SQL trace</a> 
     52<p><a href="#" onclick="expandContract('sql_trace');return false;">Show SQL trace</a> 
    5353<pre id="sql_trace" style="display:none"> 
    5454<code style="word-wrap: break-word;"> 
     
    6161<?php endif; ?> 
    6262 
    63 <p><a href="#" onclick="expandContract('session_dump')">Show $_SESSION dump</a></p> 
     63<p><a href="#" onclick="expandContract('session_dump');return false;">Show $_SESSION dump</a></p> 
    6464<div id="session_dump" style="display:none"><pre class='debug_dump'> 
    6565<?php echo print_r($_SESSION, true) ?> 
    6666</pre></div> 
    6767 
    68 <p><a href="#" onclick="expandContract('get_dump')">Show $_GET dump</a></p> 
     68<p><a href="#" onclick="expandContract('get_dump');return false;">Show $_GET dump</a></p> 
    6969<div id="get_dump" style="display:none"><pre class='debug_dump'> 
    7070<?php echo print_r($_GET, true) ?> 
    7171</pre></div> 
    7272 
    73 <p><a href="#" onclick="expandContract('post_dump')">Show $_POST dump</a></p> 
     73<p><a href="#" onclick="expandContract('post_dump');return false;">Show $_POST dump</a></p> 
    7474<div id="post_dump" style="display:none"><pre class='debug_dump'> 
    7575<?php echo print_r($_POST, true) ?> 
    7676</pre></div> 
    7777 
    78 <p><a href="#" onclick="expandContract('cookie_dump')">Show $_COOKIE dump</a></p> 
     78<p><a href="#" onclick="expandContract('cookie_dump');return false;">Show $_COOKIE dump</a></p> 
    7979<div id="cookie_dump" style="display:none"><pre class='debug_dump'> 
    8080<?php echo print_r($_COOKIE, true) ?> 
    8181</pre></div> 
    8282 
    83 <p><a href="#" onclick="expandContract('file_dump')">Show $_FILES dump</a></p> 
     83<p><a href="#" onclick="expandContract('file_dump');return false;">Show $_FILES dump</a></p> 
    8484<div id="file_dump" style="display:none"><pre class='debug_dump'> 
    8585<?php echo print_r($_FILES, true) ?>