|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
// THEMES |
|
5
|
|
|
|
|
6
|
|
|
/** |
|
7
|
|
|
* Base class for working with themes, has useful helper functions. |
|
8
|
|
|
*/ |
|
9
|
|
|
abstract class Jetpack_JSON_API_Themes_Endpoint extends Jetpack_JSON_API_Endpoint { |
|
10
|
|
|
|
|
11
|
|
|
protected $themes = array(); |
|
12
|
|
|
|
|
13
|
|
|
protected $bulk = true; |
|
14
|
|
|
protected $log; |
|
15
|
|
|
protected $current_theme_id; |
|
16
|
|
|
|
|
17
|
|
|
static $_response_format = array( |
|
|
|
|
|
|
18
|
|
|
'id' => '(string) The theme\'s ID.', |
|
19
|
|
|
'screenshot' => '(string) A theme screenshot URL', |
|
20
|
|
|
'name' => '(string) The name of the theme.', |
|
21
|
|
|
'theme_uri' => '(string) The URI of the theme\'s webpage.', |
|
22
|
|
|
'description' => '(string) A description of the theme.', |
|
23
|
|
|
'author' => '(string) The author of the theme.', |
|
24
|
|
|
'author_uri' => '(string) The website of the theme author.', |
|
25
|
|
|
'tags' => '(array) Tags indicating styles and features of the theme.', |
|
26
|
|
|
'log' => '(array) An array of log strings', |
|
27
|
|
|
'autoupdate' => '(bool) Whether the theme is automatically updated', |
|
28
|
|
|
'autoupdate_translation' => '(bool) Whether the theme is automatically updating translations', |
|
29
|
|
|
); |
|
30
|
|
|
|
|
31
|
|
|
protected function result() { |
|
32
|
|
|
|
|
33
|
|
|
$themes = $this->get_themes(); |
|
34
|
|
|
|
|
35
|
|
|
if ( ! $this->bulk && ! empty( $themes ) ) { |
|
36
|
|
|
return array_pop( $themes ); |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
return array( 'themes' => $themes ); |
|
40
|
|
|
|
|
41
|
|
|
} |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* Walks through either the submitted theme or list of themes and creates the global array |
|
45
|
|
|
* @param $theme |
|
46
|
|
|
* |
|
47
|
|
|
* @return bool |
|
48
|
|
|
*/ |
|
49
|
|
View Code Duplication |
protected function validate_input( $theme ) { |
|
50
|
|
|
$args = $this->input(); |
|
51
|
|
|
// lets set what themes were requested, and validate them |
|
52
|
|
|
if ( ! isset( $theme ) || empty( $theme ) ) { |
|
53
|
|
|
|
|
54
|
|
|
if ( ! $args['themes'] || empty( $args['themes'] ) ) { |
|
55
|
|
|
return new WP_Error( 'missing_theme', __( 'You are required to specify a theme to update.', 'jetpack' ), 400 ); |
|
56
|
|
|
} |
|
57
|
|
|
if ( is_array( $args['themes'] ) ) { |
|
58
|
|
|
$this->themes = $args['themes']; |
|
59
|
|
|
} else { |
|
60
|
|
|
$this->themes[] = $args['themes']; |
|
61
|
|
|
} |
|
62
|
|
|
} else { |
|
63
|
|
|
$this->themes[] = urldecode( $theme ); |
|
64
|
|
|
$this->bulk = false; |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
if ( is_wp_error( $error = $this->validate_themes() ) ) { |
|
68
|
|
|
return $error; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
return parent::validate_input( $theme ); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* Walks through submitted themes to make sure they are valid |
|
76
|
|
|
* @return bool|WP_Error |
|
77
|
|
|
*/ |
|
78
|
|
|
protected function validate_themes() { |
|
79
|
|
|
foreach ( $this->themes as $theme ) { |
|
80
|
|
|
if ( is_wp_error( $error = wp_get_theme( $theme )->errors() ) ) { |
|
81
|
|
|
return new WP_Error( 'unknown_theme', $error->get_error_messages() , 404 ); |
|
82
|
|
|
} |
|
83
|
|
|
} |
|
84
|
|
|
return true; |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* Format a theme for the public API |
|
89
|
|
|
* @param object $theme WP_Theme object |
|
90
|
|
|
* @return array Named array of theme info used by the API |
|
91
|
|
|
*/ |
|
92
|
|
|
protected function format_theme( $theme ) { |
|
93
|
|
|
|
|
94
|
|
|
if ( ! ( $theme instanceof WP_Theme ) ) { |
|
|
|
|
|
|
95
|
|
|
$theme = wp_get_theme( $theme ); |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
$fields = array( |
|
99
|
|
|
'name' => 'Name', |
|
100
|
|
|
'theme_uri' => 'ThemeURI', |
|
101
|
|
|
'description' => 'Description', |
|
102
|
|
|
'author' => 'Author', |
|
103
|
|
|
'author_uri' => 'AuthorURI', |
|
104
|
|
|
'tags' => 'Tags', |
|
105
|
|
|
'version' => 'Version' |
|
106
|
|
|
); |
|
107
|
|
|
|
|
108
|
|
|
$id = $theme->get_stylesheet(); |
|
109
|
|
|
$formatted_theme = array( |
|
110
|
|
|
'id' => $id, |
|
111
|
|
|
'screenshot' => jetpack_photon_url( $theme->get_screenshot(), array(), 'network_path' ), |
|
112
|
|
|
'active' => $id === $this->current_theme_id, |
|
113
|
|
|
); |
|
114
|
|
|
|
|
115
|
|
|
foreach( $fields as $key => $field ) { |
|
116
|
|
|
$formatted_theme[ $key ] = $theme->get( $field ); |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
$update_themes = get_site_transient( 'update_themes' ); |
|
120
|
|
|
$formatted_theme['update'] = ( isset( $update_themes->response[ $id ] ) ) ? $update_themes->response[ $id ] : null; |
|
121
|
|
|
|
|
122
|
|
|
$autoupdate = in_array( $id, Jetpack_Options::get_option( 'autoupdate_themes', array() ) ); |
|
123
|
|
|
$formatted_theme['autoupdate'] = $autoupdate; |
|
124
|
|
|
|
|
125
|
|
|
$autoupdate_translation = in_array( $id, Jetpack_Options::get_option( 'autoupdate_themes_translations', array() ) ); |
|
126
|
|
|
$formatted_theme['autoupdate_translation'] = $autoupdate || $autoupdate_translation || Jetpack_Options::get_option( 'autoupdate_translations', false ); |
|
127
|
|
|
|
|
128
|
|
|
if ( isset( $this->log[ $id ] ) ) { |
|
129
|
|
|
$formatted_theme['log'] = $this->log[ $id ]; |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
return $formatted_theme; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
/** |
|
136
|
|
|
* Checks the query_args our collection endpoint was passed to ensure that it's in the proper bounds. |
|
137
|
|
|
* @return bool|WP_Error a WP_Error object if the args are out of bounds, true if things are good. |
|
138
|
|
|
*/ |
|
139
|
|
|
protected function check_query_args() { |
|
140
|
|
|
$args = $this->query_args(); |
|
141
|
|
|
if ( $args['offset'] < 0 ) |
|
142
|
|
|
return new WP_Error( 'invalid_offset', __( 'Offset must be greater than or equal to 0.', 'jetpack' ), 400 ); |
|
143
|
|
|
if ( $args['limit'] < 0 ) |
|
144
|
|
|
return new WP_Error( 'invalid_limit', __( 'Limit must be greater than or equal to 0.', 'jetpack' ), 400 ); |
|
145
|
|
|
return true; |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* Format a list of themes for public display, using the supplied offset and limit args |
|
150
|
|
|
* @uses WPCOM_JSON_API_Endpoint::query_args() |
|
151
|
|
|
* @return array Public API theme objects |
|
152
|
|
|
*/ |
|
153
|
|
View Code Duplication |
protected function get_themes() { |
|
154
|
|
|
// ditch keys |
|
155
|
|
|
$themes = array_values( $this->themes ); |
|
156
|
|
|
// do offset & limit - we've already returned a 400 error if they're bad numbers |
|
157
|
|
|
$args = $this->query_args(); |
|
158
|
|
|
|
|
159
|
|
|
if ( isset( $args['offset'] ) ) |
|
160
|
|
|
$themes = array_slice( $themes, (int) $args['offset'] ); |
|
161
|
|
|
if ( isset( $args['limit'] ) ) |
|
162
|
|
|
$themes = array_slice( $themes, 0, (int) $args['limit'] ); |
|
163
|
|
|
|
|
164
|
|
|
$this->current_theme_id = wp_get_theme()->get_stylesheet(); |
|
165
|
|
|
|
|
166
|
|
|
return array_map( array( $this, 'format_theme' ), $themes ); |
|
167
|
|
|
} |
|
168
|
|
|
|
|
169
|
|
|
} |
|
170
|
|
|
|
The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using
the property is implicitly global.
To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.