Qurl.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. App::uses('ToolsAppModel', 'Tools.Model');
  3. /**
  4. * Manage Quick Urls
  5. *
  6. * @author Mark Scherer
  7. * @cakephp 2.x
  8. * @license MIT
  9. * 2012-05-21 ms
  10. */
  11. class Qurl extends ToolsAppModel {
  12. public $displayField = 'key';
  13. public $scaffoldSkipFields = array('note', 'key', 'content');
  14. public $order = array('Qurl.created' => 'DESC');
  15. protected $defaultLength = 22;
  16. protected $validity = YEAR;
  17. public $validate = array(
  18. 'key' => array(
  19. 'notEmpty' => array(
  20. 'rule' => array('notEmpty'),
  21. 'message' => 'valErrMandatoryField',
  22. 'last' => true,
  23. ),
  24. 'isUnique' => array(
  25. 'rule' => array('isUnique'),
  26. 'message' => 'valErrQurlKeyExists',
  27. ),
  28. ),
  29. 'url' => array(
  30. 'notEmpty' => array(
  31. 'rule' => array('notEmpty'),
  32. 'message' => 'valErrMandatoryField',
  33. 'last' => true
  34. ),
  35. 'validateUrl' => array(
  36. 'rule' => array('validateUrl', array('deep'=>false, 'sameDomain'=>true, 'autoComplete'=>true)),
  37. 'message' => 'valErrInvalidQurlUrl',
  38. 'last' => true
  39. )
  40. ),
  41. 'note' => array(
  42. ),
  43. 'comment' => array(
  44. ),
  45. 'used' => array(
  46. 'numeric' => array(
  47. 'rule' => array('numeric'),
  48. 'message' => 'valErrMandatoryField',
  49. ),
  50. ),
  51. );
  52. public function beforeValidate($options = array()) {
  53. parent::beforeValidate($options);
  54. if (isset($this->data[$this->alias]['key']) && empty($this->data[$this->alias]['key'])) {
  55. $length = null;
  56. if (!empty($this->data[$this->alias]['key_length'])) {
  57. $length = $this->data[$this->alias]['key_length'];
  58. }
  59. $this->data[$this->alias]['key'] = $this->generateKey($length);
  60. }
  61. return true;
  62. }
  63. public function beforeSave($options = array()) {
  64. parent::beforeSave($options);
  65. if (isset($this->data[$this->alias]['content'])) {
  66. $this->data[$this->alias]['content'] = serialize($this->data[$this->alias]['content']);
  67. }
  68. return true;
  69. }
  70. /**
  71. * Qurl::translate()
  72. *
  73. * @param mixed $key
  74. * @return array
  75. */
  76. public function translate($key) {
  77. $res = $this->find('first', array('conditions'=>array($this->alias.'.key'=>$key, $this->alias.'.active'=>1)));
  78. if (!$res) {
  79. return false;
  80. }
  81. //$res['CodeKey']['url'] = Router::url($content['url'], true);
  82. if ($res[$this->alias]['content']) {
  83. $res[$this->alias]['content'] = unserialize($res[$this->alias]['content']);
  84. } else {
  85. $res[$this->alias]['content'] = array();
  86. }
  87. return $res;
  88. }
  89. /**
  90. * Form the access url by key
  91. *
  92. * @param string $key
  93. * @return string Url (absolute)
  94. */
  95. public static function urlByKey($key, $title = null, $slugTitle = true) {
  96. if ($title && $slugTitle) {
  97. $title = Inflector::slug($title, '-');
  98. }
  99. return Router::url(array('admin' => false, 'plugin'=>'tools', 'controller'=>'qurls', 'action'=>'go', $key, $title), true);
  100. }
  101. /**
  102. * Makes an absolute url string ready to input anywhere.
  103. * Uses generate() internally to get the key.
  104. *
  105. * @param mixed $url
  106. * @return string Url (absolute)
  107. */
  108. public function url($url, $data = array()) {
  109. $key = $this->generate($url, $data);
  110. if (!$key) {
  111. return false;
  112. }
  113. return $this->urlByKey($key);
  114. }
  115. /**
  116. * Generates a Qurl key
  117. *
  118. * @param mixed $url
  119. * @param string $uid
  120. * @return string Key
  121. * 2011-07-12 ms
  122. */
  123. public function generate($url, $data = array()) {
  124. $url = Router::url($url, true);
  125. $content = array_merge($data, array('url' => $url));
  126. if (!isset($content['key'])) {
  127. $content['key'] = '';
  128. }
  129. $res = $this->save($content);
  130. if (!$res) {
  131. return false;
  132. }
  133. return $res[$this->alias]['key'];
  134. }
  135. /**
  136. * Sets Key to "used" (only once!) - directly by ID
  137. *
  138. * @param id of key to spend: necessary
  139. * @return boolean true on success, false otherwise
  140. * 2009-05-13 ms
  141. */
  142. public function markAsUsed($id = null) {
  143. if (empty($id)) {
  144. return false;
  145. }
  146. //$this->id = $id;
  147. if ($this->updateAll(array($this->alias.'.used' => $this->alias.'.used + 1', $this->alias.'.last_used'=>'"'.date(FORMAT_DB_DATETIME).'"'), array($this->alias.'.id'=>$id))) {
  148. return true;
  149. }
  150. return false;
  151. }
  152. /**
  153. * remove old/invalid keys
  154. * does not remove recently used ones (for proper feedback)!
  155. *
  156. * @return boolean success
  157. * 2010-06-17 ms
  158. */
  159. public function garbigeCollector() {
  160. $conditions = array(
  161. $this->alias.'.created <'=>date(FORMAT_DB_DATETIME, time()-$this->validity),
  162. );
  163. return $this->deleteAll($conditions, false);
  164. }
  165. /**
  166. * Get admin stats
  167. *
  168. * @return array
  169. * 2010-10-22 ms
  170. */
  171. public function stats() {
  172. $keys = array();
  173. $keys['unused_valid'] = $this->find('count', array('conditions'=>array($this->alias.'.used'=>0, $this->alias.'.created >='=>date(FORMAT_DB_DATETIME, time()-$this->validity))));
  174. $keys['used_valid'] = $this->find('count', array('conditions'=>array($this->alias.'.used'=>1, $this->alias.'.created >='=>date(FORMAT_DB_DATETIME, time()-$this->validity))));
  175. $keys['unused_invalid'] = $this->find('count', array('conditions'=>array($this->alias.'.used'=>0, $this->alias.'.created <'=>date(FORMAT_DB_DATETIME, time()-$this->validity))));
  176. $keys['used_invalid'] = $this->find('count', array('conditions'=>array($this->alias.'.used'=>1, $this->alias.'.created <'=>date(FORMAT_DB_DATETIME, time()-$this->validity))));
  177. $urls = $this->find('all', array('conditions'=>array(), 'fields'=>array('DISTINCT url')));
  178. $keys['urls'] = !empty($urls) ? Set::extract('/'.$this->alias.'/url', $urls) : array();
  179. return $keys;
  180. }
  181. /**
  182. * Generate key
  183. *
  184. * @param length (defaults to defaultLength)
  185. * @return string codekey
  186. * 2009-05-13 ms
  187. */
  188. public function generateKey($length = null) {
  189. if (empty($length)) {
  190. $length = $this->defaultLength;
  191. }
  192. App::uses('RandomLib', 'Tools.Lib');
  193. return RandomLib::generatePassword($length);
  194. }
  195. }