欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Flag 3.x API (PHP) 有大用 有大大用

内容:

首先也是最重要的

Flag 提供了一些 API 功能。在某些时候,我们转而使用面向对象编程 (OOP)。有些函数没有等效的方法(还没有?)。

要使用标志,您首先需要掌握“标志处理程序”:

$flag = flag_get_flag('bookmarks');

flag_get_flag() 的参数是标志的机器名。如果不存在这样的标志,将返回 NULL。

发现一条内容是否被标记

使用 is_flagged() 方法来确定一个项目是否被标记。

这在“node.tpl.php”中非常有用,当您想要以不同于非标记节点的方式设置标记节点的主题时。

例子:

<?php
$flag = flag_get_flag('bookmarks');

if ($flag && $flag->is_flagged($node->nid)) {
  print "This node is bookmarked!";
}


$flag = flag_get_flag('idiots');

if ($flag && $flag->is_flagged($node->uid)) {
  print "The author of this node isn't very smart!";
}


$flag = flag_get_flag('idols');

// Note the optional second parameter to is_flagged(), which allows
// us to ask if an item is flagged on behalf of a certain user. If this
// parameter isn't provided, the check is made against the current user.
//
// If the flag is "global", this second parameter is ignored.
//
if ($flag && $flag->is_flagged($node->nid, $GLOBALS['user']->uid)) {
  print "This author venerates you!";
}

// flag::is_flagged() uses a caching mechanism so it's efficient.
?>

为此,您使用 flag_create_link()。请参阅单独的页面,在页面上放置标志链接

获取项目被标记的次数

无论何时标记或取消标记项目,都会更新计数器字段。要读取此计数器,请使用 get_count() 方法:

<?php
$flag = flag_get_flag('votes');

if ($flag) {
  print "The number of people who voted for this proposal:";
  print $flag->get_count($node->nid);
}
?>

另一种方法是使用令牌。该模块为每个标志提供了一个计数令牌,例如,您可以在电子邮件中以及在每个接受令牌的地方使用它:

<?php
Hello, [node-author].
Your post has been bookmarked [flag-bookmarks-count] times.
?>

获取用户标记的项目数

另一种方法 get_user_count() 用于计算用户已标记的项目。此方法比 get_count() 效率低,因为发出了 SQL COUNT 查询。

$flag = flag_get_flag('votes');

// We assume an $account variable exists in this template.

if ($flag) {
  print format_plural($flag->get_user_count($account->uid),
    'This user has participated in 1 voting.',
    'This user has participated in @count votings.');
}

非 OO 替代方案是:

$flag = flag_get_flag('votes');
if ($flag) {
  flag_get_user_flag_counts($flag, $user);
}

标记或取消标记项目

您使用 $flag->flag() 方法来标记或取消标记项目。例子:

<?php
$flag = flag_get_flag('bookmarks');

if ($flag) {
  // Flag node #456:
  $flag->flag('flag', 456); 

  // Unflag node #456:
  $flag->flag('unflag', 456); 
}
?>

此方法的签名是:(Doxygen$this->flag()

<?php
function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL)
?>

它的完整且最新的文档位于Doxygen中。但是,简而言之:$action是您要执行的操作;“标志”或“取消标志”。$content_id是项目的标识符。$account是您要代表其执行操作的用户(此参数仅在使用非全局标志时才有意义)。请注意,这是用户对象,而不是 uid。

当将节点标记/取消标记为非特权用户时,此方法的最后一个参数很重要,例如在 hook_cron() 或 devel-generate 实现中,服务器以匿名方式运行并且权限检查将在没有 $skip_permission_check = TRUE 的情况下静默失败.

如果发生错误(例如,用户无权使用此标志;标志不适用于项目等),此方法返回 FALSE。请注意,标记已标记的项目并不是错误(在这种情况下,该方法将不执行任何操作,但不会返回 FALSE)。

响应标记

任何模块都可以通过实现 hook_flag_flag() 对被标记的一段内容作出反应,并通过实现 hook_flag_unflag() 对从一段内容中删除一个标志作出反应。

mymodule_flag_flag($flag, $content_id, $account, $flagging) {
  // Do something in response to the flagging.
}

mymodule_flag_unflag($flag, $content_id, $account, $flagging) {
  // Do something in response to the unflagging.
}

flag 模块实际上在 flag.module 中的 flag_flag_flag() 函数中实现了自己的钩子。您可以在创建自己的版本时将其用作参考。

在数据库中创建标志

要在数据库中创建节点标志,请从 flag_flag 类创建一个标志,修改默认值,然后使用 $flag->save() 方法保存。请注意,您还可以创建

  $flag = flag_flag::factory_by_entity_type('node');

  // Absolutely required, will break your site if not added properties.
  $flag->name = 'my_flag_name';
  $flag->title = 'My Title';

  $flag->types = array('story', 'page'); // An array of node types.
  $flag->flag_short = 'Flag this';
  $flag->unflag_short = 'Unflag this';

  // Optional properties, defaults are defined for these (and more).
  // Use a print_r() or dsm() to see all the available flag properties.
  $flag->global = TRUE;
  $flag->flag_long = '';
  $flag->flag_message = '';
  $flag->show_on_form = TRUE;
  $flag->show_on_node = TRUE;
  $flag->show_on_teaser = TRUE;
  $flag->link_type = 'toggle'; // For JS link. Other options: 'normal' and 'confirm'.

  // Save the flag.
  $flag->save(); 

可以为用户标志做类似的事情(这里是更新函数中的一个例子) - 也可以使用值数组而不是设置属性:

function mymodule_update_6100() {
  $ret = array();
  $flag = flag_flag::factory_by_entity_type('user');
  // Unique, machine-readable name.
  $flag->name = 'unverified_user';
  $values = array(
    'flag_short' => 'mark as unverified',
    'flag_long' => '',
    'flag_message' => '',
    'flag_confirmation' => '',
    'unflag_short' => 'mark as verified',
    'unflag_long' => '',
    'unflag_message' => '',
    'unflag_confirmation' => '',
    'link_type' => 'normal',
    'show_on_profile' => 1,
    'global' => 1,
    // A user flag doesn't support node types.
    'types' => array(),
    'title' => 'Unverified user',
  );
  $flag->form_input($values);
  $flag->save();
  $flag->enable();
  $ret[] = array('success' => !empty($flag->fid), 'query' => 'Created user flag ' . $flag->name);
  return $ret;
}

注意:如果您在更新挂钩或 hook_install() 中创建标志并想立即使用它,您必须首先调用 flag_get_flags() 重新加载标志的静态标志缓存,否则 flag_get_flag() 将找不到您的新标志。例如:

...
$flag->save();
flag_get_flags(NULL, NULL, NULL, TRUE);  // Force the new flag to be loaded
...

创建基于模块的默认标志

通过实现 hook_flag_default_flags(),可以将标志包含在模块中。通过在代码中定义一个标志,开发人员可以“锁定”一个标志的某些属性,并确保一个标志可供模块使用。任何“锁定”属性都不会显示在标志配置表单上。

为避免与可能提供同名标志的其他模块发生冲突,开发人员应在默认标志的名称前加上其模块名称。

function mymodule_flag_default_flags() {
  $flags = array();
  $flags[] = array(
    'content_type' => 'node',
    'name' => 'mymodule_starred',
    'title' => 'Starred',
    'global' => FALSE,
    'types' => array('story', 'blog'),
    'flag_short' => 'Star',
    'flag_long' => 'Add this your starred list',
    'flag_message' => 'Added to your starred list.',
    'unflag_short' => 'Unstar',
    'unflag_long' => 'Remove this issue from your starred list',
    'unflag_message' => 'Removed from your starred list.',
    'show_on_page' => TRUE,
    'show_on_teaser' => TRUE,
    'show_on_form' => FALSE,
    'status' => FALSE,
    'locked' => array('show_on_teaser', 'name', 'types', 'global'),
  );
  return $flags;
}

写入标记字段值

3.X 版本引入了将字段附加到标记实体的能力,就像任何实体一样(参见http://drupal.org/node/917576)。这些标记字段值可以直接设置(使用 stdClass)或使用实体 API(使用 entity_create() 和 entity_metadata_wrapper())。设置标记字段值后,通过使用 $flag->flag(),通过 Flag API 保存标记实体:

直接设置/保存标记字段值

$flag_name = 'my_flag';
$nid = 138;
$field_name = 'my_field';

// Create an array containing the flagging entity values.
$values = array(
  'flag_name' => $flag_name,
);
// Cast the array as a stdClass object.
$flagging = (object) $values;
// Set field values directly:
$flagging->{$field_name}['und'][0]['value'] = 'foo';

// Invoke the Flag API to set the flagging. This also saves the flagging entity.
$flag = flag_get_flag($flag_name);
$flag->flag('flag', $nid, NULL, FALSE, $flagging);

使用实体 API 设置/保存标记字段值

global $user;
$flag = flag_get_flag('my_flag');
$nid = 138;
$field_name = 'my_field';

// Create an array containing the flagging entity values.
$values = array(
  'fid' => $flag->fid,
  'entity_type' => $flag->entity_type,
  'entity_id' => $nid,
);
// Create the flagging using Entity API.
$flagging = entity_create('flagging', $values);

// Set field values using the Entity API.
$flagging_wrapper = entity_metadata_wrapper('flagging', $flagging);
$flagging_wrapper->{$field_name}->set('some text!');

// Invoke the Flag API to set the flagging. This also saves the flagging entity.
$flag->flag('flag', $nid, $user, FALSE, $flagging);

笔记:

  • 不要使用 entity_save() 来保存标记实体,因为这将绕过 Flag API

  • 使用 entity_create() 创建标记实体时,$values 数组必须至少包含“fid”、“entity_type”和“entity_id”。

注释

爬行动物的图片

请注意文档说明添加行时将设置角色:

$flag->roles = array(2);

不是真的,您必须设置自己的角色。

在这里提出了一个问题,并被告知不再使用它,所以你必须自己做:

$permissions = array(
        "flag $flag->name" =>1,
        "unflag $flag->name" => 1,
    );
    user_role_change_permissions($role_id, $permissions);

我觉得它非常反直觉和麻烦,但它必须有一个很好的理由!?!

艾琳·约尔丹诺夫的照片

我不知道如何检查是否以编程方式标记了标记。

例如,我有一个标记“订阅”来标记一个术语,另一个标记“批准订阅”来标记标记。

我已将以下代码片段放入我的自定义模块中,但我不知道如何使用 is_flagged 方法检查 $flag_sub 是否被 $flag_ok 标记。

  $flag_sub = flag_get_flag('subscribe');
  $flag_ok = flag_get_flag('approve_subscription');

旧用户名:pc-wurm、Елин Й。

约阿希姆的照片

请提交支持请求,而不是在此处发表评论。

noahott 的图片

以编程方式标记节点时如何指定附加字段的值。例如,在自定义模块中,如果我运行,

      $flag = flag_get_flag('question_viewed');
      $flag->flag('flag', $node->nid, $user_obj);

没有保存任何附加字段,也没有分配它们的默认值。这些附加字段在数据库中甚至不会出现空白。我为字段设置的默认值看起来很好,并且在通过确认表单链接标记链接时正确保存。

谢谢你的帮助,

约阿希姆的照片

请提交支持请求,而不是在此处发表评论。

普莱斯的图片

有没有办法获取某个标志机器名称的标志节点(nid)列表?
我看到您可以获取用户,但您似乎无法从函数调用中获取 nid。

Strutsagget的图片

你好

如何获取标记节点的用户列表。

如果我有一个标志 has_read 然后我想列出所有标记 has_read 的用户。

//PiJa Media & Management AB din apputvecklare

atari82 的图片

我如何为每个标记的 field_collection 项目打印 $flag->get_count() ?

例如在 field-field-collection.tpl.php 中的 field-collection-item.tpl.php。
field-field-collection.tpl.php 可能在 $item 中提供了正确的 item_id 但我不知道如何在 $item 中访问它:-/

谢谢 :-)

科迪亚克的照片

实体类型的键是“entity_type”,而不是本页所写的“content_type”。

瓦卡里特的图片

“获取项目被标记的次数”非常有效。

萨加尔·拉姆加德的照片

$flag_service = \Drupal::service('flag');
$flag = $flag_service->getFlagById('flag_machine_name');
// $entity can be $node or user, $account is the acting user.
$flag_service->flag($flag, $entity, $account);

Acquia 认证开发人员、后端和前端专家
需要帮助吗?请使用我的联系表格


来自  https://www.drupal.org/node/1748148



普通分类: