Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7d73039
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Feb 21, 2025
fbc1c31
Register classic editor metaboxes
s3rgiosan Feb 22, 2025
ce6d5e0
Move the PluginDocumentSettingPanel outside the RelationshipManager f…
s3rgiosan Feb 22, 2025
daa5c3f
Display the relationship manager component on the classic editor
s3rgiosan Feb 22, 2025
ee02171
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Mar 14, 2025
d17bf7e
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Mar 14, 2025
d8720b0
Remove old UI classes
s3rgiosan Mar 14, 2025
dcf4a01
Enqueue block editor styles in the classic editor
s3rgiosan Mar 14, 2025
b01093c
Only enqueue classic editor assets if the post is using the classic e…
s3rgiosan Mar 14, 2025
a49beb1
Render metaboxes for post-to-user and post-to-post relationships
s3rgiosan Mar 14, 2025
400cf4e
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Mar 14, 2025
c10624a
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Mar 18, 2025
360d9cb
Add dist files
s3rgiosan Mar 20, 2025
0784a92
Remove dist files
s3rgiosan Mar 21, 2025
a1cc078
Remove deprecated search API
s3rgiosan Apr 4, 2025
6cfe3af
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Apr 4, 2025
ea74052
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 6, 2025
a131a14
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 6, 2025
799dd8e
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 8, 2025
5e5ad19
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 9, 2025
c094329
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 22, 2025
c54e42e
Restore Search V1 endpoint
s3rgiosan May 22, 2025
a7dc0bf
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 22, 2025
c5a19f3
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan May 26, 2025
e8703a2
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jun 16, 2025
fa33e64
Update dependencies
s3rgiosan Jun 16, 2025
02ef40d
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jun 17, 2025
78ab86d
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
75ca707
Remove unused setup method
s3rgiosan Jan 12, 2026
1623896
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
67024a8
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
dc4d448
Update compiled assets
s3rgiosan Jan 12, 2026
1b97ba1
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
cb0aa23
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
21a4315
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
62ee315
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 12, 2026
c329050
Remove setup call that is no longer needed
s3rgiosan Jan 12, 2026
9808b84
Fix classic editor persistance
s3rgiosan Jan 12, 2026
ba6441b
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
fd2fcf9
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
a011d1f
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
d5f316a
Add missing capability checks
s3rgiosan Jan 30, 2026
63c10fa
Check file_exists before enqueuing
s3rgiosan Jan 30, 2026
01a87eb
Cache post relationship data
s3rgiosan Jan 30, 2026
36f2d20
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
7c4c2fe
Update version
s3rgiosan Jan 30, 2026
cdb49aa
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
f78c1da
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
da0439c
Enqueue admin styles for classic editor
s3rgiosan Jan 30, 2026
f2c75da
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
d3255c3
Merge branch 'feature/data-api-backbone' into feature/classic-editor-…
s3rgiosan Jan 30, 2026
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
93 changes: 93 additions & 0 deletions assets/js/classic-editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* External dependencies
*/
import React from 'react';

/**
* WordPress dependencies
*/
import { createRoot } from '@wordpress/element';
import domReady from '@wordpress/dom-ready';
import { select, dispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { RelationshipManager } from './components/RelationshipManager';
import { store, persistContentConnectChanges } from './store';
import { ContentConnectRelationship } from './store/types';

/**
* Register the relationships panels.
*/
const registerPanels = () => {
const containers = document.querySelectorAll<HTMLElement>('[data-content-connect]');
if (!containers.length) {
return;
}

const postForm = document.querySelector<HTMLFormElement>('#post');
if (!postForm) {
return;
}

let postId: number | null = null;
const relationshipsMap: Record<string, ContentConnectRelationship> = {};

containers.forEach((container) => {
const { postId: containerPostId, relationship: relationshipJson } = container.dataset;

let relationshipData: ContentConnectRelationship | false = false;
try {
relationshipData = JSON.parse(relationshipJson || '') as ContentConnectRelationship;
} catch (e) {
console.error('Invalid JSON in data-content-connect:', e);
return;
}

if (container && relationshipData) {
postId = parseInt(containerPostId ?? '0', 10);
relationshipsMap[relationshipData.rel_key] = relationshipData;

const root = createRoot(container);
root.render(
<RelationshipManager
key={relationshipData.rel_key}
postId={postId}
relationship={relationshipData}
/>
);
}
});

// Initialize relationships in the store
if (postId) {
const relationships: Record<string, ContentConnectRelationship> = {};
Object.values(relationshipsMap).forEach((rel) => {
relationships[rel.rel_key] = rel;
});
dispatch(store).setRelationships(postId, relationships);
}

// Hook into form submission to persist relationships before save
postForm.addEventListener('submit', async (event) => {
const dirtyEntityIds = select(store).getDirtyEntityIds();
console.log('dirtyEntityIds', dirtyEntityIds);

// Only intercept if there are unsaved relationship changes
if (dirtyEntityIds.length > 0) {
event.preventDefault();
event.stopPropagation();

try {
await persistContentConnectChanges();
postForm.submit();
} catch (error) {
console.error('Failed to persist Content Connect changes:', error); // eslint-disable-line no-console
postForm.submit();
}
}
});
}

domReady(registerPanels);
2 changes: 0 additions & 2 deletions assets/js/components/RelationshipManager/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ type RelationshipManagerProps = {
relationship: ContentConnectRelationship;
};

import './style.css';

export function RelationshipManager({ postId, relationship }: RelationshipManagerProps) {
const { updateRelatedEntities } = useDispatch(store);

Expand Down
32 changes: 23 additions & 9 deletions assets/js/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,21 @@ const actions = {
* @returns The action to mark the post as dirty.
*/
markPostAsDirty(postId: number): MarkPostAsDirtyAction {
// Trigger the block editor to mark the post as dirty.
dispatch(editorStore).editPost({
meta: {
_content_connect_edit_lock: Date.now()
// Only mark as dirty in block editor if the editor store is available and initialized
try {
const postType = select(editorStore).getCurrentPostType();
if (postType) {
// Trigger the block editor to mark the post as dirty.
dispatch(editorStore).editPost({
meta: {
_content_connect_edit_lock: Date.now()
}
});
}
});
} catch (error) {
// Editor store not available (e.g., in classic editor)
// Silently skip - the dirty state is still tracked in our store
}

return {
type: 'MARK_POST_AS_DIRTY',
Expand Down Expand Up @@ -220,7 +229,12 @@ export const store = createReduxStore(STORE_NAME, {

register(store);

async function persistContentConnectionChanges() {
/**
* Persists Content Connect changes.
*
* @returns Promise that resolves when all changes are persisted.
*/
export async function persistContentConnectChanges() {
const dirtyEntityIds = select(STORE_NAME).getDirtyEntityIds();

// Process each dirty post
Expand Down Expand Up @@ -258,15 +272,15 @@ async function persistContentConnectionChanges() {
// Add the pre-save hook to persist changes
addFilter(
'editor.preSavePost',
'wp-content-connect/persist-connections',
'wp-content-connect/persist-content-connect-changes',
async (edits, options: { readonly isAutosave: boolean; readonly isPreview: boolean }) => {
try {
if (!options.isAutosave && !options.isPreview) {
await persistContentConnectionChanges();
await persistContentConnectChanges();
}
return edits;
} catch (error) {
console.error('Failed to persist content connections:', error);
console.error('Failed to persist Content Connect changes:', error);
return edits;
}
}
Expand Down
1 change: 1 addition & 0 deletions dist/css/admin-styles.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array(), 'version' => 'be611dfde751cb2b3c12');
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-dom-ready', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-rich-text', 'wp-url'), 'version' => 'aebfe6ff7fd2e20961f9');
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-dom-ready', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-rich-text', 'wp-url'), 'version' => '3745dec6e96e4c92ca45');
4 changes: 2 additions & 2 deletions dist/js/wp-content-connect.js → dist/js/block-editor.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/js/classic-editor.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-primitives', 'wp-rich-text', 'wp-url'), 'version' => '08a019d31e8928d77627');
362 changes: 362 additions & 0 deletions dist/js/classic-editor.js

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions dist/js/classic-editor.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
4 changes: 2 additions & 2 deletions includes/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use TenUp\ContentConnect\Tables\PostToPost;
use TenUp\ContentConnect\Tables\PostToUser;
use TenUp\ContentConnect\UI\BlockEditor;
use TenUp\ContentConnect\UI\MetaBox;
use TenUp\ContentConnect\UI\ClassicEditor;

class Plugin {

Expand Down Expand Up @@ -65,7 +65,7 @@ public function setup() {
$modules = array(
new WPQueryIntegration(),
new UserQueryIntegration(),
new MetaBox(), // @deprecated remove in 2.0.0
new ClassicEditor(),
new BlockEditor(),
new DeletedItems(),
new REST(),
Expand Down
2 changes: 0 additions & 2 deletions includes/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ public function define_post_to_post( $from, $to, $name, $args = array() ) {
$key = $this->get_relationship_key( $from, $to, $name );

$this->post_post_relationships[ $key ] = new PostToPost( $from, $to, $name, $args );
$this->post_post_relationships[ $key ]->setup();

$relationship = $this->post_post_relationships[ $key ];

Expand Down Expand Up @@ -229,7 +228,6 @@ public function define_post_to_user( $post_type, $name, $args = array() ) {
$key = $this->get_relationship_key( $post_type, 'user', $name );

$this->post_user_relationships[ $key ] = new PostToUser( $post_type, $name, $args );
$this->post_user_relationships[ $key ]->setup();

$relationship = $this->post_user_relationships[ $key ];

Expand Down
31 changes: 0 additions & 31 deletions includes/Relationships/PostToPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@ class PostToPost extends Relationship {
*/
public $to;

/**
* The UI Object for the "from" portion of the relationship, if the from UI is enabled
*
* @var \TenUp\ContentConnect\UI\PostToPost
*/
public $from_ui;

/**
* The UI Object for the "to" portion of the relationship, if the to UI is enabled
*
* @var \TenUp\ContentConnect\UI\PostToPost
*/
public $to_ui;

public function __construct( $from, $to, $name, $args = array() ) {
if ( ! post_type_exists( $from ) ) {
throw new \Exception( "Post Type {$from} does not exist. Post types must exist to create a relationship" );
Expand All @@ -53,23 +39,6 @@ public function __construct( $from, $to, $name, $args = array() ) {
parent::__construct( $name, $args );
}

public function setup() {
if ( $this->enable_from_ui === true ) {
$this->from_ui = new \TenUp\ContentConnect\UI\PostToPost( $this, $this->from, $this->from_labels, $this->from_sortable );
$this->from_ui->setup();
}

// Make sure CPT is not the same as "from" so we don't get a duplicate, then register if enabled
if ( $this->to !== $this->from && $this->enable_to_ui === true ) {
// Currently, only support a default UI when the "to" end is a single post type
if ( count( $this->to ) === 1 ) {
$this->to_ui = new \TenUp\ContentConnect\UI\PostToPost( $this, $this->to[0], $this->to_labels, $this->to_sortable );
$this->to_ui->setup();
}
}

}

/**
* Gets the IDs that are related to the supplied post ID in the context of the current relationship
*
Expand Down
14 changes: 0 additions & 14 deletions includes/Relationships/PostToUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ class PostToUser extends Relationship {
*/
public $post_type;

/**
* The UI object for the "from" (post) relationship, if the UI is enabled
*
* @var \TenUp\ContentConnect\UI\PostToUser
*/
public $from_ui;

public function __construct( $post_type, $name, $args = array() ) {
if ( ! post_type_exists( $post_type ) ) {
throw new \Exception( "Post Type {$post_type} does not exist. Post types must exist to create a relationship" );
Expand All @@ -31,13 +24,6 @@ public function __construct( $post_type, $name, $args = array() ) {
parent::__construct( $name, $args );
}

public function setup() {
if ( $this->enable_from_ui ) {
$this->from_ui = new \TenUp\ContentConnect\UI\PostToUser( $this, $this->post_type, $this->from_labels, $this->from_sortable );
$this->from_ui->setup();
}
}

/**
* Gets the post IDs that are related to the supplied user ID in the context of the current relationship
*
Expand Down
3 changes: 0 additions & 3 deletions includes/Relationships/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,4 @@ public function __construct( $name, $args = array() ) {
$this->to_labels = $args['to']['labels'];
$this->to_max_items = $args['to']['max_items'];
}

abstract function setup();

}
26 changes: 18 additions & 8 deletions includes/UI/BlockEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,46 @@

/**
* Class BlockEditor
*
* @package TenUp\ContentConnect\UI
*/
class BlockEditor {

/**
* Setup the class.
* Setup the block editor module.
*
* @since 2.0.0
*/
public function setup() {
add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_assets' ] );
}

/**
* Enqueue block editor assets.
*
* @since 2.0.0
*/
public function enqueue_block_editor_assets() {

if ( file_exists( CONTENT_CONNECT_PATH . 'dist/js/wp-content-connect.asset.php' ) ) {
$asset_info = require CONTENT_CONNECT_PATH . 'dist/js/wp-content-connect.asset.php';
if ( file_exists( CONTENT_CONNECT_PATH . 'dist/js/block-editor.asset.php' ) ) {
$asset_info = require CONTENT_CONNECT_PATH . 'dist/js/block-editor.asset.php';

wp_enqueue_script(
'wp-content-connect',
CONTENT_CONNECT_URL . 'dist/js/wp-content-connect.js',
'wp-content-connect-block-editor',
CONTENT_CONNECT_URL . 'dist/js/block-editor.js',
$asset_info['dependencies'],
$asset_info['version'],
true
);
}

if ( file_exists( CONTENT_CONNECT_PATH . 'dist/css/admin-styles.asset.php' ) ) {
$asset_info = require CONTENT_CONNECT_PATH . 'dist/css/admin-styles.asset.php';

wp_enqueue_style(
'wp-content-connect',
CONTENT_CONNECT_URL . 'dist/css/wp-content-connect.css',
array(),
'wp-content-connect-admin-styles',
CONTENT_CONNECT_URL . 'dist/css/admin-styles.css',
$asset_info['dependencies'],
$asset_info['version']
);
}
Expand Down
Loading