PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/core/AROrm.php

https://bitbucket.org/decease/arorm
PHP | 228 lines | 155 code | 34 blank | 39 comment | 10 complexity | 01429ff39e422e16b02cfb9892d42a9d MD5 | raw file
  1. <?php
  2. require_once ('MySqlDB.php');
  3. class AROrm
  4. {
  5. /***
  6. * @param $connectionString
  7. * @param $dbType - выбор типа БД, пока только MySql
  8. */
  9. public static function Initialize($dbType, $connectionString)
  10. {
  11. DB::Connect($connectionString);
  12. }
  13. }
  14. abstract class BaseEntity
  15. {
  16. private $_entityName;
  17. private $_data = ['id' => 0];
  18. //static $foreignKey = null;
  19. public function __construct()
  20. {
  21. $this->_entityName = get_called_class();
  22. }
  23. /***
  24. * @return array Возвращает массив из всех существующих сущностей
  25. */
  26. public static function FindAll()
  27. {
  28. $entityName = get_called_class();
  29. $query = "SELECT * FROM " . strtolower($entityName) . "s";
  30. $res = DB::ResultQuery($query);
  31. return self::toEntitysArray($res);
  32. }
  33. /***
  34. * @param $id - Идентификатор сущности
  35. * @return BaseEntity Возвращает сущность с Id = $id
  36. */
  37. public static function Find($id)
  38. {
  39. $id = intval($id);
  40. $entityName = get_called_class();
  41. $tableName = strtolower($entityName) . "s";
  42. $query = "SELECT * FROM " . $tableName .
  43. " WHERE id = $id LIMIT 1";
  44. $res = DB::ResultQuery($query);
  45. $entity = new $entityName;
  46. $entity->_data = $res[0];
  47. return $entity;
  48. }
  49. /***
  50. * Сохраняет изменения внесенные в сущность, либо создает новую сущность
  51. */
  52. public function Save()
  53. {
  54. //TODO: Make validation!!
  55. if ($this->_data['id'] == 0)
  56. {
  57. $keys = [];
  58. $values = [];
  59. foreach ($this->_data as $key => $value) {
  60. $keys[] = $key;
  61. $values[] = is_string($value) ? "'$value'" : $value;
  62. }
  63. $query = "INSERT INTO " . $this->getTableName() . " (" .
  64. implode(", ", $keys) . ") VALUES (" .
  65. implode(", ", $values) . ")";
  66. $this->_data['id'] = DB::LastInsertId();
  67. }
  68. else
  69. {
  70. $conds = [];
  71. foreach ($this->_data as $key => $value)
  72. {
  73. $conds[] = $key . "=" . (is_string($value) ? "'$value'" : $value);
  74. }
  75. $query = "UPDATE " . $this->getTableName() . " SET " .
  76. implode(", ", $conds) .
  77. " WHERE id = " . $this->_data['id'];
  78. }
  79. DB::Query($query);
  80. }
  81. /***
  82. * Удаляет текущую сущность
  83. */
  84. public function Delete()
  85. {
  86. $this->_delete($this->_data['id']);
  87. }
  88. /***
  89. * @param array $ids Массив идентификаторов элементов, подлежащих
  90. * удалению
  91. */
  92. public static function DeleteAtRang(array $ids)
  93. {
  94. foreach ($ids as $id)
  95. self::_delete($id);
  96. }
  97. /***
  98. * Устанавливает внешнюю связь с другой таблицей
  99. * @param $foreignKey
  100. * @param BaseEntity $referenceEntity
  101. */
  102. public static function JoinTo($foreignKey, BaseEntity $referenceEntity)
  103. {
  104. }
  105. private static function _delete($id)
  106. {
  107. $id = intval($id);
  108. $query = "DELETE FROM " . strtolower(get_called_class()) . "s WHERE id = " . $id;
  109. DB::Query($query);
  110. }
  111. private function getTableName()
  112. {
  113. return strtolower($this->_entityName) . "s";
  114. }
  115. private static function findByField($fieldNames, $values, $conditions)
  116. {
  117. $entityName = get_called_class();
  118. $query = "SELECT * FROM " . strtolower($entityName) . "s" .
  119. " WHERE " .
  120. $fieldNames[0] . (strstr($values[0], '%') ? " LIKE " : " ") .
  121. (strstr($values[0], '%') ? "'$values[0]'" : $values[0]);
  122. $i = 1;
  123. foreach ($conditions as $cond)
  124. {
  125. $query .= " $cond ";
  126. $query .= $fieldNames[$i] . (strstr($values[$i], '%') ? " LIKE " : " ") .
  127. (strstr($values[$i], '%') ? "'$values[$i]'" : $values[$i]);
  128. $i++;
  129. }
  130. $res = DB::ResultQuery($query);
  131. return self::toEntitysArray($res);
  132. }
  133. private static function toEntitysArray(array $array)
  134. {
  135. $entityName = get_called_class();
  136. $entitys = [];
  137. foreach ($array as $row)
  138. {
  139. $entity = new $entityName;
  140. $entity->_data = $row;
  141. $entitys[$row['id']] = $entity;
  142. }
  143. return $entitys;
  144. }
  145. /***
  146. * @param $name
  147. * @param $arguments
  148. * @return array
  149. * @throws Exception
  150. *
  151. * Как вариант можно произвести выборку по условию, например функция вида
  152. * Find_by_strField_and_intField("%lo", "=100") - равносильна запрову SQL вида
  153. * SELECT * FROM tableName WHERE strField LIKE '%lo' AND intField =100;
  154. */
  155. public static function __callStatic($name, $arguments)
  156. {
  157. $arr = explode("_", $name);
  158. switch (strtolower($arr[0]))
  159. {
  160. case "find":
  161. {
  162. if (strtolower($arr[1]) == "by")
  163. {
  164. $conds = [];
  165. $fields = [];
  166. for ($i = 2; $i < count($arr); $i++)
  167. {
  168. if (in_array($arr[$i], ['and', 'or']))
  169. $conds[] = $arr[$i];
  170. else
  171. $fields[] = $arr[$i];
  172. }
  173. if (count($arguments) != count($fields))
  174. throw new Exception("Количество проверяемых полей и услоний не равно!");
  175. $res = self::findByField($fields, $arguments, $conds);
  176. return $res;
  177. }
  178. break;
  179. }
  180. }
  181. }
  182. function __set($name, $value)
  183. {
  184. //TODO: Make validation!!
  185. $this->_data[strtolower($name)] = $value;
  186. }
  187. function __get($name)
  188. {
  189. $name = strtolower($name);
  190. if (isset($this->_data[$name]))
  191. return $this->_data[$name];
  192. throw new Exception("Сущность не имеет поля {$name}");
  193. }
  194. }