<?php
-namespace Drupal\permissions_by_term;
+namespace Drupal\permissions_by_term\Service;
-use Drupal\Core\Database\Driver\mysql\Connection;
+use Drupal\Core\Database\Connection;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Form\FormState;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\Entity\User;
/**
* Class AccessStorage.
*
- * Defines an API to the database in the term access context.
- *
- * The "protected" class methods are meant for protection regarding Drupal's
- * forms and presentation layer.
- *
- * The "public" class methods can be used for extensions.
- *
* @package Drupal\permissions_by_term
*/
-class AccessStorage implements AccessStorageInterface {
+class AccessStorage {
/**
- * Drupal\Core\Database\Driver\mysql\Connection definition.
+ * The database connection.
*
- * @var Drupal\Core\Database\Driver\mysql\Connection
+ * @var Connection
*/
- protected $oDatabase;
+ protected $database;
/**
* The term name for which the access is set.
*/
protected $aSubmittedRolesGrantedAccess;
+ /**
+ * @var Term
+ */
+ protected $term;
+
+ /**
+ * @var string
+ */
+ const NODE_ACCESS_REALM = 'permissions_by_term';
+
+ /**
+ * @var AccessCheck
+ */
+ protected $accessCheck;
+
/**
* AccessStorageService constructor.
*
- * @param \Drupal\Core\Database\Driver\mysql\Connection $database
- * The connection to the database.
+ * @param Connection $database
+ * @param Term $term
+ * @param AccessCheck $accessCheck
*/
- public function __construct(Connection $database) {
- $this->oDatabase = $database;
+ public function __construct(Connection $database, Term $term, AccessCheck $accessCheck) {
+ $this->database = $database;
+ $this->term = $term;
+ $this->accessCheck = $accessCheck;
}
/**
}
/**
- * {@inheritdoc}
+ * @param FormState $form_state
*/
public function checkIfUsersExists(FormState $form_state) {
$sAllowedUsers = $form_state->getValue('access')['user'];
}
/**
- * {@inheritdoc}
+ * @param int $term_id
+ *
+ * @return array
*/
- public function getExistingUserTermPermissionsByTid($term_id) {
- return $this->oDatabase->select('permissions_by_term_user', 'pu')
+ public function getUserTermPermissionsByTid($term_id) {
+ return $this->database->select('permissions_by_term_user', 'pu')
->condition('tid', $term_id)
->fields('pu', ['uid'])
->execute()
}
/**
- * {@inheritdoc}
+ * @param int $uid
+ * @param array $rids
+ *
+ * @return array
+ */
+ public function getPermittedTids($uid, $rids) {
+ $permittedTids = $this->database->select('permissions_by_term_user', 'pu')
+ ->condition('uid', $uid)
+ ->fields('pu', ['tid'])
+ ->execute()
+ ->fetchCol();
+
+ foreach ($rids as $rid) {
+ $permittedTidsByRid = $this->database->select('permissions_by_term_role', 'pr')
+ ->condition('rid', $rid)
+ ->fields('pr', ['tid'])
+ ->execute()
+ ->fetchCol();
+
+ $permittedTids = array_merge($permittedTidsByRid, $permittedTids);
+ }
+
+ return array_unique($permittedTids);
+ }
+
+ /**
+ * @param array $tids
+ *
+ * @return array
+ */
+ public function getUserTermPermissionsByTids($tids) {
+ $uids = [];
+
+ foreach ($tids as $tid) {
+ if (!empty($tmpUids = $this->getUserTermPermissionsByTid($tid))) {
+ foreach ($tmpUids as $tmpUid) {
+ $uids[] = $tmpUid;
+ }
+ }
+ }
+
+ return $uids;
+ }
+
+ /**
+ * @param int $term_id
+ *
+ * @return array
*/
- public function getExistingRoleTermPermissionsByTid($term_id) {
- return $this->oDatabase->select('permissions_by_term_role', 'pr')
+ public function getRoleTermPermissionsByTid($term_id) {
+ return $this->database->select('permissions_by_term_role', 'pr')
->condition('tid', $term_id)
->fields('pr', ['rid'])
->execute()
}
/**
- * {@inheritdoc}
+ * @param array $tids
+ *
+ * @return array
+ */
+ public function getRoleTermPermissionsByTids($tids) {
+ $rids = [];
+
+ foreach ($tids as $tid) {
+ $tmpRids = $this->getRoleTermPermissionsByTid($tid);
+ if (!empty($tmpRids)) {
+ foreach ($tmpRids as $tmpRid) {
+ $rids[] = $tmpRid;
+ }
+ }
+ }
+
+ return $rids;
+ }
+
+ /**
+ * @param string $sUsername
+ *
+ * @return int
*/
public function getUserIdByName($sUsername) {
- return $this->oDatabase->select('users_field_data', 'ufd')
+ return $this->database->select('users_field_data', 'ufd')
->condition('name', $sUsername)
->fields('ufd', ['uid'])
->execute()
}
/**
- * {@inheritdoc}
+ * @param array $aUserNames
+ *
+ * @return array
*/
public function getUserIdsByNames($aUserNames) {
$aUserIds = [];
}
/**
- * {@inheritdoc}
+ * @param int $term_id
+ *
+ * @return array
*/
public function getAllowedUserIds($term_id) {
- $query = $this->oDatabase->select('permissions_by_term_user', 'p')
+ $query = $this->database->select('permissions_by_term_user', 'p')
->fields('p', ['uid'])
->condition('p.tid', $term_id);
}
/**
- * {@inheritdoc}
+ * @param array $aUserIdsAccessRemove
+ * @param int $term_id
*/
public function deleteTermPermissionsByUserIds($aUserIdsAccessRemove, $term_id) {
foreach ($aUserIdsAccessRemove as $iUserId) {
- $this->oDatabase->delete('permissions_by_term_user')
+ $this->database->delete('permissions_by_term_user')
->condition('uid', $iUserId, '=')
->condition('tid', $term_id, '=')
->execute();
}
/**
- * {@inheritdoc}
+ * @param array $aRoleIdsAccessRemove
+ * @param int $term_id
*/
public function deleteTermPermissionsByRoleIds($aRoleIdsAccessRemove, $term_id) {
foreach ($aRoleIdsAccessRemove as $sRoleId) {
- $this->oDatabase->delete('permissions_by_term_role')
+ $this->database->delete('permissions_by_term_role')
->condition('rid', $sRoleId, '=')
->condition('tid', $term_id, '=')
->execute();
}
/**
- * {@inheritdoc}
+ * @param int $userId
+ */
+ public function deleteAllTermPermissionsByUserId($userId) {
+ $this->database->delete('permissions_by_term_user')
+ ->condition('uid', $userId, '=')
+ ->execute();
+ }
+
+ /**
+ * @param array $aUserIdsGrantedAccess
+ * @param int $term_id
+ *
+ * @throws \Exception
*/
public function addTermPermissionsByUserIds($aUserIdsGrantedAccess, $term_id) {
foreach ($aUserIdsGrantedAccess as $iUserIdGrantedAccess) {
- $this->oDatabase->insert('permissions_by_term_user')
+ $this->database->insert('permissions_by_term_user')
->fields(['tid', 'uid'], [$term_id, $iUserIdGrantedAccess])
->execute();
}
}
/**
- * {@inheritdoc}
+ * @param array $aRoleIdsGrantedAccess
+ * @param int $term_id
+ *
+ * @throws \Exception
*/
public function addTermPermissionsByRoleIds($aRoleIdsGrantedAccess, $term_id) {
foreach ($aRoleIdsGrantedAccess as $sRoleIdGrantedAccess) {
- $this->oDatabase->insert('permissions_by_term_role')
+ $this->database->insert('permissions_by_term_role')
->fields(['tid', 'rid'], [$term_id, $sRoleIdGrantedAccess])
->execute();
}
}
- /**
- * {@inheritdoc}
- */
- public function getTermIdByName($sTermName) {
- $aTermId = \Drupal::entityQuery('taxonomy_term')
- ->condition('name', $sTermName)
- ->execute();
- return key($aTermId);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getTermNameById($term_id) {
- $term_name = \Drupal::entityQuery('taxonomy_term')
- ->condition('id', $term_id)
- ->execute();
- return key($term_name);
- }
-
/**
* Gets the user ids which have been submitted by form.
*
}
/**
- * {@inheritdoc}
+ * Saves term permissions by users.
+ *
+ * Opposite to save term permission by roles.
+ *
+ * @param FormState $form_state
+ * @param int $term_id
+ *
+ * @return array
+ * Data for database queries.
*/
public function saveTermPermissions(FormState $form_state, $term_id) {
- $aExistingUserPermissions = $this->getExistingUserTermPermissionsByTid($term_id);
+ $aExistingUserPermissions = $this->getUserTermPermissionsByTid($term_id);
$aSubmittedUserIdsGrantedAccess = $this->getSubmittedUserIds();
- $aExistingRoleIdsGrantedAccess = $this->getExistingRoleTermPermissionsByTid($term_id);
+ $aExistingRoleIdsGrantedAccess = $this->getRoleTermPermissionsByTid($term_id);
$aSubmittedRolesGrantedAccess = $this->getSubmittedRolesGrantedAccess($form_state);
$aRet = $this->getPreparedDataForDatabaseQueries($aExistingUserPermissions,
}
/**
- * {@inheritdoc}
+ * Prepares the data which has to be applied to the database.
+ *
+ * @param array $aExistingUserPermissions
+ * The permissions for existing user.
+ * @param array $aSubmittedUserIdsGrantedAccess
+ * The user ids which get access.
+ * @param array $aExistingRoleIdsGrantedAccess
+ * The existing role ids.
+ * @param array $aSubmittedRolesGrantedAccess
+ * The user roles which get access.
+ *
+ * @return array
+ * User ID and role data.
*/
public function getPreparedDataForDatabaseQueries($aExistingUserPermissions,
$aSubmittedUserIdsGrantedAccess,
}
/**
- * {@inheritdoc}
+ * The form value for allowed users as string to be shown to the user.
+ *
+ * @param User[] $aAllowedUsers
+ * An array with the allowed users.
+ *
+ * @return null|string
+ * Either null or the user name.
*/
public function getUserFormValue($aAllowedUsers) {
foreach ($aAllowedUsers as $oUser) {
$iUid = intval($oUser->id());
if ($iUid !== 0) {
- $sUsername = $oUser->getUsername();
+ $sUsername = $oUser->getDisplayName();
}
else {
$sUsername = t('Anonymous User');
*/
public function getAllNids()
{
- $query = $this->oDatabase->select('node', 'n')
+ $query = $this->database->select('node', 'n')
->fields('n', ['nid']);
return $query->execute()
->fetchCol();
}
+ /**
+ * @param $nid
+ *
+ * @return array
+ */
public function getTidsByNid($nid)
{
- $node = $this->entityManager->getStorage('node')->load($nid);
+ $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
$tids = [];
foreach ($node->getFields() as $field) {
return $tids;
}
+ /**
+ * @return array
+ */
public function getAllUids()
{
$nodes = \Drupal::entityQuery('user')
return array_values($nodes);
}
+ /**
+ * @param $nid
+ *
+ * @return array
+ */
public function getNodeType($nid)
{
- $query = $this->oDatabase->select('node', 'n')
+ $query = $this->database->select('node', 'n')
->fields('n', ['type'])
->condition('n.nid', $nid);
->fetchAssoc()['type'];
}
+ /**
+ * @param $nid
+ *
+ * @return array
+ */
public function getLangCode($nid)
{
- $query = $this->oDatabase->select('node', 'n')
+ $query = $this->database->select('node', 'n')
->fields('n', ['langcode'])
->condition('n.nid', $nid);
->fetchAssoc()['langcode'];
}
- public function getGidsByRealm($realm)
+ /**
+ * @param AccountInterface $user
+ *
+ * @return array
+ */
+ public function getGids(AccountInterface $user)
{
- $query = $this->oDatabase->select('node_access', 'na')
- ->fields('na', ['gid'])
- ->condition('na.realm', $realm);
+ $grants = null;
+
+ if (!empty($permittedNids = $this->computePermittedTids($user))) {
+ $query = $this->database->select('node_access', 'na')
+ ->fields('na', ['gid'])
+ ->condition('na.nid', $permittedNids, 'IN')
+ ->condition('na.realm', self::NODE_ACCESS_REALM);
- $gids = $query->execute()->fetchCol();
+ $gids = $query->execute()->fetchCol();
- foreach ($gids as $gid) {
- $grants[$realm][] = $gid;
+ foreach ($gids as $gid) {
+ $grants[self::NODE_ACCESS_REALM][] = $gid;
+ }
}
return $grants;
}
+ private function computePermittedTids(AccountInterface $user)
+ {
+ $nidsWithNoTidRestriction = $this->getNidsWithNoTidRestriction();
+ $nidsByTids = $this->term->getNidsByTids($this->getPermittedTids($user->id(), $user->getRoles()));
+
+ if (\Drupal::config('permissions_by_term.settings.single_term_restriction')->get('value')) {
+ $permittedNids = [];
+ foreach ($nidsByTids as $nid) {
+ if($this->accessCheck->canUserAccessByNodeId($nid)) {
+ $permittedNids[] = $nid;
+ }
+ }
+ $nidsByTids = $permittedNids;
+ }
+
+ if (!empty($nidsByTids)) {
+ return array_merge(
+ $this->getNidsWithNoTidRestriction(),
+ $nidsByTids
+ );
+ }
+
+ return $nidsWithNoTidRestriction;
+ }
+
+ private function getNidsWithNoTidRestriction() {
+ $queryNidsNoRestriction = $this->database->select('node', 'n')
+ ->fields('n', ['nid']);
+
+ $queryNidsNoRestriction->leftJoin('taxonomy_index', 'ti', 'n.nid = ti.nid');
+ $queryNidsNoRestriction->leftJoin('permissions_by_term_user', 'ptu', 'ptu.tid = ti.tid');
+ $queryNidsNoRestriction->condition('ptu.tid', NULL, 'IS');
+ $queryNidsNoRestriction->leftJoin('permissions_by_term_role', 'ptr', 'ptr.tid = ti.tid');
+ $queryNidsNoRestriction->condition('ptr.tid', NULL, 'IS');
+
+ return $queryNidsNoRestriction
+ ->execute()
+ ->fetchCol();
+ }
+
+
+ /**
+ * @param $uid
+ *
+ * @return array
+ */
public function getAllNidsUserCanAccess($uid)
{
- $query = $this->oDatabase->select('node_access', 'na')
+ $query = $this->database->select('node_access', 'na')
->fields('na', ['nid'])
->condition('na.realm', 'permissions_by_term__uid_' . $uid);
->fetchCol();
}
+ /**
+ * @param $tid
+ *
+ * @return array
+ */
public function getNidsByTid($tid)
{
- $query = $this->oDatabase->select('taxonomy_index', 'ti')
+ $query = $this->database->select('taxonomy_index', 'ti')
->fields('ti', ['nid'])
->condition('ti.tid', $tid);