/** * @used-by df_notify_exception() * @used-by \Df\Qa\Message_Failure_Error::check() * @return void * @throws \Exception */ public final function log() { /** * 2015-04-04 * Нам нужно правильно обработать ситуацию, * когда при формировании диагностического отчёта о сбое происходит новый сбой. * 1) Статическая переменная $inProcess предотвращает нас от бесконечной рекурсии. * 2) try... catch позволяет нам перехватить внутренний сбой, * сформировать диагностическое сообщение о нём, * а затем перевозбудить его снова, чтобы вывести на экран. * Обратите внимание, что внутренний сбой не будет виден на экране при асинхронном запросе * (много таких запросов делает, например, страница оформления заказа), * поэтому try... catch с целью записи отчёта крайне важно: * без этого при сбое асинхроноого запроса диагностичекское сообщение о сбое * окажется утраченным. */ static $inProcess; if (!$inProcess) { $inProcess = true; try { df_report($this->reportName(), $this->report()); $inProcess = false; } catch (\Exception $e) { df_log(df_ets($e)); throw $e; } } }
/** * @override * @param mixed $value * @throws \Zend_Filter_Exception * @return int */ public function filter($value) { /** @var int $result */ try { $result = df_nat($value); } catch (\Exception $e) { df_error(new \Zend_Filter_Exception(df_ets($e))); } return $result; }
/** * 2015-04-05 * Оборачиваем код в try..catch, * чтобы не утратить сообщение о внутреннем сбое при асинхронном запросе. * @used-by \Df\Core\Boot::init() * @return void */ public static function check() { try { if (error_get_last() && self::isFatal()) { self::i()->log(); } } catch (\Exception $e) { df_log(df_ets($e)); } }
/** * Обратите внимание, что PHP разрешает сигнатуре конструктора класса-потомка * отличаться от сигнатуры конструктора класса родителя: * http://3v4l.org/qQdJ3 * @param mixed ...$args */ public function __construct(...$args) { /** @var string|Phrase|E|array(string => mixed)|null $arg0 */ $arg0 = dfa($args, 0); /** @var E|LE|null $prev */ $prev = null; /** @var Phrase|null $message */ $message = null; // 2015-10-10 if (is_array($arg0)) { $this->_data = $arg0; } else { if ($arg0 instanceof Phrase) { $message = $arg0; } else { if (is_string($arg0)) { $message = __($arg0); } else { if ($arg0 instanceof E) { $prev = $arg0; } } } } /** @var int|string|E|Phrase|null $arg1 */ $arg1 = dfa($args, 1); if (!is_null($arg1)) { if ($arg1 instanceof E) { $prev = $arg1; } else { if (is_int($prev)) { $this->_stackLevelsCountToSkip = $arg1; } else { if (is_string($arg1) || $arg1 instanceof Phrase) { $this->comment((string) $arg1); } } } } if (is_null($message)) { $message = __($prev ? df_ets($prev) : 'No message'); } parent::__construct($message, $prev); }
/** * @used-by \Df\Qa\Message_Failure::traceS() * @override * @return string */ public function __toString() { if (!isset($this->{__METHOD__})) { /** * Метод @see __toString() не имеет права возбуждать исключительных ситуаций. * Fatal error: Method __toString() must not throw an exception * http://stackoverflow.com/questions/2429642/why-its-impossible-to-throw-exception-from-tostring */ try { /** @var string[] $resultA */ /** @uses param() */ $resultA = array_filter(array_map([__CLASS__, 'param'], [['File', str_replace(DIRECTORY_SEPARATOR, '/', df_trim_text_left($this->filePath(), BP . DIRECTORY_SEPARATOR))], ['Line', $this->line()], ['Caller', !$this->_next ? '' : $this->_next->methodName()], ['Callee', $this->methodName()]])); if ($this[self::$P__SHOW_CONTEXT] && $this->context()) { $resultA[] = self::param(['Context', "\n" . $this->context()]); } $this->{__METHOD__} = df_cc_n($resultA); } catch (\Exception $e) { df_log(df_ets($e)); $this->{__METHOD__} = df_ets($e); } } return $this->{__METHOD__}; }
/** * 2016-08-02 * @param string|Phrase|\Exception $message */ function df_message_error($message) { df_message_add(df_ets($message), IMessage::TYPE_ERROR); }
/** * 2016-07-20 * @param E $e * @return string */ function df_lets(E $e) { return df_ets(df_le($e)); }
/** * @param string|null $key * @param mixed $value * @param string[]|bool $wrapInCData [optional] * @return X */ private function importString($key, $value, $wrapInCData = []) { /** @var bool $wrapInCDataAll */ $wrapInCDataAll = is_array($wrapInCData) ? false : !!$wrapInCData; $wrapInCData = df_nta($wrapInCData); /** * null означает, что метод importString * не должен создавать дочерний тэг $key, * а должен добавить текст * в качестве единственного содержимого текущего тэга */ if (!is_null($key)) { df_param_string($key, 0); } /** @var string $keyAsString */ $keyAsString = is_null($key) ? $this->getName() : $key; /** * @var bool $valueIsString */ $valueIsString = is_string($value); /** @var string $valueAsString */ $valueAsString = null; try { $valueAsString = $valueIsString ? $value : df_string($value); } catch (E $e) { df_error("Не могу сконвертировать значение ключа «%s» в строку.\n%s", $keyAsString, df_ets($e)); } /** @var bool $needWrapInCData */ $needWrapInCData = $wrapInCDataAll; if ($valueIsString && $valueAsString) { /** * Поддержка синтаксиса array( 'Представление' => df_cdata( $this->getAddress()->format( Mage_Customer_Model_Attribute_Data::OUTPUT_FORMAT_TEXT ) ) ) * Обратите внимание, что проверка на синтаксис[[]] должна предшествовать * проверке на принадлежность ключа $keyAsString в массиве $wrapInCData, * потому что при соответствии синтаксису[[]] нам надо удалить из значения символы[[]]. * Обратите внимание, что нам нужно выполнить проверку на синтаксис df_cdata ([[]]) * даже при $wrapInCDataAll = true, потому что маркеры [[ и ]] из данных надо удалять. */ /** * Перед вызовом медленной функции @see preg_match * выполняем более быструю и простую проверку @see df_contains */ if (df_contains($valueAsString, '[[') && df_contains($valueAsString, ']]')) { /** @var string $pattern */ $pattern = "#\\[\\[([\\s\\S]*)\\]\\]#mu"; /** @var string[] $matches */ $matches = []; if (1 === preg_match($pattern, $valueAsString, $matches)) { $valueAsString = $matches[1]; $needWrapInCData = true; } } $needWrapInCData = $needWrapInCData || in_array($keyAsString, $wrapInCData); } /** @var X $result */ $result = $needWrapInCData ? is_null($key) ? $this->setCData($valueAsString) : $this->addChildText($keyAsString, $valueAsString) : (is_null($key) ? $this->setValue($valueAsString) : $this->addChild($keyAsString, $valueAsString)); df_assert($result instanceof X); return $result; }
/** * @param string|X $x * @param bool $throw [optional] * @return X|null * @throws E */ function df_xml_parse($x, $throw = true) { /** @var X $result */ if ($x instanceof X) { $result = $x; } else { df_param_string_not_empty($x, 0); $result = null; try { $result = new X($x); } catch (\Exception $e) { if ($throw) { df_error("При синтаксическом разборе документа XML произошёл сбой:\n" . "«%s»\n" . "********************\n" . "%s\n" . "********************\n", df_ets($e), df_trim($x)); } } } return $result; }
/** * @param string|mixed[] $pattern * @return string * @throws \Exception */ function df_sprintf_strict($pattern) { /** @var mixed[] $arguments */ if (is_array($pattern)) { $arguments = $pattern; $pattern = df_first($arguments); } else { $arguments = func_get_args(); } /** @var string $result */ if (1 === count($arguments)) { $result = $pattern; } else { try { $result = vsprintf($pattern, df_tail($arguments)); } catch (Exception $e) { /** @var bool $inProcess */ static $inProcess = false; if (!$inProcess) { $inProcess = true; df_error('При выполнении sprintf произошёл сбой «{message}».' . "\nШаблон: {$pattern}." . "\nПараметры:\n{params}.", ['{message}' => df_ets($e), '{params}' => print_r(df_tail($arguments), true)]); $inProcess = false; } } } return $result; }