TemplatesTest.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. /**
  3. * Test layout declaration and usage of block elements
  4. *
  5. * Copyright © Magento, Inc. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Test\Integrity\Layout;
  9. use Magento\Framework\App\Utility\Files;
  10. class TemplatesTest extends \PHPUnit\Framework\TestCase
  11. {
  12. /**
  13. * @var array
  14. */
  15. protected static $templates = [];
  16. /**
  17. * @var array
  18. */
  19. protected static $blockVirtualTypes = [];
  20. /**
  21. * Collect declarations of containers per layout file that have aliases
  22. */
  23. public static function setUpBeforeClass()
  24. {
  25. $count = 0;
  26. self::getBlockVirtualTypesWithDifferentModule();
  27. foreach (Files::init()->getLayoutFiles([], false) as $file) {
  28. $xml = simplexml_load_file($file);
  29. $blocks = $xml->xpath('//block[@template]') ?: [];
  30. $fileTemplates = [];
  31. foreach ($blocks as $block) {
  32. $fileTemplates[] = ['class' => (string)$block['class'], 'file' => (string)$block['template']];
  33. }
  34. if (!empty($fileTemplates)) {
  35. self::$templates[$file] = $fileTemplates;
  36. $count += count($fileTemplates);
  37. }
  38. }
  39. }
  40. /**
  41. * Test that references to template files follows canonical format.
  42. *
  43. * path/to/template.phtml Format is prohibited.
  44. * @return void
  45. */
  46. public function testTemplateFollowsCanonicalName()
  47. {
  48. $errors = [];
  49. $warnings = [];
  50. foreach (self::$templates as $file => $templates) {
  51. foreach ($templates as $templatePair) {
  52. if (!preg_match('/[A-Za-z0-9]_[A-Za-z0-9]+\:\:[A-Za-z0-9\\_\-\.]+/', $templatePair['file'])) {
  53. if (!isset($errors[$file])) {
  54. $errors[$file] = [];
  55. }
  56. $errors[$file][] = $templatePair['file'];
  57. } else {
  58. if (isset(self::$blockVirtualTypes[$templatePair['class']])) {
  59. $warnings[$file][] = $templatePair;
  60. }
  61. }
  62. }
  63. }
  64. if (count($errors) > 0) {
  65. $message = 'Failed to assert that the template reference follows the canonical format '
  66. . 'Vendor' . '_' . 'Module::path/to/template.phtml. Following files haven\'t pass verification:'
  67. . PHP_EOL;
  68. foreach ($errors as $file => $wrongTemplates) {
  69. $message .= $file . ':' . PHP_EOL;
  70. $message .= '- ' . implode(PHP_EOL . '- ', $wrongTemplates) . PHP_EOL;
  71. }
  72. $this->fail($message);
  73. }
  74. }
  75. /**
  76. * Initialize array with the Virtual types for blocks
  77. *
  78. * Contains just those occurrences where base type and virtual type are located in different modules
  79. */
  80. private static function getBlockVirtualTypesWithDifferentModule()
  81. {
  82. $virtual = \Magento\Framework\App\Utility\Classes::getVirtualClasses();
  83. foreach ($virtual as $className => $resolvedName) {
  84. if (strpos($resolvedName, 'Block') !== false) {
  85. $matches = [];
  86. preg_match('/([A-Za-z0-9]+\\\\[A-Za-z0-9]+).*/', $className, $matches);
  87. if (count($matches) > 1) {
  88. $oldModule = $matches[1];
  89. } else {
  90. $oldModule = $className;
  91. }
  92. $matches = [];
  93. preg_match('/([A-Za-z0-9]+\\\\[A-Za-z0-9]+).*/', $resolvedName, $matches);
  94. $newModule = $matches[1];
  95. if ($oldModule != $newModule) {
  96. self::$blockVirtualTypes[$className] = $resolvedName;
  97. }
  98. }
  99. }
  100. }
  101. }