diff --git a/Block/Adminhtml/Cache.php b/Block/Adminhtml/Cache.php
new file mode 100644
index 0000000..480d29b
--- /dev/null
+++ b/Block/Adminhtml/Cache.php
@@ -0,0 +1,43 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+namespace Igorludgero\WarmCache\Block\Adminhtml;
+
+class Cache extends \Magento\Backend\Block\Cache
+{
+ /**
+ * Cache block constructor.
+ */
+ protected function _construct()
+ {
+ parent::_construct();
+ $message = __('The Warm Cache will access a lot of store urls like product, category and cms pages to rebuild the caches. Do you agree to start now?');
+ $this->buttonList->add(
+ 'warm_cache',
+ [
+ 'label' => __('Run Warm Cache'),
+ 'onclick' => 'confirmSetLocation(\'' . $message . '\', \'' . $this->getWarmCacheUrl() . '\')',
+ 'class' => 'run-warm-cache'
+ ]
+ );
+ }
+
+ /**
+ * Get warm cache action url.
+ * @return string
+ */
+ private function getWarmCacheUrl(){
+ return $this->getUrl('warmcache/WarmCache/run');
+ }
+
+}
\ No newline at end of file
diff --git a/Console/Command/WarmCache.php b/Console/Command/WarmCache.php
new file mode 100644
index 0000000..6264d91
--- /dev/null
+++ b/Console/Command/WarmCache.php
@@ -0,0 +1,68 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+namespace Igorludgero\WarmCache\Console\Command;
+
+class WarmCache extends \Symfony\Component\Console\Command\Command
+{
+
+ /**
+ * @var \Igorludgero\WarmCache\Helper\Data
+ */
+ protected $_helper;
+
+ /**
+ * @var \Magento\Framework\App\State
+ */
+ protected $_appState;
+
+ /**
+ * WarmCache constructor.
+ * @param \Igorludgero\WarmCache\Helper\Data $helper
+ */
+ public function __construct(\Magento\Framework\App\State $appState,
+ \Igorludgero\WarmCache\Helper\Data $helper)
+ {
+ $this->_helper = $helper;
+ $this->_appState = $appState;
+ parent::__construct('igorludgero:warmcache');
+ }
+
+ /**
+ * Configure cli command.
+ */
+ protected function configure()
+ {
+ $this->setName('igorludgero:warmcache')->setDescription('Run the warm cache and cache all available pages in the store.');
+ }
+
+ /**
+ * Execute cli command.
+ * @param \Symfony\Component\Console\Input\InputInterface $input
+ * @param \Symfony\Component\Console\Output\OutputInterface $output
+ * @return $this
+ */
+ protected function execute(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output)
+ {
+ $this->_appState->setAreaCode('adminhtml');
+ if($this->_helper->run()){
+ $this->_helper->logMessage("Warm cache process finished.");
+ $output->writeln('Warm cache process finished.');
+ }
+ else{
+ $output->writeln('Was not possible to run the command, please try again later.');
+ }
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/Controller/Adminhtml/WarmCache/Run.php b/Controller/Adminhtml/WarmCache/Run.php
new file mode 100644
index 0000000..786c1e2
--- /dev/null
+++ b/Controller/Adminhtml/WarmCache/Run.php
@@ -0,0 +1,49 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+namespace Igorludgero\WarmCache\Controller\Adminhtml\WarmCache;
+
+use Magento\Backend\App\Action;
+
+class Run extends \Magento\Backend\App\Action
+{
+
+ /**
+ * @var \Igorludgero\WarmCache\Helper\Data
+ */
+ protected $_helper;
+
+ /**
+ * Run constructor.
+ * @param Action\Context $context
+ * @param \Igorludgero\WarmCache\Helper\Data $helper
+ */
+ public function __construct(\Magento\Backend\App\Action\Context $context, \Igorludgero\WarmCache\Helper\Data $helper)
+ {
+ parent::__construct($context);
+ $this->_helper = $helper;
+ }
+
+ /**
+ * Start the WarmCache.
+ */
+ public function execute()
+ {
+ $resultRedirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
+ $this->_helper->run();
+ $this->messageManager->addSuccessMessage(__("Warm cache ran successfully!"));
+ $resultRedirect->setUrl($this->_redirect->getRefererUrl());
+ return $resultRedirect;
+ }
+
+}
\ No newline at end of file
diff --git a/Cron/Run.php b/Cron/Run.php
new file mode 100644
index 0000000..4fded8f
--- /dev/null
+++ b/Cron/Run.php
@@ -0,0 +1,44 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+namespace Igorludgero\WarmCache\Cron;
+
+class Run
+{
+
+ /**
+ * @var \Igorludgero\WarmCache\Helper\Data
+ */
+ protected $_helper;
+
+ /**
+ * Run constructor.
+ * @param \Igorludgero\WarmCache\Helper\Data $helper
+ */
+ public function __construct(\Igorludgero\WarmCache\Helper\Data $helper)
+ {
+ $this->_helper = $helper;
+ }
+
+ /**
+ * Run the warm cache process.
+ * @return $this
+ */
+ public function execute()
+ {
+
+ $this->_helper->run();
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/Helper/Data.php b/Helper/Data.php
new file mode 100644
index 0000000..6f1e6b4
--- /dev/null
+++ b/Helper/Data.php
@@ -0,0 +1,204 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+namespace Igorludgero\WarmCache\Helper;
+
+class Data extends \Magento\Framework\App\Helper\AbstractHelper
+{
+
+ /**
+ * @var array
+ */
+ protected $_urls = array();
+
+ /**
+ * @var \Magento\Catalog\Model\Product
+ */
+ protected $_productModel;
+
+ /**
+ * @var \Magento\Catalog\Model\Category
+ */
+ protected $_categoryModel;
+
+ /**
+ * @var \Magento\Cms\Model\Page
+ */
+ protected $_pageModel;
+
+ /**
+ * @var \Magento\UrlRewrite\Model\UrlRewrite
+ */
+ protected $_urlRewriteModel;
+
+ /**
+ * @var \Zend\Log\Logger
+ */
+ protected $_logger;
+
+ /**
+ * @var \Magento\Framework\Url
+ */
+ protected $_frontUrlModel;
+
+ /**
+ * Data constructor.
+ * @param \Magento\Framework\App\Helper\Context $context
+ * @param \Magento\Catalog\Model\Product $productModel
+ * @param \Magento\Catalog\Model\Category $categoryModel
+ * @param \Magento\Cms\Model\Page $pageModel
+ * @param \Magento\UrlRewrite\Model\UrlRewrite $urlRewriteModel
+ * @param \Magento\Framework\Url $frontUrlModel
+ */
+ public function __construct(\Magento\Framework\App\Helper\Context $context,
+ \Magento\Catalog\Model\Product $productModel,
+ \Magento\Catalog\Model\Category $categoryModel,
+ \Magento\Cms\Model\Page $pageModel,
+ \Magento\UrlRewrite\Model\UrlRewrite $urlRewriteModel,
+ \Magento\Framework\Url $frontUrlModel)
+ {
+ parent::__construct($context);
+ $this->_productModel = $productModel;
+ $this->_categoryModel = $categoryModel;
+ $this->_pageModel = $pageModel;
+ $this->_urlRewriteModel = $urlRewriteModel;
+ $this->_frontUrlModel = $frontUrlModel;
+ $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/igorludgero_warmcache.log');
+ $this->_logger = new \Zend\Log\Logger();
+ $this->_logger->addWriter($writer);
+ $this->getUrls();
+ }
+
+ /**
+ * Log a custom message.
+ * @param $message
+ */
+ public function logMessage($message){
+ $this->_logger->info($message);
+ }
+
+ /**
+ * Get all urls to be cached.
+ */
+ private function getUrls(){
+
+ //Add Products url
+ if($this->scopeConfig->getValue('warmcache/settings/product', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+ $_productCollection = $this->_productModel->getCollection()
+ ->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+ ->addAttributeToFilter('visibility', array(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG, \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH))
+ ->addAttributeToSelect(["entity_id"]);
+ foreach ($_productCollection as $_product) {
+ $url = $this->_frontUrlModel->getUrl("catalog/product/view", ['id' => $_product->getId()]);
+ if (!in_array($url, $this->_urls)) {
+ $this->_urls[] = $url;
+ }
+ }
+ }
+
+ //Add category url
+ if($this->scopeConfig->getValue('warmcache/settings/category', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+ $_categoryCollection = $this->_categoryModel->getCollection()
+ ->addAttributeToFilter('is_active', 1)
+ ->addAttributeToSelect(["entity_id"]);
+ foreach ($_categoryCollection as $_category) {
+ $url = $this->_frontUrlModel->getUrl("catalog/category/view", ['id' => $_category->getId()]);
+ if (!in_array($url, $this->_urls)) {
+ $this->_urls[] = $url;
+ }
+ }
+ }
+
+ //Add cms pages
+ if($this->scopeConfig->getValue('warmcache/settings/cms_pages', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+ $_cmsPageCollection = $this->_pageModel->getCollection()->addFieldToFilter("is_active", 1)
+ ->addFieldToSelect("page_id");
+ foreach ($_cmsPageCollection as $page) {
+ $url = $this->_frontUrlModel->getUrl("cms/page/view", ['id' => $page->getId()]);
+ if (!in_array($url, $this->_urls)) {
+ $this->_urls[] = $url;
+ }
+ }
+ }
+
+ //Custom urls in url rewrite.
+ if($this->scopeConfig->getValue('warmcache/settings/url_rewrite', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+ $_urlRewriteCollection = $this->_urlRewriteModel->getCollection()
+ ->addFieldToSelect("target_path")
+ ->addFieldToFilter('entity_type', array('nin' => array('cms-page', 'category', 'product')));
+ foreach ($_urlRewriteCollection as $urlRewrite) {
+ $newUrl = $this->_frontUrlModel->getBaseUrl() . $urlRewrite->getRequestPath();
+ if (!in_array($newUrl, $this->_urls)) {
+ $this->_urls[] = $newUrl;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Run the crawler.
+ */
+ public function run()
+ {
+ try {
+ foreach ($this->_urls as $url) {
+ $this->checkUrl($url);
+ }
+ return true;
+ }
+ catch (\Exception $ex){
+ $this->logMessage("Error in WarmCache: ".$ex->getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * Render the url.
+ * @param $url
+ */
+ function checkUrl( $url )
+ {
+ $user_agent='Mozilla/4.0 (compatible;)';
+
+ $options = array(
+
+ CURLOPT_CUSTOMREQUEST =>"GET", //set request type post or get
+ CURLOPT_POST =>false, //set to GET
+ CURLOPT_USERAGENT => $user_agent, //set user agent
+ CURLOPT_COOKIEFILE =>"cookie.txt", //set cookie file
+ CURLOPT_COOKIEJAR =>"cookie.txt", //set cookie jar
+ CURLOPT_RETURNTRANSFER => true, // return web page
+ CURLOPT_HEADER => false, // don't return headers
+ CURLOPT_FOLLOWLOCATION => true, // follow redirects
+ CURLOPT_ENCODING => "", // handle all encodings
+ CURLOPT_AUTOREFERER => true, // set referer on redirect
+ CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
+ CURLOPT_TIMEOUT => 120, // timeout on response
+ CURLOPT_MAXREDIRS => 4, // stop after 10 redirects
+ );
+
+ $ch = curl_init( $url );
+ curl_setopt_array( $ch, $options );
+ $content = curl_exec( $ch );
+ $err = curl_errno( $ch );
+ $errmsg = curl_error( $ch );
+ $header = curl_getinfo( $ch );
+ curl_close( $ch );
+
+ $header['errno'] = $err;
+ $header['errmsg'] = $errmsg;
+ $header['content'] = $content;
+ }
+
+}
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..a34bbfe
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "igorludgero/warmcache",
+ "require": {
+ "php": "~5.6.0|~7.0.0|~7.1.0"
+ },
+ "type": "magento2-module",
+ "version": "1.0.0",
+ "description": "A warm cache extension.",
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Igorludgero\\WarmCache\\": ""
+ }
+ }
+}
diff --git a/etc/acl.xml b/etc/acl.xml
new file mode 100644
index 0000000..41fb0ae
--- /dev/null
+++ b/etc/acl.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/routes.xml b/etc/adminhtml/routes.xml
new file mode 100644
index 0000000..75522c3
--- /dev/null
+++ b/etc/adminhtml/routes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
new file mode 100644
index 0000000..860a105
--- /dev/null
+++ b/etc/adminhtml/system.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+ igorludgero
+ Igorludgero_WarmCache::settings
+
+
+ Select each entity type you want to add in the warm cache process.
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+
+
\ No newline at end of file
diff --git a/etc/cron_groups.xml b/etc/cron_groups.xml
new file mode 100644
index 0000000..778c4d9
--- /dev/null
+++ b/etc/cron_groups.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ 1
+ 4
+ 2
+ 10
+ 60
+ 600
+ 1
+
+
\ No newline at end of file
diff --git a/etc/crontab.xml b/etc/crontab.xml
new file mode 100644
index 0000000..633d752
--- /dev/null
+++ b/etc/crontab.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ * * * * *
+
+
+
\ No newline at end of file
diff --git a/etc/di.xml b/etc/di.xml
new file mode 100755
index 0000000..91ce3a4
--- /dev/null
+++ b/etc/di.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ - Igorludgero\WarmCache\Console\Command\WarmCache
+
+
+
+
\ No newline at end of file
diff --git a/etc/module.xml b/etc/module.xml
new file mode 100644
index 0000000..91cf290
--- /dev/null
+++ b/etc/module.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/registration.php b/registration.php
new file mode 100755
index 0000000..6733e08
--- /dev/null
+++ b/registration.php
@@ -0,0 +1,18 @@
+
+ * @copyright Copyright (c) 2017 Igor Ludgero Miura (https://www.igorludgero.com/)
+ * @license https://opensource.org/licenses/OSL-3.0.php Open Software License 3.0
+ */
+
+\Magento\Framework\Component\ComponentRegistrar::register(
+ \Magento\Framework\Component\ComponentRegistrar::MODULE,
+ 'Igorludgero_WarmCache',
+ __DIR__
+);
\ No newline at end of file