summaryrefslogtreecommitdiff
blob: 2e32dccd0bbd821963c72235a4b02ba1916371bb (plain)
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
178
<?php


// THEMES

/**
 * Base class for working with themes, has useful helper functions.
 */
abstract class Jetpack_JSON_API_Themes_Endpoint extends Jetpack_JSON_API_Endpoint {

	protected $themes = array();

	protected $bulk = true;
	protected $log;
	protected $current_theme_id;

	static $_response_format = array(
		'id'           => '(string) The theme\'s ID.',
		'screenshot'   => '(string) A theme screenshot URL',
		'name'         => '(string) The name of the theme.',
		'theme_uri'    => '(string) The URI of the theme\'s webpage.',
		'description'  => '(string) A description of the theme.',
		'author'       => '(string) The author of the theme.',
		'author_uri'   => '(string) The website of the theme author.',
		'tags'         => '(array) Tags indicating styles and features of the theme.',
		'log'          => '(array) An array of log strings',
		'autoupdate'   => '(bool) Whether the theme is automatically updated',
		'autoupdate_translation' => '(bool) Whether the theme is automatically updating translations',
	);

	protected function result() {

		$themes = $this->get_themes();

		if ( ! $this->bulk && ! empty( $themes ) ) {
			return array_pop( $themes );
		}

		return array( 'themes' => $themes );

	}

	/**
	 * Walks through either the submitted theme or list of themes and creates the global array
	 * @param $theme
	 *
	 * @return bool
	 */
	protected function validate_input( $theme ) {
		$args = $this->input();
		// lets set what themes were requested, and validate them
		if ( ! isset( $theme ) || empty( $theme ) ) {

			if ( ! $args['themes'] || empty( $args['themes'] ) ) {
				return new WP_Error( 'missing_theme', __( 'You are required to specify a theme to update.', 'jetpack' ), 400 );
			}
			if ( is_array( $args['themes'] ) ) {
				$this->themes = $args['themes'];
			} else {
				$this->themes[] = $args['themes'];
			}
		} else {
			$this->themes[] = urldecode( $theme );
			$this->bulk = false;
		}

		if ( is_wp_error( $error = $this->validate_themes() ) ) {
			return $error;
		}

		return parent::validate_input( $theme );
	}

	/**
	 * Walks through submitted themes to make sure they are valid
	 * @return bool|WP_Error
	 */
	protected function validate_themes() {
		foreach ( $this->themes as $theme ) {
			if ( is_wp_error( $error = wp_get_theme( $theme )->errors() ) ) {
				return new WP_Error( 'unknown_theme', $error->get_error_messages() , 404 );
			}
		}
		return true;
	}

	/**
	 * Format a theme for the public API
	 * @param  object $theme WP_Theme object
	 * @return array Named array of theme info used by the API
	 */
	protected function format_theme( $theme ) {

		if ( ! ( $theme instanceof WP_Theme ) ) {
			$theme = wp_get_theme( $theme );
		}

		$fields = array(
			'name'        => 'Name',
			'theme_uri'   => 'ThemeURI',
			'description' => 'Description',
			'author'      => 'Author',
			'author_uri'  => 'AuthorURI',
			'tags'        => 'Tags',
			'version'     => 'Version'
		);

		$id = $theme->get_stylesheet();
		$formatted_theme = array(
			'id'          => $id,
			'screenshot'  => jetpack_photon_url( $theme->get_screenshot(), array(), 'network_path' ),
			'active'      => $id === $this->current_theme_id,
		);

		foreach( $fields as $key => $field ) {
			$formatted_theme[ $key ] = $theme->get( $field );
		}

		$update_themes = get_site_transient( 'update_themes' );
		$formatted_theme['update'] = ( isset( $update_themes->response[ $id ] ) ) ? $update_themes->response[ $id ] : null;

		$autoupdate = in_array( $id, Jetpack_Options::get_option( 'autoupdate_themes', array() ) );
		$formatted_theme['autoupdate'] =  $autoupdate;

		$autoupdate_translation = in_array( $id, Jetpack_Options::get_option( 'autoupdate_themes_translations', array() ) );
		$formatted_theme['autoupdate_translation'] = $autoupdate || $autoupdate_translation || Jetpack_Options::get_option( 'autoupdate_translations', false );

		if ( isset( $this->log[ $id ] ) ) {
			$formatted_theme['log'] = $this->log[ $id ];
		}

		/**
		 * Filter the array of theme information that will be returned per theme by the Jetpack theme APIs.
		 *
		 * @module json-api
		 *
		 * @since 4.7.0
		 *
		 * @param array $formatted_theme The theme info array.
		 */
		return apply_filters( 'jetpack_format_theme_details', $formatted_theme );
	}

	/**
	 * Checks the query_args our collection endpoint was passed to ensure that it's in the proper bounds.
	 * @return bool|WP_Error a WP_Error object if the args are out of bounds, true if things are good.
	 */
	protected function check_query_args() {
		$args = $this->query_args();
		if ( $args['offset'] < 0 )
			return new WP_Error( 'invalid_offset', __( 'Offset must be greater than or equal to 0.', 'jetpack' ), 400 );
		if ( $args['limit'] < 0 )
			return new WP_Error( 'invalid_limit', __( 'Limit must be greater than or equal to 0.', 'jetpack' ), 400 );
		return true;
	}

	/**
	 * Format a list of themes for public display, using the supplied offset and limit args
	 * @uses   WPCOM_JSON_API_Endpoint::query_args()
	 * @return array         Public API theme objects
	 */
	protected function get_themes() {
		// ditch keys
		$themes = array_values( $this->themes );
		// do offset & limit - we've already returned a 400 error if they're bad numbers
		$args = $this->query_args();

		if ( isset( $args['offset'] ) )
			$themes = array_slice( $themes, (int) $args['offset'] );
		if ( isset( $args['limit'] ) )
			$themes = array_slice( $themes, 0, (int) $args['limit'] );

		$this->current_theme_id = wp_get_theme()->get_stylesheet();

		return array_map( array( $this, 'format_theme' ), $themes );
	}

}