it-swarm-eu.dev

Máte příklad zpětného volání hook_menu ()?

Stáhl jsem projekt příklady , ale v modulu menu_example všechny access callback jsou nastaveny na true .. těžko pochopit, jak to funguje.

V mém příkladu by měl být můj záznam viditelný na uzlech, ale pouze pro role, které mají oprávnění upravovat své vlastní uzly.

Nemohu najít příklad trochu podrobnější o zpětném volání přístupu.

Má někdo nějaký?

17
Strae

Úpravy: Zmeškal jsem část o oprávnění „Upravit vlastní uzel“, protože pak musíte nejen zkontrolovat oprávnění, ale také, zda tento uzel patří aktuálnímu uživateli. Níže jsem aktualizoval svůj příklad, ale výše uvedené vysvětlení nechávám tak, jak to bylo.

Je vaše položka nabídky pod uzlem/uzlem (např. Uzel/1234/něco)? Potom pravděpodobně ani nepotřebujete zpětné volání s vlastním přístupem.

Pokud definujete cestu nabídky jako v následujícím příkladu, zavolá zpětné volání přístupu (a tedy zpětné volání stránky), pokud si prohlížíte platný uzel.

'node/%node/something'

To znamená, že pro výše uvedený příklad bude volat node_load (1234) a bude pokračovat, pouze pokud bude vrácen platný objekt uzlu. Vaše oprávnění můžete definovat pomocí přístupových argumentů jako obvykle.

To znamená, že psaní zpětného volání přístupu je opravdu jednoduché. Je to jen funkce, která obdrží všechny argumenty, které jste definovali v přístupových argumentech. Například výchozí zpětné volání přístupu je ser_access () a když definujete vaše přístupové argumenty jako 'access arguments' => array('a permission string'), povede to k následujícímu volání: user_access('a permission string').

Pokud máte více argumentů, budou předány jako druhý, třetí a podobně jako argument vaší funkci. Pro přístup k aktuálně aktivnímu uzlu můžete použít menu_get_object () .

Takže byste mohli napsat své zpětné zpětné volání, jako je toto, ale znovu, možná ani nebudete muset vytvořit.

function yourmodule_access_check() {
  global $user;
  $node = menu_get_object();

  return $node && $node->uid == $user->uid && user_access('edit own ' . $node->type . ' content');
}

Místo pevného kódování řetězce oprávnění byste jej mohli předat jako argument funkci nebo cokoli, co chcete dělat.

11
Berdir

Drupal je sám příkladem toho, jak napsat kód.

Nejjednodušším příkladem je agregator_menu () , který obsahuje následující kód.

  $items['admin/config/services/aggregator'] = array(
    'title' => 'Feed aggregator', 
    'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.", 
    'page callback' => 'aggregator_admin_overview', 
    'access arguments' => array('administer news feeds'), 
    'weight' => 10, 
    'file' => 'aggregator.admin.inc',
  );
  $items['admin/config/services/aggregator/add/feed'] = array(
    'title' => 'Add feed', 
    'page callback' => 'drupal_get_form', 
    'page arguments' => array('aggregator_form_feed'), 
    'access arguments' => array('administer news feeds'), 
    'type' => MENU_LOCAL_ACTION, 
    'file' => 'aggregator.admin.inc',
  );

V tomto případě je výchozí zpětné volání přístupu ( ser_access () ) a přístupové argumenty jsou pole obsahující řetězec pro oprávnění. Kód nemůže zkontrolovat více než oprávnění; Pokud jsou oprávnění ke kontrole dvě nebo pokud podmínky kontroly nejsou pouze oprávnění, mělo by být zpětné volání přístupu jiné, včetně vlastního.

node_menu () definuje některá menu, která používají zpětné volání přístupu odlišné od výchozího. Funkce obsahuje následující kód.

  foreach (node_type_get_types() as $type) {
    $type_url_str = str_replace('_', '-', $type->type);
    $items['node/add/' . $type_url_str] = array(
      'title' => $type->name, 
      'title callback' => 'check_plain', 
      'page callback' => 'node_add', 
      'page arguments' => array($type->type), 
      'access callback' => 'node_access', 
      'access arguments' => array('create', $type->type), 
      'description' => $type->description, 
      'file' => 'node.pages.inc',
    );
  }

Funkce, která je definována jako zpětné volání přístupu ( node_access () ), je následující:

function node_access($op, $node, $account = NULL) {
  $rights = &drupal_static(__FUNCTION__, array());

  if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) {
    // If there was no node to check against, or the $op was not one of the
    // supported ones, we return access denied.
    return FALSE;
  }
  // If no user object is supplied, the access check is for the current user.
  if (empty($account)) {
    $account = $GLOBALS['user'];
  }

  // $node may be either an object or a node type. Since node types cannot be
  // an integer, use either nid or type as the static cache id.

  $cid = is_object($node) ? $node->nid : $node;

  // If we've already checked access for this node, user and op, return from
  // cache.
  if (isset($rights[$account->uid][$cid][$op])) {
    return $rights[$account->uid][$cid][$op];
  }

  if (user_access('bypass node access', $account)) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }
  if (!user_access('access content', $account)) {
    $rights[$account->uid][$cid][$op] = FALSE;
    return FALSE;
  }

  // We grant access to the node if both of the following conditions are met:
  // - No modules say to deny access.
  // - At least one module says to grant access.
  // If no module specified either allow or deny, we fall back to the
  // node_access table.
  $access = module_invoke_all('node_access', $node, $op, $account);
  if (in_array(NODE_ACCESS_DENY, $access, TRUE)) {
    $rights[$account->uid][$cid][$op] = FALSE;
    return FALSE;
  }
  elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }

  // Check if authors can view their own unpublished nodes.
  if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) {
    $rights[$account->uid][$cid][$op] = TRUE;
    return TRUE;
  }

  // If the module did not override the access rights, use those set in the
  // node_access table.
  if ($op != 'create' && $node->nid) {
    if (module_implements('node_grants')) {
      $query = db_select('node_access');
      $query->addExpression('1');
      $query->condition('grant_' . $op, 1, '>=');
      $nids = db_or()->condition('nid', $node->nid);
      if ($node->status) {
        $nids->condition('nid', 0);
      }
      $query->condition($nids);
      $query->range(0, 1);

      $grants = db_or();
      foreach (node_access_grants($op, $account) as $realm => $gids) {
        foreach ($gids as $gid) {
          $grants->condition(db_and()
            ->condition('gid', $gid)
            ->condition('realm', $realm)
          );
        }
      }
      if (count($grants) > 0) {
        $query->condition($grants);
      }
      $result =  (bool) $query
        ->execute()
        ->fetchField();
      $rights[$account->uid][$cid][$op] = $result;
      return $result;
    }
    elseif (is_object($node) && $op == 'view' && $node->status) {
      // If no modules implement hook_node_grants(), the default behavior is to
      // allow all users to view published nodes, so reflect that here.
      $rights[$account->uid][$cid][$op] = TRUE;
      return TRUE;
    }
  }

  return FALSE;
}

Všimněte si tří bodů:

  • Argumenty deklarované s „argumenty přístupu“ budou předány funkci ve stejném pořadí; funkce používá třetí parametr, protože se nepoužívá pouze pro zpětné volání.
  • Funkce vrací TRUE, pokud má uživatel přístup k nabídce, a FALSE, pokud uživatel nemá přístup k nabídce.
  • Zpětné volání přístupu lze také použít, když by se mělo menu zobrazit pouze za určitých okolností.
19
kiamlaluno