├── .gitignore
├── Block
└── Adminhtml
│ └── Cache.php
├── Console
└── Command
│ ├── Disable.php
│ └── WarmCache.php
├── Controller
└── Adminhtml
│ └── WarmCache
│ └── Run.php
├── Cron
└── Run.php
├── Helper
└── Data.php
├── README.md
├── composer.json
├── etc
├── acl.xml
├── adminhtml
│ ├── routes.xml
│ └── system.xml
├── cron_groups.xml
├── crontab.xml
├── di.xml
└── module.xml
└── registration.php
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | \.idea/
3 |
4 | \.DS_Store
5 |
--------------------------------------------------------------------------------
/Block/Adminhtml/Cache.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Block\Adminhtml;
15 |
16 | use Magento\Backend\Block\Cache as OriginalCache;
17 |
18 | class Cache extends OriginalCache
19 | {
20 | /**
21 | * Cache block constructor.
22 | */
23 | protected function _construct()
24 | {
25 | parent::_construct();
26 | $this->buttonList->add(
27 | 'warm_cache',
28 | [
29 | 'label' => __('Run Warm Cache'),
30 | 'onclick' => "window.location.href = '".$this->getWarmCacheUrl()."'",
31 | 'class' => 'run-warm-cache'
32 | ]
33 | );
34 | }
35 |
36 | /**
37 | * Get warm cache action url.
38 | * @return string
39 | */
40 | private function getWarmCacheUrl()
41 | {
42 | return $this->getUrl('warmcache/WarmCache/run');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Console/Command/Disable.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Console\Command;
15 |
16 | use Igorludgero\WarmCache\Helper\Data;
17 | use Magento\Framework\App\State;
18 | use Magento\Framework\App\ObjectManager;
19 | use Symfony\Component\Console\Command\Command;
20 | use Symfony\Component\Console\Input\InputInterface;
21 | use Symfony\Component\Console\Output\OutputInterface;
22 |
23 | class Disable extends Command
24 | {
25 | /**
26 | * @var State
27 | */
28 | protected $appState;
29 |
30 | /**
31 | * Disable constructor.
32 | * @param State $appState
33 | */
34 | public function __construct(
35 | State $appState
36 | ) {
37 | $this->appState = $appState;
38 | parent::__construct('igorludgero:warmcache_disable');
39 | }
40 |
41 | /**
42 | * Configure cli command.
43 | */
44 | protected function configure()
45 | {
46 | $this->setName('igorludgero:warmcache_disable')
47 | ->setDescription('Disable warm cache.');
48 | }
49 |
50 | /**
51 | * Execute cli command
52 | * @param InputInterface $input
53 | * @param OutputInterface $output
54 | * @return $this|int|null
55 | * @throws \Magento\Framework\Exception\LocalizedException
56 | */
57 | protected function execute(
58 | InputInterface $input,
59 | OutputInterface $output
60 | ) {
61 | $this->appState->setAreaCode('adminhtml');
62 | /**
63 | * @var $helper Data
64 | */
65 | $helper = ObjectManager::getInstance()->create(Data::class);
66 | $helper->disableExtension();
67 | $helper->logMessage("Warm cache disabled. Please clear the caches.");
68 | $output->writeln('Warm cache disabled. Please clear the caches.');
69 | return $this;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Console/Command/WarmCache.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Console\Command;
15 |
16 | use Igorludgero\WarmCache\Helper\Data;
17 | use Magento\Framework\App\State;
18 | use Magento\Framework\App\ObjectManager;
19 | use Symfony\Component\Console\Command\Command;
20 | use Symfony\Component\Console\Input\InputInterface;
21 | use Symfony\Component\Console\Output\OutputInterface;
22 |
23 | class WarmCache extends Command
24 | {
25 | /**
26 | * @var State
27 | */
28 | protected $appState;
29 |
30 | /**
31 | * WarmCache constructor.
32 | * @param State $appState
33 | */
34 | public function __construct(
35 | State $appState
36 | ) {
37 | $this->appState = $appState;
38 | parent::__construct('igorludgero:warmcache');
39 | }
40 |
41 | /**
42 | * Configure cli command.
43 | */
44 | protected function configure()
45 | {
46 | $this->setName('igorludgero:warmcache')
47 | ->setDescription('Run the warm cache and cache all available pages in the store.');
48 | }
49 |
50 | /**
51 | * Execute cli command
52 | * @param InputInterface $input
53 | * @param OutputInterface $output
54 | * @return $this|int|null
55 | * @throws \Magento\Framework\Exception\LocalizedException
56 | */
57 | protected function execute(
58 | InputInterface $input,
59 | OutputInterface $output
60 | ) {
61 | $this->appState->setAreaCode('adminhtml');
62 | /**
63 | * @var $helper Data
64 | */
65 | $helper = ObjectManager::getInstance()->create(Data::class);
66 | if ($helper->run()) {
67 | $helper->logMessage("Warm cache process finished.");
68 | $output->writeln('Warm cache process finished.');
69 | } else {
70 | $output->writeln('Was not possible to run the command, please try again later. '.
71 | 'Check if the extension is enabled on admin and if you enabled at least one warm cache type.');
72 | }
73 | return $this;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/WarmCache/Run.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Controller\Adminhtml\WarmCache;
15 |
16 | use Magento\Backend\App\Action;
17 | use Magento\Backend\App\Action\Context;
18 | use Magento\Framework\Controller\ResultFactory;
19 | use Igorludgero\WarmCache\Helper\Data;
20 |
21 | class Run extends Action
22 | {
23 | /**
24 | * @var Data
25 | */
26 | protected $helper;
27 |
28 | /**
29 | * Run constructor.
30 | * @param Action\Context $context
31 | * @param Data $helper
32 | */
33 | public function __construct(
34 | Context $context,
35 | Data $helper
36 | ) {
37 | parent::__construct($context);
38 | $this->_helper = $helper;
39 | }
40 |
41 | /**
42 | * Start the WarmCache.
43 | */
44 | public function execute()
45 | {
46 | $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
47 | $this->_helper->run();
48 | $this->messageManager->addSuccessMessage(__("Warm cache ran successfully!"));
49 | $resultRedirect->setUrl($this->_redirect->getRefererUrl());
50 | return $resultRedirect;
51 | }
52 |
53 | protected function _isAllowed()
54 | {
55 | return $this->_authorization->isAllowed('Igorludgero_Warmcache::settings');
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Cron/Run.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Cron;
15 |
16 | use Igorludgero\WarmCache\Helper\Data;
17 |
18 | class Run
19 | {
20 |
21 | /**
22 | * @var Data
23 | */
24 | protected $helper;
25 |
26 | /**
27 | * Run constructor.
28 | * @param Data $helper
29 | */
30 | public function __construct(Data $helper)
31 | {
32 | $this->helper = $helper;
33 | }
34 |
35 | /**
36 | * Run the warm cache process.
37 | * @return $this
38 | */
39 | public function execute()
40 | {
41 | $this->helper->run();
42 | return $this;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Helper/Data.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | namespace Igorludgero\WarmCache\Helper;
15 |
16 | use Magento\Catalog\Model\CategoryFactory;
17 | use Magento\Catalog\Model\Product\Attribute\Source\Status;
18 | use Magento\Catalog\Model\Product\Visibility;
19 | use Magento\Catalog\Model\ProductFactory;
20 | use Magento\Cms\Model\PageFactory;
21 | use Magento\Framework\App\Config\Storage\WriterInterface;
22 | use Magento\Framework\App\Helper\AbstractHelper;
23 | use Magento\Framework\App\Helper\Context;
24 | use Magento\Framework\Url;
25 | use Magento\Store\Model\ScopeInterface;
26 | use Magento\UrlRewrite\Model\UrlRewriteFactory;
27 | use Zend\Log\Logger;
28 |
29 | class Data extends AbstractHelper
30 | {
31 |
32 | /**
33 | * @var array
34 | */
35 | protected $urls = array();
36 |
37 | /**
38 | * @var ProductFactory
39 | */
40 | protected $productModel;
41 |
42 | /**
43 | * @var CategoryFactory
44 | */
45 | protected $categoryModel;
46 |
47 | /**
48 | * @var PageFactory
49 | */
50 | protected $pageModel;
51 |
52 | /**
53 | * @var UrlRewriteFactory
54 | */
55 | protected $urlRewriteModel;
56 |
57 | /**
58 | * @var Logger
59 | */
60 | protected $logger;
61 |
62 | /**
63 | * @var Url
64 | */
65 | protected $frontUrlModel;
66 |
67 | /**
68 | * @var WriterInterface
69 | */
70 | protected $writerInterface;
71 |
72 | /**
73 | * Data constructor.
74 | * @param Context $context
75 | * @param ProductFactory $productModel
76 | * @param CategoryFactory $categoryModel
77 | * @param PageFactory $pageModel
78 | * @param UrlRewriteFactory $urlRewriteModel
79 | * @param Url $frontUrlModel
80 | * @param WriterInterface $writerInterface
81 | */
82 | public function __construct(
83 | Context $context,
84 | ProductFactory $productModel,
85 | CategoryFactory $categoryModel,
86 | PageFactory $pageModel,
87 | UrlRewriteFactory $urlRewriteModel,
88 | Url $frontUrlModel,
89 | WriterInterface $writerInterface
90 | ) {
91 | parent::__construct($context);
92 | $this->productModel = $productModel;
93 | $this->categoryModel = $categoryModel;
94 | $this->pageModel = $pageModel;
95 | $this->urlRewriteModel = $urlRewriteModel;
96 | $this->frontUrlModel = $frontUrlModel;
97 | $this->writerInterface = $writerInterface;
98 | $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/igorludgero_warmcache.log');
99 | $this->logger = new \Zend\Log\Logger();
100 | $this->logger->addWriter($writer);
101 | }
102 |
103 | /**
104 | * Log a custom message.
105 | * @param $message
106 | */
107 | public function logMessage($message)
108 | {
109 | $this->logger->info($message);
110 | }
111 |
112 | /**
113 | * Get all urls to be cached.
114 | */
115 | private function getUrls()
116 | {
117 | //Add Products url
118 | if ($this->scopeConfig->getValue('warmcache/settings/product', ScopeInterface::SCOPE_STORE)) {
119 | $_productCollection = $this->productModel->create()->getCollection()
120 | ->addAttributeToFilter('status', Status::STATUS_ENABLED)
121 | ->addAttributeToFilter(
122 | 'visibility',
123 | array(Visibility::VISIBILITY_IN_CATALOG, Visibility::VISIBILITY_BOTH)
124 | )
125 | ->addAttributeToSelect(["entity_id"]);
126 | foreach ($_productCollection as $_product) {
127 | $url = $this->frontUrlModel->getUrl("catalog/product/view", ['id' => $_product->getId()]);
128 | if (!in_array($url, $this->urls)) {
129 | $this->urls[] = $url;
130 | }
131 | }
132 | }
133 |
134 | //Add category url
135 | if ($this->scopeConfig->getValue('warmcache/settings/category', ScopeInterface::SCOPE_STORE)) {
136 | $_categoryCollection = $this->categoryModel->create()->getCollection()
137 | ->addAttributeToFilter('is_active', 1)
138 | ->addAttributeToSelect(["entity_id"]);
139 | foreach ($_categoryCollection as $_category) {
140 | $url = $this->frontUrlModel->getUrl("catalog/category/view", ['id' => $_category->getId()]);
141 | if (!in_array($url, $this->urls)) {
142 | $this->urls[] = $url;
143 | }
144 | }
145 | }
146 |
147 | //Add cms pages
148 | if ($this->scopeConfig->getValue('warmcache/settings/cms_pages', ScopeInterface::SCOPE_STORE)) {
149 | $_cmsPageCollection = $this->pageModel->create()->getCollection()->addFieldToFilter("is_active", 1)
150 | ->addFieldToSelect("page_id");
151 | foreach ($_cmsPageCollection as $page) {
152 | $url = $this->frontUrlModel->getUrl("cms/page/view", ['id' => $page->getId()]);
153 | if (!in_array($url, $this->urls)) {
154 | $this->urls[] = $url;
155 | }
156 | }
157 | }
158 |
159 | //Custom urls in url rewrite.
160 | if ($this->scopeConfig->getValue('warmcache/settings/url_rewrite', ScopeInterface::SCOPE_STORE)) {
161 | $_urlRewriteCollection = $this->urlRewriteModel->create()
162 | ->getCollection()
163 | ->addFieldToSelect("target_path")
164 | ->addFieldToFilter('entity_type', array('nin' => array('cms-page', 'category', 'product')));
165 | foreach ($_urlRewriteCollection as $urlRewrite) {
166 | $newUrl = $this->frontUrlModel->getBaseUrl() . $urlRewrite->getRequestPath();
167 | if (!in_array($newUrl, $this->urls)) {
168 | $this->urls[] = $newUrl;
169 | }
170 | }
171 | }
172 | }
173 |
174 | /**
175 | * Run the crawler.
176 | */
177 | public function run()
178 | {
179 | if ($this->isEnabled()) {
180 | $this->getUrls();
181 | if (count($this->urls) > 0) {
182 | try {
183 | foreach ($this->urls as $url) {
184 | $this->checkUrl($url);
185 | }
186 | return true;
187 | } catch (\Exception $ex) {
188 | $this->logMessage("Error in WarmCache: " . $ex->getMessage());
189 | return false;
190 | }
191 | }
192 | }
193 | return false;
194 | }
195 |
196 | /**
197 | * Render the url.
198 | * @param $url
199 | */
200 | private function checkUrl($url)
201 | {
202 | $user_agent='Mozilla/4.0 (compatible;)';
203 |
204 | $options = array(
205 |
206 | CURLOPT_CUSTOMREQUEST =>"GET", //set request type post or get
207 | CURLOPT_POST =>false, //set to GET
208 | CURLOPT_USERAGENT => $user_agent, //set user agent
209 | CURLOPT_COOKIEFILE =>"cookie.txt", //set cookie file
210 | CURLOPT_COOKIEJAR =>"cookie.txt", //set cookie jar
211 | CURLOPT_RETURNTRANSFER => true, // return web page
212 | CURLOPT_HEADER => false, // don't return headers
213 | CURLOPT_FOLLOWLOCATION => true, // follow redirects
214 | CURLOPT_ENCODING => "", // handle all encodings
215 | CURLOPT_AUTOREFERER => true, // set referer on redirect
216 | CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
217 | CURLOPT_TIMEOUT => 120, // timeout on response
218 | CURLOPT_MAXREDIRS => 4, // stop after 10 redirects
219 | );
220 |
221 | $ch = curl_init($url);
222 | curl_setopt_array($ch, $options);
223 | $content = curl_exec($ch);
224 | $err = curl_errno($ch);
225 | $errmsg = curl_error($ch);
226 | $header = curl_getinfo($ch);
227 | curl_close($ch);
228 |
229 | $header['errno'] = $err;
230 | $header['errmsg'] = $errmsg;
231 | $header['content'] = $content;
232 | }
233 |
234 | /**
235 | * Disable warm cache enable setting
236 | */
237 | public function disableExtension()
238 | {
239 | $this->writerInterface->save("warmcache/settings/enable", 0);
240 | }
241 |
242 | /**
243 | * Is the extension enabled
244 | * @return bool
245 | */
246 | public function isEnabled()
247 | {
248 | return (bool)$this->scopeConfig->getValue('warmcache/settings/enable', ScopeInterface::SCOPE_STORE);
249 | }
250 | }
251 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cache warm extension for Magento 2 (FREE).
2 | A warm cache extension for Magento 2.
3 | This extension adds the feature of cache warm to Magento 2. It's possible to start the cache warm process from admin inside the cache management section, by the cronjob or using a command line.
4 |
5 | ### Install using composer:
6 | composer require igorludgero/warmcache
7 |
8 | ### Run the warmer from admin:
9 | http://prntscr.com/gj8ebu
10 |
11 | ### Cron job:
12 | http://prntscr.com/gj8ejs
13 |
14 | ### Cli command:
15 | php bin/magento igorludgero:warmcache
16 |
17 | #### Contact me in my email: igor@igorludgero.com
18 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "igorludgero/warmcache",
3 | "require": {
4 | },
5 | "type": "magento2-module",
6 | "version": "1.0.2",
7 | "description": "A warm cache extension for Magento 2.1 and 2.2",
8 | "autoload": {
9 | "files": [
10 | "registration.php"
11 | ],
12 | "psr-4": {
13 | "Igorludgero\\WarmCache\\": ""
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/etc/acl.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/etc/adminhtml/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | igorludgero
22 | Igorludgero_WarmCache::settings
23 |
24 |
25 | Select each entity type you want to add in the warm cache process.
26 |
27 |
28 | Magento\Config\Model\Config\Source\Yesno
29 |
30 |
31 |
32 | Magento\Config\Model\Config\Source\Yesno
33 |
34 | 1
35 |
36 |
37 |
38 |
39 | Magento\Config\Model\Config\Source\Yesno
40 |
41 | 1
42 |
43 |
44 |
45 |
46 | Magento\Config\Model\Config\Source\Yesno
47 |
48 | 1
49 |
50 |
51 |
52 |
53 | Magento\Config\Model\Config\Source\Yesno
54 |
55 | 1
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/etc/cron_groups.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 | 1380
17 | 4
18 | 2
19 | 10
20 | 60
21 | 600
22 | 1
23 |
24 |
--------------------------------------------------------------------------------
/etc/crontab.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 | * * * * *
18 |
19 |
20 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 | - Igorludgero\WarmCache\Console\Command\WarmCache
20 | - Igorludgero\WarmCache\Console\Command\Disable
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
11 | * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
12 | */
13 |
14 | \Magento\Framework\Component\ComponentRegistrar::register(
15 | \Magento\Framework\Component\ComponentRegistrar::MODULE,
16 | 'Igorludgero_WarmCache',
17 | __DIR__
18 | );
--------------------------------------------------------------------------------