Skip to content

Commit

Permalink
Merge branch 'v4' into v5
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.md
#	README.md
#	composer.json
#	src/CloudFrontPurger.php
  • Loading branch information
bencroker committed Mar 20, 2024
2 parents e2adf13 + f323c61 commit 5fca56e
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/.gitignore export-ignore
/ecs.php export-ignore
/phpstan.neon export-ignore
/tests/ export-ignore

# Auto detect text files and perform LF normalization
* text=auto
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release Notes for Blitz CloudFront Purger

## 4.0.0-beta.1 - 2024-02-19
## 5.0.0-beta.1 - 2024-03-19

### Added

Expand Down
40 changes: 22 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
[![Stable Version](https://img.shields.io/packagist/v/putyourlightson/craft-blitz-cloudfront?label=stable)]((https://packagist.org/packages/putyourlightson/craft-blitz-cloudfront))
[![Total Downloads](https://img.shields.io/packagist/dt/putyourlightson/craft-blitz-cloudfront)](https://packagist.org/packages/putyourlightson/craft-blitz-cloudfront)

<p align="center"><img width="130" src="https://putyourlightson.com/assets/logos/blitz.svg"></p>
<p align="center"><img width="130" src="https://raw.githubusercontent.com/putyourlightson/craft-blitz-cloudfront/v5/src/icon.svg"></p>

# Blitz CloudFront Purger for Craft CMS
# Blitz CloudFront Purger Plugin for Craft CMS

The CloudFront Purger allows the [Blitz](https://putyourlightson.com/plugins/blitz) plugin for [Craft CMS](https://craftcms.com/) to intelligently purge cached pages.
The CloudFront Purger plugin allows the [Blitz](https://putyourlightson.com/plugins/blitz) plugin for [Craft CMS](https://craftcms.com/) to intelligently purge cached pages.

**Note that Amazon CloudFront charges for invalidation requests. Since invalidation requests can quickly add up when purging individual URLs, you should be aware of the potential costs. PutYourLightsOn takes no responsibility whatsoever for expenses incurred.**
**Note that Amazon CloudFront charges for invalidation requests. Since
invalidation requests can quickly add up when purging individual URLs, you
should be aware of the potential costs. PutYourLightsOn takes no responsibility
whatsoever for expenses incurred.**

> The first 1,000 invalidation paths that you submit per month are free; you pay for each invalidation path over 1,000 in a month. An invalidation path can be for a single file (such as `/images/logo.jpg`) or for multiple files (such as `/images/*`). A path that includes the `*` wildcard counts as one path even if it causes CloudFront to invalidate thousands of files.
Source: [docs.aws.amazon.com](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#PayingForInvalidation)

## Usage
## Documentation

Install the purger using composer.
Read the documentation at [putyourlightson.com/plugins/blitz](https://putyourlightson.com/plugins/blitz#reverse-proxy-purgers).

```shell
composer require putyourlightson/craft-blitz-cloudfront
```
## License

Then add the class to the `cachePurgerTypes` config setting in `config/blitz.php`.
This plugin is licensed for free under the MIT License.

```php
// The purger type classes to add to the plugin’s default purger types.
'cachePurgerTypes' => [
'putyourlightson\blitzcloudfront\CloudFrontPurger',
],
## Requirements

This plugin requires [Craft CMS](https://craftcms.com/) 3.0.0 or later, or 4.0.0 or later, or 5.0.0 or later.

## Installation

To install the plugin, search for “Blitz CloudFront Purger” in the Craft Plugin Store, or install manually using composer.

```shell
composer require putyourlightson/craft-blitz-cloudfront
```

You can then select the purger and settings either in the control panel or in `config/blitz.php`.
Expand All @@ -46,8 +52,6 @@ You can then select the purger and settings either in the control panel or in `c
],
```

## Documentation

Read the documentation at [putyourlightson.com/plugins/blitz](https://putyourlightson.com/plugins/blitz#reverse-proxy-purgers).
---

Created by [PutYourLightsOn](https://putyourlightson.com/).
33 changes: 20 additions & 13 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
{
"name": "putyourlightson/craft-blitz-cloudfront",
"description": "CloudFront cache purger for the Blitz plugin.",
"version": "4.0.0-beta.1",
"type": "blitz-purger",
"version": "5.0.0-beta.1",
"type": "craft-plugin",
"homepage": "https://putyourlightson.com/plugins/blitz",
"license": "proprietary",
"keywords": [
"craftcms",
"blitz",
"cache",
"amazon",
"aws",
"cloudfront",
"cache",
"blitz",
"purger"
],
"require": {
Expand All @@ -19,20 +22,21 @@
},
"require-dev": {
"craftcms/ecs": "dev-main",
"craftcms/phpstan": "dev-main"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"putyourlightson\\blitzcloudfront\\": "src/"
}
"craftcms/phpstan": "dev-main",
"markhuot/craft-pest-core": "^2.0.0-rc2",
"mockery/mockery": "^1.0",
"putyourlightson/craft-generate-test-spec": "v2.x-dev"
},
"scripts": {
"phpstan": "phpstan --ansi --memory-limit=1G",
"check-cs": "ecs check --ansi",
"fix-cs": "ecs check --fix --ansi"
},
"autoload": {
"psr-4": {
"putyourlightson\\blitzcloudfront\\": "src/"
}
},
"config": {
"allow-plugins": {
"craftcms/plugin-installer": true,
Expand All @@ -49,8 +53,11 @@
},
"extra": {
"name": "Blitz CloudFront Purger",
"handle": "blitz-cloudfront",
"developer": "PutYourLightsOn",
"developerUrl": "https://putyourlightson.com/",
"changelogUrl": "https://raw.githubusercontent.com/putyourlightson/craft-blitz-cloudfront/v3/CHANGELOG.md"
"documentationUrl": "https://github.com/putyourlightson/craft-blitz-cloudfront",
"changelogUrl": "https://raw.githubusercontent.com/putyourlightson/craft-blitz-cloudfront/v5/CHANGELOG.md",
"class": "putyourlightson\\blitzcloudfront\\Plugin"
}
}
1 change: 1 addition & 0 deletions ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
return static function(ECSConfig $ecsConfig): void {
$ecsConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
__FILE__,
]);
$ecsConfig->parallel();
Expand Down
49 changes: 46 additions & 3 deletions src/CloudFrontPurger.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ class CloudFrontPurger extends BaseCachePurger
*/
public const REGION = 'us-east-1';

/**
* @var string
*/
public const VERSION = 'latest';

/**
* @var string
*/
Expand All @@ -49,9 +54,9 @@ class CloudFrontPurger extends BaseCachePurger
public string $distributionId = '';

/**
* @var string
* @var bool
*/
private string $version = 'latest';
public bool $condenseUrls = false;

/**
* @inheritdoc
Expand Down Expand Up @@ -142,6 +147,10 @@ public function purgeUrisWithProgress(array $siteUris, callable $setProgressHand

$urls = SiteUriHelper::getUrlsFromSiteUris($siteUris);

if ($this->condenseUrls) {
$urls = $this->getCondensedUrls($urls);
}

$count = 0;
$total = count($urls);
$label = 'Purging {total} pages.';
Expand Down Expand Up @@ -187,6 +196,40 @@ public function getSettingsHtml(): ?string
]);
}

/**
* Returns condensed URLs by eagerly adding a wildcard character.
* This overly simplified method returns a single URL with a wildcard character after the longest common prefix.
*
* @param string[] $urls
* @return string[]
*/
public function getCondensedUrls(array $urls): array
{
if (count($urls) < 2) {
return $urls;
}

// Get the longest common prefix between the two most dissimilar strings.
sort($urls);

return [$this->getLongestCommonPrefix(reset($urls), end($urls)) . '*'];
}

/**
* Returns the longest common prefix between two strings.
*/
private function getLongestCommonPrefix($str1, $str2): string
{
$length = min(strlen($str1), strlen($str2));
for ($i = 0; $i < $length; $i++) {
if ($str1[$i] !== $str2[$i]) {
return substr($str1, 0, $i);
}
}

return substr($str1, 0, $length);
}

/**
* Returns a path from a URL.
*/
Expand Down Expand Up @@ -217,7 +260,7 @@ private function getPathFromUrl(string $url): string
private function sendRequest(array $paths): bool
{
$config = [
'version' => $this->version,
'version' => self::VERSION,
'region' => self::REGION,
];

Expand Down
28 changes: 28 additions & 0 deletions src/Plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/**
* @copyright Copyright (c) PutYourLightsOn
*/

namespace putyourlightson\blitzcloudfront;

use craft\base\Plugin as BasePlugin;
use craft\events\RegisterComponentTypesEvent;
use putyourlightson\blitz\helpers\CachePurgerHelper;
use yii\base\Event;

class Plugin extends BasePlugin
{
/**
* @inheritdoc
*/
public function init(): void
{
parent::init();

Event::on(CachePurgerHelper::class, CachePurgerHelper::EVENT_REGISTER_PURGER_TYPES,
function(RegisterComponentTypesEvent $event) {
$event->types[] = CloudFrontPurger::class;
}
);
}
}
1 change: 1 addition & 0 deletions src/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 21 additions & 8 deletions src/templates/settings.twig
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{% import "_includes/forms" as forms %}

{% import '_includes/forms' as forms %}

{{ forms.autosuggestField({
label: "API Key"|t('blitz'),
label: 'API Key'|t('blitz-cloudfront'),
id: 'apiKey',
name: 'apiKey',
instructions: "An API key for your AWS account."|t('blitz'),
instructions: 'An API key for your AWS account.'|t('blitz-cloudfront'),
suggestEnvVars: true,
suggestions: craft.cp.getEnvSuggestions(),
value: purger.apiKey,
Expand All @@ -15,10 +14,10 @@
}) }}

{{ forms.autosuggestField({
label: "API Secret"|t('blitz'),
label: 'API Secret'|t('blitz-cloudfront'),
id: 'apiSecret',
name: 'apiSecret',
instructions: "An API secret for your AWS account."|t('blitz'),
instructions: 'An API secret for your AWS account.'|t('blitz-cloudfront'),
suggestEnvVars: true,
suggestions: craft.cp.getEnvSuggestions(),
value: purger.apiSecret,
Expand All @@ -27,13 +26,27 @@
}) }}

{{ forms.autosuggestField({
label: "Distribution ID"|t('blitz'),
label: 'Distribution ID'|t('blitz-cloudfront'),
id: 'distributionId',
name: 'distributionId',
instructions: "The ID of the CloudFlare distribution that should be purged."|t('blitz'),
instructions: 'The ID of the CloudFlare distribution that should be purged.'|t('blitz-cloudfront'),
suggestEnvVars: true,
suggestions: craft.cp.getEnvSuggestions(),
value: purger.distributionId,
errors: purger.getErrors('distributionId'),
required: true,
}) }}

{% set info %}
<span class="info">
{{- 'Enabling this can help reduce the number of invalidation paths sent to the CloudFront API, potentially saving on invalidation request charges. This works by condensing multiple invalidation URLs into a single URL with a wildcard character after the longest common prefix. A path that includes the `*` wildcard counts as one path even if it causes CloudFront to invalidate thousands of files.'|t('blitz-cloudfront') -}}
</span>
{% endset %}
{{ forms.lightswitchField({
label: 'Condense URLs'|t('blitz-cloudfront'),
id: 'condenseUrls',
name: 'condenseUrls',
instructions: 'Whether to condense multiple invalidation URLs into a single URL with a wildcard.'|t('blitz-cloudfront') ~ info,
on: purger.condenseUrls,
errors: purger.getErrors('condenseUrls'),
}) }}
32 changes: 32 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Testing

## Static Analysis

To run static analysis on the module,
install [PHPStan for Craft CMS](https://github.com/craftcms/phpstan) and run the following command from the root of your project.

```shell
./vendor/bin/phpstan analyse -c vendor/putyourlightson/craft-blitz-cloudfront/phpstan.neon --memory-limit 1G
```

## Easy Coding Standard

To run the Easy Coding Standard on the plugin, install [ECS for Craft CMS](https://github.com/craftcms/ecs) and run the following command from the root of your project.

```shell
./vendor/bin/ecs check -c vendor/putyourlightson/craft-blitz-cloudfront/ecs.php
```

## Pest Tests

To run Pest tests, install [Craft Pest](https://craft-pest.com/) and run the following command from the root of your project.

```shell
php craft pest/test --test-directory=vendor/putyourlightson/craft-blitz-cloudfront/tests/pest
```

Or to run a specific test.

```shell
php craft pest/test --test-directory=vendor/putyourlightson/craft-blitz-cloudfront/tests/pest --filter=CacheRequestTest
```
13 changes: 13 additions & 0 deletions tests/TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test Specification

This document outlines the test specification for the Blitz CloudFront module.

---

## Feature Tests

### [CondenseUrls](pest/Feature/CondenseUrlsTest.php)

_Tests condensing URLs._

![Pass](https://raw.githubusercontent.com/putyourlightson/craft-generate-test-spec/main/icons/pass.svg) URLs are condensed into a single URL with a wildcard character after the longest common prefix.
1 change: 1 addition & 0 deletions tests/pest/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/test-results.xml
Loading

0 comments on commit 5fca56e

Please sign in to comment.