croogo /Croogo/Lib/Utility/VisibilityFilter.php

Language PHP Lines 153
MD5 Hash bfcf94a5002c63f9a5653551a28f8157
Repository https://github.com/kareypowell/croogo.git View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php

App::uses('StringConverter', 'Croogo.Lib/Utility');

/**
 * VisibilityFilter
 *
 * @author   Rachman Chavik <rchavik@xintesa.com>
 * @package  Croogo.Croogo.Lib.Utility
 * @license  http://www.opensource.org/licenses/mit-license.php The MIT License
 * @link     http://www.croogo.org
 */
class VisibilityFilter {

/**
 * StringConverter instance
 */
	protected $_converter = null;

/**
 * Known url keys
 */
	protected $_urlKeys = array(
		'admin' => false,
		'plugin' => false,
		'controller' => false,
		'action' => false,
		'named' => false,
		'pass' => false,
	);

/**
 * Constructor
 *
 * @param CakeRequest $request
 */
	public function __construct(CakeRequest $request = null) {
		if ($request) {
			$this->_request = $request;
		} else {
			$this->_request = new CakeRequest();
		}
		$this->_converter = new StringConverter();
	}

/**
 * Check that request (passed in the constructor) is visible based on list of
 * specified rules.  The rules can specified in link string format or just a
 * plain URL fragment.  Whenever possible, use link string formatted rule since
 * a URL fragment can be expensive.
 *
 * The current request is checked against negative rules first (implicitly
 * hidden), then against positive rules (implicitly visible).
 * If there's no positive rule, defaults to visible.
 *
 * @param array $rules Array of rules in link string format
 * @return bool True if the rules are satisfied
 * @see StringConverter::linkStringToArray()
 */
	protected function _isVisible($rules) {
		$negativeRules = array_filter($rules, function($value) {
			if ($value[0] === '-') {
				return true;
			}
			return false;
		});
		foreach ($negativeRules as $rule) {
			if ($this->_ruleMatch(substr($rule, 1))) {
				return false;
			}
		}

		$positiveRules = array_diff($rules, $negativeRules);
		if (empty($positiveRules)) {
			return true;
		}
		foreach ($positiveRules as $rule) {
			if ($rule[0] == '+') {
				$rule = substr($rule, 1);
			}
			if ($this->_ruleMatch($rule)) {
				return true;
			}
		}

		return false;
	}

/**
 * Check that request matches a single rule
 *
 * @param string $rule Rule in link string or plain URL fragment
 * @return bool True if request satisfies the rule
 */
	protected function _ruleMatch($rule) {
		if (strpos($rule, ':') !== false) {
			$url = array_filter($this->_converter->linkStringToArray($rule));
			if (isset($url['?'])) {
				$queryString = $url['?'];
				unset($url['?']);
			}
		} else {
			$url = Router::parse($rule);
			$named = array_diff_key($url, $this->_urlKeys);
			$url['named'] = $named;
		}

		$intersect = array_intersect_key($this->_request->params, $url);
		$matched = $intersect == $url;

		if ($matched && isset($queryString)) {
			$matched = $this->_request->query == $queryString;
		}

		return $matched;
	}

/**
 * Remove values based on rules in visibility_path field.
 *
 * Options:
 *   - model Model alias in $values
 *   - field Field name containing the visibility path rules
 *
 * @param array $values Array of data to filter
 */
	public function remove($values, $options = array()) {
		$options = Hash::merge(array(
			'model' => null,
			'field' => null,
		), $options);
		$model = $options['model'];
		$field = $options['field'];
		$results = array();

		foreach ($values as $value) {
			if (empty($value[$model][$field])) {
				$results[] = $value;
				continue;
			}
			if (!is_array($value[$model][$field])) {
				CakeLog::error('Invalid visibility_path rule');
			}

			if ($this->_isVisible($value[$model][$field])) {
				$results[] = $value;
			}
		}
		return $results;
	}

}
Back to Top