Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add console utility, use UrlHelper.
- Loading branch information
Showing
5 changed files
with
225 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
/** | ||
* Cloudflare plugin for Craft CMS 3.x | ||
* | ||
* Purge Cloudflare caches from Craft. | ||
* | ||
* @link https://workingconcept.com | ||
* @copyright Copyright (c) 2019 Working Concept | ||
*/ | ||
|
||
namespace workingconcept\cloudflare\console\controllers; | ||
|
||
use workingconcept\cloudflare\Cloudflare; | ||
use yii\console\Controller; | ||
use yii\console\ExitCode; | ||
|
||
class PurgeController extends Controller | ||
{ | ||
// Public Methods | ||
// ========================================================================= | ||
|
||
/** | ||
* Attempt to purge specific URLs. | ||
* https://www.yiiframework.com/doc/guide/2.0/en/tutorial-console#arguments | ||
* | ||
* @param array $urls | ||
* @return int | ||
*/ | ||
public function actionPurgeUrls(array $urls): int | ||
{ | ||
$urlCount = count($urls); | ||
$plural = $urlCount == 1 ? '' : 's'; | ||
|
||
$this->stdout("Purging {$urlCount} URL{$plural}..." . PHP_EOL); | ||
|
||
$response = Cloudflare::$plugin->cloudflare->purgeUrls($urls); | ||
|
||
return $this->_handleResult($response); | ||
} | ||
|
||
/** | ||
* Attempt to purge entire zone cache. | ||
* @return int | ||
*/ | ||
public function actionPurgeAll(): int | ||
{ | ||
$this->stdout('Purging Cloudflare zone...' . PHP_EOL); | ||
|
||
$response = Cloudflare::$plugin->cloudflare->purgeZoneCache(); | ||
|
||
return $this->_handleResult($response); | ||
} | ||
|
||
|
||
// Private Methods | ||
// ========================================================================= | ||
|
||
/** | ||
* Handle Cloudflare's API response for console output. | ||
* | ||
* @param $response | ||
* @return int | ||
*/ | ||
private function _handleResult($response): int | ||
{ | ||
if ($response === null) | ||
{ | ||
$this->stdout('✗ Cloudflare plugin not configured' . PHP_EOL); | ||
return ExitCode::CONFIG; | ||
} | ||
|
||
if (isset($response->success)) | ||
{ | ||
if ($response->success) | ||
{ | ||
$this->stdout('✓ success' . PHP_EOL); | ||
return ExitCode::OK; | ||
} | ||
|
||
$this->stdout('✗ purge failed' . PHP_EOL); | ||
|
||
if (isset($response->errors)) | ||
{ | ||
foreach($response->errors as $error) | ||
{ | ||
$this->stdout("- $error->code: $error->message" . PHP_EOL); | ||
} | ||
} | ||
|
||
return ExitCode::UNAVAILABLE; | ||
} | ||
|
||
$this->stdout('✗ purge failed' . PHP_EOL); | ||
return ExitCode::UNAVAILABLE; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<?php | ||
/** | ||
* Cloudflare plugin for Craft CMS 3.x | ||
* | ||
* @link https://workingconcept.com | ||
* @copyright Copyright (c) 2019 Working Concept Inc. | ||
*/ | ||
|
||
namespace workingconcept\cloudflare\helpers; | ||
|
||
use workingconcept\cloudflare\Cloudflare; | ||
use Craft; | ||
|
||
class UrlHelper | ||
{ | ||
|
||
/** | ||
* Only return URLs that can be sent to Cloudflare. | ||
* | ||
* @param array $urls Array of URL strings to be cleared. | ||
* @return array Validated, trimmed values only. | ||
*/ | ||
public static function prepUrls($urls = []): array | ||
{ | ||
$cleanUrls = []; // to be populated | ||
$cfDomainName = Cloudflare::$plugin->getSettings()->zoneName; | ||
$includeZoneCheck = $cfDomainName !== null; | ||
|
||
/** | ||
* First trim leading+trailing whitespace, just in case. | ||
*/ | ||
$urls = array_map('trim', $urls); | ||
|
||
/** | ||
* Collect only URLs that have the ability to be cleared. | ||
*/ | ||
array_walk($urls, function($url) use ($includeZoneCheck, &$cleanUrls) { | ||
if (self::isPurgeableUrl($url, $includeZoneCheck)) | ||
{ | ||
$cleanUrls[] = $url; | ||
} | ||
}); | ||
|
||
return $cleanUrls; | ||
} | ||
|
||
/** | ||
* Make sure the supplied URL is something Cloudflare will be able to purge. | ||
* | ||
* @param string $url URL to be checked. | ||
* @param bool $includeZoneCheck Whether or not to ensure that the URL | ||
* exists on the zone this site is | ||
* configured to use. | ||
* | ||
* @return bool `true` if the URL is worth sending to Cloudflare | ||
*/ | ||
public static function isPurgeableUrl($url, $includeZoneCheck): bool | ||
{ | ||
$cfDomainName = Cloudflare::$plugin->getSettings()->zoneName; | ||
|
||
/** | ||
* Provided string is a valid URL. | ||
*/ | ||
if (filter_var($url, FILTER_VALIDATE_URL) === false) | ||
{ | ||
Craft::info( | ||
sprintf('Ignoring invalid URL: %s', $url), | ||
'cloudflare' | ||
); | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* If we've stored the zone name (FQDN) locally, make sure the URL | ||
* uses it since it otherwise won't be cleared. | ||
*/ | ||
if ($includeZoneCheck) | ||
{ | ||
$urlDomain = self::getBaseDomainFromUrl($url); | ||
|
||
if (strtolower($urlDomain) !== strtolower($cfDomainName)) | ||
{ | ||
Craft::info( | ||
sprintf('Ignoring URL outside zone: %s', $url), | ||
'cloudflare' | ||
); | ||
|
||
return false; // base domain doesn't match Cloudflare zone | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Gets the domain name and TLD only (no subdomains or query parameters) | ||
* from the given URL. | ||
* | ||
* @param string $url | ||
* @return bool|string `false` if the URL's host can't be parsed | ||
*/ | ||
public static function getBaseDomainFromUrl($url) | ||
{ | ||
$host = parse_url($url, PHP_URL_HOST); | ||
|
||
$parts = explode('.', $host); | ||
$numParts = count($parts); | ||
|
||
if ($numParts < 2) | ||
{ | ||
return false; | ||
} | ||
|
||
// hostname . tld | ||
return "{$parts[$numParts-2]}.{$parts[$numParts-1]}"; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters