public function run()
 {
     //Do not run this job if ReadPermissionSubscriptionUpdateComplete is already running
     try {
         JobInProcess::getByType('ReadPermissionSubscriptionComprehensiveUpdate');
     } catch (NotFoundException $e) {
         ReadPermissionsSubscriptionUtil::updateAllReadSubscriptionTables(true);
     }
     return true;
 }
 public function run()
 {
     $counter = 0;
     try {
         while (JobInProcess::getByType('ReadPermissionSubscriptionQuickUpdate') instanceof RedBeanModel && $counter <= self::MAX_NUMBER_OF_TRIES) {
             sleep(30);
             $counter++;
         }
     } catch (NotFoundException $e) {
         ReadPermissionsSubscriptionUtil::updateAllReadSubscriptionTables(false);
         return true;
     }
     return false;
 }
Exemplo n.º 3
0
 /**
  * Given an installSettingsForm, run the install including the schema creation and default data load. This is
  * used by the interactive install and the command line install.
  * @param object $form
  * @param object $messageStreamer
  */
 public static function runInstallation($form, &$messageStreamer)
 {
     Yii::app()->params['isFreshInstall'] = true;
     assert('$form instanceof InstallSettingsForm');
     assert('$messageStreamer instanceof MessageStreamer');
     if (defined('IS_TEST')) {
         $perInstanceFilename = "perInstanceTest.php";
         $debugFilename = "debugTest.php";
     } else {
         @set_time_limit(1200);
         $perInstanceFilename = "perInstance.php";
         $debugFilename = "debug.php";
     }
     $messageStreamer->add(Zurmo::t('InstallModule', 'Connecting to Database.'));
     static::connectToDatabase($form->databaseType, $form->databaseHostname, $form->databaseName, $form->databaseUsername, $form->databasePassword, $form->databasePort);
     ForgetAllCacheUtil::forgetAllCaches();
     $messageStreamer->add(Zurmo::t('InstallModule', 'Dropping existing tables.'));
     ZurmoRedBean::$writer->wipeAll();
     $messageStreamer->add(Zurmo::t('InstallModule', 'Creating super user.'));
     $messageLogger = new MessageLogger($messageStreamer);
     $messageLogger->logDateTimeStamp = false;
     Yii::app()->custom->runBeforeInstallationAutoBuildDatabase($messageLogger);
     $messageStreamer->add(Zurmo::t('InstallModule', 'Starting database schema creation.'));
     $startTime = microtime(true);
     $messageStreamer->add('debugOn:' . BooleanUtil::boolToString(YII_DEBUG));
     $messageStreamer->add('phpLevelCaching:' . BooleanUtil::boolToString(PHP_CACHING_ON));
     $messageStreamer->add('memcacheLevelCaching:' . BooleanUtil::boolToString(MEMCACHE_ON));
     static::autoBuildDatabase($messageLogger, false);
     $endTime = microtime(true);
     $messageStreamer->add(Zurmo::t('InstallModule', 'Total autobuild time: {formattedTime} seconds.', array('{formattedTime}' => number_format($endTime - $startTime, 3))));
     if (SHOW_QUERY_DATA) {
         $messageStreamer->add(FooterView::getTotalAndDuplicateQueryCountContent());
         $messageStreamer->add(PageView::makeNonHtmlDuplicateCountAndQueryContent());
     }
     $messageStreamer->add(Zurmo::t('InstallModule', 'Database schema creation complete.'));
     $messageStreamer->add(Zurmo::t('InstallModule', 'Rebuilding Permissions.'));
     AllPermissionsOptimizationUtil::rebuild();
     $messageStreamer->add(Zurmo::t('InstallModule', 'Rebuilding Read Permissions Subscription tables.'));
     ReadPermissionsSubscriptionUtil::buildTables();
     $messageStreamer->add(Zurmo::t('InstallModule', 'Writing Configuration File.'));
     static::writeConfiguration(INSTANCE_ROOT, $form->databaseType, $form->databaseHostname, $form->databaseName, $form->databaseUsername, $form->databasePassword, $form->databasePort, $form->memcacheHostname, (int) $form->memcachePortNumber, true, Yii::app()->language, $perInstanceFilename, $debugFilename, $form->hostInfo, $form->scriptUrl, $form->submitCrashToSentry);
     static::setZurmoTokenAndWriteToPerInstanceFile(INSTANCE_ROOT);
     ZurmoPasswordSecurityUtil::setPasswordSaltAndWriteToPerInstanceFile(INSTANCE_ROOT);
     static::createSuperUser('super', $form->superUserPassword);
     $messageStreamer->add(Zurmo::t('InstallModule', 'Setting up default data.'));
     DefaultDataUtil::load($messageLogger);
     static::createBaseControlUserConfigUtilUserAccount();
     Yii::app()->custom->runAfterInstallationDefaultDataLoad($messageLogger);
     // Send notification to super admin to delete test.php file in case if this
     // installation is used in production mode.
     $message = new NotificationMessage();
     $message->textContent = Zurmo::t('InstallModule', 'If this website is in production mode, please remove the app/test.php file.');
     $rules = new RemoveApiTestEntryScriptFileNotificationRules();
     NotificationsUtil::submit($message, $rules);
     // If minify is disabled, inform user that they should fix issues and enable minify
     $setIncludePathServiceHelper = new SetIncludePathServiceHelper();
     if (!$setIncludePathServiceHelper->runCheckAndGetIfSuccessful()) {
         $message = new NotificationMessage();
         $message->textContent = Zurmo::t('InstallModule', 'Minify has been disabled due to a system issue. Try to resolve the problem and re-enable Minify.');
         $rules = new EnableMinifyNotificationRules();
         NotificationsUtil::submit($message, $rules);
     }
     $messageStreamer->add(Zurmo::t('InstallModule', 'Installation Complete.'));
     Yii::app()->params['isFreshInstall'] = false;
 }
 /**
  * Takes post data and prepares it for setting the membership on the group.
  * Adds and removes users to group based on a form's userMembershipData
  * @param $form
  * @param $group
  * @return boolean. True if membership was set successfully.
  */
 public static function setMembershipFromForm($form, $group)
 {
     assert('$group instanceof Group');
     assert('$form instanceof GroupUserMembershipForm');
     $removedUsers = array();
     $addedUsers = array();
     foreach ($group->users as $index => $user) {
         if (empty($form->userMembershipData[$user->id]) && !$user->isSystemUser && !$user->isRootUser) {
             $removedUsers[] = $user;
         }
     }
     foreach ($removedUsers as $user) {
         $group->users->remove($user);
     }
     $users = GroupUserMembershipFormUtil::makeUsersFromUserMembershipData($form->userMembershipData);
     foreach ($users as $user) {
         if (!$group->users->contains($user)) {
             $group->users->add($user);
             $addedUsers[] = $user;
         }
     }
     $group->save();
     foreach ($removedUsers as $user) {
         AllPermissionsOptimizationUtil::userRemovedFromGroup($group, $user);
     }
     foreach ($addedUsers as $user) {
         AllPermissionsOptimizationUtil::userAddedToGroup($group, $user);
     }
     if (!empty($removedUsers)) {
         ReadPermissionsSubscriptionUtil::userRemovedFromGroup();
     }
     if (!empty($addedUsers)) {
         ReadPermissionsSubscriptionUtil::userAddedToGroup();
     }
     return true;
 }
 /**
  * @param MessageLogger $messageLogger
  * @param null $modelClassName
  */
 public static function updateReadSubscriptionTableFromBuildTable(MessageLogger $messageLogger, $modelClassName = null)
 {
     if ($modelClassName == 'Account') {
         // ToDO: Add pagination - Ivica: I do not think we need it
         $accountIds = static::getAccountIdsArrayFromBuildTable();
         ReadPermissionsSubscriptionUtil::updateAllReadSubscriptionTables($messageLogger, array($modelClassName), $accountIds);
         if ($modelClassName == 'Account' && !empty($accountIds)) {
             foreach ($accountIds as $accountId) {
                 static::deleteAccountIdFromBuildTable((int) $accountId);
             }
         }
     }
 }
Exemplo n.º 6
0
 protected function afterDelete()
 {
     parent::afterDelete();
     ReadPermissionsSubscriptionUtil::deleteUserItemsFromAllReadSubscriptionTables($this->id);
 }
 /**
  * Update read subscription table for all users and models
  * @param bool $partialBuild
  */
 public static function updateAllReadSubscriptionTables($partialBuild = true)
 {
     $loggedUser = Yii::app()->user->userModel;
     $users = User::getAll();
     foreach ($users as $user) {
         Yii::app()->user->userModel = $user;
         $modelClassNames = ReadPermissionsSubscriptionUtil::getReadSubscriptionModelClassNames();
         if (!empty($modelClassNames) && is_array($modelClassNames)) {
             foreach ($modelClassNames as $modelClassName) {
                 if ($modelClassName != 'Account') {
                     self::updateReadSubscriptionTableByModelClassNameAndUser($modelClassName, Yii::app()->user->userModel, $partialBuild, true);
                 } else {
                     self::updateReadSubscriptionTableByModelClassNameAndUser($modelClassName, Yii::app()->user->userModel, $partialBuild, false);
                 }
             }
         }
     }
     Yii::app()->user->userModel = $loggedUser;
 }
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     ContactsModule::loadStartingData();
     ReadPermissionsSubscriptionUtil::buildTables();
 }
 /**
  * @param CEvent $event
  * @return bool
  */
 public function readPermissionSubscriptionOnAfterDelete(CEvent $event)
 {
     if ($this->enabled) {
         if (get_class($event->sender) == 'Account') {
             ReadPermissionsSubscriptionUtil::updateAccountReadSubscriptionTableBasedOnBuildTable($event->sender->id);
         } else {
             ReadPermissionsSubscriptionUtil::deleteModelFromReadSubscriptionTableByModelIdAndModelClassNameAndUser($event->sender->id, get_class($event->sender), $event->sender->owner);
         }
     }
     return true;
 }
 /**
  * @depends testChangeOwnerOfModelInReadSubscriptionTableByModelIdAndModelClassNameAndUser
  */
 public function testDeleteUserItemsFromAllReadSubscriptionTables()
 {
     $super = User::getByUsername('super');
     $david = UserTestHelper::createBasicUser('david');
     Yii::app()->user->userModel = $super;
     // Clean contact table
     $contacts = Contact::getAll();
     foreach ($contacts as $contact) {
         $contact->delete();
     }
     $sql = "DELETE FROM contact_read_subscription";
     ZurmoRedBean::exec($sql);
     $sql = "SELECT * FROM contact_read_subscription";
     $rows = ZurmoRedBean::getAll($sql);
     $this->assertTrue(empty($rows));
     $contact1 = ContactTestHelper::createContactByNameForOwner('Ray', $david);
     $sql = "SELECT * FROM contact_read_subscription";
     $rows = ZurmoRedBean::getAll($sql);
     $this->assertEquals(0, count($rows));
     ReadPermissionsSubscriptionUtil::updateReadSubscriptionTableByModelClassNameAndUser('Contact', $super, time(), true, new MessageLogger());
     ReadPermissionsSubscriptionUtil::updateReadSubscriptionTableByModelClassNameAndUser('Contact', $david, time(), true, new MessageLogger());
     $sql = "SELECT * FROM contact_read_subscription";
     $rows = ZurmoRedBean::getAll($sql);
     $this->assertEquals(1, count($rows));
     $this->assertEquals($david->id, $rows[0]['userid']);
     $this->assertEquals($contact1->id, $rows[0]['modelid']);
     $this->assertEquals(ReadPermissionsSubscriptionUtil::TYPE_ADD, $rows[0]['subscriptiontype']);
     $david->delete();
     $sql = "SELECT * FROM contact_read_subscription";
     $rows = ZurmoRedBean::getAll($sql);
     $this->assertEquals(0, count($rows));
 }
 public function testGetUpdatedModels()
 {
     ReadPermissionsSubscriptionUtil::recreateTable('account_read_subscription');
     ModelCreationApiSyncUtil::buildTable();
     $account1 = AccountTestHelper::createAccountByNameForOwner('First Test Update Account', Yii::app()->user->userModel);
     $timestamp = time();
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertTrue(empty($models));
     $account1->name = 'First Test Update Account Modified';
     $this->assertTrue($account1->save());
     // This should return true, because there should be 3 second gap between created and modified timestamps
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertTrue(empty($models));
     sleep(4);
     $account1->name = 'First Test Update Account Modified 2';
     $this->assertTrue($account1->save());
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertEquals(1, count($models));
     $this->assertEquals($account1->id, $models[0]->id);
     $this->assertEquals($account1->name, $models[0]->name);
     // Check pagination
     sleep(2);
     $timestamp = time();
     $account2 = AccountTestHelper::createAccountByNameForOwner('Second Test Update Account', Yii::app()->user->userModel);
     $account3 = AccountTestHelper::createAccountByNameForOwner('Third Test Update Account', Yii::app()->user->userModel);
     $account4 = AccountTestHelper::createAccountByNameForOwner('Forth Test Update Account', Yii::app()->user->userModel);
     sleep(5);
     $account2->name = 'Second Test Update Account Modified';
     $account3->name = 'Third Test Update Account Modified';
     $account4->name = 'Forth Test Update Account Modified';
     $this->assertTrue($account2->save());
     $this->assertTrue($account3->save());
     $this->assertTrue($account4->save());
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 3, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertEquals(3, count($models));
     $this->assertTrue($account2->id == $models[0]->id || $account2->id == $models[1]->id || $account2->id == $models[2]->id);
     $this->assertTrue($account2->name == $models[0]->name || $account2->name == $models[1]->name || $account2->name == $models[2]->name);
     $this->assertTrue($account3->id == $models[0]->id || $account3->id == $models[1]->id || $account3->id == $models[2]->id);
     $this->assertTrue($account3->name == $models[0]->name || $account3->name == $models[1]->name || $account3->name == $models[2]->name);
     $this->assertTrue($account4->id == $models[0]->id || $account4->id == $models[1]->id || $account4->id == $models[2]->id);
     $this->assertTrue($account4->name == $models[0]->name || $account4->name == $models[1]->name || $account4->name == $models[2]->name);
     // Not test for non super user
     $job = new ReadPermissionSubscriptionQuickUpdateJob();
     $mike = UserTestHelper::createBasicUser('Mike');
     $mikeAccount1 = AccountTestHelper::createAccountByNameForOwner('ABC Account', Yii::app()->user->userModel);
     $timestamp = time();
     $this->assertTrue($job->run());
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertTrue(empty($models));
     $mikeAccount1->name = 'ABCD Account';
     $this->assertTrue($mikeAccount1->save());
     // This should return true, because there should be 3 second gap between created and modified timestamps
     $this->assertTrue($job->run());
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertTrue(empty($models));
     sleep(4);
     $mikeAccount1->name = 'AB Account';
     $this->assertTrue($mikeAccount1->save());
     $this->assertTrue($job->run());
     $models = ModelStateChangesSubscriptionUtil::getUpdatedModels('Account', 2, 0, $timestamp);
     $this->assertTrue(is_array($models));
     $this->assertEquals(1, count($models));
     $this->assertEquals($mikeAccount1->id, $models[0]->id);
     $this->assertEquals($mikeAccount1->name, $models[0]->name);
 }
 public function testGetAddedOrDeletedModelsFromReadSubscriptionTable()
 {
     ReadPermissionsSubscriptionUtil::buildTables();
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $task = TaskTestHelper::createTaskByNameForOwner('Test Task', $super);
     ReadPermissionsSubscriptionUtil::updateAllReadSubscriptionTables(false);
     $sql = "SELECT * FROM task_read_subscription WHERE userid = " . $super->id;
     $permissionTableRows = R::getAll($sql);
     $this->assertEquals(1, count($permissionTableRows));
     $addedModelIds = ReadPermissionsSubscriptionUtil::getAddedOrDeletedModelsFromReadSubscriptionTable('TestService', 'Task', 0, ReadPermissionsSubscriptionUtil::TYPE_ADD, $super);
     $this->asserttrue(is_array($addedModelIds));
     $this->assertEquals(1, count($addedModelIds));
     ModelCreationApiSyncUtil::insertItem('TestService', $task->id, 'Task', '2013-05-03 15:16:06');
     $addedModelIds = ReadPermissionsSubscriptionUtil::getAddedOrDeletedModelsFromReadSubscriptionTable('TestService', 'Task', 0, ReadPermissionsSubscriptionUtil::TYPE_ADD, $super);
     $this->asserttrue(is_array($addedModelIds));
     $this->assertEquals(0, count($addedModelIds));
 }
 public function run()
 {
     ReadPermissionsSubscriptionUtil::updateReadSubscriptionTableFromBuildTable($this->getMessageLogger(), 'Account');
     return true;
 }
 public function run()
 {
     ReadPermissionsSubscriptionUtil::updateAllReadSubscriptionTables($this->getMessageLogger());
     return true;
 }
Exemplo n.º 15
0
 /**
  * Cleanup models and read permission tables
  * @param $modelClassName
  */
 protected function deleteAllModelsAndRecordsFromReadPermissionTable($modelClassName)
 {
     $models = $modelClassName::getAll();
     foreach ($models as $model) {
         $model->delete();
     }
     $tableName = ReadPermissionsSubscriptionUtil::getSubscriptionTableName($modelClassName);
     $sql = "DELETE FROM {$tableName}";
     ZurmoRedBean::exec($sql);
     $tableName = ReadPermissionsSubscriptionUtil::getAccountSubscriptionTempBuildTableName($modelClassName);
     $sql = "DELETE FROM {$tableName}";
     ZurmoRedBean::exec($sql);
 }
 /**
  * @param string $serviceName
  * @param $serviceName
  * @param $modelClassName
  * @param $pageSize
  * @param $offset
  * @param $timestamp
  * @param null $stateMetadataAdapterClassName
  * @return array
  */
 public static function getDeletedModelIds($serviceName, $modelClassName, $pageSize, $offset, $timestamp, $stateMetadataAdapterClassName = null)
 {
     $modelIds = ReadPermissionsSubscriptionUtil::getAddedOrDeletedModelsFromReadSubscriptionTable($serviceName, $modelClassName, $timestamp, ReadPermissionsSubscriptionUtil::TYPE_DELETE, Yii::app()->user->userModel);
     $modelIds = array_slice($modelIds, $offset, $pageSize);
     return $modelIds;
 }
 /**
  * Given a SecurableItem, add and remove permissions
  * based on what the provided ExplicitReadWriteModelPermissions indicates should be done.
  * Sets @see SecurableItem->setTreatCurrentUserAsOwnerForPermissions as true in order to ensure the current user
  * can effectively add permissions even if the current user is no longer the owner.
  * @param SecurableItem $securableItem
  * @param ExplicitReadWriteModelPermissions $explicitReadWriteModelPermissions
  * @param bool $validate
  * @return bool|void
  * @throws NotSupportedException
  */
 public static function resolveExplicitReadWriteModelPermissions(SecurableItem $securableItem, ExplicitReadWriteModelPermissions $explicitReadWriteModelPermissions, $validate = false)
 {
     assert('$securableItem->id > 0');
     $optimizeReadPermissions = $securableItem::hasReadPermissionsOptimization();
     $securableItem->setTreatCurrentUserAsOwnerForPermissions(true);
     $saveSecurableItem = false;
     if ($explicitReadWriteModelPermissions->getReadOnlyPermitablesCount() > 0) {
         $saveSecurableItem = true;
         foreach ($explicitReadWriteModelPermissions->getReadOnlyPermitables() as $permitable) {
             if ($securableItem->addPermissions($permitable, Permission::READ) && $optimizeReadPermissions) {
                 if ($permitable instanceof Group) {
                     AllPermissionsOptimizationUtil::securableItemGivenReadPermissionsForGroup($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemGivenPermissionsForGroup($securableItem);
                 } elseif ($permitable instanceof User) {
                     AllPermissionsOptimizationUtil::securableItemGivenReadPermissionsForUser($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemGivenPermissionsForUser($securableItem);
                 } else {
                     throw new NotSupportedException();
                 }
             }
         }
     }
     if ($explicitReadWriteModelPermissions->getReadWritePermitablesCount() > 0) {
         $saveSecurableItem = true;
         foreach ($explicitReadWriteModelPermissions->getReadWritePermitables() as $permitable) {
             if ($securableItem->addPermissions($permitable, Permission::READ_WRITE_CHANGE_PERMISSIONS_CHANGE_OWNER) && $optimizeReadPermissions) {
                 if ($permitable instanceof Group) {
                     AllPermissionsOptimizationUtil::securableItemGivenPermissionsForGroup($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemGivenPermissionsForGroup($securableItem);
                 } elseif ($permitable instanceof User) {
                     AllPermissionsOptimizationUtil::securableItemGivenPermissionsForUser($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemGivenPermissionsForUser($securableItem);
                 } else {
                     throw new NotSupportedException();
                 }
             }
         }
     }
     if ($explicitReadWriteModelPermissions->getReadOnlyPermitablesToRemoveCount() > 0) {
         $saveSecurableItem = true;
         foreach ($explicitReadWriteModelPermissions->getReadOnlyPermitablesToRemove() as $permitable) {
             $securableItem->removePermissions($permitable, Permission::READ, Permission::ALLOW);
             if ($optimizeReadPermissions) {
                 if ($permitable instanceof Group) {
                     AllPermissionsOptimizationUtil::securableItemLostReadPermissionsForGroup($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemLostPermissionsForGroup($securableItem);
                 } elseif ($permitable instanceof User) {
                     AllPermissionsOptimizationUtil::securableItemLostReadPermissionsForUser($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemLostPermissionsForUser($securableItem);
                 } else {
                     throw new NotSupportedException();
                 }
             }
         }
     }
     if ($explicitReadWriteModelPermissions->getReadWritePermitablesToRemoveCount() > 0) {
         $saveSecurableItem = true;
         foreach ($explicitReadWriteModelPermissions->getReadWritePermitablesToRemove() as $permitable) {
             $securableItem->removePermissions($permitable, Permission::READ_WRITE_CHANGE_PERMISSIONS_CHANGE_OWNER, Permission::ALLOW);
             if ($optimizeReadPermissions) {
                 if ($permitable instanceof Group) {
                     AllPermissionsOptimizationUtil::securableItemLostPermissionsForGroup($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemLostPermissionsForGroup($securableItem);
                 } elseif ($permitable instanceof User) {
                     AllPermissionsOptimizationUtil::securableItemLostPermissionsForUser($securableItem, $permitable);
                     ReadPermissionsSubscriptionUtil::securableItemLostPermissionsForUser($securableItem);
                 } else {
                     throw new NotSupportedException();
                 }
             }
         }
     }
     if ($saveSecurableItem) {
         $setBackToProcess = false;
         if ($securableItem->shouldProcessWorkflowOnSave()) {
             $securableItem->setDoNotProcessWorkflowOnSave();
             $setBackToProcess = true;
         }
         $saved = $securableItem->save($validate);
         if ($setBackToProcess) {
             $securableItem->setProcessWorkflowOnSave();
         }
         $securableItem->setTreatCurrentUserAsOwnerForPermissions(false);
         return $saved;
     }
     $securableItem->setTreatCurrentUserAsOwnerForPermissions(false);
     return true;
 }
Exemplo n.º 18
0
 protected function afterDelete()
 {
     $this->forgetPermissionsRightsAndPoliciesCache();
     ReadPermissionsSubscriptionUtil::roleHasBeenDeleted();
     AllPermissionsOptimizationCache::forgetAll();
     static::forgetRoleIdToRoleCache();
 }
 protected static function addOrRemoveSpecificPermission($moduleClassName, $permitable, $permission, $value)
 {
     assert('is_string($moduleClassName)');
     assert('$permitable instanceof Permitable');
     assert('$permitable->id > 0');
     assert('is_int($permission)');
     assert('is_int($value) || $value == null');
     $item = NamedSecurableItem::getByName($moduleClassName);
     $item->allowChangePermissionsRegardlessOfUser = true;
     if (!empty($value) && $value == Permission::ALLOW) {
         //Before adding explicit allow permission, remove any existing deny permission
         $item->removePermissions($permitable, $permission, Permission::DENY);
         $item->addPermissions($permitable, $permission, Permission::ALLOW);
     } elseif (!empty($value) && $value == Permission::DENY) {
         $item->addPermissions($permitable, $permission, Permission::DENY);
     } else {
         $item->removePermissions($permitable, $permission);
     }
     $saved = $item->save();
     if ($saved) {
         ReadPermissionsSubscriptionUtil::modulePermissionsHasBeenChanged($permitable);
     }
     $item->forget();
     return $saved;
 }