Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
exporttree.php
1<?php
10
11use Bitrix\Main;
14
15class ExportTreeTable extends Entity\DataManager
16{
17 const CODE_LENGTH = 10;
19
20 protected $inserter = null;
21 protected $codeIndex = array();
22 protected $exportOffset = 1;
23 protected $exportPath = array();
24
25 public static function getFilePath()
26 {
27 return __FILE__;
28 }
29
30 public static function getTableName()
31 {
32 return 'b_tmp_export_tree';
33 }
34
35 public static function getMap()
36 {
37 return array(
38
39 'ID' => array(
40 'data_type' => 'integer',
41 'primary' => true,
42 'autocomplete' => true,
43 ),
44
45 'CODE' => array(
46 'data_type' => 'string',
47 ),
48 'PARENT_CODE' => array(
49 'data_type' => 'string',
50 ),
51 'SYS_CODE' => array(
52 'data_type' => 'string',
53 ),
54
55 'TYPE_CODE' => array(
56 'data_type' => 'string',
57 ),
58 'FIAS_TYPE' => array(
59 'data_type' => 'string',
60 ),
61 'NAME' => array(
62 'data_type' => 'string',
63 'primary' => true,
64 ),
65 'LANGNAMES' => array(
66 'data_type' => 'string',
67 ),
68 'EXTERNALS' => array(
69 'data_type' => 'string',
70 ),
71 'LATITUDE' => array(
72 'data_type' => 'string',
73 ),
74 'LONGITUDE' => array(
75 'data_type' => 'string',
76 ),
77 'SOURCE' => array(
78 'data_type' => 'string',
79 ),
80
81 'ALTERNATE_COORDS' => array(
82 'data_type' => 'string',
83 ),
84 'BOUNDED_WITH' => array(
85 'data_type' => 'string',
86 ),
87 );
88 }
89
90 public function __construct()
91 {
92 $this->create();
93
94 $this->inserter = new Location\DBBlockInserter(array(
95 'entityName' => get_called_class(),
96 'exactFields' => array(
97 'ID', 'CODE', 'PARENT_CODE', 'SYS_CODE', 'TYPE_CODE', 'FIAS_TYPE', 'NAME', 'LANGNAMES', 'EXTERNALS', 'LATITUDE', 'LONGITUDE', 'SOURCE'
98 ),
99 'parameters' => array(
100 'mtu' => 999999,
101 'autoIncrementFld' => 'ID'
102 )
103 ));
104 }
105
106 public function restoreExportOffset()
107 {
108 $this->exportOffset = intval($this->getNextFreeCode());
109 }
110
111 public function setExportOffset($offset)
112 {
113 $this->exportOffset = $offset;
114 }
115
116 public function dropCodeIndex()
117 {
118 $this->codeIndex = array();
119 }
120
121 public function insert($data)
122 {
123 if(isset($this->codeIndex[$data['SYS_CODE']])) // already in there
124 return;
125
126 $this->codeIndex[$data['SYS_CODE']] = $this->formatCode($this->exportOffset);
127
128 $data['CODE'] = $this->codeIndex[$data['SYS_CODE']];
129 $data['PARENT_CODE'] = strlen($data['PARENT_SYS_CODE']) ? $this->codeIndex[$data['PARENT_SYS_CODE']] : '';
130
131 unset($data['PARENT_SYS_CODE']);
132
133 if(is_array($data['LANGNAMES']))
134 $data['LANGNAMES'] = serialize($data['LANGNAMES']);
135
136 if(is_array($data['EXTERNALS']))
137 $data['EXTERNALS'] = serialize($data['EXTERNALS']);
138
139 $this->exportOffset++;
140
141 $this->inserter->insert($data);
142 }
143
144 public function doneInsert()
145 {
146 $this->inserter->flush();
147 }
148
149 public function deleteAll()
150 {
151 $this->cleanup();
152 }
153
154 public function getLastOccupiedCode()
155 {
156 $res = static::getList(array('order' => array('ID' => 'desc'), 'limit' => 1, 'select' => array('CODE')))->fetch();
157
158 return $res['CODE'];
159 }
160
161 public function getNextFreeCode()
162 {
163 return self::formatCode(intval(static::getLastOccupiedCode()) + 1);
164 }
165
166 public static function formatCode($value, $length = self::CODE_LENGTH)
167 {
168 if(strlen($value) >= $length)
169 return $value;
170
171 $diff = abs($length - strlen($value));
172
173 for($i = 0; $i < $diff; $i++)
174 $value = '0'.$value;
175
176 return $value;
177 }
178
179 public function getByCode($code)
180 {
181 return static::getList(array('filter' => array(
182 '=CODE' => $code
183 )));
184 }
185
186 public function getPathTo($code)
187 {
188 $nextCode = $code;
189 $result = array();
190 while($nextCode)
191 {
192 $node = $this->getByCode($nextCode)->fetch();
193
194 $result[] = $node;
195 $nextCode = $node['PARENT_CODE'];
196 }
197
198 return $result;
199 }
200
201 public function getWalkPath()
202 {
203 return $this->exportPath;
204 }
205
206 public function getWalkPathString()
207 {
208 $res = array();
209 foreach ($this->exportPath as $item)
210 {
211 $res[] = $item['NAME'].' ('.$item['TYPE_CODE'].')';
212 }
213
214 return implode(', ', $res);
215 }
216
217 public function walkInDeep($callbacks, $ignoreThisAndDeeper = array(), $startFrom = '')
218 {
219 if(!is_callable($callbacks['ITEM']))
220 throw new Main\SystemException('Invalid callback passed');
221
222 $this->exportPath = array();
223 $this->waklInDeepBundle($callbacks, $ignoreThisAndDeeper, $startFrom);
224 }
225
226 private function waklInDeepBundle($callbacks, $ignoreThisAndDeeper = array(), $parentCode = '', $depth = 1)
227 {
228 if($depth > static::RECURSION_MAX_DEPTH)
229 throw new Main\SystemException('Too deep recursion');
230
231 $res = $this->getList(array('filter' => array('PARENT_CODE' => $parentCode)));
232 while($item = $res->fetch())
233 {
234 array_push($this->exportPath, $item);
235
236 $goDeeper = true;
237 if(call_user_func($callbacks['ITEM'], $item, $this) === false)
238 $goDeeper = false;
239
240 if(isset($ignoreThisAndDeeper[$item['TYPE_CODE']]))
241 $goDeeper = false;
242
243 if($goDeeper)
244 $this->waklInDeepBundle($callbacks, $ignoreThisAndDeeper, $item['CODE'], $depth + 1);
245
246 array_pop($this->exportPath);
247 }
248 }
249
250 public function create()
251 {
252 $dbConnection = Main\HttpApplication::getConnection();
253
254 $table = static::getTableName();
255
256 global $DB;
257
258 if(!$DB->query('select * from '.$table.' where 1=0', true))
259 {
260 $dbConnection->query('create table '.$table.' (
261
262 ID int auto_increment not null primary key,
263
264 CODE varchar(100) not null,
265 PARENT_CODE varchar(100),
266 SYS_CODE varchar(100),
267
268 TYPE_CODE varchar(20),
269 FIAS_TYPE varchar(10),
270
271 NAME varchar(100) not null,
272
273 LANGNAMES varchar(300),
274 EXTERNALS varchar(200),
275
276 LATITUDE varchar(30),
277 LONGITUDE varchar(30),
278
279 ALTERNATE_COORDS varchar(100),
280 BOUNDED_WITH varchar(100),
281
282 SOURCE varchar(2)
283 )');
284
285 $this->restoreIndexes();
286 }
287 }
288
289 public function dropIndexes()
290 {
291 $dbConnection = Main\HttpApplication::getConnection();
292 $table = static::getTableName();
293
294 try
295 {
296 $dbConnection->query('DROP INDEX IX_SALE_LOCATION_EXPORT_TREE_CODE ON '.$table);
297 }
298 catch(\Exception $e)
299 {
300 }
301
302 try
303 {
304 $dbConnection->query('DROP INDEX IX_SALE_LOCATION_EXPORT_TREE_PARENT_CODE ON '.$table);
305 }
306 catch(\Exception $e)
307 {
308 }
309
310 try
311 {
312 $dbConnection->query('DROP INDEX IX_SALE_LOCATION_EXPORT_TREE_TYPE_CODE ON '.$table);
313 }
314 catch(\Exception $e)
315 {
316 }
317 }
318
319 public function restoreIndexes()
320 {
321 $dbConnection = Main\HttpApplication::getConnection();
322 $table = static::getTableName();
323
324 try
325 {
326 $dbConnection->query('CREATE INDEX IX_SALE_LOCATION_EXPORT_TREE_CODE ON '.$table.' (CODE)');
327 }
328 catch(\Exception $e)
329 {
330 }
331
332 try
333 {
334 $dbConnection->query('CREATE INDEX IX_SALE_LOCATION_EXPORT_TREE_PARENT_CODE ON '.$table.' (PARENT_CODE)');
335 }
336 catch(\Exception $e)
337 {
338 }
339
340 try
341 {
342 $dbConnection->query('CREATE INDEX IX_SALE_LOCATION_EXPORT_TREE_TYPE_CODE ON '.$table.' (TYPE_CODE)');
343 }
344 catch(\Exception $e)
345 {
346 }
347 }
348
349 public function cleanup()
350 {
351 Main\HttpApplication::getConnection()->query('truncate table '.static::getTableName());
352 }
353
354 public static function switchIndexes($way = true)
355 {
356 Main\HttpApplication::getConnection()->query('alter table '.static::getTableName().' '.($way ? 'enable' : 'disable').' keys');
357 }
358
359 public function output($data, $important = true)
360 {
361 if(!$important)
362 return false;
363
364 ob_start();
365 print_r($data);
366 $data = ob_get_contents();
367 ob_end_clean();
368
369 file_put_contents($_SERVER['DOCUMENT_ROOT'].'/output.txt', $data.PHP_EOL, FILE_APPEND);
370 }
371}
walkInDeep($callbacks, $ignoreThisAndDeeper=array(), $startFrom='')
static formatCode($value, $length=self::CODE_LENGTH)