Posted by thijsboeree on January 12, 2011 at 4:55pm
3 followers
| Project: | Taxonomy Access Control Lite |
| Version: | 6.x-1.4 |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Issue Summary
Hi,
Very nice module!!
I have a very large taxonomy "term_data" table... I want to give each user his or her own "viewing allowed" taxonomy list (each user has about 40 to 50 terms), what can i put in the node_acces table..? I have a script ready in php which can write the tid, and the uid....
Best regards!
Thijs
Comments
#1
The size of the node_access table will depend on how many nodes, and how many each is tagged with. The total number of terms doesn't matter. You don't want to write code to put values in there, instead you want to tag the nodes, then rebuild the node access table (drupal has a way to do that, I forget exactly).
#2
Ok,
But... where are the users given the access to the taxonomy id's?..
Grant ID is the tid...?
Best regards,
Thijs
#3
Ok, the tid is written in the data field of the user... But that's only 8000 characters max...
#4
in addition to thijsboeree's, i have nearly 90000 terms and users need to be tagged 3-4 different terms each. loading the individual user's access page is burdensome, so i thought of tinkering the database. following is a copy of from the users table under data field:
a:2:{s:8:"tac_lite";a:1:{i:1;a:5:
i:7;s:1:"7";
i:245;s:3:"245";
i:247;s:3:"247";
i:249;s:3:"249";
i:251;s:3:"251";}}
my intuition says that the second line is trying to say that this particular user has 5 terms tagged with the terms ids being 7, 245, 247, 249 and 251. but then, what is the "s" supposed to mean (in between i and the term id in quote marks)?
#5
i guess it's the string length then.
#6
it is php's syntax for serializing a data structure. You're better off writing PHP code to query the data, unserialize, change, then re-serialize.
#7
Is there a way to overcome this problem? Like changing the select list to an auto-complete text field where the user can just type the term that needs to be associated for the individual user's permission? Loading the page is really a huge performance setback. Or perhaps, integration with Hierarchical Select maybe?
#8
I'm open to a patch that gives admins this option. Can you code it?
I'm not sure taxonomy terms have to be unique, so any auto-complete option will have to take that into account.
#9
Attached is a snippet that I'm currently using. It helps a lot in my case, with a huge collection of terms. Drupal doesn't have to load the whole vocabulary. Even worse if there are multiple schemes.
I'm imagining an integration with the Hierarchical Select module but I can't think a way through it.
#10
Can you provide a diff?
#11
<?php
>
$items['tac_lite/autocomplete'] = array(
'title' => 'TAC lite autocomplete',
'page callback' => 'tac_lite_autocomplete',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
function get_terms_from_tids($vid, $tids){
//print_r($tids); echo '---<br>';
if (!is_array($tids) || !$vid) return false;
$s='';
foreach ($tids as $tid)
if ($tid)
{
$result = db_query_range(db_rewrite_sql("SELECT name FROM {term_data} WHERE vid = $vid AND tid = $tid", 'term_data', 'tid'), 0, 1);
while ($tag = db_fetch_object($result)) {
$s.= $tag->name .', ';
}
}
return $s;
}
function get_tids_from_terms($vid, $terms){
//print_r($terms);
$tids=array();
if (is_array($terms) && $vid)
foreach ($terms as $term){
$result = db_query_range(db_rewrite_sql("SELECT tid FROM {term_data} WHERE vid = $vid AND name = '$term'", 'term_data', 'tid'), 0, 1);
while ($tag = db_fetch_object($result)) {
$tids[$tag->tid]=$tag->tid;
}
}
//echo '-B-'; print_r($tids); echo '-E-';
return $tids;
}
function tac_lite_autocomplete($vid, $string = '') {
// The user enters a comma-separated list of tags. We only autocomplete the last tag.
// This regexp allows the following types of user input:
// this, "somecmpany, llc", "and ""this"" w,o.rks", foo bar
$regexp = %(?:^|, *)("(
?>
preg_match_all($regexp, $string, $matches);
$array = $matches[1];
// print_r($string); die();
// Fetch last tag
$last_string = trim(array_pop($array));
/*
$p=strrpos($string, ',');
if (!$p) $p=-1;
$last_string =trim(substr($string, $p+1));
*/
$matches = array();
//echo '--- '.$vid.' ---- '.$last_string;
if ($last_string != '') {
$result = db_query_range(db_rewrite_sql("SELECT t.tid, t.name AS name FROM {term_data} t WHERE t.vid = $vid AND t.name LIKE '%".$last_string."%'", 't', 'tid'), 0, 10);
$prefix = count($array) ? implode(', ', $array) .', ' : '';
while ($tag = db_fetch_object($result)) {
$n = $tag->name;
$parents = taxonomy_get_parents_all($tag->tid);
// Commas and quotes in terms are special cases, so encode 'em.
if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
$n = '"'. str_replace('"', '""', check_plain($tag->name)) .'"';
}
if(count($parents)>1){
$parent_array = array();
$parents = array_reverse($parents);
array_pop($parents);
foreach($parents as $parent){
$parent_array[] = check_plain($parent->name);
}
$matches[$prefix . $n] = check_plain($tag->name) ." (".implode(" » ",$parent_array).")";
} else {
$matches[$prefix . $n] = check_plain($tag->name);
}
}
}
print drupal_to_js($matches);
exit;
}
$vocabularies = taxonomy_get_vocabularies();
$all_defaults = variable_get('tac_lite_grants_scheme_' . $i, array());
$form['tac_lite_grants_scheme_' . $i] = array('#tree' => TRUE);
foreach ($roles as $rid => $role_name) {
$form['tac_lite_grants_scheme_' . $i][$rid] = array(
'#type' => 'fieldset', //'textfield', //
'#tree' => TRUE,
'#title' => check_plain(t('Grant permission by role: !role', array('!role' => $role_name))),
'#description' => t(''),
'#collapsible' => TRUE,
'#autocomplete_path' => 'tac_lite/autocomplete/'.$form['#vocabulary']['vid']
);
$defaults = isset($all_defaults[$rid]) ? $all_defaults[$rid] : NULL;
foreach ($vids as $vid) {
$v = $vocabularies[$vid];
$form['tac_lite_grants_scheme_' . $i][$rid][$vid] = array(
'#type' => 'textfield',
//'#maxlength' => 10000,
'#title' => $v->name,
'#default_value' => get_terms_from_tids($vid, $defaults[$vid]),
'#autocomplete_path' => 'tac_lite/autocomplete/'.$vid);
}
}
$form['#submit'][] = 'tac_lite_admin_scheme_form_submit';
return system_settings_form($form);
}
else {
return (array('body' => array('#type' => 'markup',
'#value' => t('First select vocabularies on the settings page.', array('!url' => url('admin/user/access/tac_lite'))))));
}
}
function tac_lite_split_field($string, $vid){
// Add slashes first
$string = addslashes($string);
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $string, $matches);
$string_array = $matches[1];
//echo 's: '; print_r($string_array);
return get_tids_from_terms($vid, $string_array);
}
/**
* Submit function for admin settings form to rebuild the menu.
*/
function tac_lite_admin_scheme_form_submit($form, &$form_state) {
//die('xxx');
$vids = variable_get('tac_lite_categories', NULL);
$vocabularies = taxonomy_get_vocabularies();
$schemes = variable_get('tac_lite_schemes', 1);
$roles = user_roles();
for ($i = 1; $i <= $schemes; $i++) {
foreach ($form_state['values']['tac_lite_grants_scheme_'.$i] as &$rid) {
//print_r($rid); die();
foreach ($vids as $vid) {
$rid[$vid] = tac_lite_split_field($rid[$vid], $vid);
}
}
}
variable_set('menu_rebuild_needed', TRUE);
}
function tac_lite_user_form_submit($form, &$form_state) {
//print_r($form_state['values']);die('xxx');
$x=array();
$x['tac_lite']=array();
$x['form_build_id']=$form_state['values']['_account']->form_build_id;
$vids = variable_get('tac_lite_categories', NULL);
foreach ($vids as $vid) {
$x['tac_lite'][$vid]=tac_lite_split_field($form_state['values'][$vid], $vid);
}
//print_r(serialize($x)); //die();
db_query("UPDATE {users} SET data='%s' WHERE uid=".$form_state['values']['_account']->uid, serialize($x));
}
$form['tac_lite_grants_scheme_' . $i][$rid][$vid] = array(
'#type' => 'textfield',
//'#maxlength' => 10000,
'#title' => $v->name,
//'#description' => $form['taxonomy'][$vid]['#description'],
'#default_value' => get_terms_from_tids($vid, $terms[$vid]),
'#autocomplete_path' => 'tac_lite/autocomplete/'.$vid);
?>
This works in individual page where you set their own permission settings.