Skip to content

Commit

Permalink
Merge branch 'develop' into trunk
Browse files Browse the repository at this point in the history
  • Loading branch information
dkotter committed Nov 29, 2023
2 parents 7e2085b + da28b5d commit 5d24078
Show file tree
Hide file tree
Showing 24 changed files with 679 additions and 248 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ jobs:
npx wp-env run cli "wp core version"
npx wp-env run cli "php --version"
- name: Copy .htaccess
run: npm run copy-htaccess

- name: Test
run: npm run cypress:run

Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file, per [the Ke

## [Unreleased] - TBD

## [2.0.2] - 2023-11-29
### Added
- New snippet detailing how to disable automatic content updates (props [@dkotter](https://github.com/dkotter), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1145](https://github.com/10up/distributor/pull/1145)).

### Changed
- Show proper external connection status error messages when the status is checked (props [@theskinnyghost](https://github.com/theskinnyghost), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1140](https://github.com/10up/distributor/pull/1140)).
- Updated our docs around how to connect two pieces of existing content (props [@dkotter](https://github.com/dkotter), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1145](https://github.com/10up/distributor/pull/1145)).
- Bump WordPress "tested up to" version 6.4 (props [@severine-pozzo](https://github.com/severine-pozzo), [@QAharshalkadu](https://github.com/QAharshalkadu), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#1151](https://github.com/10up/distributor/pull/1151)).

### Fixed
- Copy the htaccess file when initilizing the E2E test environment (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@theskinnyghost](https://github.com/theskinnyghost), [@dkotter](https://github.com/dkotter) via [#1143](https://github.com/10up/distributor/pull/1143)).
- Prevent early publishing of scheduled posts when pulled internally (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter), [@maxledoux](https://github.com/maxledoux), [@pcrumm](https://github.com/pcrumm) via [#1156](https://github.com/10up/distributor/pull/1156)).
- Avoid a PHP fatal error when pulling content that has previously been pulled into a different network site (props [@dkotter](https://github.com/dkotter), [@jeffpaul](https://github.com/jeffpaul), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1159](https://github.com/10up/distributor/pull/1159)).

### Security
- Bump `postcss` from 8.4.24 to 8.4.31 (props [@dependabot[bot]](https://github.com/apps/dependabot), [@ravinderk](https://github.com/ravinderk) via [#1141](https://github.com/10up/distributor/pull/1141)).
- Bump `@babel/traverse` from 7.22.5 to 7.23.2 (props [@dependabot[bot]](https://github.com/apps/dependabot), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1147](https://github.com/10up/distributor/pull/1147)).

## [2.0.1] - 2023-09-18
### Changed
- Update from Cypress v10 to v13 (props [@dkotter](https://github.com/dkotter), [@iamdharmesh](https://github.com/iamdharmesh), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#1128](https://github.com/10up/distributor/pull/1128)).
Expand Down Expand Up @@ -486,6 +504,7 @@ This adds a post type selector when viewing the Pull Content list for both exter
- Initial closed release.

[Unreleased]: https://github.com/10up/distributor/compare/trunk...develop
[2.0.2]: https://github.com/10up/distributor/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/10up/distributor/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/10up/distributor/compare/1.9.1...2.0.0
[1.9.1]: https://github.com/10up/distributor/compare/1.9.0...1.9.1
Expand Down
2 changes: 1 addition & 1 deletion CREDITS.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

> Distributor is a WordPress plugin that makes it easy to distribute and reuse content across your websites — whether in a single multisite or across the web.
[![Support Level](https://img.shields.io/badge/support-active-green.svg)](#support-level) [![Tests](https://github.com/10up/distributor/actions/workflows/test.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/test.yml) [![Linting](https://github.com/10up/distributor/actions/workflows/lint.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/lint.yml) [![Code scanning](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml) [![Release Version](https://img.shields.io/github/release/10up/distributor.svg)](https://github.com/10up/distributor/releases/latest) ![WordPress tested up to version](https://img.shields.io/badge/WordPress-v6.3%20tested-success.svg) [![License](https://img.shields.io/github/license/10up/distributor.svg)](https://github.com/10up/distributor/blob/develop/LICENSE.md)
[![Support Level](https://img.shields.io/badge/support-active-green.svg)](#support-level) [![Tests](https://github.com/10up/distributor/actions/workflows/test.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/test.yml) [![Linting](https://github.com/10up/distributor/actions/workflows/lint.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/lint.yml) [![Code scanning](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml) [![Release Version](https://img.shields.io/github/release/10up/distributor.svg)](https://github.com/10up/distributor/releases/latest) ![WordPress tested up to version](https://img.shields.io/badge/WordPress-v6.4%20tested-success.svg) [![License](https://img.shields.io/github/license/10up/distributor.svg)](https://github.com/10up/distributor/blob/develop/LICENSE.md)

*You can learn more about Distributor's features at [DistributorPlugin.com](https://distributorplugin.com) and documentation at the [Distributor documentation site](https://10up.github.io/distributor/).*

Expand Down
5 changes: 0 additions & 5 deletions assets/css/admin-external-connection.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@
}

.endpoint-result[data-endpoint-state="error"]::before,
.endpoint-result[data-endpoint-state="warning"]::before,
.endpoint-result[data-endpoint-state="valid"]::before {
content: " ";
display: inline-block;
Expand All @@ -129,10 +128,6 @@
background-color: #62ff00;
}

.endpoint-result[data-endpoint-state="warning"]::before {
background-color: #ffe000;
}

.endpoint-result .dashicons-yes {
color: #46b450;
}
Expand Down
4 changes: 0 additions & 4 deletions assets/css/admin-external-connections.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,3 @@
.connection-status.valid {
background-color: #62ff00;
}

.connection-status.warning {
background-color: #ffe000;
}
95 changes: 28 additions & 67 deletions assets/js/admin-external-connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ function checkConnections() {
.done( ( response ) => {
if ( ! response.success ) {
endpointResult.setAttribute( 'data-endpoint-state', 'error' );
} else if ( response.data.errors.no_external_connection ) {
} else if (
response.data.errors.no_external_connection ||
'no' === response.data.is_authenticated ||
response.data.errors.no_distributor ||
! response.data.can_post.length
) {
endpointResult.setAttribute( 'data-endpoint-state', 'error' );

if ( response.data.endpoint_suggestion ) {
Expand All @@ -337,88 +342,44 @@ function checkConnections() {
}`,
'polite'
);
} else {
} else if ( response.data.errors.no_distributor ) {
endpointResult.innerText = __(
'No connection found.',
'distributor'
);

speak(
__( 'No connection found.', 'distributor' ),
'polite'
);
}
} else if (
response.data.errors.no_distributor ||
! response.data.can_post.length
) {
endpointResult.setAttribute( 'data-endpoint-state', 'warning' );
endpointResult.innerText = __(
'Limited connection established.',
'distributor'
);

const warnings = [];

if ( response.data.errors.no_distributor ) {
endpointResult.innerText += ` ${ __(
'Distributor not installed on remote site.',
'distributor'
) }`;
);
speak(
`${ __(
'Limited connection established.',
'distributor'
) } ${ __(
__(
'Distributor not installed on remote site.',
'distributor'
) }`,
),
'polite'
);
} else {
} else if (
'no' === response.data.is_authenticated ||
response.data.errors.no_types
) {
endpointResult.innerText = __(
'Authentication failed due to insufficient or invalid credentials.',
'distributor'
);
speak(
`${ __(
'Limited connection established.',
__(
'Authentication failed due to insufficient or invalid credentials.',
'distributor'
) }`,
),
'polite'
);
}

if ( 'no' === response.data.is_authenticated ) {
warnings.push(
__(
'Authentication failed due to invalid credentials.',
'distributor'
)
} else {
endpointResult.innerText = __(
'No connection found.',
'distributor'
);
}

if ( 'yes' === response.data.is_authenticated ) {
warnings.push(
__(
'Authentication succeeded but your account does not have permissions to create posts on the external site.',
'distributor'
)
speak(
__( 'No connection found.', 'distributor' ),
'polite'
);
}

warnings.push(
__( 'Push distribution unavailable.', 'distributor' )
);
warnings.push(
__(
'Pull distribution limited to basic content, i.e. title and content body.',
'distributor'
)
);

warnings.forEach( ( warning ) => {
const warningNode = document.createElement( 'li' );
warningNode.innerText = warning;

endpointErrors.append( warningNode );
} );
} else {
endpointResult.setAttribute( 'data-endpoint-state', 'valid' );
endpointResult.innerText = __(
Expand Down
4 changes: 2 additions & 2 deletions distributor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/10up/distributor
* Update URI: https://distributorplugin.com
* Description: Makes it easy to distribute and reuse content across your websites, whether inside of a multisite or across the web.
* Version: 2.0.1
* Version: 2.0.2
* Requires at least: 5.7
* Requires PHP: 7.4
* Author: 10up Inc.
Expand All @@ -28,7 +28,7 @@
exit; // Exit if accessed directly.
}

define( 'DT_VERSION', '2.0.1' );
define( 'DT_VERSION', '2.0.2' );
define( 'DT_PLUGIN_FILE', preg_replace( '#^.*plugins/(.*)$#i', '$1', __FILE__ ) );
define( 'DT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
define( 'DT_PLUGIN_FULL_FILE', __FILE__ );
Expand Down
110 changes: 107 additions & 3 deletions docs/connect-to-an-existing-post.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
1. Connect the two sites
1. On Site A (source) add the meta data items `dt_subscriptions` and `dt_connection_map`
1. On Site B (distributed) add the meta data items `dt_original_post_url`, `dt_original_site_name`, `dt_original_site_url`, `dt_subscription_signature`, `dt_original_post_id`, `dt_original_source_id`
In a scenario where you have existing sites that share content and that content was in place prior to the addition of Distributor, it is useful to be able to connect that content together without having to delete one and push/pull the other one. Behind the scenes, Distributor stores a handful of details in post meta, so these details will need to be manually added for the links to work.

At it's simplest, you'll need to connect the two sites together and then add the proper meta (as detailed below) for the items that should be linked together, both on the source site and the receiving site.

## Network Connections

There are different pieces of data that will need to be set on each side of a connection, what we'll call as the source site and the receiving site.

The only piece of data needed on the source site to connect two items in Network Connections is the `dt_connection_map`. This is a serialized array of data that contains the mapping from the site ID to the post ID, along with a timestamp of when the item was linked. Note that the site ID and post ID should correspond to the data on the receiving site, not source site.

This data structure will look like the following:

```php
$data = [
[
'external' => [],
'internal' => [
2 => [
'post_id' => 674,
'time' => 1693494494,
],
],
],
];
```

In the above example, the `external` array will always be empty, unless an item is also linked to an external site. For the `internal` array, each item in the array will have a key that corresponds to the site ID (2 in the example above) and then the `post_id` should be the destination post ID.

As a further example, if I have a post with an ID of 100 that lives on a site with an ID of 1 and I want that post to be linked to an existing post with an ID of 50 on the site with an ID of 2, the `dt_connection_map` data that is stored with the original item (ID of 100, site ID 1) would look like the following:

```php
$data = [
[
'external' => [],
'internal' => [
2 => [
'post_id' => 50,
'time' => 1693494494,
],
],
],
];
update_post_meta( 100, 'dt_connection_map', $data );
```

And then on the receiving site, the following data is needed: `dt_original_post_id`, `dt_original_post_url`, `dt_original_blog_id` and `dt_syndicate_time`. These should all be fairly self explanatory but to use the same example from above:

- `dt_original_post_id` would be set to 100
- `dt_original_post_url` would be the full URL of that post with an ID of 100
- `dt_original_blog_id` would be set to 1
- `dt_syndicate_time` should match the same timestamp set in the connection map, in this case 1693494494

## External Connections

External Connections share a similar data structure as detailed above but they also contain a Subscriptions piece, which is more complicated to manually replicate (as such, full details on how to replicate the Subscription is not outlined here).

Similar to the above, there's a data mapping that is needed on the source site: `dt_connection_map`. This is a serialized array of data that contains the mapping from the external connection ID to the post ID, along with a timestamp of when the item was linked. Note that the post ID should correspond to the data on the receiving site, not source site.

This data structure will look like the following:

```php
$data = [
[
'external' => [
2 => [
'post_id' => 50,
'time' => 1693494494,
],
],
'internal' => [],
],
];
```

In the above example, the `internal` array will always be empty, unless an item is also linked to an interal site. For the `external` array, each item in the array will have a key that corresponds to the connection ID (2 in the example above) and then the `post_id` should be the destination post ID.

As a further example, if I have a post with an ID of 100 that lives on a site with an ID of 1 and I want that post to be linked to an existing post with an ID of 50 on the site with a connection ID of 2, the `dt_connection_map` data that is stored with the original item (ID of 100, site ID 1) would look like the following:

```php
$data = [
[
'external' => [
2 => [
'post_id' => 50,
'time' => 1693494494,
],
],
'internal' => [],
],
];
update_post_meta( 100, 'dt_connection_map', $data );
```

In addition, there needs to be a piece of data on the source site that contains the subscription information: `dt_subscriptions`. This contains a serialized array of data that links a hashed signature to the subscription post ID. This isn't something that is easily manually reproduced. Suggestion is to look at using the existing `Distributor\Subscriptions\create_subscription` function to replicate this data.

And then on the receiving site, the following data is needed: `dt_original_post_id`, `dt_original_post_url`, `dt_original_source_id`, `dt_original_site_name`, `dt_original_site_url`, `dt_subscription_signature`, `dt_full_connection` and `dt_syndicate_time`.

From the example above:

- `dt_original_post_id` would be set to 100
- `dt_original_post_url` would be the full URL of that post with an ID of 100
- `dt_original_source_id` would be set to 2 (the source connection ID)
- `dt_original_site_name` would be the name of the source site
- `dt_original_site_url` would be the URL of the source site
- `dt_subscription_signature` would be the signature of the subscription mentioned above
- `dt_full_connection` would be set to `true`
- `dt_syndicate_time` should match the same timestamp set in the connection map, in this case 1693494494
23 changes: 23 additions & 0 deletions docs/snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,26 @@ add_filter( 'dt_excluded_meta', function( $meta_keys ) {
return $meta_keys;
} );
```

### Turn off automatic updates for distributed content

```php
/**
* Prevent auto-updates from happening for network connections.
*/
add_action(
'init',
function() {
remove_action( 'wp_after_insert_post', [ '\Distributor\InternalConnections\NetworkSiteConnection', 'update_syndicated' ], 99 );
}
);

/**
* Prevent auto-updates from happening for external connections.
*/
add_action(
'init',
function() {
remove_action( 'wp_after_insert_post', 'Distributor\Subscriptions\send_notifications', 99 );
}
);
Loading

0 comments on commit 5d24078

Please sign in to comment.