class-wpml-rest-posts-hooks.php
5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
<?php
use \WPML\FP\Fns;
class WPML_REST_Posts_Hooks implements IWPML_Action {
/** @var SitePress $sitepress */
private $sitepress;
/** @var WPML_Term_Translation $term_translations */
private $term_translations;
public function __construct(
SitePress $sitepress,
WPML_Term_Translation $term_translations
) {
$this->sitepress = $sitepress;
$this->term_translations = $term_translations;
}
public function add_hooks() {
$post_types = $this->sitepress->get_translatable_documents();
foreach ( $post_types as $post_type => $post_object ) {
add_filter( "rest_prepare_$post_type", array( $this, 'prepare_post' ), 10, 2 );
}
add_filter( 'rest_request_before_callbacks', array( $this, 'reload_wpml_post_translation' ), 10, 3 );
}
/**
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
*
* @return WP_REST_Response
*/
public function prepare_post( $response, $post ) {
if ( $this->sitepress->get_setting( 'sync_post_taxonomies' ) ) {
$response = $this->preset_terms_in_new_translation( $response, $post );
}
$response = $this->adjust_sample_links( $response, $post );
return $response;
}
/**
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
*
* @return WP_REST_Response
*/
private function preset_terms_in_new_translation( $response, $post ) {
if ( ! isset( $_GET['trid'] ) ) {
return $response;
}
$trid = filter_var( $_GET['trid'], FILTER_SANITIZE_NUMBER_INT );
$source_lang = isset( $_GET['source_lang'] )
? filter_var( $_GET['source_lang'], FILTER_SANITIZE_FULL_SPECIAL_CHARS )
: $this->sitepress->get_default_language();
$element_type = 'post_' . $post->post_type;
if ( $this->sitepress->get_element_trid( $post->ID, $element_type ) ) {
return $response;
}
$translations = $this->sitepress->get_element_translations( $trid, $element_type );
if ( ! isset( $translations[ $source_lang ] ) ) {
return $response;
}
$current_lang = $this->sitepress->get_current_language();
$translatable_taxs = $this->sitepress->get_translatable_taxonomies( true, $post->post_type );
$all_taxs = wp_list_filter( get_object_taxonomies( $post->post_type, 'objects' ), array( 'show_in_rest' => true ) );
$data = $response->get_data();
$this->sitepress->switch_lang( $source_lang );
foreach ( $all_taxs as $tax ) {
$tax_rest_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name;
if ( ! isset( $data[ $tax_rest_base ] ) ) {
continue;
}
$terms = get_the_terms( $translations[ $source_lang ]->element_id, $tax->name );
if ( ! is_array( $terms ) ) {
continue;
}
$term_ids = $this->get_translated_term_ids( $terms, $tax, $translatable_taxs, $current_lang );
wp_set_object_terms( $post->ID, $term_ids, $tax->name );
$data[ $tax_rest_base ] = $term_ids;
}
$this->sitepress->switch_lang( null );
$response->set_data( $data );
return $response;
}
/**
* @param array $terms
* @param stdClass $tax
* @param array $translatable_taxs
* @param string $current_lang
*
* @return array
*/
private function get_translated_term_ids( array $terms, $tax, array $translatable_taxs, $current_lang ) {
$term_ids = array();
foreach ( $terms as $term ) {
if ( in_array( $tax->name, $translatable_taxs ) ) {
$term_ids[] = $this->term_translations->term_id_in( $term->term_id, $current_lang, false );
} else {
$term_ids[] = $term->term_id;
}
}
return wpml_collect( $term_ids )
->filter()
->values()
->map( Fns::unary( 'intval' ) )
->toArray();
}
/**
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
*
* @return WP_REST_Response
*/
private function adjust_sample_links( $response, $post ) {
$data = $response->get_data();
if ( ! isset( $data['link'], $data['permalink_template'] ) ) {
return $response;
}
$lang_details = $this->sitepress->get_element_language_details( $post->ID, 'post_' . $post->post_type );
if ( empty( $lang_details->language_code ) ) {
$lang = $this->sitepress->get_current_language();
$data['link'] = $this->sitepress->convert_url( $data['link'], $lang );
$data['permalink_template'] = $this->sitepress->convert_url( $data['permalink_template'], $lang );
$response->set_data( $data );
}
return $response;
}
/**
* @param WP_HTTP_Response|WP_Error $response Result to send to the client. Usually a WP_REST_Response or WP_Error.
* @param array $handler Route handler used for the request.
* @param WP_REST_Request $request Request used to generate the response.
*
* @return WP_HTTP_Response|WP_Error
*/
public function reload_wpml_post_translation( $response, array $handler, WP_REST_Request $request ) {
if ( ! is_wp_error( $response ) && $this->is_saving_reusable_block( $request ) ) {
wpml_load_post_translation( is_admin(), $this->sitepress->get_settings() );
}
return $response;
}
private function is_saving_reusable_block( WP_REST_Request $request ) {
return in_array( $request->get_method(), array( 'POST', 'PUT', 'PATCH' ) )
&& preg_match( '#\/wp\/v2\/blocks(?:\/\d+)*#', $request->get_route() );
}
}