/wp-content/plugins/shopp/core/library/Framework.php

https://github.com/sharpmachine/whiteantelopestudio.com · PHP · 494 lines · 149 code · 57 blank · 288 comment · 30 complexity · 2760e263a6974e9bf9c238b469cbb94d MD5 · raw file

  1. <?php
  2. /**
  3. * Framework
  4. *
  5. * Library of abstract design pattern templates
  6. *
  7. * @author Jonathan Davis
  8. * @version 1.0
  9. * @copyright Ingenesis Limited, May 5, 2011
  10. * @license GNU GPL version 3 (or later) {@see license.txt}
  11. * @package
  12. * @since 1.0
  13. * @subpackage framework
  14. **/
  15. defined( 'WPINC' ) || header( 'HTTP/1.1 403' ) & exit; // Prevent direct access
  16. /**
  17. * Implements a list manager with internal iteration support
  18. *
  19. * @author Jonathan Davis
  20. * @since 1.2
  21. * @package shopp
  22. **/
  23. class ListFramework implements Iterator {
  24. protected $_added;
  25. protected $_checks;
  26. protected $_list = array();
  27. /**
  28. * Add an entry to the list
  29. *
  30. * @author Jonathan Davis
  31. * @since 1.2
  32. * @version 1.3
  33. *
  34. * @param string $key The key to add the entry to
  35. * @param mixed $entry The entry to add to the list
  36. * @return mixed Returns the entry
  37. **/
  38. public function &add ( $key, $entry ) {
  39. $this->_list[$key] = $entry;
  40. $this->_added = $key;
  41. return $this->get($key);
  42. }
  43. /**
  44. * Set or get the last added entry
  45. *
  46. * @author Jonathan Davis
  47. * @since 1.3
  48. *
  49. * @param string $key The key to set as the added record
  50. * @return The added entry or false if no added entries
  51. **/
  52. public function added ( $key = null ) {
  53. if ( ! is_null($key) && $this->exists($key) )
  54. $this->_added = $key;
  55. if ( $this->exists($this->_added) )
  56. return $this->get($this->_added);
  57. return false;
  58. }
  59. /**
  60. * Populate the list from a set of records
  61. *
  62. * @author Jonathan Davis
  63. * @since 1.2
  64. * @version 1.3
  65. *
  66. * @param array $records The associative array to add
  67. * @return void
  68. **/
  69. public function populate ( array $records ) {
  70. $this->_list = array_merge($this->_list, $records);
  71. }
  72. /**
  73. * Sorts the list by keys or by callback
  74. *
  75. * @author Jonathan Davis
  76. * @since 1.3
  77. *
  78. * @param callback $callback A callback function to use for sorting instead of the default key sorting
  79. * @param string $orderby (optional) The property to use for sorting ('keys' to sort by keys, otherwise uses the values)
  80. * @return boolean TRUE on success, FALSE on failure
  81. **/
  82. public function sort ( $callback = null, $orderby = false ) {
  83. if ( is_null($callback) ) return ksort($this->_list);
  84. if ( 'keys' == $orderby ) return uksort($this->_list, $callback);
  85. else return uasort($this->_list, $callback);
  86. }
  87. /**
  88. * Updates an entry
  89. *
  90. * @author Jonathan Davis
  91. * @since 1.2
  92. * @version 1.3
  93. *
  94. * @param string $key $var Description...
  95. * @return boolean True if successful, false otherwise
  96. **/
  97. public function update ( $key, $entry ) {
  98. if ( ! $this->exists($key) ) return false;
  99. if ( is_array($this->_list[ $key ]) && is_array($entry) )
  100. $entry = array_merge($this->_list[$key],$entry);
  101. $this->_list[ $key ] = $entry;
  102. return true;
  103. }
  104. /**
  105. * Provides the count of records in the list
  106. *
  107. * @author Jonathan Davis
  108. * @since 1.3
  109. *
  110. * @return int The total number of records in the list
  111. **/
  112. public function count () {
  113. return count($this->_list);
  114. }
  115. /**
  116. * Empties the list
  117. *
  118. * @author Jonathan Davis
  119. * @since 1.3
  120. *
  121. * @return void
  122. **/
  123. public function clear () {
  124. $this->_list = array();
  125. $this->_added = null;
  126. }
  127. /**
  128. * Gets a record by key
  129. *
  130. * @author Jonathan Davis
  131. * @since 1.2
  132. * @version 1.3
  133. *
  134. * @param string $key The key of the entry to get
  135. * @return mixed A reference to the entry, or false if not found
  136. **/
  137. public function &get ( $key ) {
  138. $false = false;
  139. if ( $this->exists($key) )
  140. return $this->_list[$key];
  141. else return $false;
  142. }
  143. /**
  144. * Checks if a given entry exists
  145. *
  146. * @author Jonathan Davis
  147. * @since 1.2
  148. * @version 1.3
  149. *
  150. * @param string $key The key of the entry to check
  151. * @return boolean True if it exists, false otherwise
  152. **/
  153. public function exists ($key) {
  154. if ( ! $key ) return false;
  155. return array_key_exists($key, $this->_list);
  156. }
  157. /**
  158. * Remove an entry from the list
  159. *
  160. * @author Jonathan Davis
  161. * @since 1.2
  162. * @version 1.3
  163. *
  164. * @param string $key The key of the entry to remove
  165. * @return boolean True if successful, false otherwise
  166. **/
  167. public function remove ($key) {
  168. if ( $this->exists($key) ) {
  169. unset($this->_list[$key]);
  170. return true;
  171. }
  172. return false;
  173. }
  174. /**
  175. * Gets the keys in the list
  176. *
  177. * @author Jonathan Davis
  178. * @since 1.3
  179. *
  180. * @return array An array of entry keys in the list
  181. **/
  182. public function keys () {
  183. return array_keys($this->_list);
  184. }
  185. /**
  186. * Gets the current entry using the internal list pointer
  187. *
  188. * @author Jonathan Davis
  189. * @since 1.2
  190. *
  191. * @return mixed The current entry in the list
  192. **/
  193. public function current () {
  194. return current($this->_list);
  195. }
  196. /**
  197. * Gets the key for the current internal list pointer entry
  198. *
  199. * @author Jonathan Davis
  200. * @since 1.2
  201. *
  202. * @return string The key for the current entry
  203. **/
  204. public function key ( ) {
  205. return key($this->_list);
  206. }
  207. /**
  208. * Moves the internal pointer to the next entry and returns the entry
  209. *
  210. * @author Jonathan Davis
  211. * @since 1.2
  212. *
  213. * @return mixed The next entry in the list
  214. **/
  215. public function next () {
  216. return next($this->_list);
  217. }
  218. /**
  219. * Moves the internal pointer to the previous entry and returns the entry
  220. *
  221. * @author Aaron Campbell
  222. * @since 1.3.1
  223. *
  224. * @return mixed The previous entry in the list
  225. **/
  226. public function prev () {
  227. return prev($this->_list);
  228. }
  229. /**
  230. * Moves the internal pointer to the beginning of the list and returns the first entry
  231. *
  232. * @author Jonathan Davis
  233. * @since 1.2
  234. *
  235. * @return mixed The first entry in the list
  236. **/
  237. public function rewind () {
  238. return reset($this->_list);
  239. }
  240. /**
  241. * Determines in the current entry in the list is valid
  242. *
  243. * @author Jonathan Davis
  244. * @since 1.2
  245. *
  246. * @return boolean True if the entry exists, false otherwise
  247. **/
  248. public function valid () {
  249. return null !== $this->key();
  250. }
  251. /**
  252. * Encodes the list to a JSON string
  253. *
  254. * @author Jonathan Davis
  255. * @since 1.3
  256. *
  257. * @return string The JSON encoded string
  258. **/
  259. public function __toString () {
  260. return json_encode($this->_list);
  261. }
  262. /**
  263. * Preserves only the necessary properties when storing the object
  264. *
  265. * @author Jonathan Davis
  266. * @since 1.3
  267. *
  268. * @return void
  269. **/
  270. public function __sleep () {
  271. return array('_added', '_checks', '_list');
  272. }
  273. /**
  274. * Tracks when changes occur in the list
  275. *
  276. * @author Jonathan Davis
  277. * @since 1.3
  278. *
  279. * @return True if changed, false otherwise
  280. **/
  281. public function changed ( $state = null ) {
  282. if ( null === $state ) $state = $this->_checks; // Keep current checksum
  283. $this->_checks = $this->state(); // Get the current state
  284. // If no prior state but the list is not empty it has changed
  285. if ( null === $state && ! empty($this->_list) ) return true;
  286. // Check if the list has changed from the prior state
  287. return ( $state != $this->_checks );
  288. }
  289. /**
  290. * Return a checksum of the state of the list
  291. *
  292. * @author Jonathan Davis
  293. * @since 1.3
  294. *
  295. * @return string A hash of the list
  296. **/
  297. public function state () {
  298. // Use crc32b for fastest, short but specific enough checksum
  299. return hash('crc32b', serialize($this->_list) );
  300. }
  301. } // class ListFramework
  302. /**
  303. * Implements a Singleton pattern object
  304. *
  305. * @author Jonathan Davis
  306. * @since 1.2
  307. * @package shopp
  308. **/
  309. class SingletonFramework {
  310. // @todo Requires Late-Static Binding in PHP 5.3 before extending the framework for instance return method to work
  311. // protected static $object;
  312. // public static function object () {
  313. // if ( ! self::$object instanceof self)
  314. // self::$object = new self;
  315. // return self::$object;
  316. // }
  317. /**
  318. * Prevents constructing new instances of singletons
  319. *
  320. * @author Jonathan Davis
  321. * @since 1.0
  322. *
  323. * @return void
  324. **/
  325. protected function __construct () {}
  326. /**
  327. * Prevents cloning singletons
  328. *
  329. * @author Jonathan Davis
  330. * @since 1.0
  331. *
  332. * @return void
  333. **/
  334. protected function __clone () {}
  335. }
  336. /**
  337. * Constructs an object defined by an associative array and defined object properties in the concrete class
  338. *
  339. * @author Jonathan Davis
  340. * @since 1.2
  341. * @version 1.3
  342. * @package shopp
  343. **/
  344. class AutoObjectFramework {
  345. /**
  346. * Constructor
  347. *
  348. * Matches array keys with defined properties of the object and populates the object from the passed array
  349. *
  350. * @author Jonathan Davis
  351. * @since 1.3
  352. *
  353. * @return void
  354. **/
  355. public function __construct ( $input = null ) {
  356. $properties = get_object_vars($this);
  357. $args = func_num_args();
  358. if ( $args > 1 ) {
  359. $params = func_get_args();
  360. $propkeys = array_keys($properties);
  361. $keys = array_splice($propkeys, 0, $args);
  362. $inputs = array_combine($keys, $params);
  363. }
  364. else $inputs = $input;
  365. if ( ! is_array($inputs) || empty($inputs) ) return;
  366. $this->update($inputs);
  367. }
  368. /**
  369. * Updates the object from an associative array
  370. *
  371. * @author Jonathan Davis
  372. * @since 1.3
  373. *
  374. * @return void
  375. **/
  376. public function update ( array $inputs = array() ) {
  377. if ( empty($inputs) ) return;
  378. foreach ( $inputs as $name => $value )
  379. if ( property_exists($this, $name) )
  380. $this->$name = $value;
  381. }
  382. }
  383. class FormPostFramework {
  384. protected $form = array();
  385. protected $defaults = array();
  386. public function form ( $key = null, $latest = null ) {
  387. if ( true === $latest ) $this->updateform();
  388. if ( isset($key) ) {
  389. if ( isset($this->form[ $key ]) )
  390. return $this->form[ $key ];
  391. else return false;
  392. }
  393. return $this->form;
  394. }
  395. public function updateform () {
  396. $submitted = stripslashes_deep($_POST); // Clean it up
  397. $this->form = array_merge($this->defaults, $submitted); // Capture it
  398. }
  399. }
  400. /**
  401. * Provides a basic message dispatch object
  402. *
  403. * @author Jonathan Davis
  404. * @since 1.2
  405. * @package shopp
  406. **/
  407. class SubscriberFramework {
  408. private $subscribers = array();
  409. /**
  410. * Registers a subscriber object and callback handler
  411. *
  412. * @author Jonathan Davis
  413. * @since 1.2
  414. *
  415. * @param Object $target The target class/object
  416. * @param string $method The callback method
  417. * @return void
  418. **/
  419. public function subscribe ( $target, $method) {
  420. if ( ! isset($this->subscribers[ get_class($target) ]) )
  421. $this->subscribers[ get_class($target) ] = array($target, $method);
  422. }
  423. /**
  424. * Dispatches the message to all subscribers
  425. *
  426. * @author Jonathan Davis
  427. * @since 1.2
  428. *
  429. * @return void
  430. **/
  431. public function send () {
  432. $args = func_get_args();
  433. foreach ( $this->subscribers as $callback ) {
  434. call_user_func_array($callback, $args);
  435. }
  436. }
  437. }