Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 484 - Combine Connectors and Contexts into a single column #537

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c3ad7bc
Rename some variables
May 8, 2014
2b89941
Explicitly link contexts to connectors
May 8, 2014
528c0ac
Add parent / child option support, and add connectors as parents to t…
May 8, 2014
20e0279
Remove sorting, we can do sort later
May 8, 2014
c6bbc92
Remove empty connectors from the context menu
May 8, 2014
e4fe942
Choose connectors or contexts from the contexts menu
May 9, 2014
cf78ce8
Convert if logic to switch statement
May 9, 2014
f62ab59
Fixed a couple of small bugs
May 13, 2014
bedfa00
Better optgroups.
May 14, 2014
0634271
Change switch statement to if else
May 14, 2014
fdf9ffa
Merge branch 'develop' into issue-484
May 15, 2014
9699974
Merge branch 'develop' into issue-484
May 15, 2014
35d29de
Remove stream_context table
May 15, 2014
1110f99
More major context table changes, including an update script
May 16, 2014
0f2d0f7
Fix errors
May 16, 2014
9ef5b84
Revert to 9699974
May 16, 2014
e2c8958
List table changes to group connectors with contexts
May 18, 2014
f8e6d0a
Better args for filter_select
May 18, 2014
3d528c1
Remove js relating to optgroups
May 18, 2014
ff54cdb
Remove more js relating to optgroups
May 18, 2014
7b57177
Remove sites from connectors if not in network admin
May 18, 2014
54d4c84
Space police
May 18, 2014
5e9b200
Merge branch 'develop' into issue-484-select-ui-only
frankiejarrett May 20, 2014
18b1dd4
Maintain separate query args for connector and context in list table
frankiejarrett May 20, 2014
07abd2f
Modify query based on nested level of context selection
frankiejarrett May 20, 2014
f8ffb67
Code formatting
frankiejarrett May 20, 2014
851d5ff
More JS code formatting for Travis
frankiejarrett May 20, 2014
f902e63
Try defining vars one line at a time
frankiejarrett May 20, 2014
4ecb17d
Use singlequotes in strings
frankiejarrett May 20, 2014
2461cf4
Add missing semicolon
frankiejarrett May 20, 2014
1e56427
Fix selection bug when connector and context name match
frankiejarrett May 20, 2014
539d24f
Don't automagically hide the Connector in the context column
frankiejarrett May 20, 2014
6555b6a
Fix context query when js is disabled
May 21, 2014
9d1c548
Fix other filters inheriting context, make filter_select context unaware
May 21, 2014
cb5466f
small fix for error in last commit
May 21, 2014
14efe8b
Javascript formatting
May 21, 2014
dc80669
Better context dropdown results with javascript disabled
May 21, 2014
a82feb8
JS formatting
May 21, 2014
1fe78a8
Some minor code formatting
May 21, 2014
a2d6a28
Merge branch 'develop' into issue-484-select-ui-only
frankiejarrett May 22, 2014
9138e19
Prefixed jquery extension
May 22, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions includes/connectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
class WP_Stream_Connectors {

/**
* Contexts registered
* Connectors registered
* @var array
*/
public static $connectors = array();

/**
* Contexts registered to Connectors
* @var array
*/
public static $contexts = array();

/**
* Action taxonomy terms
* Holds slug to -localized- label association
Expand Down Expand Up @@ -36,7 +42,6 @@ public static function load() {
require_once WP_STREAM_INC_DIR . 'connector.php';

$connectors = array(
'blogs',
'comments',
'editor',
'installer',
Expand All @@ -48,6 +53,11 @@ public static function load() {
'users',
'widgets',
);

if ( is_network_admin() ) {
$connectors[] = 'blogs';
}

$classes = array();
foreach ( $connectors as $connector ) {
include_once WP_STREAM_DIR . '/connectors/' . $connector .'.php';
Expand Down Expand Up @@ -118,6 +128,9 @@ public static function load() {
$connector::register();
}

// Link context labels to their connector
self::$contexts[ $connector::$name ] = $connector::get_context_labels();

// Add new terms to our label lookup array
self::$term_labels['stream_action'] = array_merge(
self::$term_labels['stream_action'],
Expand Down
144 changes: 111 additions & 33 deletions includes/list-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,13 @@ function get_columns(){
return apply_filters(
'wp_stream_list_table_columns',
array(
'date' => __( 'Date', 'default' ),
'summary' => __( 'Summary', 'default' ),
'author' => __( 'Author', 'default' ),
'connector' => __( 'Connector', 'stream' ),
'context' => __( 'Context', 'stream' ),
'action' => __( 'Action', 'stream' ),
'ip' => __( 'IP Address', 'stream' ),
'id' => __( 'Record ID', 'stream' ),
'date' => __( 'Date', 'default' ),
'summary' => __( 'Summary', 'default' ),
'author' => __( 'Author', 'default' ),
'context' => __( 'Context', 'stream' ),
'action' => __( 'Action', 'stream' ),
'ip' => __( 'IP Address', 'stream' ),
'id' => __( 'Record ID', 'stream' ),
)
);
}
Expand Down Expand Up @@ -160,6 +159,11 @@ function get_records() {
}
$args['paged'] = $this->get_pagenum();

if ( isset( $args['context'] ) && 0 === strpos( $args['context'], 'connector-' ) ) {
$args['connector'] = str_replace( 'connector-', '', $args['context'] );
$args['context'] = '';
}

if ( ! isset( $args['records_per_page'] ) ) {
$args['records_per_page'] = $this->get_items_per_page( 'edit_stream_per_page', 20 );
}
Expand All @@ -183,7 +187,7 @@ function column_default( $item, $column_name ) {
$item->created,
get_date_from_gmt( $item->created, 'Y/m/d' )
);
$out = $this->column_link( $date_string, 'date', date( 'Y/m/d', strtotime( $item->created ) ) );
$out = $this->column_link( $date_string, 'date', date( 'Y/m/d', strtotime( $item->created ) ) );
$out .= '<br />';
$out .= get_date_from_gmt( $item->created, 'h:i:s A' );
break;
Expand Down Expand Up @@ -221,8 +225,21 @@ function column_default( $item, $column_name ) {
);
break;

case 'connector':
case 'context':
$connector_title = $this->get_term_title( $item->{'connector'}, 'connector' );
$context_title = $this->get_term_title( $item->{'context'}, 'context' );

$out = $this->column_link( $connector_title, 'connector', $item->{'connector'} );
$out .= '<br />&#8627;&nbsp;';
$out .= $this->column_link(
$context_title,
array(
'connector' => $item->{'connector'},
'context' => $item->{'context'},
)
);
break;

case 'action':
$out = $this->column_link( $this->get_term_title( $item->{$column_name}, $column_name ), $column_name, $item->{$column_name} );
break;
Expand Down Expand Up @@ -363,8 +380,7 @@ function column_link( $display, $key, $value = null, $title = null ) {
public function get_term_title( $term, $type ) {
if ( isset( WP_Stream_Connectors::$term_labels[ "stream_$type" ][ $term ] ) ) {
return WP_Stream_Connectors::$term_labels[ "stream_$type" ][ $term ];
}
else {
} else {
return $term;
}
}
Expand Down Expand Up @@ -496,11 +512,6 @@ public function get_filters() {
'ajax' => count( $authors_records ) <= 0,
);

$filters['connector'] = array(
'title' => __( 'connectors', 'stream' ),
'items' => $this->assemble_records( 'connector' ),
);

$filters['context'] = array(
'title' => __( 'contexts', 'stream' ),
'items' => $this->assemble_records( 'context' ),
Expand Down Expand Up @@ -530,15 +541,38 @@ function filters_form() {

$filters = $this->get_filters();

$filters_string = sprintf( '<input type="hidden" name="page" value="%s"/>', 'wp_stream' );
$filters_string = sprintf( '<input type="hidden" name="page" value="%s" />', 'wp_stream' );
$filters_string .= sprintf( __( '%1$sShow filter controls via the screen options tab above%2$s', 'stream' ), '<span class="filter_info" style="display:none">', '</span>' );

foreach ( $filters as $name => $data ) {
if ( 'date' === $name ) {
$filters_string .= $this->filter_date( $data['items'] );
continue;
} else {
if ( 'context' === $name ) {
// Add Connectors as parents, and apply the Contexts as children
$connectors = $this->assemble_records( 'connector' );
foreach ( $connectors as $connector => $item ) {
$context_items[ $connector ]['label'] = $item['label'];
foreach ( $data['items'] as $context_value => $context_item ) {
if ( isset( WP_Stream_Connectors::$contexts[ $connector ] ) && array_key_exists( $context_value, WP_Stream_Connectors::$contexts[ $connector ] ) ) {
$context_items[ $connector ]['children'][ $context_value ] = $context_item;
}
}
}

foreach ( $context_items as $context_value => $context_item ) {
if ( ! isset( $context_item['children'] ) || empty( $context_item['children'] ) ) {
unset( $context_items[ $context_value ] );
}
}

$data['items'] = $context_items;

// Ouput a hidden input to handle the connector value
$filters_string .= '<input type="hidden" name="connector" class="record-filter-connector" />';
}
$filters_string .= $this->filter_select( $name, $data['title'], $data['items'] );
}
$filters_string .= $this->filter_select( $name, $data['title'], isset( $data['items'] ) ? $data['items'] : array(), isset( $data['ajax'] ) && $data['ajax'] );
}

$filters_string .= sprintf( '<input type="submit" id="record-query-submit" class="button" value="%s">', __( 'Filter', 'default' ) );
Expand All @@ -548,28 +582,46 @@ function filters_form() {
printf( '<div class="alignleft actions">%s</div>', $filters_string ); // xss ok
}

function filter_select( $name, $title, $items, $ajax ) {

function filter_select( $name, $title, $items, $ajax = false ) {
if ( $ajax ) {
$out = sprintf(
'<input type="hidden" name="%s" class="chosen-select" value="%s" data-placeholder="%s"/>',
esc_attr( $name ),
esc_attr( wp_stream_filter_input( INPUT_GET, $name ) ),
esc_html( $title )
esc_attr( $title )
);
} else {
$options = array( '<option value=""></option>' );
$selected = wp_stream_filter_input( INPUT_GET, $name );
foreach ( $items as $v => $label ) {
$options[] = sprintf(
'<option value="%s" %s %s %s title="%s">%s</option>',
$v,
selected( $v, $selected, false ),
isset( $label['disabled'] ) ? $label['disabled'] : '', // xss ok
isset( $label['icon'] ) ? sprintf( ' data-icon="%s"', esc_attr( $label['icon'] ) ) : '',
isset( $label['tooltip'] ) ? esc_attr( $label['tooltip'] ) : '',
$label['label']
foreach ( $items as $key => $item ) {
$value = isset( $item['children'] ) ? 'group-' . $key : $key;
$option_args = array(
'value' => $value,
'selected' => selected( $value, $selected, false ),
'disabled' => isset( $item['disabled'] ) ? $item['disabled'] : null,
'icon' => isset( $item['icon'] ) ? $item['icon'] : null,
'group' => isset( $item['children'] ) ? $key : null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukecarbis Is this dependent on there being children or shouldn't top level items always be classified as groups?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's 6 vs ½ × 12.

I think it makes the dom a bit cleaner to leave data-group out where it's not needed. I'm not that fussed though, if you wanted to change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK we'll just leave as-is.

'tooltip' => isset( $item['tooltip'] ) ? $item['tooltip'] : null,
'class' => isset( $item['children'] ) ? 'level-1' : null,
'label' => isset( $item['label'] ) ? $item['label'] : null,
);
$options[] = $this->filter_option( $option_args );

if ( isset( $item['children'] ) ) {
foreach ( $item['children'] as $child_value => $child_item ) {
$option_args = array(
'value' => $child_value,
'selected' => selected( $child_value, $selected, false ),
'disabled' => isset( $child_item['disabled'] ) ? $child_item['disabled'] : null,
'icon' => isset( $child_item['icon'] ) ? $child_item['icon'] : null,
'group' => $key,
'tooltip' => isset( $child_item['tooltip'] ) ? $child_item['tooltip'] : null,
'class' => 'level-2',
'label' => isset( $child_item['label'] ) ? '- ' . $child_item['label'] : null,
);
$options[] = $this->filter_option( $option_args );
}
}
}
$out = sprintf(
'<select name="%s" class="chosen-select" data-placeholder="%s">%s</select>',
Expand All @@ -582,6 +634,32 @@ function filter_select( $name, $title, $items, $ajax ) {
return $out;
}

function filter_option( $args ) {
$defaults = array(
'value' => null,
'selected' => null,
'disabled' => null,
'icon' => null,
'group' => null,
'tooltip' => null,
'class' => null,
'label' => null,
);
wp_parse_args( $args, $defaults );

return sprintf(
'<option value="%s" %s %s %s %s %s class="%s">%s</option>',
esc_attr( $args['value'] ),
$args['selected'],
$args['disabled'],
$args['icon'] ? sprintf( 'data-icon="%s"', esc_attr( $args['icon'] ) ) : null,
$args['group'] ? sprintf( 'data-group="%s"', esc_attr( $args['group'] ) ) : null,
$args['tooltip'] ? sprintf( 'title="%s"', esc_attr( $args['tooltip'] ) ) : null,
$args['class'] ? esc_attr( $args['class'] ) : null,
esc_html( $args['label'] )
);
}

function filter_search() {
$out = sprintf(
'<p class="search-box">
Expand Down Expand Up @@ -656,7 +734,7 @@ class="date-picker field-to"
function display() {
$url = self_admin_url( WP_Stream_Admin::ADMIN_PARENT_PAGE );

echo '<form method="get" action="' . esc_url( $url ) . '">';
echo '<form method="get" action="' . esc_url( $url ) . '" id="record-filter-form">';
echo $this->filter_search(); // xss ok

parent::display();
Expand Down
8 changes: 8 additions & 0 deletions ui/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,14 @@
margin-bottom: 1px;
}

.wp_stream_screen li.select2-result.level-1 {
font-weight: bold;
}

.wp_stream_screen li.select2-result.level-2 {
padding-left: 1em;
}

.wp_stream_screen .select2-results .select2-disabled {
background: transparent;
color: #aaa;
Expand Down
42 changes: 40 additions & 2 deletions ui/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ jQuery(function($){
$elem = $(record.element),
icon = '';

if ( '- ' === record.text.substring( 0, 2 ) ) {
record.text = record.text.substring( 2 );
}

if ( undefined !== record.icon ) {
icon = record.icon;
} else if ( undefined !== $elem.attr('data-icon') ) {
Expand All @@ -23,12 +27,18 @@ jQuery(function($){
container.attr('title', $elem.attr('title'));

return result;
},
formatSelection = function( record ) {
if ( '- ' === record.text.substring( 0, 2 ) ) {
record.text = record.text.substring( 2 );
}
return record.text;
};

if ( $(el).find('option').length > 0 ) {
args = {
minimumResultsForSearch: 10,
formatResult: formatResult,
formatSelection: formatSelection,
allowClear: true,
width: '165px'
};
Expand All @@ -52,6 +62,7 @@ jQuery(function($){
}
},
formatResult: formatResult,
formatSelection: formatSelection,
initSelection: function (element, callback) {
var id = $(element).val();
if(id !== '') {
Expand All @@ -75,7 +86,28 @@ jQuery(function($){
};
}

$(el).select2( args );
$( el ).select2( args );
});

var $queryVars = $.getQueryParameters();
var $contextInput = $( '.toplevel_page_wp_stream :input.chosen-select[name=context]' );

if ( ( 'undefined' === typeof $queryVars.context || '' === $queryVars.context ) && 'undefined' !== typeof $queryVars.connector ) {
$contextInput.select2( 'val', 'group-' + $queryVars.connector );
}

$('#record-filter-form').submit( function() {
var $context = $( '.toplevel_page_wp_stream :input.chosen-select[name=context]' ),
$option = $context.find( 'option:selected' ),
$connector = $context.parent().find( '.record-filter-connector' ),
optionConnector = $option.data( 'group' ),
optionClass = $option.prop( 'class' );

$connector.val( optionConnector );

if ( 'level-1' === optionClass ) {
$option.val('');
}
});

var stream_select2_change_handler = function (e, input) {
Expand Down Expand Up @@ -756,3 +788,9 @@ jQuery(function($){
intervals.init( $('.date-interval') );
});
});

jQuery.extend({
getQueryParameters : function( str ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukecarbis Do you think we should prefix this function name?

Copy pasta straight from: http://css-tricks.com/snippets/jquery/get-query-params-object/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Good pickup.

return (str || document.location.search).replace(/(^\?)/,'').split('&').map(function(n){return n = n.split('='),this[n[0]] = n[1],this;}.bind({}))[0];
}
});