Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
RDbAuthManager.php
1 <?php
2 /**
3 * Rights authorization manager class file.
4 *
5 * @author Christoffer Niska <cniska@live.com>
6 * @copyright Copyright &copy; 2010 Christoffer Niska
7 * @since 0.9.7
8 */
9 class RDbAuthManager extends CDbAuthManager
10 {
11  /**
12  * @var string the name of the rights table.
13  */
14  public $rightsTable = 'Rights';
15 
16  private $_items = array();
17  private $_itemChildren = array();
18 
19  /**
20  * Adds an item as a child of another item.
21  * Overloads the parent method to make sure that
22  * we do not add already existing children.
23  * @param string $itemName the item name.
24  * @param string $childName the child item name.
25  * @throws CException if either parent or child doesn't exist or if a loop has been detected.
26  */
27  public function addItemChild($itemName, $childName)
28  {
29  // Make sure that the item doesn't already have this child.
30  if( $this->hasItemChild($itemName, $childName)===false )
31  return parent::addItemChild($itemName, $childName);
32  }
33 
34  /**
35  * Assigns an authorization item to a user making sure that
36  * the user doesn't already have this assignment.
37  * Overloads the parent method to make sure that
38  * we do not assign already assigned items.
39  * @param string $itemName the item name.
40  * @param mixed $userId the user ID (see {@link IWebUser::getId})
41  * @param string $bizRule the business rule to be executed when {@link checkAccess} is called
42  * for this particular authorization item.
43  * @param mixed $data additional data associated with this assignment.
44  * @return CAuthAssignment the authorization assignment information.
45  * @throws CException if the item does not exist or if the item has already been assigned to the user.
46  */
47  public function assign($itemName, $userId, $bizRule=null, $data=null)
48  {
49  // Make sure that this user doesn't already have this assignment.
50  if( $this->getAuthAssignment($itemName, $userId)===null )
51  return parent::assign($itemName, $userId, $bizRule, $data);
52  }
53 
54  /**
55  * Returns the authorization item with the specified name.
56  * Overloads the parent method to allow for runtime caching.
57  * @param string $name the name of the item.
58  * @param boolean $allowCaching whether to accept cached data.
59  * @return CAuthItem the authorization item. Null if the item cannot be found.
60  */
61  public function getAuthItem($name, $allowCaching=true)
62  {
63  // Get all items if necessary and cache them.
64  if( $allowCaching && $this->_items===array() )
65  $this->_items = $this->getAuthItems();
66 
67  // Get the items from cache if possible.
68  if( $allowCaching && isset($this->_items[ $name ]) )
69  {
70  return $this->_items[ $name ];
71  }
72  // Attempt to get the item.
73  else if( ($item = parent::getAuthItem($name))!==null )
74  {
75  return $item;
76  }
77 
78  // Item does not exist.
79  return null;
80  }
81 
82 
83  /**
84  * Returns the specified authorization items.
85  * @param array $names the names of the authorization items to get.
86  * @param boolean $nested whether to nest the items by type.
87  * @return array the authorization items.
88  */
89  public function getAuthItemsByNames($names, $nested=false)
90  {
91  // Get all items if necessary and cache them.
92  if( $this->_items===array() )
93  $this->_items = $this->getAuthItems();
94 
95  // Collect the items we want.
96  $items = array();
97  foreach( $this->_items as $name=>$item )
98  {
99  if( in_array($name, $names) )
100  {
101  if( $nested===true )
102  $items[ $item->getType() ][ $name ] = $item;
103  else
104  $items[ $name ] = $item;
105  }
106  }
107 
108  return $items;
109  }
110 
111  /**
112  * Returns the authorization items of the specific type and user.
113  * Overloads the parent method to allow for sorting.
114  * @param integer $type the item type (0: operation, 1: task, 2: role). Defaults to null,
115  * meaning returning all items regardless of their type.
116  * @param mixed $userId the user ID. Defaults to null, meaning returning all items even if
117  * they are not assigned to a user.
118  * @param boolean $sort whether to sort the items according to their weights.
119  * @return array the authorization items of the specific type.
120  */
121  public function getAuthItems($type=null, $userId=null, $sort=true)
122  {
123  // We need to sort the items.
124  if( $sort===true )
125  {
126  if( $type===null && $userId===null )
127  {
128  $command=$this->db->createCommand()
129  ->select('name,t1.type,description,t1.bizrule,t1.data,weight')
130  ->from($this->itemTable. ' t1')
131  ->leftJoin($this->rightsTable. ' t2', 'name=itemname')
132  ->order('t1.type DESC, weight ASC');
133  }
134  else if( $userId===null )
135  {
136  $command=$this->db->createCommand()
137  ->select('name,t1.type,description,t1.bizrule,t1.data,weight')
138  ->from($this->itemTable.' t1')
139  ->leftJoin($this->rightsTable. ' t2', 'name=itemname')
140  ->where('t1.type=:type')
141  ->order('t1.type DESC, weight ASC');
142  $command->bindValue(':type', $type);
143  }
144  else if( $type===null )
145  {
146  $command=$this->db->createCommand()
147  ->select('name,t1.type,description,t1.bizrule,t1.data,weight')
148  ->from($this->itemTable. ' t1')
149  ->leftJoin($this->assignmentTable .' t2', 'name=t2.itemname')
150  ->leftJoin($this->rightsTable. ' t3', 'name=t3.itemname')
151  ->where('userid=:userid')
152  ->order('t1.type DESC, weight ASC');
153  $command->bindValue(':userid', $userId);
154  }
155  else
156  {
157  $command=$this->db->createCommand()
158  ->select('name,t1.type,description,t1.bizrule,t1.data,weight')
159  ->from($this->itemTable. ' t1')
160  ->leftJoin($this->assignmentTable .' t2', 'name=t2.itemname')
161  ->leftJoin($this->rightsTable. ' t3', 'name=t3.itemname')
162  ->where('t1.type=:type AND userid=:userid')
163  ->order('t1.type DESC, weight ASC');
164  $command->bindValue(':type', $type);
165  $command->bindValue(':userid', $userId);
166  }
167 
168  $items = array();
169  foreach($command->queryAll() as $row)
170  $items[ $row['name'] ] = new CAuthItem($this, $row['name'], $row['type'], $row['description'], $row['bizrule'], unserialize($row['data']));
171  }
172  // No sorting required.
173  else
174  {
175  $items = parent::getAuthItems($type, $userId);
176  }
177 
178  return $items;
179  }
180 
181  /**
182  * Returns the children of the specified item.
183  * Overloads the parent method to allow for caching.
184  * @param mixed $names the parent item name. This can be either a string or an array.
185  * The latter represents a list of item names (available since version 1.0.5).
186  * @param boolean $allowCaching whether to accept cached data.
187  * @return array all child items of the parent
188  */
189  public function getItemChildren($names, $allowCaching=true)
190  {
191  // Resolve the key for runtime caching.
192  $key = $names===(array)$names ? implode('|', $names) : $names;
193 
194  // Get the children from cache if possible.
195  if( $allowCaching && isset($this->_itemChildren[ $key ])===true )
196  {
197  return $this->_itemChildren[ $key ];
198  }
199  // Children not cached or cached data is not accepted.
200  else
201  {
202  // We only have one name.
203  if( is_string($names) )
204  {
205  $condition = 'parent='.$this->db->quoteValue($names);
206  }
207  // We have multiple names.
208  else if( $names===(array)$names && $names!==array() )
209  {
210  foreach($names as &$name)
211  $name=$this->db->quoteValue($name);
212 
213  $condition = 'parent IN ('.implode(', ', $names).')';
214  }
215  else
216  {
217  $condition = '1';
218  }
219 
220 // $sql = "SELECT name, type, description, bizrule, data
221 // FROM {$this->itemTable}, {$this->itemChildTable}
222 // WHERE {$condition} AND name=child";
223 
224  $command = $this->db->createCommand()
225  ->select('name, type, description, bizrule, data')
226  ->from("{$this->itemTable}, {$this->itemChildTable}")
227  ->where("{$condition} AND name=child");
228 
229  $children = array();
230  foreach( $command->queryAll() as $row )
231  {
232  if( ($data = @unserialize($row['data']))===false )
233  $data = null;
234 
235  $children[ $row['name'] ] = new CAuthItem($this, $row['name'], $row['type'], $row['description'], $row['bizrule'], $data);
236  }
237 
238  // Attach the authorization item behavior.
239  $children = Rights::getAuthorizer()->attachAuthItemBehavior($children);
240 
241  // Cache the result.
242  return $this->_itemChildren[ $key ] = $children;
243  }
244  }
245 
246  public function getAssignmentsByItemName($name)
247  {
248 // $sql = "SELECT * FROM {$this->assignmentTable} WHERE itemname=:itemname";
249  $command = $this->db->createCommand()
250  ->select('*')
251  ->from($this->assignmentTable)
252  ->where('itemname=:itemname');
253  $command->bindValue(':itemname', $name);
254 
255  $assignments=array();
256  foreach($command->queryAll() as $row)
257  {
258  if(($data=@unserialize($row['data']))===false)
259  $data=null;
260 
261  $assignments[ $row['userid'] ] = new CAuthAssignment($this, $row['itemname'], $row['userid'], $row['bizrule'], $data);
262  }
263 
264  return $assignments;
265  }
266 
267  /**
268  * Updates the authorization items weight.
269  * @param array $result the result returned from jui-sortable.
270  */
271  public function updateItemWeight($result)
272  {
273  foreach( $result as $weight=>$itemname )
274  {
275 // $sql = "SELECT COUNT(*) FROM {$this->rightsTable}
276 // WHERE itemname=:itemname";
277  $command = $this->db->createCommand()
278  ->select('count(*)')
279  ->from($this->rightsTable)
280  ->where('itemname=:itemname');
281  $command->bindValue(':itemname', $itemname);
282 
283  // Check if the item already has a weight.
284  if( $command->queryScalar()>0 )
285  {
286 // $sql = "UPDATE {$this->rightsTable}
287 // SET weight=:weight
288 // WHERE itemname=:itemname";
289  $command = $this->db->createCommand()
290  ->update($this->rightsTable, array('weight'=> $weight), 'itemname=:itemname', array(':itemname' => $itemname));
291 // $command->bindValue(':weight', $weight);
292 // $command->bindValue(':itemname', $itemname);
293 // $command->execute();
294  }
295  // Item does not have a weight, insert it.
296  else
297  {
298  if( ($item = $this->getAuthItem($itemname))!==null )
299  {
300 // $sql = "INSERT INTO {$this->rightsTable} (itemname, type, weight)
301 // VALUES (:itemname, :type, :weight)";
302  $command = $this->db->createCommand()
303  ->insert($this->rightsTable, array('itemname' => $itemname, 'type'=>$item->getType(), 'weight'=>$weight));
304 // $command->bindValue(':itemname', $itemname);
305 // $command->bindValue(':type', $item->getType());
306 // $command->bindValue(':weight', $weight);
307 // $command->execute();
308  }
309  }
310  }
311  }
312 }