/** * Translates a path alias into an actual path. * * The translation is done according to the following procedure: * * 1. If the given alias does not start with '@', it is returned back without change; * 2. Otherwise, look for the longest registered alias that matches the beginning part * of the given alias. If it exists, replace the matching part of the given alias with * the corresponding registered path. * 3. Throw an exception or return false, depending on the `$throwException` parameter. * * For example, by default '@rock' is registered as the alias to the Rock framework directory, * say '/path/to/rock'. The alias '@rock/web' would then be translated into '/path/to/rock/web'. * * If you have registered two aliases '@foo' and '@foo/bar'. Then translating '@foo/bar/config' * would replace the part '@foo/bar' (instead of '@foo') with the corresponding registered path. * This is because the longest alias takes precedence. * * However, if the alias to be translated is '@foo/barbar/config', then '@foo' will be replaced * instead of '@foo/bar', because '/' serves as the boundary character. * * Note, this method does not check if the returned path exists or not. * * @param string $alias the alias to be translated. * @param array $placeholders * @param boolean $throwException whether to throw an exception if the given alias is invalid. * If this is false and an invalid alias is given, false will be returned by this method. * @throws \Exception if the alias is invalid while $throwException is true. * @return string|boolean the path corresponding to the alias, false if the root alias is not previously registered. * @see setAlias() */ public static function getAlias($alias, array $placeholders = [], $throwException = true) { if (strncmp($alias, '@', 1)) { // not an alias return $alias; } $delimiter = ObjectHelper::isNamespace($alias) ? '\\' : '/'; $pos = strpos($alias, $delimiter); $root = $pos === false ? $alias : substr($alias, 0, $pos); if (isset(static::$aliases[$root])) { if (is_string(static::$aliases[$root])) { $result = $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos); return StringHelper::replace($result, $placeholders, false); } else { foreach (static::$aliases[$root] as $name => $path) { if (strpos($alias . $delimiter, $name . $delimiter) === 0) { $result = $path . substr($alias, strlen($name)); return StringHelper::replace($result, $placeholders, false); } } } } if ($throwException) { throw new \Exception("Invalid path alias: {$alias}"); } else { return false; } }
public function get() { if (!isset($this->subject, $this->operands, $this->then) || empty($this->operands)) { return null; } $operands = $this->operands; $this->template->addMultiPlaceholders($this->template->findPlaceholders($this->addPlaceholders)); $paramsTpl = ['subject' => $this->subject, 'params' => $operands, 'then' => $this->then, 'template' => $this->template]; if (isset($this->else)) { $paramsTpl['else'] = $this->else; } $data = []; $this->subject = strip_tags($this->subject); foreach ($operands as $keyParam => $valueParam) { $valueParam = Helper::toType($valueParam); if (is_string($valueParam)) { $valueParam = addslashes($valueParam); } $data[$keyParam] = $valueParam; } $value = ' $template = $params[\'template\']; if (' . preg_replace('/:([\\w]+)/', '$data[\'$1\']', $this->subject) . ') { return $template->replace($params[\'then\']); }' . (isset($this->else) ? ' else {return $template->replace($params[\'else\']);}' : null); return $this->execute->get(StringHelper::removeSpaces($value), $paramsTpl, $data); }
protected function validateIdentical($input) { if (is_array($input)) { return end($input) === $this->params['endValue']; } return \rock\helpers\StringHelper::endsWith($input, $this->params['endValue'], true); }
protected function validateIdentical($input) { if (is_array($input)) { return in_array($this->params['containsValue'], $input, true); } return \rock\helpers\StringHelper::contains($input, $this->params['containsValue'], true); }
public function get() { if (!isset($this->subject) || empty($this->operands)) { return null; } $data = []; $this->subject = strip_tags($this->subject); foreach ($this->operands as $keyParam => $valueParam) { $valueParam = Helper::toType($valueParam); if (is_string($valueParam)) { $valueParam = addslashes($valueParam); } $data[$keyParam] = $valueParam; } return $this->execute->get(StringHelper::removeSpaces('return ' . preg_replace('/:([\\w]+)/', '$data[\'$1\']', $this->subject) . ';'), ['subject' => $this->subject, 'operands' => $this->operands], $data); }
/** * Display notPage layout * * @param string|null $layout * @param array $placeholders list placeholders * @return string|void */ public function notPage($layout = null, array $placeholders = []) { if (isset($this->response)) { $this->response->status404(); } $this->getTemplate()->title = StringHelper::upperFirst(i18n::t('notPage')); if (!isset($layout)) { $layout = '@common.views/layouts/notPage'; } return $this->render($layout, $placeholders); }
protected function isREST($url, $controller, $filters) { $handlers = ArrayHelper::only($this->RESTHandlers, Helper::getValue($filters['only'], []), Helper::getValue($filters['exclude'], [])); foreach ($handlers as $value) { if (!isset($value[3])) { $value[3] = null; } list($verbs, $pattern, $handler, $_filters) = $value; $filters = !empty($filters['filters']) ? $filters['filters'] : $_filters; if (StringHelper::isRegexp($pattern)) { $url = preg_quote($url, '/'); $pattern = "~{$pattern}"; } $pattern = str_replace('{url}', $url, $pattern); $this->params['controller'] = $controller; if ($this->isRoute($verbs, $pattern, $handler, $filters)) { $this->errors = 0; return true; } else { $this->errors |= $this->errors; } } return false; }
/** * Decodes special HTML entities back to the corresponding characters. * * @param string $value * @return string */ public static function decode($value) { return StringHelper::decode($value); }
/** * Replacing placeholders to URL-data. * @param array $placeholders * @return static */ public function replace(array $placeholders = []) { if (empty($placeholders)) { return $this; } $callback = function ($value) use($placeholders) { return StringHelper::replace($value, $placeholders, false); }; $this->data = ArrayHelper::map($this->data, $callback, true); return $this; }
/** * @inheritdoc */ public function sanitize($input) { return \rock\helpers\StringHelper::truncate($input, $this->length, $this->suffix); }
/** * @inheritdoc */ public function sanitize($input) { return is_string($input) ? \rock\helpers\StringHelper::encode($input, $this->doubleEncode) : $input; }
/** * @inheritdoc */ public function sanitize($input) { return is_string($input) ? \rock\helpers\StringHelper::upperFirst($input) : $input; }
/** * Converts an exception into a simple string. * * @param \Exception $exception the exception being converted * @param bool $asStack * @return string the string representation of the exception. */ public static function convertExceptionToString(\Exception $exception, $asStack = ROCK_DEBUG) { $trace = $exception->getTrace(); $placeholders = ['class' => isset($trace[0]['class']) ? $trace[0]['class'] : '', 'method' => isset($trace[0]['function']) ? $trace[0]['function'] : '', 'message' => $asStack ? $exception->getMessage() . ' ' . $exception->getTraceAsString() : $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()]; return StringHelper::replace(static::$format, $placeholders, false); }
private function prepareAliases(array $aliases) { foreach ($aliases as &$alias) { $placeholders = ['self_scheme' => $this->request->getScheme(), 'self_path' => $this->request->getUrlWithoutArgs()]; foreach ($this->request->rawGet() ?: [] as $name => $placeholder) { $placeholders["self_query_{$name}"] = $placeholder; } $alias = StringHelper::replace($alias, $placeholders, false); } return $aliases; }
/** * Adds a namespaces and aliases from constructor * * @param array $args namespaces and classes to use in the template */ public function addUses($args) { foreach ((array) $args as $key => $value) { $value = str_replace('/', '\\', $value); if (is_int($key)) { // namespace or class import if (class_exists($value)) { // class import $this->aliases[StringHelper::basename($value)] = $value; } else { // namespace $this->namespaces[] = $value; } } else { // aliased class import $this->aliases[$key] = $value; } } }
/** * @inheritdoc */ public function sanitize($input) { return is_string($input) ? \rock\helpers\StringHelper::replaceRandChars($input, $this->replaceTo) : $input; }
/** * Merge key with value * * @param array $array current array * @param string $separator separator * @param int $const constant * * - `ESCAPE` escape value quotes * * @return array */ public static function concatKeyValue(array $array, $separator = '=', $const = 0) { $result = []; foreach ($array as $key => $value) { $result[] = $key . (isset($value) && $value !== 'null' ? $separator . ($const & static::ESCAPE ? StringHelper::doubleQuotes($value) : $value) : null); } return $result; }
<?php /** @var $this \rock\template\Template */ use rock\helpers\StringHelper; use rock\widgets\Captcha; echo $this->getChunk('@frontend.views/sections/top'); ?> <main class="container main form-container" role="main" data-ng-controller="RockFormController"><?php echo $this->getSnippet('activeForm', ['model' => $this->getPlaceholder('$root.model', false), 'validate' => true, 'config' => ['action' => '@link.home/signup.html', 'validateOnChanged' => true, 'options' => ['class' => 'form-signup', 'novalidate' => 'novalidate'], 'fieldConfig' => ['template' => "{hint}\n{input}\n{error}"]], 'fields' => ['<h2>[[%signup:upperFirst]]</h2>', 'email' => ['options' => ['inputOptions' => ['class' => 'form-control form-input', 'maxlength' => 30, 'autofocus' => '', 'placeholder' => StringHelper::upperFirst(\rock\i18n\i18n::t('email')), 'data' => ['rock-reset-field-icon' => '']], 'required' => true]], 'username' => ['options' => ['inputOptions' => ['class' => 'form-control form-input', 'maxlength' => 80, 'placeholder' => StringHelper::upperFirst(\rock\i18n\i18n::t('username')), 'data' => ['rock-reset-field-icon' => '']]]], 'password' => ['options' => ['template' => "<div class='inline-column'>{hint}\n{input}<div class='strong-password' data-rock-password-strong='SignupForm.values.password'></div></div>\n{error}", 'inputOptions' => ['class' => 'form-control form-input', 'maxlength' => 20, 'value' => '', 'placeholder' => StringHelper::upperFirst(\rock\i18n\i18n::t('password')), 'data' => ['rock-reset-field-icon' => '']]], 'passwordInput'], 'password_confirm' => ['options' => ['inputOptions' => ['class' => 'form-control form-input', 'maxlength' => 20, 'value' => '', 'placeholder' => StringHelper::upperFirst(\rock\i18n\i18n::t('confirmPassword')), 'data' => ['rock-match' => 'password', 'rock-reset-field-icon' => '']]], 'passwordInput'], 'captcha' => ['options' => ['required' => true], 'widget' => [Captcha::className(), ['template' => '<div class="block-center">{image}</div>{input}', 'output' => Captcha::BASE64, 'options' => ['class' => 'form-control form-input', 'maxlength' => 7, 'value' => '', 'placeholder' => StringHelper::upperFirst(\rock\i18n\i18n::t('captcha'))]]]]], 'submitButton' => [\rock\i18n\i18n::t('signup'), ['class' => 'btn btn-primary', 'name' => 'signup-button']], 'wrapperTpl' => '@INLINE [[!+alerts:notEmpty&then=`@common.views\\elements\\alert-danger`]] [[!+output]]']); ?> </main> <script type="text/ng-template" id="form/strong-password"> <progressbar value="value" type="{{class}}"></progressbar> </script> <?php echo $this->getChunk('@frontend.views/sections/footer');
protected function translateInternal($keys, array $placeholders = []) { if (!isset(static::$data[$this->locale][$this->category])) { static::$data[$this->locale][$this->category] = []; } $result = ArrayHelper::getValue(static::$data[$this->locale][$this->category], $keys); if (!isset($result)) { if ($this->throwException) { $keys = is_array($keys) ? implode('][', $keys) : $keys; throw new i18nException(i18nException::UNKNOWN_I18N, ['name' => "{$this->category}[{$keys}]"]); } return null; } return StringHelper::replace($result, $placeholders, $this->removeBraces); }
/** * Performs string comparison using timing attack resistant approach. * @see http://codereview.stackexchange.com/questions/13512 * @param string $expected string to compare. * @param string $actual user-supplied string. * @return boolean whether strings are equal. */ public function compareString($expected, $actual) { $expected .= ""; $actual .= ""; $expectedLength = StringHelper::byteLength($expected); $actualLength = StringHelper::byteLength($actual); $diff = $expectedLength - $actualLength; for ($i = 0; $i < $actualLength; $i++) { $diff |= ord($actual[$i]) ^ ord($expected[$i % $expectedLength]); } return $diff === 0; }
/** * @inheritdoc */ public function sanitize($input) { return is_string($input) ? \rock\helpers\StringHelper::rtrimWords($input, $this->words) : $input; }
/** * Converts a array into a string representation. * * For example, * * ```php * print_r(Html::fromArray(['width' => '100px', 'height' => '200px'])); * // will display: 'width=100px; height=200px;' * ``` * * @param array $data list data * @return string */ public static function fromArray(array $data) { $result = ''; foreach ($data as $name => $value) { $value = StringHelper::toString($value, "'", Serialize::SERIALIZE_JSON); $result .= "{$name}={$value}; "; } return $result === '' ? null : rtrim($result); }
protected function defaultFormatOptions() { return ['F' => function (DateTime $datetime) { return $datetime->getLocale()->getMonth($datetime->format('n') - 1); }, 'M' => function (DateTime $datetime) { return $datetime->getLocale()->getShortMonth($datetime->format('n') - 1); }, 'l' => function (DateTime $datetime) { return $datetime->getLocale()->getWeekDay($datetime->format('N') - 1); }, 'D' => function (DateTime $datetime) { return $datetime->getLocale()->getShortWeekDay($datetime->format('N') - 1); }, 'ago' => function (DateTime $datetime) { $diff = $datetime->diff(new DateTime()); $locale = $datetime->getLocale(); if ($diff->y >= 1) { $number = $diff->y; $names = $locale->getYearNames(); } elseif ($diff->total_months >= 1) { $number = $diff->total_months; $names = $locale->getMonthNames(); } elseif ($diff->total_days >= 7) { $number = $diff->total_weeks; $names = $locale->getWeekNames(); } elseif ($diff->total_days >= 1) { $number = $diff->total_days; $names = $locale->getDayNames(); } elseif ($diff->total_hours >= 1) { $number = $diff->total_hours; $names = $locale->getHourNames(); } elseif ($diff->total_minutes >= 1) { $number = $diff->total_minutes; $names = $locale->getMinuteNames(); } else { $number = $diff->total_seconds; $names = $locale->getSecondNames(); } $options = $locale->getOptions(); if (isset($options['ago'])) { return StringHelper::replace($options['ago'], ['number' => $number, 'name' => Inflector::plural($number, $names)]); } return $number . ' ' . Inflector::plural($number, $names) . ' ago'; }]; }
/** * Adds a log record at the `EMERGENCY` level. * * This method allows for compatibility with common interfaces. * * @param string $message log message * @param array $placeholders placeholders for replacement * @return bool Whether the record has been processed */ protected function emergInternal($message, array $placeholders = []) { return $this->logger->emerg(StringHelper::replace($message, $placeholders, false), $placeholders); }
/** * Check path to view. * @param string $path path to view. * @return bool */ protected function checkPath($path) { foreach ($this->chroots as $chroot) { if (StringHelper::contains($path, $chroot)) { return true; } } return false; }
protected function replace($message) { if (empty($this->placeholders)) { return $message; } return StringHelper::replace($message, $this->placeholders); }
/** * Sends the specified content as a file to the browser. * * Note that this method only prepares the response for file sending. The file is not sent * until {@see \rock\response\Response::send()} is called explicitly or implicitly. The latter is done after you return from a controller action. * * @param string $content the content to be sent. * The existing {@see \rock\response\Response::$content} will be discarded. * @param string $attachmentName the file name shown to the user. * @param array $options additional options for sending the file. The following options are supported: * * - `mimeType`: the MIME type of the content. Defaults to 'application/octet-stream'. * - `inline`: boolean, whether the browser should open the file within the browser window. Defaults to false, * meaning a download dialog will pop up. * * @return static the response object itself * @throws ResponseException if the requested range is not satisfiable */ public function sendContentAsFile($content, $attachmentName, $options = []) { $headers = $this->getHeaders(); $contentLength = StringHelper::byteLength($content); $range = $this->getHttpRange($contentLength); if ($range === false) { $headers->set('Content-Range', "bytes */{$contentLength}"); throw new ResponseException('Requested range not satisfiable'); } $mimeType = isset($options['mimeType']) ? $options['mimeType'] : 'application/octet-stream'; $this->setDownloadHeaders($attachmentName, $mimeType, !empty($options['inline']), $contentLength); list($begin, $end) = $range; if ($begin != 0 || $end != $contentLength - 1) { $this->setStatusCode(206); $headers->set('Content-Range', "bytes {$begin}-{$end}/{$contentLength}"); $this->content = StringHelper::byteSubstr($content, $begin, $end - $begin + 1); } else { $this->setStatusCode(200); $this->content = $content; } $this->format = self::FORMAT_RAW; return $this; }
protected function searchByPattern($pattern, $error = true, $is = self::TYPE_FILE) { foreach (parent::listContents('', true) as $data) { if (isset($is) && $data['type'] !== $is) { continue; } if (preg_match($pattern, $data['path'])) { return $data['path']; } } if ($error === true) { $this->errors[] = StringHelper::replace(FileException::UNKNOWN_FILE, ['path' => $pattern]); } return null; }