1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
21:
22: App::uses('ArrayUtil', 'Base.Lib');
23: App::uses('Basics', 'Base.Lib');
24:
25: 26: 27:
28: class PaginatorUtilComponent extends Component {
29:
30: public $components = array('Session');
31: private $filters = array();
32:
33: public function __construct(ComponentCollection $collection, $settings = array()) {
34: $settings = array_merge($this->settings, (array) $settings);
35: $this->Controller = $collection->getController();
36: parent::__construct($collection, $settings);
37: }
38:
39: public function startup(\Controller $controller) {
40: parent::startup($controller);
41: if ($controller->params['action'] == 'index') {
42: $this->startupIndex($controller);
43: }
44: }
45:
46: private function startupIndex(&$controller) {
47: foreach ($this->getAllFilters($controller) as $filter) {
48: $value = $filter->getValue();
49: $condition = $filter->getCurrentCondition();
50:
51:
52: if ($value !== null && $condition) {
53: $this->Controller->paginate['conditions'][] =
54: $filter->hasConditionValue() ? array($condition => $value) : $condition;
55: }
56:
57: $filter->writePersistentValue();
58: }
59: }
60:
61: 62: 63: 64: 65:
66: private function getAllFilters(\Controller $controller) {
67: $filtersData = method_exists($controller, 'getPaginatorUtilFilters') ?
68: $controller->getPaginatorUtilFilters() :
69: array();
70: $filters = array();
71: foreach ($filtersData as $filterName => $filterData) {
72: $filters[] = $this->getFilter($controller, $filterName, $filterData);
73: }
74: return $filters;
75: }
76:
77: private function getFilter(&$controller, $filterName, $filterOptions) {
78: if (!isset($this->filters[$controller->name][$filterName])) {
79: $this->filters[$controller->name][$filterName] = new PaginatorUtilComponentFilter(
80: $this, $controller, $filterName, $filterOptions
81: );
82: }
83: return $this->filters[$controller->name][$filterName];
84: }
85:
86: public function beforeRender(\Controller $controller) {
87: parent::beforeRender($controller);
88: if ($controller->params['action'] == 'index') {
89: $this->beforeRenderIndex($controller);
90: }
91: }
92:
93: private function beforeRenderIndex(&$controller) {
94: $fields = array();
95:
96: foreach ($this->getAllFilters($controller) as $filter) {
97: $fields[$filter->getName()] = $filter->buildField();
98: }
99:
100: $controller->request->params['paginatorUtil']['filterFields'] = $fields;
101: }
102: }
103:
104: class PaginatorUtilComponentFilter {
105:
106: private $controller;
107: private $name;
108: private $component;
109:
110: 111: 112: 113: 114: 115: 116:
117: public function __construct(&$component, &$controller, $name, $options) {
118: $this->controller = $controller;
119: $this->name = $name;
120: $this->component = $component;
121: $this->options = $options;
122: }
123:
124: 125: 126: 127:
128: public function getName() {
129: return $this->name;
130: }
131:
132: 133: 134: 135: 136:
137: private function hasConfig($config) {
138: return ArrayUtil::hasArrayIndex(
139: $this->options
140: , Basics::fieldNameToArray($config)
141: );
142: }
143:
144: 145: 146: 147: 148:
149: private function getConfig($config) {
150: if ($this->hasConfig($config)) {
151: return ArrayUtil::arrayIndex($this->options, Basics::fieldNameToArray($config), true);
152: } else {
153: return null;
154: }
155: }
156:
157: 158: 159: 160:
161: public function isInputSelectType() {
162: return $this->hasConfig('values') ||
163: $this->hasConfig('conditionsPerValue');
164: }
165:
166: 167: 168: 169:
170: public function getValuesList() {
171: if ($this->hasConfig('values')) {
172: return $this->getConfig('values');
173: } else if ($this->hasConfig('conditionsPerValue')) {
174: return ArrayUtil::keysAsValues(
175: array_keys($this->getConfig('conditionsPerValue'))
176: );
177: } else {
178: return null;
179: }
180: }
181:
182: public function getFilterDefaultValue() {
183: return $this->getConfig('default');
184: }
185:
186: public function hasFilterDefaultValue() {
187: return $this->hasConfig('default');
188: }
189:
190: public function getCurrentCondition() {
191: if ($this->hasConfig('conditions')) {
192: return $this->getConfig('conditions');
193: } else if ($this->hasConfig('conditionsPerValue')) {
194: $conditions = $this->getConfig('conditionsPerValue');
195: $value = $this->getValue();
196: return $value !== null && isset($conditions[$value]) ?
197: $conditions[$value] :
198: null;
199: } else {
200: throw new Exception("Não foi definido uma condição para o filtro \"{$this->name}\" em \"{$this->controller->name}\".");
201: }
202: }
203:
204: public function getValue() {
205: $update = isset($this->controller->params['url']['_update']) ? $this->controller->params['url']['_update'] : false;
206: $clear = isset($this->controller->params['url']['_clear']) ? $this->controller->params['url']['_clear'] : false;
207:
208: $default = null;
209: if ($this->hasFilterDefaultValue()) {
210: $default = $this->getFilterDefaultValue();
211: }
212:
213: if ($update) {
214: if (isset($this->controller->params['url'][$this->getSlugedName()]) && trim($this->controller->params['url'][$this->getSlugedName()]) !== '') {
215: $value = trim($this->controller->params['url'][$this->getSlugedName()]);
216: if ($this->getConfig('fieldOptions.type') == 'date') {
217: if (strtotime($value) === false) {
218: return $default;
219: }
220: }
221: return $value;
222: } else {
223: return $default;
224: }
225: } else if ($clear) {
226: return $default;
227: } else {
228: return $this->readPersistentValue();
229: }
230: }
231:
232: private function getSlugedName() {
233: return Inflector::slug($this->name);
234: }
235:
236: private function getSessionPath() {
237: return implode(
238: '.', array(
239: 'PaginatorUtil',
240: $this->controller->name,
241: $this->controller->params['action'],
242: $this->getSlugedName()
243: )
244: );
245: }
246:
247: public function writePersistentValue() {
248: $this->component->Session->write(
249: $this->getSessionPath(), $this->getValue()
250: );
251: }
252:
253: public function readPersistentValue() {
254: return $this->component->Session->read($this->getSessionPath());
255: }
256:
257: public function buildField() {
258: $field = array(
259: 'value' => $this->getValue(),
260: 'type' => empty($this->options['type']) ? 'text' : $this->options['type']
261: );
262:
263: if ($this->isInputSelectType()) {
264: $field['options'] = $this->getValuesList();
265: $field['type'] = 'select';
266: if (!$this->hasFilterDefaultValue()) {
267: $field['empty'] = 'NÃO SELECIONADO';
268: }
269: }
270:
271: if ($this->hasConfig('fieldOptions')) {
272: $field = $this->getConfig('fieldOptions') + $field;
273: }
274:
275: if (in_array($field['type'], array('date', 'time', 'datetime'))) {
276: $field['selected'] = $field['value'];
277: }
278:
279: return $field;
280: }
281:
282: public function hasConditionValue() {
283: return !$this->hasConfig('conditionsPerValue');
284: }
285:
286: }
287: