PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.1
WooCommerce v10.9.1
10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / src / Admin / Features / Blueprint / Init.php
woocommerce / src / Admin / Features / Blueprint Last commit date
Exporters 11 months ago Init.php 11 months ago RestApi.php 1 year ago SettingOptions.php 1 year ago
Init.php
392 lines
1 <?php
2
3 declare( strict_types = 1 );
4
5 namespace Automattic\WooCommerce\Admin\Features\Blueprint;
6
7 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCPaymentGateways;
8 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsAccount;
9 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsAdvanced;
10 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsEmails;
11 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsGeneral;
12 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsTax;
13 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsIntegrations;
14 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsProducts;
15 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsSiteVisibility;
16 use Automattic\WooCommerce\Admin\Features\Blueprint\Exporters\ExportWCSettingsShipping;
17 use Automattic\WooCommerce\Admin\PageController;
18 use Automattic\WooCommerce\Blueprint\Exporters\HasAlias;
19 use Automattic\WooCommerce\Blueprint\Exporters\StepExporter;
20 use Automattic\WooCommerce\Blueprint\UseWPFunctions;
21
22 /**
23 * Class Init
24 *
25 * This class initializes the Blueprint feature for WooCommerce.
26 */
27 class Init {
28 use UseWPFunctions;
29
30 const INSTALLED_WP_ORG_PLUGINS_TRANSIENT = 'woocommerce_blueprint_installed_wp_org_plugins';
31 const INSTALLED_WP_ORG_THEMES_TRANSIENT = 'woocommerce_blueprint_installed_wp_org_themes';
32 /**
33 * Array of initialized exporters.
34 *
35 * @var StepExporter[]
36 */
37 private array $initialized_exporters = array();
38
39 /**
40 * Init constructor.
41 */
42 public function __construct() {
43 add_action( 'rest_api_init', array( $this, 'init_rest_api' ) );
44 add_filter( 'woocommerce_admin_shared_settings', array( $this, 'add_js_vars' ) );
45
46 add_filter(
47 'wooblueprint_export_landingpage',
48 function () {
49 return '/wp-admin/admin.php?page=wc-admin';
50 }
51 );
52
53 add_filter( 'wooblueprint_exporters', array( $this, 'add_woo_exporters' ) );
54
55 add_action( 'upgrader_process_complete', array( $this, 'clear_installed_wp_org_plugins_transient' ), 10, 2 );
56 add_action( 'deleted_plugin', array( $this, 'clear_installed_wp_org_plugins_transient' ), 10, 2 );
57
58 add_action( 'upgrader_process_complete', array( $this, 'clear_installed_wp_org_themes_transient' ), 10, 2 );
59 add_action( 'switch_theme', array( $this, 'clear_installed_wp_org_themes_transient' ) );
60 add_action( 'deleted_theme', array( $this, 'clear_installed_wp_org_themes_transient' ) );
61 }
62
63 /**
64 * Register REST API routes.
65 *
66 * @return void
67 */
68 public function init_rest_api() {
69 ( new RestApi() )->register_routes();
70 }
71
72 /**
73 * Return Woo Exporter classnames.
74 *
75 * @return StepExporter[]
76 */
77 public function get_woo_exporters() {
78 $classnames = array(
79 ExportWCSettingsGeneral::class,
80 ExportWCSettingsProducts::class,
81 ExportWCSettingsTax::class,
82 ExportWCSettingsShipping::class,
83 ExportWCPaymentGateways::class,
84 ExportWCSettingsAccount::class,
85 ExportWCSettingsEmails::class,
86 ExportWCSettingsIntegrations::class,
87 ExportWCSettingsSiteVisibility::class,
88 ExportWCSettingsAdvanced::class,
89 );
90
91 $exporters = array();
92 foreach ( $classnames as $classname ) {
93 $exporters[ $classname ] = $this->initialized_exporters[ $classname ] ?? new $classname();
94 $this->initialized_exporters[ $classname ] = $exporters[ $classname ];
95 }
96
97 return array_values( $exporters );
98 }
99
100 /**
101 * Add Woo Specific Exporters.
102 *
103 * @param StepExporter[] $exporters Array of step exporters.
104 *
105 * @return StepExporter[]
106 */
107 public function add_woo_exporters( array $exporters ) {
108 return array_merge(
109 $exporters,
110 $this->get_woo_exporters()
111 );
112 }
113
114 /**
115 * Get plugins for export group.
116 *
117 * @return array|array[] $plugins
118 */
119 public function get_plugins_for_export_group() {
120 $plugins = $this->get_installed_wp_org_plugins();
121
122 // Get active plugins from WordPress options and transform plugins array into export format.
123 $active_plugins = $this->wp_get_option( 'active_plugins', array() );
124 $plugins = array_map(
125 function ( $key, $plugin ) use ( $active_plugins ) {
126 return array(
127 'id' => $key,
128 'label' => $plugin['Name'],
129 'checked' => in_array( $key, $active_plugins, true ),
130 );
131 },
132 array_keys( $plugins ),
133 $plugins
134 );
135
136 usort(
137 $plugins,
138 function ( $a, $b ) {
139 return $b['checked'] <=> $a['checked'];
140 }
141 );
142 return $plugins;
143 }
144
145 /**
146 * Clear the installed WordPress.org plugins transient.
147 */
148 public function clear_installed_wp_org_plugins_transient() {
149 delete_transient( self::INSTALLED_WP_ORG_PLUGINS_TRANSIENT );
150 }
151
152 /**
153 * Clear the installed WordPress.org themes transient.
154 */
155 public function clear_installed_wp_org_themes_transient() {
156 delete_transient( self::INSTALLED_WP_ORG_THEMES_TRANSIENT );
157 }
158
159 /**
160 * Get themes for export group.
161 *
162 * @return array $themes
163 */
164 public function get_themes_for_export_group() {
165 $themes = $this->get_installed_wp_org_themes();
166 $active_theme = $this->wp_get_theme();
167
168 $themes = array_map(
169 function ( $theme ) use ( $active_theme ) {
170 return array(
171 'id' => $theme->get_stylesheet(),
172 'label' => $theme->get( 'Name' ),
173 'checked' => $theme->get_stylesheet() === $active_theme->get_stylesheet(),
174 );
175 },
176 $themes
177 );
178
179 usort(
180 $themes,
181 function ( $a, $b ) {
182 return $b['checked'] <=> $a['checked'];
183 }
184 );
185
186 return array_values( $themes );
187 }
188
189 /**
190 * Return step groups for JS.
191 *
192 * This is used to populate exportable items on the blueprint settings page.
193 *
194 * @return array
195 */
196 public function get_step_groups_for_js() {
197 return array(
198 array(
199 'id' => 'settings',
200 'description' => __( 'Includes all the items featured in WooCommerce | Settings.', 'woocommerce' ),
201 'label' => __( 'WooCommerce Settings', 'woocommerce' ),
202 'icon' => 'settings',
203 'items' => array_map(
204 function ( $exporter ) {
205 return array(
206 'id' => $exporter instanceof HasAlias ? $exporter->get_alias() : $exporter->get_step_name(),
207 'label' => $exporter->get_label(),
208 'description' => $exporter->get_description(),
209 'checked' => true,
210 );
211 },
212 $this->get_woo_exporters()
213 ),
214 ),
215 array(
216 'id' => 'plugins',
217 'description' => __( 'Includes all the installed plugins.', 'woocommerce' ),
218 'label' => __( 'Plugins', 'woocommerce' ),
219 'icon' => 'plugins',
220 'items' => $this->get_plugins_for_export_group(),
221 ),
222 array(
223 'id' => 'themes',
224 'description' => __( 'Includes all the installed themes.', 'woocommerce' ),
225 'label' => __( 'Themes', 'woocommerce' ),
226 'icon' => 'layout',
227 'items' => $this->get_themes_for_export_group(),
228 ),
229 );
230 }
231
232 /**
233 * Add shared JS vars.
234 *
235 * @param array $settings shared settings.
236 *
237 * @return mixed
238 */
239 public function add_js_vars( $settings ) {
240 if ( ! is_admin() ) {
241 return $settings;
242 }
243
244 if ( 'woocommerce_page_wc-settings-advanced-blueprint' === PageController::get_instance()->get_current_screen_id() ) {
245 // Used on the settings page.
246 // wcSettings.admin.blueprint_step_groups.
247 $settings['blueprint_step_groups'] = $this->get_step_groups_for_js();
248 $settings['blueprint_max_step_size_bytes'] = RestApi::MAX_FILE_SIZE;
249 }
250
251 return $settings;
252 }
253
254 /**
255 * Get all installed WordPress.org plugins.
256 *
257 * @return array
258 */
259 private function get_installed_wp_org_plugins() {
260 // Try to get cached plugin list.
261 $wp_org_plugins = get_transient( self::INSTALLED_WP_ORG_PLUGINS_TRANSIENT );
262 if ( is_array( $wp_org_plugins ) ) {
263 return $wp_org_plugins;
264 }
265
266 // Get all installed plugins.
267 $all_plugins = $this->wp_get_plugins();
268 $plugin_slugs = array();
269
270 // Build a map of plugin file => slug.
271 foreach ( $all_plugins as $key => $plugin ) {
272 $slug = dirname( $key );
273 /**
274 * Apply the WP Core "wp_plugin_dependencies_slug" filter to get the correct plugin slug.
275 */
276 $slug = apply_filters( 'wp_plugin_dependencies_slug', $slug ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingSinceComment
277
278 $plugin_slugs[] = $slug;
279 $all_plugins[ $key ]['slug'] = $slug;
280 }
281
282 $api_response = $this->wp_plugins_api(
283 'plugin_information',
284 array(
285 'fields' => array(
286 'short_description' => false,
287 'sections' => false,
288 'description' => false,
289 'tested' => false,
290 'requires' => false,
291 'rating' => false,
292 'ratings' => false,
293 'downloaded' => false,
294 'downloadlink' => false,
295 'last_updated' => false,
296 'added' => false,
297 'tags' => false,
298 'compatibility' => false,
299 'homepage' => false,
300 'versions' => false,
301 'donate_link' => false,
302 'reviews' => false,
303 'banners' => false,
304 'icons' => false,
305 'active_installs' => false,
306 ),
307 'slugs' => $plugin_slugs,
308 )
309 );
310
311 // If API fails, return all plugins.
312 if ( is_wp_error( $api_response ) ) {
313 return $all_plugins;
314 }
315
316 // Filter plugins: only keep those with a valid API response (no 'error' for their slug).
317 $wp_org_plugins = array_filter(
318 $all_plugins,
319 function ( $plugin ) use ( $api_response ) {
320 $slug = $plugin['slug'];
321 return isset( $api_response->{$slug} ) && ! isset( $api_response->{$slug}['error'] );
322 }
323 );
324
325 set_transient( self::INSTALLED_WP_ORG_PLUGINS_TRANSIENT, $wp_org_plugins );
326 return $wp_org_plugins;
327 }
328
329 /**
330 * Get all installed WordPress.org themes.
331 *
332 * @return array
333 */
334 private function get_installed_wp_org_themes() {
335 // Try to get cached theme list.
336 $wp_org_themes = get_transient( self::INSTALLED_WP_ORG_THEMES_TRANSIENT );
337 if ( is_array( $wp_org_themes ) ) {
338 return $wp_org_themes;
339 }
340
341 // Get all installed themes.
342 $all_themes = $this->wp_get_themes();
343 $theme_slugs = array();
344
345 // Build an array of installed theme slugs.
346 foreach ( $all_themes as $key => $theme ) {
347 if ( is_string( $key ) ) {
348 $theme_slugs[] = strtolower( $key );
349 }
350 }
351
352 $api_response = $this->wp_themes_api(
353 'theme_information',
354 array(
355 'fields' => array(
356 'downloadlink' => true,
357 'sections' => false,
358 'description' => false,
359 'rating' => false,
360 'ratings' => false,
361 'downloaded' => false,
362 'last_updated' => false,
363 'tags' => false,
364 'homepage' => false,
365 'screenshots' => false,
366 'screenshot_url' => false,
367 'parent' => false,
368 'versions' => false,
369 'extended_author' => false,
370 ),
371 'slugs' => $theme_slugs,
372 )
373 );
374
375 // If the API fails, return all installed themes.
376 if ( is_wp_error( $api_response ) ) {
377 return $all_themes;
378 }
379
380 $wp_org_themes = array_filter(
381 $all_themes,
382 function ( $theme ) use ( $api_response ) {
383 $slug = $theme->get_stylesheet();
384 return isset( $api_response->{$slug}['download_link'] );
385 }
386 );
387
388 set_transient( self::INSTALLED_WP_ORG_THEMES_TRANSIENT, $wp_org_themes );
389 return $wp_org_themes;
390 }
391 }
392