Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 29e4ec5

Browse files
author
Oliver Stark
committed
craft commands: upper/purge & upper/scheduled
1 parent f27dc98 commit 29e4ec5

File tree

3 files changed

+134
-7
lines changed

3 files changed

+134
-7
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "ostark/upper",
33
"description": "A cache plugin for Craft - supporting multiple Edge Caches",
44
"type": "craft-plugin",
5-
"version": "2.0.0-beta1",
5+
"version": "2.0.0-beta2",
66
"keywords": [
77
"craft",
88
"cms",

src/Commands.php

+131-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace ostark\upper;
44

5-
use craft\helpers\ArrayHelper;
5+
use craft\elements\Entry;
66
use craft\helpers\Console;
7-
use yii\base\InvalidArgumentException;
7+
use craft\helpers\Db;
8+
use yii\base\Module;
9+
use yii\caching\CacheInterface;
810
use yii\console\Controller as BaseConsoleController;
911
use yii\console\ExitCode;
1012
use yii\console\widgets\Table;
@@ -15,12 +17,85 @@
1517
class Commands extends BaseConsoleController
1618
{
1719

20+
const LAST_CHECK_CACHE_KEY = 'upper.lastScheduledCheck';
21+
const LAST_CHECK_DEFAULT_INTERVAL = '-24 hours';
22+
const DATE_FORMAT = 'Y-m-d H:i';
23+
24+
/**
25+
* @var \yii\caching\CacheInterface
26+
*/
27+
protected $cache;
28+
29+
/**
30+
* Commands constructor.
31+
*
32+
* @param string $id
33+
* @param \yii\base\Module $module
34+
* @param \yii\caching\CacheInterface $cache
35+
* @param array $config
36+
*/
37+
public function __construct(string $id, Module $module, CacheInterface $cache, array $config = [])
38+
{
39+
$this->cache = $cache;
40+
parent::__construct($id, $module, $config);
41+
}
42+
43+
1844
/**
1945
* Checks for scheduled Entries
46+
*
47+
* @param int $delayInSeconds Seconds between purge calls, to prevent rate limit errors
48+
* @param string $forcedCheckInterval Time string of lower bound of the range, e.g. '-2 hours'
49+
*
50+
*
51+
* @return int
52+
* @throws \Exception
2053
*/
21-
public function actionScheduled()
54+
public function actionScheduled(int $delayInSeconds = 1, $forcedCheckInterval = null)
2255
{
56+
$lastCheck = $this->cache->exists(self::LAST_CHECK_CACHE_KEY)
57+
? $this->cache->get(self::LAST_CHECK_CACHE_KEY)
58+
: Db::prepareDateForDb((new \DateTime())->modify(self::LAST_CHECK_DEFAULT_INTERVAL));
59+
60+
if ($forcedCheckInterval) {
61+
$lastCheck = Db::prepareDateForDb((new \DateTime())->modify($forcedCheckInterval));
62+
}
63+
64+
$now = Db::prepareDateForDb(new \DateTime());
65+
$published = $this->getPublishedEntries($lastCheck, $now);
66+
$expired = $this->getExpiredEntries($lastCheck, $now);
67+
$entries = array_merge($published, $expired);
68+
$rows = [];
69+
70+
// Remember this check
71+
$this->cache->set(self::LAST_CHECK_CACHE_KEY, $now);
72+
73+
// Print info
74+
$this->stdout(sprintf("> Expired Entries: %d" . PHP_EOL, count($expired)), Console::FG_GREY);
75+
$this->stdout(sprintf("> Published Entries: %d" . PHP_EOL, count($published)), Console::FG_GREY);
76+
$this->stdout(sprintf("> Range: %s to %s" . PHP_EOL, $lastCheck, $now), Console::FG_CYAN);
77+
78+
if (!count($entries)) {
79+
return ExitCode::OK;
80+
}
81+
82+
foreach ($entries as $entry) {
83+
/** @var Entry $entry */
84+
$postDateString = $entry->postDate ? $entry->postDate->format(self::DATE_FORMAT) : '-';
85+
$expiryDateString = $entry->expiryDate ? $entry->expiryDate->format(self::DATE_FORMAT) : '-';
86+
$tags[] = $tag = Plugin::TAG_PREFIX_ELEMENT . $entry->id;
87+
$rows[] = [$tag, $entry->title, $postDateString, $expiryDateString];
88+
};
89+
90+
echo Table::widget([
91+
'headers' => ['Tag', 'Title', 'PostDate', 'ExpiryDate'],
92+
'rows' => $rows,
93+
]);
2394

95+
foreach ($tags as $tag) {
96+
Plugin::getInstance()->getPurger()->purgeTag($tag);
97+
sleep($delayInSeconds);
98+
}
2499
}
25100

26101
/**
@@ -30,17 +105,68 @@ public function actionScheduled()
30105
*/
31106
public function actionPurge(array $tags = [])
32107
{
108+
// Purge all
33109
if (count($tags) === 0) {
34-
Plugin::getInstance()->getPurger()->purgeAll();
35-
return ExitCode::OK;
110+
if (Console::confirm("Do you want to purge all tags?")) {
111+
if (Plugin::getInstance()->getPurger()->purgeAll()) {
112+
$this->stdout("Cache purged." . PHP_EOL, Console::FG_GREEN);
113+
return ExitCode::OK;
114+
}
115+
$this->stdout("Purge Error." . PHP_EOL, Console::FG_RED);
116+
}
117+
return ExitCode::UNSPECIFIED_ERROR;
36118
}
37119

120+
// Purge tag(s)
38121
foreach ($tags as $tag) {
39122
if (!(Plugin::getInstance()->getPurger()->purgeTag($tag))) {
123+
$this->stdout("Unable to purge tag: $tag" . PHP_EOL, Console::FG_RED);
40124
return ExitCode::UNSPECIFIED_ERROR;
41125
}
42126
}
43127

128+
$this->stdout(sprintf("Cache tag purged: %s", implode(', ', $tags)) . PHP_EOL, Console::FG_GREEN);
44129
return ExitCode::OK;
45130
}
131+
132+
133+
/**
134+
* @param $rangeStart
135+
* @param $rangeEnd
136+
*
137+
* @return array
138+
*/
139+
protected function getPublishedEntries($rangeStart, $rangeEnd): array
140+
{
141+
// Entries published within time frame
142+
$entries = (Entry::find()
143+
->where(['not', ['postDate' => null]])
144+
->andWhere(['between', 'postDate', $rangeStart, $rangeEnd])
145+
->withStructure(false)
146+
->orderBy(null)
147+
->anyStatus())->all();
148+
149+
// Exclude manually published entries (postDate ≅ dateUpdated)
150+
return array_filter($entries, function (Entry $item) {
151+
$diffInSeconds = abs($item->postDate->getTimestamp() - $item->dateUpdated->getTimestamp());
152+
return ($diffInSeconds > 60);
153+
});
154+
}
155+
156+
/**
157+
* @param $rangeStart
158+
* @param $rangeEnd
159+
*
160+
* @return Entry[]
161+
*/
162+
protected function getExpiredEntries($rangeStart, $rangeEnd): array
163+
{
164+
return (Entry::find()
165+
->where(['not', ['expiryDate' => null]])
166+
->andWhere(['between', 'expiryDate', $rangeStart, $rangeEnd])
167+
->withStructure(false)
168+
->orderBy(null)
169+
->anyStatus()
170+
)->all();
171+
}
46172
}

src/Plugin.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use ostark\upper\drivers\CachePurgeInterface;
2020
use ostark\upper\models\Settings;
2121
use yii\base\Event;
22-
use yii\db\ActiveQuery;
22+
use yii\caching\CacheInterface;
2323

2424
/**
2525
* Class Plugin
@@ -90,6 +90,7 @@ public function init()
9090
if (\Craft::$app instanceof Application) {
9191
// Register console commands
9292
\Craft::$app->controllerMap['upper'] = Commands::class;
93+
\Craft::$app->set(CacheInterface::class, \Craft::$app->getCache());
9394
}
9495
}
9596

0 commit comments

Comments
 (0)