├── .gitignore
├── Api
├── CacheRouteManagementInterface.php
├── CacheRouteRepositoryInterface.php
├── CacheTagManagementInterface.php
├── CacheTagRepositoryInterface.php
├── CacheVaryDataRepositoryInterface.php
├── Data
│ ├── CacheRouteInterface.php
│ └── CacheTagInterface.php
└── RoutesTagsLinkManagementInterface.php
├── Console
└── Command
│ └── CacheWarmup.php
├── Model
├── CacheRouteManagement.php
├── CacheRouteRepository.php
├── CacheTagManagement.php
├── CacheTagRepository.php
├── CacheVaryDataRepository.php
├── Route
│ ├── CacheRoute.php
│ ├── Management
│ │ ├── IncrementPopularityById.php
│ │ └── IncrementPopularityByRoute.php
│ └── Query
│ │ ├── GetById.php
│ │ ├── GetByRoute.php
│ │ └── SaveRoute.php
├── RoutesTagsLink
│ └── Management
│ │ └── LinkRouteToTags.php
├── RoutesTagsLinkManagement.php
├── Tag
│ ├── CacheTag.php
│ ├── Management
│ │ └── InvalidateRoutesByTags.php
│ └── Query
│ │ ├── GetById.php
│ │ ├── GetByTag.php
│ │ └── SaveTag.php
└── VaryData
│ ├── Applicator
│ ├── CustomerGroupApplicator.php
│ ├── VaryDataApplicatorInterface.php
│ └── VaryDataApplicatorList.php
│ └── Query
│ ├── GetAllVaryData.php
│ └── SaveVaryData.php
├── Plugin
└── CacheIdentifier
│ └── SaveVaryData.php
├── Service
├── Route
│ ├── GetExistingOrNewRouteModel.php
│ └── NewRouteModelProvider.php
└── Tag
│ ├── GetExistingOrNewTagModel.php
│ └── NewTagModelProvider.php
├── Setup
└── InstallSchema.php
├── composer.json
├── etc
├── di.xml
├── frontend
│ └── di.xml
├── module.xml
└── webapi.xml
├── registration.php
└── view
└── frontend
├── layout
└── default.xml
└── web
└── increment-popularity.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/Api/CacheRouteManagementInterface.php:
--------------------------------------------------------------------------------
1 | urlInterface = $urlInterface;
52 | $this->urlRewriteCollectionFactory = $urlRewriteCollectionFactory;
53 | }
54 |
55 | /**
56 | * {@inheritdoc}
57 | */
58 | protected function configure()
59 | {
60 | $this->setName("cache:warmup")
61 | ->addOption(
62 | 'pageTypes',
63 | 'p',
64 | InputArgument::OPTIONAL,
65 | 'Comma-separated PageTypes like cms-page,product,category or all -> Default: all'
66 | )
67 | ->addArgument(
68 | 'concurrency',
69 | InputArgument::OPTIONAL,
70 | 'Maximum number of concurrent curl requests -> Default: 10'
71 | )
72 | ->addOption(
73 | 'stopAfter',
74 | 's',
75 | InputArgument::OPTIONAL
76 | )
77 | ->setDescription('Fire curl requests to warm up varnish cache');
78 |
79 | parent::configure();
80 | }
81 |
82 | private function initParams(InputInterface $input)
83 | {
84 | $pageTypes = $input->getOption("pageTypes");
85 | if (strlen($pageTypes) > 0) {
86 | $this->pageTypes = explode(",", $pageTypes);
87 | }
88 | $maxThreads = $input->getArgument("concurrency");
89 | if (intval($maxThreads) > 0) {
90 | $this->maxConcurrentRequests = $maxThreads;
91 | }
92 | $stopAfter = $input->getOption("stopAfter");
93 | if (intval($stopAfter) > 0) {
94 | $this->stopAfter = $stopAfter;
95 | }
96 | }
97 |
98 | /**
99 | * @param InputInterface $input
100 | * @param OutputInterface $output
101 | * @return int|null|void
102 | * @throws \Exception
103 | */
104 | protected function execute(InputInterface $input, OutputInterface $output)
105 | {
106 | $this->initParams($input);
107 |
108 | $urlCollection = $this->getRewriteCollection();
109 |
110 | if (!$urlCollection) {
111 | $up = new \Exception("No Rewrite Collection Loaded, may you misspelled the params?");
112 | throw $up; // haha
113 | }
114 |
115 | $client = $this->getClient();
116 | $requests = $this->getRequests($client, $urlCollection);
117 | $pool = $this->getPool($client, $requests, $output);
118 | $promise = $pool->promise();
119 | $promise->wait();
120 | }
121 |
122 | /**
123 | * @param Client $client
124 | * @param callable $requests
125 | * @param OutputInterface $output
126 | * @return Pool
127 | */
128 | private function getPool(Client $client, callable $requests, OutputInterface $output)
129 | {
130 | return new Pool($client, $requests(), [
131 | 'concurrency' => $this->maxConcurrentRequests,
132 | 'fulfilled' => function ($response, $index) use ($output) {
133 | $output->writeln("Successful: " . $index);
134 | },
135 | 'rejected' => function ($reason, $index) use ($output) {
136 | $output->writeln("Rejected: " . $index);
137 | },
138 | ]);
139 | }
140 |
141 | /**
142 | * @param Client $client
143 | * @param $urlCollection
144 | * @return \Closure
145 | */
146 | private function getRequests(Client $client, $urlCollection)
147 | {
148 | return function () use ($client, $urlCollection) {
149 | /** @var UrlRewrite $url */
150 | foreach ($urlCollection as $url) {
151 | yield function() use ($client, $url) {
152 | return $client->getAsync($url->getRequestPath());
153 | };
154 | }
155 | };
156 | }
157 |
158 | /**
159 | * @return Client
160 | */
161 | private function getClient()
162 | {
163 | $baseUrl = $this->urlInterface->getBaseUrl();
164 | return new Client([
165 | RequestOptions::ALLOW_REDIRECTS => true,
166 | 'base_uri' => $baseUrl
167 | ]);
168 | }
169 |
170 | /**
171 | * @return UrlRewriteCollection|null
172 | */
173 | private function getRewriteCollection()
174 | {
175 | $rewriteFilter = $this->getRewriteFilter();
176 | return $rewriteFilter
177 | ? $this->urlRewriteCollectionFactory->create()->addFieldToFilter("entity_type", $rewriteFilter)
178 | : null;
179 | }
180 |
181 | /**
182 | * @param OutputInterface $output
183 | * @return bool
184 | */
185 | public function isVerbose(OutputInterface $output)
186 | {
187 | return $output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE;
188 | }
189 |
190 | /**
191 | * @return array|null
192 | */
193 | private function getRewriteFilter()
194 | {
195 | if ($this->pageTypes == 'all') {
196 | return $this->possiblePageTypes;
197 | }
198 |
199 | if (!is_array($this->pageTypes)) {
200 | $this->pageTypes = [$this->pageTypes];
201 | }
202 |
203 | $filter = [];
204 |
205 | foreach ($this->pageTypes as $pageType) {
206 | if (in_array($pageType, $this->possiblePageTypes)) {
207 | $filter[] = $pageType;
208 | }
209 | }
210 |
211 | return !empty($filter) ? $filter : null;
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/Model/CacheRouteManagement.php:
--------------------------------------------------------------------------------
1 | incrementPopularityById = $incrementPopularityById;
25 | $this->incrementPopularityByRoute = $incrementPopularityByRoute;
26 | }
27 |
28 | public function incrementPopularityByRoute(string $route): void
29 | {
30 | $this->incrementPopularityByRoute->execute($route);
31 | }
32 |
33 | public function incrementPopularityById(int $routeId): void
34 | {
35 | $this->incrementPopularityById->execute($routeId);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Model/CacheRouteRepository.php:
--------------------------------------------------------------------------------
1 | getByIdQuery = $getByIdQuery;
34 | $this->getByRoute = $getByRoute;
35 | $this->saveCommand = $saveCommand;
36 | }
37 |
38 | public function getById(int $id):? CacheRouteInterface
39 | {
40 | return $this->getByIdQuery->execute($id);
41 | }
42 |
43 | public function getByRoute(string $route):? CacheRouteInterface
44 | {
45 | return $this->getByRoute->execute($route);
46 | }
47 |
48 | public function save(CacheRouteInterface $cacheRoute): void
49 | {
50 | $this->saveCommand->execute($cacheRoute);
51 | }
52 | }
--------------------------------------------------------------------------------
/Model/CacheTagManagement.php:
--------------------------------------------------------------------------------
1 | invalidateRoutesByTags = $invalidateRoutesByTags;
20 | }
21 |
22 | /**
23 | * @param string[] $tags
24 | */
25 | public function invalidateRoutesByTags(array $tags): void
26 | {
27 | $this->invalidateRoutesByTags->execute($tags);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Model/CacheTagRepository.php:
--------------------------------------------------------------------------------
1 | getById = $getById;
34 | $this->getByTag = $getByTag;
35 | $this->saveCommand = $saveCommand;
36 | }
37 |
38 | public function getById(int $id):? CacheTagInterface
39 | {
40 | return $this->getById->execute($id);
41 | }
42 |
43 | public function getByTag(string $cacheTag):? CacheTagInterface
44 | {
45 | return $this->getByTag->execute($cacheTag);
46 | }
47 |
48 | public function save(CacheTagInterface $cacheTag): void
49 | {
50 | $this->saveCommand->execute($cacheTag);
51 | }
52 | }
--------------------------------------------------------------------------------
/Model/CacheVaryDataRepository.php:
--------------------------------------------------------------------------------
1 | saveVaryData = $saveVaryData;
24 | $this->getAllVaryData = $getAllVaryData;
25 | }
26 |
27 | /**
28 | * @param array $varyData
29 | */
30 | public function save(array $varyData): void
31 | {
32 | $this->saveVaryData->execute($varyData);
33 | }
34 |
35 | /**
36 | * @return array[]
37 | */
38 | public function getAll(): array
39 | {
40 | return $this->getAllVaryData->execute();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Model/Route/CacheRoute.php:
--------------------------------------------------------------------------------
1 | id;
44 | }
45 |
46 | /**
47 | * @param int $id
48 | * @return void
49 | */
50 | public function setId(int $id): void
51 | {
52 | $this->id = $id;
53 | }
54 |
55 | /**
56 | * @return string
57 | */
58 | public function getRoute():? string
59 | {
60 | return $this->route;
61 | }
62 |
63 | /**
64 | * @param string $route
65 | * @return void
66 | */
67 | public function setRoute(string $route): void
68 | {
69 | $this->route = $route;
70 | }
71 |
72 | /**
73 | * @return bool
74 | */
75 | public function getCacheStatus():? bool
76 | {
77 | return $this->cacheStatus;
78 | }
79 |
80 | /**
81 | * @param int|bool $cacheStatus
82 | * @return void
83 | */
84 | public function setCacheStatus($cacheStatus): void
85 | {
86 | $this->cacheStatus = $cacheStatus;
87 | }
88 |
89 | /**
90 | * @return int
91 | */
92 | public function getLifetime():? int
93 | {
94 | return $this->lifetime;
95 | }
96 |
97 | /**
98 | * @param int $lifetime
99 | * @return void
100 | */
101 | public function setLifetime(int $lifetime): void
102 | {
103 | $this->lifetime = $lifetime;
104 | }
105 |
106 | /**
107 | * @return int
108 | */
109 | public function getPopularity():? int
110 | {
111 | return $this->popularity;
112 | }
113 |
114 | /**
115 | * @param int $popularity
116 | * @return void
117 | */
118 | public function setPopularity(int $popularity): void
119 | {
120 | $this->popularity = $popularity;
121 | }
122 | }
--------------------------------------------------------------------------------
/Model/Route/Management/IncrementPopularityById.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
18 | }
19 |
20 | public function execute(int $id): void
21 | {
22 | $connection = $this->resourceConnection->getConnection();
23 |
24 | $connection->update(
25 | 'cache_routes',
26 | ['popularity' => new \Zend_Db_Expr('popularity + 1')],
27 | ['id = ?' => $id]
28 | );
29 | }
30 | }
--------------------------------------------------------------------------------
/Model/Route/Management/IncrementPopularityByRoute.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
18 | }
19 |
20 | public function execute(string $route): void
21 | {
22 | $connection = $this->resourceConnection->getConnection();
23 |
24 | $connection->update(
25 | 'cache_routes',
26 | ['popularity' => new \Zend_Db_Expr('popularity + 1')],
27 | ['cache_route = ?' => $route]
28 | );
29 | }
30 | }
--------------------------------------------------------------------------------
/Model/Route/Query/GetById.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
25 | $this->cacheRouteFactory = $cacheRouteFactory;
26 | }
27 |
28 | public function execute($id):? CacheRouteInterface
29 | {
30 | $connection = $this->resourceConnection->getConnection();
31 |
32 | $dbRoute = array_pop($connection
33 | ->select()
34 | ->from('cache_routes')
35 | ->where('id = ?', $id)
36 | ->query()
37 | ->fetchAll()
38 | );
39 |
40 | if ($dbRoute) {
41 | /** @var CacheRouteInterface $cacheRoute */
42 | $cacheRoute = $this->cacheRouteFactory->create();
43 |
44 | array_walk($dbRoute, function ($value, $key) use ($cacheRoute) {
45 | $camelCaseKey = "set" . SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
46 | $cacheRoute->$camelCaseKey($value);
47 | });
48 | }
49 |
50 | return $cacheRoute ?? null;
51 | }
52 | }
--------------------------------------------------------------------------------
/Model/Route/Query/GetByRoute.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
25 | $this->cacheRouteFactory = $cacheRouteFactory;
26 | }
27 |
28 | public function execute(string $route):? CacheRouteInterface
29 | {
30 | $connection = $this->resourceConnection->getConnection();
31 |
32 | $dbRoute = array_pop($connection
33 | ->select()
34 | ->from('cache_routes')
35 | ->where('route = ?', $route)
36 | ->query()
37 | ->fetchAll()
38 | );
39 |
40 | if ($dbRoute) {
41 | /** @var CacheRouteInterface $cacheRoute */
42 | $cacheRoute = $this->cacheRouteFactory->create();
43 |
44 | array_walk($dbRoute, function ($value, $key) use ($cacheRoute) {
45 | $camelCaseKey = "set" . SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
46 | $cacheRoute->$camelCaseKey($value);
47 | });
48 | }
49 |
50 | return $cacheRoute ?? null;
51 | }
52 | }
--------------------------------------------------------------------------------
/Model/Route/Query/SaveRoute.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
18 | }
19 |
20 | public function execute(CacheRouteInterface $cacheRoute): void
21 | {
22 | $connection = $this->resourceConnection->getConnection();
23 |
24 | $connection->insertOnDuplicate(
25 | 'cache_routes',
26 | [
27 | 'route' => $cacheRoute->getRoute(),
28 | 'cache_status' => $cacheRoute->getCacheStatus() ? 1 : 0,
29 | 'popularity' => $cacheRoute->getPopularity(),
30 | 'lifetime' => $cacheRoute->getLifetime()
31 | ],
32 | ['cache_status', 'popularity', 'lifetime']
33 | );
34 |
35 | }
36 | }
--------------------------------------------------------------------------------
/Model/RoutesTagsLink/Management/LinkRouteToTags.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
19 | }
20 |
21 | /**
22 | * @param int $routeId
23 | * @param int[] $tagIds
24 | * @throws \Zend_Db_Exception
25 | */
26 | public function execute(int $routeId, array $tagIds): void
27 | {
28 | $routeToTags = [];
29 | array_walk($tagIds, function ($tagId) use ($routeId, $routeToTags) {
30 | $routeToTags[] = [
31 | 'tag_id' => $tagId,
32 | 'route_id' => $routeId
33 | ];
34 | });
35 |
36 | /** @var Mysql $connection */
37 | $connection = $this->resourceConnection->getConnection();
38 | $connection->insertArray(
39 | 'cache_routes_tags',
40 | ['route_id', 'tag_id'],
41 | $routeToTags,
42 | $connection::INSERT_IGNORE
43 | );
44 | }
45 | }
--------------------------------------------------------------------------------
/Model/RoutesTagsLinkManagement.php:
--------------------------------------------------------------------------------
1 | linkRouteToTags = $linkRouteToTags;
22 | }
23 |
24 | /**
25 | * Take care, that this only works if both (route & tags) exists
26 | *
27 | * @param CacheRouteInterface $cacheRoute
28 | * @param CacheTagInterface[] $tags
29 | *
30 | * @throws \Zend_Db_Exception
31 | */
32 | public function linkRouteToTags(CacheRouteInterface $cacheRoute, array $tags): void
33 | {
34 | array_walk($tags, function (&$value) {return $value->getId();});
35 | $this->linkRouteToTags->execute($cacheRoute->getId(), $tags);
36 | }
37 | }
--------------------------------------------------------------------------------
/Model/Tag/CacheTag.php:
--------------------------------------------------------------------------------
1 | id;
30 | }
31 |
32 | /**
33 | * @param int $id
34 | * @return mixed
35 | */
36 | public function setId(int $id): void
37 | {
38 | $this->id = $id;
39 | }
40 |
41 | /**
42 | * @return string
43 | */
44 | public function getCacheTag():? string
45 | {
46 | return $this->cacheTag;
47 | }
48 |
49 | /**
50 | * @param string $cacheTag
51 | * @return mixed
52 | */
53 | public function setCacheTag(string $cacheTag): void
54 | {
55 | $this->cacheTag = $cacheTag;
56 | }
57 | }
--------------------------------------------------------------------------------
/Model/Tag/Management/InvalidateRoutesByTags.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
18 | }
19 |
20 | /**
21 | * @param string[] $tags
22 | */
23 | public function execute(array $tags): void
24 | {
25 | $connection = $this->resourceConnection->getConnection();
26 |
27 | $routesSql = $connection
28 | ->select()
29 | ->from(["crt" => 'cache_routes_tags'], ['id' => 'route_id'])
30 | ->joinLeft(
31 | ['ct' => 'cache_tags'],
32 | "crt.tag_id = ct.id",
33 | ['tag_id' => 'id']
34 | )->where('ct.tag in (?)', $tags)->__toString();
35 |
36 | $connection->update(
37 | 'cache_routes',
38 | ['cache_status' => 0],
39 | ['id IN (?)' => $routesSql]
40 | );
41 | }
42 | }
--------------------------------------------------------------------------------
/Model/Tag/Query/GetById.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
26 | $this->cacheTagFactory = $cacheTagFactory;
27 | }
28 |
29 | public function execute(int $id):? CacheTagInterface
30 | {
31 | $connection = $this->resourceConnection->getConnection();
32 |
33 | $dbRoute = array_pop($connection
34 | ->select()
35 | ->from('cache_tags')
36 | ->where('id = ?', $id)
37 | ->query()
38 | ->fetchAll()
39 | );
40 |
41 | if ($dbRoute) {
42 | /** @var CacheTagInterface $cacheTag */
43 | $cacheRoute = $this->cacheTagFactory->create();
44 |
45 | array_walk($dbRoute, function ($value, $key) use ($cacheRoute) {
46 | $camelCaseKey = "set" . SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
47 | $cacheRoute->$camelCaseKey($value);
48 | });
49 | }
50 |
51 | return $cacheRoute ?? null;
52 | }
53 | }
--------------------------------------------------------------------------------
/Model/Tag/Query/GetByTag.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
26 | $this->cacheTagFactory = $cacheTagFactory;
27 | }
28 |
29 | public function execute(string $tag):? CacheTagInterface
30 | {
31 | $connection = $this->resourceConnection->getConnection();
32 |
33 | $dbRoute = array_pop($connection
34 | ->select()
35 | ->from('cache_tags')
36 | ->where('cache_tag = ?', $tag)
37 | ->query()
38 | ->fetchAll()
39 | );
40 |
41 | if ($dbRoute) {
42 | /** @var CacheTagInterface $cacheTag */
43 | $cacheRoute = $this->cacheTagFactory->create();
44 |
45 | array_walk($dbRoute, function ($value, $key) use ($cacheRoute) {
46 | $camelCaseKey = "set" . SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
47 | $cacheRoute->$camelCaseKey($value);
48 | });
49 | }
50 |
51 | return $cacheRoute ?? null;
52 | }
53 | }
--------------------------------------------------------------------------------
/Model/Tag/Query/SaveTag.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
18 | }
19 |
20 | public function execute(CacheTagInterface $cacheTag): void
21 | {
22 | $connection = $this->resourceConnection->getConnection();
23 |
24 | $connection->insert(
25 | 'cache_routes',
26 | ['cache_tag' => $cacheTag->getCacheTag()]
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Model/VaryData/Applicator/CustomerGroupApplicator.php:
--------------------------------------------------------------------------------
1 | customerSession = $customerSession;
25 | $this->customerFactory = $customerFactory;
26 | }
27 |
28 | public function apply(array $varyData): void
29 | {
30 | $this->customerSession->clearStorage();
31 | $customerGroupId = $varyData[self::VARY_DATA_KEY];
32 | $customer = $this->customerFactory->create()->setGroupId($customerGroupId);
33 | $this->customerSession->setCustomerGroupId($customerGroupId);
34 | $this->customerSession->setCustomer($customer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Model/VaryData/Applicator/VaryDataApplicatorInterface.php:
--------------------------------------------------------------------------------
1 | varyDataApplicators = $varyDataApplicators;
20 | }
21 |
22 | public function applyAll(array $varyData): void
23 | {
24 | foreach ($this->varyDataApplicators as $varyDataApplicator) {
25 | $varyDataApplicator->apply($varyData);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Model/VaryData/Query/GetAllVaryData.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
29 | $this->serializer = $serializer;
30 | }
31 |
32 | /**
33 | * @return array[]
34 | */
35 | public function execute(): array
36 | {
37 | $connection = $this->resourceConnection->getConnection();
38 | return $connection->select()
39 | ->from('cache_vary_data')
40 | ->query()
41 | ->fetchAll();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Model/VaryData/Query/SaveVaryData.php:
--------------------------------------------------------------------------------
1 | resourceConnection = $resourceConnection;
23 | $this->serializer = $serializer;
24 | }
25 |
26 | public function execute(array $varyData): void
27 | {
28 | $connection = $this->resourceConnection->getConnection();
29 | $connection->insertOnDuplicate(
30 | 'cache_vary_data',
31 | ['vary_data' => $this->serializer->serialize($varyData)],
32 | ['vary_data']
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Plugin/CacheIdentifier/SaveVaryData.php:
--------------------------------------------------------------------------------
1 | httpContext = $httpContext;
29 | $this->varyDataRepository = $varyDataRepository;
30 | }
31 |
32 | /**
33 | * Adds a theme key to identifier for a built-in cache if user-agent theme rule is actual
34 | *
35 | * @param \Magento\Framework\App\PageCache\Identifier $identifier
36 | * @param string $result
37 | * @return string
38 | * @SuppressWarnings(PHPMD.UnusedFormalParameter)
39 | */
40 | public function afterGetValue(\Magento\Framework\App\PageCache\Identifier $identifier, $result): string
41 | {
42 | $varyData = $this->httpContext->toArray()['data'];
43 | $this->varyDataRepository->save($varyData);
44 | return $result;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Service/Route/GetExistingOrNewRouteModel.php:
--------------------------------------------------------------------------------
1 | cacheRouteRepository = $cacheRouteRepository;
31 | $this->newRouteModelProvider = $newRouteModelProvider;
32 | }
33 |
34 | public function getByRoute(string $route): CacheRouteInterface
35 | {
36 | $routeModel = $this->cacheRouteRepository->getByRoute($route);
37 |
38 | if (!$routeModel) {
39 | $routeModel = $this->newRouteModelProvider->createForRoute($route);
40 | $this->cacheRouteRepository->save($routeModel);
41 | $routeModel = $this->cacheRouteRepository->getByRoute($route);
42 | }
43 |
44 | return $routeModel;
45 | }
46 | }
--------------------------------------------------------------------------------
/Service/Route/NewRouteModelProvider.php:
--------------------------------------------------------------------------------
1 | cacheRouteInterfaceFactory = $cacheRouteInterfaceFactory;
26 | }
27 |
28 | public function createForRoute(string $route, int $cacheStatus = 0, int $lifetime = 86400, int $popularity = 0): CacheRouteInterface
29 | {
30 | /** @var CacheRouteInterface $freshCacheRoute */
31 | $freshCacheRoute = $this->cacheRouteInterfaceFactory->create();
32 | $freshCacheRoute->setRoute($route);
33 | $freshCacheRoute->setCacheStatus($cacheStatus);
34 | $freshCacheRoute->setLifetime($lifetime);
35 | $freshCacheRoute->setPopularity($popularity);
36 |
37 | return $freshCacheRoute;
38 | }
39 | }
--------------------------------------------------------------------------------
/Service/Tag/GetExistingOrNewTagModel.php:
--------------------------------------------------------------------------------
1 | cacheTagRepository = $cacheTagRepository;
25 | $this->newTagModelProvider = $newTagModelProvider;
26 | }
27 |
28 | public function getByTag(string $cacheTag): CacheTagInterface
29 | {
30 | $cacheTag = $this->cacheTagRepository->getByTag($cacheTag);
31 |
32 | if (!$cacheTag) {
33 | $cacheTag = $this->newTagModelProvider->createForTag($cacheTag);
34 | $this->cacheTagRepository->save($cacheTag);
35 | $cacheTag = $this->cacheTagRepository->getByTag($cacheTag);
36 | }
37 |
38 | return $cacheTag;
39 | }
40 | }
--------------------------------------------------------------------------------
/Service/Tag/NewTagModelProvider.php:
--------------------------------------------------------------------------------
1 | cacheTagInterfaceFactory = $cacheTagInterfaceFactory;
19 | }
20 |
21 | public function createForTag(string $cacheTag): CacheTagInterface
22 | {
23 | /** @var CacheTagInterface $tagModel */
24 | $tagModel = $this->cacheTagInterfaceFactory->create();
25 | $tagModel->setCacheTag($cacheTag);
26 |
27 | return $tagModel;
28 | }
29 | }
--------------------------------------------------------------------------------
/Setup/InstallSchema.php:
--------------------------------------------------------------------------------
1 | startSetup();
18 | $setup->getConnection()->createTable($this->getCacheTagTableDefinition($setup));
19 | $setup->getConnection()->createTable($this->getCacheRouteTableDefinition($setup));
20 | $setup->getConnection()->createTable($this->getCacheRouteTagTableDefinition($setup));
21 | $setup->getConnection()->createTable($this->getVaryDataTableDefinition($setup));
22 | $this->addCacheRouteTagForeignKeys($setup);
23 | $setup->endSetup();
24 | }
25 |
26 | /**
27 | * @param SchemaSetupInterface $setup
28 | * @return \Magento\Framework\DB\Ddl\Table
29 | * @throws \Zend_Db_Exception
30 | */
31 | private function getCacheTagTableDefinition(SchemaSetupInterface $setup): \Magento\Framework\DB\Ddl\Table
32 | {
33 | return $setup->getConnection()->newTable($setup->getTable('cache_tags'))
34 | ->addColumn(
35 | 'id',
36 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
37 | null,
38 | [
39 | 'identity' => true,
40 | 'nullable' => false,
41 | 'primary' => true,
42 | 'unsigned' => true,
43 | ],
44 | 'Cache Tag ID'
45 | )
46 | ->addColumn(
47 | 'cache_tag',
48 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
49 | 255,
50 | ['nullable' => false],
51 | 'Cache Tag'
52 | )
53 | ->setComment('Cache Tag Table');
54 | }
55 |
56 | /**
57 | * @param SchemaSetupInterface $setup
58 | * @return \Magento\Framework\DB\Ddl\Table
59 | * @throws \Zend_Db_Exception
60 | */
61 | private function getVaryDataTableDefinition(SchemaSetupInterface $setup): \Magento\Framework\DB\Ddl\Table
62 | {
63 | return $setup->getConnection()->newTable($setup->getTable('cache_vary_data'))
64 | ->addColumn(
65 | 'vary_data',
66 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
67 | 255,
68 | [
69 | 'nullable' => false,
70 | 'primary' => true
71 | ],
72 | 'Cache Vary Data'
73 | )
74 | ->addIndex(
75 | $setup->getIdxName(
76 | 'cache_vary_data',
77 | ['vary_data'],
78 | \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
79 | ),
80 | ['vary_data'],
81 | ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
82 | )
83 | ->setComment('Cache Vary Data Table');
84 | }
85 |
86 | /**
87 | * @param SchemaSetupInterface $setup
88 | * @return \Magento\Framework\DB\Ddl\Table
89 | * @throws \Zend_Db_Exception
90 | */
91 | private function getCacheRouteTableDefinition(SchemaSetupInterface $setup): \Magento\Framework\DB\Ddl\Table
92 | {
93 | return $setup->getConnection()->newTable($setup->getTable('cache_routes'))
94 | ->addColumn(
95 | 'id',
96 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
97 | null,
98 | [
99 | 'identity' => true,
100 | 'nullable' => false,
101 | 'primary' => true,
102 | 'unsigned' => true,
103 | ],
104 | 'Cache Route ID'
105 | )
106 | ->addColumn(
107 | 'cache_route',
108 | \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
109 | 255,
110 | ['nullable' => false],
111 | 'Cache Route'
112 | )
113 | ->addIndex(
114 | $setup->getIdxName(
115 | 'cache_routes',
116 | ['cache_route'],
117 | \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
118 | ),
119 | ['cache_route'],
120 | ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
121 | )
122 | ->addColumn(
123 | 'cache_status',
124 | \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
125 | 1,
126 | ['nullable' => false],
127 | 'Cache Status'
128 | )
129 | ->addColumn(
130 | 'lifetime',
131 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
132 | null,
133 | ['nullable' => false],
134 | 'Cache Route Lifetime'
135 | )
136 | ->addColumn(
137 | 'popularity',
138 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
139 | null,
140 | ['nullable' => false],
141 | 'Cache Route Populariy'
142 | )
143 | ->setComment('Cache Route Table');
144 | }
145 |
146 | /**
147 | * @param SchemaSetupInterface $setup
148 | * @return \Magento\Framework\DB\Ddl\Table
149 | * @throws \Zend_Db_Exception
150 | */
151 | private function getCacheRouteTagTableDefinition(SchemaSetupInterface $setup): \Magento\Framework\DB\Ddl\Table
152 | {
153 | return $setup->getConnection()->newTable($setup->getTable('cache_routes_tags'))
154 | ->addColumn(
155 | 'route_id',
156 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
157 | null,
158 | ['nullable' => false, 'unsigned' => true],
159 | 'Cache Tag ID'
160 | )
161 | ->addColumn(
162 | 'tag_id',
163 | \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
164 | null,
165 | ['nullable => false', 'unsigned' => true],
166 | 'Cache Tag'
167 | )
168 | ->setComment('Cache Tag Table');
169 | }
170 |
171 | /**
172 | * @param SchemaSetupInterface $setup
173 | */
174 | private function addCacheRouteTagForeignKeys(SchemaSetupInterface $setup): void
175 | {
176 | /**
177 | * Add foreign keys again
178 | */
179 | $setup->getConnection()->addForeignKey(
180 | $setup->getFkName(
181 | 'cache_routes',
182 | 'id',
183 | 'cache_route_tags',
184 | 'route_id'
185 | ),
186 | $setup->getTable('cache_routes_tags'),
187 | 'route_id',
188 | $setup->getTable('cache_routes'),
189 | 'id',
190 | \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
191 | );
192 | $setup->getConnection()->addForeignKey(
193 | $setup->getFkName(
194 | 'cache_tags',
195 | 'id',
196 | 'cache_route_tags',
197 | 'tag_id'
198 | ),
199 | $setup->getTable('cache_routes_tags'),
200 | 'tag_id',
201 | $setup->getTable('cache_tags'),
202 | 'id',
203 | \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
204 | );
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "firegento/m2-cache-warmup",
3 | "description": "Warmup Pagecache by crawling all url_rewrites",
4 | "repositories": [
5 | {
6 | "type": "composer",
7 | "url": "https://repo.magento.com/"
8 | }
9 | ],
10 | "require": {
11 | "php": "~7.0.0|~7.1.0|~7.2.0",
12 | "magento/framework": "*",
13 | "guzzlehttp/guzzle": "~6.2"
14 | },
15 | "type": "magento2-module",
16 | "version": "0.1.0",
17 | "autoload": {
18 | "files": [
19 | "registration.php"
20 | ],
21 | "psr-4": {
22 | "Firegento\\CacheWarmup\\": ""
23 | }
24 | },
25 | "autoload-dev": {
26 | "psr-4": {
27 | "Magento\\Framework\\": "lib/internal/Magento/Framework/"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | - Firegento\CacheWarmup\Console\Command\CacheWarmup
8 |
9 |
10 |
11 |
15 |
19 |
23 |
27 |
31 |
35 |
39 |
40 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/etc/frontend/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | - Firegento\CacheWarmup\Model\VaryData\Applicator\CustomerGroupApplicator
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/etc/webapi.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/view/frontend/web/increment-popularity.js:
--------------------------------------------------------------------------------
1 | require([
2 | 'mage/storage'
3 | ], function (storage) {
4 | 'use strict';
5 | storage.put(
6 | '/rest/V1/increment-popularity',
7 | JSON.stringify({
8 | route: location.pathname
9 | })
10 | );
11 | });
12 |
--------------------------------------------------------------------------------