Completed
Push — develop ( 844154...ac08d5 )
by David
02:57 queued 11s
created

Mappings_Validator::validate()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 1
dl 0
loc 48
rs 8.5123
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Define the {@link Mappings_Validator} class.
5
 *
6
 * Validates the mapping for single post and return the  * schema.org properties mapped to ACF, custom field or text
7
 * to be used for JSON-LD output.
8
 *
9
 * @since      3.25.0
10
 * @package    Wordlift
11
 * @subpackage Wordlift/includes/sync-mappings
12
 */
13
14
namespace Wordlift\Mappings;
15
16
use Wordlift\Mappings\Validators\Rule_Groups_Validator;
17
18
final class Mappings_Validator {
19
	const TRASH_CATEGORY = 'trash';
20
	const ACTIVE_CATEGORY = 'active';
21
22
	/**
23
	 * The {@link Mappings_DBO} instance to test.
24
	 *
25
	 * @since  3.25.0
26
	 * @access private
27
	 * @var Mappings_DBO $dbo The {@link Mappings_DBO} instance to test.
28
	 */
29
	private $dbo;
30
31
	/**
32
	 * @var Rule_Groups_Validator
33
	 */
34
	private $rule_groups_validator;
35
36
	/**
37
	 * Constructor for Wordlift_Mapping_Validator.
38
	 *
39
	 * @param Mappings_DBO $dbo The {@link Mappings_DBO} instance.
40
	 * @param Rule_Groups_Validator $rule_groups_validator
41
	 */
42
	public function __construct( $dbo, $rule_groups_validator ) {
43
44
		$this->dbo                   = $dbo;
45
		$this->rule_groups_validator = $rule_groups_validator;
46
47
	}
48
49
	/**
50
	 * This method is used to filter properties based on presence
51
	 * of certain key values.
52
	 *
53
	 * @param $items array Array of properties.
54
	 *
55
	 * @return array
56
	 */
57
	private static function filter_properties_for_required_keys( $items ) {
58
		return array_filter(
59
			$items,
60
			function ( $item ) {
61
				/**
62
				 * Since the properties might also be passed
63
				 * by external plugins, we might need to check if
64
				 * they have correct data format.
65
				 */
66
				if ( ! array_key_exists( 'property_name', $item ) ||
67
				     ! array_key_exists( 'field_type', $item ) ||
68
				     ! array_key_exists( 'field_name', $item ) ||
69
				     ! array_key_exists( 'transform_function', $item )
70
				) {
71
					// If these keys doesnt exist, then dont process.
72
					return false;
73
				} else {
74
					// If the keys exist, then filter it.
75
					return true;
76
				}
77
			}
78
		);
79
	}
80
81
	/**
82
	 * Validates two values based on the passed logic
83
	 * a single rule passes the user defined logic.
84
	 *
85
	 * @param string $key The key which every object has mapped to our value.
86
	 * @param array $items The array of items.
87
	 * @param string $status The value which the items should have.
88
	 *
89
	 * @return array
90
	 */
91
	private static function get_property_item_by_status( $key, $items, $status ) {
92
		return array_filter(
93
			$items,
94
			function ( $item ) use ( $key, $status ) {
95
				return $item[ $key ] === (string) $status;
96
			}
97
		);
98
	}
99
100
	/**
101
	 * Validates a post id with the list of active mapping items and check if
102
	 * a mapping can be applied.
103
	 *
104
	 * @param int $post_id The post id.
105
	 *
106
	 * @return array
107
	 */
108
	public function validate( $post_id ) {
109
		// Reset the valid property items before making the validation.
110
		$properties = array();
111
112
		// Filter registered properties
113
		$filter_registered_properties = array();
114
115
		// Get active mappings.
116
		$mappings = $this->dbo->get_active_mappings();
117
		/**
118
		 * Apply this filter to get mappings from external plugins.
119
		 *
120
		 * @param $mappings array Array of mappings from database.
121
		 * @param $post_id int The post id.
122
		 */
123
		$mappings = apply_filters( 'wl_mappings_post', $mappings, $post_id );
124
125
		// Get all active rule groups for the mapping items.
126
		foreach ( $mappings as $mapping ) {
127
			if ( array_key_exists( 'mapping_id', $mapping ) ) {
128
				$rule_groups          = $this->dbo->get_rule_groups_by_mapping( (int) $mapping['mapping_id'] );
129
				$should_apply_mapping = $this->rule_groups_validator->is_valid( $post_id, $rule_groups );
130
				if ( $should_apply_mapping ) {
131
					$mapping_item_properties = $this->dbo->get_properties( $mapping['mapping_id'] );
132
					$properties              = array_merge( $properties, $mapping_item_properties );
133
				}
134
			} else {
135
				/**
136
				 * This is a programmatically defined mapping,
137
				 * so we will have the rule groups and the properties in the array keys
138
				 */
139
				if ( array_key_exists( 'properties', $mapping ) &&
140
				     is_array( $mapping['properties'] ) ) {
141
					$filter_registered_properties = array_merge( $filter_registered_properties, $mapping['properties'] );
142
				}
143
			}
144
		}
145
		// Filter all registered properties based on required key values.
146
		$filter_registered_properties = self::filter_properties_for_required_keys( $filter_registered_properties );
147
		$active_properties            = self::get_property_item_by_status(
148
			'property_status',
149
			$properties,
150
			self::ACTIVE_CATEGORY
151
		);
152
153
		// Merge ui defined properties with filter registered properties.
154
		return array_merge( $active_properties, $filter_registered_properties );
155
	}
156
157
}
158