1: <?php
2: 3: 4: 5: 6: 7:
8:
9: namespace GLFramework;
10:
11:
12: class Model
13: {
14: 15: 16:
17: var $db;
18: protected $order = "";
19: 20: 21: 22:
23: protected $table_name = "";
24: 25: 26: 27:
28: protected $definition = array();
29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
42: 43: 44: 45: 46: 47:
48:
49: 50: 51: 52:
53: 54: 55: 56:
57: protected $hidden = array();
58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
68: protected $models = array();
69:
70: 71: 72:
73: public function __construct($data = null)
74: {
75: $this->db = new DatabaseManager();
76: $this->setData($data);
77: }
78:
79: 80: 81: 82: 83:
84: public function insert($data = null)
85: {
86: $fields = $this->getFields();
87: $sql1 = "";
88: $sql2 = "";
89: foreach ($fields as $field) {
90:
91: {
92: $value = $this->db->escape_string($this->getFieldValue($field, $data));
93: $sql1 .= "$field, ";
94: $sql2 .= "'$value', ";
95: }
96: }
97: if (!empty($sql1)) {
98: $sql1 = substr($sql1, 0, -2);
99: $sql2 = substr($sql2, 0, -2);
100:
101: return $this->db->insert("INSERT INTO {$this->table_name} ($sql1) VALUES ($sql2)");
102: }
103: return false;
104: }
105:
106: 107: 108: 109: 110: 111:
112: public function update($data = null)
113: {
114: $fields = $this->getFields();
115: $sql1 = "";
116: foreach ($fields as $field) {
117: $value = $this->getFieldValue($field, $data);
118: if (isset($value) && $value !== '' && !$this->isIndex($field)) {
119: $value = $this->db->escape_string($value);
120: $sql1 .= "$field = '$value', ";
121: }
122: }
123: if (!empty($sql1)) {
124: $sql1 = substr($sql1, 0, -2);
125: $index = $this->getIndex();
126: $indexValue = $this->db->escape_string($this->getFieldValue($index, $data));
127: if (!$indexValue) return false;
128: return $this->db->exec("UPDATE {$this->table_name} SET $sql1 WHERE $index = '$indexValue'", $this->getCacheId($indexValue));
129: }
130: return false;
131: }
132:
133: 134: 135: 136: 137:
138: public function delete()
139: {
140: $index = $this->getIndex();
141: $value = $this->getFieldValue($index);
142: if ($value) {
143: return $this->db->exec("DELETE FROM {$this->table_name} WHERE $index = '$value'", $this->getCacheId($value));
144: }
145: return false;
146: }
147:
148: public function getCacheId($id)
149: {
150: return $this->table_name . "_" . $id;
151: }
152: 153: 154: 155: 156: 157:
158: public function get($id)
159: {
160: if (!is_array($id)) {
161:
162: $index = $this->getIndex();
163: $id = $this->db->escape_string($id);
164: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE $index = '$id' ", $this->getCacheId($id)));
165: } else if (is_array($id)) {
166: $fieldsValue = $id;
167: $fields = $this->getFields();
168: $sql = "";
169: foreach ($fields as $field) {
170: if (isset($fieldsValue[$field])) {
171: $value = $fieldsValue[$field];
172: $sql .= $field . "= '" . $this->db->escape_string($value) . "' AND ";
173: }
174: }
175: if (!empty($sql)) {
176: $sql = substr($sql, 0, -5);
177: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE $sql"));
178: }
179: }
180: return $this->build(array());
181: }
182:
183: 184: 185: 186: 187: 188:
189: public function get_or($fields)
190: {
191: $fieldsValue = $fields;
192: $fields = $this->getFields();
193: $sql = "";
194: foreach ($fields as $field) {
195: if (isset($fieldsValue[$field])) {
196: $value = $fieldsValue[$field];
197: if(is_array($value))
198: {
199: foreach($value as $subvalue)
200: {
201: $sql .= $field . "= '" . $this->db->escape_string($subvalue) . "' OR ";
202: }
203: }
204: else
205: {
206: $sql .= $field . "= '" . $this->db->escape_string($value) . "' OR ";
207: }
208: }
209: }
210: if (!empty($sql)) {
211: $sql = substr($sql, 0, -4);
212: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE $sql"));
213: }
214: return $this->build(array());
215: }
216:
217: 218: 219: 220:
221: public function get_all()
222: {
223: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE 1"));
224: }
225:
226: 227: 228: 229: 230:
231: public function get_others()
232: {
233: $index = $this->getIndex();
234: $value = $this->getFieldValue($index);
235: if ($value)
236: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE $index != '$value'"));
237: return $this->get_all();
238:
239: }
240:
241: 242: 243: 244: 245: 246:
247: public function search($fields)
248: {
249: if(!is_array($fields)) $fields = array($this->getIndex() => $fields);
250:
251: $fieldsValue = $fields;
252: $fields = $this->getFields();
253: $sql = "";
254: foreach ($fields as $field) {
255: if (isset($fieldsValue[$field])) {
256: $value = $fieldsValue[$field];
257: if($this->isString($field))
258: $sql .= $field . " LIKE '%" . $this->db->escape_string($value) . "%' OR ";
259: else
260: $sql .= $field . " = '" . $this->db->escape_string($value) . "' OR ";
261:
262: }
263: }
264: if (!empty($sql)) {
265: $sql = substr($sql, 0, -4);
266: return $this->build($this->db->select("SELECT * FROM {$this->table_name} WHERE $sql"));
267: }
268: return $this->build(array());
269: }
270:
271: 272: 273: 274: 275:
276: public function save($updateIndex = false)
277: {
278: if($this->exists())
279: {
280: return $this->update();
281: }
282: $result = $this->insert();
283: if($result && $updateIndex)
284: $this->setToIndex($result);
285:
286: return $result;
287: }
288:
289: 290: 291: 292:
293: public function exists()
294: {
295: $indexValue = $this->getFieldValue($this->getIndex());
296: if ($indexValue) {
297: return $this->get($indexValue)->count() > 0;
298: }
299: return false;
300: }
301:
302: 303: 304: 305: 306: 307:
308: public function getFieldValue($field, $data = null)
309: {
310: if ($data != null && isset($data[$field])) {
311: return $data[$field];
312: }
313: if (isset($this->{$field})) {
314: return $this->{$field};
315: }
316: return null;
317: }
318:
319: 320: 321: 322:
323: public function getFields()
324: {
325: $fields = array();
326: if (isset($this->definition['index'])) {
327: $fields[] = $this->getIndex();
328: }
329: if (isset($this->definition['fields'])) {
330: foreach ($this->definition['fields'] as $key => $value) {
331: if (!is_numeric($key))
332: $fields[] = $key;
333: else
334: $fields[] = $value;
335: }
336: }
337: return $fields;
338: }
339:
340: 341: 342: 343:
344: public function getIndex()
345: {
346: if (isset($this->definition['index'])) {
347: if (is_array($this->definition['index']))
348: return $this->definition['index']['field'];
349: return $this->definition['index'];
350: }
351: return null;
352: }
353:
354: 355: 356: 357:
358: public function setToIndex($value)
359: {
360: $field = $this->getIndex();
361: if($field)
362: $this->{$field} = $value;
363: }
364:
365: 366: 367: 368: 369:
370: public function isIndex($field)
371: {
372: return $this->getIndex() == $field;
373: }
374:
375: 376: 377: 378: 379:
380: public function build($result)
381: {
382: $modelResult = new ModelResult($this);
383: $modelResult->models = $result;
384: if (count($result) > 0) {
385: $modelResult->model = $result[0];
386: }
387: if($this->order != "") $modelResult->order($this->order);
388: return $modelResult;
389: }
390:
391: public function setDataFromArray($data, $prefix = "", $suffix = "")
392: {
393:
394: }
395:
396: 397: 398: 399: 400: 401: 402: 403:
404: public function setData($data, $allowEmpty = true, $allowUnset = false)
405: {
406: if ($data != null) {
407: if(is_array($data))
408: {
409: $fileds = $this->getFields();
410: foreach ($fileds as $field) {
411: if (isset($data[$field]) && ($allowEmpty || $data[$field] !== '')) {
412: if(strpos($this->getFieldType($field), "varchar") !== FALSE ||
413: $this->getFieldType($field) == "text")
414: {
415:
416: $encoding = mb_detect_encoding($data[$field]);
417: if($encoding != 'utf8')
418: $this->{$field} = mb_convert_encoding($data[$field], 'utf8', $encoding);
419: else
420: $this->{$field} = $data[$field];
421: }
422: else
423: {
424:
425: $this->{$field} = $data[$field];
426: }
427: }
428: else if($allowUnset)
429: {
430: $this->{$field} = false;
431: }
432: }
433: }
434: else
435: {
436: $result = $this->get($data);
437: $this->setData($result->model);
438: if(empty($result->model)) $this->asDefault();
439: }
440: }
441: if(empty($data))
442: {
443: $this->asDefault();
444: }
445: return $this;
446: }
447:
448: 449: 450: 451:
452: public function getDefinition()
453: {
454: return $this->definition;
455: }
456: 457: 458: 459:
460: public function getFieldDefinition($field)
461: {
462: if(isset($this->definition[$field]))
463: return $this->definition[$field];
464: if(isset($this->definition['fields'][$field]))
465: return $this->definition['fields'][$field];
466: return null;
467: }
468:
469: 470: 471: 472: 473:
474: public function getFieldType($field)
475: {
476: $definition = $this->getFieldDefinition($field);
477: if($definition)
478: {
479: return $definition['type'];
480: }
481: }
482:
483: 484: 485: 486:
487: public function getTableName()
488: {
489: return $this->table_name;
490: }
491:
492: 493: 494: 495: 496:
497: public function getStructureDifferences()
498: {
499: $diff = new DBStructure();
500: $excepted = $diff->getDefinition($this);
501: return $diff->getStructureDifferences($excepted);
502: }
503:
504: 505: 506: 507: 508: 509: 510:
511: public function json($fields = array())
512: {
513: $json = array();
514: if($url = $this->url())
515: {
516: $json['url'] = fix_url($url);
517: }
518: if(empty($fields)) $fields = $this->getFields();
519: foreach($fields as $field)
520: {
521: if(!in_array($field, $this->hidden))
522: {
523: if(isset($this->models[$field]))
524: {
525: $modelTransform = $this->models[$field];
526:
527: if(is_array($modelTransform))
528: {
529: $name = $modelTransform['name'];
530: $model = $modelTransform['model'];
531: $object = new $model($this->getFieldValue($field));
532: $json[$name] = $object->json();
533: }
534: else
535: {
536: $name = $this->underescapeName($modelTransform);
537: $object = new $modelTransform($this->getFieldValue($field));
538: $json[$name] = $object->json();
539: }
540: }
541: else
542: {
543: $json[$field] = $this->getFieldValue($field);
544: }
545: }
546: }
547:
548: return $json;
549: }
550:
551: 552: 553: 554: 555:
556: public function underescapeName($name)
557: {
558: if(preg_match_all("#([A-Z][a-z]*)#", $name, $matches))
559: {
560: return implode("_", array_map('strtolower', $matches[1]));
561: }
562: }
563: public function isString($field)
564: {
565: $def = strtolower( $this->getFieldDefinition($field) );
566: if(strpos($def, "varchar") !== FALSE) return true;
567: if(strpos($def, "text") !== FALSE) return true;
568: return false;
569: }
570:
571: 572: 573: 574:
575: public function asDefault(){}
576:
577: 578: 579: 580: 581: 582:
583: public function valid($fields = array())
584: {
585: if(empty($fields))
586: {
587: $fields = array_diff($this->getFields(), array($this->getIndex()));
588: }
589: foreach ($fields as $field)
590: {
591: $value = $this->getFieldValue($field);
592: if(!empty($value)) return true;
593: }
594: return false;
595: }
596:
597:
598: 599: 600: 601:
602: public static function newInstance($baseclass, $args = array())
603: {
604: print_debug($baseclass, get_class());
605: }
606:
607: public function url()
608: {
609: return null;
610: }
611:
612:
613: }