Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
stepper.php
1<?php
2
3namespace Bitrix\Main\Update;
4
5use \Bitrix\Main;
6use \Bitrix\Main\HttpApplication;
7use \Bitrix\Main\Web\Json;
8use \Bitrix\Main\Config\Option;
9use \Bitrix\Main\Context;
10use \Bitrix\Main\Localization\Loc;
11
26abstract class Stepper
27{
28 protected static $moduleId = "main";
29 protected $deleteFile = false;
30 protected $outerParams = [];
31 private static $filesToUnlink = array();
32 private static $countId = 0;
33 const CONTINUE_EXECUTION = true;
34 const FINISH_EXECUTION = false;
35
42 public static function getHtml($ids = array(), $title = "")
43 {
44 if (static::class !== __CLASS__)
45 {
46 $title = static::getTitle();
47 $ids = [static::$moduleId => [ static::class ]];
48 return call_user_func(array(__CLASS__, "getHtml"), $ids, $title);
49 }
50
51 $return = array();
52 $count = 0;
53 $steps = 0;
54
55 if (is_string($ids))
56 {
57 $ids = array($ids => null);
58 }
59
60 foreach($ids as $moduleId => $classesId)
61 {
62 if (is_string($classesId))
63 $classesId = array($classesId);
64 if (is_array($classesId))
65 {
66 foreach($classesId as $classId)
67 {
68 if (($option = Option::get("main.stepper.".$moduleId, $classId, "")) !== "")
69 {
70 $option = unserialize($option, ['allowed_classes' => false]);
71 if (is_array($option))
72 {
73 $return[] = array(
74 "moduleId" => $moduleId,
75 "class" => $classId,
76 "title" => $option["title"],
77 "steps" => $option["steps"],
78 "count" => $option["count"]
79 );
80 $count += $option["count"];
81 $steps += ($option["count"] > $option["steps"] ? $option["steps"] : $option["count"]);
82 }
83 }
84 }
85 }
86 else if (is_null($classesId))
87 {
88 $options = Option::getForModule("main.stepper.".$moduleId);
89 foreach($options as $classId => $option)
90 {
91 $option = unserialize($option, ['allowed_classes' => false]);
92 if (is_array($option))
93 {
94 $return[] = array(
95 "moduleId" => $moduleId,
96 "class" => $classId,
97 "title" => $option["title"],
98 "steps" => $option["steps"],
99 "count" => $option["count"]
100 );
101 $count += $option["count"];
102 $steps += ($option["count"] > $option["steps"] ? $option["steps"] : $option["count"]);
103 }
104 }
105 }
106 }
107
108 $result = '';
109 if (!empty($return))
110 {
111 $id = ++self::$countId;
112 \CJSCore::Init(array('update_stepper'));
113 $title = empty($title) ? self::getTitle() : $title;
114 $progress = $count > 0 ? intval($steps * 100 / $count) : 0;
115 $result .= <<<HTML
116<div class="main-stepper main-stepper-show" id="{$id}-container" data-bx-steps-count="{$count}">
117 <div class="main-stepper-info" id="{$id}-title">{$title}</div>
118 <div class="main-stepper-inner">
119 <div class="main-stepper-bar">
120 <div class="main-stepper-bar-line" id="{$id}-bar" style="width:{$progress}%;"></div>
121 </div>
122 <div class="main-stepper-steps"><span id="{$id}-steps">{$steps}</span> / <span id="{$id}-count">{$count}</span></div>
123 <div class="main-stepper-error-text" id="{$id}-error"></div>
124 </div>
125</div>
126HTML;
127 $return = \CUtil::PhpToJSObject($return);
128 $result = <<<HTML
129<div class="main-stepper-block">{$result}
130<script>BX.ready(function(){ if (BX && BX["UpdateStepperRegister"]) { BX.UpdateStepperRegister({$id}, {$return}); }});</script>
131</div>
132HTML;
133 }
134 return $result;
135 }
136
137 public static function getTitle()
138 {
139 return Loc::getMessage("STEPPER_TITLE");
140 }
145 public static function execAgent()
146 {
147 $updater = self::createInstance();
148 $className = get_class($updater);
149
150 $option = Option::get("main.stepper.".$updater->getModuleId(), $className, "");
151 if ($option !== "" )
152 $option = unserialize($option, ['allowed_classes' => false]);
153 $option = is_array($option) ? $option : array();
154 $updater->setOuterParams(func_get_args());
155 if ($updater->execute($option) === self::CONTINUE_EXECUTION)
156 {
157 $option["steps"] = (array_key_exists("steps", $option) ? (int)$option["steps"] : 0);
158 $option["count"] = (array_key_exists("count", $option) ? (int)$option["count"] : 0);
159 $option["title"] = $updater::getTitle();
160
161 Option::set("main.stepper.".$updater->getModuleId(), $className, serialize($option));
162 return $className . '::execAgent('.$updater::makeArguments($updater->getOuterParams()).');';
163 }
164 if ($updater->deleteFile === true && \Bitrix\Main\ModuleManager::isModuleInstalled("bitrix24") !== true)
165 {
166 $res = new \ReflectionClass($updater);
167 self::$filesToUnlink[] = $res->getFileName();
168 }
169 Option::delete('main.stepper.'.$updater->getModuleId(), ['name' => $className]);
170 Option::delete('main.stepper.'.$updater->getModuleId(), ['name' => '\\'.$className]);
171
172 return '';
173 }
174
175 public function __destruct()
176 {
177 if (!empty(self::$filesToUnlink))
178 {
179 while ($file = array_pop(self::$filesToUnlink))
180 {
181 $file = \CBXVirtualIo::GetInstance()->GetFile($file);
182
183 $langDir = $fileName = "";
184 $filePath = $file->GetPathWithName();
185 while(($slashPos = mb_strrpos($filePath, "/")) !== false)
186 {
187 $filePath = mb_substr($filePath, 0, $slashPos);
188 $langPath = $filePath."/lang";
189 if(is_dir($langPath))
190 {
191 $langDir = $langPath;
192 $fileName = mb_substr($file->GetPathWithName(), $slashPos);
193 break;
194 }
195 }
196 if ($langDir <> "" && ($langDir = \CBXVirtualIo::GetInstance()->GetDirectory($langDir)) &&
197 $langDir->IsExists())
198 {
199 $languages = $langDir->GetChildren();
200 foreach ($languages as $language)
201 {
202 if ($language->IsDirectory() &&
203 ($f = \CBXVirtualIo::GetInstance()->GetFile($language->GetPathWithName().$fileName)) &&
204 $f->IsExists())
205 {
206 $f->unlink();
207 }
208 }
209 unset($f);
210 }
211 $file->unlink();
212 }
213 unset($file);
214 }
215 }
221 abstract function execute(array &$option);
222
223 public function setOuterParams(array $outerParams): void
224 {
225 $this->outerParams = $outerParams;
226 }
227
228 public function getOuterParams(): array
229 {
230 return $this->outerParams;
231 }
232
238 public static function makeArguments($arguments = []): string
239 {
240 if (is_array($arguments))
241 {
242 foreach ($arguments as $key=> $val)
243 {
244 if (is_string($val))
245 {
246 $arguments[$key] = "'".EscapePHPString($val, "'")."'";
247 }
248 else
249 {
250 $arguments[$key] = intval($val);
251 }
252 }
253 return implode(", ", $arguments);
254 }
255 return "";
256 }
261 public static function createInstance()
262 {
263 return new static;
264 }
269 public static function getModuleId()
270 {
271 return static::$moduleId;
272 }
279 public static function bind($delay = 300, $withArguments = [])
280 {
282 $c = get_called_class();
283 self::bindClass($c, $c::getModuleId(), $delay, $withArguments);
284 }
285
294 public static function bindClass($className, $moduleId, $delay = 300, $withArguments = [])
295 {
296 if (class_exists("\CAgent"))
297 {
298 $addAgent = true;
299 $withArguments = is_array($withArguments) ? $withArguments : [];
300
301 $delay = (int)$delay;
302 if ($delay <= 0)
303 {
305 $addAgent = ('' !== call_user_func_array([$className, "execAgent"], $withArguments));
306 }
307
308 if ($addAgent)
309 {
310 if (Option::get("main.stepper.".$moduleId, $className, "") === "")
311 Option::set("main.stepper.".$moduleId, $className, serialize([]));
312 \CTimeZone::Disable();
313 \CAgent::AddAgent(
314 $className.'::execAgent('.(empty($withArguments) ? '' : call_user_func_array([$className, "makeArguments"], [$withArguments])).');',
315 $moduleId,
316 "Y",
317 1,
318 "",
319 "Y",
320 date(Main\Type\Date::convertFormatToPhp(\CSite::GetDateFormat("FULL")), time() + $delay),
321 100,
322 false,
323 false
324 );
325 \CTimeZone::Enable();
326 }
327 }
328 else
329 {
330 $connection = \Bitrix\Main\Application::getConnection();
331 $helper = $connection->getSqlHelper();
332
333 $arguments = '';
334 if (!empty($withArguments))
335 {
336 $arguments = class_exists($className)
337 ? call_user_func_array([$className, "makeArguments"], [$withArguments])
338 : self::makeArguments($withArguments)
339 ;
340 }
341 $name = $helper->forSql($className.'::execAgent('.$arguments.');', 2000);
342 $className = $helper->forSql($className);
343 $moduleId = $helper->forSql($moduleId);
344 $agent = $connection->query("SELECT ID FROM b_agent WHERE MODULE_ID='".$moduleId."' AND NAME = '".$name."' AND USER_ID IS NULL")->fetch();
345 if (!$agent)
346 {
347 $connection->query("INSERT INTO b_agent (MODULE_ID, SORT, NAME, ACTIVE, AGENT_INTERVAL, IS_PERIOD, NEXT_EXEC) VALUES ('".$moduleId."', 100, '".$name."', 'Y', 1, 'Y', ".($delay > 0 ? $helper->addSecondsToDateTime($delay) : $helper->getCurrentDateTimeFunction()).")");
348 $merge = $helper->prepareMerge('b_option', ['MODULE_ID', 'NAME'], [
349 'MODULE_ID' => 'main.stepper.' . $moduleId,
350 'NAME' => $className,
351 'VALUE' => 'a:0:{}',
352 ], [
353 'VALUE' => 'a:0:{}',
354 ]);
355 if ($merge)
356 {
357 $connection->Query($merge[0]);
358 }
359 }
360 }
361 }
366 public static function checkRequest()
367 {
368 $result = array();
369 $data = Context::getCurrent()->getRequest()->getPost("stepper");
370 if (is_array($data))
371 {
372 foreach ($data as $stepper)
373 {
374 if (($option = Option::get("main.stepper.".$stepper["moduleId"], $stepper["class"], "")) !== "" &&
375 ($res = unserialize($option, ['allowed_classes' => false])) && is_array($res))
376 {
377 $r = array(
378 "moduleId" => $stepper["moduleId"],
379 "class" => $stepper["class"],
380 "steps" => $res["steps"],
381 "count" => $res["count"]
382 );
383 $result[] = $r;
384 }
385 }
386 }
387 self::sendJson($result);
388 }
394 private static function sendJson($result)
395 {
396 global $APPLICATION;
397 $APPLICATION->RestartBuffer();
398
399 header('Content-Type:application/json; charset=UTF-8');
400
401 echo Json::encode($result);
402 \CMain::finalActions();
403 die;
404 }
405
406 protected function writeToLog(\Exception $exception)
407 {
408 $application = HttpApplication::getInstance();
409 $exceptionHandler = $application->getExceptionHandler();
410 $exceptionHandler->writeToLog($exception);
411 }
412}
static getCurrent()
Definition context.php:241
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static isModuleInstalled($moduleName)
writeToLog(\Exception $exception)
Definition stepper.php:406
setOuterParams(array $outerParams)
Definition stepper.php:223
static makeArguments($arguments=[])
Definition stepper.php:238
static getHtml($ids=array(), $title="")
Definition stepper.php:42
execute(array &$option)