GroupedCollection.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Asset;
  7. /**
  8. * List of page assets that combines into groups ones having the same properties
  9. *
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class GroupedCollection extends Collection
  14. {
  15. /**#@+
  16. * Special properties, enforced to be grouped by
  17. */
  18. const PROPERTY_CONTENT_TYPE = 'content_type';
  19. const PROPERTY_CAN_MERGE = 'can_merge';
  20. /**#@-*/
  21. /**#@-*/
  22. protected $propertyFactory;
  23. /**
  24. * Property Groups
  25. *
  26. * @var PropertyGroup[]
  27. */
  28. protected $groups = [];
  29. /**
  30. * Constructor
  31. *
  32. * @param PropertyGroupFactory $propertyFactory
  33. */
  34. public function __construct(PropertyGroupFactory $propertyFactory)
  35. {
  36. $this->propertyFactory = $propertyFactory;
  37. }
  38. /**
  39. * Add an instance, identified by a unique identifier, to the list and to the corresponding group
  40. *
  41. * @param string $identifier
  42. * @param AssetInterface $asset
  43. * @param array $properties
  44. * @return void
  45. */
  46. public function add($identifier, AssetInterface $asset, array $properties = [])
  47. {
  48. parent::add($identifier, $asset);
  49. $properties = $this->getFilteredProperties($asset, $properties);
  50. $this->getGroupFor($properties)->add($identifier, $asset);
  51. }
  52. /**
  53. * @param string $identifier
  54. * @param AssetInterface $asset
  55. * @param string $key
  56. * @return void
  57. */
  58. public function insert($identifier, AssetInterface $asset, $key)
  59. {
  60. parent::insert($identifier, $asset, $key);
  61. $properties = $this->getFilteredProperties($asset);
  62. $this->getGroupFor($properties)->insert($identifier, $asset, $key);
  63. }
  64. /**
  65. * @param AssetInterface $asset
  66. * @param array $properties
  67. * @return array
  68. */
  69. public function getFilteredProperties(AssetInterface $asset, $properties = [])
  70. {
  71. $properties = array_filter($properties);
  72. $properties[self::PROPERTY_CONTENT_TYPE] = $asset->getContentType();
  73. $properties[self::PROPERTY_CAN_MERGE] = $asset instanceof MergeableInterface;
  74. return $properties;
  75. }
  76. /**
  77. * Retrieve existing or new group matching the properties
  78. *
  79. * @param array $properties
  80. * @return PropertyGroup
  81. */
  82. private function getGroupFor(array $properties)
  83. {
  84. /** @var $existingGroup PropertyGroup */
  85. foreach ($this->groups as $existingGroup) {
  86. if ($existingGroup->getProperties() == $properties) {
  87. return $existingGroup;
  88. }
  89. }
  90. /** @var $newGroup PropertyGroup */
  91. $newGroup = $this->propertyFactory->create(['properties' => $properties]);
  92. $this->groups[] = $newGroup;
  93. return $newGroup;
  94. }
  95. /**
  96. * Remove an instance from the list and from the corresponding group
  97. *
  98. * @param string $identifier
  99. * @return void
  100. */
  101. public function remove($identifier)
  102. {
  103. parent::remove($identifier);
  104. /** @var PropertyGroup $group */
  105. foreach ($this->groups as $group) {
  106. if ($group->has($identifier)) {
  107. $group->remove($identifier);
  108. return;
  109. }
  110. }
  111. }
  112. /**
  113. * Retrieve groups, containing assets that have the same properties
  114. *
  115. * @return PropertyGroup[]
  116. */
  117. public function getGroups()
  118. {
  119. return $this->groups;
  120. }
  121. /**
  122. * Get asset group by content type
  123. *
  124. * @param string $contentType
  125. * @return bool|PropertyGroup
  126. */
  127. public function getGroupByContentType($contentType)
  128. {
  129. foreach ($this->groups as $group) {
  130. if ($group->getProperty(self::PROPERTY_CONTENT_TYPE) == $contentType) {
  131. return $group;
  132. }
  133. }
  134. return false;
  135. }
  136. }