|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Wordlift\Dataset; |
|
4
|
|
|
|
|
5
|
|
|
use Wordlift\Api\Api_Service; |
|
6
|
|
|
use Wordlift\Jsonld\Jsonld_Service; |
|
7
|
|
|
|
|
8
|
|
|
class Sync_Service { |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* @var \Wordlift_Log_Service |
|
12
|
|
|
*/ |
|
13
|
|
|
private $log; |
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* @var Api_Service |
|
17
|
|
|
*/ |
|
18
|
|
|
private $api_service; |
|
19
|
|
|
|
|
20
|
|
|
/** |
|
21
|
|
|
* @var Jsonld_Service |
|
22
|
|
|
*/ |
|
23
|
|
|
private $jsonld_service; |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* @var Sync_Background_Process |
|
27
|
|
|
*/ |
|
28
|
|
|
private $sync_background_process; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Constructor. |
|
32
|
|
|
* |
|
33
|
|
|
* @param $api_service Api_Service The {@link Api_Service} used to communicate with the remote APIs. |
|
34
|
|
|
* @param $jsonld_service Jsonld_Service The {@link Jsonld_Service} used to generate the JSON-LD to post to the remote API. |
|
35
|
|
|
*/ |
|
36
|
|
|
public function __construct( $api_service, $jsonld_service ) { |
|
37
|
|
|
|
|
38
|
|
|
$this->log = \Wordlift_Log_Service::get_logger( get_class() ); |
|
39
|
|
|
|
|
40
|
|
|
$this->api_service = $api_service; |
|
41
|
|
|
$this->jsonld_service = $jsonld_service; |
|
42
|
|
|
|
|
43
|
|
|
// You need to initialize this early, otherwise the Background Process isn't registered in AJAX calls. |
|
44
|
|
|
$this->sync_background_process = new Sync_Background_Process( $this );; |
|
45
|
|
|
|
|
46
|
|
|
} |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* Starts a new synchronization. |
|
50
|
|
|
*/ |
|
51
|
|
|
public function start() { |
|
52
|
|
|
|
|
53
|
|
|
// Create the Sync_Background_Process. |
|
54
|
|
|
$this->sync_background_process->start(); |
|
55
|
|
|
|
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* Request to cancel a background process. |
|
60
|
|
|
*/ |
|
61
|
|
|
public function request_cancel() { |
|
62
|
|
|
|
|
63
|
|
|
$this->sync_background_process->request_cancel(); |
|
64
|
|
|
|
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
/** |
|
68
|
|
|
* Get the next post ID to synchronize or NULL if there are no posts to synchronize. |
|
69
|
|
|
* |
|
70
|
|
|
* @return string|null The post ID or NULL if there are no posts to synchronize. |
|
71
|
|
|
*/ |
|
72
|
|
View Code Duplication |
public function next() { |
|
|
|
|
|
|
73
|
|
|
global $wpdb; |
|
74
|
|
|
|
|
75
|
|
|
// Limit the query to the allowed post types. |
|
76
|
|
|
$post_type_in = implode( "','", array_map( 'esc_sql', \Wordlift_Entity_Service::valid_entity_post_types() ) ); |
|
77
|
|
|
|
|
78
|
|
|
// Get the next post ID. |
|
79
|
|
|
return $wpdb->get_var( " |
|
80
|
|
|
SELECT p.ID |
|
81
|
|
|
FROM $wpdb->posts p |
|
82
|
|
|
LEFT JOIN $wpdb->postmeta pm |
|
83
|
|
|
ON pm.post_id = p.ID |
|
84
|
|
|
AND pm.meta_key = '_wl_synced_gmt' |
|
85
|
|
|
WHERE p.post_status = 'publish' |
|
86
|
|
|
AND p.post_type IN ( '$post_type_in' ) |
|
87
|
|
|
AND ( pm.meta_value IS NULL OR pm.meta_value < p.post_modified_gmt ) |
|
88
|
|
|
ORDER BY p.post_modified_gmt DESC |
|
89
|
|
|
LIMIT 1 |
|
90
|
|
|
" ); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
View Code Duplication |
public function count() { |
|
|
|
|
|
|
94
|
|
|
global $wpdb; |
|
95
|
|
|
$post_type_in = implode( "','", array_map( 'esc_sql', \Wordlift_Entity_Service::valid_entity_post_types() ) ); |
|
96
|
|
|
|
|
97
|
|
|
return $wpdb->get_var( " |
|
98
|
|
|
SELECT COUNT( 1 ) |
|
99
|
|
|
FROM $wpdb->posts p |
|
100
|
|
|
LEFT JOIN $wpdb->postmeta pm |
|
101
|
|
|
ON pm.post_id = p.ID |
|
102
|
|
|
AND pm.meta_key = '_wl_synced_gmt' |
|
103
|
|
|
WHERE p.post_status = 'publish' |
|
104
|
|
|
AND p.post_type IN ( '$post_type_in' ) |
|
105
|
|
|
AND ( pm.meta_value IS NULL OR pm.meta_value < p.post_modified_gmt ) |
|
106
|
|
|
" ); |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
public function info() { |
|
110
|
|
|
return Sync_Background_Process::get_state(); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
public function sync_item( $post_id ) { |
|
114
|
|
|
|
|
115
|
|
|
// Get the JSON-LD for the specified post and its entity URI. |
|
116
|
|
|
$jsonld_value = $this->jsonld_service->get( Jsonld_Service::TYPE_POST, $post_id ); |
|
117
|
|
|
$uri = get_post_meta( $post_id, 'entity_url', true ); |
|
118
|
|
|
$jsonld = wp_json_encode( $jsonld_value ); |
|
119
|
|
|
|
|
120
|
|
|
// Make a request to the remote endpoint. |
|
121
|
|
|
$response = $this->api_service->request( |
|
122
|
|
|
'POST', '/middleware/dataset?uri=' . rawurlencode( $uri ), |
|
123
|
|
|
array( 'Content-Type' => 'application/ld+json' ), |
|
124
|
|
|
$jsonld ); |
|
125
|
|
|
|
|
126
|
|
|
// Update the sync date in case of success, otherwise log an error. |
|
127
|
|
|
if ( $response->is_success() ) { |
|
128
|
|
|
update_post_meta( $post_id, '_wl_synced_gmt', current_time( 'mysql', 1 ) ); |
|
129
|
|
|
|
|
130
|
|
|
return true; |
|
131
|
|
|
} else { |
|
132
|
|
|
// @@todo: should we put a limit retry here? |
|
133
|
|
|
$response_dump = var_export( $response, true ); |
|
134
|
|
|
$this->log->error( |
|
135
|
|
|
sprintf( 'An error occurred while synchronizing the data for post ID %d: %s', $post_id, $response_dump ) ); |
|
136
|
|
|
|
|
137
|
|
|
return false; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
} |
|
143
|
|
|
|
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.