1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Access
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * JAccessRules class.
14 *
15 * @since 11.4
16 */
17 class JAccessRules
18 {
19 /**
20 * A named array.
21 *
22 * @var array
23 * @since 11.1
24 */
25 protected $data = array();
26
27 /**
28 * Constructor.
29 *
30 * The input array must be in the form: array('action' => array(-42 => true, 3 => true, 4 => false))
31 * or an equivalent JSON encoded string, or an object where properties are arrays.
32 *
33 * @param mixed $input A JSON format string (probably from the database) or a nested array.
34 *
35 * @since 11.1
36 */
37 public function __construct($input = '')
38 {
39 // Convert in input to an array.
40 if (is_string($input))
41 {
42 $input = json_decode($input, true);
43 }
44 elseif (is_object($input))
45 {
46 $input = (array) $input;
47 }
48
49 if (is_array($input))
50 {
51 // Top level keys represent the actions.
52 foreach ($input as $action => $identities)
53 {
54 $this->mergeAction($action, $identities);
55 }
56 }
57 }
58
59 /**
60 * Get the data for the action.
61 *
62 * @return array A named array of JAccessRule objects.
63 *
64 * @since 11.1
65 */
66 public function getData()
67 {
68 return $this->data;
69 }
70
71 /**
72 * Method to merge a collection of JAccessRules.
73 *
74 * @param mixed $input JAccessRule or array of JAccessRules
75 *
76 * @return void
77 *
78 * @since 11.1
79 */
80 public function mergeCollection($input)
81 {
82 // Check if the input is an array.
83 if (is_array($input))
84 {
85 foreach ($input as $actions)
86 {
87 $this->merge($actions);
88 }
89 }
90 }
91
92 /**
93 * Method to merge actions with this object.
94 *
95 * @param mixed $actions JAccessRule object, an array of actions or a JSON string array of actions.
96 *
97 * @return void
98 *
99 * @since 11.1
100 */
101 public function merge($actions)
102 {
103 if (is_string($actions))
104 {
105 $actions = json_decode($actions, true);
106 }
107
108 if (is_array($actions))
109 {
110 foreach ($actions as $action => $identities)
111 {
112 $this->mergeAction($action, $identities);
113 }
114 }
115 elseif ($actions instanceof JAccessRules)
116 {
117 $data = $actions->getData();
118
119 foreach ($data as $name => $identities)
120 {
121 $this->mergeAction($name, $identities);
122 }
123 }
124 }
125
126 /**
127 * Merges an array of identities for an action.
128 *
129 * @param string $action The name of the action.
130 * @param array $identities An array of identities
131 *
132 * @return void
133 *
134 * @since 11.1
135 */
136 public function mergeAction($action, $identities)
137 {
138 if (isset($this->data[$action]))
139 {
140 // If exists, merge the action.
141 $this->data[$action]->mergeIdentities($identities);
142 }
143 else
144 {
145 // If new, add the action.
146 $this->data[$action] = new JAccessRule($identities);
147 }
148 }
149
150 /**
151 * Checks that an action can be performed by an identity.
152 *
153 * The identity is an integer where +ve represents a user group,
154 * and -ve represents a user.
155 *
156 * @param string $action The name of the action.
157 * @param mixed $identity An integer representing the identity, or an array of identities
158 *
159 * @return mixed Object or null if there is no information about the action.
160 *
161 * @since 11.1
162 */
163 public function allow($action, $identity)
164 {
165 // Check we have information about this action.
166 if (isset($this->data[$action]))
167 {
168 return $this->data[$action]->allow($identity);
169 }
170
171 return;
172 }
173
174 /**
175 * Get the allowed actions for an identity.
176 *
177 * @param mixed $identity An integer representing the identity or an array of identities
178 *
179 * @return JObject Allowed actions for the identity or identities
180 *
181 * @since 11.1
182 */
183 public function getAllowed($identity)
184 {
185 // Sweep for the allowed actions.
186 $allowed = new JObject;
187
188 foreach ($this->data as $name => &$action)
189 {
190 if ($action->allow($identity))
191 {
192 $allowed->set($name, true);
193 }
194 }
195
196 return $allowed;
197 }
198
199 /**
200 * Magic method to convert the object to JSON string representation.
201 *
202 * @return string JSON representation of the actions array
203 *
204 * @since 11.1
205 */
206 public function __toString()
207 {
208 $temp = array();
209
210 foreach ($this->data as $name => $rule)
211 {
212 if ($data = $rule->getData())
213 {
214 $temp[$name] = $data;
215 }
216 }
217
218 return json_encode($temp, JSON_FORCE_OBJECT);
219 }
220 }
221