265 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * Plugin initialization file.
 | 
						|
 *
 | 
						|
 * @link      https://github.com/googleforcreators/web-stories-wp
 | 
						|
 *
 | 
						|
 * @copyright 2020 Google LLC
 | 
						|
 * @license   https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * Copyright 2020 Google LLC
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     https://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
declare(strict_types = 1);
 | 
						|
 | 
						|
namespace Google\Web_Stories;
 | 
						|
 | 
						|
use WP_Error;
 | 
						|
use WP_REST_Request;
 | 
						|
use WP_Site;
 | 
						|
 | 
						|
/**
 | 
						|
 * Handles plugin activation.
 | 
						|
 *
 | 
						|
 * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
 | 
						|
 *
 | 
						|
 * @since 1.0.0
 | 
						|
 *
 | 
						|
 * @param bool $network_wide Whether to activate network-wide.
 | 
						|
 */
 | 
						|
function activate( ?bool $network_wide = false ): void {
 | 
						|
	$network_wide = (bool) $network_wide;
 | 
						|
 | 
						|
	// Runs all PluginActivationAware services.
 | 
						|
	// This will also flush rewrite rules.
 | 
						|
	PluginFactory::create()->on_plugin_activation( $network_wide );
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Fires after plugin activation.
 | 
						|
	 *
 | 
						|
	 * @param bool $network_wide Whether to activate network-wide.
 | 
						|
	 */
 | 
						|
	do_action( 'web_stories_activation', $network_wide );
 | 
						|
}
 | 
						|
 | 
						|
register_activation_hook( WEBSTORIES_PLUGIN_FILE, __NAMESPACE__ . '\activate' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Hook into new site creation on Multisite.
 | 
						|
 *
 | 
						|
 * @since 1.0.0
 | 
						|
 *
 | 
						|
 * @param int|WP_Site $site Site ID or object.
 | 
						|
 */
 | 
						|
function new_site( $site ): void {
 | 
						|
	if ( ! is_multisite() ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	$site = get_site( $site );
 | 
						|
 | 
						|
	if ( ! $site ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// Runs all SiteInitializationAware services.
 | 
						|
	// This will also flush rewrite rules.
 | 
						|
	PluginFactory::create()->on_site_initialization( $site );
 | 
						|
}
 | 
						|
 | 
						|
add_action( 'wp_initialize_site', __NAMESPACE__ . '\new_site', PHP_INT_MAX );
 | 
						|
 | 
						|
/**
 | 
						|
 * Hook into site removal on Multisite.
 | 
						|
 *
 | 
						|
 * @since 1.1.0
 | 
						|
 *
 | 
						|
 * @param WP_Error    $error Unused.
 | 
						|
 * @param int|WP_Site $site Site ID or object.
 | 
						|
 */
 | 
						|
function remove_site( WP_Error $error, $site ): void {
 | 
						|
	if ( ! is_multisite() ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	$site = get_site( $site );
 | 
						|
 | 
						|
	if ( ! $site ) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	PluginFactory::create()->on_site_removal( $site );
 | 
						|
}
 | 
						|
 | 
						|
add_action( 'wp_validate_site_deletion', __NAMESPACE__ . '\remove_site', PHP_INT_MAX, 2 );
 | 
						|
 | 
						|
/**
 | 
						|
 * Handles plugin deactivation.
 | 
						|
 *
 | 
						|
 * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
 | 
						|
 *
 | 
						|
 * @since 1.0.0
 | 
						|
 *
 | 
						|
 * @param bool $network_wide Whether to deactivate network-wide.
 | 
						|
 */
 | 
						|
function deactivate( ?bool $network_wide = false ): void {
 | 
						|
	$network_wide = (bool) $network_wide;
 | 
						|
 | 
						|
	// Runs all PluginDeactivationAware services.
 | 
						|
	// This will also flush rewrite rules.
 | 
						|
	PluginFactory::create()->on_plugin_deactivation( $network_wide );
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Fires after plugin deactivation.
 | 
						|
	 *
 | 
						|
	 * @param bool $network_wide Whether to deactivate network-wide.
 | 
						|
	 */
 | 
						|
	do_action( 'web_stories_deactivation', $network_wide );
 | 
						|
}
 | 
						|
 | 
						|
register_deactivation_hook( WEBSTORIES_PLUGIN_FILE, __NAMESPACE__ . '\deactivate' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Initializes functionality to improve compatibility with the AMP plugin.
 | 
						|
 *
 | 
						|
 * Loads a separate PHP file that allows defining functions in the global namespace.
 | 
						|
 *
 | 
						|
 * Runs on the 'wp' hook to ensure the WP environment has been fully set up,
 | 
						|
 */
 | 
						|
function load_amp_plugin_compat(): void {
 | 
						|
	require_once WEBSTORIES_PLUGIN_DIR_PATH . 'includes/compat/amp.php';
 | 
						|
}
 | 
						|
 | 
						|
add_action( 'wp', __NAMESPACE__ . '\load_amp_plugin_compat' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Load functions for use by plugin developers.
 | 
						|
 *
 | 
						|
 * @todo Move to autoloader
 | 
						|
 */
 | 
						|
function load_functions(): void {
 | 
						|
	require_once WEBSTORIES_PLUGIN_DIR_PATH . 'includes/functions.php';
 | 
						|
}
 | 
						|
 | 
						|
add_action( 'init', __NAMESPACE__ . '\load_functions' );
 | 
						|
 | 
						|
/**
 | 
						|
 * Append result of internal request to REST API for purpose of preloading data to be attached to a page.
 | 
						|
 * Expected to be called in the context of `array_reduce`.
 | 
						|
 *
 | 
						|
 * Like rest_preload_api_request() in core, but embeds links and removes trailing slashes.
 | 
						|
 *
 | 
						|
 * @SuppressWarnings(PHPMD.NPathComplexity)
 | 
						|
 *
 | 
						|
 * @since 1.2.0
 | 
						|
 *
 | 
						|
 * @link https://core.trac.wordpress.org/ticket/51722
 | 
						|
 * @link https://core.trac.wordpress.org/ticket/51636
 | 
						|
 * @see \rest_preload_api_request
 | 
						|
 *
 | 
						|
 * @param array<string, array{body: string, headers: array<string,string>}|array<string, array{body: string, headers: array<string,string>}>> $memo Reduce accumulator.
 | 
						|
 * @param string|array<int, string>                                                                                                           $path REST API path to preload.
 | 
						|
 * @return array<string, array{body: string, headers: array<string,string>}|array<string, array{body: string, headers: array<string,string>}>> Modified reduce accumulator.
 | 
						|
 */
 | 
						|
function rest_preload_api_request( array $memo, $path ): array {
 | 
						|
	if ( empty( $path ) ) {
 | 
						|
		return $memo;
 | 
						|
	}
 | 
						|
 | 
						|
	$method = 'GET';
 | 
						|
	if ( \is_array( $path ) ) {
 | 
						|
		if ( 2 !== \count( $path ) ) {
 | 
						|
			return $memo;
 | 
						|
		}
 | 
						|
 | 
						|
		$method = end( $path );
 | 
						|
		$path   = (string) reset( $path );
 | 
						|
 | 
						|
		if ( ! \in_array( $method, [ 'GET', 'OPTIONS' ], true ) ) {
 | 
						|
			$method = 'GET';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * URL parts.
 | 
						|
	 *
 | 
						|
	 * @var array{path:string, query?: string}|false $path_parts
 | 
						|
	 */
 | 
						|
	$path_parts = wp_parse_url( (string) $path );
 | 
						|
	if ( ! \is_array( $path_parts ) ) {
 | 
						|
		return $memo;
 | 
						|
	}
 | 
						|
 | 
						|
	// This line is different from code. Adds untrailingslashit. See https://core.trac.wordpress.org/ticket/57048.
 | 
						|
	$request = new WP_REST_Request( $method, untrailingslashit( $path_parts['path'] ) );
 | 
						|
	if ( ! empty( $path_parts['query'] ) ) {
 | 
						|
		$query_params = [];
 | 
						|
		parse_str( $path_parts['query'], $query_params );
 | 
						|
		$request->set_query_params( $query_params );
 | 
						|
	}
 | 
						|
 | 
						|
	$response = rest_do_request( $request );
 | 
						|
	if ( 200 === $response->status ) {
 | 
						|
		$server = rest_get_server();
 | 
						|
		/**
 | 
						|
		 * Embed directive.
 | 
						|
		 *
 | 
						|
		 * @var string|string[] $embed
 | 
						|
		 */
 | 
						|
		$embed = $request['_embed'] ?? false;
 | 
						|
		$embed = $embed ? rest_parse_embed_param( $embed ) : false;
 | 
						|
		$data  = $server->response_to_data( $response, $embed );
 | 
						|
 | 
						|
		if ( 'OPTIONS' === $method ) {
 | 
						|
			$response = rest_send_allow_header( $response, $server, $request );
 | 
						|
 | 
						|
			$memo[ $method ][ $path ] = [
 | 
						|
				'body'    => $data,
 | 
						|
				'headers' => $response->headers,
 | 
						|
			];
 | 
						|
		} else {
 | 
						|
			$memo[ $path ] = [
 | 
						|
				'body'    => $data,
 | 
						|
				'headers' => $response->headers,
 | 
						|
			];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return $memo;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Returns the Web stories plugin instance.
 | 
						|
 *
 | 
						|
 * Can be used by other plugins to integrate with the plugin
 | 
						|
 * or to simply detect whether the plugin is active.
 | 
						|
 */
 | 
						|
function get_plugin_instance(): Plugin {
 | 
						|
	return PluginFactory::create();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Bootstrap the plugin.
 | 
						|
 *
 | 
						|
 * @since 1.11.0
 | 
						|
 */
 | 
						|
function bootstrap_plugin(): void {
 | 
						|
	PluginFactory::create()->register();
 | 
						|
}
 | 
						|
 | 
						|
add_action( 'plugins_loaded', __NAMESPACE__ . '\bootstrap_plugin' );
 |