Completed
Pull Request — develop (#1282)
by David
03:07
created

Sync_Service::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
1
<?php
2
3
namespace Wordlift\Dataset;
4
5
use Exception;
6
use Wordlift\Api\Api_Service;
7
use Wordlift\Jsonld\Jsonld_Service;
8
9
class Sync_Service {
10
	const JSONLD_HASH = '_wl_jsonld_hash';
11
	const SYNCED_GMT = '_wl_synced_gmt';
12
13
	/**
14
	 * @var \Wordlift_Log_Service
15
	 */
16
	private $log;
17
18
	/**
19
	 * @var Api_Service
20
	 */
21
	private $api_service;
22
23
	/**
24
	 * @var Jsonld_Service
25
	 */
26
	private $jsonld_service;
27
28
	/**
29
	 * @var Sync_Background_Process
30
	 */
31
	private $sync_background_process;
32
33
	/**
34
	 * The number of posts processed in one call.
35
	 *
36
	 * @var int The batch size.
37
	 */
38
	private $batch_size;
39
40
	/**
41
	 * @var Sync_Object_Adapter_Factory
42
	 */
43
	private $sync_object_adapter_factory;
44
45
	/**
46
	 * @var Sync_Service
47
	 */
48
	private static $instance;
49
	private $entity_service;
50
51
	/**
52
	 * Constructor.
53
	 *
54
	 * @param Api_Service $api_service The {@link Api_Service} used to communicate with the remote APIs.
55
	 * @param Sync_Object_Adapter_Factory $sync_object_adapter_factory
56
	 * @param Jsonld_Service $jsonld_service
57
	 * @param \Wordlift_Entity_Service $entity_service
58
	 */
59
	public function __construct( $api_service, $sync_object_adapter_factory, $jsonld_service, $entity_service ) {
60
61
		$this->log = \Wordlift_Log_Service::get_logger( get_class() );
62
63
		$this->api_service                 = $api_service;
64
		$this->sync_object_adapter_factory = $sync_object_adapter_factory;
65
		$this->jsonld_service              = $jsonld_service;
66
		$this->entity_service              = $entity_service;
67
		$this->batch_size                  = 10;
68
69
		// You need to initialize this early, otherwise the Background Process isn't registered in AJAX calls.
70
//		$this->sync_background_process = new Sync_Background_Process( $this );;
71
72
		// Exclude the JSONLD_HASH meta key from those that require a resync.
73
		add_filter( 'wl_dataset__sync_hooks__ignored_meta_keys', function ( $args ) {
74
			$args[] = Sync_Service::JSONLD_HASH;
75
			$args[] = Sync_Service::SYNCED_GMT;
76
77
			return $args;
78
		} );
79
80
		self::$instance = $this;
81
	}
82
83
	public static function get_instance() {
84
		return self::$instance;
85
	}
86
87
	/**
88
	 * @param int $type
89
	 * @param int $object_id
90
	 *
91
	 * @return array|false
92
	 * @throws Exception
93
	 */
94
	public function sync_one( $type, $object_id ) {
95
96
		$object = $this->sync_object_adapter_factory->create( $type, $object_id );
97
98
		return $this->sync_many( array( $object ) );
99
	}
100
101
	public function delete_one( $type, $object_id ) {
102
		$object = $this->sync_object_adapter_factory->create( $type, $object_id );
103
		$uri    = $object->get_meta( 'entity_url', true );
104
105
		// Entity URL isn't set, bail out.
106
		if ( empty( $uri ) ) {
107
			return false;
108
		}
109
110
		$response = $this->api_service->request(
111
			'DELETE', sprintf( '/middleware/dataset?uri=%s', rawurlencode( $uri ) ) );
112
113
		// Update the sync date in case of success, otherwise log an error.
114
		if ( ! $response->is_success() ) {
115
			return false;
116
		}
117
118
		return true;
119
	}
120
121
	/**
122
	 * @param Sync_Object_Adapter[] $objects
123
	 * @param bool $force Force synchronization even if the json-ld hash hasn't changed.
124
	 *
125
	 * @return bool
126
	 * @throws Exception
127
	 */
128
	public function sync_many( $objects, $force = false ) {
129
130
		$hashes   = array();
131
		$payloads = array();
132
		foreach ( $objects as $object ) {
133
			// Bail out if no payload.
134
			$payload_as_string = $this->get_payload_as_string( $object );
135
			if ( empty( $payload_as_string ) ) {
136
				continue;
137
			}
138
139
			$new_hash = sha1( $payload_as_string );
140
			$old_hash = $object->get_meta( self::JSONLD_HASH, true );
141
			// JSON-LD hasn't changed, bail out.
142
			if ( ! $force && $new_hash === $old_hash ) {
143
				continue;
144
			}
145
146
			// Collect the hashes and the payloads.
147
			$hashes[]   = array( $object, $new_hash );
148
			$payloads[] = $payload_as_string;
149
		}
150
151
		// Bail out if payloads are empty.
152
		if ( empty( $payloads ) ) {
153
			return false;
154
		}
155
156
		$response = $this->api_service->request(
157
			'POST', '/middleware/dataset/batch',
158
			array( 'Content-Type' => 'application/json', ),
159
			// Put the payload in a JSON array w/o decoding/encoding again.
160
			'[ ' . implode( ', ', $payloads ) . ' ]' );
161
162
		// Update the sync date in case of success, otherwise log an error.
163
		if ( ! $response->is_success() ) {
164
			return false;
165
		}
166
167
		// If successful update the hashes and sync'ed datetime.
168
		foreach ( $hashes as $hash ) {
169
			$object   = $hash[0];
170
			$new_hash = $hash[1];
171
			$object->update_meta( self::JSONLD_HASH, $new_hash );
172
			$object->update_meta( self::SYNCED_GMT, current_time( 'mysql', true ) );
173
		}
174
175
		return true;
176
	}
177
178
	/**
179
	 * @param Sync_Object_Adapter $object
180
	 *
181
	 * @return false|string
182
	 * @throws Exception
183
	 */
184
	private function get_payload_as_string( $object ) {
185
		$type      = $object->get_type();
186
		$object_id = $object->get_object_id();
187
188
		$jsonld_as_string = wp_json_encode( apply_filters( 'wl_dataset__sync_service__sync_item__jsonld',
189
			$this->jsonld_service->get( $type, $object_id ), $type, $object_id ) );
190
		$uri              = $this->entity_service->get_uri( $object_id, $type );
191
192
		// Entity URL isn't set, bail out.
193
		if ( empty( $uri ) ) {
194
			return false;
195
		}
196
197
		return wp_json_encode( array(
198
			'uri'     => $uri,
199
			'model'   => $jsonld_as_string,
200
			'private' => ! $object->is_public(),
201
		) );
202
	}
203
204
	/**
205
	 * @param $post_id
206
	 *
207
	 * @todo Complete the delete item.
208
	 */
209
	public function delete_item( $post_id ) {
210
		$uri = get_post_meta( $post_id, 'entity_url', true );
211
		// Make a request to the remote endpoint.
212
		$response = $this->api_service->request(
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
213
			'DELETE', '/middleware/dataset?uri=' . rawurlencode( $uri ),
214
			array( 'Content-Type' => 'application/ld+json', ) );
215
	}
216
217
	public function get_batch_size() {
218
219
		return $this->batch_size;
220
	}
221
222
	public function delete_all() {
223
		$this->api_service->request( 'DELETE', '/middleware/dataset/all' );
224
	}
225
226
}
227