From 00441906770b2e4ff3ad52e0e0e3e791e526ce79 Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Thu, 8 Oct 2026 13:38:40 +0530 Subject: [PATCH 1/8] Added: qlogsitemap module for XML sitemaps, and removed the dead HTML sitemap page --- classes/controller/FrontController.php | 1 - config/xml/themes/default.xml | 1 - controllers/admin/AdminMetaController.php | 8 +- controllers/admin/AdminStoresController.php | 6 - controllers/front/SitemapController.php | 59 ---- install-dev/data/xml/meta.xml | 6 - modules/qlogsitemap/LICENSE.md | 223 +++++++++++++ modules/qlogsitemap/classes/QgsHelper.php | 126 ++++++++ modules/qlogsitemap/classes/index.php | 32 ++ modules/qlogsitemap/index.php | 32 ++ modules/qlogsitemap/logo.gif | Bin 0 -> 1041 bytes modules/qlogsitemap/logo.png | Bin 0 -> 5839 bytes modules/qlogsitemap/qlogsitemap.php | 292 ++++++++++++++++++ modules/qlogsitemap/views/index.php | 32 ++ .../views/templates/hook/index.php | 32 ++ .../views/templates/hook/sitemap-panel.tpl | 57 ++++ modules/qlogsitemap/views/templates/index.php | 32 ++ .../hotel-reservation-theme/css/sitemap.css | 43 --- .../img/sitemap-horizontal.png | Bin 71 -> 0 bytes .../img/sitemap-last.png | Bin 97 -> 0 bytes .../hotel-reservation-theme/sass/sitemap.scss | 66 ---- themes/hotel-reservation-theme/sitemap.tpl | 203 ------------ 22 files changed, 864 insertions(+), 387 deletions(-) delete mode 100644 controllers/front/SitemapController.php create mode 100644 modules/qlogsitemap/LICENSE.md create mode 100644 modules/qlogsitemap/classes/QgsHelper.php create mode 100644 modules/qlogsitemap/classes/index.php create mode 100644 modules/qlogsitemap/index.php create mode 100644 modules/qlogsitemap/logo.gif create mode 100644 modules/qlogsitemap/logo.png create mode 100755 modules/qlogsitemap/qlogsitemap.php create mode 100644 modules/qlogsitemap/views/index.php create mode 100644 modules/qlogsitemap/views/templates/hook/index.php create mode 100644 modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl create mode 100644 modules/qlogsitemap/views/templates/index.php delete mode 100644 themes/hotel-reservation-theme/css/sitemap.css delete mode 100644 themes/hotel-reservation-theme/img/sitemap-horizontal.png delete mode 100644 themes/hotel-reservation-theme/img/sitemap-last.png delete mode 100644 themes/hotel-reservation-theme/sass/sitemap.scss delete mode 100644 themes/hotel-reservation-theme/sitemap.tpl diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php index 782f01f4a..332ce9a47 100644 --- a/classes/controller/FrontController.php +++ b/classes/controller/FrontController.php @@ -1767,7 +1767,6 @@ class FrontControllerCore extends Controller 'categoriescmsTree' => CMSCategory::getRecurseCategory($this->context->language->id, 1, 1, 1), 'voucherAllowed' => (int)CartRule::isFeatureActive(), 'PS_DISPLAY_BEST_SELLERS' => Configuration::get('PS_DISPLAY_BEST_SELLERS'), - 'display_store' => Configuration::get('PS_STORES_DISPLAY_SITEMAP'), 'conditions' => Configuration::get('PS_CONDITIONS'), 'id_cgv' => Configuration::get('PS_CONDITIONS_CMS_ID'), 'PS_SHOP_NAME' => Configuration::get('PS_SHOP_NAME'), diff --git a/config/xml/themes/default.xml b/config/xml/themes/default.xml index b8d22534f..220d18e4a 100644 --- a/config/xml/themes/default.xml +++ b/config/xml/themes/default.xml @@ -19,7 +19,6 @@ - diff --git a/controllers/admin/AdminMetaController.php b/controllers/admin/AdminMetaController.php index c7622250d..3b2bb809f 100644 --- a/controllers/admin/AdminMetaController.php +++ b/controllers/admin/AdminMetaController.php @@ -75,7 +75,7 @@ class AdminMetaControllerCore extends AdminController parent::__construct(); - $this->sm_file = _PS_ROOT_DIR_.DIRECTORY_SEPARATOR.$this->context->shop->id.'_index_sitemap.xml'; + $this->sm_file = _PS_ROOT_DIR_.DIRECTORY_SEPARATOR.'sitemap.xml'; // Options to generate friendly urls $mod_rewrite = Tools::modRewriteActive(); $general_fields = array( @@ -134,7 +134,11 @@ class AdminMetaControllerCore extends AdminController } // Options to generate robot.txt - $robots_description = $this->l('Your robots.txt file MUST be in your website\'s root directory and nowhere else (e.g. http://www.example.com/robots.txt).'); + $robots_url = Tools::safeOutput($this->context->link->getBaseLink().'robots.txt'); + $robots_description = sprintf( + $this->l('Your robots.txt file MUST be in your website\'s root directory and nowhere else (e.g. %s).'), + ''.$robots_url.'' + ); if ($this->checkConfiguration($this->rb_file)) { $robots_description .= $this->l('Generate your "robots.txt" file by clicking on the following button (this will erase the old robots.txt file)'); $robots_submit = array('name' => 'submitRobots', 'title' => $this->l('Generate robots.txt file')); diff --git a/controllers/admin/AdminStoresController.php b/controllers/admin/AdminStoresController.php index a4bcbb423..629da2633 100644 --- a/controllers/admin/AdminStoresController.php +++ b/controllers/admin/AdminStoresController.php @@ -80,12 +80,6 @@ class AdminStoresControllerCore extends AdminController 'cast' => 'intval', 'type' => 'bool' ), - 'PS_STORES_DISPLAY_SITEMAP' => array( - 'title' => $this->l('Display in the sitemap page'), - 'hint' => $this->l('Display a link to the store locator in the sitemap page.'), - 'cast' => 'intval', - 'type' => 'bool' - ), 'PS_STORES_SIMPLIFIED' => array( 'title' => $this->l('Show a simplified store locator'), 'hint' => $this->l('No map, no search, only a store directory.'), diff --git a/controllers/front/SitemapController.php b/controllers/front/SitemapController.php deleted file mode 100644 index e2604f977..000000000 --- a/controllers/front/SitemapController.php +++ /dev/null @@ -1,59 +0,0 @@ - -* @copyright 2007-2017 PrestaShop SA -* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -class SitemapControllerCore extends FrontController -{ - public $php_self = 'sitemap'; - - public function init() - { - Tools::redirect($this->context->link->getPageLink('index')); - } - - public function setMedia() - { - parent::setMedia(); - $this->addCSS(_THEME_CSS_DIR_.'sitemap.css'); - $this->addJS(_THEME_JS_DIR_.'tools/treeManagement.js'); - } - - /** - * Assign template vars related to page content - * @see FrontController::initContent() - */ - public function initContent() - { - parent::initContent(); - - $this->context->smarty->assign('categoriesTree', Category::getRootCategory()->recurseLiteCategTree(0)); - $this->context->smarty->assign('categoriescmsTree', CMSCategory::getRecurseCategory($this->context->language->id, 1, 1, 1)); - $this->context->smarty->assign('voucherAllowed', (int)CartRule::isFeatureActive()); - $this->context->smarty->assign('PS_DISPLAY_BEST_SELLERS', Configuration::get('PS_DISPLAY_BEST_SELLERS')); - $this->context->smarty->assign('display_store', Configuration::get('PS_STORES_DISPLAY_SITEMAP')); - - $this->setTemplate(_PS_THEME_DIR_.'sitemap.tpl'); - } -} diff --git a/install-dev/data/xml/meta.xml b/install-dev/data/xml/meta.xml index 581bd5ca3..48804dd12 100644 --- a/install-dev/data/xml/meta.xml +++ b/install-dev/data/xml/meta.xml @@ -37,12 +37,6 @@ prices-drop 1 ---> - supplier diff --git a/modules/qlogsitemap/LICENSE.md b/modules/qlogsitemap/LICENSE.md new file mode 100644 index 000000000..44b1b399c --- /dev/null +++ b/modules/qlogsitemap/LICENSE.md @@ -0,0 +1,223 @@ +SOFTWARE LICENCE AGREEMENT +=============================== + +This AGREEMENT is made effective on the date of the purchase of the software between Webkul Software Pvt. Ltd.,Company incorporated under the Companies Act, 1956 (hereinafter referred to as “Licensor"), and the purchaser of the software/ product (hereinafter referred to as "Licensee"). + +Preamble +================== +Licensor is a web and mobile product based organization engaged in the business of developing and marketing software for enterprise level e-commerce businesses. It is an ISO and NSR (NASSCOM) certified organization having a team of more than 150 creative engineers which come from different backgrounds. It has developed more than 700 web extensions and apps in the past few years for open source platforms which are used and trusted globally. Licensee now wishes to obtain license, and Licensor wishes to grant a license, to allow use of the software so purchased in developing the e-commerce business website/ mobile app of the Licensee, subject to the terms and conditions set forth herein. + + +THEREFORE, with the intent to be legally bound, the parties hereby agree as follows: + + +Agreement +================ + +1.Definitions : +------------------ +As used in this Agreement, the following capitalized terms shall have the definitions set forth below: + + +"Derivative Works" are works developed by Licensee, its officers, agents, contractors or employees, which are based upon, in whole or in part, the Source Code and/or the Documentation and may also be based upon and/or incorporate one or more other preexisting works of the Licensor. Derivative Works may be any improvement, revision, modification, translation (including compilation or recapitulation by computer), abridgment, condensation, expansion, or any other form in which such a preexisting work may be recast, transformed, or adapted. For purposes hereof, a Derivative Work shall also include any compilation that incorporates such a preexisting work. + + +"Documentation" is written, printed or otherwise recorded or stored (digital or paper) material relating to the Software and/or Source Code, including technical specifications and instructions for its use including Software/ Source Code annotations and other descriptions of the principles of its operation and instructions for its use. + + +"Improvements" shall mean, with respect to the Software, all modifications and changes made, developed, acquired or conceived after the date hereof and during the entire term of this Agreement. + + +"Source Code" is the computer programming source code form of the Software in the form maintained by the Licensor, and includes all non-third-party executables, libraries, components, and Documentation created or used in the creation, development, maintenance, and support of the Software as well as all updates, error corrections and revisions thereto provided by Licensor, in whole or in part. + + +2. Software License. +------------------------- + +(a)Grant of License. For the consideration set forth below, Licensor hereby grants to Licensee, and Licensee hereby accepts the worldwide, non-exclusive, perpetual, royalty-free rights and licenses set forth below: + + +(i)The right and license to use and incorporate the software, in whole or in part, to develop its website/ mobile app (including the integration of all or part of the Licensor’s software into Licensee's own software) on one domain ( Except Joomla modules , listed on store are entitled to be used on unlimited domain as per the standard guidelines ) only, solely for the own personal or business use of the Licensee. However, the License does not authorize the Licensee to compile, copy or distribute the said Software or its Derivative Works. + + +(ii)The right and license does not authorize the Licensee to make any backup or archival copies of the Software and / or the Source Code and Documentation. + +(iii)The right and license does not authorize the Licensee to migrate the domain license to another domain. + + +(b)Scope; Rights and Responsibilities. + + +(i)Licensor shall enable the Licensee to download one complete copy of the Software. + + +(ii)The Software is intended for the sole use of the Licensee in development of its own website/ mobile app. + + +(iii)Licensee does not have the right to hand over, sell, distribute, sub-license, rent, lease or lend any portion of the Software or Documentation, whether modified or unmodified, to anyone. Licensee should not place the Software on a server so that it becomes accessible via a public network such as the Internet for distribution purposes. In case the Licensee is using any source code management system like github, it can use the code there only when it has paid subscription from such management system. + + +(iv)Licensee is not authorized to appoint, or work with, third parties to perform any development services using the Source Code, the source code to Derivative Works and/or the Documentation on behalf of, or working with, the Licensee. Release of Source Code, Derivative Work source code and/or Documentation to any third party shall be considered as violation of the Agreement, inter-alia entailing forthwith termination and legal action. + + + +(c)Ownership. + + +(i)Software and Source Code. All right, title, copyright, and interest in the Software, Source Code, Software Modifications and Error corrections will be and remain the property of Licensor. + + +(ii)Derivative Works. As creation of Derivative Works by the Licensee is prohibited, thus, all right, title, copyright, and interest in any and/or all Derivative Works and Improvements created by, or on behalf of, Licensee will also be deemed to the property of Licensor. Licensor shall be entitled to protect copyright / intellectual property in all such Derivative Works and Improvements also in any country as it may deem fit including without limitation seeking copyright and/or patent protection. + + +3.Consideration. +-------------------- + +(a)Licensee shall pay to Licensor the amount as mentioned on the website from where the order is placed, as one-time, upfront fees in consideration for the licenses and rights granted hereunder (hereinafter referred to as the "License Fee"). The License Fee to be paid by Licensee shall be paid upfront at the time of placing the order, and no credit will be allowed under any circumstances. + + +(b)Once paid, the License Fees shall be non-refundable. The Licensee has fully satisfied itself about the Software and has seen the demonstration, and only thereafter has placed the order. Thus, the License Fees or any part thereof is non-refundable. No claim for refund of the Licence Fees shall be entertained under any circumstances. + + + +4.Representations and Warranties. +------------------------------------- + +(a)Mutual. Each of the parties represents and warrants to the other as follows. + + +(i)such party is a legal entity duly organized, validly existing and in good standing; + + +(ii)such party has the power and authority to conduct its business as presently conducted and to enter into, execute, deliver and perform this Agreement. + + +(iii)This Agreement has been duly and validly accepted by such party and constitutes the legal, valid and binding obligations of such party respectively, enforceable against such party in accordance with their respective terms; + + +(iv)the acceptance, execution, delivery and performance of this Agreement does not and will not violate such party's charter or by-laws; nor require any consent, authorization, approval, exemption or other action by any third party or governmental entity. + + +(b)Licensor warrants that, at the time of purchase of the Software: + + +the Software will function materially as set forth in the website or published functionality provided by Licensor to customers and potential customers describing the Software; and + + +Software add-ons, if purchased by the Licensee from the Licensor, will not materially diminish the features or functions of or the specifications of the Software as they existed as of the execution of this Agreement. + + + +(c)Title. Licensor represents and warrants that it is the exclusive owner of all copyright/ intellectual property in the Software (including the Source Code) and has good and marketable title to the Software (including the Source Code) free and clear of all liens, claims and encumbrances of any nature whatsoever (collectively, "Liens"). Licensor's grant of license and rights to Licensee hereunder does not, and will not infringe any third party's property, intellectual property or personal rights. + + + +5.Term. +------------- + +(a)Subject to Licensee's payment obligations, this Agreement shall commence as on the date of making payment of the Software by the Licensee to the Licensor, and shall continue until terminated by either party. + + +(b)The Licensor retains the right to terminate the license at any time, if the Licensee is not abiding by any of the terms of the Agreement. The Licensee may terminate the Agreement at any time at its own discretion by uninstalling the Software and /or by destroying the said Software (or any copies thereof). However, the Licensee shall not be entitled to seek any refund of the amount paid by it to the Licensor, under any circumstances. + + +(c)Survival. In the event this Agreement is terminated for any reason, the provisions set forth in Sections 2(a), 2(b), and 2(c) shall survive. + + + + +6. Indemnification +---------------------- + +The Licensee release the Licensor from, and agree to indemnify, defend and hold harmless the Licensor (and its officers, directors, employees, agents and Affiliates) against, any claim, loss, damage, settlement, cost, taxes, expense or other liability (including, without limitation, attorneys' fees) (each, a "Claim") arising from or related to: (a) any actual or alleged breach of any obligations in this Agreement; (b) any refund, adjustment, or return of Software,(c) any claim for actual or alleged infringement of any Intellectual Property Rights made by any third party or damages related thereto; or (d) Taxes. + + +7. Limitation of Liability +------------------------------ + +The Licensor will not be liable for any direct, indirect, incidental, special, consequential or exemplary damages, including but not limited to, damages for loss of profits, goodwill, use, data or other intangible losses arising out of or in connection with the Software, whether in contract, warranty, tort etc. (including negligence, software liability, any type of civil responsibility or other theory or otherwise) to the Licensee or any other person for cost of software, cover, recovery or recoupment of any investment made by the Licensee or its affiliates in connection with this Agreement, or for any other loss of profit, revenue, business, or data or punitive or consequential damages arising out of or relating to this Agreement. Further, the aggregate liability of the Licensor, arising out of or in connection with this Agreement or the transactions contemplated hereby will not exceed at any time, or under any circumstances, the total amounts received by the Licensor from the Licensee in connection with the particular software giving rise to the claim. + + +8. Force Majeure +--------------------- + +The Licensor will not be liable for any delay or failure to perform any of its obligations under this Agreement by reasons, events or other matters beyond its reasonable control. + + +9. Relationship of Parties +------------------------------ + +The Licensor and Licensee are independent legal entities, and nothing in this Agreement will be construed to create a partnership, joint venture, association of persons, agency, franchise, sales representative, or employment relationship between the parties. The Licensee will have no authority to make or accept any offers or representations on behalf of the Licensor. The relationship between the parties is that of Licensor and Licensee only, and the rights, duties, liabilities of each party shall be governed by this Agreement. + + +10. Modification +------------------------ + +The Licensor may amend any of the terms and conditions contained in this Agreement at any time and solely at its discretion. Any changes will be effective upon the posting of such changes on the Portal/ website, and the Licensee is responsible for reviewing these changes and informing itself of all applicable changes or notices. The continued use of a software by the Licensee after posting of any changes by the Licensor, will constitute the acceptance of such changes or modifications by the Licensee. + + + +11.Miscellaneous. +----------------------- + +(a)General Provisions. This Agreement: (i) may be amended only by a writing signed by each of the parties; (ii) may be executed in several counterparts, each of which shall be deemed an original but all of which shall constitute one and the same instrument; (iii) contains the entire agreement of the parties with respect to the transactions contemplated hereby and supersedes all prior written and oral agreements, and all contemporaneous oral agreements, relating to such transactions; (iv) shall be governed by, and construed and enforced in accordance with, the laws of India; and (v) shall be binding upon, and inure to the benefit of, the parties and their respective successors and permitted assigns. Each of the parties hereby irrevocably submits to the jurisdiction of the Courts at Delhi, India, for the purposes of any action or proceeding arising out of or relating to this Agreement or the subject matter hereof and brought by any other party. + + +(b)Assignment. Licensee cannot assign, pledge or otherwise transfer, whether by operation of law or otherwise, this Agreement, or any of its obligations hereunder, without the prior written consent of Licensor, which consent shall not be unreasonably withheld. + + +(c)Notices. Unless otherwise specifically provided herein, all notices, consents, requests, demands and other communications required or permitted hereunder: + + +(i)shall be in writing; + + +(ii)shall be sent by messenger, certified or registered mail/email, or reliable express delivery service, to the appropriate address(es) set forth below; and + + +(iii)shall be deemed to have been given on the date of receipt by the addressee, as evidenced by a receipt executed by the addressee (or a responsible person in his or her office), the records of the Party delivering such communication or a notice to the effect that such addressee refused to claim or accept such communication, if sent by messenger, mail or express delivery service. + + +All such communications shall be sent to the following addresses or numbers, or to such other addresses or numbers as any party may inform the others by giving five days' prior notice: + + +If to Webkul Software Pvt. Ltd.: + + + +Webkul Software Pvt. Ltd. + +H-28, ARV Park, Sector 63, NOIDA – 201301, + +Uttar Pradesh, India + + +If to Licensee: + +At the address mentioned by the Licensee + +(at the time of placing order of generating Invoice) + + +(d)Severability. It is the intent of the parties that the provisions of this Agreement be enforced to the fullest extent permissible under the laws and public policies of India in which enforcement hereof is sought. In furtherance of the foregoing, each provision hereof shall be severable from each other provision, and any provision hereof which is/ becomes unenforceable shall be subject to the following: (i) if such provision is contrary to or conflicts with any requirement of any statute, rule or regulation in effect, then such requirement shall be incorporated into, or substituted for, such unenforceable provision to the minimum extent necessary to make such provision enforceable; (ii) the court, agency or arbitrator considering the matter is hereby authorized to (or, if such court, agency or arbitrator is unwilling or fails to do so, then the parties shall) amend such provision to the minimum extent necessary to make such provision enforceable, and the parties hereby consent to the entry of an order so amending such provision; and (iii) if any such provision cannot be or is not reformed and made enforceable pursuant to clause (i) or (ii) above, then such provision shall be ineffective to the minimum extent necessary to make the remainder of this Agreement enforceable. Any application of the foregoing provisions to any provision hereof shall not effect the validity or enforceability of any other provision hereof. + + +(e)By purchasing the Software, the Licensee acknowledge that it has read this Agreement, and that it agrees to the content of the Agreement, its terms and agree to use the Software in compliance with this Agreement. + + +(f)The Licensor holds the sole copyright of the Software. The Software or any portion thereof is a copyrightable matter and is liable to be protected by the applicable laws. Copyright infringement in any manner can lead to prosecution according to the current law. The Licensor reserves the right to revoke the license of any user who is not holding any license or is holding an invalid license. + + +(g)This Agreement gives the right to use only one copy of the Software on one domain solely for the own personal or business use of the Licensee, subject to all the terms and conditions of this Agreement. A separate License has to be purchased for each new Software installation. Any distribution of the Software without the written consent of the Licensor (including non-commercial distribution) is regarded as violation of this Agreement, and will entail immediate termination of the Agreement and may invite liability, both civil and criminal, as per applicable laws. + + +(h)The Licensor reserves the rights to publish a selected list of users/ Licensees of its Software, and no permission of any Licensee is needed in this regard. The Licensee agrees that the Licensor may, in its sole discretion, disclose or make available any information provided or submitted by the Licensee or related to it under this Agreement to any judicial, quasi-judicial, governmental, regulatory or any other authority as may be required by the Licensor to co-operate and / or comply with any of their orders, instructions or directions or to fulfill any requirements under applicable Laws. + + +(i)If the Licensee continues to use the Software even after the sending of the notice by the Licensor for termination, the Licensee agree to accept an injunction to restrain itself from its further use, and to pay all costs (including but not limited to reasonable attorney fees) to enforce injunction or to revoke the License, and any damages suffered by the Licensor because of the misuse of the Software by the Licensee. + + +12. Arbitration +----------------------- + +If any dispute arises between the Licensor and the Licensee at any time, in connection with the validity, interpretation, implementation or alleged breach of any provision of this Agreement, the same shall be referred to a sole Arbitrator who shall be an independent and neutral third party appointed exclusively by the Licensor. The Licensee shall not object to the appointment of the Arbitrator so appointed by the Licensor. The place of arbitration shall be Delhi, India. The Arbitration & Conciliation Act, 1996 as amended by The Arbitration & Conciliation (Amendment) Act, 2015, shall govern the arbitration proceedings. The arbitration proceedings shall be held in the English language. diff --git a/modules/qlogsitemap/classes/QgsHelper.php b/modules/qlogsitemap/classes/QgsHelper.php new file mode 100644 index 000000000..83217d490 --- /dev/null +++ b/modules/qlogsitemap/classes/QgsHelper.php @@ -0,0 +1,126 @@ +executeS( + 'SELECT ps.`id_product` FROM `'._DB_PREFIX_.'product_shop` ps + INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = ps.`id_product`)'.$groupJoin.' + WHERE ps.`id_shop` = '.(int) $idShop.' AND ps.`active` = 1 AND ps.`visibility` <> \'none\' AND p.`booking_product` = 1 + ORDER BY ps.`id_product`' + ); + } + + public static function getCategoryIds($idShop) + { + $groupJoin = ''; + if (Group::isFeatureActive() && Configuration::get('PS_UNIDENTIFIED_GROUP')) { + $groupJoin = ' INNER JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category` + AND cg.`id_group` = '.(int) Configuration::get('PS_UNIDENTIFIED_GROUP').')'; + } + + return Db::getInstance()->executeS( + 'SELECT c.`id_category` FROM `'._DB_PREFIX_.'category` c + INNER JOIN `'._DB_PREFIX_.'category_shop` cs ON (cs.`id_category` = c.`id_category`) + INNER JOIN `'._DB_PREFIX_.'htl_branch_info` hbi ON (hbi.`id_category` = c.`id_category` AND hbi.`active` = 1)'.$groupJoin.' + WHERE c.`active` = 1 AND cs.`id_shop` = '.(int) $idShop.' + ORDER BY c.`id_category`' + ); + } + + public static function getCmsIds($idLang, $idShop) + { + return Db::getInstance()->executeS( + 'SELECT c.`id_cms` FROM `'._DB_PREFIX_.'cms` c + INNER JOIN `'._DB_PREFIX_.'cms_lang` cl ON (cl.`id_cms` = c.`id_cms` AND cl.`id_lang` = '.(int) $idLang.') + INNER JOIN `'._DB_PREFIX_.'cms_shop` cs ON (cs.`id_cms` = c.`id_cms` AND cs.`id_shop` = '.(int) $idShop.') + INNER JOIN `'._DB_PREFIX_.'cms_category` cc ON (cc.`id_cms_category` = c.`id_cms_category` AND cc.`active` = 1) + WHERE c.`active` = 1 AND c.`indexation` = 1 + GROUP BY c.`id_cms` ORDER BY c.`id_cms`' + ); + } + + public static function getSitemapFiles() + { + $files = array(); + foreach ((array) glob(_PS_ROOT_DIR_.'/*_sitemap.xml') as $path) { + $name = basename($path); + if (preg_match('/^[a-z]{2,3}(-[a-z]{2,4})?_\d+_sitemap\.xml$/i', $name)) { + $files[] = array('link' => $name); + } + } + sort($files); + + return $files; + } + + public static function deleteSitemapFiles() + { + foreach (self::getSitemapFiles() as $row) { + @unlink(_PS_ROOT_DIR_.'/'.$row['link']); + } + @unlink(_PS_ROOT_DIR_.'/'.self::QGS_INDEX_FILE_NAME); + } + + public static function createIndexFile() + { + $sitemaps = self::getSitemapFiles(); + if (!$sitemaps) { + return false; + } + + $baseLink = Context::getContext()->link->getBaseLink(); + $xml = ''.PHP_EOL.''.PHP_EOL; + foreach ($sitemaps as $sitemap) { + $xml .= ''.self::escapeXml($baseLink.$sitemap['link']).''.date('c').''.PHP_EOL; + } + $xml .= ''.PHP_EOL; + + return (bool) file_put_contents(_PS_ROOT_DIR_.'/'.self::QGS_INDEX_FILE_NAME, $xml); + } + + public static function escapeXml($string) + { + return htmlspecialchars($string, ENT_QUOTES | ENT_XML1, 'UTF-8'); + } +} diff --git a/modules/qlogsitemap/classes/index.php b/modules/qlogsitemap/classes/index.php new file mode 100644 index 000000000..409280877 --- /dev/null +++ b/modules/qlogsitemap/classes/index.php @@ -0,0 +1,32 @@ +N|pEzsFrWv8@r-jbw4(*@5zI*28 z2^0HUdY4r-&#!2j*Vhz!t1f+NV^nYBgzoU9^2WLK#lht{!6kLGifd=(RZh#Tn2}pP zHLG+=R%Uoc@ualEiK&GXQVS-;XZJ*BbVa3g#-`Oor__Zfw}&LO_(nBEMubI%hq(q< zH3lVS`NxGhMSJ-KxqFAXdWL$qrQ7*dShyFOJA|0qhnm_&nmFegIOLkxhUwU58d!yC zn}r$~MrfKwsGCHn87Hb(q^p=FD;dVi8^p_LhRJA#NoYifYeb4`M2G>AIuM16sfUTF zg^8&G$xv}MUs1JC5w&m;AgLNAq8ci!8YZj)M4>_|VS*|Vf-2!cK(=zI01zn!^D74P zDuwbYgz?G;@yZAC$cORBhw{h;a?6Es$%S#qhH=P*vdM=q%Z3O@d2>qpu}S)|N%*iz zg|bM6GE0QAO8Bx$_^^n1GmCjKiFz}MdNK-oG6=ad2)Ho_I5O}#GK>Ohgn$mn5Kvxl z;P}RHeT}Db0q;!xq!R)8WH) zdhT;?YU-XXjZTUz&CG#!avoNu`AwA8@K~|pgThfx5$#O}0zbQXx5-RMsz_)_IXuHb zsqKd4XAR~CMq>tsf{hCp+5`nuVmgc6&MP?;iRjL{{9HiJs^MRS%8K&m5BD%JGci~L E0F^KQy8r+H literal 0 HcmV?d00001 diff --git a/modules/qlogsitemap/logo.png b/modules/qlogsitemap/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..88e035c8ce72d37a1726ffa765612b317b9e0c88 GIT binary patch literal 5839 zcmY+IcTf{b)b^%MbFb#(c+?M5%lSWwefWRwO4M`=luK6tq!?1D!N-F&rZBr&RpkNr!o`_YB z!DgbC|Ep3i)K#E^$=|%ewg``L3f*aG!;{;$Wo5)I&{7M}~4KU>~@DUS?>9o-)N|_S5mQO^wT9bb94w^oY|@V_`^^ z8wz!HLwP+N8Ph$>xi!hgQI$y8Fnicjl|9I+yTZ;;s%{W+$!NJ#Z70q5Pf~rs>o9#% zHwg`%{!V@39OlM7fzElK?1gi9*R^%b8y>JPF&pNIhMenNHfNI9yNHQ*v_}(Cs4>-w z^M2jrwOl1p;bPZfb$&S#i0LlO0XV{heN=6r7u=>M{ z>2*le;Li#oUk=~!Zi%X`w!E=hqV+B+^*P!6G`^wiOTR>-of62>96mdZdPE8k`L*%_ zJ+%2i=*`MEPK~2c4lIqbc6?<|{?TQ@xCI0r4m2wD({|EWA%8sx+k=A(^yOwmRvO8@ zI=(NR<~3*_Qaq!E!+n_l?i}wc6g!%e8Jzi3XE`{J--ia)c|ileVI+&v=wVSQS^XKw zlx9?*6#Sg)@5ev})?yV!*l;PR$ZvsHBfbyq@s~{)zjvms6acaKqMiXv@Gw!f;$(>U zqs)>p!*drjsa-xM4za*+D(Ojl?Y`$brn$2>9jxXFyDt~a(0*LNrutInU3H{t+#E~9 z??)p=s^bfP{IQ>LS{{I*l6j0QDAqS#BR*O)z!$5@}=5 z0Z5T6U(qWa%$c2Cg=p5W@bC4OkF8sw(Kc%-g>&@>)g{A`AzTnYt&a-#pB!+-mS7)* zxqsiapY_QXg1o+eNV(I&0l7Oh>W--5HCI_7?UPQyQlcsCv$xF19;m6x4g5gu5)*CxHVE%G{%VW#B+K~OnszT!~|fiD3s_4m{H_*)cTf`Oi= z-!}YWYWr?OJMTqThlo#oxKouTn?igmdOh<|F0Bnu4gyb3j@DxrG*QH!J3$ndTFPWADhfn zuRzIQO`e6Pn#>@-J)(KGy~bDcu;=XU=Py@(7o-SL@K1w&kv(s*kN`)XDiPW}m)>u- zy&>RHsyj!r2T|3P9q(=qhHja?F$}ON> zXzjKEN5dAWSVp=YsR}3((BP_Jrf|5GfJo+r#p}mv@xXx>Q0QVkAk8yp~;+039 z^$dgHtuEfc{|R}{LExyey2U^eO$4H5E8J0gWLK^CtJ2iO%lsE4Ln=ab;LvEda_(MU zM;MZ-VG@d)o|T^nc^)k4JyXFOJC019eh>sX35(+fn0@C1l15ZC<__Z(&WOcpzdaM{` zW$N6}hnpP#$sm;dV)Qp}8%F6n01F$-&IjkYkoZQ$e6kVB#H@=`Zc&#ei+WiNzflXA z=sn*C22bsMD4!Y`Wjv>mhB^FwNHY6y#$7rBGNbNkd`CFr8^_}8XFq=-%+DQ{3=6fy zl}927s~`9r&IEd);u`P4i7~HQ;1FN&`xS~wHky2RFV@<|MliKYS+2h*eP_m5dC+|7yplH_$C(`Z51o zVC{=Ym#UO;Cr@yGfp46^63L<dO{>CbnO1kk9otML?rV7E!Xd_HC2NC4++(aL~qEli*2 znwKCQxTY;IT`}rxtZARz>OB)9Z*T@fzlg(}35PK2K~GSG9XFsTaVnGd#ZgVLndq9? zkmZ`~+0xkI!EZW5s?pcUp9=SeW(p=!KXSEha)qq13kq#0Pk!dck6&E+$>^$fm?OxY zU%%3XQbA94$3XqA*0f-e?J2`q#?joCfkDAh+7*%2Fmg+g7z>W^#peQG@iqLbr_tQ0 zg{}s2f7<@8zmkZgsro^SaJd&#rCNG1&$les*-aO9-*?fd-{U7v-q_NCUQ785g%fC0 zbVDl|ZJkz^6ZhBHEDdnCyMD|SSv+U2n?R*C)Pr}ojw_j0nQfbrTYQI8W+cj}t3hSsZI;%?HbZD?4j-xk`(NQlDZZ(%~d3k{DUnFMZgip90UC%tT(ApZ>R1z{JOC_DH!KyDHtZl9CXMJSFj_NwOZ(u1&VsFN;}I1L8JrGr!Lkq z?|<$b2HYd`t!pM$S}fV-8rxyazqgX;$qo;`6#Lc&M5{AgGBY9O3^ar;`}%IGh(XxW zZsC5F+%!6dTO>21yxI^>xjhds3MmDyn3;IUOS91oeKPoQg<%WM3({JAKU6VOuNL>L zo*Q7)uGH<}zpM>*m>1_(d$y4e7@E(1qy1VBw=;7?Rd=%hxxW;ix8qJ~RNV+Ea+4))p z34kdp^m3OxmOdl-B9CTv%DPJj3C8GP_Tk4rRTdh_Fa0i~^e{^fe?MuC`k5YRsermE_PpJ=|K!j#v(Nxg=)3czF)=go_=Qr!&OWAZt2pm-oOoESwJc$q}Ot?&__6 zDde4+w+_(bqvu$pIJh((MB65vm7)9##z~~q&H}LnxcinSg7RvDRc9}?WxYI;5=ON?IW`J&}v^7mrs@t zMv62A01;aBLiMr|uyZ_>{nf8Fj(IuBcQCCK-d^^lYjw`BbDIhb%Nvuzy-%|BbhG%b@SQE*`7ii0L|o^pu?TVl?Xu~264l-* z`%@XyW&_BcRNq#SRn;gnhrgGj!D;6`jDjfA9?#FuN8lGb`fJiirP+wVJ3Z(#&|m@e>g-bZewava zbV2}CXny7A?}0|3Ftm?TOj-oR|m%{&~gGdPNtdHXi74 zheUK9@{QL_zaVC$xhpH0u1(3b6IF>##el9(yti>|?CcbwdlJj3(`+-i7NyM7DevDZ zn{qM+9{J%X*z-6W-!3|1h~5M{RaatK_f_Z~+AddR^GSc>I{%DCr6uL|dY0@O1rBOcEnKIDQK$Mc!CEB6%wD?I#J-1t_O_jsr z53FAIgE8vsIj_JN-2OZ41Wxj{`(%AMmAv6-SYXb_+YoSYW0A1U9eyqhl7I8-)hG~S z5(+E4P^P^$a3qYxW8W%XY+yfd9E(bYe^Hm|`;(eWCOsT|V4i8)F5}uVtgnU~8FH28 zIw_tv#wlQrMNjKF8XW2>7k|jMd;&?d?L`ru;84VdpDZteOfgHOIX~`neVm52%Dst{ zWgAOj;{B0`JT)UmZB0VU>pn1`r;7T*cYO%PFskQNDy0|3R!(HKrbeu?cAjo6_o(xt zB)sFb8<%3CI5)@o{vopVt2Eh8;n<|DWuw{Worrcj?KL`K_L2R zEXQxJ6Fcdpcct_Kf<|7gb-~#A06$5fX$V@MTb@*dqsra!AAzUnqJNDK`7rnHCF!LB zT|I#fcKSZ#sZ-z5n;b)E>zv6EMsn1gNh-)Q2`BbJ=&mV-GxQQQ$;c*=tl^6NC4IJw z=)4~&CYz=|td4%<2rHF&&XGf@INalgE)wG4WKv8=Qo!JC#FJ7xxix_lW@9M2o?YEq zJA-ST7jrHN#l;}qM@ZmMPv*zpW<*^A!k2B#!;eXa%Eoe+k~#GzR)t!1l$#D+yFA

FFLg{GkW{cn-I^x*plcZcTAM^^xAqy3-RSLnHGNxNmA{)V3xvb(@@_+LB ze?sPd0nBztt_GnRGJE+Pt)$ z^3EE3`CejwKJB35hYqN+2o7v8n6Uqw#GzL2i6$NDc}$W0EjMdMLxcT`wGP;?HNvdl z?R|tsNmqHeoa(jJi?MQx&7TWP50rtQmCr=jR4Q0U>QjLNM(wt#kzLUF(9eeMV%){ShWDGxv zI;qe0Kf79b94PQbYE$Ooyp#*iRB*|=(W4*zacMPzGPvVlv|Qe_pl!fD>Q}+}j_C^| zL|ne;ZH8H8r>76&LS$(-Zp{4IU?DcrsK4cU}%pIq# zkqaj&p_R6*hpg^*nu8#Zx~|XM))QYxwR|Zxu^h0DH2H`SW-`j4gcuA?gW?$kxcrKW7}*I#Q3r z?-m@!e_W@J=UKj3I=h%FhgV=SZ;7*g{5ttG375$s3t`5aAz}*RRSO8r=^(fnZ-br!2G*=+bd%(T8dyHyajw~^yXfnQLHPK3Io_$#Z?=zG6UYS<%O zdRflX8Z5Cieyeb~b(l7>&*VmuZNe}!Oz0z?@2*t~Vy#6gKfXPQV2X}`2{hZU3=y@+ z-763=Vi_~XLT?=o4^jIh{=AiK5$vT9)FEiIHLhTI1j#^XfRyB&9mX4*m^mai&^{~A zczE;sGfWz=lHLL^tnES)yQD#YbeQky!1#F>m(OX$pRy}{<93Fnx60c`G#mjr5hh^~ zG2TPisg}2qJl!MI;^Dr5@i}^!(IuO_6`d}Z1I#GQX{Gk&+u2y-Hy3_mB+fQYO1*Mx zT<~Cnz2*&_G`QUCp-18l)u0DpBvbgv(e}VBH;gX zC*%HeCt3c#JNaM2>3`dn|0l8XzZE7We>t~qH++$sAI3PeG@a)~6;YYj1rtdvxWv7! x-$9;n3bvLCjo0abX%RUo|HWUW?ENK<&oh3t`)Ty 'home', + 'our-properties' => 'meta', + ); + + protected $pagesAfter = array( + 'contact' => 'contact', + 'authentication' => 'login', + ); + + protected $priorities = array( + 'home' => 1.0, + 'meta' => 0.8, + 'contact' => 0.2, + 'category' => 0.6, + 'roomType' => 0.4, + 'cms' => 0.2, + 'login' => 0.2, + ); + protected $fixedFrequencies = array( + 'cms' => 'monthly', + 'login' => 'yearly', + ); + + protected $fileHandle = null; + protected $fileUrlCount = 0; + protected $fileIndex = 0; + protected $currentIso = ''; + + public function __construct() + { + $this->name = 'qlogsitemap'; + $this->tab = 'seo'; + $this->version = '1.0.0'; + $this->ps_versions_compliancy = array('min' => '1.6', 'max' => '1.6'); + $this->qloapps_versions_compliancy = array('min' => '1.7.0', 'max' => _QLOAPPS_VERSION_); + $this->author = 'Webkul'; + $this->need_instance = 0; + $this->bootstrap = true; + + parent::__construct(); + + $this->displayName = $this->l('Sitemap'); + $this->description = $this->l('Generates XML sitemaps for your hotel website and keeps them up to date. Compatible with all major search engines.'); + $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?'); + } + + public function install() + { + return parent::install() + && $this->registerHook('displayAdminMetaOptions') + && $this->registerHook('registerCronTasks'); + } + + public function uninstall() + { + QgsHelper::deleteSitemapFiles(); + + Configuration::deleteByName('QLOGSITEMAP_LAST_EXPORT'); + + return parent::uninstall(); + } + + public function hookRegisterCronTasks() + { + return array( + array( + 'name' => 'generate_sitemap', + 'description' => $this->l('Regenerate the XML sitemaps'), + 'cron' => '0 0 * * 0', + 'callback' => 'cronGenerateSitemap', + ), + ); + } + + public function cronGenerateSitemap() + { + if (!$this->createSitemap()) { + throw new Exception('Unable to generate the sitemaps.'); + } + } + + public function hookDisplayAdminMetaOptions() + { + if ($this->context->controller) { + if (Tools::isSubmit('submitQloGsitemap')) { + if ($this->createSitemap()) { + Tools::redirectAdmin($this->context->link->getAdminLink('AdminMeta').'&qgsGenerated=1'); + } elseif (!count($this->context->controller->errors)) { + $this->context->controller->errors[] = $this->l('Unable to generate the sitemaps.'); + } + } elseif (Tools::getValue('qgsGenerated')) { + $this->context->controller->confirmations[] = $this->l('Your sitemaps were successfully created.'); + } + } + + $this->context->smarty->assign(array( + 'qgs_index_url' => $this->context->link->getBaseLink().QgsHelper::QGS_INDEX_FILE_NAME, + 'qgs_store_url' => $this->context->link->getBaseLink(), + 'qgs_sitemap_links' => QgsHelper::getSitemapFiles(), + 'qgs_last_export' => Configuration::get('QLOGSITEMAP_LAST_EXPORT'), + 'qgs_cron_manager_enabled' => Module::isEnabled('qlocrontaskmanager'), + 'qgs_cron_manager_installed' => Module::isInstalled('qlocrontaskmanager'), + 'qgs_cron_manager_link' => $this->getCronManagerLink(), + )); + + return $this->display(__FILE__, 'views/templates/hook/sitemap-panel.tpl'); + } + + protected function getCronManagerLink() + { + $link = $this->context->link; + if (Module::isEnabled('qlocrontaskmanager')) { + return $link->getAdminLink('AdminCronTaskManager'); + } + + $module = Module::getInstanceByName('qlocrontaskmanager'); + if (!$module) { + return ''; + } + + return $link->getAdminLink('AdminModules').'&module_name='.$module->name.'&tab_module='.$module->tab; + } + + public function createSitemap() + { + if (!is_writable(_PS_ROOT_DIR_)) { + if ($this->context->controller) { + $this->context->controller->errors[] = $this->l('Unable to write in the root directory. Please adjust the permissions to allow this module to create the sitemap files.'); + } + + return false; + } + + QgsHelper::deleteSitemapFiles(); + + foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { + $this->startSitemapSet($lang['iso_code']); + $this->addPageUrls($lang, $this->pagesBefore); + $this->addCategoryUrls($lang); + $this->addRoomTypeUrls($lang); + $this->addCmsUrls($lang); + $this->addPageUrls($lang, $this->pagesAfter); + $this->closeSitemapFile(); + } + + $result = QgsHelper::createIndexFile(); + if ($result) { + Configuration::updateValue('QLOGSITEMAP_LAST_EXPORT', date('Y-m-d H:i:s')); + } + + return $result; + } + + protected function startSitemapSet($iso) + { + $this->closeSitemapFile(); + $this->currentIso = $iso; + $this->fileIndex = 0; + } + + protected function openSitemapFile() + { + $fileName = $this->currentIso.'_'.$this->fileIndex.'_sitemap.xml'; + $this->fileHandle = @fopen(_PS_ROOT_DIR_.'/'.$fileName, 'wb'); + if (!$this->fileHandle) { + return false; + } + + fwrite($this->fileHandle, ''.PHP_EOL. + ''.PHP_EOL); + ++$this->fileIndex; + $this->fileUrlCount = 0; + + return true; + } + + protected function closeSitemapFile() + { + if ($this->fileHandle) { + fwrite($this->fileHandle, ''.PHP_EOL); + fclose($this->fileHandle); + $this->fileHandle = null; + } + } + + protected function addUrl($loc, $type, $lastMod = null) + { + if (!$loc) { + return false; + } + if ($this->fileHandle && $this->fileUrlCount >= QgsHelper::QGS_MAX_URLS_PER_FILE) { + $this->closeSitemapFile(); + } + if (!$this->fileHandle && !$this->openSitemapFile()) { + return false; + } + + $priority = $this->priorities[$type]; + $frequency = isset($this->fixedFrequencies[$type]) ? $this->fixedFrequencies[$type] : QgsHelper::QGS_DEFAULT_FREQUENCY; + $xml = ''.PHP_EOL.''.QgsHelper::escapeXml($loc).''.PHP_EOL; + if ($lastMod && strtotime($lastMod) > 0) { + $xml .= ''.date('Y-m-d', strtotime($lastMod)).''.PHP_EOL; + } + $xml .= ''.QgsHelper::escapeXml($frequency).''.PHP_EOL. + ''.number_format($priority, 1, '.', '').''.PHP_EOL; + $xml .= ''.PHP_EOL; + + fwrite($this->fileHandle, $xml); + ++$this->fileUrlCount; + + return true; + } + + protected function addPageUrls($lang, array $pages) + { + foreach ($pages as $page => $type) { + $this->addUrl($this->context->link->getPageLink($page, null, (int) $lang['id_lang']), $type); + } + } + + protected function addRoomTypeUrls($lang) + { + $idLang = (int) $lang['id_lang']; + $idShop = (int) $this->context->shop->id; + + foreach (QgsHelper::getRoomTypeIds($idShop) as $row) { + $product = new Product((int) $row['id_product'], false, $idLang); + $this->addUrl( + $this->context->link->getProductLink($product, $product->link_rewrite, null, null, $idLang, $idShop), + 'roomType', + $product->date_upd + ); + } + } + + protected function addCategoryUrls($lang) + { + $idLang = (int) $lang['id_lang']; + $idShop = (int) $this->context->shop->id; + + foreach (QgsHelper::getCategoryIds($idShop) as $row) { + $category = new Category((int) $row['id_category'], $idLang); + $this->addUrl( + $this->context->link->getCategoryLink($category, $category->link_rewrite, $idLang, null, $idShop), + 'category' + ); + } + } + + protected function addCmsUrls($lang) + { + $idLang = (int) $lang['id_lang']; + $idShop = (int) $this->context->shop->id; + + foreach (QgsHelper::getCmsIds($idLang, $idShop) as $row) { + $cms = new CMS((int) $row['id_cms'], $idLang); + $this->addUrl($this->context->link->getCMSLink($cms, null, null, $idLang, $idShop), 'cms'); + } + } +} diff --git a/modules/qlogsitemap/views/index.php b/modules/qlogsitemap/views/index.php new file mode 100644 index 000000000..409280877 --- /dev/null +++ b/modules/qlogsitemap/views/index.php @@ -0,0 +1,32 @@ + +

{l s='Sitemap generation' mod='qlogsitemap'}
+
+

{l s='Generate your XML sitemaps by clicking on the following button (this will erase the old sitemap files). Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlogsitemap'}

+ {if $qgs_cron_manager_enabled} +

{l s='The sitemaps are also regenerated automatically every week (Sunday at midnight) by the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.

+ {/if} +
+ {if !$qgs_cron_manager_enabled} +
+ {if $qgs_cron_manager_installed} + {l s='The Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if}, + {else} + {l s='The Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if}, + {/if} + {l s='or generate the sitemaps manually with the button below.' mod='qlogsitemap'} +
+ {/if} + {if $qgs_sitemap_links} +

{l s='Main sitemap:' mod='qlogsitemap'} {$qgs_index_url|escape:'html':'UTF-8'}

+ +

{l s='Last update:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

+ {else} +

{l s='This shop has no sitemap yet.' mod='qlogsitemap'}

+ {/if} + + diff --git a/modules/qlogsitemap/views/templates/index.php b/modules/qlogsitemap/views/templates/index.php new file mode 100644 index 000000000..409280877 --- /dev/null +++ b/modules/qlogsitemap/views/templates/index.php @@ -0,0 +1,32 @@ + li { - margin: 0 0 0 11px; } - ul.tree li.last { - border: medium none; - background: url(../img/sitemap-last.png) no-repeat 0px -4px transparent; } - -/*# sourceMappingURL=sitemap.css.map */ diff --git a/themes/hotel-reservation-theme/img/sitemap-horizontal.png b/themes/hotel-reservation-theme/img/sitemap-horizontal.png deleted file mode 100644 index 231e716f01a3a476332a1d592035f4122528e36a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W@!2~1&KS&k li { - margin: 0 0 0 11px; - } - li.last { - border: medium none; - background: url(../img/sitemap-last.png) no-repeat 0px -4px transparent; - } -} \ No newline at end of file diff --git a/themes/hotel-reservation-theme/sitemap.tpl b/themes/hotel-reservation-theme/sitemap.tpl deleted file mode 100644 index 7987292bb..000000000 --- a/themes/hotel-reservation-theme/sitemap.tpl +++ /dev/null @@ -1,203 +0,0 @@ -{* -* 2007-2017 PrestaShop -* -* NOTICE OF LICENSE -* -* This source file is subject to the Academic Free License (AFL 3.0) -* that is bundled with this package in the file LICENSE.txt. -* It is also available through the world-wide-web at this URL: -* http://opensource.org/licenses/afl-3.0.php -* If you did not receive a copy of the license and are unable to -* obtain it through the world-wide-web, please send an email -* to license@prestashop.com so we can send you a copy immediately. -* -* DISCLAIMER -* -* Do not edit or add to this file if you wish to upgrade PrestaShop to newer -* versions in the future. If you wish to customize PrestaShop for your -* needs please refer to http://www.prestashop.com for more information. -* -* @author PrestaShop SA -* @copyright 2007-2017 PrestaShop SA -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*} - -{capture name=path}{l s='Sitemap'}{/capture} - -

- {l s='Sitemap'} -

-
-
-
-

{l s='Our offers'}

- -
-
-
-
-

- {l s='Your Account'} -

- -
-
-
-
-
-
-

{l s='Categories'}

-
- -
-
    - {if isset($categoriesTree.children)} - {foreach $categoriesTree.children as $child} - {if $child@last} - {include file="$tpl_dir./category-tree-branch.tpl" node=$child last='true'} - {else} - {include file="$tpl_dir./category-tree-branch.tpl" node=$child} - {/if} - {/foreach} - {/if} -
-
-
-
-
-

{l s='Pages'}

- -
-
-
From 7de6c2772142a5ba1f9898f1b502df6a98049cac Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Mon, 12 Oct 2026 19:37:09 +0530 Subject: [PATCH 2/8] Fixed : standalone and cms pages missing in sitemap --- modules/qlogsitemap/classes/QgsHelper.php | 54 ++++++++++++++++++----- modules/qlogsitemap/qlogsitemap.php | 22 +++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/modules/qlogsitemap/classes/QgsHelper.php b/modules/qlogsitemap/classes/QgsHelper.php index 83217d490..69fe21d14 100644 --- a/modules/qlogsitemap/classes/QgsHelper.php +++ b/modules/qlogsitemap/classes/QgsHelper.php @@ -32,21 +32,55 @@ class QgsHelper const QGS_DEFAULT_FREQUENCY = 'weekly'; + protected static function getProductGroupJoin() + { + if (!Group::isFeatureActive() || !Configuration::get('PS_UNIDENTIFIED_GROUP')) { + return ''; + } + + return ' INNER JOIN ( + SELECT DISTINCT cp.`id_product` FROM `'._DB_PREFIX_.'category_product` cp + INNER JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`) + WHERE cg.`id_group` = '.(int) Configuration::get('PS_UNIDENTIFIED_GROUP').' + ) g ON ps.`id_product` = g.`id_product`'; + } + public static function getRoomTypeIds($idShop) { - $groupJoin = ''; - if (Group::isFeatureActive() && Configuration::get('PS_UNIDENTIFIED_GROUP')) { - $groupJoin = ' INNER JOIN ( - SELECT DISTINCT cp.`id_product` FROM `'._DB_PREFIX_.'category_product` cp - INNER JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = cp.`id_category`) - WHERE cg.`id_group` = '.(int) Configuration::get('PS_UNIDENTIFIED_GROUP').' - ) g ON ps.`id_product` = g.`id_product`'; - } + return Db::getInstance()->executeS( + 'SELECT ps.`id_product` FROM `'._DB_PREFIX_.'product_shop` ps + INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = ps.`id_product`)'.self::getProductGroupJoin().' + WHERE ps.`id_shop` = '.(int) $idShop.' AND ps.`active` = 1 AND ps.`visibility` <> \'none\' AND p.`booking_product` = 1 + ORDER BY ps.`id_product`' + ); + } + public static function getStandaloneProductIds($idShop) + { + $standaloneTypes = array( + Product::SELLING_PREFERENCE_WITH_STANDALONE, + Product::SELLING_PREFERENCE_WITH_STANDALONE_AND_WITH_ROOM_TYPE, + Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_STANDALONE, + Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_ROOM_TYPE_AND_WITH_STANDALONE, + ); + // Types that are also sold with hotels need at least one hotel linked to the product + $withHotelTypes = array( + Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_STANDALONE, + Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_ROOM_TYPE_AND_WITH_STANDALONE, + ); return Db::getInstance()->executeS( 'SELECT ps.`id_product` FROM `'._DB_PREFIX_.'product_shop` ps - INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = ps.`id_product`)'.$groupJoin.' - WHERE ps.`id_shop` = '.(int) $idShop.' AND ps.`active` = 1 AND ps.`visibility` <> \'none\' AND p.`booking_product` = 1 + INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = ps.`id_product`)'.self::getProductGroupJoin().' + WHERE ps.`id_shop` = '.(int) $idShop.' AND ps.`active` = 1 AND ps.`show_at_front` = 1 + AND ps.`visibility` <> \'none\' AND p.`booking_product` = 0 + AND p.`selling_preference_type` IN ('.implode(', ', array_map('intval', $standaloneTypes)).') + AND ( + p.`selling_preference_type` NOT IN ('.implode(', ', array_map('intval', $withHotelTypes)).') + OR EXISTS ( + SELECT 1 FROM `'._DB_PREFIX_.'htl_room_type_service_product` rsp + WHERE rsp.`id_product` = p.`id_product` AND rsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_HOTEL.' + ) + ) ORDER BY ps.`id_product`' ); } diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlogsitemap/qlogsitemap.php index 7344a2551..fc034eb2f 100755 --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlogsitemap/qlogsitemap.php @@ -45,6 +45,7 @@ class Qlogsitemap extends Module 'contact' => 0.2, 'category' => 0.6, 'roomType' => 0.4, + 'standalone' => 0.4, 'cms' => 0.2, 'login' => 0.2, ); @@ -170,6 +171,7 @@ class Qlogsitemap extends Module $this->addPageUrls($lang, $this->pagesBefore); $this->addCategoryUrls($lang); $this->addRoomTypeUrls($lang); + $this->addStandaloneProductUrls($lang); $this->addCmsUrls($lang); $this->addPageUrls($lang, $this->pagesAfter); $this->closeSitemapFile(); @@ -265,6 +267,26 @@ class Qlogsitemap extends Module } } + protected function addStandaloneProductUrls($lang) + { + $idLang = (int) $lang['id_lang']; + $idShop = (int) $this->context->shop->id; + + foreach (QgsHelper::getStandaloneProductIds($idShop) as $row) { + $product = new Product((int) $row['id_product'], false, $idLang); + // The product has no content in this language + if (!$product->link_rewrite) { + continue; + } + + $this->addUrl( + $this->context->link->getProductLink($product, $product->link_rewrite, null, null, $idLang, $idShop), + 'standalone', + $product->date_upd + ); + } + } + protected function addCategoryUrls($lang) { $idLang = (int) $lang['id_lang']; From b542d70639b385e424504619593d76056c04c130 Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Tue, 13 Oct 2026 15:23:44 +0530 Subject: [PATCH 3/8] text changes --- modules/qlogsitemap/qlogsitemap.php | 61 ++++++++++++++++++- .../views/templates/hook/sitemap-panel.tpl | 52 ++++++++++------ 2 files changed, 93 insertions(+), 20 deletions(-) diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlogsitemap/qlogsitemap.php index fc034eb2f..bc9a013d8 100755 --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlogsitemap/qlogsitemap.php @@ -27,18 +27,36 @@ if (!defined('_PS_VERSION_')) { require_once dirname(__FILE__).'/classes/QgsHelper.php'; +/** + * Generates XML sitemaps (one set per language) plus a sitemap index file. + */ class Qlogsitemap extends Module { + /** + * Front pages listed before the categories and room types (page name => URL type). + * + * @var array + */ protected $pagesBefore = array( 'index' => 'home', 'our-properties' => 'meta', ); + /** + * Front pages listed after the CMS pages (page name => URL type). + * + * @var array + */ protected $pagesAfter = array( 'contact' => 'contact', 'authentication' => 'login', ); + /** + * Fixed priority of each URL type. + * + * @var array + */ protected $priorities = array( 'home' => 1.0, 'meta' => 0.8, @@ -49,11 +67,22 @@ class Qlogsitemap extends Module 'cms' => 0.2, 'login' => 0.2, ); + + /** + * URL types that use their own change frequency instead of the default one. + * + * @var array + */ protected $fixedFrequencies = array( 'cms' => 'monthly', 'login' => 'yearly', ); + /** + * Writer state while a sitemap is generated. + * + * @var resource|null + */ protected $fileHandle = null; protected $fileUrlCount = 0; protected $fileIndex = 0; @@ -72,7 +101,7 @@ class Qlogsitemap extends Module parent::__construct(); - $this->displayName = $this->l('Sitemap'); + $this->displayName = $this->l('QloApps Sitemap Generator'); $this->description = $this->l('Generates XML sitemaps for your hotel website and keeps them up to date. Compatible with all major search engines.'); $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?'); } @@ -134,10 +163,40 @@ class Qlogsitemap extends Module 'qgs_cron_manager_enabled' => Module::isEnabled('qlocrontaskmanager'), 'qgs_cron_manager_installed' => Module::isInstalled('qlocrontaskmanager'), 'qgs_cron_manager_link' => $this->getCronManagerLink(), + 'qgs_cron_task' => $this->getCronTaskSchedule(), )); return $this->display(__FILE__, 'views/templates/hook/sitemap-panel.tpl'); } + protected function getCronTaskSchedule() + { + if (!Module::isEnabled('qlocrontaskmanager')) { + return false; + } + + require_once _PS_MODULE_DIR_.'qlocrontaskmanager/classes/QctmRequiredClasses.php'; + + $idTask = QctmCronTask::getByModuleAndName((int) $this->id, 'generate_sitemap'); + if (!$idTask) { + return false; + } + + $cronTask = new QctmCronTask((int) $idTask); + if (!Validate::isLoadedObject($cronTask)) { + return false; + } + + $readable = $cronTask->cron_expression; + if (\Cron\CronExpression::isValidExpression($cronTask->cron_expression)) { + $readable = (new QctmCronExpressionTranslator())->getCronExpressionTranslation($cronTask->cron_expression); + } + + return array( + 'active' => (bool) $cronTask->active, + 'expression' => $cronTask->cron_expression, + 'readable' => $readable, + ); + } protected function getCronManagerLink() { diff --git a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl b/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl index b522aefb2..4d03f3188 100644 --- a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl +++ b/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl @@ -23,34 +23,48 @@
{l s='Sitemap generation' mod='qlogsitemap'}
-

{l s='Generate your XML sitemaps by clicking on the following button (this will erase the old sitemap files). Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlogsitemap'}

- {if $qgs_cron_manager_enabled} -

{l s='The sitemaps are also regenerated automatically every week (Sunday at midnight) by the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.

- {/if} +

{l s='Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlogsitemap'}

+

{l s='The main sitemap lists one sitemap file for each active language.' mod='qlogsitemap'}

- {if !$qgs_cron_manager_enabled} -
- {if $qgs_cron_manager_installed} - {l s='The Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if}, - {else} - {l s='The Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if}, - {/if} - {l s='or generate the sitemaps manually with the button below.' mod='qlogsitemap'} -
- {/if} +

{l s='Your sitemaps' mod='qlogsitemap'}

{if $qgs_sitemap_links} -

{l s='Main sitemap:' mod='qlogsitemap'} {$qgs_index_url|escape:'html':'UTF-8'}

+

{l s='Please set up the following sitemap URL in your search engine webmaster account:' mod='qlogsitemap'}
{$qgs_index_url|escape:'html':'UTF-8'}

+

{l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlogsitemap'}

-

{l s='Last update:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

+

{l s='Your last update was made on this date:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

{else} -

{l s='This shop has no sitemap yet.' mod='qlogsitemap'}

+

{l s='No sitemap has been generated yet.' mod='qlogsitemap'}

{/if} +
+

{l s='Sitemap generation' mod='qlogsitemap'}

+
    +
  • {l s='Manual: click on the "Generate sitemap" button. This erases the old sitemap files and creates new ones.' mod='qlogsitemap'}
  • + {if $qgs_cron_manager_enabled} + {if $qgs_cron_task && !$qgs_cron_task.active} +
  • {l s='Automatic: the sitemap task is disabled, so the sitemaps are not regenerated automatically. You can enable it in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {elseif $qgs_cron_task} +
  • {l s='Automatic: the sitemaps are regenerated automatically. Current schedule:' mod='qlogsitemap'} {$qgs_cron_task.readable|escape:'html':'UTF-8'}. {l s='You can configure this schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {else} +
  • {l s='Automatic: the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {/if} + {else} +
  • + {if $qgs_cron_manager_installed} + {l s='Automatic: the Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if} + {else} + {l s='Automatic: the Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if} + {/if} + {l s='to turn on the automatic generation.' mod='qlogsitemap'} +
  • + {/if} +
+
From 2460e8ce3ace8357a679e6036318467ef8666477 Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Wed, 14 Oct 2026 16:09:19 +0530 Subject: [PATCH 4/8] sitemap configuration added and sitemap(html)fixed --- config/xml/themes/default.xml | 1 + controllers/front/SitemapController.php | 101 ++++++++ install-dev/data/xml/meta.xml | 4 + modules/qlogsitemap/classes/QgsHelper.php | 43 ++++ modules/qlogsitemap/qlogsitemap.php | 221 ++++++++++++++++-- .../views/templates/admin/config.tpl | 132 +++++++++++ .../views/templates/admin/index.php | 32 +++ .../templates/hook/sitemap-cron-info.tpl | 48 ++++ .../views/templates/hook/sitemap-panel.tpl | 34 +-- .../category-tree-branch.tpl | 11 +- themes/hotel-reservation-theme/sitemap.tpl | 185 +++++++++++++++ 11 files changed, 765 insertions(+), 47 deletions(-) create mode 100644 controllers/front/SitemapController.php mode change 100755 => 100644 modules/qlogsitemap/qlogsitemap.php create mode 100644 modules/qlogsitemap/views/templates/admin/config.tpl create mode 100644 modules/qlogsitemap/views/templates/admin/index.php create mode 100644 modules/qlogsitemap/views/templates/hook/sitemap-cron-info.tpl create mode 100644 themes/hotel-reservation-theme/sitemap.tpl diff --git a/config/xml/themes/default.xml b/config/xml/themes/default.xml index 220d18e4a..4cd0df797 100644 --- a/config/xml/themes/default.xml +++ b/config/xml/themes/default.xml @@ -19,6 +19,7 @@ + diff --git a/controllers/front/SitemapController.php b/controllers/front/SitemapController.php new file mode 100644 index 000000000..8621c27af --- /dev/null +++ b/controllers/front/SitemapController.php @@ -0,0 +1,101 @@ + +* @copyright 2007-2017 PrestaShop SA +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +class SitemapControllerCore extends FrontController +{ + public $php_self = 'sitemap'; + + public function setMedia() + { + parent::setMedia(); + $this->addCSS(_THEME_CSS_DIR_.'sitemap.css'); + $this->addJS(_THEME_JS_DIR_.'tools/treeManagement.js'); + } + + /** + * Assign template vars related to page content + * @see FrontController::initContent() + */ + public function initContent() + { + parent::initContent(); + + $categoriesTree = Category::getRootCategory()->recurseLiteCategTree(0); + $this->addRoomTypes($categoriesTree); + $this->context->smarty->assign('categoriesTree', $categoriesTree); + $this->context->smarty->assign('categoriescmsTree', CMSCategory::getRecurseCategory($this->context->language->id, 1, 1, 1)); + $this->context->smarty->assign('voucherAllowed', (int)CartRule::isFeatureActive()); + $this->context->smarty->assign('PS_DISPLAY_BEST_SELLERS', Configuration::get('PS_DISPLAY_BEST_SELLERS')); + $this->context->smarty->assign('display_store', Configuration::get('PS_STORES_DISPLAY_SITEMAP')); + + $this->setTemplate(_PS_THEME_DIR_.'sitemap.tpl'); + } + + /** + * Add the room types of each hotel to the category tree (key room_types of the hotel category node). + * + * @param array $node Category tree node, updated by reference + */ + protected function addRoomTypes(&$node) + { + static $hotelCategories = null; + if ($hotelCategories === null) { + $hotelCategories = array(); + $rows = Db::getInstance()->executeS( + 'SELECT `id`, `id_category` FROM `'._DB_PREFIX_.'htl_branch_info` WHERE `active` = 1' + ); + foreach ((array) $rows as $row) { + $hotelCategories[(int) $row['id_category']] = (int) $row['id']; + } + } + + if (isset($hotelCategories[$node['id']])) { + $idLang = (int) $this->context->language->id; + $idShop = (int) $this->context->shop->id; + $node['room_types'] = array(); + $rows = Db::getInstance()->executeS( + 'SELECT hrt.`id_product` FROM `'._DB_PREFIX_.'htl_room_type` hrt + INNER JOIN `'._DB_PREFIX_.'product_shop` ps ON (ps.`id_product` = hrt.`id_product` AND ps.`id_shop` = '.$idShop.') + WHERE hrt.`id_hotel` = '.(int) $hotelCategories[$node['id']].' AND ps.`active` = 1 AND ps.`visibility` <> \'none\' + ORDER BY hrt.`id_product`' + ); + foreach ((array) $rows as $row) { + $product = new Product((int) $row['id_product'], false, $idLang); + if (!$product->link_rewrite) { + continue; + } + $node['room_types'][] = array( + 'name' => $product->name, + 'link' => $this->context->link->getProductLink($product, $product->link_rewrite, null, null, $idLang, $idShop), + ); + } + } + + foreach ($node['children'] as &$child) { + $this->addRoomTypes($child); + } + } +} diff --git a/install-dev/data/xml/meta.xml b/install-dev/data/xml/meta.xml index 48804dd12..04b321f20 100644 --- a/install-dev/data/xml/meta.xml +++ b/install-dev/data/xml/meta.xml @@ -38,6 +38,10 @@ 1 --> + + sitemap + 1 + supplier 1 diff --git a/modules/qlogsitemap/classes/QgsHelper.php b/modules/qlogsitemap/classes/QgsHelper.php index 69fe21d14..8150f068c 100644 --- a/modules/qlogsitemap/classes/QgsHelper.php +++ b/modules/qlogsitemap/classes/QgsHelper.php @@ -31,6 +31,49 @@ class QgsHelper const QGS_INDEX_FILE_NAME = 'sitemap.xml'; const QGS_DEFAULT_FREQUENCY = 'weekly'; + const TYPE_ROOM_TYPES = 'type-room-types'; + const TYPE_PROPERTIES = 'type-properties'; + const TYPE_STANDALONE = 'type-standalone'; + const TYPE_CMS = 'type-cms'; + public static function getFrequencies() + { + return array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'); + } + public static function getFrequency() + { + $frequency = Configuration::get('QLOGSITEMAP_FREQUENCY'); + + return in_array($frequency, self::getFrequencies(), true) ? $frequency : self::QGS_DEFAULT_FREQUENCY; + } + public static function getDisabledPages() + { + $pages = Configuration::get('QLOGSITEMAP_DISABLED_PAGES'); + + return $pages ? explode(',', $pages) : array(); + } + + public static function getModulePages() + { + $pages = array(); + $rows = (array) Db::getInstance()->executeS( + 'SELECT `page` FROM `'._DB_PREFIX_.'meta` WHERE `page` LIKE \'module-%\' ORDER BY `page`' + ); + foreach ($rows as $row) { + if (!preg_match('/^module-(.+)-([a-z0-9]+)$/i', $row['page'], $match)) { + continue; + } + if (in_array(strtolower($match[2]), array('validation', 'payment', 'confirmation'))) { + continue; + } + $module = Module::getInstanceByName($match[1]); + if ($module && $module->tab == 'payments_gateways') { + continue; + } + $pages[] = $row['page']; + } + + return $pages; + } protected static function getProductGroupJoin() { diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlogsitemap/qlogsitemap.php old mode 100755 new mode 100644 index bc9a013d8..1d7af83df --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlogsitemap/qlogsitemap.php @@ -50,6 +50,7 @@ class Qlogsitemap extends Module protected $pagesAfter = array( 'contact' => 'contact', 'authentication' => 'login', + 'sitemap' => 'sitemapPage', ); /** @@ -66,16 +67,19 @@ class Qlogsitemap extends Module 'standalone' => 0.4, 'cms' => 0.2, 'login' => 0.2, + 'modulePage' => 0.4, + 'sitemapPage' => 0.2, ); /** - * URL types that use their own change frequency instead of the default one. + * Cron expression of each automatic generation option (never disables the task). * * @var array */ - protected $fixedFrequencies = array( - 'cms' => 'monthly', - 'login' => 'yearly', + protected $cronOptions = array( + 'weekly' => '0 0 * * 0', + 'monthly' => '0 0 1 * *', + 'yearly' => '0 0 1 1 *', ); /** @@ -118,6 +122,8 @@ class Qlogsitemap extends Module QgsHelper::deleteSitemapFiles(); Configuration::deleteByName('QLOGSITEMAP_LAST_EXPORT'); + Configuration::deleteByName('QLOGSITEMAP_FREQUENCY'); + Configuration::deleteByName('QLOGSITEMAP_DISABLED_PAGES'); return parent::uninstall(); } @@ -155,7 +161,168 @@ class Qlogsitemap extends Module } } + $this->assignSitemapPanelVars(); + + return $this->display(__FILE__, 'views/templates/hook/sitemap-panel.tpl'); + } + public function getContent() + { + $output = ''; + + if (Tools::isSubmit('submitQloGsitemap')) { + $saved = true; + if (Tools::getIsset('QLOGSITEMAP_FREQUENCY')) { + $configOutput = $this->postProcessConfig(); + $saved = !strpos($configOutput, 'alert-danger'); + $output .= $configOutput; + } + if ($saved && $this->createSitemap()) { + $output .= $this->displayConfirmation($this->l('Your sitemaps were successfully created.')); + } elseif ($saved) { + $output .= $this->displayError($this->l('Unable to generate the sitemaps.')); + } + } elseif (Tools::isSubmit('submitQloGsitemapConfig')) { + $output .= $this->postProcessConfig(); + } elseif (Tools::isSubmit('submitQloGsitemapCron')) { + $output .= $this->postProcessCron(); + } + + $this->assignSitemapPanelVars(); + $cronLabels = array( + 'weekly' => $this->l('Weekly'), + 'monthly' => $this->l('Monthly'), + 'yearly' => $this->l('Yearly'), + 'never' => $this->l('Never'), + ); + $frequencies = array(); + foreach (QgsHelper::getFrequencies() as $frequency) { + $frequencies[$frequency] = $this->getFrequencyLabel($frequency); + } + + $disabledPages = QgsHelper::getDisabledPages(); + $pages = array('core' => array(), 'module' => array()); + $idLang = (int) $this->context->language->id; + foreach (array_keys($this->getExcludablePages()) as $page) { + $meta = Meta::getMetaByPage($page, $idLang); + $pages['core'][] = array( + 'page' => $page, + 'title' => !empty($meta['title']) ? $meta['title'] : $page, + 'show_key' => true, + 'excluded' => in_array($page, $disabledPages), + ); + } + foreach (QgsHelper::getModulePages() as $page) { + $meta = Meta::getMetaByPage($page, $idLang); + $pages['module'][] = array( + 'page' => $page, + 'title' => !empty($meta['title']) ? $meta['title'] : $page, + 'show_key' => true, + 'excluded' => in_array($page, $disabledPages), + ); + } + foreach ($this->getExcludableTypes() as $type => $title) { + $pages['core'][] = array( + 'page' => $type, + 'title' => $title, + 'show_key' => false, + 'excluded' => in_array($type, $disabledPages), + ); + } + $this->context->smarty->assign(array( + 'qgs_form_action' => AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'), + 'qgs_cron_options' => $cronLabels, + 'qgs_frequencies' => $frequencies, + 'qgs_frequency' => QgsHelper::getFrequency(), + 'qgs_pages' => $pages, + )); + + return $output.$this->display(__FILE__, 'views/templates/admin/config.tpl'); + } + + protected function getExcludablePages() + { + return array_diff_key(array_merge($this->pagesBefore, $this->pagesAfter), array('index' => true)); + } + + protected function getExcludableTypes() + { + $types = array( + QgsHelper::TYPE_ROOM_TYPES => $this->l('Room types'), + QgsHelper::TYPE_PROPERTIES => $this->l('Properties'), + ); + if (QgsHelper::getStandaloneProductIds((int) $this->context->shop->id)) { + $types[QgsHelper::TYPE_STANDALONE] = $this->l('Standalone products'); + } + if (QgsHelper::getCmsIds((int) $this->context->language->id, (int) $this->context->shop->id)) { + $types[QgsHelper::TYPE_CMS] = $this->l('CMS pages'); + } + + return $types; + } + + protected function postProcessConfig() + { + $frequency = Tools::getValue('QLOGSITEMAP_FREQUENCY'); + if (!in_array($frequency, QgsHelper::getFrequencies(), true)) { + return $this->displayError($this->l('Invalid update frequency.')); + } + + $knownPages = array_merge(array_keys($this->getExcludablePages()), array_keys($this->getExcludableTypes()), QgsHelper::getModulePages()); + $disabledPages = array_values(array_intersect($knownPages, (array) Tools::getValue('QLOGSITEMAP_DISABLED_PAGES', array()))); + + Configuration::updateValue('QLOGSITEMAP_FREQUENCY', $frequency); + Configuration::updateValue('QLOGSITEMAP_DISABLED_PAGES', implode(',', $disabledPages)); + + return $this->displayConfirmation($this->l('Settings updated successfully. Generate the sitemap to apply them.')); + } + + protected function postProcessCron() + { + $option = Tools::getValue('QLOGSITEMAP_CRON'); + if ($option !== 'never' && !isset($this->cronOptions[$option])) { + return $this->displayError($this->l('Invalid cron schedule.')); + } + + $cronTask = $this->getCronTask(); + if (!$cronTask) { + return $this->displayError($this->l('The sitemap cron task was not found in the Cron Task Manager.')); + } + + if ($option === 'never') { + $cronTask->active = 0; + } else { + $cronTask->cron_expression = $this->cronOptions[$option]; + $cronTask->active = 1; + } + + if (!$cronTask->save()) { + return $this->displayError($this->l('Unable to update the cron task.')); + } + + return $this->displayConfirmation($this->l('Cron schedule updated successfully.')); + } + + protected function getFrequencyLabel($frequency) + { + $labels = array( + 'always' => $this->l('always'), + 'hourly' => $this->l('hourly'), + 'daily' => $this->l('daily'), + 'weekly' => $this->l('weekly'), + 'monthly' => $this->l('monthly'), + 'yearly' => $this->l('yearly'), + 'never' => $this->l('never'), + ); + + return $labels[$frequency]; + } + + protected function assignSitemapPanelVars() + { + $this->context->smarty->assign(array( + 'qgs_template_dir' => _PS_MODULE_DIR_.$this->name.'/views/templates/', + 'qgs_config_link' => $this->context->link->getAdminLink('AdminModules').'&configure='.$this->name, 'qgs_index_url' => $this->context->link->getBaseLink().QgsHelper::QGS_INDEX_FILE_NAME, 'qgs_store_url' => $this->context->link->getBaseLink(), 'qgs_sitemap_links' => QgsHelper::getSitemapFiles(), @@ -165,10 +332,9 @@ class Qlogsitemap extends Module 'qgs_cron_manager_link' => $this->getCronManagerLink(), 'qgs_cron_task' => $this->getCronTaskSchedule(), )); - - return $this->display(__FILE__, 'views/templates/hook/sitemap-panel.tpl'); } - protected function getCronTaskSchedule() + + protected function getCronTask() { if (!Module::isEnabled('qlocrontaskmanager')) { return false; @@ -182,7 +348,14 @@ class Qlogsitemap extends Module } $cronTask = new QctmCronTask((int) $idTask); - if (!Validate::isLoadedObject($cronTask)) { + + return Validate::isLoadedObject($cronTask) ? $cronTask : false; + } + + protected function getCronTaskSchedule() + { + $cronTask = $this->getCronTask(); + if (!$cronTask) { return false; } @@ -191,10 +364,18 @@ class Qlogsitemap extends Module $readable = (new QctmCronExpressionTranslator())->getCronExpressionTranslation($cronTask->cron_expression); } + $option = ''; + if (!$cronTask->active) { + $option = 'never'; + } elseif (($found = array_search($cronTask->cron_expression, $this->cronOptions, true)) !== false) { + $option = $found; + } + return array( 'active' => (bool) $cronTask->active, 'expression' => $cronTask->cron_expression, 'readable' => $readable, + 'option' => $option, ); } @@ -225,14 +406,24 @@ class Qlogsitemap extends Module QgsHelper::deleteSitemapFiles(); + $disabledPages = QgsHelper::getDisabledPages(); foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { $this->startSitemapSet($lang['iso_code']); $this->addPageUrls($lang, $this->pagesBefore); - $this->addCategoryUrls($lang); - $this->addRoomTypeUrls($lang); - $this->addStandaloneProductUrls($lang); - $this->addCmsUrls($lang); + if (!in_array(QgsHelper::TYPE_PROPERTIES, $disabledPages)) { + $this->addCategoryUrls($lang); + } + if (!in_array(QgsHelper::TYPE_ROOM_TYPES, $disabledPages)) { + $this->addRoomTypeUrls($lang); + } + if (!in_array(QgsHelper::TYPE_STANDALONE, $disabledPages)) { + $this->addStandaloneProductUrls($lang); + } + if (!in_array(QgsHelper::TYPE_CMS, $disabledPages)) { + $this->addCmsUrls($lang); + } $this->addPageUrls($lang, $this->pagesAfter); + $this->addPageUrls($lang, array_fill_keys(array_diff(QgsHelper::getModulePages(), $disabledPages), 'modulePage')); $this->closeSitemapFile(); } @@ -289,7 +480,7 @@ class Qlogsitemap extends Module } $priority = $this->priorities[$type]; - $frequency = isset($this->fixedFrequencies[$type]) ? $this->fixedFrequencies[$type] : QgsHelper::QGS_DEFAULT_FREQUENCY; + $frequency = QgsHelper::getFrequency(); $xml = ''.PHP_EOL.''.QgsHelper::escapeXml($loc).''.PHP_EOL; if ($lastMod && strtotime($lastMod) > 0) { $xml .= ''.date('Y-m-d', strtotime($lastMod)).''.PHP_EOL; @@ -306,7 +497,11 @@ class Qlogsitemap extends Module protected function addPageUrls($lang, array $pages) { + $disabledPages = QgsHelper::getDisabledPages(); foreach ($pages as $page => $type) { + if ($page !== 'index' && in_array($page, $disabledPages)) { + continue; + } $this->addUrl($this->context->link->getPageLink($page, null, (int) $lang['id_lang']), $type); } } diff --git a/modules/qlogsitemap/views/templates/admin/config.tpl b/modules/qlogsitemap/views/templates/admin/config.tpl new file mode 100644 index 000000000..9ac71c0e6 --- /dev/null +++ b/modules/qlogsitemap/views/templates/admin/config.tpl @@ -0,0 +1,132 @@ +{** +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License version 3.0 +* that is bundled with this package in the file LICENSE.md +* It is also available through the world-wide-web at this URL: +* https://opensource.org/license/osl-3-0-php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to support@qloapps.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to a newer +* versions in the future. If you wish to customize this module for your needs +* please refer to https://store.webkul.com/customisation-guidelines for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul +* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 +*} + +
+
{l s='Your sitemaps' mod='qlogsitemap'}
+ {if $qgs_sitemap_links} +

{l s='Please set up the following sitemap URL in your Google Search Console account:' mod='qlogsitemap'}
{$qgs_index_url|escape:'html':'UTF-8'}

+

{l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlogsitemap'}

+ +

{l s='Your last update was made on this date:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

+ {else} +

{l s='No sitemap has been generated yet.' mod='qlogsitemap'}

+ {/if} +
+ +
+
+
{l s='Configure your sitemap' mod='qlogsitemap'}
+

{l s='Several sitemap files will be generated depending on how your server is configured and on the number of activated products in your catalog.' mod='qlogsitemap'}

+
+ +
+ +
+
+
+ +
+ {if $qgs_pages.core} +

+ {foreach from=$qgs_pages.core item=page} +
+ +
+ {/foreach} + {else} +

{l s='No QloApps pages available.' mod='qlogsitemap'}

+ {/if} +
+
+ {if $qgs_pages.module} +
+ +
+ {if $qgs_pages.module} +

+ {foreach from=$qgs_pages.module item=page} +
+ +
+ {/foreach} + {/if} +
+
+ {/if} + +
+
+ +
+
+
{l s='Cron configuration' mod='qlogsitemap'}
+ {if $qgs_cron_task} +
+ +
+ +
+
+ {/if} + {include file="{$qgs_template_dir}hook/sitemap-cron-info.tpl"} + +
+
+ + diff --git a/modules/qlogsitemap/views/templates/admin/index.php b/modules/qlogsitemap/views/templates/admin/index.php new file mode 100644 index 000000000..409280877 --- /dev/null +++ b/modules/qlogsitemap/views/templates/admin/index.php @@ -0,0 +1,32 @@ + +

{l s='Sitemap generation' mod='qlogsitemap'}

+
    +
  • {l s='Manual: to generate the sitemap manually, click on the "Generate sitemap" button on the module configuration page. This erases the old sitemap files and creates new ones.' mod='qlogsitemap'}
  • + {if $qgs_cron_manager_enabled} + {if $qgs_cron_task && !$qgs_cron_task.active} +
  • {l s='Automatic: the sitemap task is disabled, so the sitemaps are not regenerated automatically. You can enable it in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {elseif $qgs_cron_task} +
  • {l s='Automatic: the sitemaps are regenerated automatically. Current schedule:' mod='qlogsitemap'} {$qgs_cron_task.readable|escape:'html':'UTF-8'}. {l s='You can configure this schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {else} +
  • {l s='Automatic: the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • + {/if} + {else} +
  • + {if $qgs_cron_manager_installed} + {l s='Automatic: the Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if} + {else} + {l s='Automatic: the Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} + {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if} + {/if} + {l s='to turn on the automatic generation.' mod='qlogsitemap'} +
  • + {/if} +
+
diff --git a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl b/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl index 4d03f3188..0fe56e3d8 100644 --- a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl +++ b/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl @@ -25,46 +25,16 @@

{l s='Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlogsitemap'}

{l s='The main sitemap lists one sitemap file for each active language.' mod='qlogsitemap'}

+

{l s='You can customize the sitemap configuration (update frequency and excluded pages) on the module configuration page.' mod='qlogsitemap'} {l s='Sitemap configuration' mod='qlogsitemap'}

{l s='Your sitemaps' mod='qlogsitemap'}

{if $qgs_sitemap_links}

{l s='Please set up the following sitemap URL in your search engine webmaster account:' mod='qlogsitemap'}
{$qgs_index_url|escape:'html':'UTF-8'}

-

{l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlogsitemap'}

-

{l s='Your last update was made on this date:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

{else}

{l s='No sitemap has been generated yet.' mod='qlogsitemap'}

{/if} -
-

{l s='Sitemap generation' mod='qlogsitemap'}

-
    -
  • {l s='Manual: click on the "Generate sitemap" button. This erases the old sitemap files and creates new ones.' mod='qlogsitemap'}
  • - {if $qgs_cron_manager_enabled} - {if $qgs_cron_task && !$qgs_cron_task.active} -
  • {l s='Automatic: the sitemap task is disabled, so the sitemaps are not regenerated automatically. You can enable it in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • - {elseif $qgs_cron_task} -
  • {l s='Automatic: the sitemaps are regenerated automatically. Current schedule:' mod='qlogsitemap'} {$qgs_cron_task.readable|escape:'html':'UTF-8'}. {l s='You can configure this schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • - {else} -
  • {l s='Automatic: the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
  • - {/if} - {else} -
  • - {if $qgs_cron_manager_installed} - {l s='Automatic: the Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if} - {else} - {l s='Automatic: the Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if} - {/if} - {l s='to turn on the automatic generation.' mod='qlogsitemap'} -
  • - {/if} -
-
+ {include file="{$qgs_template_dir}hook/sitemap-cron-info.tpl"} diff --git a/themes/hotel-reservation-theme/category-tree-branch.tpl b/themes/hotel-reservation-theme/category-tree-branch.tpl index fbc7bae8e..7015cd300 100644 --- a/themes/hotel-reservation-theme/category-tree-branch.tpl +++ b/themes/hotel-reservation-theme/category-tree-branch.tpl @@ -25,15 +25,22 @@
  • {$node.name|escape:'html':'UTF-8'} - {if $node.children|@count > 0} + {if $node.children|@count > 0 || (isset($node.room_types) && $node.room_types|@count > 0)}
      {foreach from=$node.children item=child name=categoryTreeBranch} - {if $smarty.foreach.categoryTreeBranch.last} + {if $smarty.foreach.categoryTreeBranch.last && !(isset($node.room_types) && $node.room_types|@count > 0)} {include file="$tpl_dir./category-tree-branch.tpl" node=$child last='true'} {else} {include file="$tpl_dir./category-tree-branch.tpl" node=$child last='false'} {/if} {/foreach} + {if isset($node.room_types)} + {foreach from=$node.room_types item=roomType name=roomTypeBranch} +
    • + {$roomType.name|escape:'html':'UTF-8'} +
    • + {/foreach} + {/if}
    {/if}
  • \ No newline at end of file diff --git a/themes/hotel-reservation-theme/sitemap.tpl b/themes/hotel-reservation-theme/sitemap.tpl new file mode 100644 index 000000000..862b93590 --- /dev/null +++ b/themes/hotel-reservation-theme/sitemap.tpl @@ -0,0 +1,185 @@ +{* +* 2007-2017 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2017 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + +{capture name=path}{l s='Sitemap'}{/capture} + +

    + {l s='Sitemap'} +

    +
    +
    +
    +

    {l s='Our properties'}

    + +
    +
    +
    +
    +

    + {l s='Your Account'} +

    + +
    +
    +
    +
    +
    +
    +

    {l s='Categories'}

    +
    + +
    +
      + {if isset($categoriesTree.children)} + {foreach $categoriesTree.children as $child} + {if $child@last} + {include file="$tpl_dir./category-tree-branch.tpl" node=$child last='true'} + {else} + {include file="$tpl_dir./category-tree-branch.tpl" node=$child} + {/if} + {/foreach} + {/if} +
    +
    +
    +
    +
    +

    {l s='Pages'}

    + +
    +
    +
    From d103f9814835c15d568ca4ff2833879ac5483cab Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Wed, 14 Oct 2026 17:18:13 +0530 Subject: [PATCH 5/8] sitemap(html)design fix --- controllers/front/SitemapController.php | 15 ++++ modules/qlogsitemap/classes/QgsHelper.php | 7 ++ modules/qlogsitemap/qlogsitemap.php | 45 ++++++------ .../hotel-reservation-theme/css/sitemap.css | 43 ++++++++++++ .../img/sitemap-horizontal.png | Bin 0 -> 71 bytes .../img/sitemap-last.png | Bin 0 -> 97 bytes .../hotel-reservation-theme/sass/sitemap.scss | 66 ++++++++++++++++++ themes/hotel-reservation-theme/sitemap.tpl | 5 -- 8 files changed, 156 insertions(+), 25 deletions(-) create mode 100644 themes/hotel-reservation-theme/css/sitemap.css create mode 100644 themes/hotel-reservation-theme/img/sitemap-horizontal.png create mode 100644 themes/hotel-reservation-theme/img/sitemap-last.png create mode 100644 themes/hotel-reservation-theme/sass/sitemap.scss diff --git a/controllers/front/SitemapController.php b/controllers/front/SitemapController.php index 8621c27af..8fb39deff 100644 --- a/controllers/front/SitemapController.php +++ b/controllers/front/SitemapController.php @@ -45,6 +45,7 @@ class SitemapControllerCore extends FrontController $categoriesTree = Category::getRootCategory()->recurseLiteCategTree(0); $this->addRoomTypes($categoriesTree); + $categoriesTree['children'] = $this->getHotelNodes($categoriesTree); $this->context->smarty->assign('categoriesTree', $categoriesTree); $this->context->smarty->assign('categoriescmsTree', CMSCategory::getRecurseCategory($this->context->language->id, 1, 1, 1)); $this->context->smarty->assign('voucherAllowed', (int)CartRule::isFeatureActive()); @@ -98,4 +99,18 @@ class SitemapControllerCore extends FrontController $this->addRoomTypes($child); } } + protected function getHotelNodes($node) + { + $hotels = array(); + if (isset($node['room_types'])) { + $node['children'] = array(); + $hotels[] = $node; + } else { + foreach ($node['children'] as $child) { + $hotels = array_merge($hotels, $this->getHotelNodes($child)); + } + } + + return $hotels; + } } diff --git a/modules/qlogsitemap/classes/QgsHelper.php b/modules/qlogsitemap/classes/QgsHelper.php index 8150f068c..3c131074b 100644 --- a/modules/qlogsitemap/classes/QgsHelper.php +++ b/modules/qlogsitemap/classes/QgsHelper.php @@ -75,6 +75,13 @@ class QgsHelper return $pages; } + public static function getMetaIdByPage($page) + { + return (int) Db::getInstance()->getValue( + 'SELECT `id_meta` FROM `'._DB_PREFIX_.'meta` WHERE `page` = \''.pSQL($page).'\'' + ); + } + protected static function getProductGroupJoin() { if (!Group::isFeatureActive() || !Configuration::get('PS_UNIDENTIFIED_GROUP')) { diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlogsitemap/qlogsitemap.php index 1d7af83df..2f93b9de7 100644 --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlogsitemap/qlogsitemap.php @@ -42,22 +42,12 @@ class Qlogsitemap extends Module 'our-properties' => 'meta', ); - /** - * Front pages listed after the CMS pages (page name => URL type). - * - * @var array - */ protected $pagesAfter = array( 'contact' => 'contact', 'authentication' => 'login', 'sitemap' => 'sitemapPage', ); - /** - * Fixed priority of each URL type. - * - * @var array - */ protected $priorities = array( 'home' => 1.0, 'meta' => 0.8, @@ -71,22 +61,12 @@ class Qlogsitemap extends Module 'sitemapPage' => 0.2, ); - /** - * Cron expression of each automatic generation option (never disables the task). - * - * @var array - */ protected $cronOptions = array( 'weekly' => '0 0 * * 0', 'monthly' => '0 0 1 * *', 'yearly' => '0 0 1 1 *', ); - /** - * Writer state while a sitemap is generated. - * - * @var resource|null - */ protected $fileHandle = null; protected $fileUrlCount = 0; protected $fileIndex = 0; @@ -405,6 +385,7 @@ class Qlogsitemap extends Module } QgsHelper::deleteSitemapFiles(); + $this->sitemapPageMeta(); $disabledPages = QgsHelper::getDisabledPages(); foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { @@ -434,6 +415,30 @@ class Qlogsitemap extends Module return $result; } + protected function sitemapPageMeta() + { + $idMeta = QgsHelper::getMetaIdByPage('sitemap'); + $objMeta = new Meta($idMeta ?: null); + if (!$idMeta) { + $objMeta->page = 'sitemap'; + $objMeta->configurable = 1; + } + + $missing = false; + foreach (Language::getLanguages(false) as $lang) { + $idLang = (int) $lang['id_lang']; + if ($idMeta && Meta::getMetaByPage('sitemap', $idLang)) { + continue; + } + $objMeta->title[$idLang] = $this->l('Sitemap'); + $objMeta->description[$idLang] = $this->l('Lost? Find what you are looking for'); + $objMeta->keywords[$idLang] = ''; + $objMeta->url_rewrite[$idLang] = 'sitemap'; + $missing = true; + } + + return $missing ? (bool) $objMeta->save() : true; + } protected function startSitemapSet($iso) { diff --git a/themes/hotel-reservation-theme/css/sitemap.css b/themes/hotel-reservation-theme/css/sitemap.css new file mode 100644 index 000000000..56a530856 --- /dev/null +++ b/themes/hotel-reservation-theme/css/sitemap.css @@ -0,0 +1,43 @@ +/****************************************************************** + Sitemap Page Styles +*******************************************************************/ +#sitemap .sitemap_block .page-subheading { + margin-bottom: 16px; } +#sitemap .sitemap_block li { + line-height: 16px; + padding-bottom: 11px; } + #sitemap .sitemap_block li a:before { + content: "\f105"; + display: inline-block; + font-family: "FontAwesome"; + padding-right: 10px; } + #sitemap .sitemap_block li a:hover { + font-weight: bold; } + +#listpage_content div.tree_top { + padding: 5px 0 0 27px; } + #listpage_content div.tree_top a:before { + content: "\f015"; + display: inline-block; + font-family: "FontAwesome"; + font-size: 20px; + color: #333; } + #listpage_content div.tree_top a:hover:before { + color: #515151; } + +ul.tree { + padding-left: 24px; } + ul.tree li { + margin: 0 0 0 21px; + padding: 5px 0 0 33px; + border-left: 1px solid #d6d4d4; + background: url(../img/sitemap-horizontal.png) no-repeat left 15px transparent; } + ul.tree li a:hover { + font-weight: bold; } + ul.tree > li { + margin: 0 0 0 11px; } + ul.tree li.last { + border: medium none; + background: url(../img/sitemap-last.png) no-repeat 0px -4px transparent; } + +/*# sourceMappingURL=sitemap.css.map */ diff --git a/themes/hotel-reservation-theme/img/sitemap-horizontal.png b/themes/hotel-reservation-theme/img/sitemap-horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..231e716f01a3a476332a1d592035f4122528e36a GIT binary patch literal 71 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W@!2~1&KS&k li { + margin: 0 0 0 11px; + } + li.last { + border: medium none; + background: url(../img/sitemap-last.png) no-repeat 0px -4px transparent; + } +} \ No newline at end of file diff --git a/themes/hotel-reservation-theme/sitemap.tpl b/themes/hotel-reservation-theme/sitemap.tpl index 862b93590..d404dd5d4 100644 --- a/themes/hotel-reservation-theme/sitemap.tpl +++ b/themes/hotel-reservation-theme/sitemap.tpl @@ -148,11 +148,6 @@

    {l s='Pages'}

      -
    • - - {$categoriescmsTree.name|escape:'html':'UTF-8'} - -
    • {if isset($categoriescmsTree.children)} {foreach $categoriescmsTree.children as $child} {if (isset($child.children) && $child.children|@count > 0) || $child.cms|@count > 0} From 18a90cc4a454266fd58e5675817d8f040d7c6727 Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Thu, 15 Oct 2026 10:44:50 +0530 Subject: [PATCH 6/8] sitemaphtml page creation updated --- modules/qlogsitemap/qlogsitemap.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlogsitemap/qlogsitemap.php index 2f93b9de7..b0a4780e2 100644 --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlogsitemap/qlogsitemap.php @@ -92,9 +92,14 @@ class Qlogsitemap extends Module public function install() { - return parent::install() - && $this->registerHook('displayAdminMetaOptions') - && $this->registerHook('registerCronTasks'); + if (!parent::install() + || !$this->registerHook('displayAdminMetaOptions') + || !$this->registerHook('registerCronTasks') + ) { + return false; + } + $this->sitemapPageMeta(); + return true; } public function uninstall() @@ -385,7 +390,6 @@ class Qlogsitemap extends Module } QgsHelper::deleteSitemapFiles(); - $this->sitemapPageMeta(); $disabledPages = QgsHelper::getDisabledPages(); foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { From 42963961f0dbe27d60ba985418b3e543f8a0f860 Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Thu, 15 Oct 2026 15:40:56 +0530 Subject: [PATCH 7/8] ui changes --- .../views/templates/admin/config.tpl | 132 ---------- .../templates/hook/sitemap-cron-info.tpl | 48 ---- .../views/templates/hook/sitemap-panel.tpl | 41 --- .../{qlogsitemap => qlositemap}/LICENSE.md | 0 .../classes/QsmHelper.php} | 24 +- .../classes/index.php | 0 modules/{qlogsitemap => qlositemap}/index.php | 0 modules/{qlogsitemap => qlositemap}/logo.gif | Bin modules/{qlogsitemap => qlositemap}/logo.png | Bin .../qlositemap.php} | 247 ++++++++++-------- .../views/index.php | 0 .../views/templates/admin/config.tpl | 162 ++++++++++++ .../views/templates/admin/index.php | 0 .../views/templates/hook/index.php | 0 .../templates/hook/sitemap-cron-info.tpl | 56 ++++ .../views/templates/hook/sitemap-panel.tpl | 40 +++ .../views/templates/index.php | 0 17 files changed, 406 insertions(+), 344 deletions(-) delete mode 100644 modules/qlogsitemap/views/templates/admin/config.tpl delete mode 100644 modules/qlogsitemap/views/templates/hook/sitemap-cron-info.tpl delete mode 100644 modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl rename modules/{qlogsitemap => qlositemap}/LICENSE.md (100%) rename modules/{qlogsitemap/classes/QgsHelper.php => qlositemap/classes/QsmHelper.php} (94%) rename modules/{qlogsitemap => qlositemap}/classes/index.php (100%) rename modules/{qlogsitemap => qlositemap}/index.php (100%) rename modules/{qlogsitemap => qlositemap}/logo.gif (100%) rename modules/{qlogsitemap => qlositemap}/logo.png (100%) rename modules/{qlogsitemap/qlogsitemap.php => qlositemap/qlositemap.php} (70%) rename modules/{qlogsitemap => qlositemap}/views/index.php (100%) create mode 100644 modules/qlositemap/views/templates/admin/config.tpl rename modules/{qlogsitemap => qlositemap}/views/templates/admin/index.php (100%) rename modules/{qlogsitemap => qlositemap}/views/templates/hook/index.php (100%) create mode 100644 modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl create mode 100644 modules/qlositemap/views/templates/hook/sitemap-panel.tpl rename modules/{qlogsitemap => qlositemap}/views/templates/index.php (100%) diff --git a/modules/qlogsitemap/views/templates/admin/config.tpl b/modules/qlogsitemap/views/templates/admin/config.tpl deleted file mode 100644 index 9ac71c0e6..000000000 --- a/modules/qlogsitemap/views/templates/admin/config.tpl +++ /dev/null @@ -1,132 +0,0 @@ -{** -* NOTICE OF LICENSE -* -* This source file is subject to the Open Software License version 3.0 -* that is bundled with this package in the file LICENSE.md -* It is also available through the world-wide-web at this URL: -* https://opensource.org/license/osl-3-0-php -* If you did not receive a copy of the license and are unable to -* obtain it through the world-wide-web, please send an email -* to support@qloapps.com so we can send you a copy immediately. -* -* DISCLAIMER -* -* Do not edit or add to this file if you wish to upgrade this module to a newer -* versions in the future. If you wish to customize this module for your needs -* please refer to https://store.webkul.com/customisation-guidelines for more information. -* -* @author Webkul IN -* @copyright Since 2010 Webkul -* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 -*} - -
      -
      {l s='Your sitemaps' mod='qlogsitemap'}
      - {if $qgs_sitemap_links} -

      {l s='Please set up the following sitemap URL in your Google Search Console account:' mod='qlogsitemap'}
      {$qgs_index_url|escape:'html':'UTF-8'}

      -

      {l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlogsitemap'}

      - -

      {l s='Your last update was made on this date:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

      - {else} -

      {l s='No sitemap has been generated yet.' mod='qlogsitemap'}

      - {/if} -
      - -
      -
      -
      {l s='Configure your sitemap' mod='qlogsitemap'}
      -

      {l s='Several sitemap files will be generated depending on how your server is configured and on the number of activated products in your catalog.' mod='qlogsitemap'}

      -
      - -
      - -
      -
      -
      - -
      - {if $qgs_pages.core} -

      - {foreach from=$qgs_pages.core item=page} -
      - -
      - {/foreach} - {else} -

      {l s='No QloApps pages available.' mod='qlogsitemap'}

      - {/if} -
      -
      - {if $qgs_pages.module} -
      - -
      - {if $qgs_pages.module} -

      - {foreach from=$qgs_pages.module item=page} -
      - -
      - {/foreach} - {/if} -
      -
      - {/if} - -
      -
      - -
      -
      -
      {l s='Cron configuration' mod='qlogsitemap'}
      - {if $qgs_cron_task} -
      - -
      - -
      -
      - {/if} - {include file="{$qgs_template_dir}hook/sitemap-cron-info.tpl"} - -
      -
      - - diff --git a/modules/qlogsitemap/views/templates/hook/sitemap-cron-info.tpl b/modules/qlogsitemap/views/templates/hook/sitemap-cron-info.tpl deleted file mode 100644 index 8ef744c8e..000000000 --- a/modules/qlogsitemap/views/templates/hook/sitemap-cron-info.tpl +++ /dev/null @@ -1,48 +0,0 @@ -{** -* NOTICE OF LICENSE -* -* This source file is subject to the Open Software License version 3.0 -* that is bundled with this package in the file LICENSE.md -* It is also available through the world-wide-web at this URL: -* https://opensource.org/license/osl-3-0-php -* If you did not receive a copy of the license and are unable to -* obtain it through the world-wide-web, please send an email -* to support@qloapps.com so we can send you a copy immediately. -* -* DISCLAIMER -* -* Do not edit or add to this file if you wish to upgrade this module to a newer -* versions in the future. If you wish to customize this module for your needs -* please refer to https://store.webkul.com/customisation-guidelines for more information. -* -* @author Webkul IN -* @copyright Since 2010 Webkul -* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 -*} - -
      -

      {l s='Sitemap generation' mod='qlogsitemap'}

      -
        -
      • {l s='Manual: to generate the sitemap manually, click on the "Generate sitemap" button on the module configuration page. This erases the old sitemap files and creates new ones.' mod='qlogsitemap'}
      • - {if $qgs_cron_manager_enabled} - {if $qgs_cron_task && !$qgs_cron_task.active} -
      • {l s='Automatic: the sitemap task is disabled, so the sitemaps are not regenerated automatically. You can enable it in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
      • - {elseif $qgs_cron_task} -
      • {l s='Automatic: the sitemaps are regenerated automatically. Current schedule:' mod='qlogsitemap'} {$qgs_cron_task.readable|escape:'html':'UTF-8'}. {l s='You can configure this schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
      • - {else} -
      • {l s='Automatic: the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlogsitemap'} {l s='Cron Task Manager' mod='qlogsitemap'}.
      • - {/if} - {else} -
      • - {if $qgs_cron_manager_installed} - {l s='Automatic: the Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Enable the module' mod='qlogsitemap'}{else}{l s='Enable the module' mod='qlogsitemap'}{/if} - {else} - {l s='Automatic: the Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlogsitemap'} - {if $qgs_cron_manager_link}{l s='Install the module' mod='qlogsitemap'}{else}{l s='Install the module' mod='qlogsitemap'}{/if} - {/if} - {l s='to turn on the automatic generation.' mod='qlogsitemap'} -
      • - {/if} -
      -
      diff --git a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl b/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl deleted file mode 100644 index 0fe56e3d8..000000000 --- a/modules/qlogsitemap/views/templates/hook/sitemap-panel.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** -* NOTICE OF LICENSE -* -* This source file is subject to the Open Software License version 3.0 -* that is bundled with this package in the file LICENSE.md -* It is also available through the world-wide-web at this URL: -* https://opensource.org/license/osl-3-0-php -* If you did not receive a copy of the license and are unable to -* obtain it through the world-wide-web, please send an email -* to support@qloapps.com so we can send you a copy immediately. -* -* DISCLAIMER -* -* Do not edit or add to this file if you wish to upgrade this module to a newer -* versions in the future. If you wish to customize this module for your needs -* please refer to https://store.webkul.com/customisation-guidelines for more information. -* -* @author Webkul IN -* @copyright Since 2010 Webkul -* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 -*} - -
      -
      {l s='Sitemap generation' mod='qlogsitemap'}
      -
      -

      {l s='Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlogsitemap'}

      -

      {l s='The main sitemap lists one sitemap file for each active language.' mod='qlogsitemap'}

      -

      {l s='You can customize the sitemap configuration (update frequency and excluded pages) on the module configuration page.' mod='qlogsitemap'} {l s='Sitemap configuration' mod='qlogsitemap'}

      -
      -

      {l s='Your sitemaps' mod='qlogsitemap'}

      - {if $qgs_sitemap_links} -

      {l s='Please set up the following sitemap URL in your search engine webmaster account:' mod='qlogsitemap'}
      {$qgs_index_url|escape:'html':'UTF-8'}

      -

      {l s='Your last update was made on this date:' mod='qlogsitemap'} {$qgs_last_export|escape:'html':'UTF-8'}

      - {else} -

      {l s='No sitemap has been generated yet.' mod='qlogsitemap'}

      - {/if} - {include file="{$qgs_template_dir}hook/sitemap-cron-info.tpl"} - -
      diff --git a/modules/qlogsitemap/LICENSE.md b/modules/qlositemap/LICENSE.md similarity index 100% rename from modules/qlogsitemap/LICENSE.md rename to modules/qlositemap/LICENSE.md diff --git a/modules/qlogsitemap/classes/QgsHelper.php b/modules/qlositemap/classes/QsmHelper.php similarity index 94% rename from modules/qlogsitemap/classes/QgsHelper.php rename to modules/qlositemap/classes/QsmHelper.php index 3c131074b..11b93663f 100644 --- a/modules/qlogsitemap/classes/QgsHelper.php +++ b/modules/qlositemap/classes/QsmHelper.php @@ -24,34 +24,32 @@ /** * Queries for the pages added to the sitemap, and helpers for the sitemap files. */ -class QgsHelper +class QsmHelper { - const QGS_MAX_URLS_PER_FILE = 25000; - - const QGS_INDEX_FILE_NAME = 'sitemap.xml'; - - const QGS_DEFAULT_FREQUENCY = 'weekly'; + const QSM_MAX_URLS_PER_FILE = 25000; + const QSM_INDEX_FILE_NAME = 'sitemap.xml'; + const QSM_DEFAULT_FREQUENCY = 'weekly'; const TYPE_ROOM_TYPES = 'type-room-types'; const TYPE_PROPERTIES = 'type-properties'; const TYPE_STANDALONE = 'type-standalone'; const TYPE_CMS = 'type-cms'; + public static function getFrequencies() { return array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'); } public static function getFrequency() { - $frequency = Configuration::get('QLOGSITEMAP_FREQUENCY'); + $frequency = Configuration::get('QLOSITEMAP_FREQUENCY'); - return in_array($frequency, self::getFrequencies(), true) ? $frequency : self::QGS_DEFAULT_FREQUENCY; + return in_array($frequency, self::getFrequencies(), true) ? $frequency : self::QSM_DEFAULT_FREQUENCY; } public static function getDisabledPages() { - $pages = Configuration::get('QLOGSITEMAP_DISABLED_PAGES'); + $pages = Configuration::get('QLOSITEMAP_DISABLED_PAGES'); return $pages ? explode(',', $pages) : array(); } - public static function getModulePages() { $pages = array(); @@ -74,7 +72,6 @@ class QgsHelper return $pages; } - public static function getMetaIdByPage($page) { return (int) Db::getInstance()->getValue( @@ -112,7 +109,6 @@ class QgsHelper Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_STANDALONE, Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_ROOM_TYPE_AND_WITH_STANDALONE, ); - // Types that are also sold with hotels need at least one hotel linked to the product $withHotelTypes = array( Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_STANDALONE, Product::SELLING_PREFERENCE_WITH_HOTEL_AND_WITH_ROOM_TYPE_AND_WITH_STANDALONE, @@ -183,7 +179,7 @@ class QgsHelper foreach (self::getSitemapFiles() as $row) { @unlink(_PS_ROOT_DIR_.'/'.$row['link']); } - @unlink(_PS_ROOT_DIR_.'/'.self::QGS_INDEX_FILE_NAME); + @unlink(_PS_ROOT_DIR_.'/'.self::QSM_INDEX_FILE_NAME); } public static function createIndexFile() @@ -200,7 +196,7 @@ class QgsHelper } $xml .= ''.PHP_EOL; - return (bool) file_put_contents(_PS_ROOT_DIR_.'/'.self::QGS_INDEX_FILE_NAME, $xml); + return (bool) file_put_contents(_PS_ROOT_DIR_.'/'.self::QSM_INDEX_FILE_NAME, $xml); } public static function escapeXml($string) diff --git a/modules/qlogsitemap/classes/index.php b/modules/qlositemap/classes/index.php similarity index 100% rename from modules/qlogsitemap/classes/index.php rename to modules/qlositemap/classes/index.php diff --git a/modules/qlogsitemap/index.php b/modules/qlositemap/index.php similarity index 100% rename from modules/qlogsitemap/index.php rename to modules/qlositemap/index.php diff --git a/modules/qlogsitemap/logo.gif b/modules/qlositemap/logo.gif similarity index 100% rename from modules/qlogsitemap/logo.gif rename to modules/qlositemap/logo.gif diff --git a/modules/qlogsitemap/logo.png b/modules/qlositemap/logo.png similarity index 100% rename from modules/qlogsitemap/logo.png rename to modules/qlositemap/logo.png diff --git a/modules/qlogsitemap/qlogsitemap.php b/modules/qlositemap/qlositemap.php similarity index 70% rename from modules/qlogsitemap/qlogsitemap.php rename to modules/qlositemap/qlositemap.php index b0a4780e2..0ea76b1c6 100644 --- a/modules/qlogsitemap/qlogsitemap.php +++ b/modules/qlositemap/qlositemap.php @@ -25,18 +25,10 @@ if (!defined('_PS_VERSION_')) { exit; } -require_once dirname(__FILE__).'/classes/QgsHelper.php'; +require_once dirname(__FILE__).'/classes/QsmHelper.php'; -/** - * Generates XML sitemaps (one set per language) plus a sitemap index file. - */ -class Qlogsitemap extends Module +class Qlositemap extends Module { - /** - * Front pages listed before the categories and room types (page name => URL type). - * - * @var array - */ protected $pagesBefore = array( 'index' => 'home', 'our-properties' => 'meta', @@ -47,7 +39,6 @@ class Qlogsitemap extends Module 'authentication' => 'login', 'sitemap' => 'sitemapPage', ); - protected $priorities = array( 'home' => 1.0, 'meta' => 0.8, @@ -74,7 +65,7 @@ class Qlogsitemap extends Module public function __construct() { - $this->name = 'qlogsitemap'; + $this->name = 'qlositemap'; $this->tab = 'seo'; $this->version = '1.0.0'; $this->ps_versions_compliancy = array('min' => '1.6', 'max' => '1.6'); @@ -92,23 +83,18 @@ class Qlogsitemap extends Module public function install() { - if (!parent::install() - || !$this->registerHook('displayAdminMetaOptions') - || !$this->registerHook('registerCronTasks') - ) { - return false; - } - $this->sitemapPageMeta(); - return true; + return parent::install() + && $this->registerHook('displayAdminMetaOptions') + && $this->registerHook('registerCronTasks'); } public function uninstall() { - QgsHelper::deleteSitemapFiles(); + QsmHelper::deleteSitemapFiles(); - Configuration::deleteByName('QLOGSITEMAP_LAST_EXPORT'); - Configuration::deleteByName('QLOGSITEMAP_FREQUENCY'); - Configuration::deleteByName('QLOGSITEMAP_DISABLED_PAGES'); + Configuration::deleteByName('QLOSITEMAP_LAST_EXPORT'); + Configuration::deleteByName('QLOSITEMAP_FREQUENCY'); + Configuration::deleteByName('QLOSITEMAP_DISABLED_PAGES'); return parent::uninstall(); } @@ -135,13 +121,13 @@ class Qlogsitemap extends Module public function hookDisplayAdminMetaOptions() { if ($this->context->controller) { - if (Tools::isSubmit('submitQloGsitemap')) { + if (Tools::isSubmit('submitQloSitemap')) { if ($this->createSitemap()) { - Tools::redirectAdmin($this->context->link->getAdminLink('AdminMeta').'&qgsGenerated=1'); + Tools::redirectAdmin($this->context->link->getAdminLink('AdminMeta').'&qsmGenerated=1'); } elseif (!count($this->context->controller->errors)) { $this->context->controller->errors[] = $this->l('Unable to generate the sitemaps.'); } - } elseif (Tools::getValue('qgsGenerated')) { + } elseif (Tools::getValue('qsmGenerated')) { $this->context->controller->confirmations[] = $this->l('Your sitemaps were successfully created.'); } } @@ -150,13 +136,14 @@ class Qlogsitemap extends Module return $this->display(__FILE__, 'views/templates/hook/sitemap-panel.tpl'); } + public function getContent() { $output = ''; - if (Tools::isSubmit('submitQloGsitemap')) { + if (Tools::isSubmit('submitQloSitemap')) { $saved = true; - if (Tools::getIsset('QLOGSITEMAP_FREQUENCY')) { + if (Tools::getIsset('QLOSITEMAP_FREQUENCY')) { $configOutput = $this->postProcessConfig(); $saved = !strpos($configOutput, 'alert-danger'); $output .= $configOutput; @@ -166,9 +153,9 @@ class Qlogsitemap extends Module } elseif ($saved) { $output .= $this->displayError($this->l('Unable to generate the sitemaps.')); } - } elseif (Tools::isSubmit('submitQloGsitemapConfig')) { + } elseif (Tools::isSubmit('submitQloSitemapConfig')) { $output .= $this->postProcessConfig(); - } elseif (Tools::isSubmit('submitQloGsitemapCron')) { + } elseif (Tools::isSubmit('submitQloSitemapCron')) { $output .= $this->postProcessCron(); } @@ -180,23 +167,14 @@ class Qlogsitemap extends Module 'never' => $this->l('Never'), ); $frequencies = array(); - foreach (QgsHelper::getFrequencies() as $frequency) { + foreach (QsmHelper::getFrequencies() as $frequency) { $frequencies[$frequency] = $this->getFrequencyLabel($frequency); } - $disabledPages = QgsHelper::getDisabledPages(); + $disabledPages = QsmHelper::getDisabledPages(); $pages = array('core' => array(), 'module' => array()); $idLang = (int) $this->context->language->id; - foreach (array_keys($this->getExcludablePages()) as $page) { - $meta = Meta::getMetaByPage($page, $idLang); - $pages['core'][] = array( - 'page' => $page, - 'title' => !empty($meta['title']) ? $meta['title'] : $page, - 'show_key' => true, - 'excluded' => in_array($page, $disabledPages), - ); - } - foreach (QgsHelper::getModulePages() as $page) { + foreach (QsmHelper::getModulePages() as $page) { $meta = Meta::getMetaByPage($page, $idLang); $pages['module'][] = array( 'page' => $page, @@ -205,25 +183,55 @@ class Qlogsitemap extends Module 'excluded' => in_array($page, $disabledPages), ); } - foreach ($this->getExcludableTypes() as $type => $title) { - $pages['core'][] = array( - 'page' => $type, - 'title' => $title, - 'show_key' => false, - 'excluded' => in_array($type, $disabledPages), - ); - } + $pages['core'] = $this->getCoreExcludableItems($disabledPages, $idLang); $this->context->smarty->assign(array( - 'qgs_form_action' => AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'), - 'qgs_cron_options' => $cronLabels, - 'qgs_frequencies' => $frequencies, - 'qgs_frequency' => QgsHelper::getFrequency(), - 'qgs_pages' => $pages, + 'qsm_form_action' => AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'), + 'qsm_cron_options' => $cronLabels, + 'qsm_frequencies' => $frequencies, + 'qsm_frequency' => QsmHelper::getFrequency(), + 'qsm_pages' => $pages, )); return $output.$this->display(__FILE__, 'views/templates/admin/config.tpl'); } + protected function getCoreExcludableItems($disabledPages, $idLang) + { + $types = $this->getExcludableTypes(); + $pageKeys = $this->getExcludablePages(); + $order = array( + QsmHelper::TYPE_PROPERTIES, + QsmHelper::TYPE_ROOM_TYPES, + QsmHelper::TYPE_STANDALONE, + 'our-properties', + 'contact', + QsmHelper::TYPE_CMS, + 'authentication', + 'sitemap', + ); + + $items = array(); + foreach ($order as $key) { + if (isset($types[$key])) { + $items[] = array( + 'page' => $key, + 'title' => $types[$key], + 'show_key' => false, + 'excluded' => in_array($key, $disabledPages), + ); + } elseif (isset($pageKeys[$key])) { + $meta = Meta::getMetaByPage($key, $idLang); + $items[] = array( + 'page' => $key, + 'title' => !empty($meta['title']) ? $meta['title'] : $key, + 'show_key' => true, + 'excluded' => in_array($key, $disabledPages), + ); + } + } + + return $items; + } protected function getExcludablePages() { @@ -233,14 +241,14 @@ class Qlogsitemap extends Module protected function getExcludableTypes() { $types = array( - QgsHelper::TYPE_ROOM_TYPES => $this->l('Room types'), - QgsHelper::TYPE_PROPERTIES => $this->l('Properties'), + QsmHelper::TYPE_ROOM_TYPES => $this->l('Room types'), + QsmHelper::TYPE_PROPERTIES => $this->l('Room type listing'), ); - if (QgsHelper::getStandaloneProductIds((int) $this->context->shop->id)) { - $types[QgsHelper::TYPE_STANDALONE] = $this->l('Standalone products'); + if (QsmHelper::getStandaloneProductIds((int) $this->context->shop->id)) { + $types[QsmHelper::TYPE_STANDALONE] = $this->l('Standalone products'); } - if (QgsHelper::getCmsIds((int) $this->context->language->id, (int) $this->context->shop->id)) { - $types[QgsHelper::TYPE_CMS] = $this->l('CMS pages'); + if (QsmHelper::getCmsIds((int) $this->context->language->id, (int) $this->context->shop->id)) { + $types[QsmHelper::TYPE_CMS] = $this->l('CMS pages'); } return $types; @@ -248,39 +256,50 @@ class Qlogsitemap extends Module protected function postProcessConfig() { - $frequency = Tools::getValue('QLOGSITEMAP_FREQUENCY'); - if (!in_array($frequency, QgsHelper::getFrequencies(), true)) { + $frequency = Tools::getValue('QLOSITEMAP_FREQUENCY'); + if (!in_array($frequency, QsmHelper::getFrequencies(), true)) { return $this->displayError($this->l('Invalid update frequency.')); } - $knownPages = array_merge(array_keys($this->getExcludablePages()), array_keys($this->getExcludableTypes()), QgsHelper::getModulePages()); - $disabledPages = array_values(array_intersect($knownPages, (array) Tools::getValue('QLOGSITEMAP_DISABLED_PAGES', array()))); + $knownPages = array_merge(array_keys($this->getExcludablePages()), array_keys($this->getExcludableTypes()), QsmHelper::getModulePages()); + $disabledPages = array_values(array_intersect($knownPages, (array) Tools::getValue('QLOSITEMAP_DISABLED_PAGES', array()))); - Configuration::updateValue('QLOGSITEMAP_FREQUENCY', $frequency); - Configuration::updateValue('QLOGSITEMAP_DISABLED_PAGES', implode(',', $disabledPages)); + Configuration::updateValue('QLOSITEMAP_FREQUENCY', $frequency); + Configuration::updateValue('QLOSITEMAP_DISABLED_PAGES', implode(',', $disabledPages)); return $this->displayConfirmation($this->l('Settings updated successfully. Generate the sitemap to apply them.')); } protected function postProcessCron() { - $option = Tools::getValue('QLOGSITEMAP_CRON'); + $option = Tools::getValue('QLOSITEMAP_CRON'); if ($option !== 'never' && !isset($this->cronOptions[$option])) { return $this->displayError($this->l('Invalid cron schedule.')); } + if (!Module::isEnabled('qlocrontaskmanager')) { + return $this->displayError($this->l('The Cron Task Manager module is not enabled.')); + } + $cronTask = $this->getCronTask(); - if (!$cronTask) { - return $this->displayError($this->l('The sitemap cron task was not found in the Cron Task Manager.')); - } - if ($option === 'never') { - $cronTask->active = 0; - } else { - $cronTask->cron_expression = $this->cronOptions[$option]; - $cronTask->active = 1; + if ($cronTask && !$cronTask->delete()) { + return $this->displayError($this->l('Unable to update the cron task.')); + } + + return $this->displayConfirmation($this->l('Cron schedule updated successfully.')); } + if (!$cronTask) { + (new QctmCronTask())->registerTasksForModule((int) $this->id, $this->hookRegisterCronTasks()); + $cronTask = $this->getCronTask(); + } + if (!$cronTask) { + return $this->displayError($this->l('Unable to create the sitemap cron task in the Cron Task Manager.')); + } + + $cronTask->cron_expression = $this->cronOptions[$option]; + $cronTask->active = 1; if (!$cronTask->save()) { return $this->displayError($this->l('Unable to update the cron task.')); } @@ -306,16 +325,16 @@ class Qlogsitemap extends Module protected function assignSitemapPanelVars() { $this->context->smarty->assign(array( - 'qgs_template_dir' => _PS_MODULE_DIR_.$this->name.'/views/templates/', - 'qgs_config_link' => $this->context->link->getAdminLink('AdminModules').'&configure='.$this->name, - 'qgs_index_url' => $this->context->link->getBaseLink().QgsHelper::QGS_INDEX_FILE_NAME, - 'qgs_store_url' => $this->context->link->getBaseLink(), - 'qgs_sitemap_links' => QgsHelper::getSitemapFiles(), - 'qgs_last_export' => Configuration::get('QLOGSITEMAP_LAST_EXPORT'), - 'qgs_cron_manager_enabled' => Module::isEnabled('qlocrontaskmanager'), - 'qgs_cron_manager_installed' => Module::isInstalled('qlocrontaskmanager'), - 'qgs_cron_manager_link' => $this->getCronManagerLink(), - 'qgs_cron_task' => $this->getCronTaskSchedule(), + 'qsm_template_dir' => _PS_MODULE_DIR_.$this->name.'/views/templates/', + 'qsm_config_link' => $this->context->link->getAdminLink('AdminModules').'&configure='.$this->name, + 'qsm_index_url' => $this->context->link->getBaseLink().QsmHelper::QSM_INDEX_FILE_NAME, + 'qsm_store_url' => $this->context->link->getBaseLink(), + 'qsm_sitemap_links' => QsmHelper::getSitemapFiles(), + 'qsm_last_export' => Configuration::get('QLOSITEMAP_LAST_EXPORT'), + 'qsm_cron_manager_enabled' => Module::isEnabled('qlocrontaskmanager'), + 'qsm_cron_manager_installed' => Module::isInstalled('qlocrontaskmanager'), + 'qsm_cron_manager_link' => $this->getCronManagerLink(), + 'qsm_cron_task' => $this->getCronTaskSchedule(), )); } @@ -339,9 +358,18 @@ class Qlogsitemap extends Module protected function getCronTaskSchedule() { + if (!Module::isEnabled('qlocrontaskmanager')) { + return false; + } + $cronTask = $this->getCronTask(); if (!$cronTask) { - return false; + return array( + 'active' => false, + 'expression' => '', + 'readable' => '', + 'option' => 'never', + ); } $readable = $cronTask->cron_expression; @@ -389,39 +417,41 @@ class Qlogsitemap extends Module return false; } - QgsHelper::deleteSitemapFiles(); + QsmHelper::deleteSitemapFiles(); + $this->ensureSitemapPageMeta(); - $disabledPages = QgsHelper::getDisabledPages(); + $disabledPages = QsmHelper::getDisabledPages(); foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { $this->startSitemapSet($lang['iso_code']); $this->addPageUrls($lang, $this->pagesBefore); - if (!in_array(QgsHelper::TYPE_PROPERTIES, $disabledPages)) { + if (!in_array(QsmHelper::TYPE_PROPERTIES, $disabledPages)) { $this->addCategoryUrls($lang); } - if (!in_array(QgsHelper::TYPE_ROOM_TYPES, $disabledPages)) { + if (!in_array(QsmHelper::TYPE_ROOM_TYPES, $disabledPages)) { $this->addRoomTypeUrls($lang); } - if (!in_array(QgsHelper::TYPE_STANDALONE, $disabledPages)) { + if (!in_array(QsmHelper::TYPE_STANDALONE, $disabledPages)) { $this->addStandaloneProductUrls($lang); } - if (!in_array(QgsHelper::TYPE_CMS, $disabledPages)) { + if (!in_array(QsmHelper::TYPE_CMS, $disabledPages)) { $this->addCmsUrls($lang); } $this->addPageUrls($lang, $this->pagesAfter); - $this->addPageUrls($lang, array_fill_keys(array_diff(QgsHelper::getModulePages(), $disabledPages), 'modulePage')); + $this->addPageUrls($lang, array_fill_keys(array_diff(QsmHelper::getModulePages(), $disabledPages), 'modulePage')); $this->closeSitemapFile(); } - $result = QgsHelper::createIndexFile(); + $result = QsmHelper::createIndexFile(); if ($result) { - Configuration::updateValue('QLOGSITEMAP_LAST_EXPORT', date('Y-m-d H:i:s')); + Configuration::updateValue('QLOSITEMAP_LAST_EXPORT', date('Y-m-d H:i:s')); } return $result; } - protected function sitemapPageMeta() + + protected function ensureSitemapPageMeta() { - $idMeta = QgsHelper::getMetaIdByPage('sitemap'); + $idMeta = QsmHelper::getMetaIdByPage('sitemap'); $objMeta = new Meta($idMeta ?: null); if (!$idMeta) { $objMeta->page = 'sitemap'; @@ -481,7 +511,7 @@ class Qlogsitemap extends Module if (!$loc) { return false; } - if ($this->fileHandle && $this->fileUrlCount >= QgsHelper::QGS_MAX_URLS_PER_FILE) { + if ($this->fileHandle && $this->fileUrlCount >= QsmHelper::QSM_MAX_URLS_PER_FILE) { $this->closeSitemapFile(); } if (!$this->fileHandle && !$this->openSitemapFile()) { @@ -489,12 +519,12 @@ class Qlogsitemap extends Module } $priority = $this->priorities[$type]; - $frequency = QgsHelper::getFrequency(); - $xml = ''.PHP_EOL.''.QgsHelper::escapeXml($loc).''.PHP_EOL; + $frequency = QsmHelper::getFrequency(); + $xml = ''.PHP_EOL.''.QsmHelper::escapeXml($loc).''.PHP_EOL; if ($lastMod && strtotime($lastMod) > 0) { $xml .= ''.date('Y-m-d', strtotime($lastMod)).''.PHP_EOL; } - $xml .= ''.QgsHelper::escapeXml($frequency).''.PHP_EOL. + $xml .= ''.QsmHelper::escapeXml($frequency).''.PHP_EOL. ''.number_format($priority, 1, '.', '').''.PHP_EOL; $xml .= ''.PHP_EOL; @@ -506,7 +536,7 @@ class Qlogsitemap extends Module protected function addPageUrls($lang, array $pages) { - $disabledPages = QgsHelper::getDisabledPages(); + $disabledPages = QsmHelper::getDisabledPages(); foreach ($pages as $page => $type) { if ($page !== 'index' && in_array($page, $disabledPages)) { continue; @@ -520,7 +550,7 @@ class Qlogsitemap extends Module $idLang = (int) $lang['id_lang']; $idShop = (int) $this->context->shop->id; - foreach (QgsHelper::getRoomTypeIds($idShop) as $row) { + foreach (QsmHelper::getRoomTypeIds($idShop) as $row) { $product = new Product((int) $row['id_product'], false, $idLang); $this->addUrl( $this->context->link->getProductLink($product, $product->link_rewrite, null, null, $idLang, $idShop), @@ -535,9 +565,8 @@ class Qlogsitemap extends Module $idLang = (int) $lang['id_lang']; $idShop = (int) $this->context->shop->id; - foreach (QgsHelper::getStandaloneProductIds($idShop) as $row) { + foreach (QsmHelper::getStandaloneProductIds($idShop) as $row) { $product = new Product((int) $row['id_product'], false, $idLang); - // The product has no content in this language if (!$product->link_rewrite) { continue; } @@ -555,7 +584,7 @@ class Qlogsitemap extends Module $idLang = (int) $lang['id_lang']; $idShop = (int) $this->context->shop->id; - foreach (QgsHelper::getCategoryIds($idShop) as $row) { + foreach (QsmHelper::getCategoryIds($idShop) as $row) { $category = new Category((int) $row['id_category'], $idLang); $this->addUrl( $this->context->link->getCategoryLink($category, $category->link_rewrite, $idLang, null, $idShop), @@ -569,7 +598,7 @@ class Qlogsitemap extends Module $idLang = (int) $lang['id_lang']; $idShop = (int) $this->context->shop->id; - foreach (QgsHelper::getCmsIds($idLang, $idShop) as $row) { + foreach (QsmHelper::getCmsIds($idLang, $idShop) as $row) { $cms = new CMS((int) $row['id_cms'], $idLang); $this->addUrl($this->context->link->getCMSLink($cms, null, null, $idLang, $idShop), 'cms'); } diff --git a/modules/qlogsitemap/views/index.php b/modules/qlositemap/views/index.php similarity index 100% rename from modules/qlogsitemap/views/index.php rename to modules/qlositemap/views/index.php diff --git a/modules/qlositemap/views/templates/admin/config.tpl b/modules/qlositemap/views/templates/admin/config.tpl new file mode 100644 index 000000000..27da5b736 --- /dev/null +++ b/modules/qlositemap/views/templates/admin/config.tpl @@ -0,0 +1,162 @@ +{** +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License version 3.0 +* that is bundled with this package in the file LICENSE.md +* It is also available through the world-wide-web at this URL: +* https://opensource.org/license/osl-3-0-php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to support@qloapps.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to a newer +* versions in the future. If you wish to customize this module for your needs +* please refer to https://store.webkul.com/customisation-guidelines for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul +* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 +*} + +
      +
      {l s='Your sitemaps' mod='qlositemap'}
      + {if $qsm_sitemap_links} +

      {l s='Please set up the following sitemap URL in your Google Search Console account:' mod='qlositemap'}
      {$qsm_index_url|escape:'html':'UTF-8'}

      +

      {l s='A separate sitemap file is generated for each active language.' mod='qlositemap'}

      +

      {l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlositemap'}

      + +

      {l s='Your last update was made on this date:' mod='qlositemap'} {$qsm_last_export|escape:'html':'UTF-8'}

      + {else} +

      {l s='No sitemap has been generated yet.' mod='qlositemap'}

      + {/if} +
      + +
      +
      +
      {l s='Configure your sitemap' mod='qlositemap'}
      +
      + {l s='CMS pages:' mod='qlositemap'} + {l s='You can manage which CMS pages are included in the sitemap in two ways. If "CMS pages" is selected here, no CMS page is included in the sitemap. To leave out only specific CMS pages, set "Indexation by search engines" to No on the page itself (Preferences > CMS).' mod='qlositemap'} +
      +
      + +
      + +
      +
      +
      + +
      + {if $qsm_pages.core} +
      +
      + {foreach from=$qsm_pages.core item=page} +
      + +
      + {/foreach} +
      + {else} +

      {l s='No QloApps pages available.' mod='qlositemap'}

      + {/if} +
      +
      + {if $qsm_pages.module} +
      + +
      + {if $qsm_pages.module} +
      +
      + {foreach from=$qsm_pages.module item=page} +
      + +
      + {/foreach} +
      + {/if} +
      +
      + {/if} + +
      +
      + +
      +
      +
      {l s='Automatic sitemap generation' mod='qlositemap'}
      + {if $qsm_cron_task} +
      + +
      + +
      +
      + {/if} + {include file="{$qsm_template_dir}hook/sitemap-cron-info.tpl"} + +
      +
      + + + diff --git a/modules/qlogsitemap/views/templates/admin/index.php b/modules/qlositemap/views/templates/admin/index.php similarity index 100% rename from modules/qlogsitemap/views/templates/admin/index.php rename to modules/qlositemap/views/templates/admin/index.php diff --git a/modules/qlogsitemap/views/templates/hook/index.php b/modules/qlositemap/views/templates/hook/index.php similarity index 100% rename from modules/qlogsitemap/views/templates/hook/index.php rename to modules/qlositemap/views/templates/hook/index.php diff --git a/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl b/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl new file mode 100644 index 000000000..829734d55 --- /dev/null +++ b/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl @@ -0,0 +1,56 @@ +{** +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License version 3.0 +* that is bundled with this package in the file LICENSE.md +* It is also available through the world-wide-web at this URL: +* https://opensource.org/license/osl-3-0-php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to support@qloapps.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to a newer +* versions in the future. If you wish to customize this module for your needs +* please refer to https://store.webkul.com/customisation-guidelines for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul +* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 +*} + +
      +

      {l s='Sitemap generation' mod='qlositemap'}

      +
        + {if $qsm_cron_manager_enabled} + {if $qsm_cron_task && !$qsm_cron_task.active} +
      • {l s='Automatic:' mod='qlositemap'} {l s='automatic sitemap generation is turned off. To generate the sitemap automatically, choose Weekly, Monthly or Yearly in Sitemap generation schedule.' mod='qlositemap'}
      • + {elseif $qsm_cron_task} +
      • {l s='Automatic:' mod='qlositemap'} {l s='the sitemaps are regenerated automatically. Current schedule:' mod='qlositemap'} {$qsm_cron_task.readable|escape:'html':'UTF-8'}.
      • + {else} +
      • {l s='Automatic:' mod='qlositemap'} {l s='the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlositemap'} {l s='Cron Task Manager' mod='qlositemap'}.
      • + {/if} + {/if} +
      • {l s='Manual:' mod='qlositemap'} {l s='to generate the sitemap manually, click on the "Generate sitemap" button. This erases the old sitemap files and creates new ones.' mod='qlositemap'}
      • +
      +
      + {if !$qsm_cron_manager_enabled} +
      +
        +
      • + {if $qsm_cron_manager_installed} + {l s='Automatic:' mod='qlositemap'} {l s='the Cron Task Manager module is disabled, so the sitemaps are not regenerated automatically.' mod='qlositemap'} + {l s='Enable the module' mod='qlositemap'} + {l s='to turn on the automatic generation.' mod='qlositemap'} + {elseif $qsm_cron_manager_link} + {l s='Automatic:' mod='qlositemap'} {l s='the Cron Task Manager module is not installed, so the sitemaps are not regenerated automatically.' mod='qlositemap'} + {l s='Install the module' mod='qlositemap'} + {l s='to turn on the automatic generation.' mod='qlositemap'} + {else} + {l s='Automatic:' mod='qlositemap'} {l s='the Cron Task Manager module (qlocrontaskmanager) is not present, so the sitemaps are not regenerated automatically. Add the module to turn on the automatic generation.' mod='qlositemap'} + {/if} +
      • +
      +
      + {/if} diff --git a/modules/qlositemap/views/templates/hook/sitemap-panel.tpl b/modules/qlositemap/views/templates/hook/sitemap-panel.tpl new file mode 100644 index 000000000..3c20f3c09 --- /dev/null +++ b/modules/qlositemap/views/templates/hook/sitemap-panel.tpl @@ -0,0 +1,40 @@ +{** +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License version 3.0 +* that is bundled with this package in the file LICENSE.md +* It is also available through the world-wide-web at this URL: +* https://opensource.org/license/osl-3-0-php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to support@qloapps.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to a newer +* versions in the future. If you wish to customize this module for your needs +* please refer to https://store.webkul.com/customisation-guidelines for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul +* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 +*} + +
      +
      {l s='Sitemap generation' mod='qlositemap'}
      +
      +

      {l s='Submit the main sitemap URL in your search engine webmaster account (for example Google Search Console).' mod='qlositemap'}

      +

      {l s='The main sitemap lists one sitemap file for each active language.' mod='qlositemap'}

      +

      {l s='You can customize the sitemap configuration from here.' mod='qlositemap'} {l s='Configuration' mod='qlositemap'}

      +
      +

      {l s='Your sitemap' mod='qlositemap'}

      + {if $qsm_sitemap_links} +

      {$qsm_index_url|escape:'html':'UTF-8'}

      +

      {l s='Your last update was made on this date:' mod='qlositemap'} {$qsm_last_export|escape:'html':'UTF-8'}

      + {else} +

      {l s='No sitemap has been generated yet.' mod='qlositemap'}

      + {/if} + +
      diff --git a/modules/qlogsitemap/views/templates/index.php b/modules/qlositemap/views/templates/index.php similarity index 100% rename from modules/qlogsitemap/views/templates/index.php rename to modules/qlositemap/views/templates/index.php From 2194ab159bef9b390008d6a9a0877c5ccfbdde6f Mon Sep 17 00:00:00 2001 From: azhar bhat Date: Fri, 16 Oct 2026 18:39:48 +0530 Subject: [PATCH 8/8] text changes updated --- modules/qlositemap/qlositemap.php | 6 ++--- .../views/templates/admin/config.tpl | 8 ++++--- .../templates/hook/sitemap-cron-info.tpl | 24 ++++++++++++------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/modules/qlositemap/qlositemap.php b/modules/qlositemap/qlositemap.php index 0ea76b1c6..7b082f9dc 100644 --- a/modules/qlositemap/qlositemap.php +++ b/modules/qlositemap/qlositemap.php @@ -33,7 +33,6 @@ class Qlositemap extends Module 'index' => 'home', 'our-properties' => 'meta', ); - protected $pagesAfter = array( 'contact' => 'contact', 'authentication' => 'login', @@ -85,7 +84,8 @@ class Qlositemap extends Module { return parent::install() && $this->registerHook('displayAdminMetaOptions') - && $this->registerHook('registerCronTasks'); + && $this->registerHook('registerCronTasks') + && $this->ensureSitemapPageMeta(); } public function uninstall() @@ -191,6 +191,7 @@ class Qlositemap extends Module 'qsm_frequencies' => $frequencies, 'qsm_frequency' => QsmHelper::getFrequency(), 'qsm_pages' => $pages, + 'qsm_cms_link' => $this->context->link->getAdminLink('AdminCmsContent'), )); return $output.$this->display(__FILE__, 'views/templates/admin/config.tpl'); @@ -418,7 +419,6 @@ class Qlositemap extends Module } QsmHelper::deleteSitemapFiles(); - $this->ensureSitemapPageMeta(); $disabledPages = QsmHelper::getDisabledPages(); foreach (Language::getLanguages(true, (int) $this->context->shop->id) as $lang) { diff --git a/modules/qlositemap/views/templates/admin/config.tpl b/modules/qlositemap/views/templates/admin/config.tpl index 27da5b736..b7e3551aa 100644 --- a/modules/qlositemap/views/templates/admin/config.tpl +++ b/modules/qlositemap/views/templates/admin/config.tpl @@ -26,7 +26,7 @@

      {l s='Please set up the following sitemap URL in your Google Search Console account:' mod='qlositemap'}
      {$qsm_index_url|escape:'html':'UTF-8'}

      {l s='A separate sitemap file is generated for each active language.' mod='qlositemap'}

      {l s='The above URL is the master sitemap file. It refers to the following sub-sitemap files:' mod='qlositemap'}

      -
        +
          {foreach from=$qsm_sitemap_links item=sitemap_link}
        • {$sitemap_link.link|escape:'html':'UTF-8'}
        • {/foreach} @@ -41,8 +41,10 @@
          {l s='Configure your sitemap' mod='qlositemap'}
          - {l s='CMS pages:' mod='qlositemap'} - {l s='You can manage which CMS pages are included in the sitemap in two ways. If "CMS pages" is selected here, no CMS page is included in the sitemap. To leave out only specific CMS pages, set "Indexation by search engines" to No on the page itself (Preferences > CMS).' mod='qlositemap'} +

          {l s='CMS pages' mod='qlositemap'}

          +

          {l s='You can manage which CMS pages are included in the sitemap in two ways.' mod='qlositemap'}

          +

          {l s='If "CMS pages" is selected here, no CMS page is included in the sitemap.' mod='qlositemap'}

          +

          {l s='To leave out only specific CMS pages, set "Indexation by search engines" to No on the page itself' mod='qlositemap'} ({l s='Preferences > CMS' mod='qlositemap'}).

          diff --git a/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl b/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl index 829734d55..f0a9f41b1 100644 --- a/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl +++ b/modules/qlositemap/views/templates/hook/sitemap-cron-info.tpl @@ -21,18 +21,26 @@ *}
          -

          {l s='Sitemap generation' mod='qlositemap'}

          -
            - {if $qsm_cron_manager_enabled} + {if $qsm_cron_manager_enabled} +

            {l s='Automatic sitemap generation' mod='qlositemap'}

            +
              {if $qsm_cron_task && !$qsm_cron_task.active} -
            • {l s='Automatic:' mod='qlositemap'} {l s='automatic sitemap generation is turned off. To generate the sitemap automatically, choose Weekly, Monthly or Yearly in Sitemap generation schedule.' mod='qlositemap'}
            • +
            • {l s='Automatic sitemap generation is turned off.' mod='qlositemap'}
            • +
            • {l s='To turn it on, select Weekly, Monthly or Yearly from the Sitemap generation schedule.' mod='qlositemap'}
            • {elseif $qsm_cron_task} -
            • {l s='Automatic:' mod='qlositemap'} {l s='the sitemaps are regenerated automatically. Current schedule:' mod='qlositemap'} {$qsm_cron_task.readable|escape:'html':'UTF-8'}.
            • +
            • {l s='The sitemaps are regenerated automatically. Current schedule:' mod='qlositemap'} {$qsm_cron_task.readable|escape:'html':'UTF-8'}.
            • +
            • {l s='To change it, select another option from the Sitemap generation schedule.' mod='qlositemap'}
            • {else} -
            • {l s='Automatic:' mod='qlositemap'} {l s='the sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlositemap'} {l s='Cron Task Manager' mod='qlositemap'}.
            • +
            • {l s='The sitemaps are regenerated automatically. You can configure the schedule in the' mod='qlositemap'} {l s='Cron Task Manager' mod='qlositemap'}.
            • {/if} - {/if} -
            • {l s='Manual:' mod='qlositemap'} {l s='to generate the sitemap manually, click on the "Generate sitemap" button. This erases the old sitemap files and creates new ones.' mod='qlositemap'}
            • + {if $qsm_cron_task} +
            • {l s='Save the configuration. The old sitemap files will then be erased and new ones created automatically, based on the schedule.' mod='qlositemap'}
            • + {/if} +
            + {/if} +

            {l s='Manual sitemap generation' mod='qlositemap'}

            +
              +
            • {l s='To update the sitemap at any time, click the "Generate sitemap" button. This erases the old sitemap files and creates new ones.' mod='qlositemap'}
          {if !$qsm_cron_manager_enabled}