/** * 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); }
/** * @param string $path * @param callable $castFunction * @param string $castName * @param bool $throw [optional] * @return mixed|null */ private function descendWithCast($path, callable $castFunction, $castName, $throw = false) { /** @var string|null $resultAsText */ $resultAsText = $this->descendS($path, $throw); /** @var mixed|null $result */ if (!df_null_or_empty_string($resultAsText)) { $result = call_user_func($castFunction, $resultAsText); } else { if ($throw) { df_error('В документе XML по пути «%s» требуется %s число, однако там пусто.', $castName, $path); } else { $result = null; } } return $result; }