/**
  * @param string $modelClassName
  * @param null | string $attributeIndexes
  * @param null | string $attributeIndexPrefix
  */
 public static function resolveAttributeIndexes($modelClassName, &$attributeIndexes, $attributeIndexPrefix = null)
 {
     assert('is_string($modelClassName)');
     assert('is_string($attributeIndexPrefix) || $attributeIndexPrefix == null');
     $moduleClassName = $modelClassName::getModuleClassName();
     if (is_subclass_of($modelClassName, 'SecurableItem') && $modelClassName::hasReadPermissionsOptimization() && $moduleClassName != null && is_subclass_of($moduleClassName, 'SecurableModule')) {
         $permission = PermissionsUtil::getActualPermissionDataForReadByModuleNameForUser($moduleClassName);
         if ($permission == Permission::NONE || $permission == Permission::DENY) {
             $indexes = array();
             $indexes[] = 'owner__User';
             $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser(Yii::app()->user->userModel);
             if (count($mungeIds) > 0 && $permission == Permission::NONE) {
                 $indexes[] = 'ReadOptimization';
             }
             $attributeIndexes[$attributeIndexPrefix] = $indexes;
         }
     }
 }
 /**
  * @param $requiredPermissions
  * @param OwnedSecurableItem $ownedSecurableItem
  * @param User $user
  * @return bool
  * @throws NotSupportedException
  * @throws AccessDeniedSecurityException
  */
 protected static function checkPermissionsHasRead($requiredPermissions, OwnedSecurableItem $ownedSecurableItem, User $user)
 {
     $modelClassName = get_class($ownedSecurableItem);
     $moduleClassName = $modelClassName::getModuleClassName();
     $permission = PermissionsUtil::getActualPermissionDataForReadByModuleNameForUser($moduleClassName, $user);
     if ($permission == Permission::NONE) {
         $mungeIds = static::getMungeIdsByUser($user);
         if (count($mungeIds) > 0 && $permission == Permission::NONE) {
             $quote = DatabaseCompatibilityUtil::getQuote();
             $mungeTableName = ReadPermissionsOptimizationUtil::getMungeTableName($modelClassName);
             $sql = "select id from " . $mungeTableName . " where {$quote}securableitem_id{$quote} = " . $ownedSecurableItem->getClassId('SecurableItem') . " and {$quote}munge_id{$quote} in ('" . join("', '", $mungeIds) . "') limit 1";
             $id = ZurmoRedBean::getCol($sql);
             if (!empty($id)) {
                 return true;
             } else {
                 throw new AccessDeniedSecurityException($user, $requiredPermissions, Permission::NONE);
             }
         } else {
             throw new NotSupportedException();
         }
     } elseif ($permission == Permission::DENY) {
         throw new AccessDeniedSecurityException($user, $requiredPermissions, Permission::DENY);
     } else {
         return true;
     }
 }
 /**
  * @param User $user
  * @param RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter
  * @param $where
  * @param $selectDistinct
  * @throws NotSupportedException
  */
 public static function resolveReadPermissionsOptimizationToSqlQuery(User $user, RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter, &$where, &$selectDistinct)
 {
     assert('$where == null || is_string($where)');
     assert('is_bool($selectDistinct)');
     $modelClassName = get_called_class();
     $moduleClassName = $modelClassName::getModuleClassName();
     //Currently only adds munge if the module is securable and this model supports it.
     if (static::hasReadPermissionsOptimization() && $moduleClassName != null && is_subclass_of($moduleClassName, 'SecurableModule')) {
         $permission = PermissionsUtil::getActualPermissionDataForReadByModuleNameForUser($moduleClassName);
         if (($permission == Permission::NONE || $permission == Permission::DENY) && !static::bypassReadPermissionsOptimizationToSqlQueryBasedOnWhere($where)) {
             $quote = DatabaseCompatibilityUtil::getQuote();
             $modelAttributeToDataProviderAdapter = new OwnedSecurableItemIdToDataProviderAdapter($modelClassName, null);
             $builder = new ModelJoinBuilder($modelAttributeToDataProviderAdapter, $joinTablesAdapter);
             $ownedTableAliasName = $builder->resolveJoins();
             $ownerColumnName = static::getForeignKeyName('OwnedSecurableItem', 'owner');
             $mungeIds = AllPermissionsOptimizationUtil::getMungeIdsByUser($user);
             if ($where != null) {
                 $where = '(' . $where . ') and ';
             }
             if (count($mungeIds) > 0 && $permission == Permission::NONE) {
                 $extraOnQueryPart = " and {$quote}munge_id{$quote} in ('" . join("', '", $mungeIds) . "')";
                 $mungeTableName = ReadPermissionsOptimizationUtil::getMungeTableName($modelClassName);
                 $mungeTableAliasName = $joinTablesAdapter->addLeftTableAndGetAliasName($mungeTableName, 'securableitem_id', $ownedTableAliasName, 'securableitem_id', $extraOnQueryPart);
                 $where .= "({$quote}{$ownedTableAliasName}{$quote}.{$quote}{$ownerColumnName}{$quote} = {$user->id} OR ";
                 // Not Coding Standard
                 $where .= "{$quote}{$mungeTableName}{$quote}.{$quote}munge_id{$quote} IS NOT NULL)";
                 // Not Coding Standard
                 $selectDistinct = true;
                 //must use distinct since adding munge table query.
             } elseif ($permission == Permission::DENY) {
                 $where .= "{$quote}{$ownedTableAliasName}{$quote}.{$quote}{$ownerColumnName}{$quote} = {$user->id}";
                 // Not Coding Standard
             } else {
                 throw new NotSupportedException();
             }
         }
     }
 }