JezK
Edit File: AccelerateWpCdn.php
<?php /** * Copyright (с) Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2023 All Rights Reserved */ namespace WP_Rocket\Cli; use Exception; use WP_CLI; /** * AccelerateWp CDN CLI commands. * * Thin CLI layer that delegates to CDN classes via do_action hooks. */ class AccelerateWpCdn { use AccelerateWpCliTrait; /** * CDN-specific validation for CLOS mode. * * @param array $assoc_args Associative arguments. * @param bool $check_api_key Whether to require api_key. * * @return array Validated CDN parameters. * @throws Exception When validation fails. */ private function validation( $assoc_args = [], $check_api_key = false ) { $account_id = array_key_exists( 'account_id', $assoc_args ) ? sanitize_text_field( wp_unslash( $assoc_args['account_id'] ) ) : 0; $cdn_url = array_key_exists( 'cdn_url', $assoc_args ) ? sanitize_text_field( wp_unslash( $assoc_args['cdn_url'] ) ) : ''; $api_key = array_key_exists( 'api_key', $assoc_args ) ? sanitize_text_field( wp_unslash( $assoc_args['api_key'] ) ) : ''; if ( empty( $account_id ) ) { throw new Exception( '--account_id is empty' ); } elseif ( empty( $cdn_url ) || is_numeric( $cdn_url ) ) { throw new Exception( '--cdn_url is empty' ); } elseif ( ! filter_var( $cdn_url, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME ) ) { throw new Exception( '--cdn_url is not valid domain, don\'t pass protocol' ); } elseif ( empty( $api_key ) && $check_api_key ) { throw new Exception( '--api_key is empty' ); } return [ 'account_id' => (int) $account_id, 'cdn_url' => $cdn_url, 'api_key' => $api_key, ]; } /** * CDN activate. * * For Standalone: Creates pullzone via SaaS API. * For CLOS: Uses provided CDN URL from hosting panel. * * @param array $args Positional arguments. * @param array $assoc_args Associative arguments. * * @return void * @throws Exception Something went wrong. */ private function enable( $args = [], $assoc_args = [] ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed try { // Standalone mode: create pullzone via SaaS API. if ( clsop_is_standalone() ) { $this->validate_cli_args( $assoc_args ); WP_CLI::log( 'Creating CDN pullzone via SaaS API...' ); $result = apply_filters( 'rocketcdn_standalone_cdn_enable', [] ); if ( empty( $result['success'] ) ) { throw new Exception( $result['message'] ?? 'Failed to enable CDN' ); } // Wait for pullzone to be ready. $cdn_domain = wp_parse_url( $result['cdn_url'], PHP_URL_HOST ); if ( $cdn_domain ) { $this->await_pull_zone( $cdn_domain ); } WP_CLI::success( 'CDN enabled: ' . $result['cdn_url'] ); return; } // CLOS mode: use provided CDN URL. $validated = $this->validation( $assoc_args, true ); $this->await_pull_zone( $validated['cdn_url'] ); do_action( 'rocketcdn_accelerate_wp_cli_cdn_enable', $validated['account_id'], $validated['cdn_url'], $validated['api_key'] ); if ( ! array_key_exists( 'skip-check', $assoc_args ) ) { $this->check( $args, $assoc_args ); } WP_CLI::success( 'Enabled.' ); } catch ( Exception $e ) { $code = $e->getCode() > 0 ? $e->getCode() : 1; WP_CLI::error( $e->getMessage(), $code ); } } /** * CDN deactivate. * * For Standalone: Deletes pullzone via SaaS API. * For CLOS: Just disables CDN locally. * * @param array $args Positional arguments. * @param array $assoc_args Associative arguments. * * @return void * @throws Exception Something went wrong. */ private function disable( $args = [], $assoc_args = [] ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed try { // Standalone mode: delete pullzone via SaaS API. if ( clsop_is_standalone() ) { WP_CLI::log( 'Deleting CDN pullzone via SaaS API...' ); $result = apply_filters( 'rocketcdn_standalone_cdn_disable', [] ); if ( empty( $result['success'] ) ) { throw new Exception( $result['message'] ?? 'Failed to disable CDN' ); } WP_CLI::success( 'CDN disabled.' ); return; } // CLOS mode: just disable locally. do_action( 'rocketcdn_accelerate_wp_cli_cdn_disable' ); WP_CLI::success( 'Disabled.' ); } catch ( Exception $e ) { $code = $e->getCode() > 0 ? $e->getCode() : 1; WP_CLI::error( $e->getMessage(), $code ); } } /** * CDN post-check. * * @param array $args Positional arguments. * @param array $assoc_args Associative arguments. * * @return void * @throws Exception Something went wrong. */ private function check( $args = [], $assoc_args = [] ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed try { // For Standalone, check CDN status via action. if ( clsop_is_standalone() ) { $status = apply_filters( 'rocketcdn_standalone_cdn_status', [] ); if ( empty( $status['enabled'] ) ) { WP_CLI::warning( 'CDN is not enabled.' ); return; } WP_CLI::success( 'CDN is enabled: ' . $status['cdn_url'] ); return; } // CLOS mode: use original validation. $validated = $this->validation( $assoc_args ); $checker = new AccelerateWpCdnCheck( $validated['account_id'], $validated['cdn_url'] ); if ( false === $checker->check() ) { $checker->report(); $reason = $checker->reason(); WP_CLI::error( 'Post-check failed: ' . $reason ); } } catch ( Exception $e ) { $code = $e->getCode() > 0 ? $e->getCode() : 1; WP_CLI::error( 'Post-check failed: ' . $e->getMessage(), $code ); } } /** * CDN cache purge. * * @param array $args Positional arguments. * @param array $assoc_args Associative arguments. * * @return void * @throws Exception Something went wrong. */ private function purge( $args = [], $assoc_args = [] ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed try { WP_CLI::log( 'Purging CDN cache...' ); $result = apply_filters( 'rocketcdn_cli_cdn_purge', [] ); if ( 'success' === $result['status'] ) { WP_CLI::success( $result['message'] ); } else { WP_CLI::error( $result['message'] ); } } catch ( Exception $e ) { $code = $e->getCode() > 0 ? $e->getCode() : 1; WP_CLI::error( $e->getMessage(), $code ); } } /** * Await pull zone to be ready. * * @param string $cdn_url PullZone URL. * * @return void */ private function await_pull_zone( $cdn_url ) { for ( $i = 0; $i < 5; $i++ ) { $response = wp_remote_get( 'https://' . $cdn_url, [ 'timeout' => 4, ] ); if ( false === is_wp_error( $response ) ) { break; } elseif ( false === strpos( $response->get_error_message(), 'SSL' ) ) { break; } sleep( 2 ); } } }