PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.2
Jetpack – WP Security, Backup, Speed, & Growth v16.2
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
jetpack / jetpack_vendor / automattic / jetpack-waf / src / class-waf-standalone-bootstrap.php

class-waf-standalone-bootstrap.php in Jetpack – WP Security, Backup, Speed, & Growth 16.2, at jetpack_vendor/automattic/jetpack-waf/src/class-waf-standalone-bootstrap.php

185 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles generation and deletion of the bootstrap for the standalone WAF mode.
4 *
5 * @package automattic/jetpack-waf
6 */
7
8 namespace Automattic\Jetpack\Waf;
9
10 use Composer\InstalledVersions;
11
12 /**
13 * Handles the bootstrap.
14 *
15 * @phan-constructor-used-for-side-effects
16 */
17 class Waf_Standalone_Bootstrap {
18
19 /**
20 * Ensures that constants are initialized if this class is used.
21 *
22 * @return void
23 */
24 public function __construct() {
25 $this->guard_against_missing_abspath();
26 $this->initialize_constants();
27 }
28
29 /**
30 * Ensures that this class is not used unless we are in the right context.
31 *
32 * @throws Waf_Exception If we are outside of WordPress.
33 *
34 * @return void
35 */
36 private function guard_against_missing_abspath() {
37
38 if ( ! defined( 'ABSPATH' ) ) {
39 throw new Waf_Exception( 'Cannot generate the WAF bootstrap if we are not running in WordPress context.' );
40 }
41 }
42
43 /**
44 * Initializes the constants required for generating the bootstrap, if they have not been initialized yet.
45 *
46 * @return void
47 */
48 private function initialize_constants() {
49 Waf_Constants::initialize_constants();
50 }
51
52 /**
53 * Initialized the WP filesystem and serves as a mocking hook for tests.
54 *
55 * Should only be implemented after the wp_loaded action hook:
56 *
57 * @link https://developer.wordpress.org/reference/functions/wp_filesystem/#more-information
58 *
59 * @return void
60 */
61 protected function initialize_filesystem() {
62 if ( ! function_exists( '\\WP_Filesystem' ) ) {
63 require_once ABSPATH . 'wp-admin/includes/file.php';
64 }
65
66 WP_Filesystem();
67 }
68
69 /**
70 * Finds the path to the autoloader, which can then be used to require the autoloader in the generated boostrap file.
71 *
72 * @throws Waf_Exception In case the autoloader file cannot be found.
73 *
74 * @return string|null
75 */
76 private function locate_autoloader_file() {
77 global $jetpack_autoloader_loader;
78
79 $autoload_file = null;
80
81 // Try the Jetpack autoloader.
82 if ( isset( $jetpack_autoloader_loader ) ) {
83 $class_file = $jetpack_autoloader_loader->find_class_file( Waf_Runner::class );
84 if ( $class_file ) {
85 $autoload_file = dirname( $class_file, 5 ) . '/vendor/autoload.php';
86 }
87 }
88
89 // Try Composer's autoloader.
90 if ( null === $autoload_file
91 && is_callable( array( InstalledVersions::class, 'getInstallPath' ) )
92 && InstalledVersions::isInstalled( 'automattic/jetpack-waf' )
93 ) {
94 $package_file = InstalledVersions::getInstallPath( 'automattic/jetpack-waf' );
95 if ( substr( $package_file, -23 ) === '/automattic/jetpack-waf' ) {
96 $autoload_file = dirname( $package_file, 3 ) . '/vendor/autoload.php';
97 }
98 }
99
100 // Guess. First look for being in a `vendor/automattic/jetpack-waf/src/', then see if we're standalone with our own vendor dir.
101 if ( null === $autoload_file ) {
102 $autoload_file = dirname( __DIR__, 4 ) . '/vendor/autoload.php';
103 if ( ! file_exists( $autoload_file ) ) {
104 $autoload_file = dirname( __DIR__ ) . '/vendor/autoload.php';
105 }
106 }
107
108 // Check that the determined file actually exists.
109 if ( ! file_exists( $autoload_file ) ) {
110 throw new Waf_Exception( 'Cannot find autoloader, and the WAF standalone boostrap will not work without it.' );
111 }
112
113 return $autoload_file;
114 }
115
116 /**
117 * Gets the path to the bootstrap.php file.
118 *
119 * @return string The bootstrap.php file path.
120 */
121 public function get_bootstrap_file_path() {
122 return trailingslashit( JETPACK_WAF_DIR ) . 'bootstrap.php';
123 }
124
125 /**
126 * Gets the entrypoint file.
127 *
128 * @return string The entrypoint file.
129 */
130 private function get_entrypoint() {
131 return defined( 'JETPACK_WAF_ENTRYPOINT' ) ? JETPACK_WAF_ENTRYPOINT : 'rules/rules.php';
132 }
133
134 /**
135 * Generates the bootstrap file.
136 *
137 * @throws File_System_Exception If the filesystem is not available.
138 * @throws File_System_Exception If the WAF directory cannot be created.
139 * @throws File_System_Exception If the bootstrap file cannot be created.
140 *
141 * @return string Absolute path to the bootstrap file.
142 */
143 public function generate() {
144
145 $this->initialize_filesystem();
146
147 global $wp_filesystem;
148 if ( ! $wp_filesystem ) {
149 throw new File_System_Exception( 'Cannot work without the file system being initialized.' );
150 }
151
152 $autoloader_file = $this->locate_autoloader_file();
153
154 $bootstrap_file = $this->get_bootstrap_file_path();
155 $entrypoint = $this->get_entrypoint();
156 $mode_option = get_option( Waf_Runner::MODE_OPTION_NAME, false );
157 $share_data_option = get_option( Waf_Runner::SHARE_DATA_OPTION_NAME, false );
158 $share_debug_data_option = get_option( Waf_Runner::SHARE_DEBUG_DATA_OPTION_NAME, false );
159
160 $code = "<?php\n"
161 . sprintf( "define( 'DISABLE_JETPACK_WAF', %s );\n", var_export( defined( 'DISABLE_JETPACK_WAF' ) && DISABLE_JETPACK_WAF, true ) )
162 . "if ( defined( 'DISABLE_JETPACK_WAF' ) && DISABLE_JETPACK_WAF ) return;\n"
163 . sprintf( "define( 'JETPACK_WAF_MODE', %s );\n", var_export( $mode_option ? $mode_option : 'silent', true ) )
164 . sprintf( "define( 'JETPACK_WAF_SHARE_DATA', %s );\n", var_export( $share_data_option, true ) )
165 . sprintf( "define( 'JETPACK_WAF_SHARE_DEBUG_DATA', %s );\n", var_export( $share_debug_data_option, true ) )
166 . sprintf( "define( 'JETPACK_WAF_DIR', %s );\n", var_export( JETPACK_WAF_DIR, true ) )
167 . sprintf( "define( 'JETPACK_WAF_WPCONFIG', %s );\n", var_export( JETPACK_WAF_WPCONFIG, true ) )
168 . sprintf( "define( 'JETPACK_WAF_ENTRYPOINT', %s );\n", var_export( $entrypoint, true ) )
169 . 'require_once ' . var_export( $autoloader_file, true ) . ";\n"
170 . "Automattic\Jetpack\Waf\Waf_Runner::initialize();\n";
171
172 if ( ! $wp_filesystem->is_dir( JETPACK_WAF_DIR ) ) {
173 if ( ! $wp_filesystem->mkdir( JETPACK_WAF_DIR ) ) {
174 throw new File_System_Exception( 'Failed creating WAF standalone bootstrap file directory: ' . JETPACK_WAF_DIR );
175 }
176 }
177
178 if ( ! $wp_filesystem->put_contents( $bootstrap_file, $code ) ) {
179 throw new File_System_Exception( 'Failed writing WAF standalone bootstrap file to: ' . $bootstrap_file );
180 }
181
182 return $bootstrap_file;
183 }
184 }
185