Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 15 additions & 0 deletions assets/css/admin-pull-table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@
padding-left: 10px;
}
}

.pull-taxonomy {

&.hide {
display: none;
}

&.show {
display: block;
}
}

.dt-reset-filters-button {
margin-left: 6px
}
}

.wp-list-table .disabled {
Expand Down
85 changes: 84 additions & 1 deletion assets/js/admin-pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
const chooseConnection = document.getElementById( 'pull_connections' );
const choosePostType = document.getElementById( 'pull_post_type' );
const choosePostTypeBtn = document.getElementById( 'pull_post_type_submit' );
const choosePostTypeReset = document.getElementById( 'pull_post_type_reset' );
const searchField = document.getElementById( 'post-search-input' );
const searchBtn = document.getElementById( 'search-submit' );
const form = document.getElementById( 'posts-filter' );
const asDraftCheckboxes = document.querySelectorAll( '[name=dt_as_draft]' );
const pullLinks = document.querySelectorAll( '.distributor_page_pull .pull a' );
const pullTaxonomies = document.querySelectorAll( '.pull-taxonomy' );

jQuery( chooseConnection ).on( 'change', ( event ) => {
const pullUrlId =
Expand All @@ -39,16 +41,80 @@
} );

if ( chooseConnection && choosePostType && form ) {
/**
Comment thread Fixed
* When the post type is changed, show/hide the taxonomy fields based on the post type.
*/
jQuery( choosePostType ).on( 'change', ( event ) => {
const selectedPostType =
event.currentTarget.options[ event.currentTarget.selectedIndex ];
if ( selectedPostType ) {
const dataTaxonomies =
selectedPostType.getAttribute( 'data-taxonomies' );
if ( dataTaxonomies ) {
const supportedTaxonomies = JSON.parse( dataTaxonomies );
if ( supportedTaxonomies.length > 0 ) {
pullTaxonomies.forEach( ( taxonomyField ) => {
if (
supportedTaxonomies.includes(
taxonomyField.id.replace( 'pull_', '' )
)
) {
jQuery( taxonomyField ).addClass( 'show' );
jQuery( taxonomyField ).removeClass( 'hide' );
} else {
jQuery( taxonomyField ).addClass( 'hide' );
jQuery( taxonomyField ).removeClass( 'show' );
}
} );
} else {
pullTaxonomies.forEach( ( taxonomyField ) => {
jQuery( taxonomyField ).addClass( 'hide' );
jQuery( taxonomyField ).removeClass( 'show' );
} );
}
}
}
} );

if ( choosePostTypeBtn ) {
jQuery( choosePostTypeBtn ).on( 'click', ( event ) => {
event.preventDefault();

document.location = getURL();

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.

document.body.className += ' ' + 'dt-loading';
} );
}

/**
* When the reset filters button is clicked, reset the filters and reload the page.
*/
if ( choosePostTypeReset ) {
jQuery( choosePostTypeReset ).on( 'click', ( event ) => {
event.preventDefault();

const pullUrlId = escapeURLComponent(
chooseConnection.options[
chooseConnection.selectedIndex
].getAttribute( 'data-pull-url-id' )
);

const baseURL = getPullUrl( pullUrlId );
let status = 'new';

if ( -1 < ` ${ form.className } `.indexOf( ' status-skipped ' ) ) {
status = 'skipped';
} else if (
-1 < ` ${ form.className } `.indexOf( ' status-pulled ' )
) {
status = 'pulled';
}

document.location = `${ baseURL }&status=${ status }`;
document.body.className += ' ' + 'dt-loading';
} );
}

if ( searchField && searchBtn ) {
jQuery( searchBtn ).on( 'click', ( event ) => {
event.preventDefault();
Expand Down Expand Up @@ -99,6 +165,23 @@
const postType = escapeURLComponent(
choosePostType.options[ choosePostType.selectedIndex ].value
);

// Build the taxonomies query string.
let taxonomies = '';
if ( pullTaxonomies ) {
pullTaxonomies.forEach( ( taxonomyField ) => {
if ( jQuery( taxonomyField ).hasClass( 'show' ) ) {
taxonomies += `${ taxonomyField.id }=${
taxonomyField.options[ taxonomyField.selectedIndex ].value
}&`;
}
} );
}

if ( taxonomies ) {
taxonomies = taxonomies.slice( 0, -1 );
}

const pullUrlId = escapeURLComponent(
chooseConnection.options[ chooseConnection.selectedIndex ].getAttribute(
'data-pull-url-id'
Expand All @@ -113,5 +196,5 @@
status = 'pulled';
}

return `${ baseURL }&pull_post_type=${ postType }&status=${ status }`;
return `${ baseURL }&pull_post_type=${ postType }&status=${ status }&${ taxonomies }`;
};
16 changes: 16 additions & 0 deletions includes/classes/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ abstract public function get_sync_log( $id );
*/
abstract public function get_post_types();

/**
* Get available post type taxonomies from a connection
*
* @param string $post_type Post type.
*
* @return array
*/
abstract public function get_post_type_taxonomies( $post_type );

/**
* Get available taxonomy terms from a connection
*
* @return array
*/
abstract public function get_taxonomy_terms();

/**
* This method is called on every page load. It's helpful for canonicalization
*
Expand Down
138 changes: 138 additions & 0 deletions includes/classes/ExternalConnections/WordPressExternalConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ class WordPressExternalConnection extends ExternalConnection {
*/
public $pull_post_types;

/**
* Default taxonomy term to pull.
*
* @var string
*/
public $pull_taxonomy_term;

/**
* Default taxonomy terms to show in filter.
*
* @var string
*/
public $pull_taxonomy_terms;

/**
* This is a utility function for parsing annoying API link headers returned by the types endpoint
*
Expand Down Expand Up @@ -168,6 +182,11 @@ public function remote_get( $args = array() ) {
}
}

// Add the tax query to the query args.
if ( isset( $args['tax_query'] ) ) {
$query_args['tax_query'] = $args['tax_query']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
}

// When running a query for the Pull screen, make a POST request instead
if ( empty( $id ) ) {
$query_args['post_type'] = isset( $post_type ) ? $post_type : 'post';
Expand Down Expand Up @@ -682,6 +701,125 @@ public function get_post_types() {
return $types_body_array;
}

/**
* Get the available post type taxonomies.
* The taxonomies with external connection are already available in the post type object.
*
* @param string $post_type Post type.
*
* @return array
*/
public function get_post_type_taxonomies( $post_type ) {
return array();
}

/**
* Get the available taxonomies from the remote connection.
*
* @param array $taxonomies Taxonomies to get.
*
* @return array|\WP_Error Array of taxonomies with rest_base and label, or WP_Error if the request fails.
*/
private function get_remote_taxonomies( $taxonomies = array() ) {

$path = self::$namespace;

$taxonomies_path = untrailingslashit( $this->base_url ) . '/' . $path . '/taxonomies';

$taxonomies_response = Utils\remote_http_request(
$taxonomies_path,
$this->auth_handler->format_get_args( array( 'timeout' => self::$timeout ) )
);

if ( is_wp_error( $taxonomies_response ) ) {
return $taxonomies_response;
}

if ( 404 === wp_remote_retrieve_response_code( $taxonomies_response ) ) {
return new \WP_Error( 'bad-endpoint', esc_html__( 'Could not connect to API endpoint.', 'distributor' ) );
}

$taxonomies_body = wp_remote_retrieve_body( $taxonomies_response );

if ( empty( $taxonomies_body ) ) {
return new \WP_Error( 'no-response-body', esc_html__( 'Response body is empty.', 'distributor' ) );
}

$taxonomies_body_array = json_decode( $taxonomies_body, true );

$taxonomies_exists = array();
foreach ( $taxonomies as $taxonomy ) {
if ( isset( $taxonomies_body_array[ $taxonomy ] ) ) {
$taxonomies_exists[ $taxonomy ] = array(
'rest_base' => $taxonomies_body_array[ $taxonomy ]['rest_base'],
'label' => $taxonomies_body_array[ $taxonomy ]['name'],
);
}
}

if ( empty( $taxonomies_exists ) ) {
return new \WP_Error( 'no-taxonomies', esc_html__( 'No taxonomies found.', 'distributor' ) );
}

return $taxonomies_exists;
}

/**
* Get the available taxonomy terms.
*
* @param array $taxonomies Taxonomies to get terms for.
*
* @return array|\WP_Error Array of taxonomy terms with items and label, or WP_Error if the request fails.
*/
public function get_taxonomy_terms( $taxonomies = array() ) {

// Get the remote taxonomies, if the request fails, return an empty array.
$remote_taxonomies = $this->get_remote_taxonomies( $taxonomies );
if ( empty( $remote_taxonomies ) || is_wp_error( $remote_taxonomies ) ) {
return array();
}

$path = self::$namespace;

$taxonomy_terms = array();

/**
* Loop through the remote taxonomies and get the terms for each taxonomy.
*/
foreach ( $remote_taxonomies as $taxonomy => $taxonomy_data ) {

$taxonomy_path = untrailingslashit( $this->base_url ) . '/' . $path . '/' . $taxonomy_data['rest_base'];

$taxonomy_response = Utils\remote_http_request(
$taxonomy_path,
$this->auth_handler->format_get_args( array( 'timeout' => self::$timeout ) )
);

if ( is_wp_error( $taxonomy_response ) ) {
continue;
}

if ( 404 === wp_remote_retrieve_response_code( $taxonomy_response ) ) {
continue;
}

$taxonomy_body = wp_remote_retrieve_body( $taxonomy_response );

if ( empty( $taxonomy_body ) ) {
continue;
}

$taxonomy_body_array = json_decode( $taxonomy_body, true );

$taxonomy_terms[ $taxonomy ] = array(
'items' => $taxonomy_body_array,
'label' => $taxonomy_data['label'],
);
}

return $taxonomy_terms;
}

/**
* Check what we can do with a given external connection (push or pull)
*
Expand Down
Loading
Loading