/** * Limits HTML with specific length with a proper tag handling. * @param string $html HTML string to limit * @param int $maxLength String length to truncate at * @param string $end * @return string */ public static function limit($html, $maxLength = 100, $end = '...') { $printedLength = 0; $position = 0; $tags = []; $re = '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\\x80-\\xFF][\\x80-\\xBF]*}'; $result = ''; while ($printedLength < $maxLength && preg_match($re, $html, $match, PREG_OFFSET_CAPTURE, $position)) { list($tag, $tagPosition) = $match[0]; $str = mb_substr($html, $position, $tagPosition - $position); if ($printedLength + StrHelper::length($str) > $maxLength) { $result .= mb_substr($str, 0, $maxLength - $printedLength) . $end; $printedLength = $maxLength; break; } $result .= $str; $printedLength += StrHelper::length($str); if ($printedLength >= $maxLength) { $result .= $end; break; } if ($tag[0] == '&' || ord($tag) >= 0x80) { $result .= $tag; $printedLength++; } else { $tagName = $match[1][0]; if ($tag[1] == '/') { $openingTag = array_pop($tags); $result .= $tag; } else { if ($tag[StrHelper::length($tag) - 2] == '/') { $result .= $tag; } else { $result .= $tag; $tags[] = $tagName; } } } $position = $tagPosition + StrHelper::length($tag); } if ($printedLength < $maxLength && $position < StrHelper::length($html)) { $result .= substr($html, $position, $maxLength - $printedLength); } while (!empty($tags)) { $result .= sprintf('</%s>', array_pop($tags)); } return $result; }
/** * Prepare variables for stubs. * * return @array */ protected function prepareVars() { $pluginCode = $this->argument('plugin'); $parts = explode('.', $pluginCode); $plugin = array_pop($parts); $author = array_pop($parts); $controller = $this->argument('controller'); /* * Determine the model name to use, * either supplied or singular from the controller name. */ $model = $this->option('model'); if (!$model) { $model = Str::singular($controller); } return ['name' => $controller, 'model' => $model, 'author' => $author, 'plugin' => $plugin]; }
/** * Sets a single slug attribute value. * @param string $slugAttribute Attribute to populate with the slug. * @param mixed $sourceAttributes Attribute(s) to generate the slug from. * Supports dotted notation for relations. * @param int $maxLength Maximum length for the slug not including the counter. * @return string The generated value. */ public function setSluggedValue($slugAttribute, $sourceAttributes, $maxLength = 240) { if (!isset($this->{$slugAttribute}) || !strlen($this->{$slugAttribute})) { if (!is_array($sourceAttributes)) { $sourceAttributes = [$sourceAttributes]; } $slugArr = []; foreach ($sourceAttributes as $attribute) { $slugArr[] = $this->getSluggableSourceAttributeValue($attribute); } $slug = implode(' ', $slugArr); $slug = substr($slug, 0, $maxLength); $slug = Str::slug($slug, $this->getSluggableSeparator()); } else { $slug = $this->{$slugAttribute}; } return $this->{$slugAttribute} = $this->getSluggableUniqueAttributeValue($slugAttribute, $slug); }
/** * Execute the console command. */ public function fire() { /* * Extract the author and name from the plugin code */ $pluginCode = $this->argument('pluginCode'); $parts = explode('.', $pluginCode); $pluginName = array_pop($parts); $authorName = array_pop($parts); $destinationPath = base_path() . '/plugins/' . strtolower($authorName) . '/' . strtolower($pluginName); $controllerName = $this->argument('controllerName'); /* * Determine the model name to use, * either supplied or singular from the controller name. */ $modelName = $this->option('model'); if (!$modelName) { $modelName = Str::singular($controllerName); } $vars = ['name' => $controllerName, 'model' => $modelName, 'author' => $authorName, 'plugin' => $pluginName]; Controller::make($destinationPath, $vars, $this->option('force')); $this->info(sprintf('Successfully generated Controller and views for "%s"', $controllerName)); }
public function testEvalHtmlArray() { $result = Str::evalHtmlArray('field'); $this->assertInternalType('array', $result); $this->assertEquals(1, count($result)); $this->assertTrue(in_array('field', $result)); $result = Str::evalHtmlArray('field[key1]'); $this->assertInternalType('array', $result); $this->assertEquals(2, count($result)); $this->assertTrue(in_array('field', $result)); $this->assertTrue(in_array('key1', $result)); $result = Str::evalHtmlArray('field[][key1]'); $this->assertInternalType('array', $result); $this->assertEquals(2, count($result)); $this->assertTrue(in_array('field', $result)); $this->assertTrue(in_array('key1', $result)); $result = Str::evalHtmlArray('field[key1][key2][key3]'); $this->assertInternalType('array', $result); $this->assertEquals(4, count($result)); $this->assertTrue(in_array('field', $result)); $this->assertTrue(in_array('key1', $result)); $this->assertTrue(in_array('key2', $result)); $this->assertTrue(in_array('key3', $result)); }
/** * Builds and caches a menu item tree. * This method is used internally for menu items and breadcrumbs. * @param \Cms\Classes\Theme $theme Specifies the current theme. * @return array Returns an array containing the page information */ public static function buildMenuTree($theme) { if (self::$menuTreeCache !== null) { return self::$menuTreeCache; } $key = crc32($theme->getPath()) . 'static-page-menu-tree'; $cached = Cache::get($key, false); $unserialized = $cached ? @unserialize($cached) : false; if ($unserialized !== false) { return self::$menuTreeCache = $unserialized; } $menuTree = ['--root-pages--' => []]; $iterator = function ($items, $parent, $level) use(&$menuTree, &$iterator) { $result = []; foreach ($items as $item) { $viewBag = $item->page->getViewBag(); $pageCode = $item->page->getBaseFileName(); $itemData = ['url' => Str::lower(RouterHelper::normalizeUrl($viewBag->property('url'))), 'title' => $viewBag->property('title'), 'mtime' => $item->page->mtime, 'items' => $iterator($item->subpages, $pageCode, $level + 1), 'parent' => $parent, 'navigation_hidden' => $viewBag->property('navigation_hidden')]; if ($level == 0) { $menuTree['--root-pages--'][] = $pageCode; } $result[] = $pageCode; $menuTree[$pageCode] = $itemData; } return $result; }; $pageList = new PageList($theme); $iterator($pageList->getPageTree(), null, 0); self::$menuTreeCache = $menuTree; Cache::put($key, serialize($menuTree), Config::get('cms.parsedPageCacheTTL', 10)); return self::$menuTreeCache; }
/** * Set current object url. * * @param string $pageName * @param Controller $controller */ public function setUrl($pageName, Controller $controller) { $params = ['event_id' => $this->id . '-' . Str::slug($this->name)]; return $this->url = $controller->pageUrl($pageName, $params); }
/** * Returns the menu item references. * This function is used on the front-end. * @param Cms\Classes\Page $page The current page object. * @return array Returns an array of the \RainLab\Pages\Classes\MenuItemReference objects. */ public function generateReferences($page) { $currentUrl = Request::path(); if (!strlen($currentUrl)) { $currentUrl = '/'; } $currentUrl = Str::lower(URL::to($currentUrl)); $activeMenuItem = $page->activeMenuItem ?: false; $iterator = function ($items) use($currentUrl, &$iterator, $activeMenuItem) { $result = []; foreach ($items as $item) { $parentReference = new MenuItemReference(); $parentReference->title = $item->title; $parentReference->code = $item->code; $parentReference->viewBag = $item->viewBag; /* * If the item type is URL, assign the reference the item's URL and compare the current URL with the item URL * to determine whether the item is active. */ if ($item->type == 'url') { $parentReference->url = $item->url; $parentReference->isActive = $currentUrl == Str::lower($item->url) || $activeMenuItem === $item->code; } else { /* * If the item type is not URL, use the API to request the item type's provider to * return the item URL, subitems and determine whether the item is active. */ $apiResult = Event::fire('pages.menuitem.resolveItem', [$item->type, $item, $currentUrl, $this->theme]); if (is_array($apiResult)) { foreach ($apiResult as $itemInfo) { if (!is_array($itemInfo)) { continue; } if (!$item->replace && isset($itemInfo['url'])) { $parentReference->url = $itemInfo['url']; $parentReference->isActive = $itemInfo['isActive'] || $activeMenuItem === $item->code; } if (isset($itemInfo['items'])) { $itemIterator = function ($items) use(&$itemIterator, $parentReference) { $result = []; foreach ($items as $item) { $reference = new MenuItemReference(); $reference->title = isset($item['title']) ? $item['title'] : '--no title--'; $reference->url = isset($item['url']) ? $item['url'] : '#'; $reference->isActive = isset($item['isActive']) ? $item['isActive'] : false; if (!strlen($parentReference->url)) { $parentReference->url = $reference->url; $parentReference->isActive = $reference->isActive; } if (isset($item['items'])) { $reference->items = $itemIterator($item['items']); } $result[] = $reference; } return $result; }; $parentReference->items = $itemIterator($itemInfo['items']); } } } } if ($item->items) { $parentReference->items = $iterator($item->items); } if (!$item->replace) { $result[] = $parentReference; } else { foreach ($parentReference->items as $subItem) { $result[] = $subItem; } } } return $result; }; $items = $iterator($this->items); /* * Populate the isChildActive property */ $hasActiveChild = function ($items) use(&$hasActiveChild) { foreach ($items as $item) { if ($item->isActive) { return true; } $result = $hasActiveChild($item->items); if ($result) { return $result; } } }; $iterator = function ($items) use(&$iterator, &$hasActiveChild) { foreach ($items as $item) { $item->isChildActive = $hasActiveChild($item->items); $iterator($item->items); } }; $iterator($items); return $items; }
/** * Determine if a set mutator exists for an attribute. * @param string $key * @return bool */ public function hasSetMutator($key) { return $this->methodExists('set' . Str::studly($key) . 'Attribute'); }
/** * Internal helper that handles modify a string, with extra logic. * * @param string|array $type * @param string $string * @return string */ protected function modifyString($type, $string) { if (is_array($type)) { foreach ($type as $_type) { $string = $this->modifyString($_type, $string); } return $string; } if ($type == 'title') { $string = str_replace('_', ' ', Str::snake($string)); } return Str::$type($string); }
/** * Loads the URL map - a list of page file names and corresponding URL patterns. * The URL map can is cached. The clearUrlMap() method resets the cache. By default * the map is updated every time when a page is saved in the back-end, or * when the interval defined with the cms.urlCacheTtl expires. * @return boolean Returns true if the URL map was loaded from the cache. Otherwise returns false. */ protected function loadUrlMap() { $key = $this->getCacheKey('static-page-url-map'); $cacheable = Config::get('cms.enableRoutesCache'); $cached = $cacheable ? Cache::get($key, false) : false; if (!$cached || ($unserialized = @unserialize($cached)) === false) { /* * The item doesn't exist in the cache, create the map */ $pageList = new PageList($this->theme); $pages = $pageList->listPages(); $map = ['urls' => [], 'files' => [], 'titles' => []]; foreach ($pages as $page) { $url = $page->getViewBag()->property('url'); if (!$url) { continue; } $url = Str::lower(RouterHelper::normalizeUrl($url)); $file = $page->getBaseFileName(); $map['urls'][$url] = $file; $map['files'][$file] = $url; $map['titles'][$file] = $page->getViewBag()->property('title'); } self::$urlMap = $map; if ($cacheable) { Cache::put($key, serialize($map), Config::get('cms.urlCacheTtl', 1)); } return false; } self::$urlMap = $unserialized; return true; }
/** * Checks if macro is registered. * * @param string $name * @return bool * @static */ public static function hasMacro($name) { //Method inherited from \Illuminate\Support\Str return \October\Rain\Support\Str::hasMacro($name); }
/** * Same as parse method, except the line number where the respective section * begins is returned. * @param string $content Specifies the file content. * @return array Returns an array with the following indexes: 'settings', 'markup', 'code'. */ public static function parseOffset($content) { $content = Str::normalizeEol($content); $sections = preg_split('/^={2,}\\s*/m', $content, -1); $count = count($sections); $result = ['settings' => null, 'code' => null, 'markup' => null]; if ($count >= 3) { $result['settings'] = self::adjustLinePosition($content); $result['code'] = self::calculateLinePosition($content); $result['markup'] = self::calculateLinePosition($content, 2); } elseif ($count == 2) { $result['settings'] = self::adjustLinePosition($content); $result['markup'] = self::calculateLinePosition($content); } elseif ($count == 1) { $result['markup'] = 1; } return $result; }