/** * 2016-07-18 * 2016-10-28 * Добавил дополнительный уровень кэширования: в оперативной памяти. * Также позволил в качестве $key передавать массив. * * 2016-11-01 * При вызове @see df_cache_get_simple синтаксис use для параметра $f использовать безопасно, * в отличие от @see dfc() и @see dfcf(), потому что ключ кэширования передаётся параметром $key. * * @param string|string[] $key * @param callable $f * @param mixed[] ...$arguments [optional] * @return mixed */ function df_cache_get_simple($key, callable $f, ...$arguments) { return dfcf(function ($key) use($f, $arguments) { /** @var string|bool $resultS */ $resultS = df_cache_load($key); /** @var mixed $result */ $result = null; if (false !== $resultS) { /** @var array(string => mixed) $result */ $result = df_unserialize_simple($resultS); } /** * 2016-10-28 * json_encode(null) возвращает строку 'null', * а json_decode('null') возвращает null. * Поэтому если $resultS равно строке 'null', * то нам не надо вызывать функцию: она уже вызывалась, * и (кэшированным) результатом этого вызова было значение null. */ if (null === $result && 'null' !== $resultS) { $result = call_user_func_array($f, $arguments); df_cache_save(df_serialize_simple($result), $key); } return $result; }, [!is_array($key) ? $key : dfa_hashm($key)]); }
/** * 2016-07-28 * @see dfp_by_trans() * @param OP|int $payment * @param string $type * @return T|null */ function df_trans_by_payment($payment, $type) { return dfcf(function ($paymentId, $type) { /** @var \Magento\Framework\DB\Select $select */ $select = df_db_from('sales_payment_transaction', 'transaction_id'); $select->where('? = payment_id', $paymentId); /** * 2016-08-17 * Раньше здесь стояло условие * $select->where('parent_txn_id IS NULL'); * потому что код использовался только для получения первой (родительской) транзакции. * Убрал это условие, потому что даже для первой транзакции оно не нужно: * ниже ведь используется операция order, и транзакция с минимальным идентификатором * и будет родительской. * Для функции же @used-by df_trans_by_payment_last() условие * $select->where('parent_txn_id IS NULL'); * и вовсе ошибочно: оно отбраковывает все дочерние транзакции. */ /** * 2016-07-28 * Раньше стояла проверка: df_assert_eq(1, count($txnIds)); * Однако при разработке платёжных модулей бывает, * что у первых транзакций данные не всегда корректны. * Негоже из-за этого падать, лучше вернуть просто первую транзакцию, как нас и просят. */ $select->order('transaction_id ' . ('first' === $type ? 'asc' : 'desc')); /** @var int $id */ $id = df_conn()->fetchOne($select, 'transaction_id'); return !$id ? null : df_trans_r()->get($id); }, [df_idn($payment), $type]); }
/** * 2015-12-28 * @param string[] $filter [optional] * @param int|string|null|bool|StoreInterface $store [optional] * @return array(array(string => string)) */ function df_currencies_options(array $filter = [], $store = null) { return dfcf(function (array $filter = [], $store = null) { /** @var array(string => string) $all */ $all = df_currencies_ctn($store); return df_map_to_options(!$filter ? $all : dfa_select_ordered($all, $filter)); }, func_get_args()); }
/** @return string */ public static function init() { return dfcf(function () { /** @var string|null $appId */ $appId = S::s()->appId(); return !$appId ? '' : df_phtml(__CLASS__, 'init', ['appId' => $appId]); }); }
/** * 2016-01-26 * @param string $entityType * @param int|string|null|bool|StoreInterface $store [optional] * @return _Meta|Meta */ function df_sales_seq_meta($entityType, $store = null) { return dfcf(function ($entityType, $store = null) { /** @var RMeta $r */ $r = df_o(RMeta::class); /** * 2016-01-26 * По аналогии с @see \Magento\SalesSequence\Model\Manager::getSequence() * https://github.com/magento/magento2/blob/d50ee5/app/code/Magento/SalesSequence/Model/Manager.php#L48 */ return $r->loadByEntityTypeAndStore($entityType, df_store_id($store)); }, func_get_args()); }
/** * @param string $type * @return mixed */ function df_o($type) { return dfcf(function ($type) { return df_om()->get($type); }, func_get_args()); }
/** * 2016-05-05 * @param string $id * @return $this */ public static function sp($id) { return dfcf(function ($id) { return new self([self::$P__ID => $id]); }, func_get_args()); }
/** * 2016-11-23 * Для каждого класса кнопок система будет создавать несколько экземпляров: * для каждого из местоположений кнопки. * Поэтому кэшируем результат вызова @uses \Df\Config\Settings::convention() для класса * (но при этом используем static::class, чтобы разные классы имели разные значения кэша). * 2016-11-24 * Передаём static::class как аргумент, чтобы потомки этого класса имели индивидуальный кэш: * https://github.com/mage2pro/core/blob/ab34df/Core/lib/cache.php?ts=4#L151-L160 * @return \Df\Config\Settings */ private static function sModule() { return dfcf(function ($c) { return \Df\Config\Settings::convention($c); }, [static::class]); }
/** * 2016-09-05 * @used-by \Df\Payment\FormElement\Currency::v() * @param null|string|int|S|Store $store [optional] * @param CurrencyM|string|null $orderCurrency [optional] * @return array(string => CurrencyM|string|null) */ private static function map($store = null, $orderCurrency = null) { return dfcf(function ($store = null, $orderCurrency = null) { return [self::$BASE => df_currency_base($store), self::$ORDER => $orderCurrency ?: df_currency_current($store)]; }, func_get_args()); }
/** * 2016-05-20 * Возвращает страну по её 2-буквенному коду по стандарту ISO 3166-1 alpha-2. * https://ru.wikipedia.org/wiki/ISO_3166-1 * @param string $iso2 * @param bool $throw [optional] * @return C|null */ function df_country($iso2, $throw = true) { return dfcf(function ($iso2, $throw = true) { /** @var C|null $result */ $result = !df_check_iso2($iso2) ? null : df_countries()->getItemById($iso2); if ($result) { df_assert($result instanceof C); } else { if ($throw) { df_error('Не могу найти страну по 2-буквенному коду «%s».', $iso2); } } return $result; }, func_get_args()); }
/** * 2016-08-06 * 2016-09-04 * Используемая конструкция реально работает: https://3v4l.org/Qb0uZ * @used-by \Df\Payment\Method::getTitle() * @return string */ public static function titleBackendS() { return dfcf(function ($class) { return Settings::convention($class, 'title_backend', null, function () use($class) { return df_class_second($class); }); }, [static::class]); }
/** * 2016-05-20 * @param string|null $ip [optional] * @return $this */ public static function sp($ip = null) { return dfcf(function ($ip = null) { return new self([self::$P__IP => $ip ?: df_visitor_ip()]); }, func_get_args()); }
/** * 2016-07-19 * Портировал из Российской сборки Magento. * @param null|string|int|ScopeA|Store $scope [optional] * @return int[] */ function df_days_off($scope = null) { return dfcf(function ($scope = null) { return df_csv_parse_int(str_replace('0', '7', df_cfg('general/locale/weekend', $scope))); }, func_get_args()); }
/** * 2016-08-04 * 2016-11-25 * Отныне метод возвращает класс не обязательно из базовой папки (например, \Df\Sso\Settings), * а из папки с тем же окончанием, что и у вызываемого класса. * Например, \Df\Sso\Settings\Button::convention() будет искать класс в папке Settings\Button * модуля, к которому относится класс $c. * @param object|string $c * @param string $key [optional] * @param null|string|int|S $scope [optional] * @param mixed|callable $d [optional] * @return self */ public static function convention($c, $key = '', $scope = null, $d = null) { /** @var self $result */ /** * 2016-11-25 * Используем 2 уровня кэширования, и оба они важны: * 1) Кэширование self::s() приводит к тому, что вызов s() непосредственно для класса * возвращает тот же объект, что и вызов convention(). Это очень важно. * 2) Кэширование dfcf() позволяет нам не рассчитывать df_con_heir() * при каждом вызове convention(). */ $result = dfcf(function ($c, $def) { return self::s(df_con_heir($c, $def)); }, [df_cts($c), static::class]); return df_null_or_empty_string($key) ? $result : $result->v($key, $scope, $d); }
/** * 2015-12-29 * Метод реализован по аналогии с @see \Magento\Framework\View\Asset\File::getSourceFile(): * https://github.com/magento/magento2/blob/2.0.0/lib/internal/Magento/Framework/View/Asset/File.php#L147-L156 * @param string $name * Обратите внимание, что в качестве $name можно передавать: * 1) короткое имя; * 2) уже собранное посредством @see df_asset_name() полное имя ассета; * @param string|null $moduleName [optional] * @param string|null $extension [optional] * @return bool */ function df_asset_exists($name, $moduleName = null, $extension = null) { return dfcf(function ($name, $moduleName = null, $extension = null) { return !!df_asset_source()->findSource(df_asset_create(df_asset_name($name, $moduleName, $extension))); }, func_get_args()); }
/** * 2016-08-25 * @uses \Df\Payment\Method::codeS() * @param string|object $caller * @return string */ function dfp_method_code($caller) { return dfcf(function ($class) { return dfp_method_call_s($class, 'codeS'); }, [df_cts($caller)]); }
/** * 2016-03-15 * How to programmatically check whether a customer is new or returning? https://mage2.pro/t/1617 * @param int|null $id * @return bool */ function df_customer_is_new($id) { return dfcf(function ($id) { return !$id || !df_conn()->fetchOne(df_db_from('sales_order', 'COUNT(*)')->where('? = customer_id', $id)->where('state IN (?)', [O::STATE_COMPLETE, O::STATE_PROCESSING])); }, [$id]); }
/** @return bool */ function df_my_local() { return dfcf(function () { return df_my() && df_is_localhost(); }); }
/** * 2016-08-27 * @param string|object $module * @param string|null $scope [optional] * @return string */ function df_route($module, $scope = 'frontend') { return dfcf(function ($m, $s) { return df_route_config()->getRouteFrontName($m, $s); }, [df_module_name($module), $scope]); }
/** * @uses Mage_Core_Model_Resource::getTableName() не кэширует результаты своей работы, * и, глядя на реализацию @see Mage_Core_Model_Resource_Setup::getTable(), * которая выполняет кэширование для @see Mage_Core_Model_Resource::getTableName(), * я решил сделать аналогичную функцию, только доступную в произвольном контексте. * @param string|string[] $name * @return string */ function df_table($name) { return dfcf(function ($name) { return df_db_resource()->getTableName($name); }, func_get_args()); }
/** * 2016-08-28 * «Dfe\AllPay\Response» => «AllPay» * 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_module_name_short($c) { return dfcf(function ($c) { return df_explode_class($c)[1]; }, [df_cts($c)]); }