/** * @used-by df_exception_get_trace() * @used-by postface() * @return string */ public final function traceS() { /** @var int $count */ $count = count($this->states()); return implode(df_map_k($this->states(), function ($index, State $state) use($count) { $index++; /** @var string $result */ $result = (string) $state; if ($index !== $count) { /** @var string $indexS */ $indexS = (string) $index; /** @var int $indexLength */ $indexLength = strlen($indexS); /** @var int $delimiterLength */ $delimiterLength = 36; /** @var int $fillerLength */ $fillerLength = $delimiterLength - $indexLength; /** @var int $fillerLengthL */ $fillerLengthL = floor($fillerLength / 2); /** @var int $fillerLengthR */ $fillerLengthR = $fillerLength - $fillerLengthL; /** @var string $delimiter */ $delimiter = str_repeat('*', $fillerLengthL) . $indexS . str_repeat('*', $fillerLengthR); $result .= "\n" . $delimiter . "\n"; } return $result; })); }
/** * 2016-07-10 * @return array(string => string) */ public function asArray() { return dfc($this, function () { return df_map_k(function ($key, $value) { return $this->formatKV($key, $value); }, $this->primary() + ['Request URL' => $this->response()->requestUrl(), 'Request params' => df_tab_multiline(df_print_params($this->response()->requestP())), 'Response' => df_tab_multiline(df_print_params($this->response()->getData()))]); }); }
/** * 2015-12-16 * @return string */ public function render() { return df_cc_n(df_map_k($this->_blocks, function ($selector, array $rules) { /** @var string $selector */ /** @var string[] $rules */ /** @var string $rulesS */ $rulesS = df_tab_multiline(df_cc_n($rules)); return "{$selector} {\n{$rulesS}\n}"; })); }
/** @return string */ private function openTagWithAttributesAsText() { return df_cc_s($this->tag(), $this->shouldAttributesBeMultiline() ? "\n" : null, call_user_func($this->shouldAttributesBeMultiline() ? 'df_tab_multiline' : 'df_nop', implode($this->shouldAttributesBeMultiline() ? "\n" : ' ', df_clean(df_map_k(function ($name, $value) { df_param_string_not_empty($name, 0); /** * 2015-04-16 * Передавать в качестве $value массив имеет смысл, например, для атрибута «class». * * 2016-11-29 * Не использую @see df_e(), чтобы сохранить двойные кавычки (data-mage-init) * и в то же время сконвертировать одинарные * (потому что значения атрибутов мы ниже обрамляем именно одинарными). */ $value = htmlspecialchars(str_replace("'", ''', !is_array($value) ? $value : df_cc_s($value)), ENT_NOQUOTES, 'UTF-8', false); return '' === $value ? '' : "{$name}='{$value}'"; }, $this->attributes()))))); }
/** * Возвращает неиспользуемое имя файла в заданной папке $directory по заданному шаблону $template. * Результатом всегда является непустая строка. * @param string $directory * @param string $template * @param string $ds [optional] * @return string */ function df_file_name($directory, $template, $ds = '-') { // 2016-11-09 // Отныне $template может содержать файловый путь: // в этом случае этот файловый путь убираем из $template и добавляем к $directory. $directory = df_path_n($directory); $template = df_path_n($template); if (df_contains($template, '/')) { /** @var string $templateA */ $templateA = explode('/', $template); $template = array_pop($templateA); $directory = df_cc_path($directory, $templateA); } /** @var string $result */ /** @var int $counter */ $counter = 1; /** @var bool $hasOrderingPosition */ $hasOrderingPosition = df_contains($template, '{ordering}'); /** @var \Zend_Date $now */ $now = \Zend_Date::now()->setTimezone('Europe/Moscow'); /** @var array(string => string) */ $vars = df_map_k(function ($k, $v) use($ds, $now) { return df_dts($now, implode($ds, $v)); }, ['date' => ['y', 'MM', 'dd'], 'time' => ['HH', 'mm'], 'time-full' => ['HH', 'mm', 'ss']]); /** * 2016-11-09 * @see \Zend_Date неправильно работает с миллисекундами: * всегда возвращает 0 вместо реального количества миллисекунд. * Так происходит из-за дефекта в методах * @see \Zend_Date::addMilliSecond() * @see \Zend_Date::setMilliSecond() * Там такой код: list($milli, $time) = explode(" ", microtime()); $milli = intval($milli); * https://github.com/OpenMage/magento-mirror/blob/1.9.3.0/lib/Zend/Date.php#L4490-L4491 * Этот код ошибочен, потому что после первой операции * $milli содержит дробное значение меньше 1, например: 0.653... * А вторая операция тупо делает из этого значения 0. */ $vars['time-full-ms'] = implode($ds, [$vars['time-full'], sprintf('%02d', round(100 * df_first(explode(' ', microtime()))))]); while (true) { /** @var string $fileName */ $fileName = df_var($template, ['ordering' => sprintf('%03d', $counter)] + $vars); /** @var string $fileFullPath */ $fileFullPath = $directory . DS . $fileName; if (!file_exists($fileFullPath)) { /** * Раньше здесь стояло file_put_contents, * и иногда почему-то возникал сбой: * failed to open stream: No such file or directory. * Может быть, такой сбой возникает, если папка не существует? */ $result = $fileFullPath; break; } else { if ($counter > 999) { df_error("Счётчик достиг предела ({$counter})."); } else { $counter++; /** * Если в шаблоне имени файла * нет переменной «{ordering}» — значит, надо добавить её, * чтобы в следующей интерации имя файла стало уникальным. * Вставляем «{ordering}» непосредственно перед расширением файла. * Например, rm.shipping.log преобразуем в rm.shipping-{ordering}.log */ if (!$hasOrderingPosition && 2 === $counter) { /** @var string[] $fileNameTemplateExploded */ $fileNameTemplateExploded = explode('.', $template); /** @var int $secondFromLastPartIndex*/ $secondFromLastPartIndex = max(0, count($fileNameTemplateExploded) - 2); /** @var string $secondFromLastPart */ $secondFromLastPart = dfa($fileNameTemplateExploded, $secondFromLastPartIndex); df_assert_string_not_empty($secondFromLastPart); $fileNameTemplateExploded[$secondFromLastPartIndex] = implode('--', [$secondFromLastPart, '{ordering}']); /** @var string $newFileNameTemplate */ $newFileNameTemplate = implode('.', $fileNameTemplateExploded); df_assert_ne($template, $newFileNameTemplate); $template = $newFileNameTemplate; } } } } return df_path_n($result); }
/** * 2016-11-17 * Не вызываем здесь @see __(), * потому что словарь ещё будет меняться, в частности, методом @see prepareDic() * @see getSpecificInformation() * Ключи потом будут автоматически переведены методом @see \Df\Payment\Info\Entry::nameT() * Значения переведены не будут! * @used-by siB() * @used-by siF() * @param string|array(string => string) $k * @param string|null $v [optional] */ protected function si($k, $v = null) { is_array($k) ? df_map_k(function ($k, $v) { return $this->si($k, $v); }, $k) : ($this->_paymentSpecificInformation[$k] = $v); }