|
| 1 | +<?php |
| 2 | + |
| 3 | +/** |
| 4 | + * Copyright © Magento, Inc. All rights reserved. |
| 5 | + * See COPYING.txt for license details. |
| 6 | + */ |
| 7 | + |
| 8 | +namespace Magento2\Sniffs\Legacy; |
| 9 | + |
| 10 | +use DOMDocument; |
| 11 | +use PHP_CodeSniffer\Sniffs\Sniff; |
| 12 | +use PHP_CodeSniffer\Files\File; |
| 13 | + |
| 14 | +class ObsoleteConfigNodesSniff implements Sniff |
| 15 | +{ |
| 16 | + private const ERROR_MESSAGE_CONFIG = "Nodes identified by XPath '%s' are obsolete. %s"; |
| 17 | + private const ERROR_CODE_CONFIG = 'ObsoleteNodeInConfig'; |
| 18 | + |
| 19 | + /** |
| 20 | + * @inheritdoc |
| 21 | + */ |
| 22 | + public function register() |
| 23 | + { |
| 24 | + return [ |
| 25 | + T_INLINE_HTML, |
| 26 | + ]; |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * @inheritdoc |
| 31 | + */ |
| 32 | + public function process(File $phpcsFile, $stackPtr) |
| 33 | + { |
| 34 | + if ($stackPtr > 0) { |
| 35 | + return; |
| 36 | + } |
| 37 | + |
| 38 | + // We need to format the incoming XML to avoid tags split into several lines. In that case, PHP's DOMElement |
| 39 | + // returns the position of the closing /> as the position of the tag, and we need the position of < |
| 40 | + // instead, as it is the one we compare with $stackPtr later on. |
| 41 | + $xml = simplexml_load_string($this->getFormattedXML($phpcsFile)); |
| 42 | + if ($xml === false) { |
| 43 | + $phpcsFile->addError( |
| 44 | + sprintf( |
| 45 | + "Couldn't parse contents of '%s', check that they are in valid XML format", |
| 46 | + $phpcsFile->getFilename(), |
| 47 | + ), |
| 48 | + $stackPtr, |
| 49 | + self::ERROR_CODE_CONFIG |
| 50 | + ); |
| 51 | + } |
| 52 | + |
| 53 | + foreach ($this->getObsoleteNodes() as $xpath => $suggestion) { |
| 54 | + $matches = $xml->xpath($xpath); |
| 55 | + if (empty($matches)) { |
| 56 | + continue; |
| 57 | + } |
| 58 | + foreach ($matches as $match) { |
| 59 | + $phpcsFile->addError( |
| 60 | + sprintf( |
| 61 | + self::ERROR_MESSAGE_CONFIG, |
| 62 | + $xpath, |
| 63 | + $suggestion |
| 64 | + ), |
| 65 | + dom_import_simplexml($match)->getLineNo()-1, |
| 66 | + self::ERROR_CODE_CONFIG |
| 67 | + ); |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + /** |
| 73 | + * Format the incoming XML to avoid tags split into several lines. |
| 74 | + * |
| 75 | + * @param File $phpcsFile |
| 76 | + * @return false|string |
| 77 | + */ |
| 78 | + private function getFormattedXML(File $phpcsFile) |
| 79 | + { |
| 80 | + $doc = new DomDocument('1.0'); |
| 81 | + $doc->formatOutput = true; |
| 82 | + $doc->loadXML($phpcsFile->getTokensAsString(0, 999999)); |
| 83 | + return $doc->saveXML(); |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + * Get a list of obsolete nodes in the format <class_name> => <replacement> |
| 88 | + * |
| 89 | + * @return array |
| 90 | + */ |
| 91 | + private function getObsoleteNodes(): array |
| 92 | + { |
| 93 | + return [ |
| 94 | + '/config/global/fieldsets' => '', |
| 95 | + '/config/global/cache/betatypes' => '', |
| 96 | + '/config/admin/fieldsets' => '', |
| 97 | + '/config/general/locale' => |
| 98 | + 'This configuration moved to Di configuration of \Magento\Framework\Locale\ConfigInterface', |
| 99 | + '/config/global/can_use_base_url' => |
| 100 | + 'This configuration moved to Di configuration of \Magento\Backend\App\Action\Context class', |
| 101 | + '/config/global/locale/allow/codes' => |
| 102 | + 'This configuration moved to Di configuration of \Magento\Framework\Locale\ConfigInterface', |
| 103 | + '/config/global/locale/allow/currencies' => |
| 104 | + 'This configuration moved to Di configuration of \Magento\Framework\Locale\ConfigInterface', |
| 105 | + '/config/global/mime/types' => |
| 106 | + 'This configuration moved to Di configuration for \Magento\Downloadable\Helper\File class', |
| 107 | + '/config/global/models/*/deprecatedNode' => '', |
| 108 | + '/config/global/models/*/entities/*/table' => '', |
| 109 | + '/config/global/models/*/class' => '', |
| 110 | + '/config/global/helpers/*/class' => '', |
| 111 | + '/config/global/blocks/*/class' => '', |
| 112 | + '/config/global/models/*/resourceModel' => '', |
| 113 | + '/config/global/page/layouts' => 'Moved to page_layouts.xml', |
| 114 | + '/config/global/cms/layouts' => 'This was never used and is no longer supported', |
| 115 | + '/config/global/payment/cc/types/*/validator' => |
| 116 | + 'This configuration was moved to DI configuration of \Magento\Centinel\Model\StateFactory', |
| 117 | + '/config/global/payment' => 'Move them to payment.xml.', |
| 118 | + '/config/adminhtml/menu' => 'Move them to adminhtml.xml.', |
| 119 | + '/config/adminhtml/acl' => 'Move them to adminhtml.xml.', |
| 120 | + '/config/adminhtml/global_search' => |
| 121 | + 'This configuration moved to Di configuration of \Magento\Backend\Controller\Index', |
| 122 | + '/config/*[self::global|self::adminhtml|self::frontend]/di' => 'This configuration moved to di.xml file', |
| 123 | + '/config/*[self::global|self::adminhtml|self::frontend]/events' => |
| 124 | + 'This configuration moved to events.xml file', |
| 125 | + '/config/*[self::global|self::adminhtml|self::frontend]/routers' => |
| 126 | + 'Routes configuration moved to routes.xml file,' . |
| 127 | + 'routers list can be set through Di configuration of \Magento\Framework\App\RouterList model', |
| 128 | + '/config/global/importexport' => 'This configuration moved to import.xml and export.xml files', |
| 129 | + '/config/global/catalog/product/type' => 'This configuration moved to product_types.xml file', |
| 130 | + '/config/global/catalog/product/options' => 'This configuration moved to product_options.xml file', |
| 131 | + '/config/global/catalog/product/media/image_types' => 'This configuration moved to Di configuration of ' . |
| 132 | + '\Magento\Backend\Block\Catalog\Product\Frontend\Product\Watermark', |
| 133 | + '/config/global/eav_attributes' => 'This configuration moved to eav_attributes.xml file', |
| 134 | + '/config/global/index' => 'This configuration moved to indexers.xml file', |
| 135 | + '/config/global/catalogrule' => |
| 136 | + 'This configuration moved to Di configuration of \Magento\CatalogRule\Model\Rule', |
| 137 | + '/config/global/salesrule' => |
| 138 | + 'This configuration moved to Di configuration of \Magento\SalesRule\Helper\Coupon', |
| 139 | + '/config/global/session' => |
| 140 | + 'This configuration moved to Di configuration of \Magento\Framework\Session\Validator', |
| 141 | + '/config/global/ignore_user_agents' => |
| 142 | + 'This configuration moved to Di configuration of \Magento\Log\Model\Visitor', |
| 143 | + '/config/global/request' => |
| 144 | + 'This configuration moved to Di configuration of \Magento\Framework\App\RequestInterface', |
| 145 | + '/config/global/secure_url' => |
| 146 | + 'This configuration moved to Di configuration of \Magento\Framework\Url\SecurityInfo', |
| 147 | + '/config/global/dev' => |
| 148 | + 'This configuration moved to Di configuration of \Magento\Framework\App\Action\Context', |
| 149 | + '/config/global/webapi' => |
| 150 | + 'This configuration moved to Di configuration of '. |
| 151 | + ' \Magento\Webapi\Controller\Request\Rest\Interpreter\Factory' . |
| 152 | + ' and \Magento\Webapi\Controller\Response\Rest\Renderer\Factory', |
| 153 | + '/config/global/cms' => |
| 154 | + 'This configuration moved to Di configuration of \Magento\Cms\Model\Wysiwyg\Images\Storage' . |
| 155 | + ' and \Magento\Cms\Model\Wysiwyg\Config', |
| 156 | + '/config/global/widget' => |
| 157 | + 'This configuration moved to Di configuration of \Magento\Cms\Model\Template\FilterProvider', |
| 158 | + '/config/global/catalog/product/flat/max_index_count' => |
| 159 | + 'This configuration moved to Di configuration of '. |
| 160 | + '\Magento\Catalog\Model\ResourceModel\Product\Flat\Indexer', |
| 161 | + '/config/global/catalog/product/flat/attribute_groups' => |
| 162 | + 'This configuration moved to Di configuration of '. |
| 163 | + '\Magento\Catalog\Model\ResourceModel\Product\Flat\Indexer', |
| 164 | + '/config/global/catalog/product/flat/add_filterable_attributes' => |
| 165 | + 'This configuration moved to Di configuration of \Magento\Catalog\Helper\Product\Flat\Indexer', |
| 166 | + '/config/global/catalog/product/flat/add_child_data' => |
| 167 | + 'This configuration moved to Di configuration of \Magento\Catalog\Helper\Product\Flat\Indexer', |
| 168 | + '/config/global/catalog/content/template_filter' => |
| 169 | + 'This configuration moved to Di configuration of \Magento\Catalog\Helper\Data', |
| 170 | + '/config/frontend/catalog/per_page_values/list' => |
| 171 | + 'This configuration moved to Di configuration of \Magento\Catalog\Model\Config\Source\ListPerPage', |
| 172 | + '/config/frontend/catalog/per_page_values/grid' => |
| 173 | + 'This configuration moved to Di configuration of \Magento\Catalog\Model\Config\Source\GridPerPage', |
| 174 | + '/config/global/catalog/product/design' => 'This configuration moved to Di configuration of' . |
| 175 | + ' \Magento\Catalog\Model\Entity\Product\Attribute\Design\Option\Container', |
| 176 | + '/config/global/catalog/product/attributes' => 'This configuration moved catalog_attributes.xml', |
| 177 | + '/config/global/eav_frontendclasses' => 'This configuration was removed. ' . |
| 178 | + 'Please pluginize \Magento\Eav\Helper\Data::getFrontendClasses to extend frontend classes list', |
| 179 | + '/config/global/resources' => |
| 180 | + 'This configuration moved to Di configuration of \Magento\Framework\App\ResourceConnection', |
| 181 | + '/config/global/resource' => |
| 182 | + 'This configuration moved to Di configuration of \Magento\Framework\App\ResourceConnection', |
| 183 | + '/config/*/events/core_block_abstract_to_html_after' => |
| 184 | + 'Event has been replaced with "core_layout_render_element"', |
| 185 | + '/config/*/events/catalog_controller_product_delete' => '', |
| 186 | + '/config//observers/*/args' => 'This was an undocumented and unused feature in event subscribers', |
| 187 | + '/config/default/design/theme' => 'Relocated to /config/<area>/design/theme', |
| 188 | + '/config/global/theme' => 'Configuration moved to DI file settings', |
| 189 | + '/config/default/web/*/base_js_url' => '', |
| 190 | + '/config/default/web/*/base_skin_url' => '/config/default/web/*/base_static_url', |
| 191 | + '/config/default/web/*/base_cache_url' => '/config/default/web/*/base_static_url', |
| 192 | + '/config/global/cache/types/*/tags' => 'use /config/global/cache/types/*/class node instead', |
| 193 | + '/config/global/disable_local_modules' => '', |
| 194 | + '/config/global/newsletter/tempate_filter' => 'Use DI configs to setup model for template processing', |
| 195 | + '/config/*/layout' => 'Use convention for layout files placement instead of configuration', |
| 196 | + '/config/frontend/product/collection/attributes' => |
| 197 | + 'Use /config/group[@name="catalog_product"] of catalog_attributes.xml', |
| 198 | + '/config/frontend/category/collection/attributes' => |
| 199 | + 'Use /config/group[@name="catalog_category"] of catalog_attributes.xml', |
| 200 | + '/config/global/sales/quote/item/product_attributes' => |
| 201 | + 'Use /config/group[@name="quote_item"] of catalog_attributes.xml', |
| 202 | + '/config/global/wishlist/item/product_attributes' => |
| 203 | + 'Use /config/group[@name="wishlist_item"] of catalog_attributes.xml', |
| 204 | + '/config/global/catalog/product/flat/attribute_nodes' => |
| 205 | + 'Use /config/global/catalog/product/flat/attribute_groups', |
| 206 | + '/config/global/customer/address/formats' => 'Use /config/format of address_formats.xml', |
| 207 | + '/config/global/pdf' => 'Use configuration in pdf.xml', |
| 208 | + '/config/install' => 'Configurations moved to DI file settings', |
| 209 | + '/config/install/design' => 'Configurations moved to DI file settings', |
| 210 | + '/config/adminhtml/design' => 'Configurations moved to DI file settings', |
| 211 | + '/config/frontend/design' => 'Configurations moved to DI file settings', |
| 212 | + '/config/crontab' => 'All cron configurations moved to crontab.xml', |
| 213 | + '/config/global/areas' => 'Configurations moved to DI file settings', |
| 214 | + '/config/vde' => 'Was moved to di', |
| 215 | + '/config/global/ignoredModules' => 'Was replaced using di', |
| 216 | + '/config/global/helpers' => 'Was replaced using di', |
| 217 | + '/config/global/external_cache' => 'Was replaced using di', |
| 218 | + '/config/global/currency/import/services' => 'Configurations moved to DI file settings', |
| 219 | + '/config/global/template' => 'Use /config/template of email_templates.xml', |
| 220 | + '/config/default/general/file/sitemap_generate_valid_paths' => '/config/default/sitemap/file/valid_paths', |
| 221 | + '/config/dev/css/minify_adapter' => 'Was replaced using di', |
| 222 | + '/config/dev/js/minify_adapter' => 'Was replaced using di', |
| 223 | + '/config/global/full_page_cache' => '/config/global/cache_advanced/full_page', |
| 224 | + '/config/adminhtml/enterprise/admingws' => 'This configuration moved to admingws.xml file', |
| 225 | + '/config/adminhtml/enterprise/websiterestriction' => |
| 226 | + 'This configuration moved to websiterestrictions.xml file', |
| 227 | + '/config/global/enterprise_cms' => 'This configuration moved to menu_hierarchy.xml file', |
| 228 | + '/config/global/enterprise/banner' => |
| 229 | + 'This configuration moved to Di configuration of \Magento\Banner\Model\Config', |
| 230 | + '/config/global/enterprise/giftcardaccount' => |
| 231 | + 'This configuration moved to Di configuration of \Magento\GiftCardAccountModelPool', |
| 232 | + '/config/global/skip_process_modules_updates' => 'Was replaced using di', |
| 233 | + '/config/system/page_cache' => 'Module is eliminated. Use PageCache module instead', |
| 234 | + '/config/system/cms/content/versioning' => 'Functionality is eliminated', |
| 235 | + ]; |
| 236 | + } |
| 237 | +} |
0 commit comments