initial
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* Block Conditions functionality.
|
||||
*
|
||||
* @package GenerateBlocksPro
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GenerateBlocks_Pro_Block_Conditions
|
||||
*/
|
||||
class GenerateBlocks_Pro_Block_Conditions extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function init() {
|
||||
// Don't initialize if block conditions are disabled.
|
||||
if ( ! generateblocks_pro_block_conditions_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'render_block', [ $this, 'check_block_conditions' ], 10, 2 );
|
||||
add_filter( 'generateblocks_condition_usage_handlers', [ $this, 'add_block_usage_handler' ], 10, 2 );
|
||||
add_filter( 'register_block_type_args', [ $this, 'add_condition_attributes' ], 10, 2 );
|
||||
add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_editor_assets' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue block editor assets for block conditions.
|
||||
*/
|
||||
public function enqueue_editor_assets() {
|
||||
$assets = generateblocks_pro_get_enqueue_assets( 'block-conditions' );
|
||||
|
||||
wp_enqueue_script(
|
||||
'generateblocks-pro-block-conditions',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/block-conditions.js',
|
||||
$assets['dependencies'],
|
||||
$assets['version'],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check block conditions and prevent rendering if conditions are not met.
|
||||
*
|
||||
* @param string $block_content The block content.
|
||||
* @param array $block The block data.
|
||||
* @return string The block content or empty string if conditions are not met.
|
||||
*/
|
||||
public function check_block_conditions( $block_content, $block ) {
|
||||
// Early return if no attributes.
|
||||
if ( empty( $block['attrs'] ) ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
$attributes = $block['attrs'];
|
||||
|
||||
// Check if this block has a condition set.
|
||||
if ( empty( $attributes['gbBlockCondition'] ) ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
$condition_id = absint( $attributes['gbBlockCondition'] );
|
||||
|
||||
// Validate condition ID.
|
||||
if ( ! $condition_id ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
// Check if the condition post exists and is published.
|
||||
$condition_post = get_post( $condition_id );
|
||||
|
||||
if ( ! $condition_post || 'publish' !== $condition_post->post_status ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
// Get the condition data.
|
||||
$display_conditions = get_post_meta( $condition_id, '_gb_conditions', true );
|
||||
|
||||
if ( empty( $display_conditions ) ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
// Pass the current post context to the conditions system.
|
||||
// This ensures conditions are evaluated for the correct post in loops.
|
||||
$context = array( 'post_id' => get_the_ID() );
|
||||
|
||||
// Use the existing conditions system to evaluate.
|
||||
$show = GenerateBlocks_Pro_Conditions::show( $display_conditions, $context );
|
||||
|
||||
// If invert is enabled, flip the result.
|
||||
if ( ! empty( $attributes['gbBlockConditionInvert'] ) ) {
|
||||
$show = ! $show;
|
||||
}
|
||||
|
||||
// Return empty string to prevent block from rendering if condition is not met.
|
||||
if ( ! $show ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add block conditions handler to usage search.
|
||||
*
|
||||
* @param array $handlers Existing handlers.
|
||||
* @param int $condition_id The condition ID.
|
||||
* @return array Modified handlers.
|
||||
*/
|
||||
public function add_block_usage_handler( $handlers, $condition_id ) {
|
||||
$handlers['block_conditions'] = [
|
||||
'method' => 'search_block_conditions_usage',
|
||||
'label' => __( 'Block Conditions', 'generateblocks-pro' ),
|
||||
];
|
||||
|
||||
return $handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add condition attributes to all blocks during server-side registration.
|
||||
* This ensures ServerSideRender calls don't fail validation.
|
||||
*
|
||||
* @param array $args The block registration arguments.
|
||||
* @param string $block_type The block type name.
|
||||
* @return array Modified arguments.
|
||||
*/
|
||||
public function add_condition_attributes( $args, $block_type ) {
|
||||
// Ensure attributes array exists.
|
||||
if ( ! isset( $args['attributes'] ) ) {
|
||||
$args['attributes'] = [];
|
||||
}
|
||||
|
||||
// Add gbBlockCondition attribute if not already defined.
|
||||
if ( ! isset( $args['attributes']['gbBlockCondition'] ) ) {
|
||||
$args['attributes']['gbBlockCondition'] = [
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
];
|
||||
}
|
||||
|
||||
// Add gbBlockConditionInvert attribute if not already defined.
|
||||
if ( ! isset( $args['attributes']['gbBlockConditionInvert'] ) ) {
|
||||
$args['attributes']['gbBlockConditionInvert'] = [
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
];
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the class.
|
||||
GenerateBlocks_Pro_Block_Conditions::get_instance()->init();
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* The class to integrate advance custom fields to dynamic content post meta.
|
||||
*
|
||||
* @package Generateblocks/Extend/DynamicContent
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* GenerateBlocks Pro Advanced custom fields integration
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Advanced_Custom_Fields extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
protected function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
if ( class_exists( 'ACF' ) ) {
|
||||
add_filter(
|
||||
'generateblocks_dynamic_content_post_meta',
|
||||
'GenerateBlocks_Pro_Advanced_Custom_Fields::load_acf_fields',
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'generateblocks_dynamic_url_post_meta',
|
||||
'GenerateBlocks_Pro_Advanced_Custom_Fields::load_link_acf_fields',
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'generateblocks_dynamic_content_author_meta',
|
||||
'GenerateBlocks_Pro_Advanced_Custom_Fields::load_author_acf_fields',
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'generateblocks_dynamic_url_author_meta',
|
||||
'GenerateBlocks_Pro_Advanced_Custom_Fields::load_author_link_acf_fields',
|
||||
10,
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load ACF fields in the frontend.
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param string|int $id The object id.
|
||||
* @param array $attributes The block attributes.
|
||||
* @param string $metaFieldKey The meta field key.
|
||||
* @param string $metaFieldPropertyNameKey The property key.
|
||||
*
|
||||
* @return mixed|string The field value.
|
||||
*/
|
||||
public static function load_acf_fields(
|
||||
$value,
|
||||
$id,
|
||||
$attributes,
|
||||
$metaFieldKey = 'metaFieldName',
|
||||
$metaFieldPropertyNameKey = 'metaFieldPropertyName'
|
||||
) {
|
||||
$field = get_field( $attributes[ $metaFieldKey ], $id );
|
||||
|
||||
if ( is_array( $field ) ) {
|
||||
if (
|
||||
isset( $attributes[ $metaFieldPropertyNameKey ] ) &&
|
||||
is_string( $attributes[ $metaFieldPropertyNameKey ] ) &&
|
||||
isset( $field[ $attributes[ $metaFieldPropertyNameKey ] ] )
|
||||
) {
|
||||
return $field[ $attributes[ $metaFieldPropertyNameKey ] ];
|
||||
}
|
||||
|
||||
// This is for backwards compatibility for dynamic images using ACF image field before 1.6.
|
||||
if ( array_key_exists( 'ID', $field ) ) {
|
||||
return $field['ID'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if (
|
||||
is_object( $field ) &&
|
||||
isset( $attributes[ $metaFieldPropertyNameKey ] ) &&
|
||||
isset( $field->{$attributes[ $metaFieldPropertyNameKey ]} )
|
||||
) {
|
||||
return $field->{$attributes[ $metaFieldPropertyNameKey ]};
|
||||
} elseif ( is_object( $field ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the author custom fields.
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param string $author_id The author id.
|
||||
* @param array $attributes The block attributes.
|
||||
*
|
||||
* @return mixed|string The field value.
|
||||
*/
|
||||
public static function load_author_acf_fields( $value, $author_id, $attributes ) {
|
||||
return self::load_acf_fields( $value, 'user_' . $author_id, $attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the link custom field.
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param string $id The object id.
|
||||
* @param array $attributes The block attributes.
|
||||
*
|
||||
* @return mixed|string The field value.
|
||||
*/
|
||||
public static function load_link_acf_fields( $value, $id, $attributes ) {
|
||||
return self::load_acf_fields(
|
||||
$value,
|
||||
$id,
|
||||
$attributes,
|
||||
'linkMetaFieldName',
|
||||
'linkMetaFieldPropertyName'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the author link custom field.
|
||||
*
|
||||
* @param mixed $value The field value.
|
||||
* @param string $author_id The author id.
|
||||
* @param array $attributes The block attributes.
|
||||
*
|
||||
* @return mixed|string The field value.
|
||||
*/
|
||||
public static function load_author_link_acf_fields( $value, $author_id, $attributes ) {
|
||||
return self::load_acf_fields(
|
||||
$value,
|
||||
'user_' . $author_id,
|
||||
$attributes,
|
||||
'linkMetaFieldName',
|
||||
'linkMetaFieldPropertyName'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Advanced_Custom_Fields::get_instance();
|
||||
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
/**
|
||||
* The class to integrate advance custom fields to dynamic content post meta.
|
||||
*
|
||||
* @package Generateblocks/Extend/DynamicTags
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* GenerateBlocks Pro Advanced custom fields integration
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Dynamic_Tags_ACF extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
|
||||
/**
|
||||
* Stored ACF option keys.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $acf_option_fields = [];
|
||||
|
||||
|
||||
/**
|
||||
* Init function
|
||||
* The post meta value.
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! class_exists( 'ACF' ) ) {
|
||||
return; // Exit if Advanced Custom Fields plugin is not active.
|
||||
}
|
||||
|
||||
add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
|
||||
|
||||
add_filter(
|
||||
'generateblocks_get_meta_pre_value',
|
||||
[ $this, 'get_meta_pre_value' ],
|
||||
10,
|
||||
5
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'generateblocks_dynamic_tags_post_record_response',
|
||||
[ $this, 'add_acf_meta_to_post_record' ],
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'generateblocks_dynamic_tags_user_record_response',
|
||||
[ $this, 'add_acf_meta_to_user_record' ],
|
||||
10,
|
||||
3
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Add appropriate meta pre values.
|
||||
*
|
||||
* @param string|null $pre_value The pre - filtered value, or null if unset.
|
||||
* @param int $id The entity ID used to fetch the meta value.
|
||||
* @param string $key The meta key to fetch.
|
||||
* @param string $callable function name to call. Should be a native WordPress function ( ex: get_post_meta).
|
||||
*/
|
||||
public function get_meta_pre_value( $pre_value, $id, $key, $callable ) {
|
||||
switch ( $callable ) {
|
||||
case 'get_post_meta':
|
||||
$value = self::get_post_meta_pre_value( $pre_value, $id, $key );
|
||||
break;
|
||||
case 'get_user_meta':
|
||||
$value = self::get_user_meta_pre_value( $pre_value, $id, $key );
|
||||
break;
|
||||
case 'get_term_meta':
|
||||
$value = self::get_term_meta_pre_value( $pre_value, $id, $key );
|
||||
break;
|
||||
case 'get_option':
|
||||
$value = self::get_option_pre_value( $pre_value, $id, $key );
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST routes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_rest_routes() {
|
||||
register_rest_route(
|
||||
'generateblocks-pro/v1',
|
||||
'/get-acf-option-fields',
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [ $this, 'get_acf_option_fields_rest' ],
|
||||
'permission_callback' => function() {
|
||||
return current_user_can( 'edit_posts' );
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This function checks if the provided key is an Advanced Custom Fields (ACF) field key.
|
||||
* If it is, the function retrieves the ACF field value using the `get_field` function. Sub fields
|
||||
* can be passed to the $key param using a "." to separate the parent and sub fields (ex: parent_child.sub_field).
|
||||
*
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @param string $value The current post meta value.
|
||||
* @param int $id The ID of the post.
|
||||
* @param string $key The post meta key.
|
||||
* @param string $type The post meta type.
|
||||
*
|
||||
* @return mixed The updated post meta value. If the key is not an ACF field key, the original value is returned.
|
||||
*/
|
||||
public function maybe_get_field( $value, $id, $key, $type = '' ) {
|
||||
|
||||
// Bail if the ACF functions are undefined.
|
||||
if ( ! function_exists( 'get_field' ) || ! function_exists( 'acf_get_meta' ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$acf_id = $type ? "{$type}_{$id}" : $id;
|
||||
$key_parts = array_map( 'trim', explode( '.', $key ) );
|
||||
$parent_name = $key_parts[0];
|
||||
$is_acf_field = false;
|
||||
$parent_is_option = 'option' === $type ? $this->is_acf_option( $parent_name ) : false;
|
||||
$acf_keys = [];
|
||||
|
||||
if ( $parent_is_option ) {
|
||||
$acf_id = 'option';
|
||||
$is_acf_field = true;
|
||||
} else {
|
||||
$acf_keys = acf_get_meta( $acf_id );
|
||||
$is_acf_field = isset( $acf_keys[ $parent_name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the ACF field check to allow for custom logic.
|
||||
*
|
||||
* @param bool $is_acf_field Whether the provided key is an ACF field key.
|
||||
* @param string|int $acf_id The ACF ID for the post. All options have the value of 'option'.
|
||||
* @param array $acf_keys The ACF keys for the $acf_id.
|
||||
* @param array $args Additional arguments: $value (the current post meta value), $id (the ID of the post), $key (the post meta key), and $type (the post meta type).
|
||||
*
|
||||
* @return bool Whether the provided key is an ACF field key.
|
||||
*/
|
||||
$is_acf_field = apply_filters(
|
||||
'generateblocks_pro_dynamic_tags_is_acf_field',
|
||||
$is_acf_field,
|
||||
$acf_id,
|
||||
$acf_keys,
|
||||
[
|
||||
$value,
|
||||
$id,
|
||||
$key,
|
||||
$type,
|
||||
]
|
||||
);
|
||||
|
||||
if ( ! $is_acf_field ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return get_field( $parent_name, $acf_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the post meta value before it's returned.
|
||||
*
|
||||
* This function checks if the provided key is an Advanced Custom Fields( ACF ) field key.
|
||||
* if it is, the function retrieves the ACF field value using the `get_field` function.
|
||||
*
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @param string $value The current post meta value.
|
||||
* @param int $post_id The ID of the post.
|
||||
* @param string $key The post meta key.
|
||||
*
|
||||
* @return mixed The updated post meta value. if the key is not an ACF field key, the original value is returned.
|
||||
*/
|
||||
public function get_post_meta_pre_value( $value, $post_id, $key ) {
|
||||
return $this->maybe_get_field( $value, $post_id, $key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the term meta value before it's returned.
|
||||
*
|
||||
* This function checks if the provided key is an Advanced Custom Fields (ACF) field key.
|
||||
* If it is, the function retrieves the ACF field value using the `get_field` function.
|
||||
*
|
||||
* @param string $value The current term meta value.
|
||||
* @param int $id The ID of the term to query meta from.
|
||||
* @param string $key The term meta key.
|
||||
*
|
||||
* @return mixed The updated post meta value. If the key is not an ACF field key, the original value is returned.
|
||||
*/
|
||||
public function get_term_meta_pre_value( $value, $id, $key ) {
|
||||
return $this->maybe_get_field( $value, $id, $key, 'term' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the user meta value before it's returned.
|
||||
*
|
||||
* This function checks if the provided key is an Advanced Custom Fields (ACF) field key.
|
||||
* If it is, the function retrieves the ACF field value using the `get_field` function.
|
||||
*
|
||||
* @param string $value The current user meta value.
|
||||
* @param int $id The ID of the user to query meta from.
|
||||
* @param string $key The user meta key.
|
||||
*
|
||||
* @return mixed The updated post meta value. If the key is not an ACF field key, the original value is returned.
|
||||
*/
|
||||
public function get_user_meta_pre_value( $value, $id, $key ) {
|
||||
return $this->maybe_get_field( $value, $id, $key, 'user' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the option value before it's returned.
|
||||
*
|
||||
* This function checks if the provided key is an Advanced Custom Fields (ACF) field key.
|
||||
* If it is, the function retrieves the ACF field value using the `get_field` function.
|
||||
*
|
||||
* @param string $value The current option meta value.
|
||||
* @param int $id The ACF ID of the option to retrieve.
|
||||
* @param string $key The option key.
|
||||
*
|
||||
* @return mixed The updated post meta value. If the key is not an ACF field key, the original value is returned.
|
||||
*/
|
||||
public function get_option_pre_value( $value, $id, $key ) {
|
||||
return $this->maybe_get_field( $value, $id, $key, 'option' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the post record to include ACF meta field keys and values.
|
||||
*
|
||||
* @param object $response Post object from the response.
|
||||
* @param int $id ID of the post record.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function add_acf_meta_to_post_record( $response, $id ) {
|
||||
|
||||
// Stop here if the ACF functions are undefined.
|
||||
if ( ! function_exists( 'acf_get_meta' ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$acf_meta = acf_get_meta( $id );
|
||||
|
||||
if ( $acf_meta ) {
|
||||
|
||||
$response->acf = array_filter(
|
||||
$acf_meta,
|
||||
function ( $key ) {
|
||||
return strpos( $key, '_' ) !== 0;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters the user record to include ACF meta field keys and values.
|
||||
*
|
||||
* @param object $response Post object from the response.
|
||||
* @param int $id ID of the post record.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function add_acf_meta_to_user_record( $response, $id ) {
|
||||
|
||||
// Stop here if the ACF functions are undefined.
|
||||
if ( ! function_exists( 'acf_get_meta' ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$acf_meta = acf_get_meta( "user_$id" );
|
||||
|
||||
if ( $acf_meta ) {
|
||||
|
||||
$response->acf = array_filter(
|
||||
$acf_meta,
|
||||
function ( $key ) {
|
||||
return strpos( $key, '_' ) !== 0;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all ACf option fields using the default option prefix.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_acf_option_fields() {
|
||||
if ( ! function_exists( 'acf_get_option_meta' ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$options = array_filter(
|
||||
acf_get_option_meta( 'options' ),
|
||||
function( $key ) {
|
||||
return strpos( $key, '_' ) !== 0;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
$response = [];
|
||||
|
||||
foreach ( $options as $key => $array_value ) {
|
||||
$response[ $key ] = $array_value[0];
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rest controller for get-acf-option-fields.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public function get_acf_option_fields_rest() {
|
||||
if ( ! $this->acf_option_fields ) {
|
||||
$this->acf_option_fields = $this->get_acf_option_fields();
|
||||
}
|
||||
|
||||
return rest_ensure_response( $this->acf_option_fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given field name is an ACF option or not.
|
||||
*
|
||||
* @param string $field_name The name of the field to check.
|
||||
* @return bool Return true if the option is an ACF option.
|
||||
*/
|
||||
public function is_acf_option( $field_name ) {
|
||||
if ( ! $this->acf_option_fields ) {
|
||||
$this->acf_option_fields = $this->get_acf_option_fields();
|
||||
}
|
||||
|
||||
return isset( $this->acf_option_fields[ $field_name ] );
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Dynamic_Tags_ACF::get_instance()->init();
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* The class to integrate adjacent post dynamic tags.
|
||||
*
|
||||
* @package Generateblocks/Extend/DynamicTags
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* GenerateBlocks Pro adjacted post dynamic tags.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Dynamic_Tags_Adjacent_Posts extends GenerateBlocks_Pro_Singleton {
|
||||
/**
|
||||
* Init.
|
||||
*/
|
||||
public function init() {
|
||||
add_filter( 'generateblocks_dynamic_tag_id', array( $this, 'set_adjacent_post_ids' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set adjacent post ids.
|
||||
*
|
||||
* @param int $id The post id.
|
||||
* @param array $options The options.
|
||||
*/
|
||||
public function set_adjacent_post_ids( $id, $options ) {
|
||||
$source = $options['source'] ?? '';
|
||||
|
||||
if ( 'next-post' === $source ) {
|
||||
$in_same_term = $options['inSameTerm'] ?? false;
|
||||
$term_taxonomy = $options['sameTermTaxonomy'] ?? 'category';
|
||||
$next_post = get_next_post( $in_same_term, '' );
|
||||
|
||||
if ( ! is_object( $next_post ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $next_post->ID;
|
||||
}
|
||||
|
||||
if ( 'previous-post' === $source ) {
|
||||
$in_same_term = $options['inSameTerm'] ?? false;
|
||||
$term_taxonomy = $options['sameTermTaxonomy'] ?? 'category';
|
||||
$previous_post = get_previous_post( $in_same_term, '', $term_taxonomy );
|
||||
|
||||
if ( ! is_object( $previous_post ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $previous_post->ID;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Dynamic_Tags_Adjacent_Posts::get_instance()->init();
|
||||
+502
@@ -0,0 +1,502 @@
|
||||
<?php
|
||||
/**
|
||||
* The Dynamic Tags class file.
|
||||
*
|
||||
* @package GenerateBlocks_Pro\Dynamic_Tags
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for handling dynamic tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Dynamic_Tags_Register extends GenerateBlocks_Pro_Singleton {
|
||||
/**
|
||||
* Initialize all hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
if ( ! class_exists( 'GenerateBlocks_Register_Dynamic_Tag' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'init', [ $this, 'register' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the tags.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register() {
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Archive Title', 'generateblocks-pro' ),
|
||||
'tag' => 'archive_title',
|
||||
'type' => 'archive',
|
||||
'supports' => [],
|
||||
'description' => __( 'Get the title for the current archive being viewed.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_archive_title' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Archive Description', 'generateblocks-pro' ),
|
||||
'tag' => 'archive_description',
|
||||
'type' => 'archive',
|
||||
'supports' => [],
|
||||
'description' => __( 'Get the description for the current archive being viewed.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_archive_description' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Option', 'generateblocks-pro' ),
|
||||
'tag' => 'option',
|
||||
'type' => 'option',
|
||||
'supports' => [ 'meta' ],
|
||||
'return' => [ $this, 'get_option' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Term Meta', 'generateblocks-pro' ),
|
||||
'tag' => 'term_meta',
|
||||
'type' => 'term',
|
||||
'supports' => [ 'meta', 'source' ],
|
||||
'description' => __( 'Access term meta by key for the specified term. Return value must be a string.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_term_meta' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'User Meta', 'generateblocks-pro' ),
|
||||
'tag' => 'user_meta',
|
||||
'type' => 'user',
|
||||
'supports' => [ 'meta', 'source' ],
|
||||
'description' => __( 'Access user meta by key for the specified user. Return value must be a string.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_user_meta' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Current year', 'generateblocks-pro' ),
|
||||
'tag' => 'current_year',
|
||||
'type' => 'site',
|
||||
'supports' => [],
|
||||
'return' => [ $this, 'get_current_year' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Site Title', 'generateblocks-pro' ),
|
||||
'tag' => 'site_title',
|
||||
'type' => 'site',
|
||||
'supports' => [],
|
||||
'return' => [ $this, 'get_site_title' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Site Tagline', 'generateblocks-pro' ),
|
||||
'tag' => 'site_tagline',
|
||||
'type' => 'site',
|
||||
'supports' => [],
|
||||
'return' => [ $this, 'get_site_tagline' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Site Logo URL', 'generateblocks-pro' ),
|
||||
'tag' => 'site_logo_url',
|
||||
'type' => 'site',
|
||||
'supports' => [],
|
||||
'return' => [ $this, 'get_site_logo_url' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Site URL', 'generateblocks-pro' ),
|
||||
'tag' => 'site_url',
|
||||
'type' => 'site',
|
||||
'supports' => [],
|
||||
'return' => [ $this, 'get_site_url' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Loop Index', 'generateblocks-pro' ),
|
||||
'tag' => 'loop_index',
|
||||
'type' => 'looper',
|
||||
'supports' => [],
|
||||
'visibility' => [
|
||||
'context' => [
|
||||
'generateblocks/loopIndex',
|
||||
],
|
||||
],
|
||||
'options' => [
|
||||
'zeroBased' => [
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Use zero-based index', 'generateblocks-pro' ),
|
||||
'help' => __( 'Enable this to start the loop index count from 0.', 'generateblocks-pro' ),
|
||||
],
|
||||
],
|
||||
'description' => __( 'The numbered index of the loop item.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_loop_index' ],
|
||||
]
|
||||
);
|
||||
|
||||
new GenerateBlocks_Register_Dynamic_Tag(
|
||||
[
|
||||
'title' => __( 'Loop Item', 'generateblocks-pro' ),
|
||||
'tag' => 'loop_item',
|
||||
'type' => 'looper',
|
||||
'supports' => [ 'properties' ],
|
||||
'visibility' => [
|
||||
'context' => [
|
||||
'generateblocks/loopItem',
|
||||
],
|
||||
],
|
||||
'description' => __( 'The current loop item data.', 'generateblocks-pro' ),
|
||||
'return' => [ $this, 'get_loop_item' ],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the archive title.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param object $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_archive_title( $options, $block, $instance ) {
|
||||
$output = '';
|
||||
$id = $options['id'] ?? 0;
|
||||
|
||||
if ( is_category() ) {
|
||||
$output = single_cat_title( '', false );
|
||||
} elseif ( is_tag() ) {
|
||||
$output = single_tag_title( '', false );
|
||||
} elseif ( is_author() ) {
|
||||
$output = get_the_author();
|
||||
} elseif ( is_post_type_archive() ) {
|
||||
$output = post_type_archive_title( '', false );
|
||||
} elseif ( is_tax() ) {
|
||||
$output = single_term_title( '', false );
|
||||
} elseif ( is_home() ) {
|
||||
$page = get_option( 'page_for_posts' ) ?? 0;
|
||||
|
||||
if ( $page ) {
|
||||
$output = get_the_title( $page );
|
||||
} else {
|
||||
$output = __( 'Blog', 'generateblocks-pro' );
|
||||
}
|
||||
} elseif ( is_search() ) {
|
||||
$output = get_search_query();
|
||||
} elseif ( $id ) {
|
||||
if ( term_exists( (int) $id ) ) {
|
||||
$term = get_term( $id );
|
||||
$output = $term->name;
|
||||
} elseif ( is_string( $id ) ) {
|
||||
// Assume it's a post type archive title.
|
||||
$post_type_obj = get_post_type_object( $id );
|
||||
$title = $post_type_obj->labels->name ?? '';
|
||||
|
||||
if ( $title ) {
|
||||
/**
|
||||
* Core Filter. Filters the post type archive title.
|
||||
*
|
||||
* @param string $post_type_name Post type 'name' label.
|
||||
* @param string $post_type Post type.
|
||||
*/
|
||||
$output = apply_filters( 'post_type_archive_title', $title, $id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the archive description.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param object $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_archive_description( $options, $block, $instance ) {
|
||||
$output = get_the_archive_description();
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the option.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_option( $options ) {
|
||||
$default = $options['default'] ?? '';
|
||||
$key = $options['key'] ?? '';
|
||||
$key_parts = array_map( 'trim', explode( '.', $key ) );
|
||||
$parent_name = $key_parts[0];
|
||||
$output = '';
|
||||
|
||||
if ( empty( $key ) ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options );
|
||||
}
|
||||
|
||||
$allowed_options = [
|
||||
'siteurl',
|
||||
'blogname',
|
||||
'blogdescription',
|
||||
'home',
|
||||
'time_format',
|
||||
'user_count',
|
||||
];
|
||||
|
||||
$acf_keys = array_keys(
|
||||
GenerateBlocks_Pro_Dynamic_Tags_ACF::get_instance()->get_acf_option_fields()
|
||||
);
|
||||
|
||||
/**
|
||||
* $allowed_options contains an array of keys from the options table along with the
|
||||
* acf option keys. Disallowed keys will return an empty string.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param array $allowed_options Array of allowed option keys.
|
||||
*/
|
||||
$allowed_options = apply_filters(
|
||||
'generateblocks_dynamic_tags_allowed_options',
|
||||
array_merge( $allowed_options, $acf_keys )
|
||||
);
|
||||
|
||||
if ( ! in_array( $parent_name, $allowed_options, true ) ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options );
|
||||
|
||||
}
|
||||
|
||||
$value = GenerateBlocks_Meta_Handler::get_option( $key, true, $default );
|
||||
|
||||
if ( ! $value ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options );
|
||||
}
|
||||
|
||||
add_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
$output = wp_kses_post( $value );
|
||||
remove_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the term meta.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_term_meta( $options, $block, $instance ) {
|
||||
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'term', $instance );
|
||||
|
||||
if ( ! $id ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( '', $options, $instance );
|
||||
}
|
||||
|
||||
$key = $options['key'] ?? '';
|
||||
$output = '';
|
||||
|
||||
if ( empty( $key ) ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
$value = GenerateBlocks_Meta_Handler::get_term_meta( $id, $key, true );
|
||||
|
||||
if ( ! $value ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
add_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
$output = wp_kses_post( $value );
|
||||
remove_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user meta.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_user_meta( $options, $block, $instance ) {
|
||||
$id = GenerateBlocks_Dynamic_Tags::get_id( $options, 'user', $instance );
|
||||
|
||||
if ( ! $id ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( '', $options, $instance );
|
||||
}
|
||||
|
||||
$key = $options['key'] ?? '';
|
||||
$output = '';
|
||||
|
||||
if ( empty( $key ) ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
$value = GenerateBlocks_Meta_Handler::get_user_meta( $id, $key, true );
|
||||
|
||||
if ( ! $value ) {
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
add_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
$output = wp_kses_post( $value );
|
||||
remove_filter( 'wp_kses_allowed_html', [ 'GenerateBlocks_Dynamic_Tags', 'expand_allowed_html' ], 10, 2 );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current year.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_current_year( $options, $block, $instance ) {
|
||||
$output = wp_date( 'Y' );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site title from settings.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_title( $options, $block, $instance ) {
|
||||
$output = get_option( 'blogname' );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site tagline from settings.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_tagline( $options, $block, $instance ) {
|
||||
$output = get_option( 'blogdescription' );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site logo URL.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_logo_url( $options, $block, $instance ) {
|
||||
$custom_logo_id = get_theme_mod( 'custom_logo' );
|
||||
$output = '';
|
||||
|
||||
if ( $custom_logo_id ) {
|
||||
$url = wp_get_attachment_url( $custom_logo_id );
|
||||
|
||||
if ( $url ) {
|
||||
$output = esc_url( $url );
|
||||
}
|
||||
}
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the site URL.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_site_url( $options, $block, $instance ) {
|
||||
$output = esc_url( site_url() );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the current looper block loop.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return int The loop index number.
|
||||
*/
|
||||
public static function get_loop_index( $options, $block, $instance ) {
|
||||
$use_zero_based = $options['zeroBased'] ?? false;
|
||||
$loop_index = (int) isset( $instance->context['generateblocks/loopIndex'] )
|
||||
? $instance->context['generateblocks/loopIndex']
|
||||
: -1;
|
||||
|
||||
if ( $use_zero_based ) {
|
||||
--$loop_index;
|
||||
}
|
||||
|
||||
if ( $loop_index > -1 ) {
|
||||
return (string) $loop_index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current loop item.
|
||||
*
|
||||
* @param array $options The options.
|
||||
* @param array $block The block.
|
||||
* @param object $instance The block instance.
|
||||
* @return string Value of the loop item or a given key's value from the loop item.
|
||||
*/
|
||||
public static function get_loop_item( $options, $block, $instance ) {
|
||||
$key = $options['key'] ?? '';
|
||||
$fallback = $options['fallback'] ?? '';
|
||||
$loop_item = $instance->context['generateblocks/loopItem'] ?? [];
|
||||
$output = GenerateBlocks_Meta_Handler::get_value( $key, $loop_item, true, $fallback );
|
||||
|
||||
return GenerateBlocks_Dynamic_Tag_Callbacks::output( $output, $options, $instance );
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Dynamic_Tags_Register::get_instance()->init();
|
||||
+455
@@ -0,0 +1,455 @@
|
||||
<?php
|
||||
/**
|
||||
* This file handles the Accordion functions.
|
||||
*
|
||||
* @package GenerateBlocksPro/Extend/Interactions/Accordion
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Accordion functions.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Block_Variant_Accordion extends GenerateBlocks_Pro_Singleton {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
if ( ! version_compare( GENERATEBLOCKS_VERSION, '1.7.0-alpha.1', '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'generateblocks_defaults', [ $this, 'set_defaults' ] );
|
||||
add_filter( 'generateblocks_after_container_open', [ $this, 'enqueue_scripts' ], 10, 2 );
|
||||
add_filter( 'generateblocks_attr_container', [ $this, 'set_container_attributes' ], 10, 4 );
|
||||
add_filter( 'generateblocks_attr_dynamic-button', [ $this, 'set_button_attributes' ], 10, 2 );
|
||||
add_action( 'generateblocks_block_one_time_css_data', [ $this, 'generate_css' ], 10, 3 );
|
||||
add_action( 'generateblocks_block_css_data', [ $this, 'do_dynamic_css' ], 10, 3 );
|
||||
add_filter( 'generateblocks_before_container_open', [ $this, 'open_accordion_content_container' ], 1, 3 );
|
||||
add_filter( 'generateblocks_after_container_close', [ $this, 'close_accordion_content_container' ], 100, 3 );
|
||||
add_filter( 'generateblocks_onboarding_user_meta_properties', [ $this, 'define_add_accordion_item_onboarding_property' ], 10, 1 );
|
||||
add_filter( 'register_block_type_args', [ $this, 'block_type_args' ], 10, 2 );
|
||||
add_action( 'wp_footer', [ $this, 'faq_schema_script' ] );
|
||||
add_filter( 'render_block', [ $this, 'gather_schema_data' ], 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our attribute defaults.
|
||||
*
|
||||
* @param array $defaults Existing defaults.
|
||||
*/
|
||||
public function set_defaults( $defaults ) {
|
||||
$defaults['container']['accordionItemOpen'] = false;
|
||||
$defaults['container']['accordionMultipleOpen'] = false;
|
||||
$defaults['container']['accordionTransition'] = '';
|
||||
$defaults['button']['accordionItemOpen'] = false;
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue our accordion script.
|
||||
*
|
||||
* @param string $content Block content.
|
||||
* @param array $attributes Block attributes.
|
||||
*/
|
||||
public function enqueue_scripts( $content, $attributes ) {
|
||||
if ( ! empty( $attributes['variantRole'] ) && 'accordion' === $attributes['variantRole'] ) {
|
||||
wp_enqueue_script(
|
||||
'generateblocks-accordion',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/accordion.js',
|
||||
array(),
|
||||
GENERATEBLOCKS_PRO_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our Container block HTML attributes.
|
||||
*
|
||||
* @param array $attributes HTML attributes.
|
||||
* @param array $settings Block settings.
|
||||
* @param string $context Context of the filter.
|
||||
* @param WP_Block $block Block instance.
|
||||
*/
|
||||
public function set_container_attributes( $attributes, $settings, $context, $block ) {
|
||||
if ( isset( $settings['variantRole'] ) && 'accordion' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-accordion';
|
||||
|
||||
if ( $settings['accordionMultipleOpen'] ) {
|
||||
$attributes['data-accordion-multiple-open'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $settings['variantRole'] ) && 'accordion-item' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-accordion__item';
|
||||
|
||||
if ( $settings['accordionItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-accordion__item-open';
|
||||
}
|
||||
|
||||
if ( $settings['accordionTransition'] ) {
|
||||
$attributes['data-transition'] = $settings['accordionTransition'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $settings['variantRole'] ) && 'accordion-content' === $settings['variantRole'] ) {
|
||||
$transition = isset( $block->context['generateblocks-pro/accordionTransition'] )
|
||||
? $block->context['generateblocks-pro/accordionTransition']
|
||||
: '';
|
||||
|
||||
if ( 'slide' !== $transition ) {
|
||||
$attributes['class'] .= ' gb-accordion__content';
|
||||
}
|
||||
|
||||
// Unset the accordion content ID. This ID is added to the wrapping div
|
||||
// in the open_accordion_content_container function.
|
||||
$attributes['id'] = '';
|
||||
}
|
||||
|
||||
if ( isset( $settings['variantRole'] ) && 'accordion-toggle' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-accordion__toggle';
|
||||
|
||||
if ( $settings['accordionItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-block-is-current';
|
||||
}
|
||||
|
||||
$attributes['role'] = 'button';
|
||||
$attributes['tabindex'] = '0';
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our dynamic Button block HTML attributes.
|
||||
*
|
||||
* @param array $attributes HTML attributes.
|
||||
* @param array $settings Block settings.
|
||||
*/
|
||||
public function set_button_attributes( $attributes, $settings ) {
|
||||
if ( isset( $settings['variantRole'] ) && 'accordion-toggle' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-accordion__toggle';
|
||||
|
||||
if ( $settings['accordionItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-block-is-current';
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate our one-time accordion CSS.
|
||||
*
|
||||
* @param string $name The block name.
|
||||
* @param array $settings Block settings.
|
||||
* @param object $css The CSS object.
|
||||
*/
|
||||
public function generate_css( $name, $settings, $css ) {
|
||||
if ( 'button' === $name ) {
|
||||
$css->set_selector( '.gb-accordion__item:not(.gb-accordion__item-open) > .gb-button .gb-accordion__icon-open' );
|
||||
$css->add_property( 'display', 'none' );
|
||||
|
||||
$css->set_selector( '.gb-accordion__item.gb-accordion__item-open > .gb-button .gb-accordion__icon' );
|
||||
$css->add_property( 'display', 'none' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate our CSS for our options.
|
||||
*
|
||||
* @since 1.0
|
||||
* @param string $name Name of the block.
|
||||
* @param array $settings Our available settings.
|
||||
* @param object $css Current desktop CSS object.
|
||||
*/
|
||||
public function do_dynamic_css( $name, $settings, $css ) {
|
||||
if ( 'container' === $name && isset( $settings['variantRole'] ) ) {
|
||||
$accordion_transition = ! empty( $settings['accordionTransition'] ) ? $settings['accordionTransition'] : '';
|
||||
$selector = function_exists( 'generateblocks_get_css_selector' )
|
||||
? generateblocks_get_css_selector( 'container', $settings )
|
||||
: '.gb-container-' . $settings['uniqueId'];
|
||||
|
||||
if ( 'accordion-item' === $settings['variantRole'] ) {
|
||||
if ( '' === $accordion_transition || 'fade' === $accordion_transition ) {
|
||||
$css->set_selector( $selector . ':not(.gb-accordion__item-open) > .gb-accordion__content' );
|
||||
$css->add_property( 'display', 'none' );
|
||||
|
||||
if ( 'fade' === $accordion_transition ) {
|
||||
$css->set_selector( $selector . '.gb-accordion__item-open > .gb-accordion__content' );
|
||||
$css->add_property( 'opacity', 1 );
|
||||
|
||||
$css->set_selector( $selector . '.gb-accordion__item-transition > .gb-accordion__content' );
|
||||
$css->add_property( 'opacity', 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'slide' === $accordion_transition ) {
|
||||
$css->set_selector( $selector . ' > .gb-accordion__content' );
|
||||
$css->add_property( 'will-change', 'max-height' );
|
||||
$css->add_property( 'max-height', 0 );
|
||||
$css->add_property( 'overflow', 'hidden' );
|
||||
$css->add_property( 'visibility', 'hidden' );
|
||||
|
||||
$css->set_selector( $selector . '.gb-accordion__item-open > .gb-accordion__content' );
|
||||
$css->add_property( 'max-height', 'inherit' );
|
||||
$css->add_property( 'visibility', 'visible' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'accordion-toggle' === $settings['variantRole'] ) {
|
||||
$css->set_selector( $selector );
|
||||
$css->add_property( 'cursor', 'pointer' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject our opening accordion content div.
|
||||
*
|
||||
* @param string $content Block content.
|
||||
* @param array $attributes Block attributes.
|
||||
* @param WP_Block $block Block instance.
|
||||
*/
|
||||
public function open_accordion_content_container( $content, $attributes, $block ) {
|
||||
$transition = isset( $block->context['generateblocks-pro/accordionTransition'] )
|
||||
? $block->context['generateblocks-pro/accordionTransition']
|
||||
: '';
|
||||
|
||||
if ( isset( $attributes['variantRole'] ) && 'accordion-content' === $attributes['variantRole'] && 'slide' === $transition ) {
|
||||
if ( ! empty( $attributes['anchor'] ) ) {
|
||||
$content = '<div id="' . esc_attr( $attributes['anchor'] ) . '" class="gb-accordion__content">' . $content;
|
||||
} else {
|
||||
$content = '<div class="gb-accordion__content">' . $content;
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject our closing accordion content div.
|
||||
*
|
||||
* @param string $content Block content.
|
||||
* @param array $attributes Block attributes.
|
||||
* @param WP_Block $block Block instance.
|
||||
*/
|
||||
public function close_accordion_content_container( $content, $attributes, $block ) {
|
||||
$transition = isset( $block->context['generateblocks-pro/accordionTransition'] )
|
||||
? $block->context['generateblocks-pro/accordionTransition']
|
||||
: '';
|
||||
|
||||
if ( isset( $attributes['variantRole'] ) && 'accordion-content' === $attributes['variantRole'] && 'slide' === $transition ) {
|
||||
$content .= '</div>';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the onboarding key for adding accordion items.
|
||||
*
|
||||
* @param array $properties The registered keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function define_add_accordion_item_onboarding_property( $properties ) {
|
||||
$properties['add_accordion_item'] = array( 'type' => 'boolean' );
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter block args.
|
||||
*
|
||||
* @param array $args Existing args.
|
||||
* @param string $name The block name.
|
||||
*/
|
||||
public function block_type_args( $args, $name ) {
|
||||
if ( 'generateblocks/container' === $name ) {
|
||||
if ( ! isset( $args['provides_context'] ) || ! is_array( $args['provides_context'] ) ) {
|
||||
$args['provides_context'] = [];
|
||||
}
|
||||
|
||||
$args['provides_context'] = array_merge(
|
||||
$args['provides_context'],
|
||||
[
|
||||
'generateblocks-pro/accordionTransition' => 'accordionTransition',
|
||||
'generateblocks-pro/faqSchema' => 'faqSchema',
|
||||
]
|
||||
);
|
||||
|
||||
if ( ! isset( $args['uses_context'] ) || ! is_array( $args['uses_context'] ) ) {
|
||||
$args['uses_context'] = [];
|
||||
}
|
||||
|
||||
$args['uses_context'] = array_merge(
|
||||
$args['uses_context'],
|
||||
[
|
||||
'generateblocks-pro/accordionTransition',
|
||||
'generateblocks-pro/faqSchema',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'generateblocks/button' === $name ) {
|
||||
if ( ! isset( $args['provides_context'] ) || ! is_array( $args['provides_context'] ) ) {
|
||||
$args['provides_context'] = [];
|
||||
}
|
||||
|
||||
$args['provides_context'] = array_merge(
|
||||
$args['provides_context'],
|
||||
[
|
||||
'generateblocks-pro/faqSchema' => 'faqSchema',
|
||||
]
|
||||
);
|
||||
|
||||
if ( ! isset( $args['uses_context'] ) || ! is_array( $args['uses_context'] ) ) {
|
||||
$args['uses_context'] = [];
|
||||
}
|
||||
|
||||
$args['uses_context'] = array_merge(
|
||||
$args['uses_context'],
|
||||
[
|
||||
'generateblocks-pro/faqSchema',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all HTML and line-breaks/whitespace from the content.
|
||||
*
|
||||
* @param string $content The block content.
|
||||
*/
|
||||
public static function strip_html( $content ) {
|
||||
$allowed_tags = [ '<h1>', '<h2>', '<h3>', '<h4>', '<h5>', '<h6>', '<br>', '<ol>', '<ul>', '<li>', '<a>', '<p>', '<b>', '<strong>', '<i>', '<em>' ];
|
||||
$allowed_tags = implode( '', $allowed_tags );
|
||||
$block_text = strip_tags( $content, $allowed_tags );
|
||||
$block_text = preg_replace( "/\n/", '', $block_text ); // Remove new lines.
|
||||
|
||||
return $block_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather FAQ schema from accordions.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @param string $block_content The block content.
|
||||
* @param array $block The block attributes/data.
|
||||
* @param WP_Block $instance The block instance.
|
||||
* @return array
|
||||
*/
|
||||
public function gather_schema_data( $block_content, $block, $instance ) {
|
||||
if (
|
||||
isset( $block['attrs']['variantRole'] ) &&
|
||||
isset( $instance->context ) &&
|
||||
! empty( $instance->context['generateblocks-pro/faqSchema'] )
|
||||
) {
|
||||
if ( 'accordion-toggle' === $block['attrs']['variantRole'] ) {
|
||||
add_filter(
|
||||
'generateblocks_faq_schema_data',
|
||||
function( $data ) use ( $block_content ) {
|
||||
$data[] = [ 'question' => self::strip_html( $block_content ) ];
|
||||
|
||||
return $data;
|
||||
},
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'accordion-content' === $block['attrs']['variantRole'] ) {
|
||||
add_filter(
|
||||
'generateblocks_faq_schema_data',
|
||||
function( $data ) use ( $block_content ) {
|
||||
foreach ( $data as $key => $info ) {
|
||||
// If we have a question but no answer, assume this is the answer.
|
||||
if ( ! empty( $info['question'] ) && empty( $info['answer'] ) ) {
|
||||
preg_match( '/<img.+src=[\'"](?P<src>.+?)[\'"].*>/i', $block_content, $image );
|
||||
|
||||
if ( ! empty( $image['src'] ) ) {
|
||||
$data[ $key ]['image'] = $image['src'];
|
||||
}
|
||||
|
||||
$data[ $key ]['answer'] = self::strip_html( $block_content );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the accordion FAQ schema to the footer.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public function faq_schema_script() {
|
||||
$faq_schema_data = apply_filters(
|
||||
'generateblocks_faq_schema_data',
|
||||
[]
|
||||
);
|
||||
|
||||
if ( empty( $faq_schema_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove any duplicated questions/answers.
|
||||
// @see https://stackoverflow.com/a/308955.
|
||||
$serialized = array_map( 'json_encode', $faq_schema_data );
|
||||
$unique = array_unique( $serialized );
|
||||
$faq_schema_data = array_values( array_intersect_key( $faq_schema_data, $unique ) );
|
||||
|
||||
$faq_schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'FAQPage',
|
||||
'name' => get_the_title(),
|
||||
'mainEntity' => [],
|
||||
];
|
||||
|
||||
foreach ( $faq_schema_data as $data ) {
|
||||
$question = [
|
||||
'@type' => 'Question',
|
||||
'name' => $data['question'],
|
||||
'acceptedAnswer' => [
|
||||
'@type' => 'Answer',
|
||||
'text' => $data['answer'],
|
||||
],
|
||||
];
|
||||
|
||||
if ( ! empty( $data['image'] ) ) {
|
||||
$question['acceptedAnswer']['image'] = [
|
||||
'@type' => 'ImageObject',
|
||||
'contentUrl' => esc_url_raw( $data['image'] ),
|
||||
];
|
||||
}
|
||||
|
||||
$faq_schema['mainEntity'][] = $question;
|
||||
}
|
||||
|
||||
if ( count( $faq_schema['mainEntity'] ) > 0 ) {
|
||||
printf( '<script type="application/ld+json">%s</script>', wp_json_encode( $faq_schema ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Block_Variant_Accordion::get_instance();
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Our Tabs block.
|
||||
*
|
||||
* @package GenerateBlocks/Extend/Interactions/Tabs
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* GenerateBlocks Pro Tabs.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Tabs_Variation extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
protected function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
if ( ! version_compare( GENERATEBLOCKS_VERSION, '1.7.0-alpha.1', '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'generateblocks_defaults', [ $this, 'set_defaults' ] );
|
||||
add_action( 'generateblocks_block_one_time_css_data', [ $this, 'generate_css' ], 10, 3 );
|
||||
add_action( 'generateblocks_block_css_data', [ $this, 'do_dynamic_css' ], 10, 3 );
|
||||
add_filter( 'generateblocks_attr_container', [ $this, 'set_container_attributes' ], 10, 2 );
|
||||
add_filter( 'generateblocks_attr_dynamic-button', [ $this, 'set_button_attributes' ], 10, 2 );
|
||||
add_filter( 'generateblocks_after_container_open', [ $this, 'enqueue_scripts' ], 10, 2 );
|
||||
add_filter( 'generateblocks_onboarding_user_meta_properties', [ $this, 'define_add_tab_item_onboarding_property' ], 10, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our attribute defaults.
|
||||
*
|
||||
* @param array $defaults Existing defaults.
|
||||
*/
|
||||
public function set_defaults( $defaults ) {
|
||||
$defaults['container']['defaultOpenedTab'] = '';
|
||||
$defaults['container']['tabItemOpen'] = false;
|
||||
$defaults['container']['tabTransition'] = '';
|
||||
$defaults['container']['borderColorCurrent'] = false;
|
||||
$defaults['container']['backgroundColorCurrent'] = '';
|
||||
$defaults['container']['textColorCurrent'] = '';
|
||||
$defaults['button']['tabItemOpen'] = false;
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue our tabs script.
|
||||
*
|
||||
* @param string $content Block content.
|
||||
* @param array $attributes Block attributes.
|
||||
*/
|
||||
public function enqueue_scripts( $content, $attributes ) {
|
||||
if ( ! empty( $attributes['variantRole'] ) && 'tabs' === $attributes['variantRole'] ) {
|
||||
wp_enqueue_script(
|
||||
'generateblocks-tabs',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/tabs.js',
|
||||
array(),
|
||||
GENERATEBLOCKS_PRO_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate our one-time tabs CSS.
|
||||
*
|
||||
* @param string $name The block name.
|
||||
* @param array $settings Block settings.
|
||||
* @param object $css The CSS object.
|
||||
*/
|
||||
public function generate_css( $name, $settings, $css ) {
|
||||
if ( 'container' === $name ) {
|
||||
$css->set_selector( '.gb-container.gb-tabs__item:not(.gb-tabs__item-open)' );
|
||||
$css->add_property( 'display', 'none' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate our CSS for our options.
|
||||
*
|
||||
* @since 1.0
|
||||
* @param string $name Name of the block.
|
||||
* @param array $settings Our available settings.
|
||||
* @param object $css Current desktop CSS object.
|
||||
*/
|
||||
public function do_dynamic_css( $name, $settings, $css ) {
|
||||
if ( 'container' === $name && isset( $settings['variantRole'] ) ) {
|
||||
$selector = function_exists( 'generateblocks_get_css_selector' )
|
||||
? generateblocks_get_css_selector( 'container', $settings )
|
||||
: '.gb-container-' . $settings['uniqueId'];
|
||||
|
||||
if ( 'tab-button' === $settings['variantRole'] ) {
|
||||
$css->set_selector( $selector . ':not(.gb-block-is-current)' );
|
||||
$css->add_property( 'cursor', 'pointer' );
|
||||
}
|
||||
|
||||
if ( 'tab-items' === $settings['variantRole'] && 'fade' === $settings['tabTransition'] ) {
|
||||
$css->set_selector( $selector . ' > .gb-tabs__item-open' );
|
||||
$css->add_property( 'opacity', 1 );
|
||||
|
||||
$css->set_selector( $selector . ' > .gb-tabs__item-transition' );
|
||||
$css->add_property( 'opacity', 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our Container block HTML attributes.
|
||||
*
|
||||
* @param array $attributes HTML attributes.
|
||||
* @param array $settings Block settings.
|
||||
*/
|
||||
public function set_container_attributes( $attributes, $settings ) {
|
||||
if ( isset( $settings['variantRole'] ) ) {
|
||||
if ( 'tabs' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs';
|
||||
$attributes['data-opened-tab'] = $settings['defaultOpenedTab'];
|
||||
}
|
||||
|
||||
if ( 'tab-items' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__items';
|
||||
}
|
||||
|
||||
if ( 'tab-buttons' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__buttons';
|
||||
}
|
||||
|
||||
if ( 'tab-button' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__button';
|
||||
|
||||
if ( true === $settings['tabItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-block-is-current';
|
||||
}
|
||||
|
||||
$attributes['role'] = 'button';
|
||||
$attributes['tabindex'] = '0';
|
||||
}
|
||||
|
||||
if ( 'tab-item' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__item';
|
||||
|
||||
if ( $settings['tabItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__item-open';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set our Button block HTML attributes.
|
||||
*
|
||||
* @param array $attributes HTML attributes.
|
||||
* @param array $settings Block settings.
|
||||
*/
|
||||
public function set_button_attributes( $attributes, $settings ) {
|
||||
if ( isset( $settings['variantRole'] ) ) {
|
||||
if ( 'tab-button' === $settings['variantRole'] ) {
|
||||
$attributes['class'] .= ' gb-tabs__button';
|
||||
|
||||
if ( $settings['tabItemOpen'] ) {
|
||||
$attributes['class'] .= ' gb-block-is-current';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the onboarding key for adding tab items.
|
||||
*
|
||||
* @param array $properties The registered keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function define_add_tab_item_onboarding_property( $properties ) {
|
||||
$properties['add_tab_item'] = array( 'type' => 'boolean' );
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Tabs_Variation::get_instance();
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Extend the Looper block.
|
||||
*
|
||||
* @package GenerateBlocksPro\Extend\Looper
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the default Query block.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Block_Looper extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* Init class.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
add_filter( 'generateblocks_looper_render_loop_items', [ $this, 'render_loop_items' ], 10, 5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render loop items based on the query type.
|
||||
*
|
||||
* @param string $output The block output.
|
||||
* @param string $query_type The query type.
|
||||
* @param array|object $query_data The query data.
|
||||
* @param WP_Block $block The block instance.
|
||||
*
|
||||
* @return string The render content.
|
||||
*/
|
||||
public function render_loop_items( $output, $query_type, $query_data, $block ) {
|
||||
if ( GenerateBlocks_Pro_Block_Query::TYPE_POST_META === $query_type ) {
|
||||
return self::render_post_meta_loop_items( $query_data, $block );
|
||||
}
|
||||
|
||||
if ( GenerateBlocks_Pro_Block_Query::TYPE_OPTION === $query_type ) {
|
||||
return self::render_option_loop_items( $query_data, $block );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the repeater items for the Looper block.
|
||||
*
|
||||
* @param array $items The items to loop over.
|
||||
* @param WP_Block $block The block instance.
|
||||
* @return string The rendered content.
|
||||
*/
|
||||
public static function render_post_meta_loop_items( $items, $block ) {
|
||||
$query_id = $block->context['generateblocks/queryData']['id'] ?? null;
|
||||
$page_key = $query_id ? 'query-' . $query_id . '-page' : 'query-page';
|
||||
$args = $block->context['generateblocks/queryData']['args'] ?? [];
|
||||
$per_page = $args['posts_per_page'] ?? get_option( 'posts_per_page' );
|
||||
$page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; // phpcs:ignore -- No data processing happening.
|
||||
$page_index = $page - 1; // Zero based index for pages.
|
||||
$offset = $page_index * $per_page;
|
||||
$content = '';
|
||||
|
||||
$index = $offset + 1;
|
||||
|
||||
// Adjust value to support array_slice.
|
||||
if ( '-1' === $per_page ) {
|
||||
$per_page = count( $items );
|
||||
}
|
||||
|
||||
if ( is_array( $items ) ) {
|
||||
$items = array_slice( $items, $offset, $per_page );
|
||||
foreach ( $items as $item ) {
|
||||
// Get the current index of the Loop.
|
||||
$content .= (
|
||||
new WP_Block(
|
||||
$block->parsed_block['innerBlocks'][0],
|
||||
array(
|
||||
'postType' => get_post_type(),
|
||||
'postId' => get_the_ID(),
|
||||
'generateblocks/queryType' => GenerateBlocks_Pro_Block_Query::TYPE_POST_META,
|
||||
'generateblocks/loopIndex' => $index,
|
||||
'generateblocks/loopItem' => $item,
|
||||
|
||||
)
|
||||
)
|
||||
)->render( array( 'dynamic' => false ) );
|
||||
$index++;
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Fallback to support previews in Elements.
|
||||
$content = (
|
||||
new WP_Block(
|
||||
$block->parsed_block['innerBlocks'][0],
|
||||
array(
|
||||
'postType' => 'post',
|
||||
'postId' => 0,
|
||||
'generateblocks/queryType' => GenerateBlocks_Pro_Block_Query::TYPE_POST_META,
|
||||
'generateblocks/loopIndex' => 1,
|
||||
'generateblocks/loopItem' => [ 'ID' => 0 ],
|
||||
|
||||
)
|
||||
)
|
||||
)->render( array( 'dynamic' => false ) );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the repeater items for the Looper block.
|
||||
*
|
||||
* @param array $items The items to loop over.
|
||||
* @param WP_Block $block The block instance.
|
||||
* @return string The rendered content.
|
||||
*/
|
||||
public static function render_option_loop_items( $items, $block ) {
|
||||
$query_id = $block->context['generateblocks/queryData']['id'] ?? null;
|
||||
$page_key = $query_id ? 'query-' . $query_id . '-page' : 'query-page';
|
||||
$args = $block->context['generateblocks/queryData']['args'] ?? [];
|
||||
$per_page = $args['posts_per_page'] ?? get_option( 'posts_per_page' );
|
||||
$page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; // phpcs:ignore -- No data processing happening.
|
||||
$page_index = $page - 1; // Zero based index for pages.
|
||||
$offset = $page_index * $per_page;
|
||||
$content = '';
|
||||
|
||||
$index = $offset + 1;
|
||||
|
||||
// Adjust value to support array_slice.
|
||||
if ( '-1' === $per_page ) {
|
||||
$per_page = count( $items );
|
||||
}
|
||||
|
||||
$inner_blocks = $block->parsed_block['innerBlocks'];
|
||||
|
||||
if ( ! $inner_blocks ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
if ( $items ) {
|
||||
$items = array_slice( $items, $offset, $per_page );
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
// Get the current index of the Loop.
|
||||
$content .= (
|
||||
new WP_Block(
|
||||
$inner_blocks[0],
|
||||
array(
|
||||
'postType' => $item['post_type'] ?? null,
|
||||
'postId' => $item['ID'] ?? $item['id'] ?? 0,
|
||||
'generateblocks/queryType' => GenerateBlocks_Pro_Block_Query::TYPE_OPTION,
|
||||
'generateblocks/loopIndex' => $index,
|
||||
'generateblocks/loopItem' => $item,
|
||||
|
||||
)
|
||||
)
|
||||
)->render( array( 'dynamic' => false ) );
|
||||
$index++;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Fallback to support previews in Elements.
|
||||
$content = (
|
||||
new WP_Block(
|
||||
$inner_blocks[0],
|
||||
array(
|
||||
'postType' => 'post',
|
||||
'postId' => 0,
|
||||
'generateblocks/queryType' => GenerateBlocks_Pro_Block_Query::TYPE_OPTION,
|
||||
'generateblocks/loopIndex' => 1,
|
||||
'generateblocks/loopItem' => [ 'ID' => 0 ],
|
||||
|
||||
)
|
||||
)
|
||||
)->render( array( 'dynamic' => false ) );
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
GenerateBlocks_Pro_Block_Looper::get_instance()->init();
|
||||
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
/**
|
||||
* Menu Item Conditions functionality.
|
||||
*
|
||||
* @package GenerateBlocksPro
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GenerateBlocks_Pro_Menu_Item_Conditions
|
||||
*/
|
||||
class GenerateBlocks_Pro_Menu_Item_Conditions extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* Cache for evaluated conditions to avoid repeated checks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $condition_cache = [];
|
||||
|
||||
/**
|
||||
* Initialize the class.
|
||||
*/
|
||||
public function init() {
|
||||
// Don't initialize if block conditions are disabled.
|
||||
if ( ! generateblocks_pro_block_conditions_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Register post meta for menu items.
|
||||
add_action( 'init', [ $this, 'register_post_meta' ] );
|
||||
|
||||
// Add fields to menu item editor.
|
||||
add_action( 'wp_nav_menu_item_custom_fields', [ $this, 'add_condition_fields' ], 20, 5 );
|
||||
|
||||
// Save menu item conditions.
|
||||
add_action( 'wp_update_nav_menu_item', [ $this, 'save_menu_item_conditions' ], 10, 2 );
|
||||
|
||||
// Filter menu items based on conditions.
|
||||
add_filter( 'wp_nav_menu_objects', [ $this, 'filter_menu_items_by_conditions' ], 10, 2 );
|
||||
|
||||
// Add to condition usage tracking.
|
||||
add_filter( 'generateblocks_condition_usage_handlers', [ $this, 'add_menu_usage_handler' ], 10, 2 );
|
||||
|
||||
// Add admin scripts for dynamic UI.
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'add_admin_scripts' ] );
|
||||
|
||||
// AJAX handler for condition search.
|
||||
add_action( 'wp_ajax_gb_search_conditions', [ $this, 'ajax_search_conditions' ] );
|
||||
|
||||
// AJAX handler for loading more conditions.
|
||||
add_action( 'wp_ajax_gb_load_more_conditions', [ $this, 'ajax_load_more_conditions' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the post meta.
|
||||
*/
|
||||
public function register_post_meta() {
|
||||
register_post_meta(
|
||||
'nav_menu_item',
|
||||
'_gb_menu_condition',
|
||||
[
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
]
|
||||
);
|
||||
|
||||
register_post_meta(
|
||||
'nav_menu_item',
|
||||
'_gb_menu_condition_invert',
|
||||
[
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'boolean',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the conditions limit per page.
|
||||
*/
|
||||
private function get_conditions_limit() {
|
||||
return apply_filters( 'generateblocks_menu_conditions_limit', 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add condition fields to menu items.
|
||||
*
|
||||
* @param string $item_id Menu item ID as a numeric string.
|
||||
* @param WP_Post $menu_item Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass|null $args An object of menu item arguments.
|
||||
* @param int $current_object_id Nav menu ID.
|
||||
*/
|
||||
public function add_condition_fields( $item_id, $menu_item, $depth, $args, $current_object_id ) {
|
||||
$condition_id = get_post_meta( $item_id, '_gb_menu_condition', true );
|
||||
$invert = get_post_meta( $item_id, '_gb_menu_condition_invert', true );
|
||||
|
||||
// Get conditions for dropdown.
|
||||
static $conditions_cache = null;
|
||||
|
||||
if ( null === $conditions_cache ) {
|
||||
// Get the most recent conditions.
|
||||
$conditions_cache = get_posts(
|
||||
[
|
||||
'post_type' => 'gblocks_condition',
|
||||
'posts_per_page' => $this->get_conditions_limit(),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'post_status' => 'publish',
|
||||
'suppress_filters' => false,
|
||||
'no_found_rows' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$conditions = $conditions_cache;
|
||||
|
||||
// Always include the currently selected condition if it's not in the list.
|
||||
if ( $condition_id && 'gblocks_condition' === get_post_type( $condition_id ) ) {
|
||||
$found = false;
|
||||
foreach ( $conditions as $condition ) {
|
||||
if ( $condition->ID === $condition_id ) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found ) {
|
||||
$selected_condition = get_post( $condition_id );
|
||||
if ( $selected_condition ) {
|
||||
// Add it to the list for this menu item only.
|
||||
$conditions = array_merge( [ $selected_condition ], $conditions );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there are more conditions than we're showing.
|
||||
$total_conditions = wp_count_posts( 'gblocks_condition' )->publish;
|
||||
$has_more = $total_conditions > count( $conditions_cache );
|
||||
?>
|
||||
<p class="field-gb-menu-condition description description-wide">
|
||||
<label for="gb-menu-condition-<?php echo esc_attr( $item_id ); ?>">
|
||||
<?php esc_html_e( 'Display Condition', 'generateblocks-pro' ); ?>
|
||||
</label>
|
||||
<div class="gb-menu-condition-wrapper" style="display: flex; align-items: center; gap: 10px;">
|
||||
<select
|
||||
name="gb-menu-condition[<?php echo esc_attr( $item_id ); ?>]"
|
||||
id="gb-menu-condition-<?php echo esc_attr( $item_id ); ?>"
|
||||
class="gb-menu-condition-select"
|
||||
style="flex: 1;"
|
||||
data-item-id="<?php echo esc_attr( $item_id ); ?>"
|
||||
data-page="1"
|
||||
>
|
||||
<option value=""><?php esc_html_e( 'No condition', 'generateblocks-pro' ); ?></option>
|
||||
<?php foreach ( $conditions as $condition ) : ?>
|
||||
<option value="<?php echo esc_attr( $condition->ID ); ?>" <?php selected( $condition_id, $condition->ID ); ?>>
|
||||
<?php echo esc_html( $condition->post_title ); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php if ( $has_more ) : ?>
|
||||
<button
|
||||
type="button"
|
||||
class="button gb-load-more-conditions"
|
||||
data-item-id="<?php echo esc_attr( $item_id ); ?>"
|
||||
>
|
||||
<?php esc_html_e( 'Load More', 'generateblocks-pro' ); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<span class="description" style="display: block; margin-top: 5px;">
|
||||
<?php esc_html_e( 'Choose a condition to control when this menu item appears.', 'generateblocks-pro' ); ?>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class="field-gb-menu-condition-invert description description-wide" style="<?php echo $condition_id ? '' : 'display: none;'; ?>">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="gb-menu-condition-invert[<?php echo esc_attr( $item_id ); ?>]"
|
||||
value="1"
|
||||
<?php checked( $invert, '1' ); ?>
|
||||
/>
|
||||
<?php esc_html_e( 'Invert condition', 'generateblocks-pro' ); ?>
|
||||
</label>
|
||||
<span class="description" style="display: block"><?php esc_html_e( 'Hide the menu item when the condition is true instead of false.', 'generateblocks-pro' ); ?></span>
|
||||
</p>
|
||||
|
||||
<?php wp_nonce_field( 'update-menu-item-condition', 'menu-item-condition-nonce' ); ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the menu item conditions.
|
||||
*
|
||||
* @param int $menu_id The menu ID.
|
||||
* @param int $menu_item_id The menu item ID.
|
||||
* @return mixed
|
||||
*/
|
||||
public function save_menu_item_conditions( $menu_id, $menu_item_id ) {
|
||||
// Verify nonce.
|
||||
if (
|
||||
! isset( $_POST['menu-item-condition-nonce'] )
|
||||
|| ! wp_verify_nonce( $_POST['menu-item-condition-nonce'], 'update-menu-item-condition' )
|
||||
) {
|
||||
return $menu_id;
|
||||
}
|
||||
|
||||
// Save condition from dropdown.
|
||||
$condition_id = isset( $_POST['gb-menu-condition'][ $menu_item_id ] )
|
||||
? sanitize_text_field( $_POST['gb-menu-condition'][ $menu_item_id ] )
|
||||
: '';
|
||||
|
||||
if ( $condition_id ) {
|
||||
update_post_meta( $menu_item_id, '_gb_menu_condition', $condition_id );
|
||||
} else {
|
||||
delete_post_meta( $menu_item_id, '_gb_menu_condition' );
|
||||
}
|
||||
|
||||
// Save invert setting.
|
||||
$invert = isset( $_POST['gb-menu-condition-invert'][ $menu_item_id ] ) ? '1' : '0';
|
||||
|
||||
if ( $condition_id && '1' === $invert ) {
|
||||
update_post_meta( $menu_item_id, '_gb_menu_condition_invert', '1' );
|
||||
} else {
|
||||
delete_post_meta( $menu_item_id, '_gb_menu_condition_invert' );
|
||||
}
|
||||
|
||||
return $menu_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter menu items based on conditions.
|
||||
*
|
||||
* @param array $sorted_menu_items The menu items, sorted by menu order.
|
||||
* @param stdClass $args The menu arguments.
|
||||
* @return array Filtered menu items.
|
||||
*/
|
||||
public function filter_menu_items_by_conditions( $sorted_menu_items, $args ) {
|
||||
if ( empty( $sorted_menu_items ) ) {
|
||||
return $sorted_menu_items;
|
||||
}
|
||||
|
||||
$removed_items = [];
|
||||
|
||||
// Build list of all items that should be removed (condition fails or parent removed).
|
||||
// Note: WordPress guarantees menu items are in hierarchical order (parents before children).
|
||||
foreach ( $sorted_menu_items as $item ) {
|
||||
$item_id = (int) $item->ID;
|
||||
|
||||
// Skip if already marked for removal.
|
||||
if ( in_array( $item_id, $removed_items, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if parent was removed.
|
||||
$parent_id = ! empty( $item->menu_item_parent ) ? (int) $item->menu_item_parent : 0;
|
||||
if ( $parent_id && in_array( $parent_id, $removed_items, true ) ) {
|
||||
$removed_items[] = $item_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check condition.
|
||||
$condition_id = get_post_meta( $item_id, '_gb_menu_condition', true );
|
||||
if ( $condition_id && ! $this->should_show_menu_item( $item_id, $condition_id ) ) {
|
||||
$removed_items[] = $item_id;
|
||||
}
|
||||
}
|
||||
|
||||
// If no items were removed, return the original array.
|
||||
if ( empty( $removed_items ) ) {
|
||||
return $sorted_menu_items;
|
||||
}
|
||||
|
||||
// Filter out removed items.
|
||||
$final_items = [];
|
||||
foreach ( $sorted_menu_items as $item ) {
|
||||
if ( ! in_array( (int) $item->ID, $removed_items, true ) ) {
|
||||
$final_items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $final_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a menu item should be shown based on its condition.
|
||||
*
|
||||
* @param int $menu_item_id The menu item ID.
|
||||
* @param string $condition_id The condition ID.
|
||||
* @return bool Whether to show the menu item.
|
||||
*/
|
||||
private function should_show_menu_item( $menu_item_id, $condition_id ) {
|
||||
$condition_id = absint( $condition_id );
|
||||
|
||||
if ( ! $condition_id ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$invert_condition = get_post_meta( $menu_item_id, '_gb_menu_condition_invert', true ) === '1';
|
||||
|
||||
// Check cache first to avoid repeated evaluations.
|
||||
$cache_key = $condition_id . '_' . ( $invert_condition ? '1' : '0' );
|
||||
|
||||
if ( isset( $this->condition_cache[ $cache_key ] ) ) {
|
||||
return $this->condition_cache[ $cache_key ];
|
||||
}
|
||||
|
||||
// Default to showing the menu item.
|
||||
$show = true;
|
||||
|
||||
// Check if the condition post exists and is published.
|
||||
$condition_post = get_post( $condition_id );
|
||||
|
||||
if ( $condition_post && 'publish' === $condition_post->post_status ) {
|
||||
// Get the condition data.
|
||||
$display_conditions = get_post_meta( $condition_id, '_gb_conditions', true );
|
||||
|
||||
if ( ! empty( $display_conditions ) ) {
|
||||
// Use the existing conditions system to evaluate.
|
||||
$show = GenerateBlocks_Pro_Conditions::show( $display_conditions );
|
||||
|
||||
// If invert is enabled, flip the result.
|
||||
if ( $invert_condition ) {
|
||||
$show = ! $show;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the result.
|
||||
$this->condition_cache[ $cache_key ] = $show;
|
||||
|
||||
return $show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add menu item conditions handler to usage search.
|
||||
*
|
||||
* @param array $handlers Existing handlers.
|
||||
* @param int $condition_id The condition ID.
|
||||
* @return array Modified handlers.
|
||||
*/
|
||||
public function add_menu_usage_handler( $handlers, $condition_id ) {
|
||||
$handlers['menu_item_conditions'] = [
|
||||
'method' => 'search_menu_item_conditions_usage',
|
||||
'label' => __( 'Menu Item Conditions', 'generateblocks-pro' ),
|
||||
];
|
||||
|
||||
return $handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for searching conditions.
|
||||
*/
|
||||
public function ajax_search_conditions() {
|
||||
// Verify nonce.
|
||||
if ( ! wp_verify_nonce( $_GET['_ajax_nonce'], 'gb_search_conditions' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 1;
|
||||
$per_page = $this->get_conditions_limit();
|
||||
|
||||
$args = [
|
||||
'post_type' => 'gblocks_condition',
|
||||
'posts_per_page' => $per_page,
|
||||
'paged' => $page,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'post_status' => 'publish',
|
||||
];
|
||||
|
||||
if ( $search ) {
|
||||
$args['s'] = $search;
|
||||
$args['orderby'] = 'relevance';
|
||||
}
|
||||
|
||||
$conditions = get_posts( $args );
|
||||
$total = wp_count_posts( 'gblocks_condition' )->publish;
|
||||
|
||||
$results = [];
|
||||
foreach ( $conditions as $condition ) {
|
||||
$results[] = [
|
||||
'id' => $condition->ID,
|
||||
'text' => $condition->post_title ? $condition->post_title : __( 'Untitled Condition', 'generateblocks-pro' ),
|
||||
];
|
||||
}
|
||||
|
||||
wp_send_json(
|
||||
[
|
||||
'results' => $results,
|
||||
'pagination' => [
|
||||
'more' => ( $page * $per_page ) < $total,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AJAX handler for loading more conditions.
|
||||
*/
|
||||
public function ajax_load_more_conditions() {
|
||||
// Verify nonce.
|
||||
if ( ! wp_verify_nonce( $_GET['_ajax_nonce'], 'gb_load_more_conditions' ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
||||
$page = isset( $_GET['page'] ) ? absint( $_GET['page'] ) : 2;
|
||||
$limit = $this->get_conditions_limit();
|
||||
$offset = ( $page - 1 ) * $limit;
|
||||
|
||||
$conditions = get_posts(
|
||||
[
|
||||
'post_type' => 'gblocks_condition',
|
||||
'posts_per_page' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'post_status' => 'publish',
|
||||
'suppress_filters' => false,
|
||||
'no_found_rows' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$formatted_conditions = [];
|
||||
foreach ( $conditions as $condition ) {
|
||||
$formatted_conditions[] = [
|
||||
'id' => $condition->ID,
|
||||
'title' => $condition->post_title ? $condition->post_title : __( 'Untitled Condition', 'generateblocks-pro' ),
|
||||
];
|
||||
}
|
||||
|
||||
$total = wp_count_posts( 'gblocks_condition' )->publish;
|
||||
$has_more = ( $page * $limit ) < $total;
|
||||
|
||||
wp_send_json_success(
|
||||
[
|
||||
'conditions' => $formatted_conditions,
|
||||
'has_more' => $has_more,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin scripts for dynamic UI behavior.
|
||||
*
|
||||
* @param string $hook_suffix The current admin page.
|
||||
*/
|
||||
public function add_admin_scripts( $hook_suffix ) {
|
||||
// Only load on nav-menus.php page.
|
||||
if ( 'nav-menus.php' !== $hook_suffix ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'gb-menu-item-conditions',
|
||||
GENERATEBLOCKS_PRO_DIR_URL . 'dist/menu-item-conditions.js',
|
||||
array(),
|
||||
GENERATEBLOCKS_PRO_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'gb-menu-item-conditions',
|
||||
'gbMenuConditions',
|
||||
array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonces' => array(
|
||||
'loadMore' => wp_create_nonce( 'gb_load_more_conditions' ),
|
||||
'search' => wp_create_nonce( 'gb_search_conditions' ),
|
||||
),
|
||||
'strings' => array(
|
||||
'loading' => __( 'Loading...', 'generateblocks-pro' ),
|
||||
'loadMore' => __( 'Load More', 'generateblocks-pro' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the class.
|
||||
GenerateBlocks_Pro_Menu_Item_Conditions::get_instance()->init();
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* The class for related author.
|
||||
*
|
||||
* @package Generateblocks/Extend/QueryLoop
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* The class for related author.
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Related_Author extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Author::include_current_author' );
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Author::exclude_current_author' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include posts of current post author to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public static function include_current_author( $query_args ) {
|
||||
return self::add_current_author( $query_args, 'author__in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude posts of current post author to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public static function exclude_current_author( $query_args ) {
|
||||
return self::add_current_author( $query_args, 'author__not_in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current author to a query argument.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
* @param string $key The query argument key.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
protected static function add_current_author( $query_args, $key ) {
|
||||
if (
|
||||
isset( $query_args[ $key ] ) &&
|
||||
in_array( 'current-post-author', $query_args[ $key ] )
|
||||
) {
|
||||
$current_post_author_index = array_search( 'current-post-author', $query_args[ $key ] );
|
||||
array_splice( $query_args[ $key ], $current_post_author_index, 1 );
|
||||
|
||||
if ( ! in_array( get_the_author_meta( 'ID' ), $query_args[ $key ] ) ) {
|
||||
$query_args[ $key ][] = get_the_author_meta( 'ID' );
|
||||
}
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Related_Author::get_instance();
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* The class for related parent.
|
||||
*
|
||||
* @package Generateblocks/Extend/QueryLoop
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* The class for related parent.
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Related_Parent extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Parent::include_current_post' );
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Parent::exclude_current_post' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current post as parent to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public static function include_current_post( $query_args ) {
|
||||
return self::add_current_post( $query_args, 'post_parent__in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude current post as parent to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public static function exclude_current_post( $query_args ) {
|
||||
return self::add_current_post( $query_args, 'post_parent__not_in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current post to a query argument.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
* @param string $key The query argument key.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
protected static function add_current_post( $query_args, $key ) {
|
||||
if (
|
||||
isset( $query_args[ $key ] ) &&
|
||||
in_array( 'current-post', $query_args[ $key ] ) &&
|
||||
get_post_type() === $query_args['post_type']
|
||||
) {
|
||||
$current_post_index = array_search( 'current-post', $query_args[ $key ] );
|
||||
array_splice( $query_args[ $key ], $current_post_index, 1 );
|
||||
|
||||
if ( ! in_array( get_the_ID(), $query_args[ $key ] ) ) {
|
||||
$query_args[ $key ][] = get_the_ID();
|
||||
}
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Related_Parent::get_instance();
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* The class for related post.
|
||||
*
|
||||
* @package Generateblocks/Extend/QueryLoop
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* The related posts class.
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Related_Post extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Post::exclude_current_post' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude current post from the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param Array $query_args The query arguments.
|
||||
*
|
||||
* @return Array The query arguments without current post.
|
||||
*/
|
||||
public static function exclude_current_post( $query_args ) {
|
||||
if (
|
||||
isset( $query_args['post__not_in'] ) &&
|
||||
in_array( 'exclude-current', $query_args['post__not_in'] ) &&
|
||||
get_post_type() === $query_args['post_type']
|
||||
) {
|
||||
if ( ! in_array( get_the_ID(), $query_args['post__not_in'] ) ) {
|
||||
$query_args['post__not_in'][] = get_the_ID();
|
||||
}
|
||||
|
||||
$exclude_current_index = array_search( 'exclude-current', $query_args['post__not_in'] );
|
||||
array_splice( $query_args['post__not_in'], $exclude_current_index, 1 );
|
||||
|
||||
// This is to avoid current post being dynamically added to post__in which will show him in the result set.
|
||||
if (
|
||||
isset( $query_args['post__in'] ) &&
|
||||
in_array( get_the_ID(), $query_args['post__in'] )
|
||||
) {
|
||||
$current_post_index = array_search( get_the_ID(), $query_args['post__in'] );
|
||||
array_splice( $query_args['post__in'], $current_post_index, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Related_Post::get_instance();
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* The class for related terms.
|
||||
*
|
||||
* @package Generateblocks/Extend/QueryLoop
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* The class for related terms.
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Related_Terms extends GenerateBlocks_Pro_Singleton {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Terms::include_current_post_terms' );
|
||||
add_filter( 'generateblocks_query_loop_args', 'GenerateBlocks_Pro_Related_Terms::exclude_current_post_terms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current post terms to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param Array $query_args The query arguments.
|
||||
*
|
||||
* @return Array The query arguments with current post terms.
|
||||
*/
|
||||
public static function include_current_post_terms( $query_args ) {
|
||||
return self::add_current_post_terms( $query_args, 'tax_query' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude current post terms to the query loop.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments without current post terms.
|
||||
*/
|
||||
public static function exclude_current_post_terms( $query_args ) {
|
||||
return self::add_current_post_terms( $query_args, 'tax_query_exclude' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current post term to a query argument.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
* @param string $key The query argument key.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
protected static function add_current_post_terms( $query_args, $key ) {
|
||||
if (
|
||||
is_singular() &&
|
||||
isset( $query_args[ $key ] )
|
||||
) {
|
||||
$query_args[ $key ] = array_map(
|
||||
function( $tax ) {
|
||||
if ( isset( $tax['terms'] ) && in_array( 'current-terms', $tax['terms'] ) ) {
|
||||
$registered_taxonomies = get_object_taxonomies( get_post_type() );
|
||||
|
||||
if ( in_array( $tax['taxonomy'], $registered_taxonomies ) ) {
|
||||
$related_terms = wp_get_object_terms(
|
||||
get_the_ID(),
|
||||
$tax['taxonomy'],
|
||||
array( 'fields' => 'ids' )
|
||||
);
|
||||
|
||||
$tax['terms'] = array_merge( $tax['terms'], $related_terms );
|
||||
}
|
||||
|
||||
$current_terms_index = array_search( 'current-terms', $tax['terms'] );
|
||||
array_splice( $tax['terms'], $current_terms_index, 1 );
|
||||
}
|
||||
|
||||
return $tax;
|
||||
},
|
||||
$query_args[ $key ]
|
||||
);
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Related_Terms::get_instance();
|
||||
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/**
|
||||
* Extend the Query block.
|
||||
*
|
||||
* @package GenerateBlocksPro\Extend\Query
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the default Query block.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class GenerateBlocks_Pro_Block_Query extends GenerateBlocks_Pro_Singleton {
|
||||
// Add new Query types here.
|
||||
const TYPE_POST_META = 'post_meta';
|
||||
const TYPE_OPTION = 'option';
|
||||
|
||||
/**
|
||||
* Init function.
|
||||
*/
|
||||
public function init() {
|
||||
if ( ! class_exists( 'GenerateBlocks_Meta_Handler' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'generateblocks_query_data', [ $this, 'set_query_data' ], 10, 5 );
|
||||
add_filter( 'generateblocks_dynamic_tag_id', [ $this, 'set_dynamic_tag_id' ], 10, 3 );
|
||||
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'exclude_current_post' ], 10, 4 );
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'include_current_author' ], 10, 4 );
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'exclude_current_author' ], 10, 4 );
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'current_post_terms' ], 10, 4 );
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'include_current_parent' ], 10, 4 );
|
||||
add_filter( 'generateblocks_query_wp_query_args', [ $this, 'exclude_current_parent' ], 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the dynamic tag's ID if it's a post tag, it has a valid loop item ID, and no other ID is set in options.
|
||||
*
|
||||
* @param int $id The current ID value for the tag.
|
||||
* @param array $options The tag options.
|
||||
* @param object $instance The block instance for the block containing the tag.
|
||||
* @return int The ID for the dynamic tag.
|
||||
*/
|
||||
public function set_dynamic_tag_id( $id, $options, $instance ) {
|
||||
// If an ID is set in options, use the original ID.
|
||||
if ( $options['id'] ?? false ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
$loop_item = $instance->context['generateblocks/loopItem'] ?? null;
|
||||
|
||||
if ( ! $loop_item ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
// Look for the ID or id keys and return the original $id if none can be found.
|
||||
if ( is_array( $loop_item ) ) {
|
||||
return $loop_item['ID'] ?? $loop_item['id'] ?? $id;
|
||||
} elseif ( is_object( $loop_item ) ) {
|
||||
return $loop_item->ID ?? $loop_item->id ?? $id;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query data for certain types.
|
||||
*
|
||||
* @param array $query_data The current query data.
|
||||
* @param string $query_type The type of query.
|
||||
* @param array $attributes An array of block attributes.
|
||||
* @param WP_Block $block The block instance.
|
||||
* @param int $page The page number.
|
||||
*
|
||||
* @return array An array of query data.
|
||||
*/
|
||||
public function set_query_data( $query_data, $query_type, $attributes, $block, $page ) {
|
||||
$pro_types = [
|
||||
self::TYPE_POST_META,
|
||||
self::TYPE_OPTION,
|
||||
];
|
||||
|
||||
if ( ! in_array( $query_type, $pro_types, true ) ) {
|
||||
return $query_data;
|
||||
}
|
||||
|
||||
$query = $attributes['query'] ?? [];
|
||||
$id = $query['meta_key_id'] ?? '';
|
||||
$meta_key = $query['meta_key'] ?? '';
|
||||
|
||||
if ( 'current' === $id || ! $id ) {
|
||||
$id = get_the_ID();
|
||||
}
|
||||
|
||||
if ( self::TYPE_POST_META === $query_type ) {
|
||||
$value = GenerateBlocks_Meta_Handler::get_post_meta( $id, $meta_key, false );
|
||||
} elseif ( self::TYPE_OPTION === $query_type ) {
|
||||
$value = GenerateBlocks_Meta_Handler::get_option( $meta_key, false );
|
||||
}
|
||||
|
||||
$data = is_array( $value ) ? $value : [];
|
||||
// Handle pagination.
|
||||
$posts_per_page = (int) ( $query['posts_per_page'] ?? get_option( 'posts_per_page' ) );
|
||||
$offset = isset( $query['offset'] ) && is_numeric( $query['offset'] ) ? $query['offset'] : 0;
|
||||
|
||||
// Get the total number of items less the user specified offset.
|
||||
$data = array_slice( $data, $offset );
|
||||
$max_pages = $posts_per_page > 0
|
||||
? (int) ceil( count( $data ) / $posts_per_page )
|
||||
: 1;
|
||||
|
||||
if ( 0 === $posts_per_page ) {
|
||||
$max_pages = 0;
|
||||
}
|
||||
|
||||
return [
|
||||
'data' => $data,
|
||||
'no_results' => empty( $data ),
|
||||
'args' => $query,
|
||||
'max_num_pages' => $max_pages,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude current post from the query.
|
||||
*
|
||||
* @param array $query_args The query arguments.
|
||||
* @param array $attributes The block attributes.
|
||||
* @param WP_Block|null $block The block instance.
|
||||
* @param array $current The current post data.
|
||||
*
|
||||
* @return array The query arguments without current post.
|
||||
*/
|
||||
public function exclude_current_post( $query_args, $attributes, $block, $current ) {
|
||||
$current_post_id = $current['post_id'] ?? get_the_ID();
|
||||
|
||||
return self::add_current_post( $query_args, $current_post_id, 'post__not_in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current parent post from the query.
|
||||
*
|
||||
* @param array $query_args The query arguments.
|
||||
* @param array $attributes The block attributes.
|
||||
* @param WP_Block|null $block The block instance.
|
||||
* @param array $current The current post data.
|
||||
*
|
||||
* @return array The query arguments without current post.
|
||||
*/
|
||||
public function include_current_parent( $query_args, $attributes, $block, $current ) {
|
||||
$current_post_id = $current['post_id'] ?? get_the_ID();
|
||||
|
||||
return self::add_current_post( $query_args, $current_post_id, 'post_parent__in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude current parent post from the query.
|
||||
*
|
||||
* @param array $query_args The query arguments.
|
||||
* @param array $attributes The block attributes.
|
||||
* @param WP_Block|null $block The block instance.
|
||||
* @param array $current The current post data.
|
||||
*
|
||||
* @return array The query arguments without current post.
|
||||
*/
|
||||
public function exclude_current_parent( $query_args, $attributes, $block, $current ) {
|
||||
$current_post_id = $current['post_id'] ?? get_the_ID();
|
||||
|
||||
return self::add_current_post( $query_args, $current_post_id, 'post_parent__not_in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current post ID to the query args.
|
||||
*
|
||||
* @param array $query_args The query arguments.
|
||||
* @param int $current_post_id The current post ID.
|
||||
* @param string $key The key to check.
|
||||
*
|
||||
* @return array The query arguments without current post.
|
||||
*/
|
||||
public static function add_current_post( $query_args, $current_post_id, $key ) {
|
||||
if (
|
||||
isset( $query_args[ $key ] ) &&
|
||||
in_array( 'current', $query_args[ $key ] )
|
||||
) {
|
||||
if ( ! in_array( $current_post_id, $query_args[ $key ] ) ) {
|
||||
$query_args[ $key ][] = $current_post_id;
|
||||
}
|
||||
|
||||
$exclude_current_index = array_search( 'current', $query_args[ $key ] );
|
||||
array_splice( $query_args[ $key ], $exclude_current_index, 1 );
|
||||
|
||||
if ( 'post__not_in' === $key ) {
|
||||
// This is to avoid current post being dynamically added to post__in which will show him in the result set.
|
||||
if (
|
||||
isset( $query_args['post__in'] ) &&
|
||||
in_array( $current_post_id, $query_args['post__in'] )
|
||||
) {
|
||||
$current_post_index = array_search( $current_post_id, $query_args['post__in'] );
|
||||
array_splice( $query_args['post__in'], $current_post_index, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include posts of current post author to the query.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public function include_current_author( $query_args ) {
|
||||
return self::add_current_author( $query_args, 'author__in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude posts of current post author to the query.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public function exclude_current_author( $query_args ) {
|
||||
return self::add_current_author( $query_args, 'author__not_in' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Include current author to a query argument.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @param array $query_args The query arguments.
|
||||
* @param string $key The query argument key.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public function add_current_author( $query_args, $key ) {
|
||||
if (
|
||||
isset( $query_args[ $key ] ) &&
|
||||
in_array( 'current', $query_args[ $key ] )
|
||||
) {
|
||||
$current_post_author_index = array_search( 'current', $query_args[ $key ] );
|
||||
array_splice( $query_args[ $key ], $current_post_author_index, 1 );
|
||||
|
||||
if ( ! in_array( get_the_author_meta( 'ID' ), $query_args[ $key ] ) ) {
|
||||
$query_args[ $key ][] = get_the_author_meta( 'ID' );
|
||||
}
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the "current" post terms.
|
||||
*
|
||||
* @param array $query_args The query arguments.
|
||||
* @param array $attributes The block attributes.
|
||||
* @param WP_Block|null $block The block instance.
|
||||
* @param array $current The current post data.
|
||||
*
|
||||
* @return array The query arguments.
|
||||
*/
|
||||
public function current_post_terms( $query_args, $attributes, $block, $current ) {
|
||||
if (
|
||||
$current['post_id'] &&
|
||||
isset( $query_args['tax_query'] )
|
||||
) {
|
||||
$query_args['tax_query'] = array_map(
|
||||
function( $tax ) use ( $current ) {
|
||||
|
||||
if ( ! isset( $tax['terms'] ) ) {
|
||||
return $tax;
|
||||
}
|
||||
|
||||
if ( in_array( 'current', $tax['terms'], true ) ) {
|
||||
$registered_taxonomies = get_object_taxonomies( get_post_type( $current['post_id'] ) );
|
||||
|
||||
if ( in_array( $tax['taxonomy'], $registered_taxonomies, true ) ) {
|
||||
$related_terms = wp_get_object_terms(
|
||||
$current['post_id'],
|
||||
$tax['taxonomy'],
|
||||
array( 'fields' => 'ids' )
|
||||
);
|
||||
|
||||
$tax['terms'] = array_merge( $tax['terms'], $related_terms );
|
||||
}
|
||||
|
||||
$current_terms_index = array_search( 'current', $tax['terms'] );
|
||||
array_splice( $tax['terms'], $current_terms_index, 1 );
|
||||
}
|
||||
|
||||
return $tax;
|
||||
},
|
||||
$query_args['tax_query']
|
||||
);
|
||||
}
|
||||
|
||||
return $query_args;
|
||||
}
|
||||
}
|
||||
|
||||
GenerateBlocks_Pro_Block_Query::get_instance()->init();
|
||||
Reference in New Issue
Block a user