#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($qry, 0, -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 ? 1 : 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($qry, 0, -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 ? 1 : 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($qry, 0, -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() - 1 ) ) { $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($return, 0, -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($return, strlen($return) -3, 3) == 'OR ' ) { $return = substr($return, 0, -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($return, 0, -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() {}
} ?>
|