Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • None
  • system
    • base
    • caching
    • console
    • db
      • ar
      • schema
    • validators
    • web
      • actions
      • auth
      • helpers
      • widgets
        • captcha
        • pagers
  • zii
    • widgets
      • grid

Classes

  • ActionMetaData
  • ActionText
  • Admin
  • AmorphousModel
  • ApiHook
  • APIModel
  • ChartSetting
  • ContactForm
  • ContactList
  • Credentials
  • Criteria
  • Dropdowns
  • Events
  • EventsData
  • Fields
  • FormLayout
  • Imports
  • InlineEmail
  • LeadRouting
  • Locations
  • LoginForm
  • Maps
  • Modules
  • Notes
  • Notification
  • PhoneNumber
  • Profile
  • Record
  • Relationships
  • Roles
  • RoleToPermission
  • RoleToUser
  • RoleToWorkflow
  • Rules
  • Session
  • SessionLog
  • Social
  • Tags
  • TempFile
  • Tips
  • Tours
  • TrackEmail
  • TriggerLog
  • URL
  • ViewLog
  • Widgets
  • X2List
  • X2ListCriterion
  • X2ListItem
  • X2Model
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /*****************************************************************************************
  4:  * X2Engine Open Source Edition is a customer relationship management program developed by
  5:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  6:  * 
  7:  * This program is free software; you can redistribute it and/or modify it under
  8:  * the terms of the GNU Affero General Public License version 3 as published by the
  9:  * Free Software Foundation with the addition of the following permission added
 10:  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 11:  * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 12:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 13:  * 
 14:  * This program is distributed in the hope that it will be useful, but WITHOUT
 15:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 16:  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 17:  * details.
 18:  * 
 19:  * You should have received a copy of the GNU Affero General Public License along with
 20:  * this program; if not, see http://www.gnu.org/licenses or write to the Free
 21:  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 22:  * 02110-1301 USA.
 23:  * 
 24:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 25:  * California 95067, USA. or at email address contact@x2engine.com.
 26:  * 
 27:  * The interactive user interfaces in modified source and object code versions
 28:  * of this program must display Appropriate Legal Notices, as required under
 29:  * Section 5 of the GNU Affero General Public License version 3.
 30:  * 
 31:  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 32:  * these Appropriate Legal Notices must retain the display of the "Powered by
 33:  * X2Engine" logo. If the display of the logo is not reasonably feasible for
 34:  * technical reasons, the Appropriate Legal Notices must display the words
 35:  * "Powered by X2Engine".
 36:  *****************************************************************************************/
 37: 
 38: /**
 39:  * This is the model class for table "x2_roles".
 40:  *
 41:  * @package application.models
 42:  * @property integer $id
 43:  * @property string $name
 44:  * @property string $users
 45:  */
 46: class Roles extends CActiveRecord {
 47: 
 48:     private static $_authNames;
 49: 
 50:     /**
 51:      * Runtime storage array of user roles indexed by user ID
 52:      * @var type
 53:      */
 54:     private static $_userRoles;
 55:     private $_tmpUsers = null;
 56:     private $_tmpEditPermissions = null;
 57:     private $_tmpViewPermissions = null;
 58: 
 59:     /**
 60:      * Retrieves a list of restricted (non-permissible) role names.
 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:      * Returns the static model of the specified AR class.
 79:      * @return Roles the static model class
 80:      */
 81:     public static function model($className = __CLASS__) {
 82:         return parent::model($className);
 83:     }
 84: 
 85:     /**
 86:      * Get roles from cache 
 87:      */
 88:     public static function getCachedUserRoles($userId) {
 89:         // check the app cache for user's roles
 90:         return Yii::app()->cache->get(self::getUserCacheVar($userId));
 91:     }
 92: 
 93:     /**
 94:      * Clear role cache for specified user 
 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:      * Determines roles of the specified user, including group-inherited roles.
104:      *
105:      * Uses cache to lookup/store roles.
106:      *
107:      * @param integer $userId user for which to look up roles. Note, null user ID
108:      *  implies guest.
109:      * @param boolean $cache whether to use cache
110:      * @return Array array of roleIds
111:      */
112:     public static function getUserRoles($userId, $cache = true) {
113:         if (isset(self::$_userRoles[$userId]))
114:             return self::$_userRoles[$userId];
115:         // check the app cache for user's roles
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) { // Authenticated user
123:             $userRoles = Yii::app()->db->createCommand() // lookup the user's roles
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() // lookup roles of all the user's groups
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 { // Guest
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:         // Combine all the roles, remove duplicates:
145:         $userRoles = array_unique($userRoles + $groupRoles);
146: 
147:         // Cache/store:
148:         self::$_userRoles[$userId] = $userRoles;
149:         if ($cache === true)
150:             Yii::app()->cache->set(self::getUserCacheVar($userId), $userRoles, 259200); // cache user groups for 3 days
151: 
152:         return $userRoles;
153:     }
154: 
155:     /**
156:      * Returns the timeout of the current user.
157:      *
158:      * Selects and returns the maximum timeout between the timeouts of the
159:      * current user's roles and the default timeout.
160:      * @return Integer Maximum timeout value
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:      * @return string the associated database table name
193:      */
194:     public function tableName() {
195:         return 'x2_roles';
196:     }
197: 
198:     /**
199:      * @return array validation rules for model attributes.
200:      */
201:     public function rules() {
202:         // NOTE: you should only define rules for those attributes that
203:         // will receive user inputs.
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:             // The following rule is used by search().
216:             // Please remove those attributes that should not be searched.
217:             array('id, name, users', 'safe', 'on' => 'search'),
218:         );
219:     }
220: 
221:     /**
222:      * @return array relational rules.
223:      */
224:     public function relations() {
225:         // NOTE: you may need to adjust the relation name and the related
226:         // class name for the relations automatically generated below.
227:         return array();
228:     }
229: 
230:     /**
231:      * @return array customized attribute labels (name=>label)
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:      * Retrieves a list of models based on the current search/filter conditions.
244:      * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
245:      */
246:     public function search() {
247:         // Warning: Please modify the following code to remove attributes that
248:         // should not be searched.
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: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0