BlockLayoutDetectorTrait.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. <?php
  2. namespace App\Support\Traits;
  3. use DOMElement;
  4. /*
  5. * Трейт: обнаружение repeater-структуры в DOM.
  6. * Используется классом BlockLayoutParser.
  7. */
  8. trait BlockLayoutDetectorTrait
  9. {
  10. /** @return array{0:DOMElement,1:DOMElement[]}|null */
  11. private function detectRepeater(DOMElement $wrapper): ?array
  12. {
  13. $children = $this->elementChildren($wrapper);
  14. // Уровень 1: прямые дети обёртки одинаковы
  15. if (count($children) >= 2 && $this->allSimilar($children)) {
  16. return [$wrapper, $children];
  17. }
  18. // Уровень 2: единственный дочерний элемент содержит похожих детей
  19. if (count($children) === 1) {
  20. $grand = $this->elementChildren($children[0]);
  21. if (count($grand) >= 2 && $this->allSimilar($grand)) {
  22. return [$children[0], $grand];
  23. }
  24. }
  25. return null;
  26. }
  27. /** Все элементы имеют одинаковый тег и класс (считаем «похожими»). */
  28. private function allSimilar(array $els): bool
  29. {
  30. $tag = strtolower($els[0]->tagName);
  31. $class = $els[0]->getAttribute('class');
  32. foreach (array_slice($els, 1) as $el) {
  33. if (strtolower($el->tagName) !== $tag) return false;
  34. if ($el->getAttribute('class') !== $class) return false;
  35. }
  36. return true;
  37. }
  38. }