Вызов функции-члена isCollection() в null

Я, используя Graphaware Neo4j-php-OGM. Я хотел бы получить доступ к отношениям 2-го уровня. Я не видел, чтобы заставить его работать. Что я делаю неправильно?

Я пытаюсь выполнить следующее:

public function allowToContinue($userUuid, $permissionUuid)
    {
        $userRepo = $this->entityManager->getRepository(User::class);
        $permRoleRepo = $this->entityManager->getRepository(PermRole::class);
        $permissionRepo = $this->entityManager->getRepository(Permission::class);
        $user = $userRepo->findOneBy(['uuid' => $userUuid]);
        $permission = $permissionRepo->findOneBy(['uuid' => $permissionUuid]);
        $allowed = false;
        foreach ($user->getPermrole() as $userRole)
        {
            var_dump($userRole);
            $role = $permRoleRepo->findOneBy(['uuid' => $userRole->getUuid()]);
            var_dump($role);
            foreach ($role->getPermissions() as $perm)
            {
                var_dump($perm->getUuid());
                if($perm->getUuid() === $permissionUuid){
                    $allowed = true;
                }
            }
        }
        return $allowed;
    }

Трассировки стека:

Error:
Call to a member function isCollection() on null

  at vendor/graphaware/neo4j-php-ogm/src/Hydrator/EntityHydrator.php:107
  at GraphAware\Neo4j\OGM\Hydrator\EntityHydrator->hydrateSimpleRelationshipCollection('permissions', object(Result), object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
     (vendor/graphaware/neo4j-php-ogm/src/Persisters/BasicEntityPersister.php:104)
  at GraphAware\Neo4j\OGM\Persisters\BasicEntityPersister->getSimpleRelationshipCollection('permissions', object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
     (vendor/graphaware/neo4j-php-ogm/src/Proxy/NodeCollectionInitializer.php:22)
  at GraphAware\Neo4j\OGM\Proxy\NodeCollectionInitializer->initialize(object(Node), object(neo4j_ogm_proxy_App_Entity_Generic_PermRole))
     (vendor/graphaware/neo4j-php-ogm/src/Proxy/LazyCollection.php:52)
  at GraphAware\Neo4j\OGM\Proxy\LazyCollection->doInitialize()
     (vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php:332)
  at Doctrine\Common\Collections\AbstractLazyCollection->initialize()
     (vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php:274)
  at Doctrine\Common\Collections\AbstractLazyCollection->getIterator()
     (src/Security/RoleChecker.php:45)
  at App\Security\RoleChecker->allowToContinue('8d88d920-5ab0-11e8-a371-001c42dff143', 'd93370b0-585d-11e8-a371-001c42dff143')
     (src/Controller/Generic/UserController.php:146)
  at App\Controller\Generic\UserController->destroy('c34f1380-5ab5-11e8-a371-001c42dff143')
     (vendor/symfony/http-kernel/HttpKernel.php:149)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:66)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:188)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public/index.php:37)

Выдает ошибку во 2-м цикле foreach в строке:

foreach ($role->getPermissions() as $perm)

Странно, правильно работает первый раз, а не второй. Также после получения объекта снова, чтобы быть уверенным. Без этого он выдает точно такое же уведомление. Заранее спасибо!

Весь код на github: https://github.com/djkevino/Support4Neo

2 ответа

  1. Похоже, $role->getPermissions() может вернуть null результат. Итак, убедитесь, что результат не null перед выполнением внутреннего foreach петля.

  2. Поскольку вы, похоже, проверяете, имеет ли какая-либо роль пользователя желаемое разрешение, вам не нужно $allowed переменная на всех. Внутренний foreach цикл может просто сразу вернуться true как только совпадение найдено, избегая ненужной обработки.

То есть попробуйте это:

public function allowToContinue($userUuid, $permissionUuid) {
    $userRepo = $this->entityManager->getRepository(User::class);
    $permRoleRepo = $this->entityManager->getRepository(PermRole::class);
    $permissionRepo = $this->entityManager->getRepository(Permission::class);
    $user = $userRepo->findOneBy(['uuid' => $userUuid]);
    $permission = $permissionRepo->findOneBy(['uuid' => $permissionUuid]);        
    foreach ($user->getPermrole() as $userRole) {
        var_dump($userRole);
        $role = $permRoleRepo->findOneBy(['uuid' => $userRole->getUuid()]);
        var_dump($role);
        $rolePerms = $role->getPermissions();
        if (!is_null($rolePerms)) {
            foreach ($rolePerms as $perm) {
                var_dump($perm->getUuid());
                if ($perm->getUuid() === $permissionUuid) {
                    return true;
                }
            }
        }
    }
    return false;
}

Честно говоря, довольно смущен этим кодом. var_dump() die() вещи в destroy()... Кроме того, мне потребовалось некоторое время, чтобы понять, что мы говорим о коде в библиотеке, а не о коде, который взаимодействует с этой библиотекой.

Можете ли вы избежать такой проблемы?

//add this next line
if (!is_iterable($user->getPermrole())) continue;
foreach ($role->getPermissions() as $perm)

Если вы не используете PHP версии 7.1 или выше, вы можете просто проверить, возвращено ли значение is_null или тест для instance of \Traversable а также is_array...

is_array($foo) || (is_object($foo) && ($foo instanceof \Traversable ));

Как указано в моем комментарии, не уверен, что эта роль, не имеющая "разрешений", считается допустимым состоянием или нет.

Другие вопросы по тегам