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

Move entry CRUD operations for entries to WPCOM_Liveblog_Entry #63

Merged
merged 17 commits into from
Dec 26, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions classes/class-wpcom-liveblog-entry-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ public function get_all( $args = array() ) {
return self::remove_replaced_entries( $this->get( $args ) );
}

public function get_by_id( $id ) {
$comment = get_comment( $id );
if ( $comment->comment_post_ID != $this->post_id || $comment->comment_type != $this->key || $comment->comment_approved != $this->key) {
return null;
}
$entries = self::entries_from_comments( array( $comment ) );
return $entries[0];
}

/**
* Get the latest liveblog entry
*
Expand Down
111 changes: 111 additions & 0 deletions classes/class-wpcom-liveblog-entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public function get_id() {
return $this->comment->comment_ID;
}

public function get_post_id() {
return $this->comment->comment_post_ID;
}

public function get_content() {
return $this->comment->comment_content;
}

/**
* Get the GMT timestamp for the comment
*
Expand Down Expand Up @@ -92,4 +100,107 @@ public static function render_content( $content, $comment ) {

return $content;
}

/**
* Inserts a new entry
*
* @param array $args The entry properties: content, post_id, user (current user object)
* @return WPCOM_Liveblog_Entry|WP_Error The newly inserted entry
*/
public static function insert( $args ) {
$comment = self::insert_comment( $args );
if ( is_wp_error( $comment ) ) {
return $comment;
}
do_action( 'liveblog_insert_entry', $comment->comment_ID, $args['post_id'] );
$entry = self::from_comment( $comment );
return $entry;
}

/**
* Updates an exsting entry
*
* Inserts a new entry, which replaces the original entry.
*
* @param array $args The entry properties: entry_id (which entry to update), content, post_id, user (current user object)
* @return WPCOM_Liveblog_Entry|WP_Error The newly inserted entry, which replaces the original
*/
public static function update( $args ) {
if ( !$args['entry_id'] ) {
return new WP_Error( 'entry-delete', __( 'Missing entry ID', 'liveblog' ) );
}
$comment = self::insert_comment( $args );
if ( is_wp_error( $comment ) ) {
return $comment;
}
do_action( 'liveblog_update_entry', $comment->comment_ID, $args['post_id'] );
add_comment_meta( $comment->comment_ID, self::replaces_meta_key, $args['entry_id'] );
wp_update_comment( array(
'comment_ID' => $args['entry_id'],
'comment_content' => wp_filter_post_kses( $args['content'] ),
) );
$entry = self::from_comment( $comment );
return $entry;
}

/**
* Deletes an existing entry
*
* Inserts a new entry, which replaces the original entry.
*
* @param array $args The entry properties: entry_id (which entry to delete), post_id, user (current user object)
* @return WPCOM_Liveblog_Entry|WP_Error The newly inserted entry, which replaces the original
*/
public static function delete( $args ) {
if ( !$args['entry_id'] ) {
return new WP_Error( 'entry-delete', __( 'Missing entry ID', 'liveblog' ) );
}
$args['content'] = '';
$comment = self::insert_comment( $args );
if ( is_wp_error( $comment ) ) {
return $comment;
}
do_action( 'liveblog_delete_entry', $comment->comment_ID, $args['post_id'] );
add_comment_meta( $comment->comment_ID, self::replaces_meta_key, $args['entry_id'] );
wp_delete_comment( $args['entry_id'] );
$entry = self::from_comment( $comment );
return $entry;
}

private static function insert_comment( $args ) {
$valid_args = self::validate_args( $args );
if ( is_wp_error( $valid_args ) ) {
return $valid_args;
}
$new_comment_id = wp_insert_comment( array(
'comment_post_ID' => $args['post_id'],
'comment_content' => wp_filter_post_kses( $args['content'] ),
'comment_approved' => 'liveblog',
'comment_type' => 'liveblog',
'user_id' => $args['user']->ID,

'comment_author' => $args['user']->display_name,
'comment_author_email' => $args['user']->user_email,
'comment_author_url' => $args['user']->user_url,
) );
wp_cache_delete( 'liveblog_entries_asc_' . $args['post_id'], 'liveblog' );
if ( empty( $new_comment_id ) || is_wp_error( $new_comment_id ) ) {
return new WP_Error( 'comment-insert', __( 'Error posting entry', 'liveblog' ) );
}
$comment = get_comment( $new_comment_id );
if ( !$comment ) {
return new WP_Error( 'get-comment', __( 'Error retrieving comment', 'liveblog' ) );
}
return $comment;
}

private static function validate_args( $args ) {
$required_keys = array( 'post_id', 'user', );
foreach( $required_keys as $key ) {
if ( !isset( $args[$key] ) || !$args[$key] ) {
return new WP_Error( 'entry-invalid-args', sprintf( __( 'Missing entry argument: %s', 'liveblog' ), $key ) );
}
}
return true;
}
}
13 changes: 6 additions & 7 deletions js/liveblog-publisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@
return;

var data = {
action: 'liveblog_insert_entry',
entry_content: entry_content,
crud_action: 'insert',
content: entry_content,
post_id: liveblog_settings.post_id
};

data[ liveblog_settings.nonce_key ] = liveblog.publisher.$nonce.val();
liveblog.publisher.disable_posting_interface();
liveblog.publisher.show_spinner();
liveblog.ajax_request( liveblog_settings.endpoint_url + 'insert', data, liveblog.publisher.insert_entry_success, liveblog.publisher.insert_entry_error, 'POST' );
liveblog.ajax_request( liveblog_settings.endpoint_url + 'crud', data, liveblog.publisher.insert_entry_success, liveblog.publisher.insert_entry_error, 'POST' );
};

liveblog.publisher.insert_entry_success = function( response, status, xhr ) {
Expand All @@ -105,15 +105,14 @@

liveblog.publisher.delete_entry = function( id ) {
var data = {
action: 'liveblog_insert_entry',
crud_action: 'delete',
post_id: liveblog_settings.post_id,
replaces: id,
entry_content: ''
entry_id: id,
};
data[ liveblog_settings.nonce_key ] = liveblog.publisher.$nonce.val();
liveblog.publisher.disable_posting_interface();
liveblog.publisher.show_spinner();
liveblog.ajax_request( liveblog_settings.endpoint_url + 'insert', data, liveblog.publisher.insert_entry_success, liveblog.publisher.insert_entry_error, 'POST' );
liveblog.ajax_request( liveblog_settings.endpoint_url + 'crud', data, liveblog.publisher.insert_entry_success, liveblog.publisher.insert_entry_error, 'POST' );
};

liveblog.publisher.disable_posting_interface = function() {
Expand Down
74 changes: 14 additions & 60 deletions liveblog.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ private static function add_actions() {
// flush the rewrite rules a lot later so that we don't interfere with other plugins using rewrite rules
add_action( 'init', array( __CLASS__, 'flush_rewrite_rules' ), 1000 );
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'wp_ajax_liveblog_insert_entry', array( __CLASS__, 'ajax_insert_entry' ) );
add_action( 'wp_ajax_liveblog_preview_entry', array( __CLASS__, 'ajax_preview_entry' ) );
}

Expand Down Expand Up @@ -193,7 +192,7 @@ private static function handle_ajax_request() {

$suffix_to_method = array(
'\d+/\d+' => 'ajax_entries_between',
'insert' => 'ajax_insert_entry',
'crud' => 'ajax_crud_entry',
'preview' => 'ajax_preview_entry',
);

Expand Down Expand Up @@ -342,72 +341,30 @@ private static function get_timestamps_from_query() {
return array_map( 'intval', $timestamps );
}

/**
* Inserts, updates, or deletes a liveblog entry
*/
public static function ajax_insert_entry() {

// Capability and Intention Checks
public static function ajax_crud_entry() {
self::ajax_current_user_can_edit_liveblog();
self::ajax_check_nonce();

// Check POST data
$post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
$replaces_comment_id = isset( $_POST['replaces'] ) ? intval( $_POST['replaces'] ) : 0;
$entry_content = isset( $_POST['entry_content'] ) ? $_POST['entry_content'] : '';

if ( empty( $post_id ) )
self::send_user_error( __( 'Sorry, that post is not accepting Liveblog entries.', 'liveblog' ) );
$args = array();

// Get the current user
$user = wp_get_current_user();

// Insert new comment
$new_comment_id = wp_insert_comment( array(
'comment_post_ID' => $post_id,
'comment_content' => wp_filter_post_kses( $entry_content ),
'comment_approved' => self::key,
'comment_type' => self::key,
'user_id' => $user->ID,

'comment_author' => $user->display_name,
'comment_author_email' => $user->user_email,
'comment_author_url' => $user->user_url,

// Borrowed from core as wp_insert_comment does not generate them
'comment_author_IP' => preg_replace( '/[^0-9a-fA-F:., ]/', '',$_SERVER['REMOTE_ADDR'] ),
'comment_agent' => substr( $_SERVER['HTTP_USER_AGENT'], 0, 254 ),
) );
wp_cache_delete( self::key . '_entries_asc_' . $post_id, 'liveblog' );
$crud_action = isset( $_POST['crud_action'] ) ? $_POST['crud_action'] : 0;

// Bail if comment could not be saved
if ( empty( $new_comment_id ) || is_wp_error( $new_comment_id ) )
self::send_server_error( __( 'Error posting entry', 'liveblog' ) );
if ( !in_array( $crud_action, array( 'insert', 'update', 'delete' ) ) ) {
self::send_user_error( sprintf( __( 'Invalid entry crud_action: %s', 'liveblog' ), $crud_action ) );
}

// Are we replacing an existing comment?
if ( !empty( $replaces_comment_id ) ) {
$args['post_id'] = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
$args['content'] = isset( $_POST['content'] ) ? $_POST['content'] : '';
$args['entry_id'] = isset( $_POST['entry_id'] ) ? intval( $_POST['entry_id'] ) : 0;

add_comment_meta( $new_comment_id, WPCOM_Liveblog_Entry::replaces_meta_key, $replaces_comment_id );
$args['user'] = wp_get_current_user();

// Update an existing comment
if ( !empty( $entry_content ) ) {
do_action( 'liveblog_update_entry', $replaces_comment_id, $new_comment_id, $post_id );
wp_update_comment( array(
'comment_ID' => $replaces_comment_id,
'comment_content' => wp_filter_post_kses( $entry_content ),
) );
$entry = call_user_func( array( 'WPCOM_Liveblog_Entry', $crud_action ), $args );

// Delete this comment
} else {
do_action( 'liveblog_delete_entry', $replaces_comment_id, $post_id );
wp_delete_comment( $replaces_comment_id );
}
} else {
do_action( 'liveblog_insert_entry', $new_comment_id, $post_id );
if ( is_wp_error( $entry ) ) {
self::send_server_error( $entry->get_error_message() );
}

$entry = WPCOM_Liveblog_Entry::from_comment( get_comment( $new_comment_id ) );

// Do not send latest_timestamp. If we send it the client won't get
// older entries. Since we send only the new one, we don't know if there
// weren't any entries in between.
Expand All @@ -418,9 +375,6 @@ public static function ajax_insert_entry() {
}

function ajax_preview_entry() {
self::ajax_current_user_can_edit_liveblog();
self::ajax_check_nonce();

$entry_content = isset( $_REQUEST['entry_content'] ) ? $_REQUEST['entry_content'] : '';
$entry_content = stripslashes( wp_filter_post_kses( $entry_content ) );
$entry_content = WPCOM_Liveblog_Entry::render_content( $entry_content );
Expand Down
11 changes: 11 additions & 0 deletions t/test-entry-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ function test_remove_replaced_entries_should_not_remove_entries_replacing_non_ex
$this->assertEquals( array( 1, 1000 ), $this->get_ids_from_entries( $filtered_entries ) );
}

function test_get_by_id_should_return_the_entry() {
$comment_id = $this->create_comment();
$this->assertEquals( $comment_id, $this->entry_query->get_by_id( $comment_id )->get_id() );
}

function test_get_by_id_should_not_return_entries_for_trashed_comments() {
$comment_id = $this->create_comment();
wp_delete_comment( $comment_id );
$this->assertNull( $this->entry_query->get_by_id( $comment_id ) );
}

private function create_comment( $args = array() ) {
$defaults = array(
'comment_post_ID' => $this->entry_query->post_id,
Expand Down
58 changes: 58 additions & 0 deletions t/test-entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,64 @@ function test_constructor_should_set_replaces_to_false_if_no_replace_meta() {
$this->assertTrue( !$entry->replaces );
}

function test_insert_should_return_entry() {
$entry = $this->insert_entry();
$this->assertInstanceOf( 'WPCOM_Liveblog_Entry', $entry );
}

function test_insert_should_fire_liveblog_insert_entry() {
unset( $GLOBALS['liveblog_hook_fired'] );
add_action( 'liveblog_insert_entry', function() { $GLOBALS['liveblog_hook_fired'] = true; } );
$this->insert_entry();
$this->assertTrue( isset( $GLOBALS['liveblog_hook_fired'] ) );
}

function test_update_should_replace_the_content_in_the_query() {
$entry = $this->insert_entry();
$update_entry = WPCOM_Liveblog_Entry::update( $this->build_entry_args( array( 'entry_id' => $entry->get_id(), 'content' => 'updated' ) ) );
$this->assertEquals( $entry->get_id(), $update_entry->replaces );
}

function test_update_should_fire_liveblog_update_entry() {
unset( $GLOBALS['liveblog_hook_fired'] );
add_action( 'liveblog_update_entry', function() { $GLOBALS['liveblog_hook_fired'] = true; } );
$entry = $this->insert_entry();
WPCOM_Liveblog_Entry::update( $this->build_entry_args( array( 'entry_id' => $entry->get_id(), 'content' => 'updated' ) ) );
$this->assertTrue( isset( $GLOBALS['liveblog_hook_fired'] ) );
}

function test_update_should_update_original_entry() {
$entry = $this->insert_entry();
$update_entry = WPCOM_Liveblog_Entry::update( $this->build_entry_args( array( 'entry_id' => $entry->get_id(), 'content' => 'updated' ) ) );
$query = new WPCOM_Liveblog_Entry_Query( $entry->get_post_id(), 'liveblog' );
$this->assertEquals( 'updated', $query->get_by_id( $entry->get_id() )->get_content() );
}

function test_delete_should_replace_the_content_in_the_query() {
$entry = $this->insert_entry();
$update_entry = WPCOM_Liveblog_Entry::delete( $this->build_entry_args( array( 'entry_id' => $entry->get_id()) ) );
$this->assertEquals( $entry->get_id(), $update_entry->replaces );
$this->assertEquals( '', $update_entry->get_content() );
}

function test_delete_should_delete_original_entry() {
$entry = $this->insert_entry();
$update_entry = WPCOM_Liveblog_Entry::delete( $this->build_entry_args( array( 'entry_id' => $entry->get_id() ) ) );
$query = new WPCOM_Liveblog_Entry_Query( $entry->get_post_id(), 'liveblog' );
$this->assertNull( $query->get_by_id( $entry->get_id() ) );
}

private function insert_entry( $args = array() ) {
$entry = WPCOM_Liveblog_Entry::insert( $this->build_entry_args( $args ) );
return $entry;
}

private function build_entry_args( $args = array() ) {
$user = $this->factory->user->create_and_get();
$defaults = array( 'post_id' => 1, 'content' => 'baba', 'user' => $user, );
return array_merge( $defaults, $args );
}

private function create_and_get_comment_with_replaces( $replaces, $args = array() ) {
$comment = $this->factory->comment->create_and_get( $args );
add_comment_meta( $comment->comment_ID, WPCOM_Liveblog_Entry::replaces_meta_key, $replaces );
Expand Down