diff --git a/assets/css/admin-pull-table.scss b/assets/css/admin-pull-table.scss index a5d37a417..6c22b64cb 100644 --- a/assets/css/admin-pull-table.scss +++ b/assets/css/admin-pull-table.scss @@ -18,6 +18,28 @@ padding-left: 10px; } } + + #distributor-pull-modal{ + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: rgba(0, 0, 0, 50%); + display: flex; + align-items: center; + z-index: 9999; + + &>div{ + margin: 0 auto; + display: block; + width: 300px; + background: white; + padding: 20px; + border-radius: 10px; + box-shadow: 1px 2px 15px rgba(0, 0, 0, 30%); + } + } } .wp-list-table .disabled { diff --git a/assets/js/admin-pull.js b/assets/js/admin-pull.js index 4488187a4..b3474306a 100755 --- a/assets/js/admin-pull.js +++ b/assets/js/admin-pull.js @@ -1,7 +1,6 @@ import '../css/admin-pull-table.scss'; import jQuery from 'jquery'; -import { addQueryArgs } from '@wordpress/url'; import { __ } from '@wordpress/i18n'; const { document, DISTRIBUTOR } = window; @@ -28,6 +27,7 @@ const form = document.getElementById( 'posts-filter' ); const asDraftCheckboxes = document.querySelectorAll( '[name=dt_as_draft]' ); const pullLinks = document.querySelectorAll( '.distributor_page_pull .pull a' ); +// Change target website to pull contents from jQuery( chooseConnection ).on( 'change', ( event ) => { const pullUrlId = event.currentTarget.options[ @@ -39,6 +39,7 @@ jQuery( chooseConnection ).on( 'change', ( event ) => { } ); if ( chooseConnection && choosePostType && form ) { + // Handle post type selection if ( choosePostTypeBtn ) { jQuery( choosePostTypeBtn ).on( 'click', ( event ) => { event.preventDefault(); @@ -49,6 +50,7 @@ if ( chooseConnection && choosePostType && form ) { } ); } + // Handle search button click if ( searchField && searchBtn ) { jQuery( searchBtn ).on( 'click', ( event ) => { event.preventDefault(); @@ -61,33 +63,174 @@ if ( chooseConnection && choosePostType && form ) { } ); } - if ( asDraftCheckboxes && pullLinks ) { + // Handle pull mode checkbox event + if ( asDraftCheckboxes ) { jQuery( asDraftCheckboxes ).on( 'change', ( event ) => { if ( event.currentTarget.checked ) { + // Check all pull mode checkbox as there are multiple. Ideally before and after post list. for ( let i = 0; i < asDraftCheckboxes.length; ++i ) { asDraftCheckboxes[ i ].checked = true; } for ( let i = 0; i < pullLinks.length; ++i ) { - pullLinks[ i ].href = addQueryArgs( pullLinks[ i ].href, { - dt_as_draft: 'draft' /*eslint camelcase: 0*/, - } ); pullLinks[ i ].text = __( 'Pull as draft', 'distributor' ); } } else { + // Uncheck all pull mode checkbox as there are multiple. Ideally before and after post list. for ( let i = 0; i < asDraftCheckboxes.length; ++i ) { asDraftCheckboxes[ i ].checked = false; } for ( let i = 0; i < pullLinks.length; ++i ) { - pullLinks[ i ].href = addQueryArgs( pullLinks[ i ].href, { - dt_as_draft: '' /*eslint camelcase: 0*/, - } ); pullLinks[ i ].text = __( 'Pull', 'distributor' ); } } } ); } + + // Pull content via ajax + jQuery( '#doaction, #doaction2' ).on( 'click', ( e ) => { + // Check action + if ( 'bulk-syndicate' !== jQuery( '[name="action"]' ).val() ) { + return; + } + e.preventDefault(); + openModal(); + } ); + + jQuery( '.distributor_page_pull .pull a' ).on( 'click', function ( e ) { + e.preventDefault(); + jQuery( this ) + .closest( 'tr' ) + .find( '.check-column input[type="checkbox"]' ) + .prop( 'checked', true ); + openModal(); + } ); + + function openModal() { + // Prepare data + let aborted = false; + const postIds = []; + + jQuery( '#the-list .check-column input[type="checkbox"]:checked' ).each( + function () { + const id = parseInt( jQuery( this ).val() ); + if ( id && postIds.indexOf( id ) === -1 ) { + postIds.push( id ); + } + } + ); + + const postIdsCount = postIds.length; + if ( ! postIdsCount ) { + return; + } + + function log( customContent ) { + jQuery( '#distributor-pull-modal .pull-progress' ).html( + customContent || + `Pulled: ${ + postIdsCount - postIds.length + }/${ postIdsCount }` + ); + } + + // Create modal for pulling via ajax + const sourceLabel = jQuery( + '#pull_connections option:selected' + ).text(); + + jQuery( '#distributor-pull-modal' ).remove(); + jQuery( 'body' ).append( + ` +
' . esc_html__( 'Sorry, you are not allowed to add this item.', 'distributor' ) . '
', - 403 - ); - } - - if ( empty( $_GET['pull_post_type'] ) || empty( $_GET['connection_type'] ) || empty( $_GET['connection_id'] ) || empty( $_GET['post'] ) ) { - break; - } + // Verify nonce + if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'bulk-distributor_page_pull' ) ) { + wp_send_json_error( array( 'message' => __( 'Invalid Session!', 'distributor' ) ) ); + exit; + } - $posts = array_map( 'intval', (array) wp_unslash( $_GET['post'] ) ); - $post_type = sanitize_text_field( $_GET['pull_post_type'] ); - $post_status = ! empty( $_GET['dt_as_draft'] ) && 'draft' === $_GET['dt_as_draft'] ? 'draft' : ''; - - $posts = array_map( - function( $remote_post_id ) use ( $post_type, $post_status ) { - return [ - 'remote_post_id' => $remote_post_id, - 'post_type' => $post_type, - 'post_status' => $post_status, - ]; - }, - $posts - ); + // Capability check + if ( ! current_user_can( apply_filters( 'dt_pull_capabilities', 'manage_options' ) ) ) { + wp_send_json_error( array( 'message' => __( 'Sorry, you are not allowed to add this item.', 'distributor' ) ) ); + exit; + } - if ( 'external' === $_GET['connection_type'] ) { - $connection = \Distributor\ExternalConnection::instantiate( intval( $_GET['connection_id'] ) ); - $new_posts = $connection->pull( $posts ); - $error_key = "external_{$connection->id}"; + // Input data check + if ( empty( $_POST['pull_post_type'] ) || empty( $_POST['connection_type'] ) || empty( $_POST['connection_id'] ) || empty( $_POST['post_id'] ) ) { + wp_send_json_error( array( 'message' => __( 'Invalid data!', 'distributor' ) ) ); + exit; + } - foreach ( $posts as $key => $post_array ) { - if ( is_wp_error( $new_posts[ $key ] ) ) { - continue; - } - \Distributor\Subscriptions\create_remote_subscription( $connection, $post_array['remote_post_id'], $new_posts[ $key ] ); - } - } else { - $site = get_site( intval( $_GET['connection_id'] ) ); - $connection = new \Distributor\InternalConnections\NetworkSiteConnection( $site ); - $new_posts = $connection->pull( $posts ); - $error_key = "internal_{$connection->site->blog_id}"; - } + // Prepare arguments + $new_post = null; + $post_type = sanitize_text_field( $_POST['pull_post_type'] ); + $post_status = ! empty( $_POST['dt_as_draft'] ) && 'draft' === $_POST['dt_as_draft'] ? 'draft' : ''; + $post = array( + 'remote_post_id' => (int) $_POST['post_id'], + 'post_type' => $post_type, + 'post_status' => $post_status, + ); - $post_id_mappings = array(); - $pull_errors = array(); + // Pull contents external or internal + if ( 'external' === $_POST['connection_type'] ) { + $connection = \Distributor\ExternalConnection::instantiate( intval( $_POST['connection_id'] ) ); + $new_posts = $connection->pull( array( $post ) ); + $new_post = is_array( $new_posts ) ? $new_posts[0] ?? null : null; - foreach ( $posts as $key => $post_array ) { - if ( is_wp_error( $new_posts[ $key ] ) ) { - $pull_errors[ $post_array['remote_post_id'] ] = [ $new_posts[ $key ]->get_error_message() ]; - continue; - } - $post_id_mappings[ $post_array['remote_post_id'] ] = $new_posts[ $key ]; + if ( ! empty( $new_post ) ) { + \Distributor\Subscriptions\create_remote_subscription( $connection, $post['remote_post_id'], $new_post ); + } + } else { + $site = get_site( intval( $_POST['connection_id'] ) ); + $connection = new \Distributor\InternalConnections\NetworkSiteConnection( $site ); + $new_posts = $connection->pull( array( $post ) ); + $new_post = is_array( $new_posts ) ? $new_posts[0] ?? null : null; + } - $media_errors = get_transient( 'dt_media_errors_' . $new_posts[ $key ] ); + if ( empty( $new_post ) || $is_error = is_wp_error( $new_post ) ) { + wp_send_json_error( array( 'message' => $is_error ? $new_post->get_error_message() : __( 'Pull Failed!', 'distributor' ) ) ); + exit; + } - if ( ! empty( $media_errors ) ) { - delete_transient( 'dt_media_errors_' . $new_posts[ $key ] ); - $pull_errors[ $post_array['remote_post_id'] ] = $media_errors; - } - } + // Delete media error + $media_errors = get_transient( 'dt_media_errors_' . $new_post ); + if ( ! empty( $media_errors ) ) { + delete_transient( 'dt_media_errors_' . $new_post ); + } - if ( ! empty( $pull_errors ) ) { - set_transient( 'dt_connection_pull_errors_' . $error_key, $pull_errors, DAY_IN_SECONDS ); - } + // Log mapping + $connection->log_sync( array( $post['remote_post_id'] => $new_post ), 0, false ); - $connection->log_sync( $post_id_mappings ); + if ( empty( $dt_pull_messages['duplicated'] ) ) { + setcookie( 'dt-syndicated', 1, time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() ); + } - if ( empty( $dt_pull_messages['duplicated'] ) ) { - setcookie( 'dt-syndicated', 1, time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() ); - } + if ( ! empty( $dt_pull_messages['duplicated'] ) ) { + setcookie( 'dt-duplicated', 1, time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() ); + } - if ( ! empty( $dt_pull_messages['duplicated'] ) ) { - setcookie( 'dt-duplicated', 1, time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() ); - } + // Redirect to the pulled content tab + wp_send_json_success( + array( + 'redirect_to' => add_query_arg( 'status', 'pulled', wp_get_referer() ), + ) + ); + exit; +} - // Redirect to the pulled content tab - wp_safe_redirect( add_query_arg( 'status', 'pulled', wp_get_referer() ) ); - exit; +/** + * Process content changing actions + * + * @since 0.8 + */ +function process_actions( ) { + global $connection_list_table; + switch ( $connection_list_table->current_action() ) { case 'bulk-skip': case 'skip': if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'dt_skip' ) && ! wp_verify_nonce( $_GET['_wpnonce'], 'bulk-distributor_page_pull' ) ) { @@ -557,8 +553,6 @@ function dashboard() { - - prepare_items(); ?> pull_error ) ) : ?> @@ -593,65 +587,3 @@ function dashboard() { id}"; - } elseif ( is_a( $connection_now, '\Distributor\InternalConnections\NetworkSiteConnection' ) ) { - $error_key = "internal_{$connection_now->site->blog_id}"; - } else { - return; - } - - $pull_errors = get_transient( 'dt_connection_pull_errors_' . $error_key ); - - if ( empty( $pull_errors ) ) { - return; - } - - delete_transient( 'dt_connection_pull_errors_' . $error_key ); - - $post_ids = array_keys( $pull_errors ); - - $_posts = $connection_now->remote_get( [ 'post__in' => $post_ids ] ); - $posts = []; - - if ( empty( $_posts ) ) { - return; - } - - foreach ( $_posts['items'] as $post ) { - $posts[ $post->ID ] = $post->post_title; - } - ?> - -