/app/plugins/utils/models/behaviors/publishable.php

https://github.com/ciudadanointeligente/votainteligente.com.ar · PHP · 265 lines · 151 code · 44 blank · 70 comment · 37 complexity · 9ba182ee62214ef3e3caf48fe84f6101 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright 2007-2010, Cake Development Corporation (http://cakedc.com)
  4. *
  5. * Licensed under The MIT License
  6. * Redistributions of files must retain the above copyright notice.
  7. *
  8. * @copyright Copyright 2007-2010, Cake Development Corporation (http://cakedc.com)
  9. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  10. */
  11. /**
  12. * Utils Plugin
  13. *
  14. * Utils Publishable Behavior
  15. *
  16. * @package utils
  17. * @subpackage utils.models.behaviors
  18. */
  19. class PublishableBehavior extends ModelBehavior {
  20. /**
  21. * Contain settings indexed by model name.
  22. *
  23. * @var array
  24. */
  25. var $__settings = array();
  26. /**
  27. * Initiate behaviour for the model using settings.
  28. *
  29. * @param object $Model Model using the behaviour
  30. * @param array $settings Settings to override for model.
  31. */
  32. function setup(&$Model, $settings = array()) {
  33. $default = array('field' => 'published', 'field_date' => 'published_date', 'find' => true);
  34. if (!isset($this->__settings[$Model->alias])) {
  35. $this->__settings[$Model->alias] = $default;
  36. }
  37. $this->__settings[$Model->alias] = array_merge($this->__settings[$Model->alias], is_array($settings) ? $settings : array());
  38. }
  39. /**
  40. * Marks a record as published and optionally change other fields.
  41. *
  42. * @param object $Model Model from where the method is being executed.
  43. * @param mixed $id ID of the publishable record.
  44. * @param $attributes Other fields to change (in the form of field => value)
  45. * @return boolean Result of the operation.
  46. */
  47. function publish(&$Model, $id = null, $attributes = array()) {
  48. if ($Model->hasField($this->__settings[$Model->alias]['field'])) {
  49. if (empty($id)) {
  50. $id = $Model->id;
  51. }
  52. $data = array($Model->alias => array(
  53. $Model->primaryKey => $id,
  54. $this->__settings[$Model->alias]['field'] => true
  55. ));
  56. $Model->id = $id;
  57. if (isset($this->__settings[$Model->alias]['field_date']) && $Model->hasField($this->__settings[$Model->alias]['field_date'])) {
  58. if (!$Model->exists()) {
  59. $data[$Model->alias][$this->__settings[$Model->alias]['field_date']] = date('Y-m-d');
  60. }
  61. }
  62. if (!empty($attributes)) {
  63. $data[$Model->alias] = array_merge($data[$Model->alias], $attributes);
  64. }
  65. $onFind = $this->__settings[$Model->alias]['find'];
  66. $this->enablePublishable($Model, false);
  67. $result = $Model->save($data, false, array_keys($data[$Model->alias]));
  68. $this->enablePublishable($Model, 'find', $onFind);
  69. return ($result !== false);
  70. }
  71. return false;
  72. }
  73. /**
  74. * Marks a record as unpublished and optionally change other fields.
  75. *
  76. * @param object $Model Model from where the method is being executed.
  77. * @param mixed $id ID of the publishable record.
  78. * @param $attributes Other fields to change (in the form of field => value)
  79. * @return boolean Result of the operation.
  80. */
  81. function unPublish(&$Model, $id = null, $attributes = array()) {
  82. if ($Model->hasField($this->__settings[$Model->alias]['field'])) {
  83. if (empty($id)) {
  84. $id = $Model->id;
  85. }
  86. $data = array($Model->alias => array(
  87. $Model->primaryKey => $id,
  88. $this->__settings[$Model->alias]['field'] => false
  89. ));
  90. if (!empty($attributes)) {
  91. $data[$Model->alias] = array_merge($data[$Model->alias], $attributes);
  92. }
  93. $onFind = $this->__settings[$Model->alias]['find'];
  94. $this->enablePublishable($Model, false);
  95. $Model->id = $id;
  96. $result = $Model->save($data, false, array_keys($data[$Model->alias]));
  97. $this->enablePublishable($Model, 'find', $onFind);
  98. return ($result !== false);
  99. }
  100. return false;
  101. }
  102. /**
  103. * Set if the beforeFind() should be overriden for specific model.
  104. *
  105. * @param object $Model Model to be published
  106. * @param mixed $methods If string, method to enable on, if array array of method names, if boolean, enable it for find method
  107. * @param boolean $enable If specified method should be overriden.
  108. */
  109. function enablePublishable(&$Model, $methods, $enable = true) {
  110. if (is_bool($methods)) {
  111. $enable = $methods;
  112. $methods = array('find');
  113. }
  114. if (!is_array($methods)) {
  115. $methods = array($methods);
  116. }
  117. foreach($methods as $method) {
  118. $this->__settings[$Model->alias][$method] = $enable;
  119. }
  120. }
  121. /**
  122. * Run before a model is about to be find, used only fetch for published records.
  123. *
  124. * @param object $Model Model
  125. * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
  126. * @return mixed Set to false to abort find operation, or return an array with data used to execute query
  127. */
  128. function beforeFind(&$Model, $queryData, $recursive = null) {
  129. if (Configure::read('Publishable.disable') === true) {
  130. return $queryData;
  131. }
  132. if ($this->__settings[$Model->alias]['find'] && $Model->hasField($this->__settings[$Model->alias]['field'])) {
  133. $Db =& ConnectionManager::getDataSource($Model->useDbConfig);
  134. $include = false;
  135. if (!empty($queryData['conditions']) && is_string($queryData['conditions'])) {
  136. $include = true;
  137. $fields = array(
  138. $Db->name($Model->alias) . '.' . $Db->name($this->__settings[$Model->alias]['field']),
  139. $Db->name($this->__settings[$Model->alias]['field']),
  140. $Model->alias . '.' . $this->__settings[$Model->alias]['field'],
  141. $this->__settings[$Model->alias]['field']
  142. );
  143. foreach($fields as $field) {
  144. if (preg_match('/^' . preg_quote($field) . '[\s=!]+/i', $queryData['conditions']) ||
  145. preg_match('/\\x20+' . preg_quote($field) . '[\s=!]+/i', $queryData['conditions'])) {
  146. $include = false;
  147. break;
  148. }
  149. }
  150. }
  151. else if (empty($queryData['conditions']) ||
  152. (!in_array($this->__settings[$Model->alias]['field'], array_keys($queryData['conditions'])) &&
  153. !in_array($Model->alias . '.' . $this->__settings[$Model->alias]['field'], array_keys($queryData['conditions'])))) {
  154. $include = true;
  155. }
  156. if ($include) {
  157. if (isset($this->__settings[$Model->alias]['field_date']) && $Model->hasField($this->__settings[$Model->alias]['field_date'])) {
  158. $includeDateCondition = true;
  159. }
  160. if (empty($queryData['conditions'])) {
  161. $queryData['conditions'] = array();
  162. }
  163. if (is_string($queryData['conditions'])) {
  164. $queryData['conditions'] = $Db->name($Model->alias) . '.' . $Db->name($this->__settings[$Model->alias]['field']) . '= 1 AND ' . $queryData['conditions'];
  165. }
  166. else {
  167. $queryData['conditions'][$Model->alias . '.' . $this->__settings[$Model->alias]['field']] = true;
  168. if (!empty($includeDateCondition)) {
  169. $queryData['conditions'][$Model->alias . '.' . $this->__settings[$Model->alias]['field_date'] . ' <='] = date('Y-m-d H:i');
  170. }
  171. }
  172. }
  173. if (is_null($recursive) && !empty($queryData['recursive'])) {
  174. $recursive = $queryData['recursive'];
  175. } elseif (is_null($recursive)) {
  176. $recursive = $Model->recursive;
  177. }
  178. if ($recursive < 0) {
  179. return $queryData;
  180. }
  181. $associated = $Model->getAssociated('belongsTo');
  182. foreach ($associated as $m) {
  183. if ($Model->{$m}->Behaviors->enabled('Publishable')) {
  184. $queryData = $Model->{$m}->Behaviors->Publishable->beforeFind($Model->{$m}, $queryData, --$recursive);
  185. }
  186. }
  187. }
  188. return $queryData;
  189. }
  190. /**
  191. * Run before a model is saved, used to disable beforeFind() override.
  192. *
  193. * @param object $Model Model about to be saved.
  194. * @return boolean True if the operation should continue, false if it should abort
  195. */
  196. function beforeSave(&$Model) {
  197. if ($this->__settings[$Model->alias]['find']) {
  198. if (!isset($this->__backAttributes)) {
  199. $this->__backAttributes = array($Model->alias => array());
  200. }
  201. else if (!isset($this->__backAttributes[$Model->alias])) {
  202. $this->__backAttributes[$Model->alias] = array();
  203. }
  204. $this->__backAttributes[$Model->alias]['find'] = $this->__settings[$Model->alias]['find'];
  205. $this->enablePublishable($Model, false);
  206. }
  207. return true;
  208. }
  209. /**
  210. * Run after a model has been saved, used to enable beforeFind() override.
  211. *
  212. * @param object $Model Model just saved.
  213. * @param boolean $created True if this save created a new record
  214. */
  215. function afterSave(&$Model, $created) {
  216. if (isset($this->__backAttributes[$Model->alias]['find'])) {
  217. $this->enablePublishable($Model, 'find', $this->__backAttributes[$Model->alias]['find']);
  218. unset($this->__backAttributes[$Model->alias]['find']);
  219. }
  220. }
  221. }