1: <?php
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: class Roles extends CActiveRecord {
47:
48: private static $_authNames;
49:
50: 51: 52: 53:
54: private static $_userRoles;
55: private $_tmpUsers = null;
56: private $_tmpEditPermissions = null;
57: private $_tmpViewPermissions = null;
58:
59: 60: 61:
62: public static function getAuthNames() {
63: if (!isset(self::$_authNames)) {
64: $x2Roles = Yii::app()->db->createCommand()
65: ->select('name')
66: ->from('x2_roles')
67: ->queryColumn();
68: $authRoles = Yii::app()->db->createCommand()
69: ->select('name')
70: ->from('x2_auth_item')
71: ->queryColumn();
72: self::$_authNames = array_diff($authRoles, $x2Roles);
73: }
74: return self::$_authNames;
75: }
76:
77: 78: 79: 80:
81: public static function model($className = __CLASS__) {
82: return parent::model($className);
83: }
84:
85: 86: 87:
88: public static function getCachedUserRoles($userId) {
89:
90: return Yii::app()->cache->get(self::getUserCacheVar($userId));
91: }
92:
93: 94: 95:
96: public static function clearCachedUserRoles($userId) {
97: if (isset(self::$_userRoles[$userId]))
98: unset(self::$_userRoles[$userId]);
99: Yii::app()->cache->delete(self::getUserCacheVar($userId));
100: }
101:
102: 103: 104: 105: 106: 107: 108: 109: 110: 111:
112: public static function getUserRoles($userId, $cache = true) {
113: if (isset(self::$_userRoles[$userId]))
114: return self::$_userRoles[$userId];
115:
116: if ($cache === true && ($userRoles = self::getCachedUserRoles($userId)) !== false) {
117: self::$_userRoles[$userId] = $userRoles;
118: return $userRoles;
119: }
120: $userRoles = array();
121:
122: if ($userId !== null) {
123: $userRoles = Yii::app()->db->createCommand()
124: ->select('roleId')
125: ->from('x2_role_to_user')
126: ->where('`type`="user" AND `userId`=:userId')
127: ->queryColumn(array(':userId' => $userId));
128:
129: $groupRoles = Yii::app()->db->createCommand()
130: ->select('rtu.roleId')
131: ->from('x2_group_to_user gtu')
132: ->join('x2_role_to_user rtu', 'rtu.userId=gtu.groupId '
133: . 'AND gtu.userId=:userId '
134: . 'AND type="group"')
135: ->queryColumn(array(':userId' => $userId));
136: } else {
137: $groupRoles = array();
138: $userRoles = array();
139: $guestRole = self::model()->findByAttributes(array('name' => 'Guest'));
140: if (!empty($guestRole))
141: $userRoles = array($guestRole->id);
142: }
143:
144:
145: $userRoles = array_unique($userRoles + $groupRoles);
146:
147:
148: self::$_userRoles[$userId] = $userRoles;
149: if ($cache === true)
150: Yii::app()->cache->set(self::getUserCacheVar($userId), $userRoles, 259200);
151:
152: return $userRoles;
153: }
154:
155: 156: 157: 158: 159: 160: 161:
162: public static function getUserTimeout($userId, $cache = true) {
163: $cacheVar = 'user_roles_timeout' . $userId;
164: if ($cache === true && ($timeout = Yii::app()->cache->get($cacheVar)) !== false)
165: return $timeout;
166:
167:
168: $userRoles = Roles::getUserRoles($userId);
169: $availableTimeouts = array();
170: foreach ($userRoles as $role) {
171: $timeout = Yii::app()->db->createCommand()
172: ->select('timeout')
173: ->from('x2_roles')
174: ->where('id=:role', array(':role' => $role))
175: ->queryScalar();
176: if (!is_null($timeout))
177: $availableTimeouts[] = (integer) $timeout;
178: }
179:
180: $availableTimeouts[] = Yii::app()->settings->timeout;
181: $timeout = max($availableTimeouts);
182: if ($cache === true)
183: Yii::app()->cache->set($cacheVar, $timeout, 259200);
184: return $timeout;
185: }
186:
187: private static function getUserCacheVar($userId) {
188: return 'user_roles_' . ($userId === null ? 'guest' : $userId);
189: }
190:
191: 192: 193:
194: public function tableName() {
195: return 'x2_roles';
196: }
197:
198: 199: 200:
201: public function rules() {
202:
203:
204: return array(
205: array('name', 'required'),
206: array('name', 'length', 'max' => 250),
207: array('name', 'match',
208: 'not' => true,
209: 'pattern' => '/^(' . implode('|', array_map(function($n) {
210: return preg_quote($n);
211: }, self::getAuthNames())) . ')/i',
212: 'message' => Yii::t('admin', 'The name you entered is reserved or belongs to the system.')),
213: array('timeout', 'numerical', 'integerOnly' => true, 'min' => 5),
214: array('users', 'safe'),
215:
216:
217: array('id, name, users', 'safe', 'on' => 'search'),
218: );
219: }
220:
221: 222: 223:
224: public function relations() {
225:
226:
227: return array();
228: }
229:
230: 231: 232:
233: public function attributeLabels() {
234: return array(
235: 'id' => Yii::t('admin', 'ID'),
236: 'name' => Yii::t('admin', 'Name'),
237: 'users' => Yii::t('admin', 'Users'),
238: 'timeout' => Yii::t('admin','Timeout'),
239: );
240: }
241:
242: 243: 244: 245:
246: public function search() {
247:
248:
249:
250: $criteria = new CDbCriteria;
251:
252: $criteria->compare('id', $this->id);
253: $criteria->compare('name', $this->name, true);
254: $criteria->compare('users', $this->users, true);
255:
256: return new CActiveDataProvider(get_class($this), array(
257: 'criteria' => $criteria,
258: ));
259: }
260:
261: public function getUsers() {
262: $users = Yii::app()->db->createCommand()
263: ->select('userId')
264: ->from('x2_role_to_user')
265: ->where('roleId=:roleId', array(':roleId' => $this->id))
266: ->queryColumn();
267:
268: return $users;
269: }
270:
271: public function getFieldPermissions($permission = null) {
272: $permissions = array();
273: $where = 'roleId=:roleId';
274: $params = array(':roleId' => $this->id);
275: if (!is_null($permission)) {
276: $where.=' AND permission=:permission';
277: $params[':permission'] = $permission;
278: }
279: $fieldData = Yii::app()->db->createCommand()
280: ->select('fieldId, permission')
281: ->from('x2_role_to_permission')
282: ->where($where, $params)
283: ->queryAll();
284: foreach ($fieldData as $row) {
285: $permissions[$row['fieldId']] = $row['permission'];
286: }
287: return $permissions;
288: }
289:
290: public function afterSave() {
291: $this->updateUsers();
292: $this->updatePermissions();
293: parent::afterSave();
294: }
295:
296: public function updateUsers() {
297: if (!is_null($this->_tmpUsers)) {
298: Yii::app()->db->createCommand()
299: ->delete('x2_role_to_user', 'roleId = :roleId', array(':roleId' => $this->id));
300: $insertData = array();
301: foreach ($this->_tmpUsers as $user) {
302: $userId = $user;
303: $type = 'group';
304: if (!is_numeric($user)) {
305: $userRecord = User::model()->findByAttributes(array('username' => $user));
306: $userId = isset($userRecord) ? $userRecord->id : null;
307: $type = 'user';
308: }
309: if (!is_null($userId)) {
310: $insertData[] = array('roleId' => $this->id, 'userId' => $userId, 'type' => $type);
311: }
312: }
313: if (!empty($insertData)) {
314: $builder = Yii::app()->db->schema->commandBuilder;
315: $command = $builder->createMultipleInsertCommand('x2_role_to_user', $insertData);
316: $command->execute();
317: }
318: }
319: }
320:
321: public function updatePermissions() {
322: if (!is_null($this->_tmpEditPermissions) && !is_null($this->_tmpViewPermissions)) {
323: $newPermissions = $this->calculatePermissions();
324: $this->executeMassPermissionsInsertUpdateQuery($newPermissions);
325: }
326: }
327:
328: public function setUsers(Array $users) {
329: $this->_tmpUsers = $users;
330: }
331:
332: public function setEditPermissions(Array $editPermissions) {
333: $this->_tmpEditPermissions = $editPermissions;
334: }
335:
336: public function setViewPermissions(Array $viewPermissions) {
337: $this->_tmpViewPermissions = $viewPermissions;
338: }
339:
340: private function calculatePermissions() {
341: $ret = array(
342: 'edit' => array(),
343: 'view' => array(),
344: 'none' => array()
345: );
346:
347: $fieldIds = Yii::app()->db->createCommand()
348: ->select('id')
349: ->from('x2_fields')
350: ->queryColumn();
351:
352: $ret['edit'] = array_intersect($this->_tmpViewPermissions, $this->_tmpEditPermissions);
353: $ret['view'] = array_diff($this->_tmpViewPermissions, $this->_tmpEditPermissions);
354: $ret['none'] = array_diff($fieldIds, $this->_tmpViewPermissions);
355:
356: return $ret;
357: }
358:
359: private function executeMassPermissionsInsertUpdateQuery($permissions) {
360: $sql = "REPLACE INTO x2_role_to_permission (`roleId`, `fieldId`, `permission`) VALUES ";
361: $editBindParams = AuxLib::bindArray($permissions['edit'], 'edit_');
362: foreach (array_keys($editBindParams) as $bind) {
363: $sql.="\n ({$this->id}, $bind, 2),";
364: }
365: $viewBindParams = AuxLib::bindArray($permissions['view'], 'view_');
366: foreach (array_keys($viewBindParams) as $bind) {
367: $sql.="\n ({$this->id}, $bind, 1),";
368: }
369: $noneBindParams = AuxLib::bindArray($permissions['none'], 'none_');
370: foreach (array_keys($noneBindParams) as $bind) {
371: $sql.="\n ({$this->id}, $bind, 0),";
372: }
373: $sql = substr($sql, 0, -1) . ';';
374: $cmd = Yii::app()->db->createCommand()
375: ->setText($sql);
376:
377: $cmd->execute(array_merge($editBindParams, $viewBindParams, $noneBindParams));
378: }
379:
380: }
381: