web/wp-content/plugins/acf-extended/includes/fields/field-flexible-content-preview.php (335 lines of code) (raw):
<?php
if(!defined('ABSPATH')){
exit;
}
if(!class_exists('acfe_field_flexible_content_preview')):
class acfe_field_flexible_content_preview{
/**
* construct
*/
function __construct(){
// Hooks
add_filter('acfe/flexible/defaults_field', array($this, 'defaults_field'), 2);
add_filter('acfe/flexible/defaults_layout', array($this, 'defaults_layout'), 2);
add_action('acfe/flexible/render_field_settings', array($this, 'render_field_settings'), 2);
add_action('acfe/flexible/render_layout_settings', array($this, 'render_layout_settings'), 15, 3);
add_action('acf/render_field/type=flexible_content', array($this, 'render_field'), 8);
add_filter('acfe/flexible/wrapper_attributes', array($this, 'wrapper_attributes'), 10, 2);
add_filter('acfe/flexible/prepare_layout', array($this, 'prepare_layout'), 25, 5);
// Ajax
add_action('wp_ajax_acfe/flexible/layout_preview', array($this, 'layout_preview'));
}
/**
* defaults_field
*
* @param $field
*
* @return mixed
*/
function defaults_field($field){
$field['acfe_flexible_layouts_templates'] = false;
$field['acfe_flexible_layouts_previews'] = false;
$field['acfe_flexible_layouts_placeholder'] = false;
return $field;
}
/**
* defaults_layout
*
* @param $layout
*
* @return mixed
*/
function defaults_layout($layout){
$layout['acfe_flexible_render_template'] = false;
$layout['acfe_flexible_render_style'] = false;
$layout['acfe_flexible_render_script'] = false;
return $layout;
}
/**
* render_field_settings
*
* @param $field
*/
function render_field_settings($field){
// Render
acf_render_field_setting($field, array(
'label' => __('Dynamic Render', 'acfe'),
'name' => 'acfe_flexible_layouts_templates',
'key' => 'acfe_flexible_layouts_templates',
'instructions' => __('Render the layout using custom template, style & javascript files', 'acfe') . '. ' . '<a href="https://www.acf-extended.com/features/fields/flexible-content/dynamic-render" target="_blank">' . __('See documentation', 'acfe') . '</a>',
'type' => 'true_false',
'message' => '',
'default_value' => false,
'ui' => true,
'ui_on_text' => '',
'ui_off_text' => '',
'conditional_logic' => array(
array(
array(
'field' => 'acfe_flexible_advanced',
'operator' => '==',
'value' => '1',
),
)
)
));
// Preview
acf_render_field_setting($field, array(
'label' => __('Dynamic Preview', 'acfe'),
'name' => 'acfe_flexible_layouts_previews',
'key' => 'acfe_flexible_layouts_previews',
'instructions' => __('Use layouts render settings to display a dynamic preview in the administration', 'acfe') . '. ' . '<a href="https://www.acf-extended.com/features/fields/flexible-content/dynamic-render#dynamic-preview" target="_blank">' . __('See documentation', 'acfe') . '</a>',
'type' => 'true_false',
'message' => '',
'default_value' => false,
'ui' => true,
'ui_on_text' => '',
'ui_off_text' => '',
'conditional_logic' => array(
array(
array(
'field' => 'acfe_flexible_advanced',
'operator' => '==',
'value' => '1',
),
array(
'field' => 'acfe_flexible_layouts_templates',
'operator' => '==',
'value' => '1',
),
)
)
));
// Placholder
acf_render_field_setting($field, array(
'label' => __('Layouts Placeholder', 'acfe'),
'name' => 'acfe_flexible_layouts_placeholder',
'key' => 'acfe_flexible_layouts_placeholder',
'instructions' => __('Display a placeholder with an icon', 'acfe') . '. ' . '<a href="https://www.acf-extended.com/features/fields/flexible-content/advanced-settings#layouts-placeholder" target="_blank">' . __('See documentation', 'acfe') . '</a>',
'type' => 'true_false',
'message' => '',
'default_value' => false,
'ui' => true,
'ui_on_text' => '',
'ui_off_text' => '',
'conditional_logic' => array(
array(
array(
'field' => 'acfe_flexible_advanced',
'operator' => '==',
'value' => '1',
),
array(
'field' => 'acfe_flexible_layouts_previews',
'operator' => '!=',
'value' => '1',
),
)
)
));
}
/**
* render_layout_settings
*
* @param $flexible
* @param $layout
* @param $prefix
*/
function render_layout_settings($flexible, $layout, $prefix){
if(!acf_maybe_get($flexible, 'acfe_flexible_layouts_templates')){
return;
}
// vars
$name = $flexible['name'];
$key = $flexible['key'];
$l_name = $layout['name'];
$prepend = acfe_get_setting('theme_folder') ? trailingslashit(acfe_get_setting('theme_folder')) : '';
// Title
echo '</li>';
acf_render_field_wrap(array(
'label' => __('Render', 'acfe'),
'type' => 'hidden',
'name' => 'acfe_flexible_render_label',
'wrapper' => array(
'class' => 'acfe-flexible-field-setting acfe-flexible-field-setting-row',
)
), 'ul');
echo '<li>';
// Template
$prepend = apply_filters("acfe/flexible/prepend/template", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/template/name={$name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/template/key={$key}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/template/layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/template/name={$name}&layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/template/key={$key}&layout={$l_name}", $prepend, $flexible, $layout);
acf_render_field_wrap(array(
'prepend' => $prepend,
'name' => 'acfe_flexible_render_template',
'type' => 'text',
'class' => 'acf-fc-meta-name',
'prefix' => $prefix,
'value' => $layout['acfe_flexible_render_template'],
'placeholder' => 'template.php',
), 'ul');
// Style
$prepend = apply_filters("acfe/flexible/prepend/style", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/style/name={$name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/style/key={$key}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/style/layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/style/name={$name}&layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/style/key={$key}&layout={$l_name}", $prepend, $flexible, $layout);
acf_render_field_wrap(array(
'prepend' => $prepend,
'name' => 'acfe_flexible_render_style',
'type' => 'text',
'class' => 'acf-fc-meta-name',
'prefix' => $prefix,
'value' => $layout['acfe_flexible_render_style'],
'placeholder' => 'style.css',
), 'ul');
// Script
$prepend = apply_filters("acfe/flexible/prepend/script", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/script/name={$name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/script/key={$key}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/script/layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/script/name={$name}&layout={$l_name}", $prepend, $flexible, $layout);
$prepend = apply_filters("acfe/flexible/prepend/script/key={$key}&layout={$l_name}", $prepend, $flexible, $layout);
acf_render_field_wrap(array(
'prepend' => $prepend,
'name' => 'acfe_flexible_render_script',
'type' => 'text',
'class' => 'acf-fc-meta-name',
'prefix' => $prefix,
'value' => $layout['acfe_flexible_render_script'],
'placeholder' => 'script.js',
), 'ul');
}
/**
* render_field
*
* @param $field
*/
function render_field($field){
// check setting
if(!acf_maybe_get($field, 'acfe_flexible_layouts_templates') || !acf_maybe_get($field, 'acfe_flexible_layouts_previews')){
return;
}
// vars
$name = $field['_name'];
$key = $field['key'];
// vars
global $is_preview;
$is_preview = true;
// actions
do_action("acfe/flexible/enqueue", $field, $is_preview);
do_action("acfe/flexible/enqueue/name={$name}", $field, $is_preview);
do_action("acfe/flexible/enqueue/key={$key}", $field, $is_preview);
// loop
foreach($field['layouts'] as $layout){
// Enqueue
acfe_flexible_render_layout_enqueue($layout, $field);
}
}
/**
* wrapper_attributes
*
* @param $wrapper
* @param $field
*
* @return mixed
*/
function wrapper_attributes($wrapper, $field){
if(acf_maybe_get($field, 'acfe_flexible_layouts_placeholder')){
$wrapper['data-acfe-flexible-placeholder'] = 1;
}
if(acf_maybe_get($field, 'acfe_flexible_layouts_templates') && acf_maybe_get($field, 'acfe_flexible_layouts_previews')){
$wrapper['data-acfe-flexible-placeholder'] = 1;
$wrapper['data-acfe-flexible-preview'] = 1;
}
return $wrapper;
}
/**
* prepare_layout
*
* @param $layout
* @param $field
* @param $i
* @param $value
* @param $prefix
*
* @return mixed
*/
function prepare_layout($layout, $field, $i, $value, $prefix){
if(!acf_maybe_get($field, 'acfe_flexible_layouts_placeholder') && !acf_maybe_get($field, 'acfe_flexible_layouts_previews')){
return $layout;
}
// Vars
$name = $field['_name'];
$key = $field['key'];
$l_name = $layout['name'];
$placeholder = array(
'class' => 'acfe-fc-placeholder',
'title' => __('Edit layout', 'acfe'),
);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder", $placeholder, $layout, $field, $i, $value, $prefix);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder/name={$name}", $placeholder, $layout, $field, $i, $value, $prefix);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder/key={$key}", $placeholder, $layout, $field, $i, $value, $prefix);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder/layout={$l_name}", $placeholder, $layout, $field, $i, $value, $prefix);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder/name={$name}&layout={$l_name}", $placeholder, $layout, $field, $i, $value, $prefix);
$placeholder = apply_filters("acfe/flexible/layouts/placeholder/key={$key}&layout={$l_name}", $placeholder, $layout, $field, $i, $value, $prefix);
$html = false;
if(!empty($value) && acf_maybe_get($field, 'acfe_flexible_layouts_previews')){
ob_start();
$this->layout_preview(array(
'post_id' => acf_get_valid_post_id(),
'i' => $i,
'field_key' => $key,
'layout' => $l_name,
'value' => $value,
));
$html = ob_get_clean();
if(strlen($html) > 0){
$placeholder['class'] .= ' acfe-fc-preview';
}
}
?>
<div <?php echo acf_esc_atts($placeholder); ?>>
<a href="#" class="button">
<span class="dashicons dashicons-edit"></span>
</a>
<div class="acfe-fc-overlay"></div>
<div class="acfe-flexible-placeholder -preview"><?php echo $html; ?></div>
</div>
<?php
return $layout;
}
var $no_post = false;
/**
* layout_preview
*
* @param $options
*
* @return bool|null
*/
function layout_preview($options = array()){
if(empty($options)){
// Options
$options = acf_parse_args($_POST, array(
'post_id' => 0,
'i' => 0,
'field_key' => '',
'nonce' => '',
'layout' => '',
'value' => array()
));
}
// Load field
$field = acf_get_field($options['field_key']);
if(!$field){
return $this->return_or_die();
}
// Layout
$instance = acf_get_field_type('flexible_content');
$layout = $instance->get_layout($options['layout'], $field);
if(!$layout){
return $this->return_or_die();
}
// Global
global $is_preview;
// Vars
$is_preview = true;
$name = $field['_name'];
$key = $field['key'];
$l_name = $layout['name'];
$post_id = acf_uniqid('acfe/flexible_content/preview');
// Prepare values
$meta = array($options['field_key'] => array(
wp_unslash($options['value'])
));
acfe_setup_meta($meta, $post_id, true);
if(have_rows($options['field_key'])):
while(have_rows($options['field_key'])): the_row();
global $post;
if($this->no_post){
$post = null;
}
// context:ajax/taxonomy/user page
if(!isset($post)){
$post_id = acfe_get_post_id('array');
// ajax
if($post_id['type'] === 'post'){
$post = get_post($post_id['id']);
// /taxonomy/user page
}else{
// assign for next call
// this fix the issue where doing new WP_Query() in a taxonomy page
// will setup the last $post as global and break next get_field() calls
$this->no_post = true;
}
}
if($this->no_post){
add_action('loop_end', array($this, 'loop_end'));
}
add_filter('acf/pre_load_post_id', array($this, 'pre_load_post_id'), 2, 2);
add_action('loop_start', array($this, 'loop_start'));
// update loop for get_row_index
$i = (int) $options['i'];
acf_update_loop('active', 'i', $i);
// deprecated
do_action_deprecated("acfe/flexible/preview/name={$name}", array($field, $layout), '0.8.6.7');
do_action_deprecated("acfe/flexible/preview/key={$key}", array($field, $layout), '0.8.6.7');
do_action_deprecated("acfe/flexible/layout/preview/layout={$l_name}", array($field, $layout), '0.8.6.7');
do_action_deprecated("acfe/flexible/layout/preview/name={$name}&layout={$l_name}", array($field, $layout), '0.8.6.7');
do_action_deprecated("acfe/flexible/layout/preview/key={$key}&layout={$l_name}", array($field, $layout), '0.8.6.7');
do_action_deprecated("acfe/flexible/preview", array($field, $layout), '0.8.6.7');
// include template
acfe_flexible_render_layout_template($layout, $field);
remove_filter('acf/pre_load_post_id', array($this, 'pre_load_post_id'), 2);
remove_action('loop_start', array($this, 'loop_start'));
if($this->no_post){
remove_action('loop_end', array($this, 'loop_end'));
}
endwhile;
endif;
acfe_reset_meta();
return $this->return_or_die();
}
/**
* loop_start
*
* Allow to use new WP_Query() in the layout preview/admin
* https://core.trac.wordpress.org/ticket/18408
*
* @return void
*/
function loop_start(){
if(is_admin()){
global $wp_query, $post;
$wp_query->post = $post;
}
}
/**
* loop_end
*
* Quick hack for taxonomy/user/options page
* This reset the global $post after the end of while($q->have_posts()): $q->the_post()
* Not ideal, but it works
*
* @return void
*/
function loop_end(){
if(is_admin()){
global $post;
$post = null;
}
}
/**
* pre_load_post_id
*
* This only affect get_field() in the layout preview/admin
*
* @param $null
* @param $post_id
*
* @return false|mixed
*/
function pre_load_post_id($null, $post_id){
if(!$post_id){
global $post;
if($post){
return null; // let acf find the post id from the $post
}
// taxonomy/user/options page
// retrieve the correct post id dynamically
return acfe_get_post_id();
}
return $null;
}
/**
* return_or_die
*
* @return bool|void
*/
function return_or_die(){
// check ajax & make sure the action is correct
if(wp_doing_ajax() && acf_maybe_get_POST('action') === 'acfe/flexible/layout_preview'){
die;
}
return true;
}
}
acf_new_instance('acfe_field_flexible_content_preview');
endif;