diff --git README.txt README.txt
index c83a12f..4d5e23b 100644
--- README.txt
+++ README.txt
@@ -24,6 +24,7 @@ CONTENTS
4. Configuration
4.1 Access schemes
4.1.1 Automated section assignment
+4.1.2 Allow multiple section assignments
4.2 Access sections
4.2.1 Manual section configuration
4.2.2 Automated section configuration
@@ -475,6 +476,21 @@ automatically configured for you.
----
+4.1.2 Allow multiple section assignments
+
+The checkbox labeled 'Allow multiple section assignments' controls the behavior
+of the section selection form when editing content. This optional setting is
+disabled by default.
+
+ [ ] Allow multiple section assignments
+ Let content be assigned to multiple sections.
+
+If enabled, editors will be shown a multiple select option when editing section
+assignments. This configuration can be useful if you have content that spans
+several parts of your organization.
+
+
+----
4.2 Access sections
Once you have declared an access scheme, you may enable the sections for that
diff --git includes/workbench_access_handler_field_section.inc includes/workbench_access_handler_field_section.inc
index 96699e5..e3e8e02 100644
--- includes/workbench_access_handler_field_section.inc
+++ includes/workbench_access_handler_field_section.inc
@@ -9,67 +9,57 @@
* @TODO: support multiple sections.
*/
-class workbench_access_handler_field_section extends views_handler_field {
- // No query for this field.
+class workbench_access_handler_field_section extends views_handler_field_prerender_list {
+ function init(&$view, &$options) {
+ parent::init($view, $options);
+ if ($view->base_table == 'node_revisions') {
+ $this->additional_fields['nid'] = array('table' => 'node_revisions', 'field' => 'nid');
+ }
+ else {
+ $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid');
+ }
+ }
+ // Add the additional fields.
function query() {
- $active = workbench_access_get_active_tree();
- $field_table = $this->query->ensure_table($active['access_scheme']['field_table']);
- // Using this field alias breaks the COUNT query. Views bug?
- $field = $this->query->add_field($field_table, $active['access_scheme']['query_field'], 'workbench_access_id');
+ $this->add_additional_fields();
}
- function click_sort($order) {
- $active = workbench_access_get_active_tree();
- if (empty($active['access_scheme']['sort'])) {
- return;
+ function pre_render(&$values) {
+ // We have to find the sections assigned to each node.
+ $this->field_alias = $this->aliases['nid'];
+ $nids = array();
+ foreach ($values as $result) {
+ if (!empty($result->{$this->aliases['nid']})) {
+ $nids[] = $result->{$this->aliases['nid']};
+ }
}
- foreach ($active['access_scheme']['sort'] as $sort) {
- $table = $this->query->ensure_table($sort['table']);
- if (!empty($table)) {
- $this->query->add_orderby($table, $sort['field'], (isset($sort['order'])) ? $sort['order'] : $order);
+ foreach ($values as $result) {
+ if (!empty($result->{$this->aliases['nid']})) {
+ $nids[$result->{$this->aliases['nid']}] = new stdClass();
+ $nids[$result->{$this->aliases['nid']}]->nid = $result->{$this->aliases['nid']};
}
}
- // Logic to remove JOIN to the default table, which can cause duplicate results.
- $base_table = $this->view->base_table;
- if ($base_table == 'node' && isset($active['access_scheme']['adjust_join'])) {
- foreach ($active['access_scheme']['adjust_join'] as $table => $replace) {
- $join = $this->query->get_join_data($table, $base_table);
- if (isset($join->left_table) && $join->left_table == $replace['original_table']) {
- $this->query->table_queue[$table]['join']->left_table = $replace['new_table'];
- $this->query->table_queue[$table]['join']->left_field = $replace['new_field'];
- unset($this->query->tables['node'][$replace['original_table']]);
- unset($this->query->table_queue[$replace['original_table']]);
+ workbench_access_node_load($nids, array());
+ $active = workbench_access_get_active_tree();
+ foreach ($values as $value) {
+ if (isset($value->nid) && isset($nids[$value->nid]->workbench_access)) {
+ foreach ($nids[$value->nid]->workbench_access as $access_id) {
+ $value->workbench_access[] = check_plain($active['tree'][$access_id]['name']);
+ $this->items[$value->nid][$access_id]['value'] = check_plain($active['tree'][$access_id]['name']);
}
}
+ else {
+ $value->workbench_access = array();
+ }
}
}
-
+ // Only render() seems to work. What gives, Views?
function render($values) {
- global $user;
- $account = $user;
- if (!isset($account->workbench_access)) {
- workbench_access_user_load_data($account);
- }
- if (!isset($values->workbench_access_id)) {
- return '';
- }
- $active = workbench_access_get_active_tree();
- $name = '';
- $tree = $active['tree'];
- workbench_access_build_tree($tree, array_keys($account->workbench_access));
- if (isset($account->workbench_access[$values->workbench_access_id])) {
- $name = $tree[$values->workbench_access_id]['name'];
- }
- else {
- foreach ($account->workbench_access as $id => $data) {
- if (!empty($tree[$id]['children'])) {
- $children = $tree[$id]['children'];
- if (in_array($values->workbench_access_id, $children)) {
- $name = $tree[$id]['name'] . ' > ' . $tree[$values->workbench_access_id]['name'];
- }
- }
- }
+ if ($this->options['type'] == 'separator') {
+ return implode($this->sanitize_value($this->options['separator']), $values->workbench_access);
}
- return check_plain($name);
+ $variables['items'] = $values->workbench_access;
+ $variables['type'] = $this->options['type'];
+ return theme('item_list', $variables);
}
}
diff --git includes/workbench_access_handler_filter_access.inc includes/workbench_access_handler_filter_access.inc
index 9b07363..75d1258 100644
--- includes/workbench_access_handler_filter_access.inc
+++ includes/workbench_access_handler_filter_access.inc
@@ -7,7 +7,7 @@
* Provides a filter to display nodes by assigned section.
*/
-class workbench_access_handler_filter_access extends views_handler_filter {
+class workbench_access_handler_filter_access extends views_handler_filter_many_to_one {
function option_definition() {
$options = parent::option_definition();
$options['access_id'] = array('default' => NULL);
@@ -67,6 +67,7 @@ class workbench_access_handler_filter_access extends views_handler_filter {
}
function query() {
+ return;
global $user;
$account = $user; // Not a clone, but that's ok, since we need this data on $user.
if (!isset($account->workbench_access)) {
diff --git workbench_access.admin.inc workbench_access.admin.inc
index b8fa840..817e3b9 100644
--- workbench_access.admin.inc
+++ workbench_access.admin.inc
@@ -53,6 +53,12 @@ function workbench_access_settings_form($form, &$form_state) {
'#default_value' => variable_get('workbench_access_auto_assign', 1),
'#description' => t('Enable all sections automatically for the active scheme.'),
);
+ $form['workbench_access_allow_multiple'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Allow multiple section assignments'),
+ '#default_value' => variable_get('workbench_access_allow_multiple', 0),
+ '#description' => t('Let content be assigned to multiple sections.'),
+ );
/*
$form['workbench_access_custom_form'] = array(
'#type' => 'checkbox',
diff --git workbench_access.module workbench_access.module
index 26b60f6..613884b 100644
--- workbench_access.module
+++ workbench_access.module
@@ -504,15 +504,19 @@ function workbench_access_node_load($nodes, $types) {
if (!isset($scheme)) {
$scheme = variable_get('workbench_access', 'taxonomy');
}
- $result = db_query("SELECT nid, access_id FROM {workbench_access_node} WHERE nid IN (:nid) AND access_scheme = :access_scheme", array(':nid' => array_keys($nodes), ':access_scheme' => $scheme))->fetchAllAssoc('nid');
+ $result = db_query("SELECT nid, access_id FROM {workbench_access_node} WHERE nid IN (:nid) AND access_scheme = :access_scheme", array(':nid' => array_keys($nodes), ':access_scheme' => $scheme))->fetchAll();
+ $data = array();
+ foreach ($result as $obj) {
+ $data[$obj->nid][$obj->access_id] = $obj->access_id;
+ }
foreach ($nodes as $node) {
// Cannot load if the node has not been created yet.
if (empty($node->nid)) {
continue;
}
$nodes[$node->nid]->workbench_access = array();
- if (isset($result[$node->nid])) {
- $nodes[$node->nid]->workbench_access[$result[$node->nid]->access_id] = $result[$node->nid]->access_id;
+ if (isset($data[$node->nid])) {
+ $nodes[$node->nid]->workbench_access = $data[$node->nid];
}
}
}
@@ -526,12 +530,35 @@ function workbench_access_node_insert($node) {
return;
}
workbench_access_node_delete($node);
- $record = array(
- 'nid' => $node->nid,
- 'access_id' => $node->workbench_access_id,
- 'access_scheme' => $node->workbench_access_scheme['access_scheme'],
- );
- drupal_write_record('workbench_access_node', $record);
+ if (empty($node->workbench_access_id)) {
+ return;
+ }
+ if (!is_array($node->workbench_access_id)) {
+ $node->workbench_access_id = array($node->workbench_access_id);
+ }
+ foreach ($node->workbench_access_id as $id) {
+ $record = array(
+ 'nid' => $node->nid,
+ 'access_id' => $id,
+ 'access_scheme' => $node->workbench_access_scheme['access_scheme'],
+ );
+ drupal_write_record('workbench_access_node', $record);
+ }
+}
+
+/**
+ * Implements hook_node_presave().
+ */
+function workbench_access_node_presave($node) {
+ if (isset($node->workbench_access_id) && isset($node->workbench_access_fixed)) {
+ if (!is_array($node->workbench_access_id)) {
+ $node->workbench_access_id = array($node->workbench_access_id);
+ }
+ if (!is_array($node->workbench_access_fixed)) {
+ $node->workbench_access_fixed = array($node->workbench_access_fixed);
+ }
+ $node->workbench_access_id += $node->workbench_access_fixed;
+ }
}
/**
@@ -1176,12 +1203,10 @@ function workbench_access_form_alter(&$form, $form_state, $form_id) {
$tree = workbench_access_get_user_tree();
// Generate options so we can check for access.
$options = workbench_access_options($tree, $active['active']);
- // TODO: multi-select
- $default = NULL;
+ $default = array();
if (!empty($form['#node']->workbench_access)) {
- $default = current(array_keys($form['#node']->workbench_access));
+ $default = array_keys($form['#node']->workbench_access);
}
-
// If there are no options and the 'workbench_access' variable has not been set
// then it seems that Workbench Access has not been configured.
if (empty($options) && !variable_get('workbench_access', FALSE)) {
@@ -1198,20 +1223,42 @@ function workbench_access_form_alter(&$form, $form_state, $form_id) {
'#options' => $options,
'#required' => TRUE,
'#default_value' => $default,
- '#description' => t('Select the proper editorial group for this content.'),
+ '#multiple' => variable_get('workbench_access_allow_multiple', 0),
+ '#description' => t('Select the proper editorial group(s) for this content.'),
);
// If the default is set and is not in the user's range, then pass hidden and
// display a message.
- // TODO: $default might legitimately be zero in some edge cases.
- if (!empty($default) && !isset($options[$default]) && isset($active['tree'][$default])) {
- $name = check_plain($active['tree'][$default]['name']);
- $element['#type'] = 'value';
- $element['#value'] = $element['#default_value'];
- $form['workbench_access']['message'] = array(
- '#type' => 'item',
- '#title' => t('Workbench access'),
- '#markup' => t('%title is assigned to the %section editorial group and may not be changed.', array('%title' => $form['#node']->title, '%section' => $name)),
- );
+ if (!empty($default)) {
+ $all = array();
+ $disallowed = array();
+ foreach ($default as $item) {
+ if (isset($active['tree'][$item]['name'])) {
+ $all[$active['tree'][$item]['access_id']] = check_plain($active['tree'][$item]['name']);
+ if (!isset($options[$item])) {
+ $disallowed[$active['tree'][$item]['access_id']] = check_plain($active['tree'][$item]['name']);
+ }
+ }
+ }
+ if (!empty($disallowed)) {
+ $diff = array_diff($all, $disallowed);
+ // TODO: If we toggle from single to multiple, then this can get messy.
+ if (empty($diff) || !variable_get('workbench_access_allow_multiple', 0)) {
+ $element['#type'] = 'value';
+ $element['#value'] = $element['#default_value'];
+ $form['workbench_access']['message'] = array(
+ '#type' => 'item',
+ '#title' => t('Workbench access'),
+ '#markup' => t('%title is assigned to the %section editorial group(s), which may not be changed.', array('%title' => $form['#node']->title, '%section' => implode(', ', $disallowed))),
+ );
+ }
+ else {
+ $form['workbench_access']['workbench_access_fixed'] = array(
+ '#type' => 'value',
+ '#value' => array_keys($disallowed),
+ );
+ $element['#description'] = $element['#description'] . '
' . t('%title is also assigned to the %section editorial group(s), which may not be changed.', array('%title' => $form['#node']->title, '%section' => implode(', ', $disallowed)));
+ }
+ }
}
workbench_access_alter_form('node_element', $element, $form_state);
$form['workbench_access']['workbench_access_id'] = $element;
@@ -1451,10 +1498,13 @@ function workbench_access_workbench_block() {
return array(t('Workbench Access: Unassigned'));
}
else {
+ $names = array();
$access_type = variable_get('workbench_access', 'taxonomy');
- $access_id = current($node->workbench_access);
- $section = workbench_access_load($access_type, $access_id);
- return array(t('Workbench Access: %section', array('%section' => $section['name'])));
+ foreach ($node->workbench_access as $access_id) {
+ $section = workbench_access_load($access_type, $access_id);
+ $names[] = check_plain($section['name']);
+ }
+ return array(t('Workbench Access: %section', array('%section' => implode(', ', $names))));
}
}
}
diff --git workbench_access.views.inc workbench_access.views.inc
index e23d067..5637ec1 100644
--- workbench_access.views.inc
+++ workbench_access.views.inc
@@ -24,7 +24,7 @@ function workbench_access_views_data() {
'help' => t('The section to which this node belongs.'),
'field' => array(
'handler' => 'workbench_access_handler_field_section',
- 'click sortable' => TRUE,
+ 'click sortable' => FALSE,
),
'sort' => array(
'handler' => 'workbench_access_handler_sort_section',