diff options
-rw-r--r-- | includes/common.inc | 1 | ||||
-rw-r--r-- | misc/drupal.css | 31 | ||||
-rw-r--r-- | modules/node.module | 134 | ||||
-rw-r--r-- | modules/node/node.module | 134 | ||||
-rw-r--r-- | modules/taxonomy.module | 19 | ||||
-rw-r--r-- | modules/taxonomy/taxonomy.module | 19 | ||||
-rw-r--r-- | sites/default/settings.php | 3 |
7 files changed, 277 insertions, 64 deletions
diff --git a/includes/common.inc b/includes/common.inc index bc61140e9..f07df36af 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -1787,6 +1787,7 @@ include_once 'includes/menu.inc'; include_once 'includes/tablesort.inc'; include_once 'includes/file.inc'; include_once 'includes/xmlrpc.inc'; +include_once 'includes/js.inc'; // Set the Drupal custom error handler. set_error_handler('error_handler'); diff --git a/misc/drupal.css b/misc/drupal.css index edab0bb95..cdbed2f30 100644 --- a/misc/drupal.css +++ b/misc/drupal.css @@ -330,6 +330,37 @@ tr.light .form-item, tr.dark .form-item { #forum td.posts, #forum td.topics, #forum td.replies, #forum td.pager { text-align: center; } +#node-admin-filter { + list-style-type: none; + padding: 0px; + margin: 0px; +} +.node-admin-filter { + float: left; + margin-left: 1em; +} +html.js dl.js-multiselect dd .form-item { + display: none; +} +dl.js-multiselect dd, dl.js-multiselect .form-item, dl.js-multiselect select { + font-family: inherit; + font-size: inherit; + width: 15em; +} +dl.js-multiselect dt, dl.js-multiselect dd { + float: left; + line-height: 1.9em; + padding: 0px; + margin: 0px 1em 0px 0px; +} +dl.js-multiselect .form-item { + height: 1.9em; + margin: 0px; +} +#node-admin-update { + margin-top: 1.5em; + clear: left; +} #permissions td.module { font-weight: bold; } diff --git a/modules/node.module b/modules/node.module index c1fb09108..a3c048359 100644 --- a/modules/node.module +++ b/modules/node.module @@ -719,15 +719,12 @@ function node_menu($may_cache) { * Generate the content administration overview. */ function node_admin_nodes() { - $filters = array( - array(t('View posts that are new or updated'), 'ORDER BY n.changed DESC'), - array(t('View posts that need approval'), 'WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC'), - array(t('View posts that are promoted'), 'WHERE n.status = 1 AND n.promote = 1 ORDER BY n.changed DESC'), - array(t('View posts that are not promoted'), 'WHERE n.status = 1 AND n.promote = 0 ORDER BY n.changed DESC'), - array(t('View posts that are sticky'), 'WHERE n.status = 1 AND n.sticky = 1 ORDER BY n.changed DESC'), - array(t('View posts that are unpublished'), 'WHERE n.status = 0 AND n.moderate = 0 ORDER BY n.changed DESC') - ); + // Add Javascript for js-multiselect. + drupal_add_js(); + /* + ** Operations + */ $operations = array( array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'), array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d'), @@ -737,16 +734,6 @@ function node_admin_nodes() { ); // Handle operations: - if (empty($_SESSION['node_overview_filter'])) { - $_SESSION['node_overview_filter'] = 0; - } - - $op = $_POST['op']; - - if ($op == t('Filter') && isset($_POST['edit']['filter'])) { - $_SESSION['node_overview_filter'] = $_POST['edit']['filter']; - } - if ($op == t('Update') && isset($_POST['edit']['operation']) && isset($_POST['edit']['status'])) { $operation = $operations[$_POST['edit']['operation']][1]; foreach ($_POST['edit']['status'] as $nid => $value) { @@ -758,42 +745,125 @@ function node_admin_nodes() { drupal_set_message(t('The update has been performed.')); } - $filter = $_SESSION['node_overview_filter']; + /* + ** Filters + */ + $node_types = drupal_map_assoc(node_list()); + foreach ($node_types as $k => $v) { + $node_types[$k] = node_invoke($v, 'node_name'); + } + // Merge all vocabularies into one for retrieving $value below + $taxonomy = taxonomy_form_all(); + $terms = array(); + foreach ($taxonomy as $key => $value) { + $terms = $terms + $value; + } + $filters = array( + 'type' => array('title' => t('type'), 'where' => "n.type = '%s'", + 'options' => $node_types), + 'publish' => array('title' => t('published status'), 'where' => 'n.status = %d', + 'options' => array(1 => t('published'), 0 => t('not published'))), + 'moderate' => array('title' => t('moderation status'), 'where' => 'n.moderate = %d', + 'options' => array(1 => t('in moderation'), 0 => t('not in moderation'))), + 'promote' => array('title' => t('promotion status'), 'where' => 'n.promote = %d', + 'options' => array(1 => t('promoted'), 0 => t('not promoted'))), + 'sticky' => array('title' => t('sticky status'), 'where' => 'n.sticky = %d', + 'options' => array(1 => t('sticky'), 0 => t('not sticky'))), + 'category' => array('title' => t('category'), 'where' => 'tn.tid = %d', + 'options' => $terms, 'join' => 'INNER JOIN {term_node} tn ON n.nid = tn.nid')); + + // Initialize/reset filters + $op = $_POST['op']; + if (empty($_SESSION['node_overview_filter']) || $op == t('Reset')) { + $_SESSION['node_overview_filter'] = array(); + } + $session = &$_SESSION['node_overview_filter']; + $filter = $_POST['edit']['filter']; + // Add filter to list + if (($op == t('Filter') || $op == t('Refine')) && isset($filter) && isset($filters[$filter])) { + $session[$filter] = $_POST['edit'][$filter]; + } + // Remove filter from list + if ($op == t('Undo')) { + array_pop($session); + } - // Render filter form: + // Existing filters + $output = '<ul id="node-admin-filter">'; + $i = 0; + foreach ($session as $type => $value) { + $params = array('%a' => '<strong>'. $filters[$type]['title'] .'</strong>', '%b' => '<strong>'. $filters[$type]['options'][$value] .'</strong>'); + $output .= '<li>'. ($i++ ? t('<em>and</em> items where %a is %b', $params) : t('Show only items where %a is %b', $params)) .'</li>'; + } + + // New filter + $filters['category']['options'] = $taxonomy; + $values = ''; $options = array(); foreach ($filters as $key => $value) { - $options[] = $value[0]; + if (!isset($session[$key])) { + $options[$key] = $value['title']; + $b .= form_select('', $key, 1, $filters[$key]['options']); + } } + $buttons = ''; + if (count($options)) { + $output .= '<li><dl class="js-multiselect">'; + $a = ''; + foreach ($options as $key => $value) { + $a .= form_radio($value, 'filter', $key); + } + if (!$i) { + $output .= t('<dt>Show only items where</dt> <dd>%a</dd> <dt>is</dt> <dd>%b</dd>', array('%a' => $a, '%b' => $b)); + } + else { + $output .= t('<dt>and items where</dt> <dd>%a</dd> <dt>is</dt> <dd>%b</dd>', array('%a' => $a, '%b' => $b)); + } + $output .= '</dl>'; + $buttons = form_submit(count($session) ? t('Refine') : t('Filter')); + } + if (count($session)) { + $buttons .= form_submit(t('Undo')) . form_submit(t('Reset')); + } + $output .= '<div class="container-inline node-admin-filter">'. $buttons .'</div>'; + $output .= '</li></ul>'; - $form = form_select(NULL, 'filter', $filter, $options); - $form .= form_submit(t('Filter')); - - $output .= '<h3>'. t('Filter options') .'</h3>'; - $output .= "<div class=\"container-inline\">$form</div>"; - - // Render operations form: - $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid '. $filters[$filter][1], 50); + // Build query + $where = $args = array(); + $join = ''; + foreach ($session as $key => $value) { + $where[] = $filters[$key]['where']; + $join .= $filters[$key]['join']; + $args[] = $value; + } + $where = count($where) ? 'WHERE '. implode(' AND ', $where) : ''; + $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n '. $join .' INNER JOIN {users} u ON n.uid = u.uid '. $where, 50, 0, NULL, $args); // Make sure the update controls are disabled if we don't have any rows to select from. $disabled = !db_num_rows($result); + // Output operations form $options = array(); foreach ($operations as $key => $value) { $options[] = $value[0]; } - $form = form_select(NULL, 'operation', 0, $options, NULL, ($disabled ? 'disabled="disabled"' : '')); $form .= form_submit(t('Update'), 'op', ($disabled ? array('disabled' => 'disabled') : array())); - $output .= '<h3>'. t('Update options') .'</h3>'; + $output .= '<h3 id="node-admin-update">'. t('Update options') .'</h3>'; $output .= "<div class=\"container-inline\">$form</div>"; // Overview table: $header = array(NULL, t('Title'), t('Type'), t('Author'), t('Status'), array('data' => t('Operations'), 'colspan' => '2')); while ($node = db_fetch_object($result)) { - $rows[] = array(form_checkbox(NULL, 'status]['. $node->nid, 1, 0), l($node->title, 'node/'. $node->nid) .' '. (node_is_new($node->nid, $node->changed) ? theme_mark() : ''), node_invoke($node, 'node_name'), format_name($node), ($node->status ? t('published') : t('not published')), l(t('edit'), 'node/'. $node->nid .'/edit'), l(t('delete'), 'admin/node/delete/'. $node->nid)); + $rows[] = array(form_checkbox(NULL, 'status]['. $node->nid, 1, 0), + l($node->title, 'node/'. $node->nid) .' '. (node_is_new($node->nid, $node->changed) ? theme_mark() : ''), + node_invoke($node, 'node_name'), + format_name($node), + ($node->status ? t('published') : t('not published')), + l(t('edit'), 'node/'. $node->nid .'/edit'), + l(t('delete'), 'admin/node/delete/'. $node->nid)); } if ($pager = theme('pager', NULL, 50, 0)) { diff --git a/modules/node/node.module b/modules/node/node.module index c1fb09108..a3c048359 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -719,15 +719,12 @@ function node_menu($may_cache) { * Generate the content administration overview. */ function node_admin_nodes() { - $filters = array( - array(t('View posts that are new or updated'), 'ORDER BY n.changed DESC'), - array(t('View posts that need approval'), 'WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC'), - array(t('View posts that are promoted'), 'WHERE n.status = 1 AND n.promote = 1 ORDER BY n.changed DESC'), - array(t('View posts that are not promoted'), 'WHERE n.status = 1 AND n.promote = 0 ORDER BY n.changed DESC'), - array(t('View posts that are sticky'), 'WHERE n.status = 1 AND n.sticky = 1 ORDER BY n.changed DESC'), - array(t('View posts that are unpublished'), 'WHERE n.status = 0 AND n.moderate = 0 ORDER BY n.changed DESC') - ); + // Add Javascript for js-multiselect. + drupal_add_js(); + /* + ** Operations + */ $operations = array( array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'), array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d'), @@ -737,16 +734,6 @@ function node_admin_nodes() { ); // Handle operations: - if (empty($_SESSION['node_overview_filter'])) { - $_SESSION['node_overview_filter'] = 0; - } - - $op = $_POST['op']; - - if ($op == t('Filter') && isset($_POST['edit']['filter'])) { - $_SESSION['node_overview_filter'] = $_POST['edit']['filter']; - } - if ($op == t('Update') && isset($_POST['edit']['operation']) && isset($_POST['edit']['status'])) { $operation = $operations[$_POST['edit']['operation']][1]; foreach ($_POST['edit']['status'] as $nid => $value) { @@ -758,42 +745,125 @@ function node_admin_nodes() { drupal_set_message(t('The update has been performed.')); } - $filter = $_SESSION['node_overview_filter']; + /* + ** Filters + */ + $node_types = drupal_map_assoc(node_list()); + foreach ($node_types as $k => $v) { + $node_types[$k] = node_invoke($v, 'node_name'); + } + // Merge all vocabularies into one for retrieving $value below + $taxonomy = taxonomy_form_all(); + $terms = array(); + foreach ($taxonomy as $key => $value) { + $terms = $terms + $value; + } + $filters = array( + 'type' => array('title' => t('type'), 'where' => "n.type = '%s'", + 'options' => $node_types), + 'publish' => array('title' => t('published status'), 'where' => 'n.status = %d', + 'options' => array(1 => t('published'), 0 => t('not published'))), + 'moderate' => array('title' => t('moderation status'), 'where' => 'n.moderate = %d', + 'options' => array(1 => t('in moderation'), 0 => t('not in moderation'))), + 'promote' => array('title' => t('promotion status'), 'where' => 'n.promote = %d', + 'options' => array(1 => t('promoted'), 0 => t('not promoted'))), + 'sticky' => array('title' => t('sticky status'), 'where' => 'n.sticky = %d', + 'options' => array(1 => t('sticky'), 0 => t('not sticky'))), + 'category' => array('title' => t('category'), 'where' => 'tn.tid = %d', + 'options' => $terms, 'join' => 'INNER JOIN {term_node} tn ON n.nid = tn.nid')); + + // Initialize/reset filters + $op = $_POST['op']; + if (empty($_SESSION['node_overview_filter']) || $op == t('Reset')) { + $_SESSION['node_overview_filter'] = array(); + } + $session = &$_SESSION['node_overview_filter']; + $filter = $_POST['edit']['filter']; + // Add filter to list + if (($op == t('Filter') || $op == t('Refine')) && isset($filter) && isset($filters[$filter])) { + $session[$filter] = $_POST['edit'][$filter]; + } + // Remove filter from list + if ($op == t('Undo')) { + array_pop($session); + } - // Render filter form: + // Existing filters + $output = '<ul id="node-admin-filter">'; + $i = 0; + foreach ($session as $type => $value) { + $params = array('%a' => '<strong>'. $filters[$type]['title'] .'</strong>', '%b' => '<strong>'. $filters[$type]['options'][$value] .'</strong>'); + $output .= '<li>'. ($i++ ? t('<em>and</em> items where %a is %b', $params) : t('Show only items where %a is %b', $params)) .'</li>'; + } + + // New filter + $filters['category']['options'] = $taxonomy; + $values = ''; $options = array(); foreach ($filters as $key => $value) { - $options[] = $value[0]; + if (!isset($session[$key])) { + $options[$key] = $value['title']; + $b .= form_select('', $key, 1, $filters[$key]['options']); + } } + $buttons = ''; + if (count($options)) { + $output .= '<li><dl class="js-multiselect">'; + $a = ''; + foreach ($options as $key => $value) { + $a .= form_radio($value, 'filter', $key); + } + if (!$i) { + $output .= t('<dt>Show only items where</dt> <dd>%a</dd> <dt>is</dt> <dd>%b</dd>', array('%a' => $a, '%b' => $b)); + } + else { + $output .= t('<dt>and items where</dt> <dd>%a</dd> <dt>is</dt> <dd>%b</dd>', array('%a' => $a, '%b' => $b)); + } + $output .= '</dl>'; + $buttons = form_submit(count($session) ? t('Refine') : t('Filter')); + } + if (count($session)) { + $buttons .= form_submit(t('Undo')) . form_submit(t('Reset')); + } + $output .= '<div class="container-inline node-admin-filter">'. $buttons .'</div>'; + $output .= '</li></ul>'; - $form = form_select(NULL, 'filter', $filter, $options); - $form .= form_submit(t('Filter')); - - $output .= '<h3>'. t('Filter options') .'</h3>'; - $output .= "<div class=\"container-inline\">$form</div>"; - - // Render operations form: - $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid '. $filters[$filter][1], 50); + // Build query + $where = $args = array(); + $join = ''; + foreach ($session as $key => $value) { + $where[] = $filters[$key]['where']; + $join .= $filters[$key]['join']; + $args[] = $value; + } + $where = count($where) ? 'WHERE '. implode(' AND ', $where) : ''; + $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n '. $join .' INNER JOIN {users} u ON n.uid = u.uid '. $where, 50, 0, NULL, $args); // Make sure the update controls are disabled if we don't have any rows to select from. $disabled = !db_num_rows($result); + // Output operations form $options = array(); foreach ($operations as $key => $value) { $options[] = $value[0]; } - $form = form_select(NULL, 'operation', 0, $options, NULL, ($disabled ? 'disabled="disabled"' : '')); $form .= form_submit(t('Update'), 'op', ($disabled ? array('disabled' => 'disabled') : array())); - $output .= '<h3>'. t('Update options') .'</h3>'; + $output .= '<h3 id="node-admin-update">'. t('Update options') .'</h3>'; $output .= "<div class=\"container-inline\">$form</div>"; // Overview table: $header = array(NULL, t('Title'), t('Type'), t('Author'), t('Status'), array('data' => t('Operations'), 'colspan' => '2')); while ($node = db_fetch_object($result)) { - $rows[] = array(form_checkbox(NULL, 'status]['. $node->nid, 1, 0), l($node->title, 'node/'. $node->nid) .' '. (node_is_new($node->nid, $node->changed) ? theme_mark() : ''), node_invoke($node, 'node_name'), format_name($node), ($node->status ? t('published') : t('not published')), l(t('edit'), 'node/'. $node->nid .'/edit'), l(t('delete'), 'admin/node/delete/'. $node->nid)); + $rows[] = array(form_checkbox(NULL, 'status]['. $node->nid, 1, 0), + l($node->title, 'node/'. $node->nid) .' '. (node_is_new($node->nid, $node->changed) ? theme_mark() : ''), + node_invoke($node, 'node_name'), + format_name($node), + ($node->status ? t('published') : t('not published')), + l(t('edit'), 'node/'. $node->nid .'/edit'), + l(t('delete'), 'admin/node/delete/'. $node->nid)); } if ($pager = theme('pager', NULL, 50, 0)) { diff --git a/modules/taxonomy.module b/modules/taxonomy.module index caa3fa1fe..c30032355 100644 --- a/modules/taxonomy.module +++ b/modules/taxonomy.module @@ -389,6 +389,25 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') { } /** +* Generate a set of options for selecting a term from all vocabularies. Can be +* passed to form_select. +*/ +function taxonomy_form_all($value = 0, $help = NULL, $name = 'taxonomy') { + $vocabularies = taxonomy_get_vocabularies(); + $options = array(); + foreach ($vocabularies as $vid => $vocabulary) { + $tree = taxonomy_get_tree($vid); + $options[$vocabulary->name] = array(); + if ($tree) { + foreach ($tree as $term) { + $options[$vocabulary->name][$term->tid] = _taxonomy_depth($term->depth, '-') . $term->name; + } + } + } + return $options; +} + +/** * Return an array of all vocabulary objects. * * @param $type diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module index caa3fa1fe..c30032355 100644 --- a/modules/taxonomy/taxonomy.module +++ b/modules/taxonomy/taxonomy.module @@ -389,6 +389,25 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') { } /** +* Generate a set of options for selecting a term from all vocabularies. Can be +* passed to form_select. +*/ +function taxonomy_form_all($value = 0, $help = NULL, $name = 'taxonomy') { + $vocabularies = taxonomy_get_vocabularies(); + $options = array(); + foreach ($vocabularies as $vid => $vocabulary) { + $tree = taxonomy_get_tree($vid); + $options[$vocabulary->name] = array(); + if ($tree) { + foreach ($tree as $term) { + $options[$vocabulary->name][$term->tid] = _taxonomy_depth($term->depth, '-') . $term->name; + } + } + } + return $options; +} + +/** * Return an array of all vocabulary objects. * * @param $type diff --git a/sites/default/settings.php b/sites/default/settings.php index 5df0b0ba3..365d4fd68 100644 --- a/sites/default/settings.php +++ b/sites/default/settings.php @@ -47,6 +47,9 @@ $base_url = "http://localhost"; # the .htaccesss file in Drupal's root directory. If you get # unexpected warnings or errors, double-check your PHP settings. +# If required, update PHP's include path to include your PEAR directory: +// ini_set("include_path", ".:/path/to/pear"); + # # Variable overrides: # |