PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/php/lib/class.baseobject.php

https://code.google.com/p/movabletype/
PHP | 387 lines | 321 code | 48 blank | 18 comment | 50 complexity | a8d074f24bcd03fc8830dafb9d248971 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.1
  1. <?php
  2. # Movable Type (r) Open Source (C) 2001-2010 Six Apart, Ltd.
  3. # This program is distributed under the terms of the
  4. # GNU General Public License, version 2.
  5. #
  6. # $Id: class.baseobject.php 5325 2010-02-23 10:44:56Z takayama $
  7. /***
  8. * Base class for mt object
  9. */
  10. require_once('adodb.inc.php');
  11. require_once('adodb-active-record.inc.php');
  12. require_once('adodb-exceptions.inc.php');
  13. abstract class BaseObject extends ADOdb_Active_Record
  14. {
  15. // Member variables
  16. protected static $_cache_driver = null;
  17. private static $_meta_info = array(
  18. 'author' => array(
  19. 'widgets' => 'vblob',
  20. 'favorite_blogs' => 'vblob',
  21. 'password_reset' => 'vchar',
  22. 'password_reset_expires' => 'vchar',
  23. 'password_reset_return_to' => 'vchar'
  24. ),
  25. 'asset' => array(
  26. 'image_width' => 'vinteger',
  27. 'image_height' => 'vinteger'
  28. ),
  29. 'template' => array(
  30. 'last_rebuild_time' => 'vinteger',
  31. 'page_layout' => 'vchar',
  32. 'include_with_ssi' => 'vinteger',
  33. 'cache_expire_type' => 'vinteger',
  34. 'cache_expire_interval' => 'vinteger',
  35. 'cache_expire_event' => 'vchar',
  36. 'cache_path' => 'vchar',
  37. 'modulesets' => 'vchar'
  38. ),
  39. 'blog' => array(
  40. 'image_default_wrap_text' => 'vinteger',
  41. 'image_default_align' => 'vchar',
  42. 'image_default_thumb' => 'vinteger',
  43. 'image_default_width' => 'vinteger',
  44. 'image_default_wunits' => 'vchar',
  45. 'image_default_constrain' => 'vinteger',
  46. 'image_default_popup' => 'vinteger',
  47. 'commenter_authenticators' => 'vchar',
  48. 'require_typekey_emails' => 'vinteger',
  49. 'nofollow_urls' => 'vinteger',
  50. 'follow_auth_links' => 'vinteger',
  51. 'update_pings' => 'vchar',
  52. 'captcha_provider' => 'vchar',
  53. 'publish_queue' => 'vinteger',
  54. 'nwc_smart_replace' => 'vinteger',
  55. 'nwc_replace_field' => 'vchar',
  56. 'template_set' => 'vchar',
  57. 'page_layout' => 'vchar',
  58. 'include_system' => 'vchar',
  59. 'include_cache' => 'vinteger'
  60. )
  61. );
  62. private $_meta_fields = array(
  63. 'vchar',
  64. 'vchar_idx',
  65. 'vdatetime',
  66. 'vdatetime_idx',
  67. 'vinteger',
  68. 'vinteger_idx',
  69. 'vfloat',
  70. 'vfloat_idx',
  71. 'vblob',
  72. 'vclob'
  73. );
  74. protected $_has_meta = false;
  75. // Override functions
  76. public function __get( $name ) {
  77. if (is_null($this->_prefix))
  78. return;
  79. $pattern = '/^' . $this->_prefix . "/i";
  80. if (!preg_match($pattern, $name))
  81. $name = $this->_prefix . $name;
  82. return $this->$name;
  83. }
  84. public function __set($name, $value) {
  85. if (is_null($this->_prefix))
  86. return;
  87. $pattern = '/^' . $this->_prefix . "/i";
  88. if (!preg_match($pattern, $name))
  89. $name = $this->_prefix . $name;
  90. parent::__set($name, $value);
  91. }
  92. public function Load( $where = null, $bindarr = false ) {
  93. $ret = parent::Load($where, $bindarr);
  94. if ($ret && $this->has_meta())
  95. $this->load_meta($this);
  96. return $ret;
  97. }
  98. public function Find($whereOrderBy, $bindarr = false, $pkeysArr = false, $extra = array()) {
  99. $db = $this->DB();
  100. if (!$db || empty($this->_table))
  101. return false;
  102. $join = '';
  103. if (isset($extra['join'])) {
  104. $joins = $extra['join'];
  105. $keys = array_keys($joins);
  106. foreach($keys as $key) {
  107. $table = $key;
  108. $cond = $joins[$key]['condition'];
  109. $type = '';
  110. if (isset($joins[$key]['type']))
  111. $type = $joins[$key]['type'];
  112. $join .= ' ' . strtolower($type) . ' JOIN ' . $table . ' ON ' . $cond;
  113. }
  114. }
  115. if (isset($extra['distinct'])) {
  116. $mt = MT::get_instance();
  117. $mtdb = $mt->db();
  118. if ( !$mtdb->has_distinct_support ) {
  119. $unique_myself = true;
  120. $extra['distinct'] = null;
  121. }
  122. }
  123. $objs = $db->GetActiveRecordsClass(get_class($this),
  124. $this->_table . $join,
  125. $whereOrderBy,
  126. $bindarr,
  127. $pkeysArr,
  128. $extra);
  129. $ret_objs;
  130. $unique_arr = array();
  131. if ($objs) {
  132. if ( $unique_myself ) {
  133. $pkeys = empty($pkeysArr)
  134. ? $db->MetaPrimaryKeys( $this->_table )
  135. : $pKeysArr;
  136. }
  137. $count = count($objs);
  138. for($i = 0; $i < $count; $i++) {
  139. if ( $unique_myself ) {
  140. $key = "";
  141. foreach ( $pkeys as $p ) {
  142. $key .= $objs[$i]->$p.":";
  143. }
  144. if (array_key_exists($key, $unique_arr))
  145. continue;
  146. else
  147. $unique_arr[$key] = 1;
  148. }
  149. if ($this->has_meta()) {
  150. $objs[$i] = $this->load_meta($objs[$i]);
  151. }
  152. $ret_objs[] = $objs[$i];
  153. }
  154. }
  155. return $ret_objs;
  156. }
  157. // Member functions
  158. public static function install_meta($class, $name, $type) {
  159. if (empty($name) or empty($type) or empty($class))
  160. return;
  161. self::$_meta_info[$class][$name] = $type;
  162. return true;
  163. }
  164. public static function get_meta_info($class = null) {
  165. if (empty($class))
  166. return self::$_meta_info;
  167. return self::$_meta_info[$class];
  168. }
  169. public function has_meta() {
  170. return $this->_has_meta;
  171. }
  172. public function has_column($col_name) {
  173. if ( empty($col_name)) return false;
  174. // Retrieve from MetaInfo
  175. $col = $col_name;
  176. if ( preg_match('/^field[:\.](.+)$/', $col, $match) ) {
  177. $col = $match[1];
  178. }
  179. $cls = strtolower(get_class($this));
  180. $meta_info = BaseObject::get_meta_info($cls);
  181. if ( !empty($meta_info) ) {
  182. if ( array_key_exists($col, $meta_info) )
  183. return true;
  184. }
  185. // Retrieve from column
  186. $pattern = '/^' . $this->_prefix . "/i";
  187. if (!preg_match($pattern, $col))
  188. $col = $this->_prefix . $col;
  189. $flds = $this->GetAttributeNames();
  190. return in_array( strtolower($col), $flds );
  191. }
  192. public function load_meta($obj) {
  193. if (!$obj->id)
  194. return null;
  195. // Load meta info
  196. $meta_table = $obj->_table . '_meta';
  197. $meta_info = $obj->LoadRelations($meta_table);
  198. if (!isset($meta_info) || count($meta_info) === 0)
  199. return $obj;
  200. // Parse meta info
  201. foreach ($meta_info as $meta) {
  202. $col_name = $obj->_prefix . 'meta_type';
  203. $meta_name = $meta->$col_name;
  204. $value = null;
  205. $is_blob = false;
  206. foreach ($obj->_meta_fields as $f) {
  207. $col_name = $obj->_prefix . 'meta_' . $f;
  208. $value = $meta->$col_name;
  209. if (!is_null($value))
  210. break;
  211. if (preg_match("/^BIN:SERG/", $value)) {
  212. $mt = MT::get_instance();
  213. $value = preg_replace("/^BIN:/", "", $value);
  214. $value = $mt->db()->unserialize($value);
  215. }
  216. }
  217. $obj->$meta_name = $value;
  218. $obj->_original[] = $value;
  219. }
  220. return $obj;
  221. }
  222. public function count($args = null) {
  223. $join = '';
  224. if (isset($args['join'])) {
  225. $joins = $args['join'];
  226. $keys = array_keys($joins);
  227. foreach($keys as $key) {
  228. $table = $key;
  229. $cond = $joins[$key]['condition'];
  230. $type = '';
  231. if (isset($jo[$key]['type']))
  232. $type = $jo[$key]['type'];
  233. $join .= ' ' . strtolower($type) . ' JOIN ' . $table . ' ON ' . $cond;
  234. }
  235. }
  236. $where = '';
  237. if (isset($args['where']))
  238. $where = $args['where'];
  239. $sql = "select count(*) " .
  240. "from " . $this->_table . $join;
  241. if (!empty($where))
  242. $sql = $sql . " where $where";
  243. $db = $this->db();
  244. $saved = $db->SetFetchMode(ADODB_FETCH_NUM);
  245. $result = $db->Execute($sql);
  246. $cnt = $result->fields[0];
  247. $db->SetFetchMode($saved);
  248. return $cnt;
  249. }
  250. public function set_values($args) {
  251. $keys = array_keys($args);
  252. foreach($keys as $key) {
  253. $this->$key = $args[$key];
  254. }
  255. }
  256. public function GetArray() {
  257. $columns = $this->GetAttributeNames();
  258. $row = array();
  259. foreach($columns as $col)
  260. $row[$col] = $this->$col;
  261. return $row;
  262. }
  263. // Related table loader
  264. public function blog () {
  265. $col_name = $this->_prefix . "blog_id";
  266. $blog = null;
  267. if (isset($this->$col_name) && is_numeric($this->$col_name)) {
  268. $blog_id = $this->$col_name;
  269. $blog = $this->load_cache($this->_prefix . ":" . $this->id . ":blog:" . $blog_id);
  270. if (empty($blog)) {
  271. require_once('class.mt_blog.php');
  272. $blog = new Blog;
  273. $blog->Load("blog_id = $blog_id");
  274. }
  275. }
  276. if ($blog->class == 'website') {
  277. require_once('class.mt_website.php');
  278. $blog = new Website;
  279. $blog->Load("blog_id = $blog_id");
  280. }
  281. if (!empty($blog))
  282. $this->cache($this->_prefix . ":" . $this->id . ":blog:" . $blog->id, $blog);
  283. return $blog;
  284. }
  285. public function author () {
  286. $col_name = $this->_prefix . "author_id";
  287. $author = null;
  288. if (isset($this->$col_name) && is_numeric($this->$col_name)) {
  289. $author_id = $this->$col_name;
  290. $author = $this->load_cache($this->_prefix . ":" . $this->id . ":author:" . $author_id);
  291. if (empty($author)) {
  292. require_once('class.mt_author.php');
  293. $author = new Author;
  294. $author->Load("author_id = $author_id");
  295. $this->cache($this->_prefix . ":" . $this->id . ":author:" . $author->id, $author);
  296. }
  297. }
  298. return $author;
  299. }
  300. public function entry () {
  301. $col_name = $this->_prefix . "entry_id";
  302. $entry = null;
  303. if (isset($this->$col_name) && is_numeric($this->$col_name) && $this->$col_name > 0) {
  304. $entry_id = $this->$col_name;
  305. $entry = $this->load_cache($this->_prefix . ":" . $this->id . ":entry:" . $entry_id);
  306. if (empty($entry)) {
  307. require_once('class.mt_entry.php');
  308. $entry = new Entry;
  309. $entry->Load("entry_id = $entry_id");
  310. $this->cache($this->_prefix . ":" . $this->id . ":entry:" . $entry->id, $entry);
  311. }
  312. }
  313. return $entry;
  314. }
  315. // Objcet cache
  316. protected function cache($key, $obj) {
  317. if (empty($key))
  318. return;
  319. $this->cache_driver()->set($key, $obj);
  320. }
  321. protected function load_cache($key) {
  322. if (empty($key))
  323. return null;
  324. $this->cache_driver()->get($key);
  325. }
  326. protected function cache_driver() {
  327. if (empty(self::$_cache_driver)) {
  328. require_once("class.basecache.php");
  329. try {
  330. self::$_cache_driver = CacheProviderFactory::get_provider('memcached');
  331. } catch (Exception $e) {
  332. # Memcached not supported.
  333. self::$_cache_driver = CacheProviderFactory::get_provider('memory');
  334. }
  335. }
  336. return self::$_cache_driver;
  337. }
  338. }
  339. ?>