*/ private array $field_values; private Source $source; /** * Used e.g. for inner Views or Pods Blocks * * @var array|null */ private ?array $local_data; public function __construct( Field_Provider_Cluster $provider_cluster, Template_Renderer_Storage $template_renderer_storage, string $twig_template, Layout_Settings $layout_settings, Source $source, Field_Markup $field_markup, string $classes = '' ) { parent::__construct( $layout_settings, $twig_template, $classes ); $this->layout_settings = $layout_settings; $this->provider_cluster = $provider_cluster; $this->source = $source; $this->field_markup = $field_markup; $this->template_renderer_storage = $template_renderer_storage; $this->field_values = array(); $this->local_data = null; } /** * @param int|string $object_id Can be 'options' or 'user_x' * @param array $default_variables * @param array $field_values * @param array $custom_arguments * @param \Psr\Container\ContainerInterface|null $container * * @return array */ protected static function get_custom_template_variables( string $php_code, string $short_unique_view_id, $object_id, array $default_variables, array $field_values, array $custom_arguments = array(), bool $is_for_validation = false, $container = null ): array { $template_controller = eval_snippet( $php_code, array( // declared variables for back compatibility. '_viewId' => $short_unique_view_id, '_objectId' => $object_id, '_fields' => $field_values, ), $error ); return self::get_custom_controller_variables( $template_controller, $short_unique_view_id, $object_id, $default_variables, $field_values, $custom_arguments, $is_for_validation, $container ); } /** * @param mixed $template_controller * @param int|string $object_id Can be 'options' or 'user_x' * @param array $default_variables * @param array $field_values * @param array $custom_arguments * @param \Psr\Container\ContainerInterface|null $container * * @return array */ protected static function get_custom_controller_variables( $template_controller, string $short_unique_view_id, $object_id, array $default_variables, array $field_values, array $custom_arguments, bool $is_for_validation, $container ): array { if ( $template_controller instanceof Layout_Template_Controller ) { $template_controller->set_object_id( $object_id ); $template_controller->set_instance_id( $short_unique_view_id ); $template_controller->set_default_variables( $default_variables ); $template_controller->set_custom_arguments( $custom_arguments ); $template_controller->set_container( $container ); return ! $is_for_validation ? $template_controller->get_variables() : $template_controller->get_variables_for_validation(); } // array return is allowed for back compatibility. if ( is_array( $template_controller ) ) { /** * @var array $template_controller */ return $template_controller; } return array(); } /** * @return array */ public function get_ajax_response( string $php_code = '' ): array { return parent::get_ajax_response( $this->get_view_data()->php_variables ); } /** * @return mixed */ public function get_field_value( Field_Settings $field_settings, Field_Meta $field_meta, ?Item_Settings $item_settings = null, bool $is_formatted = false ) { return $this->provider_cluster->get_field_value( $field_settings, $field_meta, $this->source, $item_settings, $is_formatted, $this->local_data ); } public function convert_string_to_date_time( Field_Meta $field_meta, string $value ): ?DateTime { return $this->provider_cluster->convert_string_to_date_time( $field_meta, $value ); } public function get_source(): Source { return $this->source; } /** * @param array $custom_arguments */ public function insert_fields_and_print_html( array $custom_arguments = array() ): bool { $template = $this->get_template(); $twig_variables = $this->get_template_variables( false, $custom_arguments ); ob_start(); $is_rendered = $this->render_template_and_print_html( $template, $twig_variables ); $html = (string) ob_get_clean(); // shortcode support (necessary for the relationship field with the Field Layout option and others). echo do_shortcode( $html ); return $is_rendered; } public function get_view_data(): Layout_Settings { return $this->layout_settings; } /** * @param array|null $local_data */ public function set_local_data( ?array $local_data ): void { $this->local_data = $local_data; } /** * @param mixed $field_value * * @return array */ protected function get_template_args_for_variable( Item_Settings $item_settings, Field_Meta $field_meta, Source $source, $field_value, bool $is_for_validation ): array { $twig_args = $this->field_markup->get_field_twig_args( $this->layout_settings, $item_settings, $item_settings->field, $field_meta, $this, $source, $field_value, $is_for_validation ); return array( $item_settings->field->get_template_field_id() => array_merge( $twig_args, array( 'label' => $item_settings->field->get_label_translation(), ) ), ); } /** * @param array $variables */ protected function render_template_and_print_html( string $template, array $variables, bool $is_for_validation = false ): bool { if ( ! $this->layout_settings->allows_empty_rendering() && ! $is_for_validation ) { $is_empty = true; foreach ( $variables as $twig_variable_name => $twig_variable_value ) { $is_empty_value = is_array( $twig_variable_value ) && key_exists( 'value', $twig_variable_value ) && in_array( $twig_variable_value['value'], array( '', array(), null ), true ); // ignore the system variables. if ( in_array( $twig_variable_value, array( '', array(), null ), true ) || in_array( $twig_variable_name, $this->get_system_variable_names(), true ) || $is_empty_value ) { continue; } $is_empty = false; break; } if ( $is_empty ) { // do not render, as Twig saves template in cache // so if it's first, then it'll use the empty one for all next calls of this view. return false; } } $template_engine = $this->template_renderer_storage ->resolve_renderer( $this->layout_settings->template_engine ); if ( null !== $template_engine ) { $template_engine->print( $this->layout_settings->get_unique_id(), $template, $variables, $is_for_validation ); } else { $this->print_template_engine_is_not_loaded_message(); } return true; } /** * @param mixed $controller * * @return array */ protected function get_ajax_response_args( $controller ): array { if ( $controller instanceof Request_Controller ) { $controller->set_container( $this->get_container() ); return $controller->get_ajax_response(); } return array(); } /** * @param mixed $controller * * @return array */ protected function get_rest_api_response_args( WP_REST_Request $wprest_request, $controller ): array { if ( $controller instanceof Request_Controller ) { $controller->set_container( $this->get_container() ); return $controller->get_rest_api_response( $wprest_request ); } return array(); } public function get_rest_api_response( WP_REST_Request $wprest_request, string $php_code = '' ): array { return parent::get_rest_api_response( $wprest_request, $this->get_view_data()->php_variables ); } /** * @param array $custom_arguments * * @return array */ protected function get_template_variables( bool $is_for_validation = false, array $custom_arguments = array() ): array { $template_variables = $this->get_default_template_variables( $is_for_validation ); $short_unique_view_id = $this->get_view_data()->get_unique_id( true ); $object_id = ! $is_for_validation ? $this->get_source()->get_id() : '0'; // the static function is used to avoid any chance of changing the context (this). $php_variables = self::get_custom_template_variables( $this->get_view_data()->php_variables, $short_unique_view_id, $object_id, $template_variables, $this->get_field_values(), $custom_arguments, $is_for_validation, $this->get_container() ); $custom_variables = $this->apply_custom_variables_filter( $php_variables, $object_id, $is_for_validation ); foreach ( $custom_variables as $name => $value ) { $name = str_replace( '-', '_', $name ); $name = str_replace( ' ', '_', $name ); $template_variables[ $name ] = $value; } return $template_variables; } /** * @return string[] */ protected function get_system_variable_names(): array { return array( '_view', // for back compatibility. Hard_Layout_Cpt::variable_name(), ); } /** * @return array */ protected function get_default_template_variables( bool $is_for_validation = false ): array { $object_id = ! $is_for_validation ? strval( $this->source->get_id() ) : '0'; $this->field_values = array(); $twig_variables = array(); // internal variables. $internal_variables = array( 'classes' => $this->get_classes(), 'id' => $this->layout_settings->get_markup_id(), // replace for others: term_6 to term-6. 'object_id' => str_replace( '_', '-', $object_id ), ); foreach ( $this->get_system_variable_names() as $name ) { $twig_variables[ $name ] = $internal_variables; } foreach ( $this->layout_settings->items as $item ) { $field_meta = $item->field->get_field_meta(); $field_value = false === $is_for_validation ? $this->get_field_value( $item->field, $field_meta, $item ) : null; $is_empty_value = in_array( $field_value, array( '', array(), null ), true ); // 1. default value from our plugin. Note: custom field types don't support default values if ( $is_empty_value && $field_meta->is_native_type() ) { $field_value = $item->field->default_value; } $is_empty_value = in_array( $field_value, array( '', array(), null ), true ); // 2. default value from ACF. Note: custom field types don't support default values if ( $is_empty_value && $field_meta->is_native_type() ) { $field_value = $field_meta->get_default_value(); } $this->field_values[ $item->field->id ] = $field_value; $twig_variables = array_merge( $twig_variables, $this->get_template_args_for_variable( $item, $field_meta, $this->source, $field_value, $is_for_validation ) ); } return $twig_variables; } /** * @param array $php_variables * @param mixed $object_id * * @return mixed[] */ protected function apply_custom_variables_filter( array $php_variables, $object_id, bool $is_for_validation ): array { $short_unique_view_id = $this->get_view_data()->get_unique_id( true ); $custom_variables = Plugin::apply_filters( array( 'advanced_views/layout/custom_variables', 'acf_views/view/custom_variables', ), $php_variables, $short_unique_view_id, $object_id, $this->get_field_values(), $is_for_validation ); $custom_variables = Plugin::apply_filters( array( sprintf( 'advanced_views/layout/custom_variables/layout_id=%s', $short_unique_view_id ), sprintf( 'acf_views/view/custom_variables/view_id=%s', $short_unique_view_id ), ), $custom_variables, $short_unique_view_id, $object_id, $this->get_field_values(), $is_for_validation ); return arr( $custom_variables ); } /** * @return array */ protected function get_field_values(): array { return $this->field_values; } }