diff --git a/classes/Pods.php b/classes/Pods.php index 424c3194d3..d87e75a1df 100644 --- a/classes/Pods.php +++ b/classes/Pods.php @@ -827,6 +827,7 @@ public function field( $name, $single = null, $raw = false ) { $is_tableless_field = in_array( $field_type, $tableless_field_types, true ); $is_repeatable_field = $field_data instanceof Field && $field_data->is_repeatable(); $is_pick_field = 'pick' === $field_type; + $is_mapped = false; // Handle output specific handling. if ( $is_pick_field ) { @@ -925,11 +926,11 @@ public function field( $name, $single = null, $raw = false ) { $value = $map_field_values->map_value( $first_field, $traverse_fields, $is_field_set ? $field_data : null, $this, $params ); - $object_field_found = null !== $value; + $is_mapped = null !== $value; } // Continue regular field parsing. - if ( false === $object_field_found ) { + if ( false === $object_field_found && false === $is_mapped ) { $params->traverse = array( $params->name ); if ( false !== strpos( $params->name, '.' ) ) { @@ -1696,7 +1697,7 @@ public function field( $name, $single = null, $raw = false ) { $value = array_merge( ...$value ); } - if ( ! empty( $field_data ) && ( $params->display || ! $params->raw ) && ! $params->in_form && ! $params->raw_display ) { + if ( ! $is_mapped && ! empty( $field_data ) && ( $params->display || ! $params->raw ) && ! $params->in_form && ! $params->raw_display ) { if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && ! in_array( $field_data['type'], $tableless_field_types, true ) ) ) { $post_temp = false; $old_post = null; diff --git a/src/Pods/Data/Map_Field_Values.php b/src/Pods/Data/Map_Field_Values.php index 06c79b8622..c283ba2ab6 100644 --- a/src/Pods/Data/Map_Field_Values.php +++ b/src/Pods/Data/Map_Field_Values.php @@ -58,6 +58,7 @@ public function map_value( $field, $traverse, $field_data, $obj = null, $params 'context_info', 'calculation', 'image_fields', + 'date_fields', 'avatar', ]; @@ -703,6 +704,91 @@ public function image_fields( $field, $traverse, $field_data, $obj ) { return pods_traverse( $traverse_params, $value ); } + /** + * Map the date field value. + * + * @since 2.9.14 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods|null $obj The Pods object or null if not set. + * + * @return null|mixed The date field value or null if there was no match. + */ + public function date_fields( $field, $traverse, $field_data, $obj = null ) { + + // Skip if there is no information about this field. + if ( ! $field_data ) { + return null; + } + + /** + * Default date field handlers. + * @see \PodsForm::date_field_types + */ + $date_fields = array( + 'date', + 'time', + 'datetime', + ); + + $field_type = $field_data->get_type(); + + // Skip if the field is NOT a date/time/datetime field type. + if ( ! in_array( $field_type, $date_fields, true ) ) { + return null; + } + + // Handle getting current field value. + $value = $obj->field( $field, [ + 'raw' => true, + 'bypass_map_field_values' => true, + ] ); + + // No fields modifiers found. + if ( empty( $traverse[0] ) || empty( $traverse[1] ) ) { + return null; + } + + switch ( $traverse[0] ) { + case '_format': + $format = $traverse[1]; + + switch ( $format ) { + case 'date': + case 'wp_date': + case 'wordpress_date': + $format = get_option( 'date_format' ); + break; + case 'time': + case 'wp_time': + case 'wordpress_time': + $format = get_option( 'time_format' ); + break; + case 'datetime': + case 'wp': + case 'wordpress': + if ( 'time' === $field_type ) { + $format = get_option( 'time_format' ); + } elseif ( 'date' === $field_type ) { + $format = get_option( 'date_format' ); + } else { + $format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); + } + break; + } + + $value = date_i18n( $format, strtotime( $value ) ); + break; + default: + return null; + break; + } + + return $value; + } + /** * Map the matching avatar field value. * diff --git a/tests/codeception/wpunit/Pods/MappingTest.php b/tests/codeception/wpunit/Pods/MappingTest.php index e2ba04a505..49e78d8f61 100644 --- a/tests/codeception/wpunit/Pods/MappingTest.php +++ b/tests/codeception/wpunit/Pods/MappingTest.php @@ -557,4 +557,160 @@ public function test_image_fields_image_attachment() { $this->assertContains( '-123x123.jpg', pods_data_field( null, 'image_attachment_src.' . $attachment_id . '.123x123' ) ); } + /** + * @covers \Pods\Data\Map_Field_Values::date_fields + */ + public function test_date_fields() { + + /** + * Setup. + */ + + $api = pods_api(); + + $datetime_field = 'test_datetime'; + + $field_params = [ + 'pod_id' => $this->pod_id, + 'name' => $datetime_field, + 'label' => 'Test Date Time', + 'type' => 'datetime', + ]; + + $api->save_field( $field_params ); + + $date_field = 'test_date'; + + $field_params = [ + 'pod_id' => $this->pod_id, + 'name' => $date_field, + 'label' => 'Test Date', + 'type' => 'date', + ]; + + $api->save_field( $field_params ); + + $time_field = 'test_time'; + + $field_params = [ + 'pod_id' => $this->pod_id, + 'name' => $time_field, + 'label' => 'Test Time', + 'type' => 'time', + ]; + + $api->save_field( $field_params ); + + $pod = pods( $this->pod_name, $this->item_id ); + + /** + * POST DATE FIELD + */ + + $timestamp = get_post_timestamp( $this->item_id ); + $field = 'post_date'; + $alias = 'date'; + + $format = 'y-m-d!!H:s'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $field . '._format.' . $format ), 'Value of ' . $field . '._format.' . $format . ' is not what was expected' ); + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $alias . '._format.' . $format ), 'Value of ' . $alias . '._format.' . $format . ' is not what was expected' ); + + $format = 'Y.m.d!!H|s'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $field . '._format.' . $format ), 'Value of ' . $field . '._format.' . $format . ' is not what was expected' ); + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $alias . '._format.' . $format ), 'Value of ' . $alias . '._format.' . $format . ' is not what was expected' ); + + $format = 'wp'; + $wp_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $field . '._format.' . $format ), 'Value of ' . $field . '._format.' . $format . ' is not what was expected' ); + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $alias . '._format.' . $format ), 'Value of ' . $alias . '._format.' . $format . ' is not what was expected' ); + + $format = 'wp_date'; + $wp_format = get_option( 'date_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $field . '._format.' . $format ), 'Value of ' . $field . '._format.' . $format . ' is not what was expected' ); + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $alias . '._format.' . $format ), 'Value of ' . $alias . '._format.' . $format . ' is not what was expected' ); + + $format = 'wp_time'; + $wp_format = get_option( 'time_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $field . '._format.' . $format ), 'Value of ' . $field . '._format.' . $format . ' is not what was expected' ); + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $alias . '._format.' . $format ), 'Value of ' . $alias . '._format.' . $format . ' is not what was expected' ); + + /** + * Custom field tests. + */ + + $timestamp = time(); + + $pod->save( array( $datetime_field => date_i18n( \PodsField_DateTime::$storage_format, $timestamp ) ) ); + + $pod->save( array( $date_field => date_i18n( \PodsField_Date::$storage_format, $timestamp ) ) ); + + $pod->save( array( $time_field => date_i18n( \PodsField_Time::$storage_format, $timestamp ) ) ); + + /** + * DATETIME FIELD + */ + + $format = 'y-m-d!!H:s'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $datetime_field . '._format.' . $format ) ); + + $format = 'Y.m.d!!H|s'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $datetime_field . '._format.' . $format ) ); + + $format = 'wp'; + $wp_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $datetime_field . '._format.' . $format ) ); + + $format = 'wp_date'; + $wp_format = get_option( 'date_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $datetime_field . '._format.' . $format ) ); + + $format = 'wp_time'; + $wp_format = get_option( 'time_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $datetime_field . '._format.' . $format ) ); + + /** + * DATE FIELD + */ + + $format = 'y-m-d'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $date_field . '._format.' . $format ) ); + + $format = 'Y.m.d'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $date_field . '._format.' . $format ) ); + + $format = 'wp'; + $wp_format = get_option( 'date_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $date_field . '._format.' . $format ) ); + + /** + * TIME FIELD + */ + + $format = 'H:i:s'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $time_field . '._format.' . $format ) ); + + $format = 'H|i'; + + $this->assertEquals( date_i18n( $format, $timestamp ), $pod->field( $time_field . '._format.' . $format ) ); + + $format = 'wp'; + $wp_format = get_option( 'time_format' ); + + $this->assertEquals( date_i18n( $wp_format, $timestamp ), $pod->field( $time_field . '._format.' . $format ) ); + } + }