- Patch #6847 by Gerhard: replaced vocabulary->nodes by a separate table and tidied up the taxonomy API a bit. This fixes a number of issues.

4.6.x
Dries Buytaert 2005-01-19 16:22:52 +00:00
parent 6adc3dd055
commit 7bdca92aad
6 changed files with 133 additions and 73 deletions

View File

@ -25,6 +25,8 @@ Drupal x.x.x, xxxx-xx-xx
* improved performance of the forum topics block.
* improved performance of the tracker module.
* improved performance of the node pages.
- documentation:
* improved and extended PHPDoc/Doxygen comments.
Drupal 4.5.2, 2005-01-15
------------------------

View File

@ -749,11 +749,20 @@ CREATE TABLE vocabulary (
hierarchy tinyint(3) unsigned NOT NULL default '0',
multiple tinyint(3) unsigned NOT NULL default '0',
required tinyint(3) unsigned NOT NULL default '0',
nodes longtext,
weight tinyint(4) NOT NULL default '0',
PRIMARY KEY (vid)
) TYPE=MyISAM;
--
-- Table structure for table 'vocabulary_node_types'
--
CREATE TABLE vocabulary_node_types (
vid int(10) unsigned NOT NULL DEFAULT '0',
type varchar(16) NOT NULL DEFAULT '',
PRIMARY KEY (vid, type)
) TYPE=MyISAM;
--
-- Table structure for table 'watchdog'
--

View File

@ -736,11 +736,20 @@ CREATE TABLE vocabulary (
hierarchy smallint NOT NULL default '0',
multiple smallint NOT NULL default '0',
required smallint NOT NULL default '0',
nodes text default '',
weight smallint NOT NULL default '0',
PRIMARY KEY (vid)
);
--
-- Table structure for vocabulary_node_types
--
CREATE TABLE vocabulary_node_types (
vid integer NOT NULL default '0',
type varchar(16) NOT NULL default '',
PRIMARY KEY (vid, type)
);
--
-- Table structure for watchdog
--

View File

@ -92,7 +92,9 @@ $sql_updates = array(
"2004-11-28" => "update_113",
"2004-12-05" => "update_114",
"2005-01-07" => "update_115",
"2005-01-14" => "update_116"
"2005-01-14" => "update_116",
"2005-01-18" => "update_117",
"2005-01-19" => "update_118"
);
function update_32() {
@ -2083,6 +2085,38 @@ function update_116() {
return array(update_sql("DELETE FROM {system} WHERE name = 'admin'"));
}
function update_117() {
$ret = array();
if ($GLOBALS['db_type'] == 'mysql') {
$ret[] = update_sql("CREATE TABLE {vocabulary_node_types} (
vid int(10) NOT NULL default '',
type varchar(16) NOT NULL default '',
PRIMARY KEY (vid, type))");
}
else if ($GLOBALS['db_type'] == 'pgsql') {
$ret[] = update_sql("CREATE TABLE {vocabulary_node_types} (
vid integer NOT NULL default '0',
type varchar(16) NOT NULL default '',
PRIMARY KEY (vid, type))");
}
return $ret;
}
function update_118() {
$ret = array();
$result = db_query('SELECT vid, nodes FROM {vocabulary}');
while ($vocabulary = db_fetch_object($result)) {
$node_types[$vocabulary->vid] = explode(',', $vocabulary->nodes);
}
foreach ($node_types as $vid => $type_array) {
foreach ($type_array as $type) {
db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $vid, $type);
}
}
$ret[] = update_sql("ALTER TABLE {vocabulary} DROP nodes");
return $ret;
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);

View File

@ -116,14 +116,15 @@ function taxonomy_block($op = 'list', $delta = 0) {
}
function taxonomy_form_vocabulary($edit = array()) {
foreach (node_list() as $type) {
$nodetypes[$type] = node_invoke($type, 'node_name');
foreach (array_merge(node_list(), $edit['nodes']) as $type) {
$node_type = node_invoke($type, 'node_name');
$nodes[$type] = $node_type ? $node_type : $type;
}
$form .= form_textfield(t('Vocabulary name'), 'name', $edit['name'], 50, 64, t('The name for this vocabulary. Example: "Topic".'), NULL, TRUE);
$form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('Description of the vocabulary; can be used by modules.'));
$form .= form_textfield(t('Help text'), 'help', $edit['help'], 50, 255, t('Instructions to present to the user when choosing a term.'));
$form .= form_checkboxes(t('Types'), 'nodes', explode(',', $edit['nodes']), $nodetypes, t('A list of node types you want to associate with this vocabulary.'), NULL, TRUE);
$form .= form_checkboxes(t('Types'), 'nodes', $edit['nodes'], $nodes, t('A list of node types you want to associate with this vocabulary.'), NULL, TRUE);
$form .= form_checkbox(t('Related terms'), 'relations', 1, $edit['relations'], t('Allows <a href="%help-url">related terms</a> in this vocabulary.', array('%help-url' => url('admin/help/taxonomy', NULL, NULL, 'related-terms'))));
$form .= form_radios(t('Hierarchy'), 'hierarchy', $edit['hierarchy'], array(t('Disabled'), t('Single'), t('Multiple')), t('Allows <a href="%help-url">a tree-like hierarchy</a> between terms of this vocabulary.', array('%help-url' => url('admin/help/taxonomy', NULL, NULL, 'hierarchy'))));
$form .= form_checkbox(t('Multiple select'), 'multiple', 1, $edit['multiple'], t('Allows nodes to have more than one term in this vocabulary.'));
@ -144,9 +145,13 @@ function taxonomy_save_vocabulary($edit) {
$edit['nodes'] = array();
}
$data = array('name' => $edit['name'], 'nodes' => implode(',', $edit['nodes']), 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight']);
$data = array('name' => $edit['name'], 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight']);
if ($edit['vid'] && $edit['name']) {
db_query('UPDATE {vocabulary} SET '. _taxonomy_prepare_update($data) .' WHERE vid = %d', $edit['vid']);
db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d", $edit['vid']);
foreach ($edit['nodes'] as $type) {
db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
}
module_invoke_all('taxonomy', 'update', 'vocabulary', $edit);
$message = t('Updated vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
}
@ -156,6 +161,9 @@ function taxonomy_save_vocabulary($edit) {
else {
$data['vid'] = $edit['vid'] = db_next_id('{vocabulary}_vid');
db_query('INSERT INTO {vocabulary} '. _taxonomy_prepare_insert($data, 1) .' VALUES '. _taxonomy_prepare_insert($data, 2));
foreach ($edit['nodes'] as $type) {
db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
}
module_invoke_all('taxonomy', 'insert', 'vocabulary', $edit);
$message = t('Created new vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
}
@ -171,6 +179,7 @@ function taxonomy_del_vocabulary($vid) {
$vocabulary = taxonomy_get_vocabulary($vid);
db_query('DELETE FROM {vocabulary} WHERE vid = %d', $vid);
db_query('DELETE FROM {vocabulary_node_types} WHERE vid = %d', $vid);
$result = db_query('SELECT tid FROM {term_data} WHERE vid = %d', $vid);
while ($term = db_fetch_object($result)) {
taxonomy_del_term($term->tid);
@ -348,11 +357,12 @@ function taxonomy_overview() {
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $vocabulary) {
$links = array();
$types = array();
foreach(explode(',', $vocabulary->nodes) as $type) {
$types[] = node_invoke($type, 'node_name');
foreach($vocabulary->nodes as $type) {
$node_type = node_invoke($type, 'node_name');
$types[] = $node_type ? $node_type : $type;
}
$rows[] = array($vocabulary->name, array('data' => implode(', ', $types), 'align' => 'center'), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
$tree = taxonomy_get_tree($vocabulary->vid);
@ -394,16 +404,22 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
* @param $type
* If set, return only those vocabularies associated with this node type.
*/
function taxonomy_get_vocabularies($type = '', $key = 'vid') {
function taxonomy_get_vocabularies($type = NULL) {
if ($type) {
$result = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
$result = db_query("SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
}
else {
$result = db_query('SELECT * FROM {vocabulary} ORDER BY weight, name');
$result = db_query('SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid ORDER BY v.weight, v.name');
}
$vocabularies = array();
$node_types = array();
while ($voc = db_fetch_object($result)) {
$vocabularies[$voc->$key] = $voc;
$node_types[$voc->vid][] = $voc->type;
unset($voc->type);
$voc->nodes = $node_types[$voc->vid];
$vocabularies[$voc->vid] = $voc;
}
return $vocabularies;
@ -425,7 +441,7 @@ function taxonomy_node_form($type, $node = '', $help = NULL, $name = 'taxonomy')
$terms = $node->taxonomy;
}
$c = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
while ($vocabulary = db_fetch_object($c)) {
$result[] = taxonomy_form($vocabulary->vid, $terms, $help, $name);
}
@ -677,28 +693,6 @@ function _taxonomy_term_children($tid) {
return $children[$tid] ? $children[$tid] : array();
}
/**
* Try to map a string to an existing vocabulary.
*
* Provides a case-insensitive and trimmed mapping, to maximize the
* likelihood of a successful match.
*
* @param name
* Name of the vocabulary to search for.
*
* @return
* An array of matching vocabulary objects.
*/
function taxonomy_get_vocabulary_by_name($name) {
$db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
$result = array();
while ($vocabulary = db_fetch_object($db_result)) {
$result[] = $vocabulary;
}
return $result;
}
/**
* Try to map a string to an existing term, as for glossary use.
*
@ -725,7 +719,16 @@ function taxonomy_get_term_by_name($name) {
* Return the vocabulary object matching a vocabulary ID.
*/
function taxonomy_get_vocabulary($vid) {
return db_fetch_object(db_query('SELECT * FROM {vocabulary} WHERE vid = %d', $vid));
$result = db_query('SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid WHERE v.vid = %d ORDER BY v.weight, v.name', $vid);
$node_types = array();
while ($voc = db_fetch_object($result)) {
$node_types[] = $voc->type;
unset($voc->type);
$voc->nodes = $node_types;
$vocabulary = $voc;
}
return $vocabulary;
}
/**

View File

@ -116,14 +116,15 @@ function taxonomy_block($op = 'list', $delta = 0) {
}
function taxonomy_form_vocabulary($edit = array()) {
foreach (node_list() as $type) {
$nodetypes[$type] = node_invoke($type, 'node_name');
foreach (array_merge(node_list(), $edit['nodes']) as $type) {
$node_type = node_invoke($type, 'node_name');
$nodes[$type] = $node_type ? $node_type : $type;
}
$form .= form_textfield(t('Vocabulary name'), 'name', $edit['name'], 50, 64, t('The name for this vocabulary. Example: "Topic".'), NULL, TRUE);
$form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('Description of the vocabulary; can be used by modules.'));
$form .= form_textfield(t('Help text'), 'help', $edit['help'], 50, 255, t('Instructions to present to the user when choosing a term.'));
$form .= form_checkboxes(t('Types'), 'nodes', explode(',', $edit['nodes']), $nodetypes, t('A list of node types you want to associate with this vocabulary.'), NULL, TRUE);
$form .= form_checkboxes(t('Types'), 'nodes', $edit['nodes'], $nodes, t('A list of node types you want to associate with this vocabulary.'), NULL, TRUE);
$form .= form_checkbox(t('Related terms'), 'relations', 1, $edit['relations'], t('Allows <a href="%help-url">related terms</a> in this vocabulary.', array('%help-url' => url('admin/help/taxonomy', NULL, NULL, 'related-terms'))));
$form .= form_radios(t('Hierarchy'), 'hierarchy', $edit['hierarchy'], array(t('Disabled'), t('Single'), t('Multiple')), t('Allows <a href="%help-url">a tree-like hierarchy</a> between terms of this vocabulary.', array('%help-url' => url('admin/help/taxonomy', NULL, NULL, 'hierarchy'))));
$form .= form_checkbox(t('Multiple select'), 'multiple', 1, $edit['multiple'], t('Allows nodes to have more than one term in this vocabulary.'));
@ -144,9 +145,13 @@ function taxonomy_save_vocabulary($edit) {
$edit['nodes'] = array();
}
$data = array('name' => $edit['name'], 'nodes' => implode(',', $edit['nodes']), 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight']);
$data = array('name' => $edit['name'], 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight']);
if ($edit['vid'] && $edit['name']) {
db_query('UPDATE {vocabulary} SET '. _taxonomy_prepare_update($data) .' WHERE vid = %d', $edit['vid']);
db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d", $edit['vid']);
foreach ($edit['nodes'] as $type) {
db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
}
module_invoke_all('taxonomy', 'update', 'vocabulary', $edit);
$message = t('Updated vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
}
@ -156,6 +161,9 @@ function taxonomy_save_vocabulary($edit) {
else {
$data['vid'] = $edit['vid'] = db_next_id('{vocabulary}_vid');
db_query('INSERT INTO {vocabulary} '. _taxonomy_prepare_insert($data, 1) .' VALUES '. _taxonomy_prepare_insert($data, 2));
foreach ($edit['nodes'] as $type) {
db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
}
module_invoke_all('taxonomy', 'insert', 'vocabulary', $edit);
$message = t('Created new vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
}
@ -171,6 +179,7 @@ function taxonomy_del_vocabulary($vid) {
$vocabulary = taxonomy_get_vocabulary($vid);
db_query('DELETE FROM {vocabulary} WHERE vid = %d', $vid);
db_query('DELETE FROM {vocabulary_node_types} WHERE vid = %d', $vid);
$result = db_query('SELECT tid FROM {term_data} WHERE vid = %d', $vid);
while ($term = db_fetch_object($result)) {
taxonomy_del_term($term->tid);
@ -348,11 +357,12 @@ function taxonomy_overview() {
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $vocabulary) {
$links = array();
$types = array();
foreach(explode(',', $vocabulary->nodes) as $type) {
$types[] = node_invoke($type, 'node_name');
foreach($vocabulary->nodes as $type) {
$node_type = node_invoke($type, 'node_name');
$types[] = $node_type ? $node_type : $type;
}
$rows[] = array($vocabulary->name, array('data' => implode(', ', $types), 'align' => 'center'), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
$tree = taxonomy_get_tree($vocabulary->vid);
@ -394,16 +404,22 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
* @param $type
* If set, return only those vocabularies associated with this node type.
*/
function taxonomy_get_vocabularies($type = '', $key = 'vid') {
function taxonomy_get_vocabularies($type = NULL) {
if ($type) {
$result = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
$result = db_query("SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
}
else {
$result = db_query('SELECT * FROM {vocabulary} ORDER BY weight, name');
$result = db_query('SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid ORDER BY v.weight, v.name');
}
$vocabularies = array();
$node_types = array();
while ($voc = db_fetch_object($result)) {
$vocabularies[$voc->$key] = $voc;
$node_types[$voc->vid][] = $voc->type;
unset($voc->type);
$voc->nodes = $node_types[$voc->vid];
$vocabularies[$voc->vid] = $voc;
}
return $vocabularies;
@ -425,7 +441,7 @@ function taxonomy_node_form($type, $node = '', $help = NULL, $name = 'taxonomy')
$terms = $node->taxonomy;
}
$c = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
$c = db_query("SELECT v.*, n.type FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type);
while ($vocabulary = db_fetch_object($c)) {
$result[] = taxonomy_form($vocabulary->vid, $terms, $help, $name);
}
@ -677,28 +693,6 @@ function _taxonomy_term_children($tid) {
return $children[$tid] ? $children[$tid] : array();
}
/**
* Try to map a string to an existing vocabulary.
*
* Provides a case-insensitive and trimmed mapping, to maximize the
* likelihood of a successful match.
*
* @param name
* Name of the vocabulary to search for.
*
* @return
* An array of matching vocabulary objects.
*/
function taxonomy_get_vocabulary_by_name($name) {
$db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
$result = array();
while ($vocabulary = db_fetch_object($db_result)) {
$result[] = $vocabulary;
}
return $result;
}
/**
* Try to map a string to an existing term, as for glossary use.
*
@ -725,7 +719,16 @@ function taxonomy_get_term_by_name($name) {
* Return the vocabulary object matching a vocabulary ID.
*/
function taxonomy_get_vocabulary($vid) {
return db_fetch_object(db_query('SELECT * FROM {vocabulary} WHERE vid = %d', $vid));
$result = db_query('SELECT v.*, n.type FROM {vocabulary_node_types} n INNER JOIN {vocabulary} v ON v.vid = n.vid WHERE v.vid = %d ORDER BY v.weight, v.name', $vid);
$node_types = array();
while ($voc = db_fetch_object($result)) {
$node_types[] = $voc->type;
unset($voc->type);
$voc->nodes = $node_types;
$vocabulary = $voc;
}
return $vocabulary;
}
/**