| 
<?php
 /**
 * Implements hook_shadow_node_edit.
 *
 * @param Environment $env
 *   The current Environment.
 * @param $vars
 *   An array of variables.
 */
 function access_shadow_node_form($env, $vars) {
 /** @var Shadow $shadow */
 $shadow = &$vars['shadow'];
 $shadow->addTab('manage permissions', file_get_contents($env->getModulePath('access') . '/tpl/permissions_form.html'), 5);
 }
 
 /**
 * Implements hook_node_presave().
 *
 * @param Environment $env
 *   The current Environment.
 * @param $vars
 *   An array of variables.
 */
 function access_node_presave($env, $vars) {
 $node_permissions = array(
 'node_add',
 'node_edit',
 'node_delete',
 'node_view',
 );
 /** @var Node $node */
 $node = &$vars['node'];
 // TODO: review this process.
 if (!isset($node->json->permissions)) {
 $node->json->permissions = new StdClass();
 }
 // Set all the node's permissions.
 foreach ($node_permissions as $permission) {
 if (isset($vars['data'][$permission])) {
 $node->json->permissions->{$permission} = $vars['data'][$permission];
 }
 }
 }
 
 /**
 * Implements hook_node_open().
 *
 * @param Environment $env
 *   The Environment.
 * @param $vars
 *   An array of variables.
 */
 function access_node_open($env, $vars) {
 /** @var Node $node */
 $node = &$vars['node'];
 
 // Check if the user can access the node.
 if (!empty($node) && $node->exists) {
 $has_access = NodeAccess::check($env, NODE_ACTION_VIEW, array('node' => $node));
 if (!$has_access) {
 $node = NodeFactory::buildForbiddenNode($env);
 }
 }
 }
 
 /**
 * Check if a qtag is filtered via the filter attribute.
 *
 * TODO: make it open for all node attributes
 *
 * @param Environment $env
 *   The Environment.
 * @param $vars
 *   An array of variables.
 */
 function access_qtag_preload($env, $vars) {
 $node = NodeFactory::current($env);
 $user = UserFactory::current($env);
 
 // The user has selected to show the tag only if a certain criteria is matched.
 if (!empty($vars['attributes']['filter'])) {
 $filter_match = _access_filter($env, $vars['attributes']['filter'], $node, $user);
 // If there is an active tag filter, and it doesn't match, empty the tag.
 if (!$filter_match) {
 $vars['access'] = FALSE;
 }
 }
 }
 
 /**
 * Check access as defined by a qtag filter attribute.
 *
 * @param Environment $env
 *   The Environment.
 * @param string $criteria
 *   The criteria to use for filtering check.
 * @param Node $node
 *   The node to use for filtering check.
 * @param User $user
 *   The user to use for filtering check.
 * @return bool
 *   Returns true if the access check was positive.
 */
 function _access_filter($env, $criteria, $node, $user = NULL) {
 
 
 // Explode the criteria values.
 $filter = explode(',', $criteria);
 
 // Make matching false by default.
 $filter_match = FALSE;
 
 if ($user == NULL) {
 $user = UserFactory::load($env, $node->getName());
 }
 
 // Check all filters.
 foreach ($filter as $filter_item) {
 $exp = explode('@', $filter_item);
 $filter_type = $exp[0];
 if (substr($filter_type, 0, 12) == 'current_user') {
 $filter_type = str_replace('current_user', 'user', $filter_type);
 $user = UserFactory::current($env);
 }
 if (substr($filter_type, 0, 12) == 'node_author') {
 $filter_type = str_replace('node_author', 'user', $filter_type);
 $user = new User($env, $node->getAuthor());
 }
 $filter_values = explode(';', $exp[1]);
 
 $filter_match = FALSE;
 $break = FALSE;
 $one_match = FALSE;
 
 switch ($filter_type) {
 // Filter by HTTP referer.
 case 'referer':
 $explode = explode('/', $_SERVER['HTTP_REFERER']);
 $filter_check = $explode;
 break;
 // Filter by current node path.
 case 'path':
 $filter_check = array($node->getName());
 break;
 // Filter by current node's father node.
 case 'father':
 $filter_check = array($node->getFather()->getName());
 break;
 // Filter by current user's name.
 case 'user_name':
 $filter_check = array($user->getName());
 break;
 // Filter by current user's role.
 case 'user_role':
 $filter_check = $user->getRoles();
 break;
 // Filter by node's lineage (father, grandfather, and all ancestors!).
 case 'lineage':
 $one_match = TRUE;
 $filter_check = array();
 $lineage = $node->getLineage();
 foreach ($lineage as $lineage_node) {
 /** @var Node $lineage_node */
 $filter_check[] = $lineage_node->getName();
 }
 break;
 
 case 'context':
 $filter_check[] = $env->getContext();
 break;
 
 case 'category':
 $filter_check = array();
 $categories = $node->getCategories();
 foreach ($categories as $category_node) {
 /** @var Node $category_node */
 $filter_check[] = $category_node->getName();
 }
 break;
 
 case 'status':
 $filter_check = array($node->getStatus());
 break;
 
 default:
 
 break;
 }
 
 if (!empty($filter_check)) {
 
 // Check if the filtered item corresponds to the user input.
 foreach ($filter_check as $check) {
 
 foreach ($filter_values as $filter_value) {
 
 if (substr($filter_value, 0, 1) == '!') {
 $negate = TRUE;
 $filter_value = str_replace('!', '', $filter_value);
 }
 
 $filter_match = ($check == $filter_value);
 
 if ($filter_match && !isset($negate)) {
 unset($one_match);
 $break = TRUE;
 }
 
 if (isset($negate)) {
 $filter_match = !$filter_match;
 unset($negate);
 
 if (!$filter_match) {
 $break = TRUE;
 }
 }
 
 if ($break) {
 break;
 }
 }
 
 // For multiple fields such as lineage one match is enough to validate.
 if ($break) {
 break;
 }
 }
 
 //TODO: handle invalid / unknown filters.
 //TODO: use hook for custom filters.
 
 if (!$filter_match) {
 break;
 }
 }
 else {
 $filter_match = TRUE;
 }
 
 }
 return $filter_match;
 }
 
 |