Sin descripción

class-wc-admin-addons.php 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. <?php
  2. /**
  3. * Addons Page
  4. *
  5. * @package WooCommerce\Admin
  6. * @version 2.5.0
  7. */
  8. use Automattic\Jetpack\Constants;
  9. if ( ! defined( 'ABSPATH' ) ) {
  10. exit;
  11. }
  12. /**
  13. * WC_Admin_Addons Class.
  14. */
  15. class WC_Admin_Addons {
  16. /**
  17. * Get featured for the addons screen
  18. *
  19. * @return array of objects
  20. */
  21. public static function get_featured() {
  22. $featured = get_transient( 'wc_addons_featured' );
  23. if ( false === $featured ) {
  24. $headers = array();
  25. $auth = WC_Helper_Options::get( 'auth' );
  26. if ( ! empty( $auth['access_token'] ) ) {
  27. $headers['Authorization'] = 'Bearer ' . $auth['access_token'];
  28. }
  29. $raw_featured = wp_safe_remote_get(
  30. 'https://woocommerce.com/wp-json/wccom-extensions/1.0/featured',
  31. array(
  32. 'headers' => $headers,
  33. 'user-agent' => 'WooCommerce Addons Page',
  34. )
  35. );
  36. if ( ! is_wp_error( $raw_featured ) ) {
  37. $featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
  38. if ( $featured ) {
  39. set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
  40. }
  41. }
  42. }
  43. if ( is_object( $featured ) ) {
  44. self::output_featured_sections( $featured->sections );
  45. return $featured;
  46. }
  47. }
  48. /**
  49. * Build url parameter string
  50. *
  51. * @param string $category Addon (sub) category.
  52. * @param string $term Search terms.
  53. * @param string $country Store country.
  54. *
  55. * @return string url parameter string
  56. */
  57. public static function build_parameter_string( $category, $term, $country ) {
  58. $parameters = array(
  59. 'category' => $category,
  60. 'term' => $term,
  61. 'country' => $country,
  62. );
  63. return '?' . http_build_query( $parameters );
  64. }
  65. /**
  66. * Call API to get extensions
  67. *
  68. * @param string $category Addon (sub) category.
  69. * @param string $term Search terms.
  70. * @param string $country Store country.
  71. *
  72. * @return array of extensions
  73. */
  74. public static function get_extension_data( $category, $term, $country ) {
  75. $parameters = self::build_parameter_string( $category, $term, $country );
  76. $headers = array();
  77. $auth = WC_Helper_Options::get( 'auth' );
  78. if ( ! empty( $auth['access_token'] ) ) {
  79. $headers['Authorization'] = 'Bearer ' . $auth['access_token'];
  80. }
  81. $raw_extensions = wp_safe_remote_get(
  82. 'https://woocommerce.com/wp-json/wccom-extensions/1.0/search' . $parameters,
  83. array( 'headers' => $headers )
  84. );
  85. if ( ! is_wp_error( $raw_extensions ) ) {
  86. $addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) )->products;
  87. }
  88. return $addons;
  89. }
  90. /**
  91. * Get sections for the addons screen
  92. *
  93. * @return array of objects
  94. */
  95. public static function get_sections() {
  96. $addon_sections = get_transient( 'wc_addons_sections' );
  97. if ( false === ( $addon_sections ) ) {
  98. $raw_sections = wp_safe_remote_get(
  99. 'https://woocommerce.com/wp-json/wccom-extensions/1.0/categories'
  100. );
  101. if ( ! is_wp_error( $raw_sections ) ) {
  102. $addon_sections = json_decode( wp_remote_retrieve_body( $raw_sections ) );
  103. if ( $addon_sections ) {
  104. set_transient( 'wc_addons_sections', $addon_sections, WEEK_IN_SECONDS );
  105. }
  106. }
  107. }
  108. return apply_filters( 'woocommerce_addons_sections', $addon_sections );
  109. }
  110. /**
  111. * Get section for the addons screen.
  112. *
  113. * @param string $section_id Required section ID.
  114. *
  115. * @return object|bool
  116. */
  117. public static function get_section( $section_id ) {
  118. $sections = self::get_sections();
  119. if ( isset( $sections[ $section_id ] ) ) {
  120. return $sections[ $section_id ];
  121. }
  122. return false;
  123. }
  124. /**
  125. * Get section content for the addons screen.
  126. *
  127. * @param string $section_id Required section ID.
  128. *
  129. * @return array
  130. */
  131. public static function get_section_data( $section_id ) {
  132. $section = self::get_section( $section_id );
  133. $section_data = '';
  134. if ( ! empty( $section->endpoint ) ) {
  135. $section_data = get_transient( 'wc_addons_section_' . $section_id );
  136. if ( false === $section_data ) {
  137. $raw_section = wp_safe_remote_get( esc_url_raw( $section->endpoint ), array( 'user-agent' => 'WooCommerce Addons Page' ) );
  138. if ( ! is_wp_error( $raw_section ) ) {
  139. $section_data = json_decode( wp_remote_retrieve_body( $raw_section ) );
  140. if ( ! empty( $section_data->products ) ) {
  141. set_transient( 'wc_addons_section_' . $section_id, $section_data, WEEK_IN_SECONDS );
  142. }
  143. }
  144. }
  145. }
  146. return apply_filters( 'woocommerce_addons_section_data', $section_data->products, $section_id );
  147. }
  148. /**
  149. * Handles the outputting of a contextually aware Storefront link (points to child themes if Storefront is already active).
  150. */
  151. public static function output_storefront_button() {
  152. $template = get_option( 'template' );
  153. $stylesheet = get_option( 'stylesheet' );
  154. if ( 'storefront' === $template ) {
  155. if ( 'storefront' === $stylesheet ) {
  156. $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/';
  157. $text = __( 'Need a fresh look? Try Storefront child themes', 'woocommerce' );
  158. $utm_content = 'nostorefrontchildtheme';
  159. } else {
  160. $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/';
  161. $text = __( 'View more Storefront child themes', 'woocommerce' );
  162. $utm_content = 'hasstorefrontchildtheme';
  163. }
  164. } else {
  165. $url = 'https://woocommerce.com/storefront/';
  166. $text = __( 'Need a theme? Try Storefront', 'woocommerce' );
  167. $utm_content = 'nostorefront';
  168. }
  169. $url = add_query_arg(
  170. array(
  171. 'utm_source' => 'addons',
  172. 'utm_medium' => 'product',
  173. 'utm_campaign' => 'woocommerceplugin',
  174. 'utm_content' => $utm_content,
  175. ),
  176. $url
  177. );
  178. echo '<a href="' . esc_url( $url ) . '" class="add-new-h2">' . esc_html( $text ) . '</a>' . "\n";
  179. }
  180. /**
  181. * Handles the outputting of a banner block.
  182. *
  183. * @param object $block Banner data.
  184. */
  185. public static function output_banner_block( $block ) {
  186. ?>
  187. <div class="addons-banner-block">
  188. <h1><?php echo esc_html( $block->title ); ?></h1>
  189. <p><?php echo esc_html( $block->description ); ?></p>
  190. <div class="addons-banner-block-items">
  191. <?php foreach ( $block->items as $item ) : ?>
  192. <?php if ( self::show_extension( $item ) ) : ?>
  193. <div class="addons-banner-block-item">
  194. <div class="addons-banner-block-item-icon">
  195. <img class="addons-img" src="<?php echo esc_url( $item->image ); ?>" />
  196. </div>
  197. <div class="addons-banner-block-item-content">
  198. <h3><?php echo esc_html( $item->title ); ?></h3>
  199. <p><?php echo esc_html( $item->description ); ?></p>
  200. <?php
  201. self::output_button(
  202. $item->href,
  203. $item->button,
  204. 'addons-button-solid',
  205. $item->plugin
  206. );
  207. ?>
  208. </div>
  209. </div>
  210. <?php endif; ?>
  211. <?php endforeach; ?>
  212. </div>
  213. </div>
  214. <?php
  215. }
  216. /**
  217. * Handles the outputting of a column.
  218. *
  219. * @param object $block Column data.
  220. */
  221. public static function output_column( $block ) {
  222. if ( isset( $block->container ) && 'column_container_start' === $block->container ) {
  223. ?>
  224. <div class="addons-column-section">
  225. <?php
  226. }
  227. if ( 'column_start' === $block->module ) {
  228. ?>
  229. <div class="addons-column">
  230. <?php
  231. } else {
  232. ?>
  233. </div>
  234. <?php
  235. }
  236. if ( isset( $block->container ) && 'column_container_end' === $block->container ) {
  237. ?>
  238. </div>
  239. <?php
  240. }
  241. }
  242. /**
  243. * Handles the outputting of a column block.
  244. *
  245. * @param object $block Column block data.
  246. */
  247. public static function output_column_block( $block ) {
  248. ?>
  249. <div class="addons-column-block">
  250. <h1><?php echo esc_html( $block->title ); ?></h1>
  251. <p><?php echo esc_html( $block->description ); ?></p>
  252. <?php foreach ( $block->items as $item ) : ?>
  253. <?php if ( self::show_extension( $item ) ) : ?>
  254. <div class="addons-column-block-item">
  255. <div class="addons-column-block-item-icon">
  256. <img class="addons-img" src="<?php echo esc_url( $item->image ); ?>" />
  257. </div>
  258. <div class="addons-column-block-item-content">
  259. <h2><?php echo esc_html( $item->title ); ?></h2>
  260. <?php
  261. self::output_button(
  262. $item->href,
  263. $item->button,
  264. 'addons-button-solid',
  265. $item->plugin
  266. );
  267. ?>
  268. <p><?php echo esc_html( $item->description ); ?></p>
  269. </div>
  270. </div>
  271. <?php endif; ?>
  272. <?php endforeach; ?>
  273. </div>
  274. <?php
  275. }
  276. /**
  277. * Handles the outputting of a small light block.
  278. *
  279. * @param object $block Block data.
  280. */
  281. public static function output_small_light_block( $block ) {
  282. ?>
  283. <div class="addons-small-light-block">
  284. <img class="addons-img" src="<?php echo esc_url( $block->image ); ?>" />
  285. <div class="addons-small-light-block-content">
  286. <h1><?php echo esc_html( $block->title ); ?></h1>
  287. <p><?php echo esc_html( $block->description ); ?></p>
  288. <div class="addons-small-light-block-buttons">
  289. <?php foreach ( $block->buttons as $button ) : ?>
  290. <?php
  291. self::output_button(
  292. $button->href,
  293. $button->text,
  294. 'addons-button-solid'
  295. );
  296. ?>
  297. <?php endforeach; ?>
  298. </div>
  299. </div>
  300. </div>
  301. <?php
  302. }
  303. /**
  304. * Handles the outputting of a small dark block.
  305. *
  306. * @param object $block Block data.
  307. */
  308. public static function output_small_dark_block( $block ) {
  309. ?>
  310. <div class="addons-small-dark-block">
  311. <h1><?php echo esc_html( $block->title ); ?></h1>
  312. <p><?php echo esc_html( $block->description ); ?></p>
  313. <div class="addons-small-dark-items">
  314. <?php foreach ( $block->items as $item ) : ?>
  315. <div class="addons-small-dark-item">
  316. <?php if ( ! empty( $item->image ) ) : ?>
  317. <div class="addons-small-dark-item-icon">
  318. <img class="addons-img" src="<?php echo esc_url( $item->image ); ?>" />
  319. </div>
  320. <?php endif; ?>
  321. <?php
  322. self::output_button(
  323. $item->href,
  324. $item->button,
  325. 'addons-button-outline-white'
  326. );
  327. ?>
  328. </div>
  329. <?php endforeach; ?>
  330. </div>
  331. </div>
  332. <?php
  333. }
  334. /**
  335. * Handles the outputting of the WooCommerce Services banner block.
  336. *
  337. * @param object $block Block data.
  338. */
  339. public static function output_wcs_banner_block( $block = array() ) {
  340. $is_active = is_plugin_active( 'woocommerce-services/woocommerce-services.php' );
  341. $location = wc_get_base_location();
  342. if (
  343. ! in_array( $location['country'], array( 'US' ), true ) ||
  344. $is_active ||
  345. ! current_user_can( 'install_plugins' ) ||
  346. ! current_user_can( 'activate_plugins' )
  347. ) {
  348. return;
  349. }
  350. $button_url = wp_nonce_url(
  351. add_query_arg(
  352. array(
  353. 'install-addon' => 'woocommerce-services',
  354. )
  355. ),
  356. 'install-addon_woocommerce-services'
  357. );
  358. $defaults = array(
  359. 'image' => WC()->plugin_url() . '/assets/images/wcs-extensions-banner-3x.jpg',
  360. 'image_alt' => __( 'WooCommerce Shipping', 'woocommerce' ),
  361. 'title' => __( 'Save time and money with WooCommerce Shipping', 'woocommerce' ),
  362. 'description' => __( 'Print discounted USPS and DHL labels straight from your WooCommerce dashboard and save on shipping.', 'woocommerce' ),
  363. 'button' => __( 'Free - Install now', 'woocommerce' ),
  364. 'href' => $button_url,
  365. 'logos' => array(),
  366. );
  367. switch ( $location['country'] ) {
  368. case 'US':
  369. $local_defaults = array(
  370. 'logos' => array_merge(
  371. $defaults['logos'],
  372. array(
  373. array(
  374. 'link' => WC()->plugin_url() . '/assets/images/wcs-usps-logo.png',
  375. 'alt' => 'USPS logo',
  376. ),
  377. array(
  378. 'link' => WC()->plugin_url() . '/assets/images/wcs-dhlexpress-logo.png',
  379. 'alt' => 'DHL Express logo',
  380. ),
  381. )
  382. ),
  383. );
  384. break;
  385. default:
  386. $local_defaults = array();
  387. }
  388. $block_data = array_merge( $defaults, $local_defaults, $block );
  389. ?>
  390. <div class="addons-wcs-banner-block">
  391. <div class="addons-wcs-banner-block-image is-full-image">
  392. <img
  393. class="addons-img"
  394. src="<?php echo esc_url( $block_data['image'] ); ?>"
  395. alt="<?php echo esc_attr( $block_data['image_alt'] ); ?>"
  396. />
  397. </div>
  398. <div class="addons-wcs-banner-block-content">
  399. <h1><?php echo esc_html( $block_data['title'] ); ?></h1>
  400. <p><?php echo esc_html( $block_data['description'] ); ?></p>
  401. <ul class="wcs-logos-container">
  402. <?php foreach ( $block_data['logos'] as $logo ) : ?>
  403. <li>
  404. <img
  405. alt="<?php echo esc_attr( $logo['alt'] ); ?>"
  406. class="wcs-service-logo"
  407. src="<?php echo esc_url( $logo['link'] ); ?>"
  408. >
  409. </li>
  410. <?php endforeach; ?>
  411. </ul>
  412. <?php
  413. self::output_button(
  414. $block_data['href'],
  415. $block_data['button'],
  416. 'addons-button-outline-purple'
  417. );
  418. ?>
  419. </div>
  420. </div>
  421. <?php
  422. }
  423. /**
  424. * Handles the outputting of the WooCommerce Pay banner block.
  425. *
  426. * @param object $block Block data.
  427. */
  428. public static function output_wcpay_banner_block( $block = array() ) {
  429. $is_active = is_plugin_active( 'woocommerce-payments/woocommerce-payments.php' );
  430. $location = wc_get_base_location();
  431. if (
  432. ! in_array( $location['country'], array( 'US' ), true ) ||
  433. $is_active ||
  434. ! current_user_can( 'install_plugins' ) ||
  435. ! current_user_can( 'activate_plugins' )
  436. ) {
  437. return;
  438. }
  439. $button_url = wp_nonce_url(
  440. add_query_arg(
  441. array(
  442. 'install-addon' => 'woocommerce-payments',
  443. )
  444. ),
  445. 'install-addon_woocommerce-payments'
  446. );
  447. $defaults = array(
  448. 'image' => WC()->plugin_url() . '/assets/images/wcpayments-icon-secure.png',
  449. 'image_alt' => __( 'WooCommerce Payments', 'woocommerce' ),
  450. 'title' => __( 'Payments made simple, with no monthly fees &mdash; exclusively for WooCommerce stores.', 'woocommerce' ),
  451. 'description' => __( 'Securely accept cards in your store. See payments, track cash flow into your bank account, and stay on top of disputes – right from your dashboard.', 'woocommerce' ),
  452. 'button' => __( 'Free - Install now', 'woocommerce' ),
  453. 'href' => $button_url,
  454. 'logos' => array(),
  455. );
  456. $block_data = array_merge( $defaults, $block );
  457. ?>
  458. <div class="addons-wcs-banner-block">
  459. <div class="addons-wcs-banner-block-image">
  460. <img
  461. class="addons-img"
  462. src="<?php echo esc_url( $block_data['image'] ); ?>"
  463. alt="<?php echo esc_attr( $block_data['image_alt'] ); ?>"
  464. />
  465. </div>
  466. <div class="addons-wcs-banner-block-content">
  467. <h1><?php echo esc_html( $block_data['title'] ); ?></h1>
  468. <p><?php echo esc_html( $block_data['description'] ); ?></p>
  469. <?php
  470. self::output_button(
  471. $block_data['href'],
  472. $block_data['button'],
  473. 'addons-button-outline-purple'
  474. );
  475. ?>
  476. </div>
  477. </div>
  478. <?php
  479. }
  480. /**
  481. * Handles the output of a full-width block.
  482. *
  483. * @param array $section Section data.
  484. */
  485. public static function output_promotion_block( $section ) {
  486. if (
  487. ! current_user_can( 'install_plugins' ) ||
  488. ! current_user_can( 'activate_plugins' )
  489. ) {
  490. return;
  491. }
  492. $section_object = (object) $section;
  493. if ( ! empty( $section_object->geowhitelist ) ) {
  494. $section_object->geowhitelist = explode( ',', $section_object->geowhitelist );
  495. }
  496. if ( ! empty( $section_object->geoblacklist ) ) {
  497. $section_object->geoblacklist = explode( ',', $section_object->geoblacklist );
  498. }
  499. if ( ! self::show_extension( $section_object ) ) {
  500. return;
  501. }
  502. ?>
  503. <div class="addons-banner-block addons-promotion-block">
  504. <img
  505. class="addons-img"
  506. src="<?php echo esc_url( $section['image'] ); ?>"
  507. alt="<?php echo esc_attr( $section['image_alt'] ); ?>"
  508. />
  509. <div class="addons-promotion-block-content">
  510. <h1 class="addons-promotion-block-title"><?php echo esc_html( $section['title'] ); ?></h1>
  511. <div class="addons-promotion-block-description">
  512. <?php echo wp_kses_post( $section['description'] ); ?>
  513. </div>
  514. <div class="addons-promotion-block-buttons">
  515. <?php
  516. if ( $section['button_1'] ) {
  517. self::output_button(
  518. $section['button_1_href'],
  519. $section['button_1'],
  520. 'addons-button-expandable addons-button-solid',
  521. $section['plugin']
  522. );
  523. }
  524. if ( $section['button_2'] ) {
  525. self::output_button(
  526. $section['button_2_href'],
  527. $section['button_2'],
  528. 'addons-button-expandable addons-button-outline-purple',
  529. $section['plugin']
  530. );
  531. }
  532. ?>
  533. </div>
  534. </div>
  535. </div>
  536. <?php
  537. }
  538. /**
  539. * Handles the outputting of featured sections
  540. *
  541. * @param array $sections Section data.
  542. */
  543. public static function output_featured_sections( $sections ) {
  544. foreach ( $sections as $section ) {
  545. switch ( $section->module ) {
  546. case 'banner_block':
  547. self::output_banner_block( $section );
  548. break;
  549. case 'column_start':
  550. self::output_column( $section );
  551. break;
  552. case 'column_end':
  553. self::output_column( $section );
  554. break;
  555. case 'column_block':
  556. self::output_column_block( $section );
  557. break;
  558. case 'small_light_block':
  559. self::output_small_light_block( $section );
  560. break;
  561. case 'small_dark_block':
  562. self::output_small_dark_block( $section );
  563. break;
  564. case 'wcs_banner_block':
  565. self::output_wcs_banner_block( (array) $section );
  566. break;
  567. case 'wcpay_banner_block':
  568. self::output_wcpay_banner_block( (array) $section );
  569. break;
  570. case 'promotion_block':
  571. self::output_promotion_block( (array) $section );
  572. break;
  573. }
  574. }
  575. }
  576. /**
  577. * Returns in-app-purchase URL params.
  578. */
  579. public static function get_in_app_purchase_url_params() {
  580. // Get url (from path onward) for the current page,
  581. // so WCCOM "back" link returns user to where they were.
  582. $back_admin_path = add_query_arg( array() );
  583. return array(
  584. 'wccom-site' => site_url(),
  585. 'wccom-back' => rawurlencode( $back_admin_path ),
  586. 'wccom-woo-version' => Constants::get_constant( 'WC_VERSION' ),
  587. 'wccom-connect-nonce' => wp_create_nonce( 'connect' ),
  588. );
  589. }
  590. /**
  591. * Add in-app-purchase URL params to link.
  592. *
  593. * Adds various url parameters to a url to support a streamlined
  594. * flow for obtaining and setting up WooCommerce extensons.
  595. *
  596. * @param string $url Destination URL.
  597. */
  598. public static function add_in_app_purchase_url_params( $url ) {
  599. return add_query_arg(
  600. self::get_in_app_purchase_url_params(),
  601. $url
  602. );
  603. }
  604. /**
  605. * Outputs a button.
  606. *
  607. * @param string $url Destination URL.
  608. * @param string $text Button label text.
  609. * @param string $style Button style class.
  610. * @param string $plugin The plugin the button is promoting.
  611. */
  612. public static function output_button( $url, $text, $style, $plugin = '' ) {
  613. $style = __( 'Free', 'woocommerce' ) === $text ? 'addons-button-outline-purple' : $style;
  614. $style = is_plugin_active( $plugin ) ? 'addons-button-installed' : $style;
  615. $text = is_plugin_active( $plugin ) ? __( 'Installed', 'woocommerce' ) : $text;
  616. $url = self::add_in_app_purchase_url_params( $url );
  617. ?>
  618. <a
  619. class="addons-button <?php echo esc_attr( $style ); ?>"
  620. href="<?php echo esc_url( $url ); ?>">
  621. <?php echo esc_html( $text ); ?>
  622. </a>
  623. <?php
  624. }
  625. /**
  626. * Handles output of the addons page in admin.
  627. */
  628. public static function output() {
  629. $section = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '_featured';
  630. $search = isset( $_GET['search'] ) ? sanitize_text_field( wp_unslash( $_GET['search'] ) ) : '';
  631. if ( isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) {
  632. do_action( 'woocommerce_helper_output' );
  633. return;
  634. }
  635. if ( isset( $_GET['install-addon'] ) ) {
  636. switch ( $_GET['install-addon'] ) {
  637. case 'woocommerce-services':
  638. self::install_woocommerce_services_addon();
  639. break;
  640. case 'woocommerce-payments':
  641. self::install_woocommerce_payments_addon( $section );
  642. break;
  643. default:
  644. // Do nothing.
  645. break;
  646. }
  647. }
  648. $sections = self::get_sections();
  649. $theme = wp_get_theme();
  650. $current_section = isset( $_GET['section'] ) ? $section : '_featured';
  651. $addons = array();
  652. if ( '_featured' !== $current_section ) {
  653. $category = $section ? $section : null;
  654. $term = $search ? $search : null;
  655. $country = WC()->countries->get_base_country();
  656. $addons = self::get_extension_data( $category, $term, $country );
  657. }
  658. /**
  659. * Addon page view.
  660. *
  661. * @uses $addons
  662. * @uses $search
  663. * @uses $sections
  664. * @uses $theme
  665. * @uses $current_section
  666. */
  667. include_once dirname( __FILE__ ) . '/views/html-admin-page-addons.php';
  668. }
  669. /**
  670. * Install WooCommerce Services from Extensions screens.
  671. */
  672. public static function install_woocommerce_services_addon() {
  673. check_admin_referer( 'install-addon_woocommerce-services' );
  674. $services_plugin_id = 'woocommerce-services';
  675. $services_plugin = array(
  676. 'name' => __( 'WooCommerce Services', 'woocommerce' ),
  677. 'repo-slug' => 'woocommerce-services',
  678. );
  679. WC_Install::background_installer( $services_plugin_id, $services_plugin );
  680. wp_safe_redirect( remove_query_arg( array( 'install-addon', '_wpnonce' ) ) );
  681. exit;
  682. }
  683. /**
  684. * Install WooCommerce Payments from the Extensions screens.
  685. *
  686. * @param string $section Optional. Extenstions tab.
  687. *
  688. * @return void
  689. */
  690. public static function install_woocommerce_payments_addon( $section = '_featured' ) {
  691. check_admin_referer( 'install-addon_woocommerce-payments' );
  692. $wcpay_plugin_id = 'woocommerce-payments';
  693. $wcpay_plugin = array(
  694. 'name' => __( 'WooCommerce Payments', 'woocommerce' ),
  695. 'repo-slug' => 'woocommerce-payments',
  696. );
  697. WC_Install::background_installer( $wcpay_plugin_id, $wcpay_plugin );
  698. do_action( 'woocommerce_addon_installed', $wcpay_plugin_id, $section );
  699. wp_safe_redirect( remove_query_arg( array( 'install-addon', '_wpnonce' ) ) );
  700. exit;
  701. }
  702. /**
  703. * Should an extension be shown on the featured page.
  704. *
  705. * @param object $item Item data.
  706. * @return boolean
  707. */
  708. public static function show_extension( $item ) {
  709. $location = WC()->countries->get_base_country();
  710. if ( isset( $item->geowhitelist ) && ! in_array( $location, $item->geowhitelist, true ) ) {
  711. return false;
  712. }
  713. if ( isset( $item->geoblacklist ) && in_array( $location, $item->geoblacklist, true ) ) {
  714. return false;
  715. }
  716. if ( is_plugin_active( $item->plugin ) ) {
  717. return false;
  718. }
  719. return true;
  720. }
  721. /**
  722. * We're displaying page=wc-addons and page=wc-addons&section=helper as two separate pages.
  723. * When we're on those pages, add body classes to distinguishe them.
  724. *
  725. * @param string $admin_body_class Unfiltered body class.
  726. *
  727. * @return string Body class with added class for Marketplace or My Subscriptions page.
  728. */
  729. public static function filter_admin_body_classes( string $admin_body_class = '' ): string {
  730. if ( isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) {
  731. return " $admin_body_class woocommerce-page-wc-subscriptions ";
  732. }
  733. return " $admin_body_class woocommerce-page-wc-marketplace ";
  734. }
  735. }