set_basename( false, __FILE__ ); return; } // Include Freemius functions. require_once dirname( __FILE__ ) . '/freemius.php'; if ( !class_exists( MetaFieldBlock::class ) ) { /** * The main class */ class MetaFieldBlock { /** * Plugin version * * @var String */ protected $version = '1.2.5' ; /** * Components * * @var Array */ protected $components = array() ; /** * Plugin instance * * @var MetaFieldBlock */ private static $instance ; /** * A dummy constructor */ private function __construct() { } /** * Initialize the instance. * * @return MetaFieldBlock */ public static function get_instance() { if ( !isset( self::$instance ) ) { self::$instance = new MetaFieldBlock(); self::$instance->initialize(); } return self::$instance; } /** * Kick start function. * Define constants * Load dependencies * Register components * Run the main hooks * * @return void */ public function initialize() { // Setup constants. $this->setup_constants(); // Load dependencies. $this->load_dependencies(); // Register components. $this->register_components(); // Run hooks. $this->run(); } /** * Setup constants * * @return void */ public function setup_constants() { $this->define_constant( 'MFB', true ); $this->define_constant( 'MFB_ROOT_FILE', __FILE__ ); $this->define_constant( 'MFB_VERSION', $this->version ); $this->define_constant( 'MFB_PATH', trailingslashit( plugin_dir_path( MFB_ROOT_FILE ) ) ); $this->define_constant( 'MFB_URL', trailingslashit( plugin_dir_url( MFB_ROOT_FILE ) ) ); } /** * Load core components * * @return void */ public function register_components() { // Load & register core components. $this->include_file( 'includes/rest-fields.php' ); $this->include_file( 'includes/acf-fields.php' ); $this->include_file( 'includes/dynamic-field.php' ); $this->include_file( 'includes/freemius-config.php' ); $this->include_file( 'includes/settings.php' ); $core_components = [ RestFields::class, ACFFields::class, DynamicField::class, Settings::class, FreemiusConfig::class ]; $components = apply_filters( 'meta_field_block_get_components', $core_components ); foreach ( $components as $component ) { $this->register_component( $component ); } } /** * Load dependencies * * @return void */ public function load_dependencies() { // Load core component. $this->include_file( 'includes/core-component.php' ); $this->include_file( 'includes/helper-functions.php' ); } /** * Run main hooks * * @return void */ public function run() { // Load translations. add_action( 'plugins_loaded', [ $this, 'load_textdomain' ] ); // Register the block. add_action( 'init', [ $this, 'register_block' ] ); // Save version and trigger upgraded hook. add_action( 'admin_menu', [ $this, 'version_upgrade' ], 1 ); // Run all components. foreach ( $this->components as $component ) { $component->run(); } } /** * Load text domain * * @return void */ public function load_textdomain() { load_plugin_textdomain( 'display-a-meta-field-as-block', false, plugin_basename( realpath( __DIR__ . '/languages' ) ) ); } /** * Register the block * * @return void */ public function register_block() { // Register block. register_block_type( MFB_PATH . '/build', [ 'render_callback' => [ $this, 'render_block' ], 'skip_inner_blocks' => true, ] ); } /** * Renders the `mbf/meta-field-block` block on the server. * * @param array $attributes Block attributes. * @param string $content Block default content. * @param WP_Block $block Block instance. * @return string Returns the value for the field. */ public function render_block( $attributes, $content, $block ) { $field_name = $attributes['fieldName'] ?? ''; if ( empty($field_name) ) { return ''; } // Get object type. $object_type = $this->get_object_type( $field_name, $attributes, $block ); // Get object id. $object_id = $this->get_object_id( $object_type, $attributes, $block ); // Get field type. $field_type = $attributes['fieldType'] ?? 'rest_field'; // Is dynamic block? $is_dynamic_block = $this->is_dynamic_block( $attributes ); if ( $is_dynamic_block ) { if ( 'acf' === $field_type ) { if ( function_exists( 'get_field_object' ) ) { $block_value = $this->get_component( ACFFields::class )->get_field_value( $field_name, $object_id, $object_type ); $content = $block_value['value'] ?? ''; $content = apply_filters( '_meta_field_block_render_dynamic_block', $content, $block_value, $object_id, $object_type, $attributes, $block ); } else { $content = '' . __( 'This data type requires the ACF plugin installed and activated!', 'display-a-meta-field-as-block' ) . ''; } } else { if ( in_array( $object_type, [ 'post', 'term', 'user' ], true ) ) { $get_meta_callback = "get_{$object_type}_meta"; $content = $get_meta_callback( $object_id, $field_name, true ); } else { $content = apply_filters( '_meta_field_block_get_field_value_other_type', $content, $field_name, $object_id, $object_type, $attributes, $block ); } $content = apply_filters( '_meta_field_block_get_field_value', $content, $field_name, $object_id, $object_type, $attributes, $block ); } } else { $content = apply_filters( '_meta_field_block_render_static_block', $content, $field_name, $object_id, $object_type, $attributes, $block ); } // Additional block classes. $classes = "is-{$field_type}-field"; if ( $attributes['fieldSettings']['type'] ?? false ) { $classes .= " is-{$attributes['fieldSettings']['type']}-field"; } // Get the block markup. return meta_field_block_get_block_markup( $content, $attributes, $block, $object_id, $object_type, $classes, $is_dynamic_block ); } /** * Get object type. * * @param string $field_name Field name. * @param array $attributes Block attributes. * @param WP_Block $block The block instance. * @return string */ public function get_object_type( $field_name, $attributes, $block ) { // Get object type from meta type. $object_type = $attributes['metaType'] ?? ''; if ( $object_type ) { return $object_type; } // Cache key. $cache_key = 'object_type_' . $field_name; // Get object_type from the cache. $object_type = wp_cache_get( $cache_key, 'mfb' ); if ( $object_type === false ) { $object_type = 'post'; if ( $this->is_custom_context( $field_name, $block, is_category() || is_tag() || is_tax() ) ) { $object_type = 'term'; } elseif ( $this->is_custom_context( $field_name, $block, is_author() ) ) { $object_type = 'user'; } // Update cache. if ( !empty($object_type) ) { wp_cache_set( $cache_key, $object_type, 'mfb' ); } } return $object_type; } /** * Get object id by object type. * * @param string $object_type Object type. * @param array $attributes Block attributes. * @param WP_Block $block Block instance. * * @return string */ public function get_object_id( $object_type, $attributes, $block ) { if ( in_array( $object_type, [ 'post', 'term', 'user' ], true ) && ($attributes['isCustomSource'] ?? false) && ($attributes['objectId'] ?? false) ) { return $attributes['objectId']; } if ( in_array( $object_type, [ 'term', 'user' ], true ) ) { // Get queried object id. $object_id = get_queried_object_id(); } else { if ( isset( $block->context['postId'] ) ) { // Get value from the context. $object_id = $block->context['postId']; } else { // Fallback to the current queried object id. $object_id = get_queried_object_id(); } } return $object_id; } /** * Is the field is in a custom context? * * @param string $field_name * @param WP_Block $block * @param boolean $condition * @return boolean */ private function is_custom_context( $field_name, $block, $condition ) { if ( $condition ) { if ( !isset( $block->context['postId'] ) ) { return true; } else { global $_wp_current_template_id, $_wp_current_template_content ; if ( !$_wp_current_template_id || !$_wp_current_template_content ) { return false; } else { // Cache key for the blocks of template. $cache_key = 'blocks_by_' . str_replace( '//', '__', $_wp_current_template_id ); // Get from the cache. $blocks = wp_cache_get( $cache_key, 'mfb' ); if ( $blocks === false ) { $blocks = \parse_blocks( $_wp_current_template_content ); // Update cache. if ( !empty($blocks) ) { wp_cache_set( $cache_key, $blocks, 'mfb' ); } } return $this->find_mfb( $field_name, $blocks ); } } } return false; } /** * Find MFB not within a core query from an array of blocks * * @param string $field_name * @param array $blocks * @return boolean */ private function find_mfb( $field_name, $blocks ) { $found = false; foreach ( $blocks as $block ) { $block_name = $block['blockName'] ?? ''; if ( 'core/query' === $block_name ) { continue; } if ( 'mfb/meta-field-block' === $block_name ) { if ( $field_name === ($block['attrs']['fieldName'] ?? '') ) { $found = true; break; } } elseif ( !empty($block['innerBlocks']) ) { $found = $this->find_mfb( $field_name, $block['innerBlocks'] ); if ( $found ) { break; } } } return $found; } /** * Check whether if the block is dynamic of static * * @param array $attributes * @param mixed $content * @param WP_Block $block * @return boolean */ private function is_dynamic_block( $attributes ) { $field_type = $attributes['fieldType'] ?? ''; if ( 'acf' === $field_type ) { if ( $attributes['fieldSettings']['isStatic'] ?? false ) { return false; } } return true; } /** * Save version and trigger an upgrade hook * * @return void */ public function version_upgrade() { if ( get_option( 'mfb_current_version' ) !== $this->version ) { do_action( 'mfb_version_upgraded', get_option( 'mfb_current_version' ), $this->version ); update_option( 'mfb_current_version', $this->version ); } } /** * Register component * * @param string $classname The class name of the component. * @return void */ public function register_component( $classname ) { $this->components[$classname] = new $classname( $this ); } /** * Get a component by class name * * @param string $classname The class name of the component. * @return mixed */ public function get_component( $classname ) { return $this->components[$classname] ?? false; } /** * Define constant * * @param string $name The name of the constant. * @param mixed $value The value of the constant. * @return void */ public function define_constant( $name, $value ) { if ( !defined( $name ) ) { define( $name, $value ); } } /** * Retrn file path for file or folder. * * @param string $path file path. * @return string */ public function get_file_path( $path ) { return MFB_PATH . $path; } /** * Include file path. * * @param string $path file path. * @return mixed */ public function include_file( $path ) { return include_once $this->get_file_path( $path ); } /** * Get file uri by file path. * * @param string $path file path. * @return string */ public function get_file_uri( $path ) { return MFB_URL . $path; } /** * Create version for scripts/styles * * @param array $asset_file * @return string */ public function get_script_version( $asset_file ) { return ( wp_get_environment_type() !== 'production' ? $asset_file['version'] ?? MFB_VERSION : MFB_VERSION ); } /** * Get the plugin version * * @return string */ public function get_plugin_version() { return $this->version; } /** * Is Debugging * * @return boolean */ public function is_debug_mode() { return defined( 'MFB_DEBUG' ) && MFB_DEBUG || 'development' === wp_get_environment_type(); } /** * Enqueue debug log information * * @param string $handle * @return void */ public function enqueue_debug_information( $handle ) { wp_add_inline_script( $handle, 'var MFBLOG=' . wp_json_encode( [ 'environmentType' => ( $this->is_debug_mode() ? 'development' : wp_get_environment_type() ), ] ), 'before' ); } } /** * Kick start * * @return MetaFieldBlock instance */ function mfb_get_instance() { return MetaFieldBlock::get_instance(); } // Instantiate. mfb_get_instance(); } if ( !function_exists( __NAMESPACE__ . '\\meta_field_block_activate' ) ) { /** * Trigger an action when the plugin is activated. * * @return void */ function meta_field_block_activate() { do_action( 'meta_field_block_activate' ); } register_activation_hook( __FILE__, __NAMESPACE__ . '\\meta_field_block_activate' ); }