| 1 |
<?php
|
| 2 |
// $Id: cmt_admin.inc,v 1.5 2007/08/19 21:35:22 agaric Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* Implementation of hook_help().
|
| 6 |
*/
|
| 7 |
function cmt_help($section) {
|
| 8 |
switch ($section) {
|
| 9 |
case 'admin/content/cmt':
|
| 10 |
return '<p>'.t('Community-managed vocabularies are listed below. To add one, <a href="@taxonomy-add-vocab">make a new vocabulary</a> or <a href="@taxonomy-admin">edit an existing vocabulary</a> and select an initial threshold under the "Community management" option.', array('@taxonomy-admin' => url('admin/content/taxonomy'), '@taxonomy-add-vocab' => url('admin/content/taxonomy/add/vocabulary'))).'</p>';
|
| 11 |
case 'admin/content/cmt/settings':
|
| 12 |
return '<p>'.t('Edit system-wide settings for Community-managed Taxonomy.').'</p>';
|
| 13 |
}
|
| 14 |
}
|
| 15 |
|
| 16 |
/**
|
| 17 |
* List and manage vocabularies.
|
| 18 |
*/
|
| 19 |
function cmt_overview_vocabularies() {
|
| 20 |
$vocabularies = cmt_get_vocabularies();
|
| 21 |
$rows = array();
|
| 22 |
foreach ($vocabularies as $vocabulary) {
|
| 23 |
$types = array();
|
| 24 |
foreach ($vocabulary->nodes as $type) {
|
| 25 |
$node_type = node_get_types('name', $type);
|
| 26 |
$types[] = $node_type ? $node_type : $type;
|
| 27 |
}
|
| 28 |
$rows[] = array('name' => check_plain($vocabulary->name),
|
| 29 |
'type' => implode(', ', $types),
|
| 30 |
'cmt_edit' => l(t('edit vocabulary community-managed settings'), "admin/content/cmt/edit/vocabulary/$vocabulary->vid"),
|
| 31 |
'edit' => l(t('edit other vocabulary settings'), "admin/content/taxonomy/edit/vocabulary/$vocabulary->vid"),
|
| 32 |
// 'list' => l(t('list terms'), "admin/content/taxonomy/$vocabulary->vid"),
|
| 33 |
// 'add' => l(t('add terms'), "admin/content/taxonomy/$vocabulary->vid/add/term")
|
| 34 |
);
|
| 35 |
}
|
| 36 |
if (empty($rows)) {
|
| 37 |
$rows[] = array(array('data' => t('No categories are community-managed.'), 'colspan' => '4'));
|
| 38 |
}
|
| 39 |
$header = array(t('Name'), t('Type'), array('data' => t('Operations'), 'colspan' => '2'));
|
| 40 |
|
| 41 |
return theme('table', $header, $rows, array('id' => 'taxonomy'));
|
| 42 |
}
|
| 43 |
|
| 44 |
/**
|
| 45 |
* Display form for adding and editing vocabularies' community-managed options.
|
| 46 |
*/
|
| 47 |
function cmt_form_vocabulary($edit = array()) {
|
| 48 |
$form['info'] = array('#type' => 'markup',
|
| 49 |
'#value' => '<div>' . t('This administration page is to set options for the community-managed features of this vocabulary, <em>@name</em>. Edit other aspects of this vocabulary at its <a href="@taxonomy-admin">taxonomy administration page</a>.', array('@taxonomy-admin' => url('admin/content/taxonomy/edit/vocabulary/' . $edit['vid']), '@name' => $edit['name'])) . '</div>',
|
| 50 |
);
|
| 51 |
$form['cmt_enabled'] = array(
|
| 52 |
'#type' => 'checkbox',
|
| 53 |
'#title' => t('Community managed'),
|
| 54 |
'#default_value' => $edit['cmt_enabled'],
|
| 55 |
'#description' => t('Unchecking this box enables you to temporarily disable community managing of this vocabulary without losing stored votes.'),
|
| 56 |
);
|
| 57 |
$form['thresholds'] = array(
|
| 58 |
'#type' => 'fieldset',
|
| 59 |
'#title' => t('Thresholds'),
|
| 60 |
'#description' => t('Set voting threshold, including to one vote (no threshold). The lower the threshold setting the more quickly an action takes place based on community input. You can also disable community-managing capabilities entirely for each aspect of a vocabulary. Threshold numbers go high because they can, but sticking to low numbers - in fact, the defaults - is recommended unless you have a huge number of active users. No thresholds can work fine, the default threshold of 2 votes helps keep changes from occurring by accident. Changing thresholds after the vocabulary is in use may lead to unexpected results.'),
|
| 61 |
'#collapsible' => TRUE,
|
| 62 |
'#collapsed' => FALSE,
|
| 63 |
);
|
| 64 |
$form['threshold_options'] = array(
|
| 65 |
'#type' => 'value',
|
| 66 |
'#value' => array(
|
| 67 |
'0' => t('Disable community management'),
|
| 68 |
'1' => t('No threshold (1 vote)'),
|
| 69 |
'2' => t('2 votes'),
|
| 70 |
'3' => t('3 votes'),
|
| 71 |
'4' => t('4 votes'),
|
| 72 |
'5' => t('5 votes'),
|
| 73 |
'6' => t('6 votes'),
|
| 74 |
'7' => t('7 votes'),
|
| 75 |
'8' => t('8 votes'),
|
| 76 |
'9' => t('9 votes'),
|
| 77 |
'10' => t('10 votes'),
|
| 78 |
'11' => t('11 votes'),
|
| 79 |
'12' => t('12 votes'),
|
| 80 |
'13' => t('13 votes'),
|
| 81 |
'14' => t('14 votes'),
|
| 82 |
'15' => t('15 votes'),
|
| 83 |
'16' => t('16 votes'),
|
| 84 |
'17' => t('17 votes'),
|
| 85 |
'18' => t('18 votes'),
|
| 86 |
'19' => t('19 votes'),
|
| 87 |
'20' => t('20 votes'),
|
| 88 |
'21' => t('21 votes'),
|
| 89 |
'22' => t('22 votes'),
|
| 90 |
'23' => t('23 votes'),
|
| 91 |
'24' => t('24 votes'),
|
| 92 |
'25' => t('25 votes'),
|
| 93 |
'30' => t('30 votes'),
|
| 94 |
'35' => t('35 votes'),
|
| 95 |
'40' => t('40 votes'),
|
| 96 |
'45' => t('45 votes'),
|
| 97 |
'50' => t('50 votes'),
|
| 98 |
'55' => t('55 votes'),
|
| 99 |
'60' => t('60 votes'),
|
| 100 |
'65' => t('65 votes'),
|
| 101 |
'70' => t('70 votes'),
|
| 102 |
'75' => t('75 votes'),
|
| 103 |
'80' => t('80 votes'),
|
| 104 |
'90' => t('90 votes'),
|
| 105 |
'100' => t('100 votes'),
|
| 106 |
'110' => t('110 votes'),
|
| 107 |
'120' => t('120 votes'),
|
| 108 |
'130' => t('130 votes'),
|
| 109 |
'140' => t('140 votes'),
|
| 110 |
'150' => t('150 votes'),
|
| 111 |
'160' => t('160 votes'),
|
| 112 |
'170' => t('170 votes'),
|
| 113 |
'180' => t('180 votes'),
|
| 114 |
'190' => t('190 votes'),
|
| 115 |
'200' => t('200 votes'),
|
| 116 |
),
|
| 117 |
);
|
| 118 |
$form['thresholds']['cmt_description_th'] = array(
|
| 119 |
'#type' => 'select', // for dropdown
|
| 120 |
'#title' => t('Description'),
|
| 121 |
'#options' => $form['threshold_options']['#value'],
|
| 122 |
'#default_value' => $edit['cmt_description_th'],
|
| 123 |
'#description' => t('Votes needed for the first user-chosen description to be used.'),
|
| 124 |
);
|
| 125 |
$form['thresholds']['cmt_weight_th'] = array(
|
| 126 |
'#type' => 'select',
|
| 127 |
'#title' => t('Weight'),
|
| 128 |
'#options' => $form['threshold_options']['#value'],
|
| 129 |
'#default_value' => $edit['cmt_weight_th'],
|
| 130 |
'#description' => t('Votes needed for the first user-chosen weight to be used.'),
|
| 131 |
);
|
| 132 |
$form['thresholds']['cmt_name_th'] = array(
|
| 133 |
'#type' => 'select',
|
| 134 |
'#title' => t('Names'),
|
| 135 |
'#options' => $form['threshold_options']['#value'],
|
| 136 |
'#default_value' => $edit['cmt_name_th'],
|
| 137 |
'#description' => t('Votes needed for the first user-chosen name or any user-chosen synonym to be used.'),
|
| 138 |
);
|
| 139 |
$form['thresholds']['cmt_hierarchy_th'] = array(
|
| 140 |
'#type' => 'select',
|
| 141 |
'#title' => t('Positions'),
|
| 142 |
'#options' => $form['threshold_options']['#value'],
|
| 143 |
'#default_value' => $edit['cmt_hierarchy_th'],
|
| 144 |
'#description' => t('Votes needed for any user-chosen term position (also called arrangement, hierarchy, structure, categorization) to be used.'),
|
| 145 |
);
|
| 146 |
$form['thresholds']['cmt_node_th'] = array(
|
| 147 |
'#type' => 'select',
|
| 148 |
'#title' => t('Creating terms'),
|
| 149 |
'#options' => $form['threshold_options']['#value'],
|
| 150 |
'#default_value' => $edit['cmt_node_th'],
|
| 151 |
'#description' => t('Votes needed for any user-chosen term to be created and attached to a node (in short, the threshold for tagging).'),
|
| 152 |
);
|
| 153 |
$form['thresholds']['cmt_merge_th'] = array(
|
| 154 |
'#type' => 'select',
|
| 155 |
'#title' => t('Merge'),
|
| 156 |
'#options' => $form['threshold_options']['#value'],
|
| 157 |
'#default_value' => $edit['cmt_merge_th'],
|
| 158 |
'#description' => t('Votes needed for any user-chosen merging of terms to take effect.'),
|
| 159 |
);
|
| 160 |
$form['thresholds']['cmt_related_th'] = array(
|
| 161 |
'#type' => 'select',
|
| 162 |
'#title' => t('Related terms'),
|
| 163 |
'#options' => $form['threshold_options']['#value'],
|
| 164 |
'#default_value' => $edit['cmt_related_th'],
|
| 165 |
'#description' => t('Votes <em>for merging</em> needed for terms to be considered related terms (that is, term relations are derived from users\' term merge recommendations). Related terms must be enabled for this vocabulary.'), // (unless I can do it programatically)
|
| 166 |
);
|
| 167 |
|
| 168 |
// it should not be possible to edit this form without a vid present
|
| 169 |
$form['vid'] = array('#type' => 'value', '#value' => $edit['vid']);
|
| 170 |
$form['module'] = array('#type' => 'value', '#value' => $edit['module']);
|
| 171 |
$new = 'update'; // not new
|
| 172 |
if ($edit['cmt_enabled']===NULL) $new = 'insert'; // somehow, new
|
| 173 |
$form['new'] = array('#type' => 'value', '#value' => $new);
|
| 174 |
$form['name'] = array('#type' => 'value', '#value' => $edit['name']);
|
| 175 |
|
| 176 |
$form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
|
| 177 |
|
| 178 |
return $form;
|
| 179 |
}
|
| 180 |
|
| 181 |
/**
|
| 182 |
* Accept the form submission for a vocabulary and save the results.
|
| 183 |
*/
|
| 184 |
function cmt_form_vocabulary_submit($form_id, $form_values) {
|
| 185 |
switch (cmt_save_vocabulary($form_values, $form_values['new'])) {
|
| 186 |
// this should never happen here-- this only edits existing vocabs right now
|
| 187 |
// however, since I screwed up the uninstall (it didn't change vocab names back)
|
| 188 |
// I made this so I could just make CMT vocabs with no entries a new vocab
|
| 189 |
case SAVED_NEW:
|
| 190 |
drupal_set_message(t('Made vocabulary %name community-managed.', array('%name' => $form_values['name'])));
|
| 191 |
break;
|
| 192 |
case SAVED_UPDATED:
|
| 193 |
drupal_set_message(t('Updated community-managed options for vocabulary %name.', array('%name' => $form_values['name'])));
|
| 194 |
break;
|
| 195 |
}
|
| 196 |
return 'admin/content/cmt';
|
| 197 |
}
|
| 198 |
|
| 199 |
function cmt_save_vocabulary($edit, $op = 'insert') {
|
| 200 |
switch ($op) {
|
| 201 |
case 'update':
|
| 202 |
if (db_query("UPDATE {cmt_vocabulary} c SET c.cmt_enabled = %d, c.cmt_description_th = %d, c.cmt_weight_th = %d, c.cmt_name_th = %d, c.cmt_hierarchy_th = %d, c.cmt_merge_th = %d, c.cmt_node_th = %d, c.cmt_related_th = %d WHERE c.vid = %d", $edit['cmt_enabled'], $edit['cmt_description_th'], $edit['cmt_weight_th'], $edit['cmt_name_th'], $edit['cmt_hierarchy_th'], $edit['cmt_merge_th'], $edit['cmt_node_th'], $edit['cmt_related_th'], $edit['vid'])) {
|
| 203 |
return SAVED_UPDATED;
|
| 204 |
}
|
| 205 |
break;
|
| 206 |
case 'insert':
|
| 207 |
// $edit['vid'] should be available from taxonomy_save_vocabulary, which had it by reference
|
| 208 |
if (db_query("INSERT INTO {cmt_vocabulary} (vid, cmt_enabled, cmt_description_th, cmt_weight_th, cmt_name_th, cmt_hierarchy_th, cmt_merge_th, cmt_node_th, cmt_related_th) VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)", $edit['vid'], $edit['cmt_enabled'], $edit['cmt_description_th'], $edit['cmt_weight_th'], $edit['cmt_name_th'], $edit['cmt_hierarchy_th'], $edit['cmt_merge_th'], $edit['cmt_node_th'], $edit['cmt_related_th'])) {
|
| 209 |
return SAVED_NEW;
|
| 210 |
}
|
| 211 |
}
|
| 212 |
}
|
| 213 |
|
| 214 |
/**
|
| 215 |
* Delete a vocabulary.
|
| 216 |
*
|
| 217 |
* @param $vid
|
| 218 |
* A vocabulary ID.
|
| 219 |
* @return
|
| 220 |
* Constant indicating items were deleted.
|
| 221 |
*/
|
| 222 |
function _cmt_del_vocabulary($vid) {
|
| 223 |
db_query('DELETE FROM {cmt_vocabulary} WHERE vid = %d', $vid);
|
| 224 |
$result = db_query('SELECT tid FROM {cmt_term_vocab} WHERE vid = %d', $vid);
|
| 225 |
while ($term = db_fetch_object($result)) {
|
| 226 |
// core taxonomy uses taxonomy_del_term but CMT don't delete unless whole vocab killed
|
| 227 |
// can't this be done in one pretty query? Why doesn't Drupal core do that?
|
| 228 |
db_query('DELETE FROM {cmt_term_data} WHERE tid = %d', $tid);
|
| 229 |
db_query('DELETE FROM {cmt_term_description} WHERE tid = %d', $tid);
|
| 230 |
db_query('DELETE FROM {cmt_term_weight} WHERE tid = %d', $tid);
|
| 231 |
db_query('DELETE FROM {cmt_term_name} WHERE tid = %d', $tid);
|
| 232 |
db_query('DELETE FROM {cmt_term_hierarchy} WHERE tid = %d', $tid);
|
| 233 |
db_query('DELETE FROM {cmt_term_merge} WHERE tid1 = %d OR tid2 = %d', $tid, $tid);
|
| 234 |
db_query('DELETE FROM {cmt_term_node} WHERE tid = %d', $tid);
|
| 235 |
db_query('DELETE FROM {cmt_term_vocab} WHERE tid = %d', $tid);
|
| 236 |
}
|
| 237 |
return SAVED_DELETED;
|
| 238 |
}
|
| 239 |
|
| 240 |
/**
|
| 241 |
* Page to edit the community-management settings for a vocabulary.
|
| 242 |
*/
|
| 243 |
function cmt_admin_vocabulary_edit($vid = NULL) {
|
| 244 |
if (!is_numeric($vid)) {
|
| 245 |
drupal_set_message("That's not a number!", 'error');
|
| 246 |
return;
|
| 247 |
}
|
| 248 |
// deleting vocabularies is handled by taxonomy.module's admin pages, not here
|
| 249 |
// same with creating. So if there's no vid, don't show the form
|
| 250 |
// it better be one of ours, too
|
| 251 |
if (cmt_is_vid_cmt($vid)) {
|
| 252 |
$vocabulary = (array)taxonomy_get_vocabulary($vid);
|
| 253 |
$cmt_vocabulary = (array)cmt_get_vocabulary($vid); // get the CMT info for this vocab
|
| 254 |
$vocabulary = array_merge($vocabulary, $cmt_vocabulary);
|
| 255 |
return drupal_get_form('cmt_form_vocabulary', $vocabulary);
|
| 256 |
}
|
| 257 |
return drupal_not_found();
|
| 258 |
}
|
| 259 |
|
| 260 |
|
| 261 |
/**
|
| 262 |
* Configures the various Community Managed Taxonomy options; system_settings_form().
|
| 263 |
*/
|
| 264 |
function cmt_settings() {
|
| 265 |
$form = array();
|
| 266 |
$form['information'] = array(
|
| 267 |
'#type' => 'markup',
|
| 268 |
'#title' => t('Site-wide settings for Community Managed Taxonomy'),
|
| 269 |
'#description' => t('Terms added or modified through the usual administrative interface (rather than through community managed taxonomy\'s collaborative interface) are padded up to the minimum threshold or the number of votes needed to have it take effect.'),
|
| 270 |
);
|
| 271 |
$form['cmt_general'] = array(
|
| 272 |
'#type' => 'fieldset',
|
| 273 |
'#title' => t('General settings'),
|
| 274 |
'#collapsible' => TRUE,
|
| 275 |
'#collapsed' => FALSE,
|
| 276 |
);
|
| 277 |
return system_settings_form($form);
|
| 278 |
}
|
| 279 |
|
| 280 |
/**
|
| 281 |
* Implementation of hook_user
|
| 282 |
*
|
| 283 |
* Delete user CMT votes and recalculate results.
|
| 284 |
*
|
| 285 |
*/
|
| 286 |
function cmt_user($op, $edit, $account, $category) {
|
| 287 |
if ($op == 'delete') {
|
| 288 |
/* I would have liked to delete votes from a user and recalculate results when a user is deleted. It's not a big deal but votingapi's lack of an easy way to do this surprises me.
|
| 289 |
All vote deleting by user AND vote recalculating functions require you to also provide the content ID, which quite defeats the point. I'm happy to delete a user content_type at a time, but I can't believe I have to run a select on users and content_ids first, or write my own way of tracking what content_ids I delete users from, in order to keep the tally of results accurate.
|
| 290 |
When I do so I'll want it to tell me when I'm deleting the only vote for a content_id so I can delete its row in my cmt_whatever_type table as well
|
| 291 |
*/
|
| 292 |
// $votingapi_cache = votingapi_unset_vote('cmt_term_description', $content_id, $uid = NULL)
|
| 293 |
// cmt_push($content_type, $content_id, $votingapi_cache)
|
| 294 |
}
|
| 295 |
}
|