Answers:
只需通过Drupal或从外部进行SQL查询,就可以在Drupal中做很多事情。通常,您永远都不想采用这种方法。在某些情况下,它可以正常工作,但是在大多数情况下,没有理由这样做。
Drupal具有丰富的API,Drupal 6、7和8确实如此,因为它们一直是Drupal的关键功能。在您的concreate示例中,您可以使用taxonomy_term_load
并taxonomy_term_save
促进术语的更新。这样,您可以编辑任何数据部分,包括vid
。仅仅因为您使用API来做,被禁止的事情不会自动起作用,但是事情进展的机会得到了极大的提高。
在此具体示例中,API不会执行任何必需的操作。它在该术语上设置了一些内部数据,并通过调用钩子字母模块知道已更新。
您应该注意,如果要更改的术语是层次结构的一部分,则事情可能会中断。如果不允许该字段引用新词汇表中的术语,则对于引用该术语的节点来说,事情也可能会中断。
数据迁移是防弹解决方案,除非您拥有庞大的数据集,否则可以轻松开发和执行它。这个想法是创建一个新术语并迁移您想要迁移的内容,然后删除旧术语。作为更新挂钩,示例代码如下所示:
/**
* Put in modules .install file, replace xxxx with 7000 or higher
*/
function MODULE_NAME_update_XXXX(&$sandbox) {
$term = taxonomy_term_load(CONSTANT_WITH_TID);
$new_term = clone $term;
unset($new_term->tid);
unset($new_term->tid);
$new_term->vid = CONSTANT_WITH_VID;
taxonomy_term_save($term);
// Find all nodes we want to update and update them.
// If there is a lot of nodes, can use $sandbox to make this a batch job.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
$result = $query->execute();
foreach (node_load_multiple(array_keys($result['node'])) as $node) {
$node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
node_save($node);
}
// Migration all done - delete the old term.
taxonomy_term_delete($term->tid);
}
请注意,以上代码是纯示例代码,由衷地编写。可能存在语法错误或其他错误,并且会做出很多假设。这仅是为了说明一个想法,并表明迁移可能并不重要。
这是不可取的使用Drupal工作时做数据库的直接变化。但是,是的,如果我们知道所有它可以影响并相应地做必要的修改,它是确定做数据库中直接修改。因为在这种情况下,这不可能通过UI进行。注意:如果您有与Term相关联的节点,则也必须手动处理它。
查看此链接,该链接说明了我们如何在Drupal 7中更改术语词汇表:使用数据库在Drupal 7中更改分类术语的词汇表。
我不建议您以在问题中描述的方式更改该术语。相反,我将使用一种替代方法来实现类似的结果(按指定的顺序),下面将对此进行详细说明。
创建一个新的分类术语字段,以便“从现在开始”任何将来的节点更新(或正在创建的新节点)都将使用该新字段。我假设这些术语用于节点(如果您将其用于某些其他实体类型,例如用户等),则相同的方法也可以用于那些实体。
使用“ 规则”模块创建如下规则:
before saving content
。entity has field
,其中field =旧字段。entity has field
,其中field =新字段)。set Drupal message
,其中包含一些说明,必须将旧字段清空,而新字段应包含适当的值。显然,如果必须手动完成一次,则步骤1中的方法将花费“一些”时间,每次需要1个节点。但是,使用Views(构建要更新的类似节点的列表)和VBO(大规模更新此类列表),您可能(应该!)可以大大加快此过程。
特别是如果您要使用“规则”为此类VBO视图创建自定义批量操作,请参见“ 如何使用规则为VBO视图创建自定义批量操作? ”中的解释。这是一个规则组件的原型,它应有助于实现这种自定义批量操作(以“规则导出”格式):
{ "rules_replace_a_term_field_by_another_term_field" : {
"LABEL" : "Replace a term field by another term field",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
"IF" : [
{ "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
{ "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
{ "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
],
"DO" : [
{ "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
{ "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
]
}
}
一些更多细节来解释上述原型:
这些是规则条件:
field_sample_tags
。field_demo_tags
。field_demo_tags
对应于我们要替换的术语(在此示例中,该术语具有id = 1
)。请注意,如果不满足此条件,则不会执行任何规则操作。这些是规则操作:
field_sample_tags
等于带有术语id = 31
的术语(这是新创建的词汇表中与要替换的词汇表中的术语匹配的术语)。Term updated in node with id = 72
,而是72
更新节点的节点ID。如果需要,请调整以上原型中字段名称的机器名称以及使用的术语ID。然后将其导入您自己的站点(使用Rules UI),并使用导入的Rules Component右侧的“ execute”链接进行质量检查(并在切换到“直接输入后输入一些节点ID进行测试”模式”以能够指定节点ID)。如果在测试过程中没有收到这样的Term updated in node ...
消息,那一定是因为您选择的节点未使用规则条件中指定的术语值。
在完成对第2步中的“规则”组件的质量检查测试之后,创建要处理的节点的VBO视图,在其中,您可以参考上面的“规则”原型(或为满足您的需要而对其进行的变形)。
使用这种方法,您可以最大程度地降低引入数据不一致的风险(与直接更新数据库相比),并且只需零个自定义代码(您只能使用Views UI和Rules UI)。
我知道您是通过编程方式说出来的,但是如果您想使用模块,可以使用Taxonomy Manager
该模块提供了用于管理分类法的强大接口。词汇将显示在动态树视图中,在其中可以扩展父项以列出其嵌套的子项,也可以将其折叠。
分类管理器具有以下操作和关键功能:
- 动态树视图
- 批量删除
- 大量增加新术语
- 在术语合并中移动术语(使用7.x中的“术语合并”模块)
- 上下箭头可快速改变重量(并节省AJAX)
- AJAX支持的术语编辑表单
- 简单的搜索界面
- CSV导出条款
- i18n支持多语言词汇(按语言术语)
- Double Tree界面,用于在层次结构中移动术语,添加新的翻译并在不同词汇之间切换术语