00001 <?php
00021 class SModel extends SObject {
00023 private $DBI = "";
00025 private $entity;
00027 private $isMarkedForDeletion = false;
00028 private $touchedValues = array();
00029
00042 public function __construct($id = "") {
00043 global $DBI;
00044
00045
00046
00047 $class = get_class($this);
00048 $this->setEntity($this->lowercaseFirst($class));
00049
00050
00051 if (isset($DBI)) {
00052 $this->setDBI($DBI);
00053 }
00054
00055
00056 if ($id !== ""){ $this->populate($id); }
00057 else { $this->reset(); }
00058
00059 return true;
00060 }
00061
00070 public function getAttributes() {
00071 return array();
00072 }
00073
00085 public function getUniqueAttributes() {
00086 return array();
00087 }
00088
00089
00090
00091
00092
00093
00094
00109 public function populate($id = "") {
00110
00111
00112 if (count($this->getError()) > 0){
00113 $this->setError($this->getFailedString('populate')
00114 . "Object error count is non-zero.");
00115 return false;
00116 }
00117
00118
00119 $uas = $this->getUniqueAttributes();
00120 if (count($uas) < 1) {
00121 $this->setError($this->getFailedString('populate')
00122 . "No unique attributes specified.");
00123 return false;
00124 }
00125
00126 $pai = 0;
00127 $pa = $uas[$pai];
00128
00129
00130
00131 while ($id === "" && ($pai + 1) < count($uas)) {
00132 $pai++;
00133 if (isset($uas[$pai])){
00134 $pa = $uas[$pai];
00135 $getFn = $this->getFunctionFromEntity($pa);
00136 $id = $this->$getFn();
00137 }
00138 }
00139
00140
00141 if ($id === "") {
00142 $this->setError($this->getFailedString('populate')
00143 . "No populate attribute was set.");
00144 return false;
00145 }
00146
00147
00148
00149 $whereCond = "$pa = '" . $id . "'";
00150
00151
00152 $fkinfo = $this->getForeignKey();
00153 if($fkinfo) {
00154 $query = "SELECT " . implode(", ", array_map(array($this, 'preAppendEntity'), $this->getAttributes()))
00155 . " FROM " . $this->getEntity();
00156 foreach($fkinfo as $fkitem) {
00157 $query .= " LEFT JOIN " . $fkitem['table'] . " ON " . $this->getEntity() . "." . $fkitem['foreignkey']
00158 . " = " . $fkitem['table'] . "." . $fkitem['tablekey'];
00159 }
00160 $query .= " WHERE " . $whereCond . " LIMIT 1;";
00161 } else {
00162
00163 $query = "SELECT "
00164 . implode(", ",
00165 array_map(array($this, 'preAppendEntity'), $this->getAttributes()))
00166 . " FROM " . $this->getEntity() . " WHERE "
00167 . $whereCond
00168 . " LIMIT 1;";
00169 }
00170
00171
00172
00173 if ($this->DBIHasNoError('populate') == false){
00174 return false;
00175 }
00176
00177
00178 $result = $this->getDBI()->query($query);
00179
00180
00181 if ($this->DBIHasNoError('populate',
00182 'Error performing populate query.') == false){
00183 return false;
00184 }
00185
00186
00187
00188 if (count($result) != 1){
00189 $this->setError($this->getFailedString('populate')
00190 . "Record matching $pa $id not found.");
00191 return false;
00192 }
00193
00194
00195
00196
00197 $tmp = $this->getAttributes();
00198 $tmp = array_map(array($this,'convertAttrFromDB'), $tmp);
00199 foreach($tmp as $attribute) {
00200 $setFn = $this->setFunctionFromEntity($attribute);
00201 $this->$setFn($result[0][$attribute]);
00202 }
00203
00204
00205
00206 $this->touchedValues = array();
00207
00208 return true;
00209 }
00210
00218 public function getForeignKey() {
00219 return false;
00220
00221
00222
00223
00224
00225 }
00226
00235 protected function preAppendEntity($value) {
00236 if(strpos($value, ".")) {
00237 $tmp = explode(".", $value);
00238 return $value . " AS " . $tmp[0] . "_" . $tmp[1];
00239 }
00240 else {
00241 return $this->getEntity() . "." . $value;
00242 }
00243 }
00244
00256 public function commitForeign($table, $unique, $attributes, $foreignKey) {
00257
00258 if (count($this->getError()) > 0){
00259 $this->setError($this->getFailedString('commitForeign')
00260 . "Object error count is non-zero.");
00261 print "foo <br />\n";
00262 return false;
00263 }
00264 $priKey = $unique;
00265
00266
00267
00268 $getIdFn = $this->getFunctionFromEntity($priKey);
00269 $setIdFn = $this->setFunctionFromEntity($priKey);
00270
00271 $attrs = explode(", ", $attributes);
00272 $values = array();
00273
00274 foreach($attrs as $attr) {
00275 $getValueFn = $this->getFunctionFromEntity($attr);
00276 array_push($values, "$attr = '" . SWATFunctions::safeSql($this->$getValueFn())
00277 . "'");
00278 }
00279
00280 if ($this->$getIdFn() == "") {
00281
00282 $query = "INSERT INTO " . $table . " SET "
00283 . implode(", ", $values)
00284 . ";";
00285
00286 print "commitForeign query (inserting): $query <br />\n";
00287
00288 $result = $this->getDBI()->query($query);
00289
00290
00291 if ($this->DBIHasNoError('commitForeign',
00292 'Query to insert new record failed.') == false){
00293 return false;
00294 }
00295
00296
00297
00298 $this->$setIdFn($this->getDBI()->mysql_insert_id());
00299 $setFnKey = $this->setFunctionFromEntity($foreignKey);
00300 $this->$setFnKey($this->$getIdFn());
00301
00302 return true;
00303 }
00304
00305
00306
00307
00308 $query = "SELECT " . $priKey . " FROM " . $table
00309 . " WHERE " . $priKey . " = '" . SWATFunctions::safeSql($this->$getIdFn())
00310 . "' LIMIT 1;";
00311
00312 print "commitForeign query (update 1): $query <br />\n";
00313
00314
00315 $result = $this->getDBI()->query($query);
00316
00317
00318 if ($this->DBIHasNoError('commitForeign',
00319 'Query to check for existing record failed.') == false){
00320 return false;
00321 }
00322
00323
00324
00325 if (count($result) != 1) {
00326 $this->setError($this->getFailedString('commitForeign')
00327 . "Can't commit this object; record with $priKey = "
00328 . $this->$getIdFn() . " is not found.");
00329 return false;
00330 }
00331
00332
00333
00334 $query = "UPDATE " . $table . " SET "
00335 . implode(", ", $values)
00336 . " WHERE " . $priKey
00337 . " = '" . SWATFunctions::safeSql($this->$getIdFn()) . "';";
00338
00339 print "commitForeign query (update 2): $query <br />\n";
00340
00341
00342 $result = $this->getDBI()->query($query);
00343
00344
00345 if ($this->DBIHasNoError('commitForeign',
00346 "Query to update existing record with $priKey = "
00347 . $this->$getIdFn() . "failed.") == false){
00348 return false;
00349 }
00350
00351
00352 return true;
00353 }
00354
00370 public function commit() {
00371
00372
00373 if (count($this->getError()) > 0){
00374 $this->setError($this->getFailedString('commit')
00375 . "Object error count is non-zero.");
00376 return false;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 $uas = $this->getUniqueAttributes();
00386 if (count($uas) < 1) {
00387 $this->setError($this->getFailedString('commit')
00388 . "No unique attributes specified.");
00389 return false;
00390 }
00391
00392
00393 $as = $this->getAttributes();
00394 if (count($as) < 1) {
00395 $this->setError($this->getFailedString('commit')
00396 . "No attributes specified.");
00397 return false;
00398 }
00399
00400 if (!$this->isValidObject()){
00401 $this->setError($this->getFailedString('commit')
00402 . "Valid object check fails.");
00403 return false;
00404 }
00405
00406
00407
00408 $priKey = $uas[0];
00409
00410
00411
00412 $getIdFn = $this->getFunctionFromEntity($priKey);
00413 $setIdFn = $this->setFunctionFromEntity($priKey);
00414
00415
00416 $values = array();
00417
00418
00419
00420
00421 foreach($as as $a) {
00422
00423 if ($a == $priKey) continue;
00424
00425 if (strpos($a, ".") > 0) {
00426
00427 continue;
00428 }
00429
00430
00431 $getValueFn = $this->getFunctionFromEntity($a);
00432
00433
00434
00435
00436
00437
00438
00439 if($this->$getValueFn() === null){
00440
00441 if (isset($this->touchedValues[$a])) {
00442
00443
00444
00445 if (!in_array($a, $uas)) {
00446 array_push($values, "$a = NULL");
00447 }
00448 }
00449 } else {
00450 array_push($values, "$a = '"
00451 . SWATFunctions::safeSql($this->$getValueFn())
00452 . "'");
00453 }
00454 }
00455
00456
00457
00458 if ($this->DBIHasNoError('commit') == false){
00459 return false;
00460 }
00461
00462
00463
00464
00465
00466 if ($this->$getIdFn() == "") {
00467
00468
00469 $query = "INSERT INTO " . $this->getEntity();
00470
00471
00472 if (count($values) > 0){
00473 $query .= " SET "
00474 . implode(", ", $values);
00475
00476 } else {
00477 $query .= " VALUES ()";
00478 }
00479
00480 $query .= ";";
00481
00482
00483
00484
00485
00486 $result = $this->getDBI()->query($query);
00487
00488
00489 if ($this->DBIHasNoError('commit',
00490 'Query to insert new record failed.') == false){
00491 return false;
00492 }
00493
00494
00495
00496 $this->$setIdFn($this->getDBI()->mysql_insert_id());
00497
00498
00499
00500 return true;
00501 }
00502
00503
00504
00505
00506 $query = "SELECT " . $priKey . " FROM " . $this->getEntity()
00507 . " WHERE " . $priKey . " = '" . SWATFunctions::safeSql($this->$getIdFn()) . "'"
00508 . " LIMIT 1;";
00509
00510
00511 $result = $this->getDBI()->query($query);
00512
00513
00514 if ($this->DBIHasNoError('commit',
00515 'Query to check for existing record failed.') == false){
00516 return false;
00517 }
00518
00519
00520
00521 if (count($result) != 1) {
00522 $this->setError($this->getFailedString('commit')
00523 . "Can't commit this object; record with $priKey = "
00524 . $this->$getIdFn() . " is not found.");
00525 return false;
00526 }
00527
00528 if ($this->isMarkedForDeletion) {
00529
00530
00531 $query = "DELETE FROM " . $this->getEntity()
00532 . " WHERE " . $this->preAppendEntity($priKey)
00533 . " = '" . SWATFunctions::safeSql($this->$getIdFn()) . "';";
00534
00535 } else {
00536
00537
00538
00539 $query = "UPDATE " . $this->getEntity() . " SET "
00540 . implode(", ", $values)
00541 . " WHERE " . $this->preAppendEntity($priKey)
00542 . " = '" . SWATFunctions::safeSql($this->$getIdFn()) . "';";
00543 }
00544
00545
00546 $result = $this->getDBI()->query($query);
00547
00548
00549 if ($this->DBIHasNoError('commit',
00550 "Query to update existing record with $priKey = "
00551 . $this->$getIdFn() . "failed.") == false){
00552 return false;
00553 }
00554
00555
00556 return true;
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00579 public function isValidObject() {
00580 return true;
00581 }
00582
00586 public function reset() {
00587 $as = $this->getAttributes();
00588 foreach($as as $attribute) {
00589
00590
00591
00592
00593
00594
00595
00596
00597 $setFn = $this->setFunctionFromEntity($attribute);
00598 $this->$setFn(null);
00599 }
00600 $this->isMarkedForDeletion = false;
00601 $this->touchedValues = array();
00602 }
00603
00612 protected function getFailedString($action) {
00613 return "Attempt to $action " . get_class($this) . " failed: ";
00614 }
00615
00616
00626 public function convertAttrToDB($attr) {
00627 if(strpos($attr, "_")) {
00628 return preg_replace("/_/", ".", $attr);
00629 }
00630 else
00631 return $attr;
00632 }
00633
00634
00644 public function convertAttrFromDB($attr) {
00645 if(strpos($attr, ".")) {
00646 return preg_replace("/\./", "_", $attr);
00647 }
00648 else
00649 return $attr;
00650 }
00651
00659 public function getAllAttributes() {
00660 $ret = array();
00661 foreach($this->getAttributes() as $attr) {
00662 $getFn = $this->getFunctionFromEntity($attr);
00663 $attrVal = $this->$getFn();
00664 $ret[$attr] = $attrVal;
00665 }
00666 return $ret;
00667 }
00668
00669
00670
00671
00672
00683 public function getListQuery( $criteria ) {
00684
00685 $keys = array_keys($criteria);
00686 $attributes = $this->getAttributes();
00687 $where_clause = " WHERE";
00688 $limit_clause = "";
00689 $order_clause = "";
00690 $data = array();
00691 $elements = array();
00692 $constraints = false;
00693
00694
00695 foreach( $keys as $key )
00696 {
00697 if ($key == "limit") {
00698 $limit_clause = " LIMIT " . $criteria[$key];
00699 } else if ($key == "order") {
00700 $order_clause = " ORDER BY " . $criteria[$key];
00701 } else if( in_array($key, $attributes) ) {
00702 $constraints = true;
00703
00704
00705
00706 if(!is_array($criteria[$key])){
00707 if ($criteria[$key] === null) {
00708 $element = " " . $key . " IS NULL ";
00709 } else {
00710 $element = " " . $key . "= '" . $criteria[$key] . "' ";
00711 }
00712 } else {
00713 $element = " " . $key . $criteria[$key][1] . "'" . $criteria[$key][0] . "' ";
00714 }
00715 array_push( $elements, $element );
00716 continue;
00717 }
00718 else
00719 {
00720 $this->setError( $key . " attribute passed into getListQuery() may be invalid" );
00721 return false;
00722 }
00723
00724 }
00725
00726 $where_clause .= implode( 'AND', $elements );
00727
00728
00729 $uas = $this->getUniqueAttributes();
00730 if (count($uas) < 1)
00731 {
00732 $this->setError($this->getFailedString('getListQuery')
00733 . "No unique attributes specified.");
00734 return false;
00735 }
00736 $uniqueId = $uas[0];
00737
00738
00739 $query = "SELECT " . $uniqueId .
00740 " FROM " . $this->getEntity();
00741
00742
00743 if ($constraints) $query .= $where_clause;
00744 $query .= $order_clause . $limit_clause . ";";
00745
00746
00747
00748
00749
00750
00751 if ($this->DBIHasNoError('getList') == false){
00752 return false;
00753 }
00754
00755 $result = $this->DBI->query($query);
00756
00757
00758 $className = get_class($this);
00759 for( $i = 0; $i < count($result); $i++ ) {
00760 $newObject = new $className();
00761
00762 $newObject->setDBI($this->getDBI());
00763 $newObject->populate($result[$i][$uniqueId]);
00764 $data []= $newObject;
00765 }
00766
00767 return ($data);
00768 }
00769
00781 public function getList($criteria = "", $nullable = false) {
00782 $allowedInEq = array(">",">=","<","<=","=","<>");
00783 if ($criteria == "") $criteria = array();
00784 assert(is_array($criteria));
00785 $keys = array_keys($criteria);
00786
00787
00788 foreach($keys as $key) {
00789 if($nullable == false){
00790 if (!isset($criteria[$key])){
00791 $this->setError( "attribute $key in the passed parameters is not set" );
00792 return false;
00793 }
00794 }
00795
00796
00797 if(is_array($criteria[$key])){
00798
00799
00800 if(!isset($criteria[$key][0]) || !isset($criteria[$key][1])){
00801 $this->setError( "attribute $key in the passed parameters is not set" );
00802 return false;
00803 } else if (array_search($criteria[$key][1],$allowedInEq) === false){
00804 $this->setError( "invalid equality test in $key" );
00805 return false;
00806 }
00807 }
00808 }
00809
00810
00811 $uas = $this->getUniqueAttributes();
00812 if (count($uas) < 1) {
00813 $this->setError($this->getFailedString('getListQuery')
00814 . "No unique attributes specified.");
00815 return false;
00816 }
00817 $uniqueId = $uas[0];
00818
00819 if (count($criteria) == 0){
00820
00821
00822 $data = array();
00823 $query = "SELECT " . $uniqueId . " FROM " . $this->getEntity() . ";";
00824
00825 $result = $this->DBI->query($query);
00826 $className = get_class($this);
00827
00828 for ($i = 0; $i < count($result); $i++) {
00829 $newItem = new $className();
00830 $newItem->setDBI($this->DBI);
00831 $newItem->populate($result[$i][$uniqueId]);
00832 if ($newItem->hasError()){
00833 $this->setPrettyError('getList', 'Could not populate returned object.');
00834 }
00835 array_push($data, $newItem);
00836 }
00837 return ($data);
00838 } else {
00839
00840 return $this->getListQuery( $criteria );
00841 }
00842 }
00843
00854 public function superGetList($criteria, $order = "", $limit = ""){
00855 $attrib = $this->getAttributes();
00856
00857 $uas = $this->getUniqueAttributes();
00858 if (count($uas) < 1)
00859 {
00860 $this->setError($this->getFailedString('getListQuery')
00861 . "No unique attributes specified.");
00862 return false;
00863 }
00864 $uniqueId = $uas[0];
00865
00866
00867
00868 $query = "SELECT " . $uniqueId .
00869 " FROM " . $this->getEntity() . " ";
00870
00871 $query .= "WHERE" . self::criteriaToString($criteria, $attrib);
00872
00873 if($order != ""){
00874 $query .= self::orderToString($order, $attrib);
00875 }
00876 if($limit != ""){
00877 $query .= self::limitToString($limit);
00878 }
00879
00880 $query .= ";";
00881
00882
00883 $result = $this->DBI->query($query);
00884
00885
00886
00887 $className = get_class($this);
00888 $data = array();
00889 for( $i = 0; $i < count($result); $i++ )
00890 {
00891 array_push( $data, new $className($result[$i][$uniqueId]) );
00892 }
00893
00894 return ($data);
00895 }
00896
00905 public function getByCriteria($criteria) {
00906 return false;
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00926 protected function doreplace($item) {
00927 $result = strpos($item, ".");
00928 if(!$result)
00929 return $item;
00930 else {
00931 return preg_replace("/\./", "_", $item);
00932
00933 }
00934 }
00935
00946 public function __call($m, $args)
00947 {
00948
00949 if ((substr($m, 0, 3) == "get") && (strlen($m) > 3)) {
00950
00951
00952
00953 $pos = strpos($m, "_");
00954 if($pos) {
00955 $tmp = explode("_", substr($m, 3));
00956 $var = $tmp[0] . "_" . $tmp[1];
00957 $var2 = $this->lowercaseFirst($tmp[0]) . "_" . $this->lowercaseFirst($tmp[1]);
00958 }
00959 else {
00960 $var = $this->lowercaseFirst(substr($m, 3));
00961 $var2 = substr($m, 3);
00962 }
00963
00964
00965
00966 $tmp = $this->getAttributes();
00967 $tmp = array_map(array($this,'convertAttrFromDB'), $tmp);
00968
00969 if (in_array($var, $tmp)) {
00970 return $this->$var;
00971 } else if (in_array($var2, $tmp)) {
00972 return $this->$var2;
00973 } else {
00974 print "No attribute: call was: $m <br />\n";
00975 print "$var, $var2 <br />\n";
00976 print_r($tmp);
00977 print "<br />\n";
00978 ob_start();
00979 debug_print_backtrace();
00980 $bt = ob_get_contents();
00981 ob_end_clean();
00982 $bt = preg_replace("/\n/", "<br />\n", $bt);
00983 print $bt;
00984 $this->setError("Attribute $var and $var2 not found on this object.");
00985 return false;
00986 }
00987
00988
00989
00990 }else if ((substr($m, 0, 3) == "set") && (strlen($m) > 3)) {
00991
00992
00993
00994
00995
00996
00997 $pos = strpos($m, "_");
00998 if($pos) {
00999 $tmp = explode("_", substr($m, 3));
01000 $var = $tmp[0] . "_" . $tmp[1];
01001 $var2 = $this->lowercaseFirst($tmp[0]) . "_" . $this->lowercaseFirst($tmp[1]);
01002 }
01003 else {
01004 $var = $this->lowercaseFirst(substr($m, 3));
01005 $var2 = substr($m, 3);
01006 }
01007
01008
01009
01010 if (count($args) < 1) {
01011 print "No args: call was: $m <br />\n";
01012 $this->setError("Call to set attribute $var lacks an argument.");
01013 return false;
01014 }
01015
01016
01017
01018 $tmp = $this->getAttributes();
01019 $tmp = array_map(array($this,'convertAttrFromDB'), $tmp);
01020
01021 if (in_array($var, $tmp)){
01022 $this->$var = $args[0];
01023 $this->touchedValues[$var] = true;
01024 } else if (in_array($var2, $tmp)) {
01025 $this->$var2 = $args[0];
01026 $this->touchedValues[$var2] = true;
01027 } else {
01028 print "No attribute: call was $m <br />\n";
01029 $this->setError("Attribute $var and $var2 not found on this object.");
01030 return false;
01031 }
01032 } else {
01033 $this->setError("Unknown function $m called on object.");
01034 return false;
01035 }
01036 }
01037
01043 public function getEntity() {
01044 return $this->entity;
01045 }
01046
01052 protected function setEntity($entity) {
01053 $this->entity = $entity;
01054 }
01055
01064 public function setDBI($DBI) {
01065 $this->DBI = &$DBI;
01066 }
01067
01074 public function markForDeletion() {
01075 $this->isMarkedForDeletion = true;
01076 }
01077
01081 public function unmarkForDeletion() {
01082 $this->isMarkedForDeletion = false;
01083 }
01084
01090 public function getDBI() {
01091 return $this->DBI;
01092 }
01093
01094
01095
01096
01097
01107 public function setFunctionFromEntity($entity) {
01108 $pos = strpos($entity, ".");
01109 if($pos)
01110 return "set" . strtoupper(substr($entity, 0, 1)) . substr($entity, 1, $pos - 1)
01111 . "_" . strtoupper(substr($entity, $pos + 1, 1))
01112 . substr($entity, $pos + 2);
01113 else
01114 return "set" . strtoupper(substr($entity, 0, 1)) . substr($entity, 1);
01115 }
01116
01126 public function getFunctionFromEntity($entity) {
01127 $pos = strpos($entity, ".");
01128 if($pos)
01129 return "get" . strtoupper(substr($entity, 0, 1)) . substr($entity, 1, $pos - 1)
01130 . "_" . strtoupper(substr($entity, $pos + 1, 1))
01131 . substr($entity, $pos + 2);
01132 else
01133 return "get" . strtoupper(substr($entity, 0, 1)) . substr($entity, 1);
01134 }
01135
01145 public function lowercaseFirst($string) {
01146 return strtolower(substr($string,0,1)) . substr($string, 1);
01147 }
01148
01149
01150
01151
01152
01162 public function DBIHasNoError($function = "<not specified>", $msg = "") {
01163
01164 if ($this->getDBI() == null) {
01165 $this->setError($this->getFailedString($function)
01166 . "No database was found. $msg");
01167 return false;
01168 }
01169
01170
01171 if (count($this->getDBI()->getError()) > 0) {
01172 $this->setError($this->getFailedString($function)
01173 . "An error was generated when connecting to/ "
01174 . "querying the database. $msg");
01175 $this->setError($this->getDBI()->getError());
01176 return false;
01177 }
01178 return true;
01179 }
01180
01181
01182
01192 public static function criteriaToString($arr, $attributes) {
01193 if(is_string($arr))
01194 return $arr;
01195 else if(!is_array($arr)) {
01196 self::setStaticError('Criteria must be string or array!');
01197 return false;
01198 }
01199 else if(count($arr) == 0)
01200 return '';
01201
01202 $collect = "";
01203 $op = "=";
01204 $conj = "AND";
01205 foreach($arr as $k => $v) {
01206
01207 if(ctype_digit((string) $k)) {
01208
01209 if(is_string($v)) {
01210 switch(strtoupper($v)) {
01211 case 'AND':
01212 case 'OR':
01213 $conj = $v;
01214 break;
01215 case '=':
01216 case '>=':
01217 case '<=':
01218 case '<':
01219 case '>':
01220 case '<>':
01221 case 'LIKE':
01222 case 'LIKE BINARY':
01223 case 'IS':
01224 case 'IS NOT':
01225 case 'IS NULL':
01226 case 'IS NOT NULL':
01227 $op = $v;
01228 break;
01229 default:
01230 self::setStaticError("Invalid operator or conjunction in criteria: $v");
01231 return false;
01232 }
01233 }
01234
01235 else if(is_array($v)) {
01236 $res = self::criteriaToString($v, $attributes);
01237 if($res === false)
01238 return false;
01239 if($collect != "")
01240
01241 $collect .= " $conj " . $res;
01242 else
01243 $collect .= $res;
01244 }
01245
01246 else {
01247 self::setStaticError("Invalid operator or conjunction in criteria: $v");
01248 return false;
01249 }
01250 }
01251
01252 else if(is_string($k)) {
01253
01254 if(!in_array($k, $attributes)) {
01255 self::setStaticError("Invalid field '$k' in criteria");
01256 return false;
01257 }
01258
01259
01260 if(is_array($v)) {
01261 foreach($v as $value) {
01262
01263
01264
01265 if($op == 'IS NULL' || $op == 'IS NOT NULL') {
01266 if($collect != "")
01267 $collect .= " $conj $k $op";
01268 else
01269 $collect = "$k $op";
01270 }
01271 else {
01272
01273 if($collect != "")
01274 $collect .= " $conj $k $op '$value'";
01275 else
01276 $collect = "$k $op '$value'";
01277 }
01278 }
01279 }
01280 else {
01281
01282 if($op == 'IS NULL' || $op == 'IS NOT NULL') {
01283 if($collect != "")
01284 $collect .= " $conj $k $op";
01285 else
01286 $collect = "$k $op";
01287 }
01288 else {
01289 if($collect != "")
01290 $collect .= " $conj $k $op '$v'";
01291 else
01292 $collect = "$k $op '$v'";
01293 }
01294 }
01295 }
01296 }
01297
01298
01299 if($collect != "")
01300 $collect = "($collect)";
01301
01302 return $collect;
01303 }
01304
01314 public static function limitToString($limit) {
01315 if($limit == "" || count($limit) == 0)
01316 return '';
01317
01318 if(is_array($limit)) {
01319 if(count($limit) == 2) {
01320 if(!ctype_digit((string) $limit[0]) || $limit[0] < 0 || !ctype_digit((string) $limit[1]) || $limit[1] < 0) {
01321 self::setStaticError('Invalid limit values');
01322 return false;
01323 }
01324 return " LIMIT $limit[0], $limit[1]";
01325 }
01326 else if(count($limit) == 1) {
01327 if(!ctype_digit((string) $limit[0]) || $limit[0] < 0) {
01328 self::setStaticError('Invalid limit values');
01329 return false;
01330 }
01331 return " LIMIT $limit[0]";
01332 }
01333 }
01334 else if(ctype_digit((string) $limit)) {
01335 if($limit < 0) {
01336 self::setStaticError('Invalid limit values');
01337 return false;
01338 }
01339 return " LIMIT $limit";
01340 }
01341
01342 self::setStaticError('Invalid limit array!');
01343 return false;
01344 }
01345
01357 public static function orderToString($order, $attributes) {
01358 if($order == "" || count($order) == 0)
01359 return '';
01360
01361 if(is_array($order)) {
01362 $orderStr = ' ORDER BY ';
01363 foreach($order as $key => $value) {
01364 if(ctype_digit((string) $key)) {
01365 if(!in_array($value, $attributes)) {
01366 self::setStaticError('Invalid attribute \'' . $value . '\'');
01367 return false;
01368 }
01369 $orderStr .= $value . ', ';
01370 }
01371 else {
01372 if(!in_array($key, $attributes)) {
01373 self::setStaticError('Invalid attribute \'' . $key . '\'');
01374 return false;
01375 }
01376 $value = strtoupper($value);
01377 if($value != 'ASC' && $value != 'DESC') {
01378 self::setStaticError('Ordering must be ASC or DESC');
01379 return false;
01380 }
01381 $orderStr .= $key . ' ' . $value . ', ';
01382 }
01383 }
01384 return rtrim($orderStr, ', ');
01385 }
01386 else if(is_string($order)) {
01387 return " ORDER BY $order";
01388 }
01389 else {
01390 self::setStaticError('Invalid order by array');
01391 return false;
01392 }
01393 }
01394
01402 protected function resetTouchedValues() {
01403 $this->touchedValues = array();
01404 }
01405
01413 protected function getTouchedValues() {
01414 return $this->touchedValues;
01415 }
01416
01425 protected function addTouchedValue($key) {
01426 $this->touchedValues[$key] = true;
01427 }
01428 }
01429 ?>