Esempio n. 1
0
 /**
 * 2015-11-28
 		{
 			domain: "usageLimits",
 			reason: "accessNotConfigured",
 			message: "Access Not Configured. The API (Google Fonts Developer API) is not enabled for your project. Please use the Google Developers Console to update your configuration.",
 			extendedHelp: "https://console.developers.google.com"
 		}
 * @return array(string => string)
 */
 private function firstError()
 {
     if (!isset($this->{__METHOD__})) {
         $this->{__METHOD__} = df_first($this['errors']);
     }
     return $this->{__METHOD__};
 }
Esempio n. 2
0
 /**
  * 2016-09-04
  * @override
  * @see \Df\Framework\Form\Element\Select::getValue()
  * @used-by \Df\Framework\Form\Element\Select2::setRenderer()
  * @return string|null
  */
 public function getValue()
 {
     /** @var string|null $result */
     $result = parent::getValue();
     /** @var string[] $filter */
     $filter = $this->filter();
     return $filter && (!$result || !in_array($result, $filter)) ? df_first($filter) : ($result ?: self::$ORDER);
 }
Esempio n. 3
0
 /**
  * 2015-10-10
  * @param string $name
  * @param string $label
  * @return void
  */
 protected final function attribute($name, $label)
 {
     /** @var int $ordering */
     static $ordering = 1000;
     df_eav_setup()->addAttribute('customer', $name, ['type' => 'static', 'label' => "{$this->labelPrefix()} {$label}", 'input' => 'text', 'sort_order' => $ordering, 'position' => $ordering++, 'visible' => false, 'system' => false, 'required' => false]);
     /** @var int $attributeId */
     $attributeId = df_first(df_fetch_col('eav_attribute', 'attribute_id', 'attribute_code', $name));
     df_conn()->insert(df_table('customer_form_attribute'), ['form_code' => 'adminhtml_customer', 'attribute_id' => $attributeId]);
 }
Esempio n. 4
0
 /**
  * 2016-05-13
  * Наша проблема заключается в том, что Magento передаёт флаг $isMultiselect = true
  * только для элементов типа multiselect:
  * How is the isMultiselect parameter passed
  * to the toOptionArray method of @see \Magento\Framework\Data\OptionSourceInterface?
  * https://mage2.pro/t/1613
  * Наш же элемент управления имеет другой тип: type='Df\Framework\Form\Element\Multiselect'
  * https://code.dmitry-fedyuk.com/m2e/stripe/blob/b105882/etc/adminhtml/system.xml#L250
  * Получается, что флаг $isMultiselect имеет значение false,
  * и тогда метод @see \Magento\Directory\Model\Config\Source\Country::toOptionArray()
  * и другие аналогичные методы добавляют фэйковую опцию «--Please Select--».
  * Нам она не нужна, поэтому удаляем её здесь.
  *
  * @override
  * @see \Magento\Framework\DataObject::__call()
  * @used-by \Magento\Config\Block\System\Config\Form::_initElement()
  * https://github.com/magento/magento2/blob/ffea3cd/app/code/Magento/Config/Block/System/Config/Form.php#L375-L377
  * How are the options set to a select/multiselect form element? https://mage2.pro/t/1615
  * How is @see \Magento\Config\Model\Config\Structure\Element\Field::getOptions()
  * implemented and used? https://mage2.pro/t/1616
  * @param array $values
  */
 public function setValues(array $values)
 {
     /** @var array(string => string)|null $first */
     $first = df_first($values);
     /**
      * 2016-05-13
      * @see \Magento\Directory\Model\Config\Source\Country::toOptionArray()
      * https://github.com/magento/magento2/blob/ffea3cd/app/code/Magento/Directory/Model/Config/Source/Country.php#L51-L51
      */
     if ($first && (string) __('--Please Select--') === (string) dfa($first, 'label')) {
         array_shift($values);
     }
     $this['values'] = $values;
 }
Esempio n. 5
0
 /**
  * 2015-09-27
  * Цель метода — получение информации о формировании в данный момент заголовка страницы.
  * @uses \Magento\Framework\View\Page\Title::get()
  * @param Sb $sb
  * @param \Closure $proceed
  * @return string
  */
 public function aroundGet(Sb $sb, \Closure $proceed)
 {
     df_state()->renderingTitle(true);
     try {
         $result = $proceed();
         /**
          * Делаем браузерные заголовки административной части
          * более короткими и понятными: оставляем лишь первую и последнюю части заголовка.
          */
         if (df_is_backend()) {
             /** @var string[] $resultA */
             $resultA = explode(Sb::TITLE_GLUE, $result);
             $result = 3 > count($resultA) ? $result : implode(Sb::TITLE_GLUE, [df_first($resultA), df_last($resultA)]);
         }
     } finally {
         df_state()->renderingTitle(false);
     }
     return $result;
 }
Esempio n. 6
0
 /**
  * 2016-07-30
  * @override
  * @see \Df\Framework\Form\Element\Text::onFormInitialized()
  * @used-by \Df\Framework\Plugin\Data\Form\Element\AbstractElement::afterSetForm()
  * @return void
  */
 public function onFormInitialized()
 {
     parent::onFormInitialized();
     $this->addClass('df-quantity');
     /** @var string|null|Phrase $title */
     $title = $this->getTitle();
     $this->unsTitle();
     /** @var Text|E $input */
     $input = $this->text('value', $this->getLabel(), ['title' => $title]);
     $this->unsLabel();
     /** @var array(int|string => string)|string $values */
     $values = dfa($this->_data, self::P__VALUES, []);
     if (is_string($values)) {
         $values = [$values];
     }
     $this->unsetData(self::P__VALUES);
     if (1 < count($values)) {
         $this->select('units', null, $values, ['title' => $title]);
     } else {
         $input->setAfterElementHtml(df_first($values));
     }
     df_fe_init($this, __CLASS__);
 }
Esempio n. 7
0
 /**
  * @param string $name
  * @return Entity|null
  */
 public function findByName($name)
 {
     $this->getItems();
     return df_first($this->findByNameAll($name));
 }
Esempio n. 8
0
File: O.php Progetto: mage2pro/core
 /**
  * @param string $key
  * @param \\Zend_Validate_Interface|\Df\Zf\Validate\Type|string|mixed[] $validator
  * @param bool|null $isRequired [optional]
  * @throws \Df\Core\Exception
  * @return $this
  */
 protected function _prop($key, $validator, $isRequired = null)
 {
     /**
     * Полезная проверка!
     * Как-то раз ошибочно описал поле без значения:
     			private static $P__TYPE;
     * И при вызове $this->_prop(self::$P__TYPE, DF_V_STRING_NE)
     * получил диагностическое сообщение: «значение «» недопустимо для свойства «».»
     */
     df_param_string_not_empty($key, 0);
     /**
      * Обратите внимание, что если метод @see _prop() был вызван с двумя параметрами,
      * то и count($arguments) вернёт 2,
      * хотя в методе @see _prop() всегда доступен и 3-х параметр: $isRequired.
      * Другими словами, @see func_get_args() не возвращает параметры по умолчанию,
      * если они не были реально указаны при вызове текущего метода.
      */
     /**
      * Хотя документация к PHP говорит,
      * что @uses func_num_args() быть параметром других функций лишь с версии 5.3 PHP,
      * однако на самом деле @uses func_num_args() быть параметром других функций
      * в любых версиях PHP 5 и даже PHP 4.
      * http://3v4l.org/HKFP7
      * http://php.net/manual/function.func-num-args.php
      */
     if (2 < func_num_args()) {
         /** @var mixed[] $arguments */
         $arguments = func_get_args();
         $isRequired = df_last($arguments);
         /** @var bool $hasRequiredFlag */
         $hasRequiredFlag = is_bool($isRequired) || is_null($isRequired);
         if ($hasRequiredFlag) {
             $validator = array_slice($arguments, 1, -1);
         } else {
             $isRequired = null;
             $validator = df_tail($arguments);
         }
     }
     /** @var \Zend_Validate_Interface[] $additionalValidators */
     $additionalValidators = [];
     /** @var \Zend_Filter_Interface[] $additionalFilters */
     $additionalFilters = [];
     if (!is_array($validator)) {
         $validator = Validator::resolveForProperty($this, $validator, $key, $skipOnNull = false === $isRequired);
         df_assert($validator instanceof \Zend_Validate_Interface);
     } else {
         /** @var array(\Zend_Validate_Interface|Df_Zf_Validate_Type|string) $additionalValidatorsRaw */
         $additionalValidatorsRaw = df_tail($validator);
         $validator = Validator::resolveForProperty($this, df_first($validator), $key, $skipOnNull = false === $isRequired);
         df_assert($validator instanceof \Zend_Validate_Interface);
         foreach ($additionalValidatorsRaw as $additionalValidatorRaw) {
             /** @var \Zend_Validate_Interface|\Zend_Filter_Interface|string $additionalValidatorsRaw */
             /** @var \Zend_Validate_Interface|\Zend_Filter_Interface $additionalValidator */
             $additionalValidator = Validator::resolveForProperty($this, $additionalValidatorRaw, $key);
             if ($additionalValidator instanceof \Zend_Validate_Interface) {
                 $additionalValidators[] = $additionalValidator;
             }
             if ($additionalValidator instanceof \Zend_Filter_Interface) {
                 $additionalFilters[] = $additionalValidator;
             }
         }
     }
     $this->_validators[$key][] = $validator;
     if ($validator instanceof \Zend_Filter_Interface) {
         /** @var \Zend_Filter_Interface $filter */
         $filter = $validator;
         $this->_addFilter($key, $filter);
     }
     foreach ($additionalFilters as $additionalFilter) {
         /** @var \Zend_Filter_Interface $additionalFilter */
         $this->_addFilter($key, $additionalFilter);
     }
     /**
      * Раньше мы проводили валидацию лишь при извлечении значения свойства,
      * в методе @see getData().
      * Однако затем мы сделали улучшение:
      * перенести валидацию на более раннюю стадию — инициализацию свойства @see setData(),
      * и инициализацию валидатора/фильтра @see _prop().
      * Это улучшило диагностику случаев установки объекту некорректных значений свойств,
      * потому что теперь мы возбуждаем исключительную ситуацию
      * сразу при попытке установки некорректного значения.
      * А раньше, когда мы проводили валидацию лишь при извлечении значения свойства,
      * то при диагностике было не вполне понятно,
      * когда конкретно объекту было присвоено некорректное значение свойства.
      */
     /** @var bool $hasValueVorTheKey */
     $hasValueVorTheKey = array_key_exists($key, $this->_data);
     if ($hasValueVorTheKey) {
         Validator::checkProperty($this, $key, $this->_data[$key], $validator);
     }
     foreach ($additionalValidators as $additionalValidator) {
         /** @var \Zend_Validate_Interface $additionalValidator */
         $this->_validators[$key][] = $additionalValidator;
         if ($hasValueVorTheKey) {
             Validator::checkProperty($this, $key, $this->_data[$key], $additionalValidator);
         }
     }
     return $this;
 }
Esempio n. 9
0
File: db.php Progetto: mage2pro/core
/**
 * 2015-08-23
 * Обратите внимание, что метод
 * @see Varien_Db_Adapter_Pdo_Mysql::getPrimaryKeyName()
 * возвращает не название колонки, а слово «PRIMARY»,
 * поэтому он нам не подходит.
 * @used-by Df_Localization_Onetime_Dictionary_Db_Table::primaryKey()
 * @param string $table
 * @return string|null
 */
function df_primary_key($table)
{
    return dfcf(function ($table) {
        return df_first(df_nta(dfa_deep(df_conn()->getIndexList($table), 'PRIMARY/COLUMNS_LIST')));
    }, func_get_args());
}
Esempio n. 10
0
 /**
 * 2016-08-24
 * Несмотря на то, что опция @see \Df\Payment\Settings::askForBillingAddress()
 * стала общей для всех моих платёжных модулей,
 * платёжный адрес у заказа всегда присутствует,
 * просто при askForBillingAddress = false платёжный адрес является вырожденным:
 * он содержит только email покупателя.
 *
 * Только что проверил, как метод работает для анонимных покупателей.
 * Оказывается, если аноничный покупатель при оформлении заказа указал адреса,
 * то эти адреса в данном методе уже будут доступны как посредством
 * @see \Magento\Sales\Model\Order::getAddresses()
 * так и, соответственно, посредством @uses \Magento\Sales\Model\Order::getBillingAddress()
 * и @uses \Magento\Sales\Model\Order::getShippingAddress()
 * Так происходит в связи с особенностью реализации метода
 * @see \Magento\Sales\Model\Order::getAddresses()
 * https://github.com/magento/magento2/blob/2.1.0/app/code/Magento/Sales/Model/Order.php#L1957-L1969
 			if ($this->getData('addresses') == null) {
 				$this->setData('addresses', $this->getAddressesCollection()->getItems());
 			}
 			return $this->getData('addresses');
 * Как видно, метод необязательно получает адреса из базы данных:
 * для анонимных покупателей (или ранее покупавших, но указавшим в этот раз новый адрес),
 * адреса берутся из поля «addresses».
 * А содержимое этого поля устанавливается методом @see \Magento\Sales\Model\Order::addAddress()
 * https://github.com/magento/magento2/blob/2.1.0/app/code/Magento/Sales/Model/Order.php#L1238-L1250
 *
 * @param bool $bs
 * @return OA
 */
 private function addressMixed($bs)
 {
     return dfc($this, function ($bs) {
         /** @var OA[] $aa */
         $aa = df_clean([$this->addressB(), $this->addressS()]);
         $aa = $bs ? $aa : array_reverse($aa);
         /** @var OA $result */
         $result = df_create(OA::class, df_clean(df_first($aa)->getData()) + df_last($aa)->getData());
         /**
          * 2016-08-24
          * Сам класс @see \Magento\Sales\Model\Order\Address никак order не использует.
          * Однако пользователи класса могут ожидать работоспособность метода
          * @see \Magento\Sales\Model\Order\Address::getOrder()
          * В частности, этого ожидает метод @see \Dfe\TwoCheckout\Address::build()
          */
         $result->setOrder($this->o());
         return $result;
     }, func_get_args());
 }
Esempio n. 11
0
/**
 * 2016-08-08
 * @used-by \Df\Payment\Charge::iia()
 * @used-by \Df\Payment\Method::iia()
 * @param II|OP|QP $payment
 * @param string|string[]|null $keys  [optional]
 * @return mixed|array(string => mixed)
 */
function dfp_iia(II $payment, $keys = null)
{
    /** @var mixed|array(string => mixed) $result */
    if (is_null($keys)) {
        $result = $payment->getAdditionalInformation();
    } else {
        if (!is_array($keys)) {
            $keys = df_tail(func_get_args());
        }
        $result = 1 === count($keys) ? $payment->getAdditionalInformation(df_first($keys)) : dfa_select_ordered($payment->getAdditionalInformation(), $keys);
    }
    return $result;
}
Esempio n. 12
0
/**
 * 2015-12-28
 * Преобразует при необходимости простой одномерный массив в список опций.
 * @param string[] $values
 * @return array(array(string => string|int))
 */
function df_a_to_options(array $values)
{
    /** @var mixed $first */
    $first = df_first($values);
    return is_null($first) || isset($first['value']) ? $values : df_map_to_options(dfa_combine_self($values));
}
Esempio n. 13
0
/**
 * @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;
}
Esempio n. 14
0
/**
 * Возвращает неиспользуемое имя файла в заданной папке $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);
}
Esempio n. 15
0
 /**
  * 2016-05-21
  * @param string[] ...$keys
  * @return mixed|array(string => mixed)
  */
 protected function iia(...$keys)
 {
     return !$keys ? $this->ii()->getAdditionalInformation() : (1 === count($keys) ? $this->ii()->getAdditionalInformation(df_first($keys)) : dfa_select_ordered($this->ii()->getAdditionalInformation(), $keys));
 }
Esempio n. 16
0
 /** @return string */
 private function family()
 {
     return df_first($this->familyA());
 }
Esempio n. 17
0
 /** @return string */
 public function family()
 {
     return df_first($this->familyA());
 }
Esempio n. 18
0
/**
 * 2016-01-01
 * 2016-10-20
 * Нельзя делать параметр $c опциональным, потому что иначе получим сбой:
 * «get_class() called without object from outside a class»
 * https://3v4l.org/k6Hd5
 * @param string|object $c
 * @return string
 */
function df_class_first($c)
{
    return df_first(df_explode_class($c));
}