Completed
Pull Request — develop (#1161)
by Naveen
05:58 queued 02:12
created

Jsonld_Converter   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 234
Duplicated Lines 8.12 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 19
loc 234
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 4

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A wl_term_jsonld_array() 9 9 1
A wl_post_jsonld_array() 10 10 1
A build_jsonld() 0 23 4
A get_property_data() 0 14 3
B process_nested_properties() 0 35 6
A make_single() 0 14 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Define the Wordlift_Mapping_Jsonld_Converter class to add JSON-LD generated from mappings.
4
 *
5
 * @since   3.25.0
6
 * @package Wordlift
7
 * @subpackage Wordlift\Mappings
8
 */
9
10
namespace Wordlift\Mappings;
11
12
use Wordlift\Mappings\Data_Source\Data_Source_Factory;
13
14
/**
15
 * This class takes the output from json-ld service and alter depends on the
16
 * rule and properties defined in sync mappings.
17
 *
18
 * @since 3.25.0
19
 */
20
class Jsonld_Converter {
21
	/**
22
	 * Enumerations for the field types.
23
	 */
24
	const FIELD_TYPE_TEXT_FIELD = 'text';
25
	const FIELD_TYPE_CUSTOM_FIELD = 'custom_field';
26
	const FIELD_TYPE_ACF = 'acf';
27
28
	/**
29
	 * Mappings can be applied to either post
30
	 * or term, the below is used to specify whether it is a post or a term.
31
	 */
32
	const POST = 'post';
33
	const TERM = 'term';
34
	/**
35
	 * The {@link Mappings_Validator} instance to test.
36
	 *
37
	 * @since  3.25.0
38
	 * @access private
39
	 * @var Mappings_Validator $validator The {@link Mappings_Validator} instance.
40
	 */
41
	private $validator;
42
43
	/**
44
	 * The {@link Mappings_Transform_Functions_Registry} instance.
45
	 *
46
	 * @since  3.25.0
47
	 * @access private
48
	 * @var Mappings_Transform_Functions_Registry $transform_functions_registry The {@link Mappings_Transform_Functions_Registry} instance.
49
	 */
50
	private $transform_functions_registry;
51
52
	/**
53
	 * Initialize all dependencies required.
54
	 *
55
	 * @param Mappings_Validator $validator A {@link Mappings_Validator} instance.
56
	 * @param Mappings_Transform_Functions_Registry $transform_functions_registry
57
	 */
58
	public function __construct( $validator, $transform_functions_registry ) {
59
60
		$this->validator                    = $validator;
61
		$this->transform_functions_registry = $transform_functions_registry;
62
63
		// Hook to refactor the JSON-LD.
64
		add_filter( 'wl_post_jsonld_array', array( $this, 'wl_post_jsonld_array' ), 11, 2 );
65
		add_filter( 'wl_entity_jsonld_array', array( $this, 'wl_post_jsonld_array' ), 11, 2 );
66
67
		// Hook at add term jsonld.
68
		add_filter( 'wl_term_jsonld_array', array( $this, 'wl_term_jsonld_array' ), 11, 2 );
69
	}
70
71
	/**
72
	 * Hook to `wl_term_jsonld_array`.
73
	 *
74
	 * Receive the JSON-LD and the references in the array along with the term ID and transform them according to
75
	 * the configuration.
76
	 *
77
	 * @param array $value {
78
	 *      The array containing the JSON-LD and the references.
79
	 *
80
	 * @type array $jsonld The JSON-LD array.
81
	 * @type int[] $references An array of post ID referenced by the JSON-LD (will be expanded by the converter).
82
	 * }
83
	 *
84
	 * @param int $term_id The Term ID.
85
	 *
86
	 * @return array An array with the updated JSON-LD and references.
87
	 */
88 View Code Duplication
	public function wl_term_jsonld_array( $value, $term_id ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
		$jsonld     = $value['jsonld'];
90
		$references = $value['references'];
91
92
		return array(
93
			'jsonld'     => $this->build_jsonld( $jsonld, $term_id, $references, self::TERM ),
94
			'references' => $references,
95
		);
96
	}
97
98
99
	/**
100
	 * Hook to `wl_post_jsonld_array` and `wl_entity_jsonld_array`.
101
	 *
102
	 * Receive the JSON-LD and the references in the array along with the post ID and transform them according to
103
	 * the configuration.
104
	 *
105
	 * @param array $value {
106
	 *      The array containing the JSON-LD and the references.
107
	 *
108
	 * @type array $jsonld The JSON-LD array.
109
	 * @type int[] $references An array of post ID referenced by the JSON-LD (will be expanded by the converter).
110
	 * }
111
	 *
112
	 * @param int $post_id The post ID.
113
	 *
114
	 * @return array An array with the updated JSON-LD and references.
115
	 */
116 View Code Duplication
	public function wl_post_jsonld_array( $value, $post_id ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
118
		$jsonld     = $value['jsonld'];
119
		$references = $value['references'];
120
121
		return array(
122
			'jsonld'     => $this->build_jsonld( $jsonld, $post_id, $references, self::POST ),
123
			'references' => $references,
124
		);
125
	}
126
127
	/**
128
	 * Returns JSON-LD data after applying transformation functions.
129
	 *
130
	 * @param array $jsonld The JSON-LD structure.
131
	 * @param int $identifier The {@link WP_Post} id or {@link \WP_Term} id.
132
	 * @param array $references An array of post references.
133
	 *
134
	 * @param string $type Post or term.
135
	 *
136
	 * @return array the new refactored array structure.
137
	 * @since 3.25.0
138
	 */
139
	private function build_jsonld( $jsonld, $identifier, &$references, $type ) {
140
		// @@todo I think there's an issue here with the Validator, because you're changing the instance state and the
141
		// instance may be reused afterwards.
142
143
		$properties        = $this->validator->validate( $identifier, $type );
144
		$nested_properties = array();
145
146
		foreach ( $properties as $property ) {
147
			// If the property has the character '/' in the property name then it is a nested property.
148
			if ( strpos( $property['property_name'], '/' ) !== false ) {
149
				$nested_properties[] = $property;
150
				continue;
151
			}
152
			$property_transformed_data = $this->get_property_data( $property, $jsonld, $identifier, $references, $type );
153
			if ( false !== $property_transformed_data ) {
154
				$jsonld[ $property['property_name'] ] = $property_transformed_data;
155
			}
156
		}
157
158
		$jsonld = $this->process_nested_properties( $nested_properties, $jsonld, $identifier, $references, $type );
159
160
		return $jsonld;
161
	}
162
163
	/**
164
	 * Get the property data by applying the transformation function
165
	 *
166
	 * @param $property
167
	 * @param $jsonld
168
	 * @param $identifier
169
	 * @param $references
170
	 *
171
	 * @param $type
172
	 *
173
	 * @return array|bool|null
174
	 */
175
	public function get_property_data( $property, $jsonld, $identifier, &$references, $type ) {
176
		$transform_instance = $this->transform_functions_registry->get_transform_function( $property['transform_function'] );
177
		$data               = Data_Source_Factory::get_instance()->get_data( $identifier, $property, $type );
178
		if ( null !== $transform_instance ) {
179
			$transform_data = $transform_instance->transform_data( $data, $jsonld, $references, $identifier );
180
			if ( null !== $transform_data ) {
181
				return $this->make_single( $transform_data );
182
			}
183
		} else {
184
			return $this->make_single( $data );
185
		}
186
187
		return false;
188
	}
189
190
	/**
191
	 * Process all the nested properties.
192
	 *
193
	 * @param $nested_properties array
194
	 * @param $jsonld array
195
	 *
196
	 * @param $identifier
197
	 * @param $references
198
	 * @param string $type Post or term.
199
	 *
200
	 * @return array
201
	 */
202
	public function process_nested_properties( $nested_properties, $jsonld, $identifier, &$references, $type ) {
203
		foreach ( $nested_properties as $property ) {
204
			$property_data = $this->get_property_data( $property, $jsonld, $identifier, $references, $type );
205
			if ( false === $property_data ) {
206
				// No need to create nested levels.
207
				continue;
208
			}
209
210
			$keys = explode( '/', $property['property_name'] );
211
			// end is the last level of the nested property.
212
			$end                      = array_pop( $keys );
213
			$current_property_pointer = &$jsonld;
214
215
			/**
216
			 * Once we find all the nested levels from the property name
217
			 * loop through it and create associative array if the levels
218
			 * didnt exist.
219
			 */
220
			while ( count( $keys ) > 0 ) {
221
				$key = array_shift( $keys );
222
				if ( $key === "" ) {
223
					continue;
224
				}
225
				if ( ! array_key_exists( $key, $current_property_pointer ) ) {
226
					$current_property_pointer[ $key ] = array();
227
				}
228
				// We are setting the pointer to the current key, so that at the end
229
				// we can add the data at last level.
230
				$current_property_pointer = &$current_property_pointer[ $key ];
231
			}
232
			$current_property_pointer[ $end ] = $property_data;
233
		}
234
235
		return $jsonld;
236
	}
237
238
	private function make_single( $value ) {
239
240
		$values = (array) $value;
241
242
		if ( empty( $values ) ) {
243
			return false;
244
		}
245
246
		if ( 1 === count( $values ) && 0 === key( $values ) ) {
247
			return current( $values );
248
		}
249
250
		return $values;
251
	}
252
253
}
254