Bez popisu

class-wc-rest-system-status-v2-controller.php 44KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. <?php
  2. /**
  3. * REST API WC System Status controller
  4. *
  5. * Handles requests to the /system_status endpoint.
  6. *
  7. * @package WooCommerce\RestApi
  8. * @since 3.0.0
  9. */
  10. defined( 'ABSPATH' ) || exit;
  11. /**
  12. * System status controller class.
  13. *
  14. * @package WooCommerce\RestApi
  15. * @extends WC_REST_Controller
  16. */
  17. class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
  18. /**
  19. * Endpoint namespace.
  20. *
  21. * @var string
  22. */
  23. protected $namespace = 'wc/v2';
  24. /**
  25. * Route base.
  26. *
  27. * @var string
  28. */
  29. protected $rest_base = 'system_status';
  30. /**
  31. * Register the route for /system_status
  32. */
  33. public function register_routes() {
  34. register_rest_route(
  35. $this->namespace,
  36. '/' . $this->rest_base,
  37. array(
  38. array(
  39. 'methods' => WP_REST_Server::READABLE,
  40. 'callback' => array( $this, 'get_items' ),
  41. 'permission_callback' => array( $this, 'get_items_permissions_check' ),
  42. 'args' => $this->get_collection_params(),
  43. ),
  44. 'schema' => array( $this, 'get_public_item_schema' ),
  45. )
  46. );
  47. }
  48. /**
  49. * Check whether a given request has permission to view system status.
  50. *
  51. * @param WP_REST_Request $request Full details about the request.
  52. * @return WP_Error|boolean
  53. */
  54. public function get_items_permissions_check( $request ) {
  55. if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
  56. return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  57. }
  58. return true;
  59. }
  60. /**
  61. * Get a system status info, by section.
  62. *
  63. * @param WP_REST_Request $request Full details about the request.
  64. * @return WP_Error|WP_REST_Response
  65. */
  66. public function get_items( $request ) {
  67. $fields = $this->get_fields_for_response( $request );
  68. $mappings = $this->get_item_mappings_per_fields( $fields );
  69. $response = $this->prepare_item_for_response( $mappings, $request );
  70. return rest_ensure_response( $response );
  71. }
  72. /**
  73. * Get the system status schema, conforming to JSON Schema.
  74. *
  75. * @return array
  76. */
  77. public function get_item_schema() {
  78. $schema = array(
  79. '$schema' => 'http://json-schema.org/draft-04/schema#',
  80. 'title' => 'system_status',
  81. 'type' => 'object',
  82. 'properties' => array(
  83. 'environment' => array(
  84. 'description' => __( 'Environment.', 'woocommerce' ),
  85. 'type' => 'object',
  86. 'context' => array( 'view' ),
  87. 'readonly' => true,
  88. 'properties' => array(
  89. 'home_url' => array(
  90. 'description' => __( 'Home URL.', 'woocommerce' ),
  91. 'type' => 'string',
  92. 'format' => 'uri',
  93. 'context' => array( 'view' ),
  94. 'readonly' => true,
  95. ),
  96. 'site_url' => array(
  97. 'description' => __( 'Site URL.', 'woocommerce' ),
  98. 'type' => 'string',
  99. 'format' => 'uri',
  100. 'context' => array( 'view' ),
  101. 'readonly' => true,
  102. ),
  103. 'version' => array(
  104. 'description' => __( 'WooCommerce version.', 'woocommerce' ),
  105. 'type' => 'string',
  106. 'context' => array( 'view' ),
  107. 'readonly' => true,
  108. ),
  109. 'log_directory' => array(
  110. 'description' => __( 'Log directory.', 'woocommerce' ),
  111. 'type' => 'string',
  112. 'context' => array( 'view' ),
  113. 'readonly' => true,
  114. ),
  115. 'log_directory_writable' => array(
  116. 'description' => __( 'Is log directory writable?', 'woocommerce' ),
  117. 'type' => 'boolean',
  118. 'context' => array( 'view' ),
  119. 'readonly' => true,
  120. ),
  121. 'wp_version' => array(
  122. 'description' => __( 'WordPress version.', 'woocommerce' ),
  123. 'type' => 'string',
  124. 'context' => array( 'view' ),
  125. 'readonly' => true,
  126. ),
  127. 'wp_multisite' => array(
  128. 'description' => __( 'Is WordPress multisite?', 'woocommerce' ),
  129. 'type' => 'boolean',
  130. 'context' => array( 'view' ),
  131. 'readonly' => true,
  132. ),
  133. 'wp_memory_limit' => array(
  134. 'description' => __( 'WordPress memory limit.', 'woocommerce' ),
  135. 'type' => 'integer',
  136. 'context' => array( 'view' ),
  137. 'readonly' => true,
  138. ),
  139. 'wp_debug_mode' => array(
  140. 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ),
  141. 'type' => 'boolean',
  142. 'context' => array( 'view' ),
  143. 'readonly' => true,
  144. ),
  145. 'wp_cron' => array(
  146. 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ),
  147. 'type' => 'boolean',
  148. 'context' => array( 'view' ),
  149. 'readonly' => true,
  150. ),
  151. 'language' => array(
  152. 'description' => __( 'WordPress language.', 'woocommerce' ),
  153. 'type' => 'string',
  154. 'context' => array( 'view' ),
  155. 'readonly' => true,
  156. ),
  157. 'server_info' => array(
  158. 'description' => __( 'Server info.', 'woocommerce' ),
  159. 'type' => 'string',
  160. 'context' => array( 'view' ),
  161. 'readonly' => true,
  162. ),
  163. 'php_version' => array(
  164. 'description' => __( 'PHP version.', 'woocommerce' ),
  165. 'type' => 'string',
  166. 'context' => array( 'view' ),
  167. 'readonly' => true,
  168. ),
  169. 'php_post_max_size' => array(
  170. 'description' => __( 'PHP post max size.', 'woocommerce' ),
  171. 'type' => 'integer',
  172. 'context' => array( 'view' ),
  173. 'readonly' => true,
  174. ),
  175. 'php_max_execution_time' => array(
  176. 'description' => __( 'PHP max execution time.', 'woocommerce' ),
  177. 'type' => 'integer',
  178. 'context' => array( 'view' ),
  179. 'readonly' => true,
  180. ),
  181. 'php_max_input_vars' => array(
  182. 'description' => __( 'PHP max input vars.', 'woocommerce' ),
  183. 'type' => 'integer',
  184. 'context' => array( 'view' ),
  185. 'readonly' => true,
  186. ),
  187. 'curl_version' => array(
  188. 'description' => __( 'cURL version.', 'woocommerce' ),
  189. 'type' => 'string',
  190. 'context' => array( 'view' ),
  191. 'readonly' => true,
  192. ),
  193. 'suhosin_installed' => array(
  194. 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ),
  195. 'type' => 'boolean',
  196. 'context' => array( 'view' ),
  197. 'readonly' => true,
  198. ),
  199. 'max_upload_size' => array(
  200. 'description' => __( 'Max upload size.', 'woocommerce' ),
  201. 'type' => 'integer',
  202. 'context' => array( 'view' ),
  203. 'readonly' => true,
  204. ),
  205. 'mysql_version' => array(
  206. 'description' => __( 'MySQL version.', 'woocommerce' ),
  207. 'type' => 'string',
  208. 'context' => array( 'view' ),
  209. 'readonly' => true,
  210. ),
  211. 'mysql_version_string' => array(
  212. 'description' => __( 'MySQL version string.', 'woocommerce' ),
  213. 'type' => 'string',
  214. 'context' => array( 'view' ),
  215. 'readonly' => true,
  216. ),
  217. 'default_timezone' => array(
  218. 'description' => __( 'Default timezone.', 'woocommerce' ),
  219. 'type' => 'string',
  220. 'context' => array( 'view' ),
  221. 'readonly' => true,
  222. ),
  223. 'fsockopen_or_curl_enabled' => array(
  224. 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ),
  225. 'type' => 'boolean',
  226. 'context' => array( 'view' ),
  227. 'readonly' => true,
  228. ),
  229. 'soapclient_enabled' => array(
  230. 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ),
  231. 'type' => 'boolean',
  232. 'context' => array( 'view' ),
  233. 'readonly' => true,
  234. ),
  235. 'domdocument_enabled' => array(
  236. 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ),
  237. 'type' => 'boolean',
  238. 'context' => array( 'view' ),
  239. 'readonly' => true,
  240. ),
  241. 'gzip_enabled' => array(
  242. 'description' => __( 'Is GZip enabled?', 'woocommerce' ),
  243. 'type' => 'boolean',
  244. 'context' => array( 'view' ),
  245. 'readonly' => true,
  246. ),
  247. 'mbstring_enabled' => array(
  248. 'description' => __( 'Is mbstring enabled?', 'woocommerce' ),
  249. 'type' => 'boolean',
  250. 'context' => array( 'view' ),
  251. 'readonly' => true,
  252. ),
  253. 'remote_post_successful' => array(
  254. 'description' => __( 'Remote POST successful?', 'woocommerce' ),
  255. 'type' => 'boolean',
  256. 'context' => array( 'view' ),
  257. 'readonly' => true,
  258. ),
  259. 'remote_post_response' => array(
  260. 'description' => __( 'Remote POST response.', 'woocommerce' ),
  261. 'type' => 'string',
  262. 'context' => array( 'view' ),
  263. 'readonly' => true,
  264. ),
  265. 'remote_get_successful' => array(
  266. 'description' => __( 'Remote GET successful?', 'woocommerce' ),
  267. 'type' => 'boolean',
  268. 'context' => array( 'view' ),
  269. 'readonly' => true,
  270. ),
  271. 'remote_get_response' => array(
  272. 'description' => __( 'Remote GET response.', 'woocommerce' ),
  273. 'type' => 'string',
  274. 'context' => array( 'view' ),
  275. 'readonly' => true,
  276. ),
  277. ),
  278. ),
  279. 'database' => array(
  280. 'description' => __( 'Database.', 'woocommerce' ),
  281. 'type' => 'object',
  282. 'context' => array( 'view' ),
  283. 'readonly' => true,
  284. 'properties' => array(
  285. 'wc_database_version' => array(
  286. 'description' => __( 'WC database version.', 'woocommerce' ),
  287. 'type' => 'string',
  288. 'context' => array( 'view' ),
  289. 'readonly' => true,
  290. ),
  291. 'database_prefix' => array(
  292. 'description' => __( 'Database prefix.', 'woocommerce' ),
  293. 'type' => 'string',
  294. 'context' => array( 'view' ),
  295. 'readonly' => true,
  296. ),
  297. 'maxmind_geoip_database' => array(
  298. 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ),
  299. 'type' => 'string',
  300. 'context' => array( 'view' ),
  301. 'readonly' => true,
  302. ),
  303. 'database_tables' => array(
  304. 'description' => __( 'Database tables.', 'woocommerce' ),
  305. 'type' => 'array',
  306. 'context' => array( 'view' ),
  307. 'readonly' => true,
  308. 'items' => array(
  309. 'type' => 'string',
  310. ),
  311. ),
  312. ),
  313. ),
  314. 'active_plugins' => array(
  315. 'description' => __( 'Active plugins.', 'woocommerce' ),
  316. 'type' => 'array',
  317. 'context' => array( 'view' ),
  318. 'readonly' => true,
  319. 'items' => array(
  320. 'type' => 'string',
  321. ),
  322. ),
  323. 'inactive_plugins' => array(
  324. 'description' => __( 'Inactive plugins.', 'woocommerce' ),
  325. 'type' => 'array',
  326. 'context' => array( 'view' ),
  327. 'readonly' => true,
  328. 'items' => array(
  329. 'type' => 'string',
  330. ),
  331. ),
  332. 'dropins_mu_plugins' => array(
  333. 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ),
  334. 'type' => 'array',
  335. 'context' => array( 'view' ),
  336. 'readonly' => true,
  337. 'items' => array(
  338. 'type' => 'string',
  339. ),
  340. ),
  341. 'theme' => array(
  342. 'description' => __( 'Theme.', 'woocommerce' ),
  343. 'type' => 'object',
  344. 'context' => array( 'view' ),
  345. 'readonly' => true,
  346. 'properties' => array(
  347. 'name' => array(
  348. 'description' => __( 'Theme name.', 'woocommerce' ),
  349. 'type' => 'string',
  350. 'context' => array( 'view' ),
  351. 'readonly' => true,
  352. ),
  353. 'version' => array(
  354. 'description' => __( 'Theme version.', 'woocommerce' ),
  355. 'type' => 'string',
  356. 'context' => array( 'view' ),
  357. 'readonly' => true,
  358. ),
  359. 'version_latest' => array(
  360. 'description' => __( 'Latest version of theme.', 'woocommerce' ),
  361. 'type' => 'string',
  362. 'context' => array( 'view' ),
  363. 'readonly' => true,
  364. ),
  365. 'author_url' => array(
  366. 'description' => __( 'Theme author URL.', 'woocommerce' ),
  367. 'type' => 'string',
  368. 'format' => 'uri',
  369. 'context' => array( 'view' ),
  370. 'readonly' => true,
  371. ),
  372. 'is_child_theme' => array(
  373. 'description' => __( 'Is this theme a child theme?', 'woocommerce' ),
  374. 'type' => 'boolean',
  375. 'context' => array( 'view' ),
  376. 'readonly' => true,
  377. ),
  378. 'has_woocommerce_support' => array(
  379. 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ),
  380. 'type' => 'boolean',
  381. 'context' => array( 'view' ),
  382. 'readonly' => true,
  383. ),
  384. 'has_woocommerce_file' => array(
  385. 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ),
  386. 'type' => 'boolean',
  387. 'context' => array( 'view' ),
  388. 'readonly' => true,
  389. ),
  390. 'has_outdated_templates' => array(
  391. 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ),
  392. 'type' => 'boolean',
  393. 'context' => array( 'view' ),
  394. 'readonly' => true,
  395. ),
  396. 'overrides' => array(
  397. 'description' => __( 'Template overrides.', 'woocommerce' ),
  398. 'type' => 'array',
  399. 'context' => array( 'view' ),
  400. 'readonly' => true,
  401. 'items' => array(
  402. 'type' => 'string',
  403. ),
  404. ),
  405. 'parent_name' => array(
  406. 'description' => __( 'Parent theme name.', 'woocommerce' ),
  407. 'type' => 'string',
  408. 'context' => array( 'view' ),
  409. 'readonly' => true,
  410. ),
  411. 'parent_version' => array(
  412. 'description' => __( 'Parent theme version.', 'woocommerce' ),
  413. 'type' => 'string',
  414. 'context' => array( 'view' ),
  415. 'readonly' => true,
  416. ),
  417. 'parent_author_url' => array(
  418. 'description' => __( 'Parent theme author URL.', 'woocommerce' ),
  419. 'type' => 'string',
  420. 'format' => 'uri',
  421. 'context' => array( 'view' ),
  422. 'readonly' => true,
  423. ),
  424. ),
  425. ),
  426. 'settings' => array(
  427. 'description' => __( 'Settings.', 'woocommerce' ),
  428. 'type' => 'object',
  429. 'context' => array( 'view' ),
  430. 'readonly' => true,
  431. 'properties' => array(
  432. 'api_enabled' => array(
  433. 'description' => __( 'REST API enabled?', 'woocommerce' ),
  434. 'type' => 'boolean',
  435. 'context' => array( 'view' ),
  436. 'readonly' => true,
  437. ),
  438. 'force_ssl' => array(
  439. 'description' => __( 'SSL forced?', 'woocommerce' ),
  440. 'type' => 'boolean',
  441. 'context' => array( 'view' ),
  442. 'readonly' => true,
  443. ),
  444. 'currency' => array(
  445. 'description' => __( 'Currency.', 'woocommerce' ),
  446. 'type' => 'string',
  447. 'context' => array( 'view' ),
  448. 'readonly' => true,
  449. ),
  450. 'currency_symbol' => array(
  451. 'description' => __( 'Currency symbol.', 'woocommerce' ),
  452. 'type' => 'string',
  453. 'context' => array( 'view' ),
  454. 'readonly' => true,
  455. ),
  456. 'currency_position' => array(
  457. 'description' => __( 'Currency position.', 'woocommerce' ),
  458. 'type' => 'string',
  459. 'context' => array( 'view' ),
  460. 'readonly' => true,
  461. ),
  462. 'thousand_separator' => array(
  463. 'description' => __( 'Thousand separator.', 'woocommerce' ),
  464. 'type' => 'string',
  465. 'context' => array( 'view' ),
  466. 'readonly' => true,
  467. ),
  468. 'decimal_separator' => array(
  469. 'description' => __( 'Decimal separator.', 'woocommerce' ),
  470. 'type' => 'string',
  471. 'context' => array( 'view' ),
  472. 'readonly' => true,
  473. ),
  474. 'number_of_decimals' => array(
  475. 'description' => __( 'Number of decimals.', 'woocommerce' ),
  476. 'type' => 'integer',
  477. 'context' => array( 'view' ),
  478. 'readonly' => true,
  479. ),
  480. 'geolocation_enabled' => array(
  481. 'description' => __( 'Geolocation enabled?', 'woocommerce' ),
  482. 'type' => 'boolean',
  483. 'context' => array( 'view' ),
  484. 'readonly' => true,
  485. ),
  486. 'taxonomies' => array(
  487. 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ),
  488. 'type' => 'array',
  489. 'context' => array( 'view' ),
  490. 'readonly' => true,
  491. 'items' => array(
  492. 'type' => 'string',
  493. ),
  494. ),
  495. 'product_visibility_terms' => array(
  496. 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ),
  497. 'type' => 'array',
  498. 'context' => array( 'view' ),
  499. 'readonly' => true,
  500. 'items' => array(
  501. 'type' => 'string',
  502. ),
  503. ),
  504. ),
  505. ),
  506. 'security' => array(
  507. 'description' => __( 'Security.', 'woocommerce' ),
  508. 'type' => 'object',
  509. 'context' => array( 'view' ),
  510. 'readonly' => true,
  511. 'properties' => array(
  512. 'secure_connection' => array(
  513. 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ),
  514. 'type' => 'boolean',
  515. 'context' => array( 'view' ),
  516. 'readonly' => true,
  517. ),
  518. 'hide_errors' => array(
  519. 'description' => __( 'Hide errors from visitors?', 'woocommerce' ),
  520. 'type' => 'boolean',
  521. 'context' => array( 'view' ),
  522. 'readonly' => true,
  523. ),
  524. ),
  525. ),
  526. 'pages' => array(
  527. 'description' => __( 'WooCommerce pages.', 'woocommerce' ),
  528. 'type' => 'array',
  529. 'context' => array( 'view' ),
  530. 'readonly' => true,
  531. 'items' => array(
  532. 'type' => 'string',
  533. ),
  534. ),
  535. 'post_type_counts' => array(
  536. 'description' => __( 'Total post count.', 'woocommerce' ),
  537. 'type' => 'array',
  538. 'context' => array( 'view' ),
  539. 'readonly' => true,
  540. 'items' => array(
  541. 'type' => 'string',
  542. ),
  543. ),
  544. ),
  545. );
  546. return $this->add_additional_fields_schema( $schema );
  547. }
  548. /**
  549. * Return an array of sections and the data associated with each.
  550. *
  551. * @deprecated 3.9.0
  552. * @return array
  553. */
  554. public function get_item_mappings() {
  555. return array(
  556. 'environment' => $this->get_environment_info(),
  557. 'database' => $this->get_database_info(),
  558. 'active_plugins' => $this->get_active_plugins(),
  559. 'inactive_plugins' => $this->get_inactive_plugins(),
  560. 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(),
  561. 'theme' => $this->get_theme_info(),
  562. 'settings' => $this->get_settings(),
  563. 'security' => $this->get_security_info(),
  564. 'pages' => $this->get_pages(),
  565. 'post_type_counts' => $this->get_post_type_counts(),
  566. );
  567. }
  568. /**
  569. * Return an array of sections and the data associated with each.
  570. *
  571. * @since 3.9.0
  572. * @param array $fields List of fields to be included on the response.
  573. * @return array
  574. */
  575. public function get_item_mappings_per_fields( $fields ) {
  576. return array(
  577. 'environment' => $this->get_environment_info_per_fields( $fields ),
  578. 'database' => $this->get_database_info(),
  579. 'active_plugins' => $this->get_active_plugins(),
  580. 'inactive_plugins' => $this->get_inactive_plugins(),
  581. 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(),
  582. 'theme' => $this->get_theme_info(),
  583. 'settings' => $this->get_settings(),
  584. 'security' => $this->get_security_info(),
  585. 'pages' => $this->get_pages(),
  586. 'post_type_counts' => $this->get_post_type_counts(),
  587. );
  588. }
  589. /**
  590. * Get array of environment information. Includes thing like software
  591. * versions, and various server settings.
  592. *
  593. * @deprecated 3.9.0
  594. * @return array
  595. */
  596. public function get_environment_info() {
  597. return $this->get_environment_info_per_fields( array( 'environment' ) );
  598. }
  599. /**
  600. * Check if field item exists.
  601. *
  602. * @since 3.9.0
  603. * @param string $section Fields section.
  604. * @param array $items List of items to check for.
  605. * @param array $fields List of fields to be included on the response.
  606. * @return bool
  607. */
  608. private function check_if_field_item_exists( $section, $items, $fields ) {
  609. if ( ! in_array( $section, $fields, true ) ) {
  610. return false;
  611. }
  612. $exclude = array();
  613. foreach ( $fields as $field ) {
  614. $values = explode( '.', $field );
  615. if ( $section !== $values[0] || empty( $values[1] ) ) {
  616. continue;
  617. }
  618. $exclude[] = $values[1];
  619. }
  620. return 0 <= count( array_intersect( $items, $exclude ) );
  621. }
  622. /**
  623. * Get array of environment information. Includes thing like software
  624. * versions, and various server settings.
  625. *
  626. * @param array $fields List of fields to be included on the response.
  627. * @return array
  628. */
  629. public function get_environment_info_per_fields( $fields ) {
  630. global $wpdb;
  631. $enable_remote_post = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields );
  632. $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_get_successful', 'remote_get_response' ), $fields );
  633. // Figure out cURL version, if installed.
  634. $curl_version = '';
  635. if ( function_exists( 'curl_version' ) ) {
  636. $curl_version = curl_version();
  637. $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
  638. } elseif ( extension_loaded( 'curl' ) ) {
  639. $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' );
  640. }
  641. // WP memory limit.
  642. $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT );
  643. if ( function_exists( 'memory_get_usage' ) ) {
  644. $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
  645. }
  646. // Test POST requests.
  647. $post_response_successful = null;
  648. $post_response_code = null;
  649. if ( $enable_remote_post ) {
  650. $post_response_code = get_transient( 'woocommerce_test_remote_post' );
  651. if ( false === $post_response_code || is_wp_error( $post_response_code ) ) {
  652. $response = wp_safe_remote_post(
  653. 'https://www.paypal.com/cgi-bin/webscr',
  654. array(
  655. 'timeout' => 10,
  656. 'user-agent' => 'WooCommerce/' . WC()->version,
  657. 'httpversion' => '1.1',
  658. 'body' => array(
  659. 'cmd' => '_notify-validate',
  660. ),
  661. )
  662. );
  663. if ( ! is_wp_error( $response ) ) {
  664. $post_response_code = $response['response']['code'];
  665. }
  666. set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS );
  667. }
  668. $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300;
  669. }
  670. // Test GET requests.
  671. $get_response_successful = null;
  672. $get_response_code = null;
  673. if ( $enable_remote_get ) {
  674. $get_response_code = get_transient( 'woocommerce_test_remote_get' );
  675. if ( false === $get_response_code || is_wp_error( $get_response_code ) ) {
  676. $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) );
  677. if ( ! is_wp_error( $response ) ) {
  678. $get_response_code = $response['response']['code'];
  679. }
  680. set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS );
  681. }
  682. $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300;
  683. }
  684. $database_version = wc_get_server_database_version();
  685. // Return all environment info. Described by JSON Schema.
  686. return array(
  687. 'home_url' => get_option( 'home' ),
  688. 'site_url' => get_option( 'siteurl' ),
  689. 'version' => WC()->version,
  690. 'log_directory' => WC_LOG_DIR,
  691. 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen
  692. 'wp_version' => get_bloginfo( 'version' ),
  693. 'wp_multisite' => is_multisite(),
  694. 'wp_memory_limit' => $wp_memory_limit,
  695. 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
  696. 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
  697. 'language' => get_locale(),
  698. 'external_object_cache' => wp_using_ext_object_cache(),
  699. 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '',
  700. 'php_version' => phpversion(),
  701. 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ),
  702. 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ),
  703. 'php_max_input_vars' => (int) ini_get( 'max_input_vars' ),
  704. 'curl_version' => $curl_version,
  705. 'suhosin_installed' => extension_loaded( 'suhosin' ),
  706. 'max_upload_size' => wp_max_upload_size(),
  707. 'mysql_version' => $database_version['number'],
  708. 'mysql_version_string' => $database_version['string'],
  709. 'default_timezone' => date_default_timezone_get(),
  710. 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ),
  711. 'soapclient_enabled' => class_exists( 'SoapClient' ),
  712. 'domdocument_enabled' => class_exists( 'DOMDocument' ),
  713. 'gzip_enabled' => is_callable( 'gzopen' ),
  714. 'mbstring_enabled' => extension_loaded( 'mbstring' ),
  715. 'remote_post_successful' => $post_response_successful,
  716. 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code,
  717. 'remote_get_successful' => $get_response_successful,
  718. 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code,
  719. );
  720. }
  721. /**
  722. * Add prefix to table.
  723. *
  724. * @param string $table Table name.
  725. * @return stromg
  726. */
  727. protected function add_db_table_prefix( $table ) {
  728. global $wpdb;
  729. return $wpdb->prefix . $table;
  730. }
  731. /**
  732. * Get array of database information. Version, prefix, and table existence.
  733. *
  734. * @return array
  735. */
  736. public function get_database_info() {
  737. global $wpdb;
  738. $tables = array();
  739. $database_size = array();
  740. // It is not possible to get the database name from some classes that replace wpdb (e.g., HyperDB)
  741. // and that is why this if condition is needed.
  742. if ( defined( 'DB_NAME' ) ) {
  743. $database_table_information = $wpdb->get_results(
  744. $wpdb->prepare(
  745. "SELECT
  746. table_name AS 'name',
  747. engine AS 'engine',
  748. round( ( data_length / 1024 / 1024 ), 2 ) 'data',
  749. round( ( index_length / 1024 / 1024 ), 2 ) 'index'
  750. FROM information_schema.TABLES
  751. WHERE table_schema = %s
  752. ORDER BY name ASC;",
  753. DB_NAME
  754. )
  755. );
  756. // WC Core tables to check existence of.
  757. $core_tables = apply_filters(
  758. 'woocommerce_database_tables',
  759. array(
  760. 'woocommerce_sessions',
  761. 'woocommerce_api_keys',
  762. 'woocommerce_attribute_taxonomies',
  763. 'woocommerce_downloadable_product_permissions',
  764. 'woocommerce_order_items',
  765. 'woocommerce_order_itemmeta',
  766. 'woocommerce_tax_rates',
  767. 'woocommerce_tax_rate_locations',
  768. 'woocommerce_shipping_zones',
  769. 'woocommerce_shipping_zone_locations',
  770. 'woocommerce_shipping_zone_methods',
  771. 'woocommerce_payment_tokens',
  772. 'woocommerce_payment_tokenmeta',
  773. 'woocommerce_log',
  774. )
  775. );
  776. /**
  777. * Adding the prefix to the tables array, for backwards compatibility.
  778. *
  779. * If we changed the tables above to include the prefix, then any filters against that table could break.
  780. */
  781. $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables );
  782. /**
  783. * Organize WooCommerce and non-WooCommerce tables separately for display purposes later.
  784. *
  785. * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables.
  786. */
  787. $tables = array(
  788. 'woocommerce' => array_fill_keys( $core_tables, false ),
  789. 'other' => array(),
  790. );
  791. $database_size = array(
  792. 'data' => 0,
  793. 'index' => 0,
  794. );
  795. $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() );
  796. $global_tables = $wpdb->tables( 'global', true );
  797. foreach ( $database_table_information as $table ) {
  798. // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current.
  799. if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) {
  800. continue;
  801. }
  802. $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other';
  803. $tables[ $table_type ][ $table->name ] = array(
  804. 'data' => $table->data,
  805. 'index' => $table->index,
  806. 'engine' => $table->engine,
  807. );
  808. $database_size['data'] += $table->data;
  809. $database_size['index'] += $table->index;
  810. }
  811. }
  812. // Return all database info. Described by JSON Schema.
  813. return array(
  814. 'wc_database_version' => get_option( 'woocommerce_db_version' ),
  815. 'database_prefix' => $wpdb->prefix,
  816. 'maxmind_geoip_database' => '',
  817. 'database_tables' => $tables,
  818. 'database_size' => $database_size,
  819. );
  820. }
  821. /**
  822. * Get array of counts of objects. Orders, products, etc.
  823. *
  824. * @return array
  825. */
  826. public function get_post_type_counts() {
  827. global $wpdb;
  828. $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" );
  829. return is_array( $post_type_counts ) ? $post_type_counts : array();
  830. }
  831. /**
  832. * Get a list of plugins active on the site.
  833. *
  834. * @return array
  835. */
  836. public function get_active_plugins() {
  837. require_once ABSPATH . 'wp-admin/includes/plugin.php';
  838. if ( ! function_exists( 'get_plugin_data' ) ) {
  839. return array();
  840. }
  841. $active_plugins = (array) get_option( 'active_plugins', array() );
  842. if ( is_multisite() ) {
  843. $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
  844. $active_plugins = array_merge( $active_plugins, $network_activated_plugins );
  845. }
  846. $active_plugins_data = array();
  847. foreach ( $active_plugins as $plugin ) {
  848. $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
  849. $active_plugins_data[] = $this->format_plugin_data( $plugin, $data );
  850. }
  851. return $active_plugins_data;
  852. }
  853. /**
  854. * Get a list of inplugins active on the site.
  855. *
  856. * @return array
  857. */
  858. public function get_inactive_plugins() {
  859. require_once ABSPATH . 'wp-admin/includes/plugin.php';
  860. if ( ! function_exists( 'get_plugins' ) ) {
  861. return array();
  862. }
  863. $plugins = get_plugins();
  864. $active_plugins = (array) get_option( 'active_plugins', array() );
  865. if ( is_multisite() ) {
  866. $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
  867. $active_plugins = array_merge( $active_plugins, $network_activated_plugins );
  868. }
  869. $plugins_data = array();
  870. foreach ( $plugins as $plugin => $data ) {
  871. if ( in_array( $plugin, $active_plugins, true ) ) {
  872. continue;
  873. }
  874. $plugins_data[] = $this->format_plugin_data( $plugin, $data );
  875. }
  876. return $plugins_data;
  877. }
  878. /**
  879. * Format plugin data, including data on updates, into a standard format.
  880. *
  881. * @since 3.6.0
  882. * @param string $plugin Plugin directory/file.
  883. * @param array $data Plugin data from WP.
  884. * @return array Formatted data.
  885. */
  886. protected function format_plugin_data( $plugin, $data ) {
  887. require_once ABSPATH . 'wp-admin/includes/update.php';
  888. if ( ! function_exists( 'get_plugin_updates' ) ) {
  889. return array();
  890. }
  891. // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins.
  892. if ( empty( $this->available_updates ) ) {
  893. $this->available_updates = get_plugin_updates();
  894. }
  895. $version_latest = $data['Version'];
  896. // Find latest version.
  897. if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) {
  898. $version_latest = $this->available_updates[ $plugin ]->update->new_version;
  899. }
  900. return array(
  901. 'plugin' => $plugin,
  902. 'name' => $data['Name'],
  903. 'version' => $data['Version'],
  904. 'version_latest' => $version_latest,
  905. 'url' => $data['PluginURI'],
  906. 'author_name' => $data['AuthorName'],
  907. 'author_url' => esc_url_raw( $data['AuthorURI'] ),
  908. 'network_activated' => $data['Network'],
  909. );
  910. }
  911. /**
  912. * Get a list of Dropins and MU plugins.
  913. *
  914. * @since 3.6.0
  915. * @return array
  916. */
  917. public function get_dropins_mu_plugins() {
  918. $dropins = get_dropins();
  919. $plugins = array(
  920. 'dropins' => array(),
  921. 'mu_plugins' => array(),
  922. );
  923. foreach ( $dropins as $key => $dropin ) {
  924. $plugins['dropins'][] = array(
  925. 'plugin' => $key,
  926. 'name' => $dropin['Name'],
  927. );
  928. }
  929. $mu_plugins = get_mu_plugins();
  930. foreach ( $mu_plugins as $plugin => $mu_plugin ) {
  931. $plugins['mu_plugins'][] = array(
  932. 'plugin' => $plugin,
  933. 'name' => $mu_plugin['Name'],
  934. 'version' => $mu_plugin['Version'],
  935. 'url' => $mu_plugin['PluginURI'],
  936. 'author_name' => $mu_plugin['AuthorName'],
  937. 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ),
  938. );
  939. }
  940. return $plugins;
  941. }
  942. /**
  943. * Get info on the current active theme, info on parent theme (if presnet)
  944. * and a list of template overrides.
  945. *
  946. * @return array
  947. */
  948. public function get_theme_info() {
  949. $active_theme = wp_get_theme();
  950. // Get parent theme info if this theme is a child theme, otherwise
  951. // pass empty info in the response.
  952. if ( is_child_theme() ) {
  953. $parent_theme = wp_get_theme( $active_theme->template );
  954. $parent_theme_info = array(
  955. 'parent_name' => $parent_theme->name,
  956. 'parent_version' => $parent_theme->version,
  957. 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ),
  958. 'parent_author_url' => $parent_theme->{'Author URI'},
  959. );
  960. } else {
  961. $parent_theme_info = array(
  962. 'parent_name' => '',
  963. 'parent_version' => '',
  964. 'parent_version_latest' => '',
  965. 'parent_author_url' => '',
  966. );
  967. }
  968. /**
  969. * Scan the theme directory for all WC templates to see if our theme
  970. * overrides any of them.
  971. */
  972. $override_files = array();
  973. $outdated_templates = false;
  974. $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' );
  975. // Include *-product_<cat|tag> templates for backwards compatibility.
  976. $scan_files[] = 'content-product_cat.php';
  977. $scan_files[] = 'taxonomy-product_cat.php';
  978. $scan_files[] = 'taxonomy-product_tag.php';
  979. foreach ( $scan_files as $file ) {
  980. $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' );
  981. if ( file_exists( $located ) ) {
  982. $theme_file = $located;
  983. } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
  984. $theme_file = get_stylesheet_directory() . '/' . $file;
  985. } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) {
  986. $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file;
  987. } elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
  988. $theme_file = get_template_directory() . '/' . $file;
  989. } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) {
  990. $theme_file = get_template_directory() . '/' . WC()->template_path() . $file;
  991. } else {
  992. $theme_file = false;
  993. }
  994. if ( ! empty( $theme_file ) ) {
  995. $core_file = $file;
  996. // Update *-product_<cat|tag> template name before searching in core.
  997. if ( false !== strpos( $core_file, '-product_cat' ) || false !== strpos( $core_file, '-product_tag' ) ) {
  998. $core_file = str_replace( '_', '-', $core_file );
  999. }
  1000. $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $core_file );
  1001. $theme_version = WC_Admin_Status::get_file_version( $theme_file );
  1002. if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
  1003. if ( ! $outdated_templates ) {
  1004. $outdated_templates = true;
  1005. }
  1006. }
  1007. $override_files[] = array(
  1008. 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
  1009. 'version' => $theme_version,
  1010. 'core_version' => $core_version,
  1011. );
  1012. }
  1013. }
  1014. $active_theme_info = array(
  1015. 'name' => $active_theme->name,
  1016. 'version' => $active_theme->version,
  1017. 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ),
  1018. 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ),
  1019. 'is_child_theme' => is_child_theme(),
  1020. 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ),
  1021. 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ),
  1022. 'has_outdated_templates' => $outdated_templates,
  1023. 'overrides' => $override_files,
  1024. );
  1025. return array_merge( $active_theme_info, $parent_theme_info );
  1026. }
  1027. /**
  1028. * Get some setting values for the site that are useful for debugging
  1029. * purposes. For full settings access, use the settings api.
  1030. *
  1031. * @return array
  1032. */
  1033. public function get_settings() {
  1034. // Get a list of terms used for product/order taxonomies.
  1035. $term_response = array();
  1036. $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
  1037. foreach ( $terms as $term ) {
  1038. $term_response[ $term->slug ] = strtolower( $term->name );
  1039. }
  1040. // Get a list of terms used for product visibility.
  1041. $product_visibility_terms = array();
  1042. $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) );
  1043. foreach ( $terms as $term ) {
  1044. $product_visibility_terms[ $term->slug ] = strtolower( $term->name );
  1045. }
  1046. // Check if WooCommerce.com account is connected.
  1047. $woo_com_connected = 'no';
  1048. $helper_options = get_option( 'woocommerce_helper_data', array() );
  1049. if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) {
  1050. $woo_com_connected = 'yes';
  1051. }
  1052. // Return array of useful settings for debugging.
  1053. return array(
  1054. 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ),
  1055. 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ),
  1056. 'currency' => get_woocommerce_currency(),
  1057. 'currency_symbol' => get_woocommerce_currency_symbol(),
  1058. 'currency_position' => get_option( 'woocommerce_currency_pos' ),
  1059. 'thousand_separator' => wc_get_price_thousand_separator(),
  1060. 'decimal_separator' => wc_get_price_decimal_separator(),
  1061. 'number_of_decimals' => wc_get_price_decimals(),
  1062. 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ), true ),
  1063. 'taxonomies' => $term_response,
  1064. 'product_visibility_terms' => $product_visibility_terms,
  1065. 'woocommerce_com_connected' => $woo_com_connected,
  1066. );
  1067. }
  1068. /**
  1069. * Returns security tips.
  1070. *
  1071. * @return array
  1072. */
  1073. public function get_security_info() {
  1074. $check_page = wc_get_page_permalink( 'shop' );
  1075. return array(
  1076. 'secure_connection' => 'https' === substr( $check_page, 0, 5 ),
  1077. 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ),
  1078. );
  1079. }
  1080. /**
  1081. * Returns a mini-report on WC pages and if they are configured correctly:
  1082. * Present, visible, and including the correct shortcode or block.
  1083. *
  1084. * @return array
  1085. */
  1086. public function get_pages() {
  1087. // WC pages to check against.
  1088. $check_pages = array(
  1089. _x( 'Shop base', 'Page setting', 'woocommerce' ) => array(
  1090. 'option' => 'woocommerce_shop_page_id',
  1091. 'shortcode' => '',
  1092. 'block' => '',
  1093. ),
  1094. _x( 'Cart', 'Page setting', 'woocommerce' ) => array(
  1095. 'option' => 'woocommerce_cart_page_id',
  1096. 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
  1097. 'block' => 'woocommerce/cart',
  1098. ),
  1099. _x( 'Checkout', 'Page setting', 'woocommerce' ) => array(
  1100. 'option' => 'woocommerce_checkout_page_id',
  1101. 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
  1102. 'block' => 'woocommerce/checkout',
  1103. ),
  1104. _x( 'My account', 'Page setting', 'woocommerce' ) => array(
  1105. 'option' => 'woocommerce_myaccount_page_id',
  1106. 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
  1107. 'block' => '',
  1108. ),
  1109. _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array(
  1110. 'option' => 'woocommerce_terms_page_id',
  1111. 'shortcode' => '',
  1112. 'block' => '',
  1113. ),
  1114. );
  1115. $pages_output = array();
  1116. foreach ( $check_pages as $page_name => $values ) {
  1117. $page_id = get_option( $values['option'] );
  1118. $page_set = false;
  1119. $page_exists = false;
  1120. $page_visible = false;
  1121. $shortcode_present = false;
  1122. $shortcode_required = false;
  1123. $block_present = false;
  1124. $block_required = false;
  1125. // Page checks.
  1126. if ( $page_id ) {
  1127. $page_set = true;
  1128. }
  1129. if ( get_post( $page_id ) ) {
  1130. $page_exists = true;
  1131. }
  1132. if ( 'publish' === get_post_status( $page_id ) ) {
  1133. $page_visible = true;
  1134. }
  1135. // Shortcode checks.
  1136. if ( $values['shortcode'] && get_post( $page_id ) ) {
  1137. $shortcode_required = true;
  1138. $page = get_post( $page_id );
  1139. if ( strstr( $page->post_content, $values['shortcode'] ) ) {
  1140. $shortcode_present = true;
  1141. }
  1142. }
  1143. // Block checks.
  1144. if ( $values['block'] && get_post( $page_id ) ) {
  1145. $block_required = true;
  1146. $block_present = WC_Blocks_Utils::has_block_in_page( $page_id, $values['block'] );
  1147. }
  1148. // Wrap up our findings into an output array.
  1149. $pages_output[] = array(
  1150. 'page_name' => $page_name,
  1151. 'page_id' => $page_id,
  1152. 'page_set' => $page_set,
  1153. 'page_exists' => $page_exists,
  1154. 'page_visible' => $page_visible,
  1155. 'shortcode' => $values['shortcode'],
  1156. 'block' => $values['block'],
  1157. 'shortcode_required' => $shortcode_required,
  1158. 'shortcode_present' => $shortcode_present,
  1159. 'block_present' => $block_present,
  1160. 'block_required' => $block_required,
  1161. );
  1162. }
  1163. return $pages_output;
  1164. }
  1165. /**
  1166. * Get any query params needed.
  1167. *
  1168. * @return array
  1169. */
  1170. public function get_collection_params() {
  1171. return array(
  1172. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  1173. );
  1174. }
  1175. /**
  1176. * Prepare the system status response
  1177. *
  1178. * @param array $system_status System status data.
  1179. * @param WP_REST_Request $request Request object.
  1180. * @return WP_REST_Response
  1181. */
  1182. public function prepare_item_for_response( $system_status, $request ) {
  1183. $data = $this->add_additional_fields_to_object( $system_status, $request );
  1184. $data = $this->filter_response_by_context( $data, 'view' );
  1185. $response = rest_ensure_response( $data );
  1186. /**
  1187. * Filter the system status returned from the REST API.
  1188. *
  1189. * @param WP_REST_Response $response The response object.
  1190. * @param mixed $system_status System status
  1191. * @param WP_REST_Request $request Request object.
  1192. */
  1193. return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request );
  1194. }
  1195. }