You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
6.8 KiB
PHTML

<?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' );