<?php
/**
* Class description
*
* @package package_name
* @author Cherry Team
* @license GPL-2.0+
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( ! class_exists( 'Jet_Engine_ACF_Package' ) ) {
/**
* Define Jet_Engine_ACF_Package class
*/
class Jet_Engine_ACF_Package {
private $fields_groups = null;
private $found_fields = array();
/**
* Constructor for the class
*/
function __construct() {
add_filter( 'jet-engine/listings/data/sources', array( $this, 'add_field_source' ) );
add_filter( 'jet-engine/listings/dynamic-image/fields', array( $this, 'add_field_source' ) );
add_filter( 'jet-engine/listings/dynamic-link/fields', array( $this, 'add_field_source' ) );
add_filter( 'jet-engine/listings/dynamic-repeater/fields', array( $this, 'add_field_source' ) );
add_action( 'jet-engine/listings/dynamic-field/source-controls', array( $this, 'field_controls' ) );
add_action( 'jet-engine/listings/dynamic-link/source-controls', array( $this, 'link_controls' ) );
add_action( 'jet-engine/listings/dynamic-repeater/source-controls', array( $this, 'repeater_controls' ) );
add_action( 'jet-engine/listings/dynamic-image/source-controls', array( $this, 'image_controls' ) );
add_action( 'jet-engine/listings/dynamic-image/link-source-controls', array( $this, 'linked_image_controls' ) );
add_filter( 'jet-engine/listings/dynamic-image/custom-image', array( $this, 'image_render' ), 10, 2 );
add_filter( 'jet-engine/listings/dynamic-image/custom-url', array( $this, 'image_url_render' ), 10, 2 );
add_filter( 'jet-engine/listings/dynamic-link/custom-url', array( $this, 'link_render' ), 10, 2 );
add_filter( 'jet-engine/listings/dynamic-field/field-value', array( $this, 'field_render' ), 10, 2 );
add_filter( 'jet-engine/listings/dynamic-repeater/pre-get-saved', array( $this, 'repeater_val' ), 10, 2 );
add_filter( 'jet-engine/listings/allowed-callbacks', array( $this, 'gallery_field_callbacks' ) );
}
/**
* Add ACF gallery filter callback to allowed callbacks list
*
* @param array $callbacks [description]
* @return [type] [description]
*/
public function gallery_field_callbacks( $callbacks = array() ) {
$callbacks['jet_engine_acf_gallery_wp'] = __( 'ACF Gallery as WP Gallery', 'jet-engine' );
return $callbacks;
}
/**
* Returns repeater field value
*
* @param [type] $val [description]
* @param [type] $settings [description]
* @return [type] [description]
*/
public function repeater_val( $result, $settings ) {
if ( 'acf_field_groups' !== $settings['dynamic_field_source'] ) {
return $result;
}
$key = isset( $settings['acf_field_key'] ) ? $settings['acf_field_key'] : false;
$keyinfo = $this->parse_key( $key, true );
if ( empty( $key ) ) {
return $result;
}
$key = $keyinfo['key'];
$id = $keyinfo['id'];
if ( 'options' === $id ) {
$field_object = get_field_object( $key, $id );
if ( $field_object ) {
return $field_object['value'];
}
return $result;
}
$field = acf_get_field( $id );
$sub_fields = isset( $field['sub_fields'] ) ? $field['sub_fields'] : false;
if ( empty( $sub_fields ) ) {
return $result;
}
$count = jet_engine()->listings->data->get_meta( $key );
if ( ! $count ) {
return $result;
}
$result = array();
for ( $i = 0; $i < absint( $count ); $i++ ) {
$item = array();
foreach ( $sub_fields as $sub_field ) {
$item[ $sub_field['name'] ] = jet_engine()->listings->data->get_meta(
$key . '_' . $i . '_' . $sub_field['name']
);
}
$result[] = $item;
}
return $result;
}
/**
* Render field
*
* @param [type] $result [description]
* @param array $settings [description]
* @return [type] [description]
*/
public function field_render( $result, $settings = array() ) {
$key = isset( $settings['acf_field_key'] ) ? $settings['acf_field_key'] : false;
$key = $this->parse_key( $key, true );
if ( ! $key ) {
return $result;
}
$field_id = $key['id'];
$key = $key['key'];
if ( 'options' === $field_id ) {
$field_object = get_field_object( $key, $field_id );
} else {
$field_object = get_field_object( $field_id );
}
if ( $field_object ) {
return $field_object['value'];
}
return jet_engine()->listings->data->get_meta( $key );
}
/**
* Return custom image for ACF
*
* @param [type] $result [description]
* @param [type] $settings [description]
* @return [type] [description]
*/
public function image_render( $result, $settings ) {
if ( 'acf_field_groups' !== $settings['dynamic_image_source'] ) {
return $result;
}
$key = isset( $settings['acf_field_key'] ) ? $settings['acf_field_key'] : false;
$key = $this->parse_key( $key, true );
if ( ! $key ) {
return $result;
}
$field_id = $key['id'];
$key = $key['key'];
if ( 'options' === $field_id ) {
$field_object = get_field_object( $key, $field_id );
} else {
$field_object = false;
}
if ( $field_object ) {
$image = $field_object['value'];
if ( ! empty( $field_object['return_format'] ) ) {
switch ( $field_object['return_format'] ) {
case 'array':
$image = $image['ID'];
break;
case 'url':
$image = attachment_url_to_postid( $image );
break;
}
}
} else {
$image = jet_engine()->listings->data->get_meta( $key );
}
if ( ! $image ) {
return $result;
}
$image = absint( $image );
if ( ! $image ) {
return $result;
}
$size = isset( $settings['dynamic_image_size'] ) ? $settings['dynamic_image_size'] : 'full';
return wp_get_attachment_image( $image, $size, false, array( 'alt' => get_the_title() ) );
}
/**
* Return custom image URL for ACF
*
* @param [type] $url [description]
* @param array $settings [description]
* @return [type] [description]
*/
public function image_url_render( $url, $settings = array() ) {
$custom = ! empty( $settings['image_link_source_custom'] ) ? $settings['image_link_source_custom'] : false;
if ( $custom ) {
return $url;
}
$key = isset( $settings['acf_link_field_key'] ) ? $settings['acf_link_field_key'] : false;
$key = $this->parse_key( $key, true );
if ( ! $key ) {
return $url;
}
$field_id = $key['id'];
$key = $key['key'];
if ( 'options' === $field_id ) {
$field_object = get_field_object( $key, $field_id );
if ( $field_object ) {
return $field_object['value'];
}
}
$val = jet_engine()->listings->data->get_meta( $key );
if ( 0 < absint( $val ) ) {
return get_permalink( $val );
} else {
return $val;
}
}
/**
* Return custom image URL for ACF
*
* @param [type] $url [description]
* @param array $settings [description]
* @return [type] [description]
*/
public function link_render( $url, $settings = array() ) {
if ( ! empty( $settings['dynamic_link_source_custom'] ) ) {
return $url;
}
$key = isset( $settings['acf_field_key'] ) ? $settings['acf_field_key'] : false;
$key = $this->parse_key( $key, true );
if ( empty( $key ) ) {
return $url;
}
$field_id = $key['id'];
$key = $key['key'];
if ( 'options' === $field_id ) {
$field_object = get_field_object( $key, $field_id );
} else {
$field_object = get_field_object( $field_id );
}
if ( $field_object ) {
return $field_object['value'];
}
$val = jet_engine()->listings->data->get_meta( $key );
if ( 0 < absint( $val ) ) {
return get_permalink( $val );
} else {
return $val;
}
}
/**
* Parse key from string
*
* @param [type] $key [description]
* @return [type] [description]
*/
public function parse_key( $key, $return_with_id = false ) {
if ( ! $key ) {
return false;
}
$key_parts = explode( '::', $key );
if ( ! isset( $key_parts[1] ) ) {
return false;
}
$key = $key_parts[1];
if ( true === $return_with_id ) {
return array(
'key' => $key,
'id' => $key_parts[0],
);
} else {
return $key;
}
}
/**
* Add field source
*/
public function add_field_source( $sources ) {
$sources['acf_field_groups'] = __( 'ACF', 'jet-engine' );
return $sources;
}
/**
* Repeater controls
*
* @return [type] [description]
*/
public function repeater_controls( $widget ) {
$this->add_control( $widget, array(
'group' => 'repeater',
'condition' => array(
'dynamic_field_source' => 'acf_field_groups',
),
) );
}
/**
* Image controls
*
* @return [type] [description]
*/
public function image_controls( $widget ) {
$this->add_control( $widget, array(
'group' => 'images',
'condition' => array(
'dynamic_image_source' => 'acf_field_groups',
),
) );
}
public function linked_image_controls( $widget ) {
$this->add_control( $widget, array(
'id' => 'acf_link_field_key',
'group' => 'links',
'condition' => array(
'linked_image' => 'yes',
'image_link_source' => 'acf_field_groups',
),
) );
}
public function link_controls( $widget ) {
$this->add_control( $widget, array(
'group' => 'links',
'condition' => array(
'dynamic_link_source' => 'acf_field_groups',
),
) );
}
/**
* Field controls
*
* @return [type] [description]
*/
public function field_controls( $widget ) {
$this->add_control( $widget, array(
'group' => 'fields',
'condition' => array(
'dynamic_field_source' => 'acf_field_groups',
),
) );
}
public function add_control( $widget, $args = array() ) {
$group = isset( $args['group'] ) ? $args['group'] : 'fields';
$condition = isset( $args['condition'] ) ? $args['condition'] : array();
$id = isset( $args['id'] ) ? $args['id'] : 'acf_field_key';
$widget->add_control(
$id,
array(
'label' => __( 'ACF Field', 'jet-engine' ),
'type' => Elementor\Controls_Manager::SELECT,
'default' => '',
'groups' => $this->get_fields_goups( $group ),
'condition' => $condition,
)
);
}
public function get_fields_goups( $group = 'fields' ) {
$cb = array(
'fields' => 'map_fields',
'images' => 'map_images',
'links' => 'map_links',
'repeater' => 'map_repeater',
);
$groups = $this->get_raw_goups();
$result = array();
if ( empty( $groups ) ) {
return $result;
}
foreach ( $groups as $data ) {
$fields = array_filter( array_map( array( $this, $cb[ $group ] ), $data['options'] ) );
if ( ! empty( $fields ) ) {
$result[] = array(
'label' => $data['label'],
'options' => $fields,
);
}
}
return $result;
}
/**
* Map images callback
*
* @param [type] $field [description]
* @return [type] [description]
*/
public function map_images( $field ) {
$whitelisted = $this->whitelisted_fields();
$type = $field['type'];
if ( ! in_array( 'image', $whitelisted[ $type ] ) ) {
return false;
} else {
return $field['label'];
}
}
/**
* Map links callback
*
* @param [type] $field [description]
* @return [type] [description]
*/
public function map_links( $field ) {
$whitelisted = $this->whitelisted_fields();
$type = $field['type'];
if ( ! in_array( 'link', $whitelisted[ $type ] ) ) {
return false;
} else {
return $field['label'];
}
}
/**
* Map fields callback
*
* @param [type] $field [description]
* @return [type] [description]
*/
public function map_fields( $field ) {
$whitelisted = $this->whitelisted_fields();
$type = $field['type'];
if ( ! in_array( 'field', $whitelisted[ $type ] ) ) {
return false;
} else {
return $field['label'];
}
}
/**
* Map fields callback
*
* @param [type] $field [description]
* @return [type] [description]
*/
public function map_repeater( $field ) {
$whitelisted = $this->whitelisted_fields();
$type = $field['type'];
if ( ! in_array( 'repeater', $whitelisted[ $type ] ) ) {
return false;
} else {
return $field['label'];
}
}
/**
* Fields gorups
*
* @return array
*/
public function get_raw_goups() {
if ( null !== $this->fields_groups ) {
return $this->fields_groups;
}
// ACF >= 5.0.0
if ( function_exists( 'acf_get_field_groups' ) ) {
$groups = acf_get_field_groups();
} else {
$groups = apply_filters( 'acf/get_field_groups', [] );
}
$options_page_groups_ids = array();
if ( function_exists( 'acf_options_page' ) ) {
$pages = acf_options_page()->get_pages();
foreach ( $pages as $slug => $page ) {
$options_page_groups = acf_get_field_groups( array(
'options_page' => $slug,
) );
foreach ( $options_page_groups as $options_page_group ) {
$options_page_groups_ids[] = $options_page_group['ID'];
}
}
}
$result = array();
$whitelisted = $this->whitelisted_fields();
foreach ( $groups as $group ) {
// ACF >= 5.0.0
if ( function_exists( 'acf_get_fields' ) ) {
$fields = acf_get_fields( $group['ID'] );
} else {
$fields = apply_filters( 'acf/field_group/get_fields', [], $group['id'] );
}
$options = [];
if ( ! is_array( $fields ) ) {
continue;
}
$has_option_page_location = in_array( $group['ID'], $options_page_groups_ids, true );
$is_only_options_page = $has_option_page_location && 1 === count( $group['location'] );
foreach ( $fields as $field ) {
if ( ! isset( $whitelisted[ $field['type'] ] ) ) {
continue;
}
if ( $has_option_page_location ) {
$key = 'options::' . $field['name'];
$options[ $key ] = array(
'type' => $field['type'],
'label' => __( 'Options', 'jet-engine' ) . ':' . $field['label'],
);
if ( $is_only_options_page ) {
continue;
}
}
$key = $field['key'] . '::' . $field['name'];
$options[ $key ] = array(
'type' => $field['type'],
'label' => $field['label']
);
}
if ( empty( $options ) ) {
continue;
}
$result[] = array(
'label' => $group['title'],
'options' => $options,
);
}
$this->fields_groups = $result;
return $this->fields_groups;
}
/**
* Returns whitelisted fields
*
* @return [type] [description]
*/
public function whitelisted_fields() {
return array(
'text' => array( 'field', 'link' ),
'textarea' => array( 'field' ),
'number' => array( 'field' ),
'range' => array( 'field' ),
'email' => array( 'field', 'link' ),
'url' => array( 'field', 'link' ),
'wysiwyg' => array( 'field' ),
'image' => array( 'link', 'image' ),
'file' => array( 'link' ),
'gallery' => array( 'field' ),
'select' => array( 'field' ),
'radio' => array( 'field' ),
'checkbox' => array( 'field' ),
'button_group' => array( 'field' ),
'true_false' => array( 'field' ),
'page_link' => array( 'field', 'link' ),
'post_object' => array( 'field', 'link' ),
'relationship' => array( 'field', 'link' ),
'taxonomy' => array( 'field', 'link' ),
'date_picker' => array( 'field', 'link' ),
'date_time_picker' => array( 'field' ),
'time_picker' => array( 'field' ),
'repeater' => array( 'repeater' ),
'oembed' => array( 'field' ),
);
}
}
}
$jet_engine_acf = new Jet_Engine_ACF_Package();
/**
* Define additional functions
*/
function jet_engine_acf_gallery_wp( $value ) {
if ( ! $value ) {
return false;
}
if ( ! is_array( $value ) ) {
return false;
}
return do_shortcode( '[gallery ids="' . implode( ',', $value ) . '"]' );
}