PluginProbe
WPGraphQL / 2.22.0
WPGraphQL v2.22.0
2.22.3 2.22.2 2.22.1 2.22.0 2.21.1 2.21.0 2.20.0 2.19.0 2.18.0 2.17.0 2.16.0 2.15.1 2.15.0 2.14.1 2.14.0 2.13.0 2.2.0 2.3.0 2.3.3 2.3.6 2.3.8 2.5.0 2.5.1 2.5.2 2.5.3 All 177 releases
wp-graphql / wp-graphql.php

wp-graphql.php in WPGraphQL 2.22.0, at wp-graphql.php

236 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: WPGraphQL
4 * Plugin URI: https://github.com/wp-graphql/wp-graphql
5 * Description: GraphQL API for WordPress
6 * Author: WPGraphQL
7 * Author URI: http://www.wpgraphql.com
8 * Version: 2.22.0
9 * Text Domain: wp-graphql
10 * Domain Path: /languages/
11 * Requires at least: 6.0
12 * Tested up to: 7.0
13 * Requires PHP: 7.4
14 * License: GPL-3
15 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
16 *
17 * @package WPGraphQL
18 * @category Core
19 * @author WPGraphQL
20 * @version 2.22.0
21 */
22
23 // Exit if accessed directly.
24 if ( ! defined( 'ABSPATH' ) ) {
25 exit;
26 }
27
28 // If the codeception remote coverage file exists, require it.
29 // This file should only exist locally or when CI bootstraps the environment for testing
30 if ( file_exists( __DIR__ . '/c3.php' ) ) {
31 require_once __DIR__ . '/c3.php';
32 }
33
34 /**
35 * Load files that are required even if the composer autoloader isn't installed
36 */
37 function graphql_require_bootstrap_files(): void {
38 if ( file_exists( __DIR__ . '/constants.php' ) ) {
39 require_once __DIR__ . '/constants.php';
40 }
41 if ( file_exists( __DIR__ . '/activation.php' ) ) {
42 require_once __DIR__ . '/activation.php';
43 }
44 if ( file_exists( __DIR__ . '/deactivation.php' ) ) {
45 require_once __DIR__ . '/deactivation.php';
46 }
47 if ( file_exists( __DIR__ . '/access-functions.php' ) ) {
48 require_once __DIR__ . '/access-functions.php';
49 }
50 if ( file_exists( __DIR__ . '/src/WPGraphQL.php' ) ) {
51 require_once __DIR__ . '/src/WPGraphQL.php';
52 }
53 }
54
55 /**
56 * Determines if the plugin can load.
57 *
58 * Test env:
59 * - WPGRAPHQL_AUTOLOAD: false
60 * - autoload installed and manually added in test env
61 *
62 * Bedrock
63 * - WPGRAPHQL_AUTOLOAD: not defined
64 * - composer deps installed outside the plugin
65 *
66 * Normal (.org repo install)
67 * - WPGRAPHQL_AUTOLOAD: not defined
68 * - composer deps installed INSIDE the plugin
69 */
70 function graphql_can_load_plugin(): bool {
71
72 // Load the bootstrap files (needed before autoloader is configured)
73 graphql_require_bootstrap_files();
74
75 // If GraphQL\GraphQL and WPGraphQL are both already loaded,
76 // We can assume that WPGraphQL has been installed as a composer dependency of a parent project
77 if ( class_exists( 'GraphQL\GraphQL' ) && class_exists( 'WPGraphQL' ) ) {
78 return true;
79 }
80
81 /**
82 * WPGRAPHQL_AUTOLOAD can be set to "false" to prevent the autoloader from running.
83 * In most cases, this is not something that should be disabled, but some environments
84 * may bootstrap their dependencies in a global autoloader that will autoload files
85 * before we get to this point, and requiring the autoloader again can trigger fatal errors.
86 *
87 * The codeception tests are an example of an environment where adding the autoloader again causes issues
88 * so this is set to false for tests.
89 */
90 if ( defined( 'WPGRAPHQL_AUTOLOAD' ) && false === WPGRAPHQL_AUTOLOAD ) {
91
92 // IF WPGRAPHQL_AUTOLOAD is defined as false,
93 // but the WPGraphQL Class exists, we can assume the dependencies
94 // are loaded from the parent project.
95 return true;
96 }
97
98 if ( file_exists( plugin_dir_path( __FILE__ ) . 'vendor/autoload.php' ) ) {
99 // Autoload Required Classes.
100 require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
101 }
102
103 // If the GraphQL class still doesn't exist, bail as there was an issue bootstrapping the plugin
104 if ( ! class_exists( 'GraphQL\GraphQL' ) || ! class_exists( 'WPGraphQL' ) ) {
105 return false;
106 }
107
108 return true;
109 }
110
111 if ( ! function_exists( 'graphql_init' ) ) {
112 /**
113 * Function that instantiates the plugins main class
114 *
115 * @return object|null
116 */
117 function graphql_init() {
118
119 // if the plugin can't be loaded, bail
120 if ( false === graphql_can_load_plugin() ) {
121 add_action( 'network_admin_notices', 'graphql_cannot_load_admin_notice_callback' );
122 add_action( 'admin_notices', 'graphql_cannot_load_admin_notice_callback' );
123 return null;
124 }
125
126 /**
127 * Return an instance of the action
128 */
129 return \WPGraphQL::instance();
130 }
131 }
132 graphql_init();
133
134 // Run this function when WPGraphQL is de-activated
135 register_deactivation_hook( __FILE__, 'graphql_deactivation_callback' );
136 register_activation_hook( __FILE__, 'graphql_activation_callback' );
137
138 /**
139 * Render an admin notice if the plugin cannot load
140 */
141 function graphql_cannot_load_admin_notice_callback(): void {
142 if ( ! current_user_can( 'manage_options' ) ) {
143 return;
144 }
145
146 printf(
147 '<div class="notice notice-error">' .
148 '<p>%s</p>' .
149 '</div>',
150 esc_html__( 'WPGraphQL appears to have been installed without it\'s dependencies. It will not work properly until dependencies are installed. This likely means you have cloned WPGraphQL from Github and need to run the command `composer install`.', 'wp-graphql' )
151 );
152 }
153
154 /**
155 * Initialize the plugin tracker.
156 */
157 function graphql_init_appsero_telemetry(): void {
158 // If the class doesn't exist, or code is being scanned by PHPSTAN, move on.
159 if ( ! class_exists( 'Appsero\Client' ) || defined( 'PHPSTAN' ) ) {
160 return;
161 }
162
163 // Wrap the Appsero client in a try/catch block to prevent fatal errors
164 try {
165 $client = new \Appsero\Client( 'cd0d1172-95a0-4460-a36a-2c303807c9ef', 'WPGraphQL', __FILE__ );
166
167 /**
168 * @var \Appsero\Insights $insights
169 *
170 * @phpstan-ignore varTag.type (The doctype for Appsero\Client::insights() is wrong.)
171 */
172 $insights = $client->insights();
173
174 // If the Appsero client has the add_plugin_data method, use it
175 if ( method_exists( $insights, 'add_plugin_data' ) ) {
176 $insights->add_plugin_data();
177 }
178
179 $insights->init();
180 } catch ( \Throwable $e ) {
181 error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Error logging is intentional here.
182 sprintf(
183 // translators: %s is the error message
184 __( 'Error initializing Appsero: %s', 'wp-graphql' ),
185 $e->getMessage()
186 )
187 );
188 }
189 }
190
191 graphql_init_appsero_telemetry();
192
193 /**
194 * Mirror the Appsero API requests to our own telemetry server.
195 *
196 * @param bool|\WP_Error $preempt Whether to preempt the request.
197 * @param array $args The arguments for the request.
198 * @param string $url The URL for the request.
199 * @return bool|\WP_Error Whether to preempt the request.
200 */
201 add_filter(
202 'pre_http_request',
203 static function ( $preempt, $args, $url ) {
204 if ( strpos( $url, 'api.appsero.com' ) === false ) {
205 return $preempt;
206 }
207
208 // Scope: only mirror this plugin's payloads, not other Appsero plugins on the site.
209 $body = is_array( $args['body'] ?? null ) ? $args['body'] : [];
210 if ( ( $body['hash'] ?? null ) !== 'cd0d1172-95a0-4460-a36a-2c303807c9ef' ) {
211 return $preempt;
212 }
213
214 $mirror = str_replace(
215 'https://api.appsero.com/',
216 'https://telemetry.wpgraphql.com/api/appsero/',
217 $url
218 );
219
220 wp_remote_post(
221 $mirror,
222 array_merge(
223 $args,
224 [
225 'blocking' => false,
226 'timeout' => 3,
227 ]
228 )
229 );
230
231 return $preempt; // let the real Appsero request proceed
232 },
233 10,
234 3
235 );
236