initial
This commit is contained in:
+2095
File diff suppressed because it is too large
Load Diff
+609
@@ -0,0 +1,609 @@
|
||||
<?php
|
||||
/**
|
||||
* The Libraries class file.
|
||||
*
|
||||
* @package GenerateBlocks\Pattern_Library
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
if ( class_exists( 'GenerateBlocks_Libraries' ) ) :
|
||||
/**
|
||||
* Class for handling with libraries.
|
||||
*
|
||||
* @since 1.9.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Pattern_Library extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The default id.
|
||||
*
|
||||
* @var string The default library id.
|
||||
*/
|
||||
protected $default_library_id = 'gb_default_pro_library';
|
||||
|
||||
/**
|
||||
* Initialize the class filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
add_filter(
|
||||
'generateblocks_pattern_libraries',
|
||||
array( $this, 'register_pro_libraries' ),
|
||||
5
|
||||
);
|
||||
|
||||
add_action( 'wp_after_insert_post', [ $this, 'after_save' ], 10, 2 );
|
||||
add_action( 'wp_after_insert_post', [ $this, 'rebuild_trees_after_form_save' ], 20, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register PRO libraries.
|
||||
*
|
||||
* @param array $libraries The registered libraries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register_pro_libraries( array $libraries ): array {
|
||||
$libraries_instance = GenerateBlocks_Libraries::get_instance();
|
||||
|
||||
// Force to always have the PRO library registered.
|
||||
if ( ! $libraries_instance->exists( $libraries, $this->default_library_id ) ) {
|
||||
$pro_library = $this->get_default();
|
||||
$libraries = array_merge( array( $pro_library ), $libraries );
|
||||
}
|
||||
|
||||
$collections = $this->get_collections();
|
||||
|
||||
$local_libraries = array_map(
|
||||
function( WP_term $term ) use ( $libraries_instance ) {
|
||||
return $libraries_instance->create(
|
||||
array(
|
||||
'id' => $term->slug,
|
||||
'name' => $term->name,
|
||||
'domain' => get_site_url(),
|
||||
'publicKey' => $term->slug,
|
||||
'isEnabled' => false,
|
||||
'isDefault' => false,
|
||||
'isLocal' => true,
|
||||
)
|
||||
);
|
||||
},
|
||||
$collections
|
||||
);
|
||||
|
||||
return array_merge( $libraries, $local_libraries );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of collections.s
|
||||
*
|
||||
* @return int[]|string|string[]|WP_Error|WP_Term[]
|
||||
*/
|
||||
protected function get_collections() {
|
||||
return get_terms(
|
||||
[
|
||||
'taxonomy' => 'gblocks_pattern_collections',
|
||||
'hide_empty' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default library.
|
||||
*
|
||||
* @return GenerateBlocks_Library_DTO
|
||||
*/
|
||||
protected function get_default(): GenerateBlocks_Library_DTO {
|
||||
$use_legacy_pattern_library = ! function_exists( 'generateblocks_use_v1_blocks' ) ||
|
||||
generateblocks_use_v1_blocks();
|
||||
|
||||
$domain = 'https://patterns.generatepress.com';
|
||||
$public_key = 'NPhxc91jLH5yGB4Ni6KryXN6HKKggte0';
|
||||
|
||||
if (
|
||||
$use_legacy_pattern_library ||
|
||||
apply_filters( 'generateblocks_force_v1_pattern_library', false )
|
||||
) {
|
||||
$domain = 'https://patterns.generateblocks.com';
|
||||
$public_key = 'c4ngBQvKWeqG17W8SAWVJ0FuyD9uCVvq';
|
||||
}
|
||||
|
||||
return ( new GenerateBlocks_Library_DTO() )
|
||||
->set( 'id', $this->default_library_id )
|
||||
->set( 'name', __( 'Pro', 'generateblocks-pro' ) )
|
||||
->set( 'domain', $domain )
|
||||
->set( 'public_key', $public_key )
|
||||
->set( 'is_enabled', true )
|
||||
->set( 'is_default', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a stored GenerateCloud boolean permission is enabled.
|
||||
*
|
||||
* @param mixed $value The stored permission value.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_permission_enabled( $value ): bool {
|
||||
if ( true === $value || 1 === $value || '1' === $value ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( is_string( $value ) ) {
|
||||
return 'true' === strtolower( $value );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validated pattern permissions for a GenerateCloud public key.
|
||||
*
|
||||
* @param mixed $public_key The public key.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function get_pattern_permissions_by_public_key( $public_key ): ?array {
|
||||
if (
|
||||
! is_string( $public_key ) ||
|
||||
'' === $public_key ||
|
||||
! class_exists( 'GenerateCloud\Utils\Functions' )
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$public_key_post = GenerateCloud\Utils\Functions::get_public_key_post( $public_key );
|
||||
|
||||
if ( ! isset( $public_key_post->ID ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$permissions = get_post_meta( $public_key_post->ID, 'gb_permissions', true );
|
||||
|
||||
if ( ! is_array( $permissions ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$patterns = $permissions['patterns'] ?? null;
|
||||
|
||||
if ( ! is_array( $patterns ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! $this->is_permission_enabled( $patterns['enabled'] ?? false ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$includes = $patterns['includes'] ?? [];
|
||||
|
||||
if ( ! is_array( $includes ) ) {
|
||||
$includes = [];
|
||||
}
|
||||
|
||||
$collections = [];
|
||||
|
||||
foreach ( $includes as $collection ) {
|
||||
if ( ! is_numeric( $collection ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$collection = (int) $collection;
|
||||
|
||||
if ( $collection > 0 ) {
|
||||
$collections[] = $collection;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => is_string( $patterns['name'] ?? '' ) ? $patterns['name'] : '',
|
||||
'includes' => array_values( array_unique( $collections ) ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a key searches for all pattern collections.
|
||||
*
|
||||
* @param mixed $public_key The public key.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function get_collections_by_public_key( $public_key ) {
|
||||
$permissions = $this->get_pattern_permissions_by_public_key( $public_key );
|
||||
|
||||
if ( is_null( $permissions ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $permissions['includes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves our pattern tree when saving a pattern.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param WP_Post $post The post object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function after_save( int $post_id, WP_Post $post ): void {
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it is an autosave or a revision.
|
||||
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type = get_post_type( $post_id );
|
||||
|
||||
if ( 'wp_block' !== $post_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tree = $this->build_tree( $post->post_content, $post_id );
|
||||
update_post_meta( $post_id, 'generateblocks_patterns_tree', $tree );
|
||||
|
||||
// Clear our block pattern cache so it can regenerate.
|
||||
delete_option( 'generateblocks_block_patterns' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild pattern trees that reference a form whenever the form is saved.
|
||||
*
|
||||
* The cached `preview` HTML inside each `wp_block`'s
|
||||
* `generateblocks_patterns_tree` is generated once at pattern save and
|
||||
* embeds the referenced form's fields/styles at that moment. Form edits
|
||||
* therefore go stale in the inserter until the pattern is re-saved.
|
||||
* Mirror `invalidate_referencing_post_css` so a form save eagerly
|
||||
* regenerates dependent pattern previews.
|
||||
*
|
||||
* @param int $post_id Saved post ID.
|
||||
* @param WP_Post $post Saved post.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rebuild_trees_after_form_save( int $post_id, WP_Post $post ): void {
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'GenerateBlocks_Pro_Form_Post_Type' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( GenerateBlocks_Pro_Form_Post_Type::POST_TYPE !== $post->post_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pattern_ids = $this->get_pattern_ids_referencing_form( $post_id );
|
||||
|
||||
if ( empty( $pattern_ids ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rebuilt = false;
|
||||
|
||||
foreach ( $pattern_ids as $pattern_id ) {
|
||||
$pattern = get_post( $pattern_id );
|
||||
|
||||
if ( ! $pattern instanceof WP_Post || 'wp_block' !== $pattern->post_type ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tree = $this->build_tree( $pattern->post_content, $pattern->ID );
|
||||
update_post_meta( $pattern->ID, 'generateblocks_patterns_tree', $tree );
|
||||
$rebuilt = true;
|
||||
}
|
||||
|
||||
if ( $rebuilt ) {
|
||||
// Mirror after_save(): the block pattern registration cache
|
||||
// embeds preview/scripts/styles from the tree, so it has to
|
||||
// regenerate alongside the trees we just rewrote.
|
||||
delete_option( 'generateblocks_block_patterns' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find pattern post IDs whose cached tree references the given form.
|
||||
*
|
||||
* The `formRefs` array on each tree item serializes integers as
|
||||
* `i:N;`. A `LIKE` prefilter on that token avoids unserializing every
|
||||
* `generateblocks_patterns_tree` row in `wp_postmeta`; the follow-up
|
||||
* walk discards false positives (e.g. an unrelated integer that
|
||||
* happens to equal the form ID).
|
||||
*
|
||||
* @param int $form_id Form post ID.
|
||||
*
|
||||
* @return array<int>
|
||||
*/
|
||||
private function get_pattern_ids_referencing_form( int $form_id ): array {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! $wpdb || $form_id <= 0 ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$like = '%' . $wpdb->esc_like( 'i:' . $form_id . ';' ) . '%';
|
||||
|
||||
$rows = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT post_id, meta_value FROM {$wpdb->postmeta}
|
||||
WHERE meta_key = %s AND meta_value LIKE %s",
|
||||
'generateblocks_patterns_tree',
|
||||
$like
|
||||
)
|
||||
);
|
||||
|
||||
$matches = [];
|
||||
|
||||
foreach ( (array) $rows as $row ) {
|
||||
$tree = maybe_unserialize( $row->meta_value ?? '' );
|
||||
|
||||
if ( ! is_array( $tree ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $tree as $pattern ) {
|
||||
if ( ! is_array( $pattern ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$refs = $pattern['formRefs'] ?? [];
|
||||
|
||||
if ( ! is_array( $refs ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $refs as $ref ) {
|
||||
if ( (int) $ref === $form_id ) {
|
||||
$matches[] = absint( $row->post_id ?? 0 );
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values( array_unique( array_filter( $matches ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable inline styles.
|
||||
* We need a function so we can remove_action it after.
|
||||
*/
|
||||
public function enable_inline_styles() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts global styles from blocks.
|
||||
*
|
||||
* @param array $blocks The parsed blocks on the page.
|
||||
* @param array $data Optional. Additional data to be populated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function extract_global_style_selectors(
|
||||
$blocks,
|
||||
$data = [
|
||||
'selectors' => [],
|
||||
'reusableBlockIds' => [],
|
||||
'formIds' => [],
|
||||
]
|
||||
) {
|
||||
$global_styles = [];
|
||||
|
||||
if ( ! is_array( $blocks ) || empty( $blocks ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $blocks as $index => $block ) {
|
||||
if ( ! isset( $block['attrs'] ) || ! isset( $block['blockName'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$block_global_styles = $block['attrs']['globalClasses'] ?? [];
|
||||
|
||||
if ( ! empty( $block_global_styles ) ) {
|
||||
foreach ( $block_global_styles as $global_style ) {
|
||||
if ( ! in_array( $global_style, $global_styles ) ) {
|
||||
$data['selectors'][] = '.' . $global_style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'core/block' === $block['blockName'] ) {
|
||||
if ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) {
|
||||
$atts = $block['attrs'];
|
||||
|
||||
if ( isset( $atts['ref'] ) && ( empty( $data['reusableBlockIds'] ) || ! in_array( $atts['ref'], (array) $data['reusableBlockIds'] ) ) ) {
|
||||
$reusable_block = get_post( $atts['ref'] );
|
||||
|
||||
if ( $reusable_block && 'wp_block' === $reusable_block->post_type && 'publish' === $reusable_block->post_status ) {
|
||||
$reuse_data_block = parse_blocks( $reusable_block->post_content );
|
||||
|
||||
if ( ! empty( $reuse_data_block ) ) {
|
||||
$data['reusableBlockIds'][] = $atts['ref'];
|
||||
$data = $this->extract_global_style_selectors( $reuse_data_block, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'generateblocks-pro/form-render' === $block['blockName'] ) {
|
||||
$form_id = absint( $block['attrs']['formId'] ?? 0 );
|
||||
|
||||
if (
|
||||
$form_id > 0 &&
|
||||
( empty( $data['formIds'] ) || ! in_array( $form_id, (array) $data['formIds'], true ) ) &&
|
||||
class_exists( 'GenerateBlocks_Pro_Form_Post_Type' )
|
||||
) {
|
||||
$form = get_post( $form_id );
|
||||
|
||||
if (
|
||||
$form &&
|
||||
GenerateBlocks_Pro_Form_Post_Type::POST_TYPE === $form->post_type &&
|
||||
'publish' === $form->post_status
|
||||
) {
|
||||
$form_blocks = parse_blocks( $form->post_content );
|
||||
|
||||
if ( ! empty( $form_blocks ) ) {
|
||||
$data['formIds'][] = $form_id;
|
||||
$data = $this->extract_global_style_selectors( $form_blocks, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
|
||||
$data = $this->extract_global_style_selectors( $block['innerBlocks'], $data );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract form-render references from blocks.
|
||||
*
|
||||
* @param array $blocks The parsed blocks on the page.
|
||||
* @param array $data Optional. Additional data to be populated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extract_form_refs(
|
||||
$blocks,
|
||||
$data = [
|
||||
'formIds' => [],
|
||||
'reusableBlockIds' => [],
|
||||
]
|
||||
) {
|
||||
if ( ! is_array( $blocks ) || empty( $blocks ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ( $blocks as $block ) {
|
||||
if ( ! isset( $block['attrs'] ) || ! isset( $block['blockName'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'generateblocks-pro/form-render' === $block['blockName'] ) {
|
||||
$form_id = absint( $block['attrs']['formId'] ?? 0 );
|
||||
|
||||
if ( $form_id > 0 && ! in_array( $form_id, (array) $data['formIds'], true ) ) {
|
||||
$data['formIds'][] = $form_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'core/block' === $block['blockName'] ) {
|
||||
$atts = is_array( $block['attrs'] ) ? $block['attrs'] : [];
|
||||
$ref = absint( $atts['ref'] ?? 0 );
|
||||
|
||||
if ( $ref > 0 && ! in_array( $ref, (array) $data['reusableBlockIds'], true ) ) {
|
||||
$reusable_block = get_post( $ref );
|
||||
|
||||
if ( $reusable_block && 'wp_block' === $reusable_block->post_type && 'publish' === $reusable_block->post_status ) {
|
||||
$data['reusableBlockIds'][] = $ref;
|
||||
$data = $this->extract_form_refs( parse_blocks( $reusable_block->post_content ), $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
|
||||
$data = $this->extract_form_refs( $block['innerBlocks'], $data );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build our pattern tree.
|
||||
*
|
||||
* @param string $post_content The post content from our pattern.
|
||||
* @param int $post_id The ID of our post.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function build_tree( string $post_content, $post_id ): array {
|
||||
// Force our previews to print inline styles above each block.
|
||||
add_filter( 'generateblocks_do_inline_styles', [ $this, 'enable_inline_styles' ] );
|
||||
|
||||
// Get our full pattern to insert into the editor.
|
||||
$preview = do_blocks( $post_content );
|
||||
|
||||
// Get any script URLs that need to be added later.
|
||||
$scripts = [];
|
||||
$styles = [];
|
||||
|
||||
if ( strpos( $preview, 'gb-accordion' ) !== false ) {
|
||||
$scripts[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/accordion.js';
|
||||
$styles[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/accordion-style.css';
|
||||
}
|
||||
|
||||
if ( strpos( $preview, 'gb-tabs' ) !== false ) {
|
||||
$scripts[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/tabs.js';
|
||||
$styles[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/blocks/tabs/tabs.css';
|
||||
}
|
||||
|
||||
if ( strpos( $preview, 'gb-menu' ) !== false ) {
|
||||
$scripts[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/classic-menu.js';
|
||||
$styles[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/classic-menu-style.css';
|
||||
}
|
||||
|
||||
if ( strpos( $preview, 'gb-form' ) !== false ) {
|
||||
$styles[] = GENERATEBLOCKS_PRO_DIR_URL . 'dist/form-style.css';
|
||||
}
|
||||
|
||||
$blocks = parse_blocks( $post_content );
|
||||
$global_style_selectors = $this->extract_global_style_selectors( $blocks );
|
||||
$form_refs = $this->extract_form_refs( $blocks );
|
||||
|
||||
$patterns[] = [
|
||||
'id' => 'pattern-' . $post_id,
|
||||
'label' => get_the_title( $post_id ) ?? 'pattern-' . $post_id,
|
||||
'pattern' => wp_slash( $post_content ),
|
||||
'preview' => $preview,
|
||||
'scripts' => apply_filters(
|
||||
'generateblocks_pattern_preview_scripts',
|
||||
$scripts,
|
||||
[
|
||||
'preview' => $preview,
|
||||
'post_content' => $post_content,
|
||||
]
|
||||
),
|
||||
'styles' => apply_filters(
|
||||
'generateblocks_pattern_preview_styles',
|
||||
$styles,
|
||||
[
|
||||
'preview' => $preview,
|
||||
'post_content' => $post_content,
|
||||
]
|
||||
),
|
||||
'categories' => wp_get_post_terms( $post_id, 'wp_pattern_category', [ 'fields' => 'ids' ] ),
|
||||
'globalStyleSelectors' => $global_style_selectors['selectors'] ?? [],
|
||||
'formRefs' => $form_refs['formIds'] ?? [],
|
||||
];
|
||||
|
||||
// Cleanup.
|
||||
remove_filter( 'generateblocks_do_inline_styles', [ $this, 'enable_inline_styles' ] );
|
||||
|
||||
return $patterns;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Pattern_Library::get_instance()->init();
|
||||
endif;
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/**
|
||||
* The Patterns post type file.
|
||||
*
|
||||
* @package GenerateBlocksPro\Post_Types
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the core Patterns post type.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Patterns_Post_Type extends GenerateBlocks_Pro_Singleton {
|
||||
/**
|
||||
* Initialize the class filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init(): void {
|
||||
add_action( 'init', array( $this, 'register_taxonomy' ) );
|
||||
add_filter( 'register_taxonomy_args', array( $this, 'modify_taxonomy_args' ), 10, 2 );
|
||||
add_filter( 'views_edit-wp_block', array( $this, 'taxonomy_links' ) );
|
||||
add_action( 'admin_head', array( $this, 'fix_menu' ) );
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'init', array( $this, 'register_post_meta' ) );
|
||||
add_action( 'generateblocks_dashboard_tabs', array( $this, 'add_tab' ) );
|
||||
add_action( 'admin_menu', [ $this, 'add_menu' ] );
|
||||
add_action( 'admin_footer', [ $this, 'add_scripts' ] );
|
||||
add_filter( 'wp_sitemaps_taxonomies', [ $this, 'sitemaps_taxonomies' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our Dashboard menu item.
|
||||
*/
|
||||
public function add_menu() {
|
||||
add_submenu_page(
|
||||
'generateblocks',
|
||||
__( 'Local Patterns', 'generateblocks-pro' ),
|
||||
__( 'Local Patterns', 'generateblocks-pro' ),
|
||||
'manage_options',
|
||||
'edit.php?post_type=wp_block',
|
||||
'',
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue our editor scripts.
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
if ( 'wp_block' !== get_post_type() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$assets = generateblocks_pro_get_enqueue_assets( 'pattern-library' );
|
||||
|
||||
wp_enqueue_script(
|
||||
'generateblocks-pro-pattern-library',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/pattern-library.js',
|
||||
$assets['dependencies'],
|
||||
$assets['version'],
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'generateblocks-pro-pattern-library',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/pattern-library.css',
|
||||
array( 'wp-components' ),
|
||||
GENERATEBLOCKS_PRO_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our post meta.
|
||||
*/
|
||||
public function register_post_meta() {
|
||||
register_post_meta(
|
||||
'wp_block',
|
||||
'_editor_width',
|
||||
[
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'auth_callback' => function() {
|
||||
return current_user_can( 'edit_posts' );
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the taxonomy.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_taxonomy() {
|
||||
register_taxonomy(
|
||||
'gblocks_pattern_collections',
|
||||
array( 'wp_block', 'gblocks_public_keys' ),
|
||||
array(
|
||||
'public' => true,
|
||||
'publicly_queryable' => false,
|
||||
'show_in_menu' => true,
|
||||
'show_in_nav_menus' => false,
|
||||
'show_in_rest' => true,
|
||||
'show_admin_column' => true,
|
||||
'capabilities' => array(
|
||||
'manage_terms' => 'manage_categories',
|
||||
'edit_terms' => 'manage_categories',
|
||||
'delete_terms' => 'manage_categories',
|
||||
'assign_terms' => 'edit_posts',
|
||||
),
|
||||
'labels' => array(
|
||||
'name' => __( 'Collections', 'generateblocks-pro' ),
|
||||
'singular_name' => __( 'Collection', 'generateblocks-pro' ),
|
||||
'menu_name' => __( 'Collections', 'generateblocks-pro' ),
|
||||
'all_items' => __( 'All Collections', 'generateblocks-pro' ),
|
||||
'parent_item' => __( 'Parent Collection', 'generateblocks-pro' ),
|
||||
'parent_item_colon' => __( 'Parent Collection:', 'generateblocks-pro' ),
|
||||
'new_item_name' => __( 'New Collection Name', 'generateblocks-pro' ),
|
||||
'add_new_item' => __( 'Add New Collection', 'generateblocks-pro' ),
|
||||
'edit_item' => __( 'Edit Collection', 'generateblocks-pro' ),
|
||||
'update_item' => __( 'Update Collection', 'generateblocks-pro' ),
|
||||
'view_item' => __( 'View Collection', 'generateblocks-pro' ),
|
||||
'separate_items_with_commas' => __( 'Separate collections with commas', 'generateblocks-pro' ),
|
||||
'add_or_remove_items' => __( 'Add or remove collections', 'generateblocks-pro' ),
|
||||
'choose_from_most_used' => __( 'Choose from the most used', 'generateblocks-pro' ),
|
||||
'popular_items' => __( 'Popular Collections', 'generateblocks-pro' ),
|
||||
'search_items' => __( 'Search Collections', 'generateblocks-pro' ),
|
||||
'not_found' => __( 'No collections found.', 'generateblocks-pro' ),
|
||||
'no_terms' => __( 'No collections', 'generateblocks-pro' ),
|
||||
'items_list' => __( 'Collections list', 'generateblocks-pro' ),
|
||||
'items_list_navigation' => __( 'Collections list navigation', 'generateblocks-pro' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the taxonomy args.
|
||||
*
|
||||
* @param array $args The taxonomy args.
|
||||
* @param string $taxonomy The taxonomy name.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function modify_taxonomy_args( $args, $taxonomy ) {
|
||||
if ( 'gblocks_pattern_collections' !== $taxonomy ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
if ( ! $this->should_set_default_term() ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$use_default_term = apply_filters( 'generateblocks_use_default_pattern_term', true );
|
||||
|
||||
if ( $use_default_term ) {
|
||||
$args['default_term'] = array(
|
||||
'name' => __( 'Local', 'generateblocks-pro' ),
|
||||
'slug' => 'local-patterns',
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the pattern collection default term should be registered.
|
||||
*
|
||||
* WordPress checks/creates taxonomy default terms inside register_taxonomy().
|
||||
* Keeping this off normal frontend requests avoids term_exists() queries on
|
||||
* every page load. REST_REQUEST is not defined yet on init, so JSON request
|
||||
* detection keeps block editor REST saves covered.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function should_set_default_term(): bool {
|
||||
if ( is_admin() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( function_exists( 'wp_is_json_request' ) && wp_is_json_request() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return defined( 'WP_CLI' ) && WP_CLI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add links to our taxonomies.
|
||||
*
|
||||
* @param array $views Links to display above the patterns.
|
||||
*/
|
||||
public function taxonomy_links( $views ) {
|
||||
$custom_links = [];
|
||||
$custom_links[ __( 'Collections', 'generateblocks-pro' ) ] = admin_url( 'edit-tags.php?taxonomy=gblocks_pattern_collections&post_type=wp_block' );
|
||||
$custom_links[ __( 'Categories', 'generateblocks-pro' ) ] = admin_url( 'edit-tags.php?taxonomy=wp_pattern_category&post_type=wp_block' );
|
||||
|
||||
foreach ( $custom_links as $label => $url ) {
|
||||
$views[ $label ] = '<a href="' . esc_url( $url ) . '">' . $label . '</a>';
|
||||
}
|
||||
|
||||
return $views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trick the WordPress menu to highlight our Patterns menu item
|
||||
* when we're dealing with collections or categories.
|
||||
*/
|
||||
public function fix_menu() {
|
||||
global $parent_file, $submenu_file, $post_type;
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( 'edit-gblocks_pattern_collections' === $screen->id || 'edit-wp_pattern_category' === $screen->id ) {
|
||||
$parent_file = 'generateblocks'; // phpcs:ignore -- Override necessary.
|
||||
$submenu_file = 'edit.php?post_type=wp_block'; // phpcs:ignore -- Override necessary.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Local Templates tab to the GB Dashboard tabs.
|
||||
*
|
||||
* @param array $tabs The existing tabs.
|
||||
*/
|
||||
public function add_tab( $tabs ) {
|
||||
$screen = get_current_screen();
|
||||
|
||||
$tabs['local-templates'] = array(
|
||||
'name' => __( 'Local Patterns', 'generateblocks-pro' ),
|
||||
'url' => admin_url( 'edit.php?post_type=wp_block' ),
|
||||
'class' => 'edit-wp_block' === $screen->id ? 'active' : '',
|
||||
);
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a link to the legacy patterns.
|
||||
*/
|
||||
public function add_scripts() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( 'edit-wp_block' !== $screen->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$legacy_patterns_count = generateblocks_pro_get_legacy_patterns_count();
|
||||
|
||||
if ( ! $legacy_patterns_count ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$admin_settings = wp_parse_args(
|
||||
get_option( 'generateblocks_admin', array() ),
|
||||
generateblocks_pro_get_admin_option_defaults()
|
||||
);
|
||||
|
||||
if ( ! $admin_settings['enable_local_templates'] ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', () => {
|
||||
const button = document.querySelector( '.page-title-action' );
|
||||
|
||||
if ( ! button ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const legacyButton = document.createElement( 'a' );
|
||||
legacyButton.classList.add( 'page-title-action' );
|
||||
legacyButton.href = '<?php echo esc_url( admin_url( 'edit.php?post_type=gblocks_templates' ) ); ?>';
|
||||
legacyButton.textContent = '<?php echo esc_html( __( 'Legacy Patterns', 'generateblocks-pro' ) ); ?>';
|
||||
legacyButton.textContent += ' (<?php echo absint( $legacy_patterns_count ); ?>)';
|
||||
button.parentNode.insertBefore( legacyButton, button );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove our collections taxonomy from sitemaps.
|
||||
*
|
||||
* @param array $taxonomies The existing taxonomies.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sitemaps_taxonomies( $taxonomies ) {
|
||||
if ( isset( $taxonomies['gblocks_pattern_collections'] ) ) {
|
||||
unset( $taxonomies['gblocks_pattern_collections'] );
|
||||
}
|
||||
|
||||
return $taxonomies;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Patterns_Post_Type::get_instance()->init();
|
||||
Reference in New Issue
Block a user