diff --git a/components/Templates/includes/functions-view_template.php b/components/Templates/includes/functions-view_template.php index 98b9f8a8f6..d895d02a68 100644 --- a/components/Templates/includes/functions-view_template.php +++ b/components/Templates/includes/functions-view_template.php @@ -91,6 +91,14 @@ function frontier_decode_template( $code, $atts ) { */ function frontier_if_block( $atts, $code ) { + $defaults = array( + 'pod' => null, + 'id' => null, + 'field' => null, + ); + + $atts = wp_parse_args( $atts, $defaults ); + $pod = pods( $atts['pod'], $atts['id'] ); if ( ! $pod || ! $pod->valid() || ! $pod->exists() ) { @@ -116,9 +124,58 @@ function frontier_if_block( $atts, $code ) { break; } } else { - $field_data = $pod->field( $atts['field'] ); - $field_type = $pod->fields( $atts['field'], 'type' ); + /** + * @since 2.7.27 Iterate recursively over magic tag fields (relationships). + * @todo Refactor to only use the Pods::field() method. + */ + $fields = explode( '.', $atts['field'] ); + $field_pod = $pod; + $total = count( $fields ); + $counter = 0; + + foreach ( $fields as $field_name ) { + $field = $field_name; + if ( ++$counter < $total ) { + + $field_type = $field_pod->fields( $field, 'type' ); + if ( ! in_array( $field_type, array( 'pick', 'taxonomy' ), true ) ) { + // Relationship type required. + break; + } + + $entries = $field_pod->field( $field ); + $rel_pod = $field_pod->fields( $field, 'pick_val' ); + + if ( ! $entries || ! $rel_pod ) { + // No relationships or pod name found. + break; + } + + $entry_id = null; + if ( isset( $entries['ID'] ) ) { + $entry_id = $entries['ID']; + } elseif ( isset( $entries['term_id'] ) ) { + $entry_id = $entries['term_id']; + } else { + // Multiple relationships. + $entries = reset( $entries ); + if ( isset( $entries['ID'] ) ) { + $entry_id = $entries['ID']; + } elseif ( isset( $entries['term_id'] ) ) { + $entry_id = $entries['term_id']; + } + } + + $new_pod = pods( $rel_pod, $entry_id ); + if ( $new_pod && $new_pod->valid() && $new_pod->exists() ) { + $field_pod = $new_pod; + } + } else { + $field_data = $field_pod->field( $field ); + $field_type = $field_pod->fields( $field, 'type' ); + } + } } $is_empty = true; @@ -472,7 +529,7 @@ function frontier_pseudo_magic_tags( $template, $data, $pod = null, $skip_unknow } /** - * processes template code within an each command from the base template + * Processes template code within an each command from the base template. * * @param array attributes from template * @param string template to be processed @@ -533,11 +590,6 @@ function frontier_prefilter_template( $code, $template, $pod ) { } else { $field = trim( $matches[2][ $key ] ); } - if ( false !== strpos( $field, '.' ) ) { - $path = explode( '.', $field ); - $field = array_pop( $path ); - $ID = '{@' . implode( '.', $path ) . '.' . $pod->api->pod_data['field_id'] . '}'; - } $atts = ' id="' . $ID . '" pod="@pod" field="' . $field . '"'; if ( ! empty( $value ) ) { $atts .= ' value="' . $value . '"'; diff --git a/tests/phpunit/includes/Shortcodes/Test_Each.php b/tests/phpunit/includes/Shortcodes/Test_Each.php index e94359f9e1..ea15bdca49 100644 --- a/tests/phpunit/includes/Shortcodes/Test_Each.php +++ b/tests/phpunit/includes/Shortcodes/Test_Each.php @@ -235,4 +235,45 @@ public function test_each_nested_in_external() { $content = base64_encode( '{@number1}_{@number2}' ); $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[test_each_recurse][pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template][/test_each_recurse]" ) ); } + + /** + * Test traversal each statements. + * Almost similar to test_each_nested_in_external() but this traverses one level deeper. + */ + public function test_each_traversal() { + + $pod_name = self::$pod_name; + $subsub_ids = array(); + $pod = pods( $pod_name ); + for ( $x = 1; $x <= 5; $x ++ ) { + $subsub_ids[] = $pod->add( + array( + 'post_status' => 'publish', + 'name' => $x, + 'number1' => $x, + 'number2' => $x * $x, + ) + ); + } + $sub_id = $pod->add( + array( + 'post_status' => 'publish', + 'name' => 'sub post', + 'number1' => 123, + 'number2' => 456, + 'related_field' => $subsub_ids, + ) + ); + $main_id = $pod->add( + array( + 'post_status' => 'publish', + 'name' => 'main post', + 'number1' => 159, + 'number2' => 753, + 'related_field' => $sub_id, + ) + ); + $content = base64_encode( '{@number1}_{@number2}' ); + $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[test_each_recurse][pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field.related_field']{$content}[/pod_sub_template][/test_each_recurse]" ) ); + } } diff --git a/tests/phpunit/includes/Shortcodes/Test_If.php b/tests/phpunit/includes/Shortcodes/Test_If.php index 8eb5926dbb..a40ed75bb9 100644 --- a/tests/phpunit/includes/Shortcodes/Test_If.php +++ b/tests/phpunit/includes/Shortcodes/Test_If.php @@ -235,4 +235,62 @@ public function test_if_related_field() { $this->assertEquals( 'first post title', do_shortcode( "[pods name='{$pod_name}' id='{$id2}'][if related_field]{@related_field.post_title}[/if][/pods]" ) ); } + + /** + * Test traversal if statements. + * Almost similar to test_if_related_field() but this traverses one level deeper and also adds the post title to the if statement. + */ + public function test_if_traversal() { + + $pod_name = self::$pod_name; + $id1 = pods( $pod_name )->add( + array( + 'post_status' => 'publish', + 'name' => 'first post title', + 'number1' => 123, + 'number2' => 456, + ) + ); + $id2 = pods( $pod_name )->add( + array( + 'post_status' => 'publish', + 'name' => 'second post title', + 'number1' => 987, + 'number2' => 654, + 'related_field' => $id1, + ) + ); + $id3 = pods( $pod_name )->add( + array( + 'post_status' => 'publish', + 'name' => 'third post title', + 'number1' => 159, + 'number2' => 753, + 'related_field' => $id2, + ) + ); + + // Not exactly related to the shortcode test but lets make sure we can at least retrieve the proper data + $this->assertEquals( '123', pods( $pod_name, $id3 )->field( 'related_field.related_field.number1' ) ); + + + // Traverse to the second relationship. + $content = base64_encode( '{@related_field.related_field.post_title}' ); + $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id3}' field='related_field.related_field']{$content}[/pod_if_field]" ) ); + + $content = base64_encode( '{@related_field.related_field.post_title}' ); + $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id3}' field='related_field.related_field']{$content}[/pod_if_field]" ) ); + + $this->assertEquals( 'first post title', do_shortcode( "[pods name='{$pod_name}' id='{$id3}'][if related_field.related_field]{@related_field.related_field.post_title}[/if][/pods]" ) ); + + // Traverse to the second relationship's post title + $content = base64_encode( '{@related_field.related_field.post_title}' ); + $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id3}' field='related_field.related_field.post_title']{$content}[/pod_if_field]" ) ); + + $content = base64_encode( '{@related_field.related_field.post_title}' ); + $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id3}' field='related_field.related_field.post_title']{$content}[/pod_if_field]" ) ); + + $this->assertEquals( 'first post title', do_shortcode( "[pods name='{$pod_name}' id='{$id3}'][if related_field.related_field.post_title]{@related_field.related_field.post_title}[/if][/pods]" ) ); + + } }