store.class.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. namespace Shibboleth;
  3. use \Database;
  4. /**
  5. * A database store. Used interact with the database - save objects, run queries.
  6. *
  7. * One store = one table.
  8. *
  9. * @license see /license.txt
  10. * @author Laurent Opprecht <laurent@opprecht.info>, Nicolas Rod for the University of Geneva
  11. */
  12. class Store
  13. {
  14. /**
  15. *
  16. * @return Store
  17. */
  18. public static function create($table_name, $class_name = '', $id_name = 'id', $db_name = '')
  19. {
  20. return new self($table_name, $class_name, $id_name, $db_name);
  21. }
  22. protected $db_name = '';
  23. protected $table_name = '';
  24. protected $id_name = '';
  25. protected $class_name = '';
  26. function __construct($table_name, $class_name = '', $id_name = 'id', $db_name = '')
  27. {
  28. $this->db_name = $db_name ? $db_name : Database::get_main_database();
  29. $this->table_name = $table_name;
  30. $this->class_name = $class_name;
  31. $this->id_name = $id_name;
  32. }
  33. function get_db_name($object = '')
  34. {
  35. if ($this->db_name)
  36. {
  37. return $this->db_name;
  38. }
  39. if ($object)
  40. {
  41. $result = isset($object->{db_name}) ? $object->{db_name} : '';
  42. $result = $result ? $result : Database :: get_main_database();
  43. return $result;
  44. }
  45. return Database::get_main_database();
  46. }
  47. function get($w)
  48. {
  49. $args = func_get_args();
  50. $f = array($this, 'get_where');
  51. $db_name = $this->get_db_name();
  52. $where = call_user_func_array($f, $args);
  53. $sql = "SELECT *
  54. FROM `{$db_name}`.`{$this->table_name}`
  55. WHERE $where";
  56. $items = $this->query($sql);
  57. return (count($items) == 1) ? reset($items) : null;
  58. }
  59. function select($w)
  60. {
  61. $args = func_get_args();
  62. $f = array($this, 'get_where');
  63. $db_name = $this->get_db_name();
  64. $where = call_user_func_array($f, $args);
  65. $sql = "SELECT *
  66. FROM `{$db_name}`.`{$this->table_name}`
  67. WHERE $where";
  68. $result = $this->query($sql);
  69. return $result;
  70. }
  71. function exist($w)
  72. {
  73. $args = func_get_args();
  74. $f = array($this, 'get');
  75. $object = call_user_func_array($f, $args);
  76. return !empty($object);
  77. }
  78. function is_new($object)
  79. {
  80. $id_name = $this->id_name;
  81. $id = isset($object->{$id_name}) ? $object->{$id_name} : false;
  82. return empty($id);
  83. }
  84. function save($object)
  85. {
  86. if (empty($object))
  87. {
  88. return false;
  89. }
  90. $object = is_array($object) ? $this->create_object($object) : $object;
  91. $this->before_save($object);
  92. if ($this->is_new($object))
  93. {
  94. $result = $this->insert($object);
  95. }
  96. else
  97. {
  98. $result = $this->update($object);
  99. }
  100. return $result;
  101. }
  102. function delete($object)
  103. {
  104. $args = func_get_args();
  105. $f = array($this, 'get_where');
  106. $db_name = $this->get_db_name();
  107. $where = call_user_func_array($f, $args);
  108. $sql = "DELETE
  109. FROM `{$db_name
  110. }
  111. `.`{$this->table_name
  112. }
  113. `
  114. WHERE $where";
  115. $result = $this->query($sql);
  116. return $result;
  117. }
  118. /**
  119. *
  120. * @param array|object $data
  121. * @return object
  122. */
  123. public function create_object($data = array())
  124. {
  125. $data = $data ? $data : array();
  126. $data = (object) $data;
  127. $class = $this->class_name;
  128. if (empty($class))
  129. {
  130. return clone $data;
  131. }
  132. $result = new $class();
  133. foreach ($result as $key => $value)
  134. {
  135. $result->{$key} = property_exists($data, $key) ? $data->{$key} : null;
  136. }
  137. return $result;
  138. }
  139. public function fields($object)
  140. {
  141. static $result = array();
  142. if (!empty($result))
  143. {
  144. return $result;
  145. }
  146. $db_name = $this->get_db_name($object);
  147. $sql = "SELECT *
  148. FROM `{$db_name}`.`{$this->table_name}`
  149. LIMIT 1";
  150. $rs = Database::query($sql, null, __FILE__);
  151. while ($field = mysql_fetch_field($rs))
  152. {
  153. $result[] = $field;
  154. }
  155. return $result;
  156. }
  157. protected function before_save($object)
  158. {
  159. //hook
  160. }
  161. protected function update($object)
  162. {
  163. $id = isset($object->{$this->id_name}) ? $object->{$this->id_name} : false;
  164. if (empty($id))
  165. {
  166. return false;
  167. }
  168. $items = array();
  169. $fields = $this->fields($object);
  170. foreach ($fields as $field)
  171. {
  172. $name = $field->name;
  173. if ($name != $this->id_name)
  174. {
  175. if (property_exists($object, $name))
  176. {
  177. $value = $object->{$name};
  178. $value = $this->format_value($value);
  179. $items[] = "$name=$value";
  180. }
  181. }
  182. }
  183. $db_name = $this->get_db_name($object);
  184. $sql = "UPDATE `{$db_name}`.`{$this->table_name}` SET ";
  185. $sql .= join(', ', $items);
  186. $sql .= " WHERE {$this->id_name}=$id";
  187. $result = $this->execute($sql);
  188. if ($result)
  189. {
  190. $object->{db_name} = $db_name;
  191. }
  192. return (bool) $result;
  193. }
  194. protected function insert($object)
  195. {
  196. $id = isset($object->{$this->id_name}) ? $object->{$this->id_name} : false;
  197. if (empty($object))
  198. {
  199. return false;
  200. }
  201. $values = array();
  202. $keys = array();
  203. $fields = $this->fields($object);
  204. foreach ($fields as $field)
  205. {
  206. $name = $field->name;
  207. if ($name != $this->id_name)
  208. {
  209. if (property_exists($object, $name))
  210. {
  211. $value = $object->{$name};
  212. $value = is_null($value) ? 'DEFAULT' : $this->format_value($value);
  213. $values[] = $value;
  214. $keys[] = $name;
  215. }
  216. }
  217. }
  218. $db_name = $this->get_db_name($object);
  219. $sql = "INSERT INTO `{$db_name}`.`{$this->table_name}` ";
  220. $sql .= ' (' . join(', ', $keys) . ') ';
  221. $sql .= 'VALUES';
  222. $sql .= ' (' . join(', ', $values) . ') ';
  223. $result = $this->execute($sql);
  224. if ($result)
  225. {
  226. $id = mysql_insert_id();
  227. $object->{$this->id_name} = $id;
  228. $object->{db_name} = $db_name;
  229. return $id;
  230. }
  231. else
  232. {
  233. return false;
  234. }
  235. }
  236. protected function get_where($_)
  237. {
  238. $args = func_get_args();
  239. if (count($args) == 1)
  240. {
  241. $arg = reset($args);
  242. if (is_numeric($arg))
  243. {
  244. $id = (int) $arg;
  245. if (empty($id))
  246. {
  247. return '';
  248. }
  249. $args = array($this->pk_name, $arg);
  250. }
  251. else if (is_string($arg))
  252. {
  253. return $arg;
  254. }
  255. else if (is_array($arg))
  256. {
  257. $args = $arg;
  258. }
  259. else
  260. {
  261. return $arg;
  262. }
  263. }
  264. $items = array();
  265. foreach ($args as $key => $val)
  266. {
  267. $items[] = $key . ' = ' . $this->format_value($val);
  268. }
  269. return implode(' AND ', $items);
  270. }
  271. protected function format_value($value)
  272. {
  273. if (is_null($value))
  274. {
  275. return 'NULL';
  276. }
  277. if (is_bool($var))
  278. {
  279. return $value ? '1' : '0';
  280. }
  281. else if (is_numeric($value))
  282. {
  283. return empty($value) ? '0' : $value;
  284. }
  285. else if (is_string($value))
  286. {
  287. $value = mysql_escape_string($value);
  288. return "'$value'";
  289. }
  290. else
  291. {
  292. return $value;
  293. }
  294. }
  295. /**
  296. *
  297. * @param string $sql
  298. * @return array
  299. */
  300. protected function query($sql)
  301. {
  302. $resource = Database::query($sql, null, __FILE__);
  303. if ($resource == false)
  304. {
  305. return array();
  306. }
  307. $result = array();
  308. while ($data = mysql_fetch_assoc($resource))
  309. {
  310. $result[] = $this->create_object($data);
  311. }
  312. return $result;
  313. }
  314. protected function execute($sql)
  315. {
  316. return Database::query($sql, null, __FILE__);
  317. }
  318. }