/** * 2015-10-27 * @used-by df_fe_init() * @used-by \Dfe\Markdown\FormElement::getBeforeElementHtml() * @param string|string[] $resource * @return string */ function df_link_inline($resource) { if (1 < func_num_args()) { $resource = func_get_args(); } /** @var string $result */ if (is_array($resource)) { $result = df_cc_n(array_map(__FUNCTION__, $resource)); } else { /** * 2015-12-11 * Не имеет смысла несколько раз загружать на страницу один и тот же файл CSS. * Как оказалось, браузер при наличии на странице нескольких тегов link с одинаковым адресом * применяет одни и те же правила несколько раз (хотя, видимо, не делает повторных обращений к серверу * при включенном в браузере кэшировании браузерных ресурсов). */ /** @var string[] $cache */ static $cache; if (isset($cache[$resource])) { $result = ''; } else { /** * 2016-03-23 * Добавил обработку пустой строки $resource. * Нам это нужно, потому что пустую строку может вернуть @see \Df\Typography\Font::link() * https://mage2.pro/t/1010 */ $result = !$resource ? '' : df_tag('link', ['href' => df_asset_create($resource)->getUrl(), 'rel' => 'stylesheet', 'type' => 'text/css'], null, false); $cache[$resource] = true; } } return $result; }
/** * 2015-11-27 * @override * @see \Df\Core\Exception::message() * @return string */ public function message() { /** @var string[] $resultA */ $resultA[] = "Google Fonts API error: «{$this->messageI()}»."; if ($this->isAccessNotConfigured()) { $resultA[] = 'You need to setup Google Fonts API using the instruction https://mage2.pro/t/269'; } return df_cc_n($resultA); }
/** * 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}"; })); }
/** * @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__}; }
/** * @used-by \Df\Qa\Message::report() * @return string */ public static function render() { /** @var string $result */ // 2015-09-02 // Warning: max(): Array must contain at least one element if (!self::$_items) { $result = ''; } else { /** @uses \Df\Qa\Context::sort() */ uasort(self::$_items, [__CLASS__, 'sort']); /** @var int $padSize */ $padSize = 2 + max(array_map('mb_strlen', array_keys(self::$_items))); /** @var string[] $rows */ $rows = []; foreach (self::$_items as $label => $item) { /** @var string $label */ /** @var array(string => string|int) $item */ $rows[] = df_pad($label . ':', $padSize) . $item[self::$VALUE]; } $result = df_cc_n($rows); } return $result; }
/** @return string */ private function getSubjectReportPart() { if (!isset($this->{__METHOD__})) { $this->{__METHOD__} = !$this->isSubjectTooLongToReport() ? $this->getSubject() : df_cc_n(array_slice($this->getSubjectSplitted(), 0, $this->getSubjectMaxLinesToReport())); } return $this->{__METHOD__}; }
/** * 2015-04-05 * @used-by Df_Checkout_Module_Config_Area::getVar() * @param mixed $value * @param \Zend_Validate_Interface $validator * @throws \Df\Core\Exception * @return void */ public static function check($value, \Zend_Validate_Interface $validator) { if (!self::validate($value, $validator)) { df_error(new \Df\Core\Exception(df_cc_n($validator->getMessages()), df_print_params(['Значение' => df_debug_type($value), 'Проверяющий' => get_class($value)]))); } }
/** * @param \Zend_Validate_Interface $validator * @param mixed $value * @param int $stackLevel * @return void * @throws \Exception */ public static function validateValue(\Zend_Validate_Interface $validator, $value, $stackLevel = 1) { if (!$validator->isValid($value)) { /** @var string $messagesS */ $messagesS = df_cc_n($validator->getMessages()); /** @var string $validatorClass */ $validatorClass = get_class($validator); self::throwException("Значение переменной забраковано проверяющим «{$validatorClass}»." . "\nСообщения проверяющего:\n{$messagesS}", $stackLevel); } }
/** * @param string[] $tags * @return string */ private function implodeTags(array $tags) { return df_tab_multiline(df_cc_n($tags)); }
/** * 2016-08-31 * @return string */ private function _p() { /** @var string $result */ /** * Обратите внимание, что метод ядра Magento CE * @see \Magento\Framework\Simplexml\Element::asNiceXml() * не сохраняет в документе XML блоки CDATA, * а вместо этого заменяет недопустимые для XML символы их допустимыми кодами, * например: & => & * * Также @see \Magento\Framework\Simplexml\Element::asNiceXml() * не добавляет к документу заголовок XML: его надо добавить вручную. * * 2015-02-27 * Обратите внимание, что для конвертации объекта класса @see SimpleXMLElement в строку * надо использовать именно метод @uses SimpleXMLElement::asXML(), * а не @see SimpleXMLElement::__toString() или оператор (string)$this. * * @see SimpleXMLElement::__toString() и (string)$this * возвращают непустую строку только для концевых узлов (листьев дерева XML). * Пример: <?xml version='1.0' encoding='utf-8'?> <menu> <product> <cms> <class>aaa</class> <weight>1</weight> </cms> <test> <class>bbb</class> <weight>2</weight> </test> </product> </menu> * Здесь для $e1 = $xml->{'product'}->{'cms'}->{'class'} * мы можем использовать $e1->__toString() и (string)$e1. * http://3v4l.org/rAq3F * Однако для $e2 = $xml->{'product'}->{'cms'} * мы не можем использовать $e2->__toString() и (string)$e2, * потому что узел «cms» не является концевым узлом (листом дерева XML). * http://3v4l.org/Pkj37 * Более того, метод @see SimpleXMLElement::__toString() * отсутствует в PHP версий 5.2.17 и ниже: * http://3v4l.org/Wiia2#v500 */ /** @var string $header */ $header = $this[self::P__SKIP_HEADER] ? '' : df_xml_header($this[self::P__1251] ? 'Windows-1251' : 'UTF-8'); /** @var X $x */ $x = df_xml_parse(df_cc_n($header, $this[self::P__DOC_TYPE], sprintf('<%s/>', $this[self::$P__TAG]))); $x->addAttributes($this[self::P__ATTRIBUTES]); $x->importArray($this[self::$P__CONTENTS], $this[self::P__WRAP_IN_CDATA]); /** @var bool $pretty */ $pretty = $this[self::P__PRETTY]; $result = $this[self::P__SKIP_HEADER] ? $x->asXMLPart() : ($pretty || $this[self::P__1251] ? df_cc_n($header, $pretty ? $x->asNiceXml() : $x->asXMLPart()) : $x->asXML()); // Убеждаемся, что asXML вернуло строку, а не false. df_assert_ne(false, $result); /** * Символ 0xB (вертикальная табуляция) допустим в UTF-8, но недопустим в XML: * http://stackoverflow.com/a/10095901 */ $result = str_replace("\v", "", $result); if ($this[self::P__1251]) { $result = df_1251_to($result); } if ($this[self::P__REMOVE_LINE_BREAKS]) { $result = df_t()->removeLineBreaks($result); } if ($this[self::P__DECODE_ENTITIES]) { $result = html_entity_decode($result, ENT_NOQUOTES, 'UTF-8'); } return $result; }
/** * 2016-07-10 * @override * @see \Df\Core\Exception::message() * @return string */ public function message() { return df_cc_n($this->getMessage(), $this->response()->report()->asText()); }
/** * 2016-08-19 * @used-by dfp_error() * @used-by \Df\Payment\PlaceOrderInternal::message() * @used-by \Dfe\Stripe\Exception::messageC() * @param string|null $message [optional] * @return string */ function dfp_error_message($message = null) { return nl2br(df_cc_n(__("Sorry, the payment attempt is failed."), $message ? __("The payment service's message is «<b>%1</b>».", $message) : null, __("Please try again, or try another payment method."))); }
/** * 2016-09-01 * @uses \Df\Xml\X::asNiceXml() не сохраняет заголовок XML. * @see df_json_prettify() * @param string|X $x * @return string */ function df_xml_prettify($x) { return df_cc_n(df_xml_parse_header($x), df_xml_parse($x)->asNiceXml()); }
/** * @param object $object * @param string $propertyName * @param mixed $propertyValue * @param \Zend_Validate_Interface $failedValidator */ public function __construct($object, $propertyName, $propertyValue, \Zend_Validate_Interface $failedValidator) { parent::__construct(sprintf("«%s»: значение %s недопустимо для свойства «%s».\nСообщение проверяющего:\n%s", get_class($object), df_debug_type($propertyValue), $propertyName, df_cc_n($failedValidator->getMessages()))); }
/** * @param string $text * @return string */ function df_tab_multiline($text) { return df_cc_n(df_tab(df_explode_n($text))); }
/** * 2016-07-10 * @return string */ public function asText() { return dfc($this, function () { return df_cc_n($this->asArray()); }); }
/** * 2015-11-28 * @param AE|E $e * @param string $class [optional] * @param string|string[] $css [optional] * @param array(string => string) $params [optional] * @param string|null $path [optional] * @return void */ function df_fe_init(AE $e, $class = '', $css = [], $params = [], $path = null) { $class = $class ?: get_class($e); /** @var string $moduleName */ $moduleName = df_module_name($class); // 2015-12-29 // Мы различаем ситуации, когда $path равно null и пустой строке. // *) null означает, что имя ресурса должно определяться по имени класса. // *) пустая строка означает, что ресурс не имеет префикса, т.е. его имя просто «main». if (is_null($path)) { /** @var string[] $classA */ $classA = df_explode_class_lc($class); $classLast = array_pop($classA); switch ($classLast) { // Если имя класса заканчивается на FormElement, // то это окончание в пути к ресурсу отбрасываем. case 'formElement': // $path будет равно null break; // Если имя класса заканчивается на Element, // то в качестве пути к ресурсу используем предыдущую часть класса. // Пример: «Dfe\SalesSequence\Config\Matrix\Element» => «matrix» // Если имя класса заканчивается на Element, // то в качестве пути к ресурсу используем предыдущую часть класса. // Пример: «Dfe\SalesSequence\Config\Matrix\Element» => «matrix» case 'element': $path = array_pop($classA); break; default: $path = $classLast; } } // 2015-12-29 // Используем df_ccc, чтобы отбросить $path, равный пустой строке. // Если имя класса заканчивается на FormElement, то это окончание в пути к ресурсу отбрасываем. $path = df_ccc('/', 'formElement', $path, 'main'); /** * 2015-12-29 * На практике заметил, что основной файл CSS используется почти всегда, * и его имя имеет формат: Df_Framework::formElement/color/main.css. * Добавляем его обязательно в конец массива, * чтобы правила основного файла CSS элемента * имели приоритет над правилами библиотечных файлов CSS, * которые элемент мог включать в массив $css. * Обратите внимание, что мы даже не проверяем, * присутствует ли уже $mainCss в массиве $css, * потому что @uses df_link_inline делает это сама. */ $css = df_array($css); /** * 2015-12-30 * Раньше я думал, что основной файл CSS используется всегда, однако нашлось исключение: * @see \Dfe\CurrencyFormat\FormElement обходится в настоящее время без CSS. */ if (df_asset_exists($path, $moduleName, 'less')) { $css[] = df_asset_name($path, $moduleName, 'css'); } /** * 2016-03-08 * Отныне getBeforeElementHtml() будет гарантированно вызываться благодаря * @used-by \Df\Framework\Plugin\Data\Form\Element\AbstractElement::afterGetElementHtml() */ $e['before_element_html'] .= df_cc_n(!df_asset_exists($path, $moduleName, 'js') ? null : df_x_magento_init($moduleName, $path, ['id' => $e->getHtmlId()] + df_clean($params)), df_link_inline($css)); }
/** @return string */ private function renderItems() { return df_cc_n(array_map([$this, 'renderItem'], $this->getItems())); }