Skip to content

Commit

Permalink
Merge pull request #1286 from greenpeace/cache-clear-command
Browse files Browse the repository at this point in the history
PLANET-5870: Cache clear command
  • Loading branch information
Inwerpsel authored Feb 5, 2021
2 parents 907d282 + b451af8 commit 5cfd476
Show file tree
Hide file tree
Showing 8 changed files with 303 additions and 38 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ jobs:
JIRA_USERNAME=planet4 python /home/circleci/book-test-instance.py \
--pr-url $(cat /tmp/workspace/pr) \
--results /tmp/workspace/booking.json >/tmp/workspace/test-instance
echo "https://app.circleci.com/pipelines/github/greenpeace/planet4-test-$(cat /tmp/workspace/test-instance)/"
- run: activate-gcloud-account.sh
- run:
name: "Put zip in cloud storage"
Expand Down
27 changes: 27 additions & 0 deletions src/Commands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Commands.
*/

namespace P4\MasterTheme;

use P4\MasterTheme\Commands\CloudflarePurge;
use P4\MasterTheme\Commands\RunActivator;
use P4\MasterTheme\Commands\SaveCloudflareKey;

/**
* Class with a static function just because PHP can't autoload functions.
*/
class Commands {
/**
* Add some WP_CLI commands if we're in CLI.
*/
public static function load() {
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}
RunActivator::register();
SaveCloudflareKey::register();
CloudflarePurge::register();
}
}
122 changes: 122 additions & 0 deletions src/Commands/CloudflarePurge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

namespace P4\MasterTheme\Commands;

use CF\Integration\DefaultConfig;
use CF\Integration\DefaultIntegration;
use CF\Integration\DefaultLogger;
use CF\WordPress\DataStore;
use CF\WordPress\WordPressAPI;
use CF\WordPress\WordPressClientAPI;
use P4\MasterTheme\Features;
use WP_CLI;

/**
* Class CloudflarePurge
*/
class CloudflarePurge extends Command {

/**
* The name to access the command.
*
* @return string The command name.
*/
protected static function get_name(): string {
return 'p4-cf-purge';
}

/**
* The description shown in the argument's help.
*
* @return string The description text.
*/
protected static function get_short_description(): string {
return 'Purge urls from Cloudflare cache';
}

/**
* The logic of the command. Has WP_CLI command signature.
*
* @param array|null $args Positional arguments.
* @param array|null $assoc_args Named arguments.
*/
public static function execute( ?array $args, ?array $assoc_args ): void {
if ( ! Features::is_active( Features::CLOUDFLARE_DEPLOY_PURGE ) ) {
WP_CLI::warning( 'Purge on deploy is not enabled, not purging.' );

return;
}

if ( ! defined( 'CLOUDFLARE_PLUGIN_DIR' ) ) {
define( 'CLOUDFLARE_PLUGIN_DIR', WP_PLUGIN_DIR . '/cloudflare/' );
}
require_once CLOUDFLARE_PLUGIN_DIR . 'vendor/autoload.php';

// The following is just a copy of the plugin's dependency chain, can probably be improved.
$config = new DefaultConfig( file_get_contents( CLOUDFLARE_PLUGIN_DIR . 'config.json', true ) );
$logger = new DefaultLogger( $config->getValue( 'debug' ) );
$data_store = new DataStore( $logger );
$integration_api = new WordPressAPI( $data_store );
$integration = new DefaultIntegration( $config, $integration_api, $data_store, $logger );
$api = new WordPressClientAPI( $integration );

$zone_id = $api->getZoneTag( get_option( 'cloudflare_cached_domain_name' ) );

$urls = self::get_urls( $assoc_args );
WP_CLI::log( 'About to purge ' . count( $urls ) . ' urls.' );

// 30 is Cloudflare's purge api limit.
$chunks = array_chunk( $urls, 30 );

foreach ( $chunks as $i => $chunk ) {
// We only use $i to be human readable, increment it immediately.
++ $i;

$ok = $api->zonePurgeFiles( $zone_id, $chunk );
// It's unlikely that only some of the chunks will fail, as Cloudflare's API responds with success
// for any url, even if on non-existent domains. Giving a warning per chunk anyway, just in case.
if ( ! $ok ) {
$joined = implode( $chunk, "\n" );
WP_CLI::warning( "Chunk $i failed, one or more of these didn't work out: \n$joined" );
}
}
}

/**
* Determine which urls to purge. Throws error if right args were not passed.
*
* @param array|null $assoc_args The named args passed to the command.
*
* @throws \RuntimeException If you don't provide the right args.
*
* @return array The urls to purge
*/
private static function get_urls( ?array $assoc_args ): array {
if ( isset( $assoc_args['urls'] ) ) {
return explode( ',', $assoc_args['urls'] );
}

if ( isset( $assoc_args['all'] ) ) {
$post_types = isset( $assoc_args['post-types'] )
? explode( ',', $assoc_args['post-types'] )
: [
'post',
'page',
'campaign',
];
$query_args = [
'post_type' => $post_types,
'posts_per_page' => - 1,
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'fields' => 'ids',
];

$ids = get_posts( $query_args );

return array_map( 'get_permalink', $ids );
}

throw new \RuntimeException( 'Please provide either --urls, or purge all urls with --all.' );
}
}
47 changes: 47 additions & 0 deletions src/Commands/Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace P4\MasterTheme\Commands;

use WP_CLI;

/**
* Base class for WP_CLI commands.
*/
abstract class Command {
/**
* Registers the command.
*
* @throws \Exception If WP_CLI doesn't like what we register.
*/
public static function register(): void {
WP_CLI::add_command(
static::get_name(),
[ static::class, 'execute' ],
[
'shortdesc' => static::get_short_description(),
]
);
}

/**
* The name to access the command.
*
* @return string The command name.
*/
abstract protected static function get_name(): string;

/**
* The description shown in the argument's help.
*
* @return string The description text.
*/
abstract protected static function get_short_description(): string;

/**
* The logic of the command. Has WP_CLI command signature.
*
* @param array|null $args Positional arguments.
* @param array|null $assoc_args Named arguments.
*/
abstract public static function execute( ?array $args, ?array $assoc_args ): void;
}
39 changes: 39 additions & 0 deletions src/Commands/RunActivator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace P4\MasterTheme\Commands;

use P4\MasterTheme\Activator;

/**
* Class RunActivator
*/
class RunActivator extends Command {

/**
* The name to access the command.
*
* @return string The command name.
*/
protected static function get_name(): string {
return 'p4-run-activator';
}

/**
* The description shown in the argument's help.
*
* @return string The description text.
*/
protected static function get_short_description(): string {
return 'Update roles in DB and run migrations scripts';
}

/**
* The logic of the command. Has WP_CLI command signature.
*
* @param array|null $args Positional arguments.
* @param array|null $assoc_args Named arguments.
*/
public static function execute( ?array $args, ?array $assoc_args ): void {
Activator::run();
}
}
55 changes: 55 additions & 0 deletions src/Commands/SaveCloudflareKey.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace P4\MasterTheme\Commands;

use WP_CLI;

/**
* Class SaveCloudflareKey
*/
class SaveCloudflareKey extends Command {

/**
* The name to access the command.
*
* @return string The command name.
*/
protected static function get_name(): string {
return 'p4-cf-key-in-db';
}

/**
* The description shown in the argument's help.
*
* @return string The description text.
*/
protected static function get_short_description(): string {
return 'Put Cloudflare key in DB from config file';
}

/**
* The logic of the command. Has WP_CLI command signature.
*
* @param array|null $args Positional arguments.
* @param array|null $assoc_args Named arguments.
*
* @throws WP_CLI\ExitException If no hostname or Cloudflare key is not present.
*/
public static function execute( ?array $args, ?array $assoc_args ): void {
$hostname = $args[0] ?? null;
if ( empty( $hostname ) ) {
WP_CLI::error( 'Please specify the hostname.' );
}

if ( ! defined( 'CLOUDFLARE_API_KEY' ) || empty( CLOUDFLARE_API_KEY ) ) {
WP_CLI::error( 'CLOUDFLARE_API_KEY constant is not set.' );
}

$domain_parts = explode( '.', $hostname );

$root_domain = implode( '.', array_slice( $domain_parts, - 2 ) );
update_option( 'cloudflare_api_key', CLOUDFLARE_API_KEY );
update_option( 'automatic_platform_optimization', [ 'value' => 1 ] );
update_option( 'cloudflare_cached_domain_name', $root_domain );
}
}
11 changes: 11 additions & 0 deletions src/Features.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Features {

public const ENGAGING_NETWORKS = 'feature_engaging_networks';

public const CLOUDFLARE_DEPLOY_PURGE = 'cloudflare_deploy_purge';

/**
* Get the features options page settings.
*
Expand Down Expand Up @@ -55,6 +57,15 @@ private static function get_fields(): array {
'id' => self::ENGAGING_NETWORKS,
'type' => 'checkbox',
],
[
'name' => __( 'Purge HTML from Cloudflare on deploy.', 'planet4-master-theme-backend' ),
'desc' => __(
'WARNING: Do not change this setting without checking with Planet4 team. This will purge all URLs from Cloudflare after a deploy. We are still experimenting with the effects of that on Cloudflare performance.',
'planet4-master-theme-backend'
),
'id' => self::CLOUDFLARE_DEPLOY_PURGE,
'type' => 'checkbox',
],
];
}

Expand Down
39 changes: 1 addition & 38 deletions src/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace P4\MasterTheme;

use RuntimeException;
use WP_CLI;

/**
* Class Loader.
Expand Down Expand Up @@ -52,7 +51,7 @@ public static function get_instance( $services = [] ) : Loader {
private function __construct( $services ) {
$this->load_services( $services );
$this->add_filters();
$this->load_commands();
Commands::load();
}

/**
Expand Down Expand Up @@ -146,42 +145,6 @@ private function add_filters(): void {
add_filter( 'pre_delete_post', [ $this, 'do_not_delete_autosave' ], 1, 3 );
}

/**
* Registers WP_CLI commands.
*/
public function load_commands() {
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}

$activator_command = static function ( $args, $assoc_args ) {
Activator::run();
};
WP_CLI::add_command( 'p4-run-activator', $activator_command );

/**
* Put the CF API key into the options table, where the CF plugin uses it from.
*/
$put_cf_key_in_db = static function ( $args ) {
$hostname = $args[0];
if ( empty( $hostname ) ) {
WP_CLI::error( 'Please specify the hostname.' );
}

if ( ! defined( 'CLOUDFLARE_API_KEY' ) || empty( CLOUDFLARE_API_KEY ) ) {
WP_CLI::error( 'CLOUDFLARE_API_KEY constant is not set.' );
}

$domain_parts = explode( '.', $hostname );

$root_domain = implode( '.', array_slice( $domain_parts, - 2 ) );
update_option( 'cloudflare_api_key', CLOUDFLARE_API_KEY );
update_option( 'automatic_platform_optimization', [ 'value' => 1 ] );
update_option( 'cloudflare_cached_domain_name', $root_domain );
};
WP_CLI::add_command( 'p4-cf-key-in-db', $put_cf_key_in_db );
}

/**
* Due to a bug in WordPress core the "autosave revision" of a post is created and deleted all of the time.
* This is pretty pointless and makes it impractical to add any post meta to that revision.
Expand Down

0 comments on commit 5cfd476

Please sign in to comment.