Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ThemeList.php
Go to the documentation of this file.
1 <?php
7 
10 
15 {
19  const CONSTRAINT_AREA = 'area';
20 
26  const CONSTRAINT_VENDOR = 'vendor';
27 
33  const CONSTRAINT_THEME_NAME = 'theme_name';
34 
40  protected $_itemObjectClass = ThemeInterface::class;
41 
46 
52  private $constraints = [
53  self::CONSTRAINT_AREA => [],
54  self::CONSTRAINT_VENDOR => [],
55  self::CONSTRAINT_THEME_NAME => [],
56  ];
57 
63  private $themePackageList;
64 
70  private $dirReadFactory;
71 
80  public function __construct(
81  \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
83  ThemePackageList $themePackageList,
84  ReadFactory $dirReadFactory
85  ) {
86  parent::__construct($entityFactory);
87  $this->themeConfigFactory = $themeConfigFactory;
88  $this->themePackageList = $themePackageList;
89  $this->dirReadFactory = $dirReadFactory;
90  }
91 
101  public function addConstraint($type, $value)
102  {
103  if (!isset($this->constraints[$type])) {
104  throw new \UnexpectedValueException("Constraint '$type' is not supported");
105  }
106  if ($this->isLoaded()) {
107  $this->clear();
108  }
109  $this->constraints[$type][] = $value;
110  $this->constraints[$type] = array_unique($this->constraints[$type]);
111  }
112 
118  public function resetConstraints()
119  {
120  foreach (array_keys($this->constraints) as $key) {
121  $this->constraints[$key] = [];
122  }
123  }
124 
132  private function isAcceptable($constraintType, $value)
133  {
134  return empty($this->constraints[$constraintType]) || in_array($value, $this->constraints[$constraintType]);
135  }
136 
145  public function loadData($printQuery = false, $logQuery = false)
146  {
147  if ($this->isLoaded()) {
148  return $this;
149  }
150 
151  $themes = [];
152  foreach ($this->themePackageList->getThemes() as $themePackage) {
153  if ($this->isAcceptable(self::CONSTRAINT_AREA, $themePackage->getArea())
154  && $this->isAcceptable(self::CONSTRAINT_VENDOR, $themePackage->getVendor())
155  && $this->isAcceptable(self::CONSTRAINT_THEME_NAME, $themePackage->getName())
156  ) {
157  $themes[] = $themePackage;
158  }
159  }
160 
161  $this->_loadFromFilesystem($themes);
162  $this->resetConstraints();
163  $this->_updateRelations()
164  ->_renderFilters()
165  ->_clearFilters();
166 
167  return $this;
168  }
169 
175  protected function _updateRelations()
176  {
177  $themeItems = $this->getItems();
179  foreach ($themeItems as $theme) {
180  $parentThemePath = $theme->getData('parent_theme_path');
181  if ($parentThemePath) {
182  $themePath = $theme->getArea() . ThemeInterface::PATH_SEPARATOR . $parentThemePath;
183  if (isset($themeItems[$themePath])) {
184  $theme->setParentTheme($themeItems[$themePath]);
185  }
186  }
187  }
188  return $this;
189  }
190 
197  protected function _loadFromFilesystem(array $themes)
198  {
199  foreach ($themes as $themePackage) {
200  $theme = $this->getNewEmptyItem()->addData($this->_prepareConfigurationData($themePackage));
201  $this->addItem($theme);
202  }
203  $this->_setIsLoaded();
204 
205  return $this;
206  }
207 
214  protected function _preparePathData($themePackage)
215  {
216  return [
217  'theme_path_pieces' => [
218  $themePackage->getVendor(),
219  $themePackage->getName(),
220  ]
221  ];
222  }
223 
230  protected function _prepareConfigurationData($themePackage)
231  {
232  $themeConfig = $this->_getConfigModel($themePackage);
233  $pathData = $this->_preparePathData($themePackage);
234  $media = $themeConfig->getMedia();
235 
236  $parentPathPieces = $themeConfig->getParentTheme();
237  if (is_array($parentPathPieces) && count($parentPathPieces) == 1) {
238  $pathPieces = $pathData['theme_path_pieces'];
239  array_pop($pathPieces);
240  $parentPathPieces = array_merge($pathPieces, $parentPathPieces);
241  }
242 
243  $themePath = implode(ThemeInterface::PATH_SEPARATOR, $pathData['theme_path_pieces']);
244  $themeCode = implode(ThemeInterface::CODE_SEPARATOR, $pathData['theme_path_pieces']);
245  $parentPath = $parentPathPieces ? implode(ThemeInterface::PATH_SEPARATOR, $parentPathPieces) : null;
246 
247  return [
248  'parent_id' => null,
250  'area' => $themePackage->getArea(),
251  'theme_path' => $themePath,
252  'code' => $themeCode,
253  'theme_title' => $themeConfig->getThemeTitle(),
254  'preview_image' => $media['preview_image'] ? $media['preview_image'] : null,
255  'parent_theme_path' => $parentPath
256  ];
257  }
258 
264  protected function _renderFilters()
265  {
266  $filters = $this->getFilter([]);
268  foreach ($this->getItems() as $itemKey => $theme) {
269  $removeItem = false;
270  foreach ($filters as $filter) {
271  if ($filter['type'] == 'and' && $theme->getDataUsingMethod($filter['field']) != $filter['value']) {
272  $removeItem = true;
273  }
274  }
275  if ($removeItem) {
276  $this->removeItemByKey($itemKey);
277  }
278  }
279  return $this;
280  }
281 
287  protected function _clearFilters()
288  {
289  $this->_filters = [];
290  return $this;
291  }
292 
299  protected function _getConfigModel($themePackage)
300  {
301  $themeDir = $this->dirReadFactory->create($themePackage->getPath());
302  if ($themeDir->isExist('theme.xml')) {
303  $configContent = $themeDir->readFile('theme.xml');
304  } else {
305  $configContent = '';
306  }
307  return $this->themeConfigFactory->create(['configContent' => $configContent]);
308  }
309 
316  protected function _getItemId(\Magento\Framework\DataObject $item)
317  {
318  return $item->getFullPath();
319  }
320 
327  public function toOptionArray($addEmptyField = false)
328  {
329  $optionArray = $addEmptyField ? ['' => ''] : [];
330  return $optionArray + $this->_toOptionArray('theme_id', 'theme_title');
331  }
332 
339  public function hasTheme(ThemeInterface $theme)
340  {
341  $themeItems = $this->getItems();
342  return $theme->getThemePath() && isset($themeItems[$theme->getFullPath()]);
343  }
344 
351  public function getThemeByFullPath($fullPath)
352  {
353  list($area, $themePath) = explode('/', $fullPath, 2);
354  $this->addConstraint(self::CONSTRAINT_AREA, $area);
355  $this->addFilter('theme_path', $themePath);
356 
357  return $this->getFirstItem();
358  }
359 }
_getItemId(\Magento\Framework\DataObject $item)
Definition: ThemeList.php:316
addFilter($field, $value, $type='and')
Definition: Collection.php:118
$type
Definition: item.phtml:13
$themePackageList
Definition: bootstrap.php:88
_toOptionArray($valueField='id', $labelField='name', $additional=[])
Definition: Collection.php:760
$value
Definition: gender.phtml:16
$theme
$filters
Definition: uploader.phtml:11
__construct(\Magento\Framework\Data\Collection\EntityFactory $entityFactory, \Magento\Framework\Config\ThemeFactory $themeConfigFactory, ThemePackageList $themePackageList, ReadFactory $dirReadFactory)
Definition: ThemeList.php:80
loadData($printQuery=false, $logQuery=false)
Definition: ThemeList.php:145
addItem(\Magento\Framework\DataObject $item)
Definition: Collection.php:399