Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
theme.php
1<?php
3
4use \Bitrix\Landing\Block;
5use \Bitrix\Landing\Site;
6use \Bitrix\Landing\Manager;
7
8class Theme
9{
13 const FILE_PATH_SITE_MANIFEST = '/bitrix/components/bitrix/landing.demo/data/site/#code#/.theme.php';
14
18 const DEFAULT_PAGE_TEMPLATE = 'empty';
19
25 private static function getStyleClasses(string $content): array
26 {
27 if (preg_match_all('/class="([^"]+)"/', $content, $matches))
28 {
29 $allClasses = [];
30 foreach ($matches[1] as $classes)
31 {
32 // some hack for future search optimization
33 $allClasses[] = ' ' . $classes . ' ';
34 }
35 return $allClasses;
36 }
37 return [];
38 }
39
45 private static function getThemeManifest(string $tplCode): array
46 {
48 $path = Manager::getDocRoot() . str_replace('#code#', $tplCode, $path);
49 if (file_exists($path))
50 {
51 $manifest = include $path;
52 if (is_array($manifest))
53 {
54 return $manifest;
55 }
56 }
57 return [];
58 }
59
67 private static function removeSiblingsClasses(string $classString, array $targetClasses, string $namespace): string
68 {
69 static $classesGroups = [];
70
71 $styleManifest = Block::getStyle();
72
73 // build classes groups (static cache)
74 if (!array_key_exists($namespace, $classesGroups))
75 {
76 $classesGroups[$namespace] = [];
77 if (
78 isset($styleManifest[$namespace]['style']) &&
79 is_array($styleManifest[$namespace]['style'])
80 )
81 {
82 foreach ($styleManifest[$namespace]['style'] as $style)
83 {
84 if (isset($style['items']) && is_array($style['items']))
85 {
86 $classesGroup = [];
87 foreach ($style['items'] as $item)
88 {
89 if (isset($item['value']) && is_string($item['value']))
90 {
91 $classesGroup[] = trim($item['value']);
92 }
93 }
94 if ($classesGroup)
95 {
96 $classesGroups[$namespace][] = $classesGroup;
97 }
98 }
99 }
100 }
101 }
102
103 $allClasses = $classesGroups[$namespace];
104
105 // local function to find siblings
106 $findSiblings = function($targetClass) use($allClasses)
107 {
108 $targetClass = trim($targetClass);
109 foreach ($allClasses as $classes)
110 {
111 if (in_array($targetClass, $classes))
112 {
113 return $classes;
114 }
115 }
116
117 return [];
118 };
119
120 // try to find siblings of each target class
121 foreach ($targetClasses as $targetClass)
122 {
123 // and remove from class attribute
124 foreach ($findSiblings($targetClass) as $classRemove)
125 {
126 $classString = str_replace(' ' . $classRemove . ' ', ' ', $classString);
127 }
128 }
129
130
131 return trim($classString);
132 }
133
139 public static function processing(Block $block): void
140 {
141 // first we check all we need
142
143 $blockMetadata = $block->getMeta();
144 if (!$blockMetadata['SITE_TPL_CODE'])
145 {
146 return;
147 }
148
149 $themeManifest = self::getThemeManifest($blockMetadata['SITE_TPL_CODE']);
150 if (
151 isset($themeManifest['newBlockStyle']) &&
152 is_array($themeManifest['newBlockStyle'])
153 )
154 {
155 $themeManifest = $themeManifest['newBlockStyle'];
156 }
157 else
158 {
159 return;
160 }
161
162 $contentWasChanged = false;
163 $blockContent = $block->getContent();
164 $blockClasses = self::getStyleClasses($blockContent);
165 if (!$blockClasses)
166 {
167 return;
168 }
169
170 $blockManifest = $block->getManifest();
171 if (!isset($blockManifest['namespace']))
172 {
173 return;
174 }
175
176 $blockNamespace = $blockManifest['namespace'];
177 $semanticManifest = Block::getSemantic();
178 if (isset($semanticManifest[$blockNamespace]))
179 {
180 $semanticManifest = $semanticManifest[$blockNamespace];
181 }
182 else
183 {
184 return;
185 }
186
187 // work with theme manifest
188 foreach ($themeManifest as $semanticCode => $needClasses)
189 {
190 if (!isset($semanticManifest[$semanticCode]))
191 {
192 continue;
193 }
194 if (!is_array($needClasses))
195 {
196 $needClasses = (array)$needClasses;
197 }
198
199 // by specific style class we redefine some classes
200 foreach ((array) $semanticManifest[$semanticCode] as $semanticClass)
201 {
202 $semanticClass = ' ' . $semanticClass . ' ';
203 foreach ($blockClasses as $classesString)
204 {
205 if (mb_strpos($classesString, $semanticClass) !== false)
206 {
207 $contentWasChanged = true;
208 $newClassString = self::removeSiblingsClasses(
209 $classesString,
210 $needClasses,
211 $blockNamespace
212 );
213 $blockContent = str_replace(
214 'class="' . trim($classesString) . '"',
215 'class="' . $newClassString . ' ' . implode(' ', $needClasses) . '"',
216 $blockContent
217 );
218 }
219 }
220 }
221 }
222
223 // save content to the block
224 if ($contentWasChanged)
225 {
226 $block->saveContent($blockContent);
227 }
228 }
229
235 public static function getNewPageTemplate(int $siteId): string
236 {
237 static $sites = [];
238
239 if (!array_key_exists($siteId, $sites))
240 {
241 $sites[$siteId] = null;
242 $res = Site::getList([
243 'select' => [
244 'XML_ID', 'TPL_CODE'
245 ],
246 'filter' => [
247 'ID' => $siteId
248 ]
249 ]);
250 if ($row = $res->fetch())
251 {
252 if (!$row['TPL_CODE'] && mb_strpos($row['XML_ID'], '|'))
253 {
254 [, $row['TPL_CODE']] = explode('|', $row['XML_ID']);
255 }
256 if ($row['TPL_CODE'])
257 {
258 $manifest = self::getThemeManifest($row['TPL_CODE']);
259 if (
260 isset($manifest['newPageTemplate'][0]) &&
261 is_string($manifest['newPageTemplate'][0])
262 )
263 {
264 $sites[$siteId] = $manifest['newPageTemplate'][0];
265 }
266 }
267 }
268 }
269
270 if ($sites[$siteId])
271 {
272 return $sites[$siteId];
273 }
274
276 }
277}
static getNewPageTemplate(int $siteId)
Definition theme.php:235
getManifest($extended=false, $missCache=false, array $params=array())
Definition block.php:2117
saveContent(string $content, $designed=false)
Definition block.php:3108