We are using the Profile module and I'm trying to hide the menu tab on the user's account for certain users based on a value of a field on the user.
I have the alterRoute set.
namespace Drupal\mymodule\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Listens to the dynamic route events.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
// Change access for path '/user/%/myprofile'.
if ($route = $collection->get('profile.user_page.single')) {
$route->setRequirement('_custom_access', 'Drupal\mymodule\Access\ProfileAccessCheck::access');
}
}
}
I've created the services in the mymodule.services.yml file.
services:
mymodule.route_subscriber:
class: Drupal\mymodule\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
mymodule.profile_access_checker:
class: Drupal\mymodule\Access\ProfileAccessCheck
tags:
- { name: access_check, applies_to: _custom_access }
And here is my ProfileAccessCheck.php
namespace Drupal\mymodule\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Drupal\user\UserInterface;
/**
* Checks whether the profile type allows multiple profiles per user.
*/
class ProfileAccessCheck implements AccessInterface {
/**
* Checks access for the single/multiple pages.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The currently logged in account.
* @param \Drupal\user\UserInterface $user
* The user account.
*/
public function access(AccountInterface $account, $user) {
$user_access = $user->access('view', $account, TRUE);
if (!$user_access->isAllowed()) {
// The account does not have access to the user's canonical page
// ("/user/{user}"), don't allow access to any sub-pages either.
return AccessResult::allowed();
}
if(!empty($account->field_pro_profile->getValue()) && $account->field_pro_profile->getValue() == 'Disable') {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
}
I have a couple of issues. First is, I'm getting this error:
Error: Call to a member function access() on string in Drupal\mymodule\Access\ProfileAccessCheck->access() (line 26 of modules/custom/mymodule/src/Access/ProfileAccessCheck.php).
If I remove that access $user->access
line then I get this error:
Notice: Undefined property: Drupal\Core\Session\AccountProxy::$field_pro_profile in Drupal\mymodule\Access\ProfileAccessCheck->access() (line 26 of modules/custom/mymodule/src/Access/ProfileAccessCheck.php).
I'm also getting this error on some other pages like the module enable/disable page /admin/modules
:
RuntimeException: Callable "Drupal\mymodule\Access\ProfileAccessCheck::access" requires a value for the "$user" argument. in Drupal\Component\Utility\ArgumentsResolver->handleUnresolvedArgument() (line 142 of core/lib/Drupal/Component/Utility/ArgumentsResolver.php).
Why can't I access the user object, what am I missing? Also, it seems to be overriding the access from the profile module. What is the correct way to make sure I call the original module access function too? Because it does not return tabs if I do AccessResult::neutral(); it hides all tabs that match user/%/%