View Source

/hsphere/local/home/c251266/sunsetvines.com/www.sunsetvines.com/sunsetvines/current/vendor/creovel/classes/model.php (25.818 KB)

#0001  
#0002  
#0003  
#0004  
#0005  
#0006  
#0007  
#0008  
#0009  
#0010  
#0011  
#0012  
#0013  
#0014  
#0015  
#0016  
#0017  
#0018  
#0019  
#0020  
#0021  
#0022  
#0023  
#0024  
#0025  
#0026  
#0027  
#0028  
#0029  
#0030  
#0031  
#0032  
#0033  
#0034  
#0035  
#0036  
#0037  
#0038  
#0039  
#0040  
#0041  
#0042  
#0043  
#0044  
#0045  
#0046  
#0047  
#0048  
#0049  
#0050  
#0051  
#0052  
#0053  
#0054  
#0055  
#0056  
#0057  
#0058  
#0059  
#0060  
#0061  
#0062  
#0063  
#0064  
#0065  
#0066  
#0067  
#0068  
#0069  
#0070  
#0071  
#0072  
#0073  
#0074  
#0075  
#0076  
#0077  
#0078  
#0079  
#0080  
#0081  
#0082  
#0083  
#0084  
#0085  
#0086  
#0087  
#0088  
#0089  
#0090  
#0091  
#0092  
#0093  
#0094  
#0095  
#0096  
#0097  
#0098  
#0099  
#0100  
#0101  
#0102  
#0103  
#0104  
#0105  
#0106  
#0107  
#0108  
#0109  
#0110  
#0111  
#0112  
#0113  
#0114  
#0115  
#0116  
#0117  
#0118  
#0119  
#0120  
#0121  
#0122  
#0123  
#0124  
#0125  
#0126  
#0127  
#0128  
#0129  
#0130  
#0131  
#0132  
#0133  
#0134  
#0135  
#0136  
#0137  
#0138  
#0139  
#0140  
#0141  
#0142  
#0143  
#0144  
#0145  
#0146  
#0147  
#0148  
#0149  
#0150  
#0151  
#0152  
#0153  
#0154  
#0155  
#0156  
#0157  
#0158  
#0159  
#0160  
#0161  
#0162  
#0163  
#0164  
#0165  
#0166  
#0167  
#0168  
#0169  
#0170  
#0171  
#0172  
#0173  
#0174  
#0175  
#0176  
#0177  
#0178  
#0179  
#0180  
#0181  
#0182  
#0183  
#0184  
#0185  
#0186  
#0187  
#0188  
#0189  
#0190  
#0191  
#0192  
#0193  
#0194  
#0195  
#0196  
#0197  
#0198  
#0199  
#0200  
#0201  
#0202  
#0203  
#0204  
#0205  
#0206  
#0207  
#0208  
#0209  
#0210  
#0211  
#0212  
#0213  
#0214  
#0215  
#0216  
#0217  
#0218  
#0219  
#0220  
#0221  
#0222  
#0223  
#0224  
#0225  
#0226  
#0227  
#0228  
#0229  
#0230  
#0231  
#0232  
#0233  
#0234  
#0235  
#0236  
#0237  
#0238  
#0239  
#0240  
#0241  
#0242  
#0243  
#0244  
#0245  
#0246  
#0247  
#0248  
#0249  
#0250  
#0251  
#0252  
#0253  
#0254  
#0255  
#0256  
#0257  
#0258  
#0259  
#0260  
#0261  
#0262  
#0263  
#0264  
#0265  
#0266  
#0267  
#0268  
#0269  
#0270  
#0271  
#0272  
#0273  
#0274  
#0275  
#0276  
#0277  
#0278  
#0279  
#0280  
#0281  
#0282  
#0283  
#0284  
#0285  
#0286  
#0287  
#0288  
#0289  
#0290  
#0291  
#0292  
#0293  
#0294  
#0295  
#0296  
#0297  
#0298  
#0299  
#0300  
#0301  
#0302  
#0303  
#0304  
#0305  
#0306  
#0307  
#0308  
#0309  
#0310  
#0311  
#0312  
#0313  
#0314  
#0315  
#0316  
#0317  
#0318  
#0319  
#0320  
#0321  
#0322  
#0323  
#0324  
#0325  
#0326  
#0327  
#0328  
#0329  
#0330  
#0331  
#0332  
#0333  
#0334  
#0335  
#0336  
#0337  
#0338  
#0339  
#0340  
#0341  
#0342  
#0343  
#0344  
#0345  
#0346  
#0347  
#0348  
#0349  
#0350  
#0351  
#0352  
#0353  
#0354  
#0355  
#0356  
#0357  
#0358  
#0359  
#0360  
#0361  
#0362  
#0363  
#0364  
#0365  
#0366  
#0367  
#0368  
#0369  
#0370  
#0371  
#0372  
#0373  
#0374  
#0375  
#0376  
#0377  
#0378  
#0379  
#0380  
#0381  
#0382  
#0383  
#0384  
#0385  
#0386  
#0387  
#0388  
#0389  
#0390  
#0391  
#0392  
#0393  
#0394  
#0395  
#0396  
#0397  
#0398  
#0399  
#0400  
#0401  
#0402  
#0403  
#0404  
#0405  
#0406  
#0407  
#0408  
#0409  
#0410  
#0411  
#0412  
#0413  
#0414  
#0415  
#0416  
#0417  
#0418  
#0419  
#0420  
#0421  
#0422  
#0423  
#0424  
#0425  
#0426  
#0427  
#0428  
#0429  
#0430  
#0431  
#0432  
#0433  
#0434  
#0435  
#0436  
#0437  
#0438  
#0439  
#0440  
#0441  
#0442  
#0443  
#0444  
#0445  
#0446  
#0447  
#0448  
#0449  
#0450  
#0451  
#0452  
#0453  
#0454  
#0455  
#0456  
#0457  
#0458  
#0459  
#0460  
#0461  
#0462  
#0463  
#0464  
#0465  
#0466  
#0467  
#0468  
#0469  
#0470  
#0471  
#0472  
#0473  
#0474  
#0475  
#0476  
#0477  
#0478  
#0479  
#0480  
#0481  
#0482  
#0483  
#0484  
#0485  
#0486  
#0487  
#0488  
#0489  
#0490  
#0491  
#0492  
#0493  
#0494  
#0495  
#0496  
#0497  
#0498  
#0499  
#0500  
#0501  
#0502  
#0503  
#0504  
#0505  
#0506  
#0507  
#0508  
#0509  
#0510  
#0511  
#0512  
#0513  
#0514  
#0515  
#0516  
#0517  
#0518  
#0519  
#0520  
#0521  
#0522  
#0523  
#0524  
#0525  
#0526  
#0527  
#0528  
#0529  
#0530  
#0531  
#0532  
#0533  
#0534  
#0535  
#0536  
#0537  
#0538  
#0539  
#0540  
#0541  
#0542  
#0543  
#0544  
#0545  
#0546  
#0547  
#0548  
#0549  
#0550  
#0551  
#0552  
#0553  
#0554  
#0555  
#0556  
#0557  
#0558  
#0559  
#0560  
#0561  
#0562  
#0563  
#0564  
#0565  
#0566  
#0567  
#0568  
#0569  
#0570  
#0571  
#0572  
#0573  
#0574  
#0575  
#0576  
#0577  
#0578  
#0579  
#0580  
#0581  
#0582  
#0583  
#0584  
#0585  
#0586  
#0587  
#0588  
#0589  
#0590  
#0591  
#0592  
#0593  
#0594  
#0595  
#0596  
#0597  
#0598  
#0599  
#0600  
#0601  
#0602  
#0603  
#0604  
#0605  
#0606  
#0607  
#0608  
#0609  
#0610  
#0611  
#0612  
#0613  
#0614  
#0615  
#0616  
#0617  
#0618  
#0619  
#0620  
#0621  
#0622  
#0623  
#0624  
#0625  
#0626  
#0627  
#0628  
#0629  
#0630  
#0631  
#0632  
#0633  
#0634  
#0635  
#0636  
#0637  
#0638  
#0639  
#0640  
#0641  
#0642  
#0643  
#0644  
#0645  
#0646  
#0647  
#0648  
#0649  
#0650  
#0651  
#0652  
#0653  
#0654  
#0655  
#0656  
#0657  
#0658  
#0659  
#0660  
#0661  
#0662  
#0663  
#0664  
#0665  
#0666  
#0667  
#0668  
#0669  
#0670  
#0671  
#0672  
#0673  
#0674  
#0675  
#0676  
#0677  
#0678  
#0679  
#0680  
#0681  
#0682  
#0683  
#0684  
#0685  
#0686  
#0687  
#0688  
#0689  
#0690  
#0691  
#0692  
#0693  
#0694  
#0695  
#0696  
#0697  
#0698  
#0699  
#0700  
#0701  
#0702  
#0703  
#0704  
#0705  
#0706  
#0707  
#0708  
#0709  
#0710  
#0711  
#0712  
#0713  
#0714  
#0715  
#0716  
#0717  
#0718  
#0719  
#0720  
#0721  
#0722  
#0723  
#0724  
#0725  
#0726  
#0727  
#0728  
#0729  
#0730  
#0731  
#0732  
#0733  
#0734  
#0735  
#0736  
#0737  
#0738  
#0739  
#0740  
#0741  
#0742  
#0743  
#0744  
#0745  
#0746  
#0747  
#0748  
#0749  
#0750  
#0751  
#0752  
#0753  
#0754  
#0755  
#0756  
#0757  
#0758  
#0759  
#0760  
#0761  
#0762  
#0763  
#0764  
#0765  
#0766  
#0767  
#0768  
#0769  
#0770  
#0771  
#0772  
#0773  
#0774  
#0775  
#0776  
#0777  
#0778  
#0779  
#0780  
#0781  
#0782  
#0783  
#0784  
#0785  
#0786  
#0787  
#0788  
#0789  
#0790  
#0791  
#0792  
#0793  
#0794  
#0795  
#0796  
#0797  
#0798  
#0799  
#0800  
#0801  
#0802  
#0803  
#0804  
#0805  
#0806  
#0807  
#0808  
#0809  
#0810  
#0811  
#0812  
#0813  
#0814  
#0815  
#0816  
#0817  
#0818  
#0819  
#0820  
#0821  
#0822  
#0823  
#0824  
#0825  
#0826  
#0827  
#0828  
#0829  
#0830  
#0831  
#0832  
#0833  
#0834  
#0835  
#0836  
#0837  
#0838  
#0839  
#0840  
#0841  
#0842  
#0843  
#0844  
#0845  
#0846  
#0847  
#0848  
#0849  
#0850  
#0851  
#0852  
#0853  
#0854  
#0855  
#0856  
#0857  
#0858  
#0859  
#0860  
#0861  
#0862  
#0863  
#0864  
#0865  
#0866  
#0867  
#0868  
#0869  
#0870  
#0871  
#0872  
#0873  
#0874  
#0875  
#0876  
#0877  
#0878  
#0879  
#0880  
#0881  
#0882  
#0883  
#0884  
#0885  
#0886  
#0887  
#0888  
#0889  
#0890  
#0891  
#0892  
#0893  
#0894  
#0895  
#0896  
#0897  
#0898  
#0899  
#0900  
#0901  
#0902  
#0903  
#0904  
#0905  
#0906  
#0907  
#0908  
#0909  
#0910  
#0911  
#0912  
#0913  
#0914  
#0915  
#0916  
#0917  
#0918  
#0919  
#0920  
#0921  
#0922  
#0923  
#0924  
#0925  
#0926  
#0927  
#0928  
#0929  
#0930  
#0931  
#0932  
#0933  
#0934  
#0935  
#0936  
#0937  
#0938  
#0939  
#0940  
#0941  
#0942  
#0943  
#0944  
#0945  
#0946  
#0947  
#0948  
#0949  
#0950  
#0951  
#0952  
#0953  
#0954  
#0955  
#0956  
#0957  
#0958  
#0959  
#0960  
#0961  
#0962  
#0963  
#0964  
#0965  
#0966  
#0967  
#0968  
#0969  
#0970  
#0971  
#0972  
#0973  
#0974  
#0975  
#0976  
#0977  
#0978  
#0979  
#0980  
#0981  
#0982  
#0983  
#0984  
#0985  
#0986  
#0987  
#0988  
#0989  
#0990  
#0991  
#0992  
#0993  
#0994  
#0995  
#0996  
#0997  
#0998  
#0999  
#01000  
#01001  
#01002  
#01003  
#01004  
#01005  
#01006  
#01007  
#01008  
#01009  
#01010  
#01011  
#01012  
#01013  
#01014  
#01015  
#01016  
#01017  
#01018  
#01019  
#01020  
#01021  
#01022  
#01023  
#01024  
#01025  
#01026  
#01027  
#01028  
#01029  
#01030  
#01031  
#01032  
#01033  
#01034  
#01035  
#01036  
#01037  
#01038  
#01039  
#01040  
#01041  
#01042  
#01043  
#01044  
#01045  
#01046  
#01047  
#01048  
#01049  
#01050  
#01051  
#01052  
#01053  
#01054  
#01055  
#01056  
#01057  
#01058  
#01059  
#01060  
#01061  
#01062  
#01063  
#01064  
#01065  
#01066  
#01067  
#01068  
#01069  
#01070  
#01071  
#01072  
#01073  
#01074  
#01075  
#01076  
#01077  
#01078  
#01079  
#01080  
#01081  
#01082  
#01083  
#01084  
#01085  
#01086  
#01087  
#01088  
#01089  
#01090  
#01091  
#01092  
#01093  
#01094  
#01095  
#01096  
#01097  
#01098  
#01099  
#01100  
#01101  
#01102  
#01103  
#01104  
#01105  
#01106  
#01107  
#01108  
#01109  
#01110  
#01111  
#01112  
#01113  
#01114  
#01115  
#01116  
#01117  
#01118  
#01119  
#01120  
#01121  
#01122  
#01123  
#01124  
#01125  
#01126  
#01127  
#01128  
#01129  
#01130  
#01131  
#01132  
#01133  
#01134  
#01135  
#01136  
#01137  
#01138  
#01139  
#01140  
#01141  
#01142  
#01143  
#01144  
#01145  
#01146  
#01147  
#01148  
#01149  
#01150  
#01151  
#01152  
#01153  
#01154  
#01155  
#01156  
#01157  
#01158  
#01159  
#01160  
#01161  
#01162  
#01163  
#01164  
#01165  
#01166  
#01167  
#01168  
#01169  
#01170  
#01171  
#01172  
#01173  
#01174  
#01175  
#01176  
#01177  
#01178  
#01179  
#01180  
#01181  
#01182  
#01183  
#01184  
#01185  
#01186  
#01187  
#01188  
#01189  
#01190  
#01191  
#01192  
#01193  
#01194  
#01195  
#01196  
#01197  
#01198  
#01199  
#01200  
#01201  
#01202  
#01203  
#01204  
#01205  
#01206  
#01207  
#01208  
#01209  
#01210  
#01211  
#01212  
#01213  
#01214  
#01215  
#01216  
#01217  
#01218  
#01219  
#01220  
#01221  
#01222  
#01223  
#01224  
#01225  
#01226  
#01227  
#01228  
#01229  
#01230  
#01231  
#01232  
#01233  
#01234  
#01235  
<?

/**
 * Model class
 * 
 */ 

class model implements Iterator {

    
    
/**
    * Database the table resides in 
    *
    * @author John Faircloth
    * @access protected
    * @var string
    */
    
protected $_db_name;
    
    
/**
    * Table name the model is representing 
    *
    * @author John Faircloth
    * @access protected
    * @var string 
    */
    
protected $_table_name;
    
    
/**
    * Table columns
    *
    * @author John Faircloth
    * @access private
    * @var object
    */
    
protected $_fields;
     
    
/**
    * The primary key column (underscore format).
    * @author John Faircloth
    * @access private
    * @var object
    */
    
protected $_primary_key 'id';
    
    
/**
    * Adapter
    * @author Nesbert Hidalgo
    * @access public
    * @var object
    */
    
public $_select_query;
    
    
/**
    * Adapter
    * @author Nesbert Hidalgo
    * @access private
    * @var object
    */
    
public $_action_query;
    
    
/**
    * Adapter
    * @author John Faircloth
    * @access public
    * @var array
    */
    
public $_links = array();
    
    
/**
    * Adapter
    * @author John Faircloth
    * @access public
    * @var array
    */
    
public $_valid = array();
    
    
/**
    * Paging object
    * @author Nesbert Hidalgo
    * @access public
    * @var object
    */
    
public $page;
    
    
/**
    * Errors object
    * @author Nesbert Hidalgo
    * @access public
    * @var object
    */
    
public $errors;
    
    
/**
    * Errors object
    * @author Nesbert Hidalgo
    * @access public
    * @var object
    */
    
public $validation;
    
    private 
$_select;
    private 
$_from;
    private 
$_where;
    private 
$_group;
    private 
$_order;
    private 
$_limit;
    private 
$_offset;
    private 
$_query_str;
    
    
/**
    * Constructor.
    *
    * @author John Faircloth
    * @access public
    * @params string array $data used to load the model with values
     */     
    
public function __construct($data null$connection_properties null)
    {
        
        
$this->errors = new error(get_class($this));
        
$this->validation = new validation($this->errors);

        
$this->_select_query $this->establish_connection($connection_properties);
        
$this->_action_query $this->establish_connection($connection_properties);        
        
        if (
$adapter) {
            
$this->_adpater $adapter;
        }
        
        
$this->_set_table();
        
$this->_set_data($data);
        
    }
    
    
/**
    * Set Table up
    *
    * @author John Faircloth
    * @access private
    */
    
private function _set_table()
    {
        
        if (!
$this->_table_name) {
            
$model_name =  $this->_class();
            
$this->_table_name pluralize($model_name);
        }
        
        
$this->_db_name $this->_select_query->get_database();
        
$this->_select_query->set_table($this->_table_name);
        
$this->_fields $this->_select_query->get_fields_object();
    }
    
    private function 
_class()
    {
        return 
str_replace('_model'''get_class($this));            
    }
    
    
/**
    * Choose the correct DB adapter to use and sets its properties.
    * Returns an DB Layer object.
    *
    * @author Nesbert Hidalgo
    * @access public
    * @param array $db_properties required
    * @return object
    */
    
public function establish_connection($connection_properties false)
    {
        if (!
is_array($connection_properties)) {
            
$connection_properties $this->_get_connection_properties();
        }
        
        switch ( 
strtolower($connection_properties['adapter']) ) {
        
            case 
'mysql':
                
$adapter 'mysql';
            break;
            
            default:
                die(
'<strong>Error:</strong> Unknown Database Adapter.');
            break;
            
        }
        
        
$db_obj = new $adapter($connection_properties);
        
        return 
$db_obj;
        
    }
    
    
/**
     * Get connection properties for DB as defined in the ENV
     *
     * @author Nesbert Hidalgo
     * @access private
     * @return array
     */
    
private function _get_connection_properties()
    {
    
    
        switch ( 
$_ENV['mode'] ) {
        
            case 
'production':
                
$_ENV['production']['mode'] = 'production';
                return 
$_ENV['production'];
            break;
        
            case 
'test':
                
$_ENV['test']['mode'] = 'test';
                return 
$_ENV['test'];
            break;
        
            case 
'development':
            default:
                
$_ENV['development']['mode'] = 'development';
                return 
$_ENV['development'];
            break;
        
        }

    }

    protected function 
_set_data($data) {
    
        if (
$data) {
            if (
is_array($data)) {
                if (isset(
$data[$this->_primary_key])) {
                    
$function 'set_' $this->_primary_key;
                    
$this->$function($data[$this->_primary_key]);
                    
                }
                        
                foreach(
$data as $name => $value) {
                    if (
$name != $this->_primary_key) {
                            
                        
$function 'set_' $name;
                        
                        
$this->$function($value);
                    }
                }
            } else {
                
$function 'set_' $this->_primary_key;
                
$this->$function($data);
            }
            
        }
        
    }
    
    
/**
     * Creates an object mapped to the current table's structure
     *
     * @author Nesbert Hidalgo
     * @access private
     */     
    
private function _get_fields_object()
    {
        
// reset class properties
        
$this->reset();
        
        
// send a DESCRIBE query and set result on success
        
$this->_select_query->query('DESCRIBE ' $this->_table_name);
        
        
// foreach row in results insert into fields object
        
while ( $row mysql_fetch_assoc($result) ) {
        
            
// set fields into an associative array        
            
foreach ( $row as $key => $value ) if ( $key != 'Field' $temp_arr[strtolower($key)] = $value;
            
// get default value for field
            
$temp_arr['value'] = ( $row['Default'] !== 'NULL' $row['Default'] : null );
            
// set property in fields object
            
$fields->$row['Field'] = (object) $temp_arr;
            
        }
    
        return 
$fields;
        
    }
    
    
    public function 
save()
    {
        
// validate model on every save
        
$this->validate();
        
// if error return false        
        
if ( $this->errors->has_errors() ) return false;
        
        
$this->before_save();
        
        if ( 
$key $this->key() ) {
        
            
// validate model on every update
            
$this->validate_on_update();
            
// if error return false
            
if ( $this->errors->has_errors() ) return false;
            
            
$ret_val $this->update($this->values(), $this->_primary_key " = '" $this->key() . "'");
            
        } else {
        
            
// validate model on every insert
            
$this->validate_on_create();    
            
// if error return false
            
if ( $this->errors->has_errors() ) return false;
            
            
$this->before_create();
            
            
$ret_val $this->insert($this->values());
            
        }
        
        if ( 
$ret_val ) {
            
$this->after_save();
            return 
$this->key();
        } else {
            return 
false;
        }    
        
        
    
    }
    
    public function 
insert($data) {
        
        
$qry "INSERT INTO {$this->_table_name} (";
        
        foreach (
$data as $name => $value) {
            
            if (
$name == $this->_primary_key) {                
                continue;
            }

            
$qry .= $name ', ';

        }        
        
        
$qry substr($qry0, -2) . ') VALUES (';
        
        foreach (
$data as $name => $value) {

            if (
$name == $this->_primary_key) {
                continue;
            }
            
$this->_fields->$name->value $value;
            
$obj $this->_fields->$name;
            
            if (
$name == 'created_at') {
                
                
$qry .= "'" date('Y-m-d H:i:s')  . "', ";

            } elseif (
$name == 'updated_at') {
                
                
$qry .= "'" date('Y-m-d H:i:s')  . "', ";

            } elseif (
$obj->null == 'YES' && ($obj->value === '' || $obj->value === null)) {
            
                
$qry .= "NULL, ";
                
            } elseif (
is_bool($obj->value)) {
                
                
$qry .= "'" . ($obj->value 0) . "', ";
                
            } elseif (
is_numeric($obj->value)) {
                
                
$qry .= "'" $obj->value "', ";
                
            } elseif (
is_string($obj->value)) {
                
                
$qry .= "'" addslashes(trim($obj->value)) . "', ";
                
            } elseif (
is_array($obj->value)) {
            
                
// if datetime save array
                
if ( $this->_fields->$name->type == 'datetime' ) {
                    
$qry .= "'".datetime($obj->value)."', ";
                } else {                
                    
$qry .= "'" addslashes(serialize($obj->value)) . "', ";                    
                }
                            
            } else {
                
                
$qry .= "'" $obj->default "', ";
                
            }

        }
        
        
$qry substr($qry0, -2) ;
        
        
$qry .= ')';
        
$this->_action_query->query($qry);
        
        
$key $this->_primary_key;
        
$this->_fields->$key->value =  $this->_action_query->insert_id;
        
        return 
$this->key(); 
         
    }
    
    public function 
update($data$where) {
        
        
$qry "UPDATE {$this->_table_name} SET ";
        
        foreach (
$data as $name => $value) {

            if (
$name == $this->_primary_key) {
                continue;

            }
            
$this->_fields->$name->value $value;
            
$obj $this->_fields->$name;
            
            if (
$name == 'created_at') {
                
                continue;            
    
            } elseif (
$name == 'updated_at') {
                
                
$qry .= $name " = '" date('Y-m-d H:i:s')  . "', ";

            } elseif (
$obj->null == 'YES' && ($obj->value === '' || $obj->value === null)) {
            
                
$qry .= $name " = " "NULL, ";
                
            } elseif (
is_bool($obj->value)) {
                
                
$qry .= $name " = " "'" . ($obj->value 0) . "', ";
                

            } elseif (
is_numeric($obj->value)) {
                
                
$qry .= $name " = " "'" $obj->value "', ";
                
            } elseif (
is_string($obj->value)) {
                
                
$qry .= $name " = " "'" addslashes(trim($obj->value)) . "', ";
                
            } elseif (
is_array($obj->value)) {
                
                
// if datetime save array
                
if ( $this->_fields->$name->type == 'datetime' ) {
                    
$qry .= $name " = " "'".datetime($obj->value)."', ";
                } else {                
                    
$qry .= $name " = " "'" addslashes(serialize($obj->value)) . "', ";                    
                }
                            
            }else {
                
                
$qry .= $name " = " "'" $obj->default "', ";
                
            }

            
        }
        
        
$qry substr($qry0, -2) ;
        
$key $data[$this->_primary_key];
        
$qry .= " WHERE {$this->_primary_key} = '{$key}'";
        
$this->_action_query->query($qry);
        
        
//$key = $this->_primary_key;
        //$this->_fields->$key->value = $this->_action_query->insert_id;
        
        
return $key
    }
    
    public function 
delete($where null)
    {
        
// if no $where    delete current load record
        
if ( !$where ) {
            
$property $this->_primary_key;
            
$where "{$this->_primary_key} = '{$this->$property}' LIMIT 1";
        }
        
$this->_action_query->query("DELETE FROM {$this->_table_name} WHERE $where");
        
        return 
$this->_action_query->row_count;
    }
    
    public function 
values() {
        
$ret = array();
        
        foreach ( 
$this->_fields as $field => $obj ) {
        
            
$ret[$field] = $obj->value;
        }
        
        return 
$ret;
        
    }
    
    public function 
find($args false) {
        
$this->reset();
        
    
        switch (
true) {
            case isset(
$args['total']):
                
$this->select('count(*) as total ');
                break;
            case isset(
$args['selected']):
                
$this->select($args['selected']);
                break;
            default:
                break;
        }
        
        if (isset(
$args['from'])) {
            
$this->from($args['from']);    
        }
        
        if (isset(
$args['where'])) {
            
$this->where($args['where']);    
        }
        
        if (isset(
$args['group'])) {
            
$this->group($args['group']);    
        }
        
        if (isset(
$args['order'])) {
            
$this->order($args['order']);    
        }

        if (isset(
$args['limit'])) {
            
$this->limit($args['limit']);    
        }
        
        if (isset(
$args['offset'])) {
            
$this->offset($args['offset']);    
        }
        
        return 
$this->query();
    }
    
    public function 
find_all($args null) {
        
        unset(
$args['limit']);
        unset(
$args['offset']);
        
$this->find($args);
    
    }
    
    public function 
find_first($args null) {
        
$args['limit'] = 1;
        
$this->find($args);
        return 
$this->next();
    }
    
    public function 
find_total($args null) {
    
        
$args['total'] = true;
        unset(
$args['limit']);
        unset(
$args['offset']);
        unset(
$args['select']);
        
$this->find($args);
        
        
$row $this->_select_query->get_row();
        
$this->reset();
        return 
$row['total'];
        
    }
    
    public function 
select($select) {
        
$this->_select $select;
    }
    
    public function 
from($from) {
        
$this->_from $from;
    }
    
    public function 
where($where) {
        
$this->_where $where;
    }
    
    public function 
order($order) {
        
$this->_order $order;
    }
    
    public function 
group($group) {
        
$this->_group $group;
    }
    
    public function 
limit($limit$offset null) {
        
$this->_limit $limit;
        
$this->_offset $offset;
    }
    
    public function 
offset($offset)
    {
        
$this->_offset $offset;
    }
    
    public function 
query($str null) {
        if (
$str) {
            
$this->_query_str $str
        } else {
            
$this->_build_qry();
        }
        
        return 
$this->_select_query->query($this->_query_str);
    }
    
    public function 
query_str($no_breaks false) {
        if (! 
$this->_query_str$this->_build_qry();
        
        if (
$no_breaks) {
            return 
$this->_query_str;
        } else {
            return 
nl2br($this->_query_str);
        }
    
    }
    
    
    private function 
_build_qry() {
        
        
$str '';
        
        if (
$this->_select) {
            
$str .= "SELECT " $this->_select "\n";
        } else {
            
$str .= "SELECT * \n";
        }
        
        if (
$this->_from) {
            
$str .= "FROM " $this->_from "\n";
        } else {
            
$str .= "FROM " $this->_table_name "\n";
        }
        
        if (
$this->_where) {
            
$str .= "WHERE " $this->_where "\n";
        } else {
            
$str .= "WHERE 1 \n";
        }
        
        if (
$this->_group) {
            
$str .= "GROUP BY " $this->_group "\n";
        }
        
        if (
$this->_order) {
            
$str .= "ORDER BY " $this->_order "\n";
        }
        
        if (
$this->_offset) {
            
$str .= "LIMIT " $this->_offset ', ' $this->_limit "\n";
        } else {
            if (
$this->_limit) {
                
$str .= "LIMIT " $this->_limit "\n";
            }
        }
        
        
$this->_query_str $str;
    }
    
    public function 
reset() {
        
$this->_select null;
        
$this->_from null;
        
$this->_where null;
        
$this->_group null;
        
$this->_order null;
        
$this->_limit null;
        
$this->_offset null;
        
$this->_query_str null;
        
$this->_select_query->reset();
    
    }
    
    
    
//iterator interface
    
        /**
       * Return the array "pointer" to the first element
       * PHP's reset() returns false if the array has no elements
       */
     
function rewind(){
        
        
$this->_select_query->rewind();
        
$this->next();
    }

   
/**
   * Return the current array element
   */
     
function current(){
        return 
$this->_create_child();
     }

   
/**
   * Return the key of the current array element
   */
     
function key(){
        
$function 'get_' $this->_primary_key;
        
        return 
$this->$function();
    }

   
/**
   * Move forward by one
   * PHP's next() returns false if there are no more elements
   */
    
function next(){
        
          if ( 
$this->get_pointer() <= ( $this->row_count() - ) ) {
        
            
$row $this->_select_query->get_row($this->get_pointer(), $type);
            
$this->load_values_into_fields($row$type);
            
$this->_select_query->pointer++;
            
$this->_valid true;
            return 
$row;
            
        } else {
            
$this->_valid false;
            
$this->_select_query->pointer--;
            return 
false;
            
        }
    }

   
/**
   * Is the current element valid?
   */
     
function valid(){
        return 
$this->_valid;
       }
    
    private function 
_create_child()
    {
        return clone 
$this;
        
/*
        $item = new $this;
        $item->load_values_into_fields($this->values());
        return $item;
        */
    
}
    
    public function 
get_pointer()
    {
        return 
$this->_select_query->pointer $this->_select_query->pointer 0;
    }
    
    public function 
row_count() {
        
        return 
$this->_select_query->row_count;
    
    }
    
    public function 
get_affected_rows()
    {
        return 
$this->_select_query->get_affected_rows();
    }
    
    private function 
load_values_into_fields($data$type self::ROW_ASSOC)
    {
    
        switch ( 
$type ) {
        
            default:
                foreach ( 
$data as $field => $value $this->_fields->$field->value $value;
            break;
            
        }
        
    }
    
    public function 
get_values()
    {
        
$ret_array = array();
        foreach ( 
$this->_fields as $field => $attributes ) {
            
$ret_array[$field] = $attributes->value;
        }
        return 
$ret_array;
    }
    
    
/**
    * Magic Functions
    *
    * @author John Faircloth, Nesbert Hidalgo
    * @access public
    * @param string $method name of function being called
    * @param array $arguments passed to the function
    */
    
public function __call($method$arguments)
    {
    
        try {
        
            switch ( 
true ) {
    
                case 
preg_match('/^get_(.+)$/'$method$regs):
                    
                    if ( isset(
$this->_fields->$regs[1]) ) {
                        
                        if ( 
is_string($this->_fields->$regs[1]->value) ) {
    
                            return 
stripslashes($this->_fields->$regs[1]->value);
    
                        } else {
    
                            return 
$this->_fields->$regs[1]->value;
    
                        }
    
                    } else {
    
                        throw new 
Exception("Property '{$property}' not found in <strong>".get_class($this)."</strong> model.");
                        
                    }
                    
                break;
                
                case 
preg_match('/^set_(.+)$/'$method$regs):
    
                    if (isset(
$this->_fields->$regs[1])) {
    
                        if ( 
count($arguments) != 1) {
    
                            throw new 
Exception("Too many parameters for method '{$method}' in <strong>".get_class($this)."</strong> model. One expected, ".count($arguments)." given.");
    
                        } else {
    
                            if ( 
$regs[1] == $this->_primary_key ) {
                            
                                
$this->reset();
                                
                                
$this->_select_query->query("SELECT * FROM {$this->_table_name} WHERE {$this->_primary_key} = '{$arguments[0]}'");
                                
                                if ( 
$this->_select_query->row_count ) {
                                        
                                    
$row $this->_select_query->get_row();
                    
                                    
$this->load_values_into_fields($row$type);
                    
                                    return 
true;
                    
                                } else {
                    
                                    return 
false;
                                
                                }
    
                            
                            } else {
                            
                                
$this->_fields->$regs[1]->value $arguments[0];
                            
                            }
                            
                            return 
true;
    
                        }
    
                    } else {
                    
                        throw new 
Exception("Property '{$property}' not found in <strong>".get_class($this)."</strong> model.");
        
                    }
                
                break;
    
                case 
preg_match('/^find_by_(.+)$/'$method$regs):
                    
$args['where'] = $this->_conditions_str_from_method($method$arguments);
                    
$args['limit'] = 1;
                    
$this->find($args);
                    break;
    
                case 
preg_match('/^find_first_by_(.+)$/'$method$regs):
                    
$args['where'] = $this->_conditions_str_from_method($method$arguments);
                    
$args['limit'] = 1;
                    
$this->find($args);
                    
$this->next();
                break;
    
                case 
preg_match('/^find_total_by_(.+)$/'$method$regs):
                    
$args['where'] = $this->_conditions_str_from_method($method$arguments);
                    return 
$this->find_total($args);
                    break;
                    
                case ( 
preg_match('/^validates_(.+)$/'$method$regs) ):
                    
$this->_validate_by_method($method$arguments);
                break;
                
                
/* Paging Links */
                
case ( preg_match('/^link_to_(.+)$/'$method$regs) ):
                case ( 
preg_match('/^paging_(.+)$/'$method$regs) ):
                    if ( 
method_exists($this->page$method) ) {
                        return 
call_user_func_array(array($this->page$method), $arguments);                                
                    } else {
                        throw new 
Exception("Undefined method '{$method}' in <strong>".get_class($this)."</strong> model.");
                    }
                break;
                
                default:
                    throw new 
Exception("Undefined method '{$method}' in <strong>".get_class($this)."</strong> model.");
                break;
                    
            }

        } catch ( 
Exception $e ) {
        
            
// add to errors
            
$_ENV['error']->add($e->getMessage(), $e);
        
        }
        
    }
    
    public function 
__set($property$value)
    {

        try {
                
            if ( isset(
$this->_fields->$property) ) {
    
                
$function 'set_' $property;
                return 
$this->$function($value);
            
            } else {
            
                throw new 
Exception("Property '{$property}' not found in <strong>".get_class($this)."</strong> model.");
    
            }
            
        } catch ( 
Exception $e ) {
        
            
// add to errors
            
$_ENV['error']->add($e->getMessage(), $e);
        
        }        

    }
    
    public function 
__get($property) {
    
        try {
                
            if ( isset(
$this->_fields->$property) ) {
            
                
$function 'get_' $property;
                return 
$this->$function($value);
            
            } else if (
array_key_exists($property$this->_links)) {
    
                return 
$this->get_link_object($property);
            
            } else {
            
                throw new 
Exception("Property '{$property}' not found in <strong>".get_class($this)."</strong> model.");
                
            }
            
        } catch ( 
Exception $e ) {
        
            
// add to errors
            
$_ENV['error']->add($e->getMessage(), $e);
        
        }        
            
    }
    
    public function 
has_many($name$options = array()) {
        
        
$this->_links[$name]['type'] = 'has_many';
        
$this->_links[$name]['options'] = $options;
        
$this->_links[$name]['linked_to'] = false;
        
$this->_links[$name]['object'] = false;
    
    }
    
    public function 
belongs_to($name$options = array()) {
        
        
$this->_links[$name]['type'] = 'belongs_to';
        
$this->_links[$name]['options'] = $options;
        
$this->_links[$name]['linked_to'] = false;
        
$this->_links[$name]['object'] = false;
        
    }
    
    public function 
has_many_link($name$options = array()) {
        
$this->_links[$name]['type'] = 'has_many_link';
        
$this->_links[$name]['options'] = $options;
        
$this->_links[$name]['linked_to'] = false;
        
$this->_links[$name]['object'] = false;
    
    }
    
    public function 
has_one($name$options = array()) {
    
        
$this->_links[$name]['type'] = 'has_one';
        
$this->_links[$name]['options'] = $options;
        
$this->_links[$name]['linked_to'] = false;
        
$this->_links[$name]['object'] = false;
    
    }
    
    private function 
get_link_object($name) {
        
        if (!
$this->is_linked($name)) {
    
            if(!
$this->create_link($name)) {

                return 
false;
            }
        } 
    
        return 
$this->_links[$name]['object'];
    }
    
    private function 
is_linked($name) {
        if (
$this->key()) {
            if (
$this->_links[$name]['linked_to'] == $this->key()) {
                return 
true;
            } else {
                
                return 
false;
            }    
        } else {
            return 
false;
        }
    }
    
    private function 
create_link($name) {

        
        if (
$this->_links[$name]['options']['class_name']) {
            
            
$model_name $this->_links[$name]['options']['class_name'];
            
        } else {
        
            
$model_name singularize($name);
        
        }
        
        
$model_obj = new $model_name();
        
$args $this->_links[$name]['options'];
    
        if (!
$this->_links[$name]['options']['foreign_key']) {
            
$this->_links[$name]['options']['foreign_key'] = $this->_class() . '_id';
        }        
            
        if (
$this->get_id()) {
            
            switch(
$this->_links[$name]['type']) {
                case 
'has_many':
                    if (
$args['where']) {
                        
$args['where'] = ' ' $this->_links[$name]['options']['foreign_key'] . " = '" $this->key() . "' and (" $args['where'] . ")" 
                    } else {
                        
$args['where'] = ' ' $this->_links[$name]['options']['foreign_key'] . " = '" $this->key() ."'";
                    }
                    
                    
$model_obj->find($args);
                    
                    break;
                case 
'has_many_link':
                
/*    $args['selected'] = $model_obj->get_table_name().'.*';
                    $args['from'] = $model_obj->get_table_name().', ' . $this->links[$name]['link_table'];
                    $args['conditions'] = $this->links[$name]['other_table_id'] . ' = ' . $model_obj->get_table_name(). '.id and '.$this->links[$name]['this_table_id'].' = ' . $this->get_id() .' ' . $args['conditions'];
                    
                    $model_obj->find($args);
                */
                    
break;
                case 
'has_one':
                
                    if (
$args['where']) {
                        
$args['where'] = ' ' $this->_links[$name]['options']['foreign_key'] . " = '" $this->key() . "' and (" $args['where'] . ")" 
                    } else {
                        
$args['where'] = ' ' $this->_links[$name]['options']['foreign_key'] . " = '" $this->key();
                    }
                    
$model_obj->find_first($args);
                    break;
                
                case 
'belongs_to':
                    
/*$function = 'get_' . $this->links[$name]['link_field'];
                    if ($this->links[$name]['link_field']) {
                        $args['conditions'] .= " id = '" . $this->$function() . "' "; 
                    }
                    $model_obj->find_first($args);
                    */
                    
break;
            
            }
        } 
                
        
$this->_links[$name]['object'] = $model_obj;
        
$this->_links[$name]['linked_to'] = $this->key();
        
        return 
true;
    
        
    }
    
    
/**
    * Alias to find and set the $page object. default page limit is 10 records
    *
    * @author Nesbert Hidalgo
    * @access private
    * @param string $method required
    * @param array $args optional
    */
    
private function _validate_by_method($method$args null)
    {
        switch ( 
$method ) {
        
            case 
'validates_uniqueness_of':
                
// check if a column with that value exists in the current table and is not the currentlly loaded row
                
$this->_action_query->query("SELECT * FROM {$this->_table_name} WHERE {$args[0]} = '{$args[1]}' AND {$this->_primary_key} != '{$this->id}'");
                
// if record found add error
                
if ( $this->_action_query->row_count ) {
                    
$this->errors->add($args[0], ( $args[2] ? $args[2] : humanize($args[0]).' is not unique.' ));
                } else {
                    return 
true;                
                }
            break;
            
            default:
                if ( 
method_exists($this->validation$method) ) {
                    
call_user_func_array(array($this->validation$method), $args);
                } else {
                    
$_ENV['error']->add("Undefined validation '{$method->_action}' in <strong>{get_class()}</strong>");
                }
            break;
            
        }
    }
    
    
/**
    * Creates SQL string for conditons used for find_by... magic funtions
    *
    * @author Nesbert Hidalgo
    * @access private
    * @param string $method required
    * @param array $args required
    * @return string
    */
    
private function _conditions_str_from_method($method$args)
    {
        
// remove find_by... from method name
        
$method str_replace(array('find_by_','find_first_by_''find_total_by_'), ''$method);
        
$args_index 0;
        
$return '';
        
        
// if no "AND" or "OR" return single column sql
        
if ( !strstr($method'_and_') && !strstr($method'_or_') ) {
            return  
"{$method} = '{$args[0]}'";
        }
        
        
// hande "OR" and create/return sql string
        
if ( strstr($method'_or_') ) {
            
$ors explode('_or_'$method);
            
$or_count 1;
            foreach ( 
$ors as $or ) {
                
// hande "AND" and append to sql string
                
if ( strstr($or'_and_') ) {                
                    
$ands explode('_and_'$or);
                    
$return .= '(';
                    foreach ( 
$ands as $field ) {
                        
$return .= "{$field} = '{$args[$args_index]}' AND ";
                        
$args_index++;            
                    }
                    
$return substr($return0, -4).')';
                } else {
                    
$return .= "{$or} = '{$args[$args_index]}'";
                    
$args_index++;            
                }
                
                
// and or if not last $or
                
if ( count($ors) != $or_count $return .= ' OR ';
                
$or_count++;        
            }
            
            
// clean return string
            
if ( substr($returnstrlen($return) -33) == 'OR ' ) {
                
$return substr($return0, -3);
            }
            
            return 
str_replace('OR OR ''OR '$return);
        }
        
        
// handle "AND" and create/return sql string
        
if ( strstr($method'_and_') ) {
            
$ands explode('_and_'$method);
            foreach ( 
$ands as $field ) {
                
$return .= "{$field} = '{$args[$args_index]}' AND ";
                
$args_index++;            
            }
            
$return substr($return0, -4);
        }
        
        return 
$return;
    
    }

    
/**
     * Alias to find and set the $page object. default page limit is 10 records
     *
     * @author Nesbert Hidalgo
     * @access public
     * @param array $args optional
     */
    
public function paginate($args null)
    {
    
        
// create temp args
        
$temp $args;
        unset(
$temp['offset']);
        
$temp['total_records'] = $this->find_total($temp);
        
$temp = (object) $temp;
        
        
// create page object
        
$this->page = new pager($temp);
        
        
// update agrs with paging data
        
$args['offset'] = $this->page->offset;
        
$args['limit'] = $this->page->limit;
        
        
// execute query
        
$this->find($args);
        
    }
    
    
    
/*
     * Callback Functions -> Override If Needed
     */
    
public function before_save() {}
    public function 
before_create() {}
    public function 
after_save() {}
    public function 
validate() {}
    public function 
validate_on_create() {}
    public function 
validate_on_update() {}    

}
?>