* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ class Blocks extends Items { public const ITEM_CLASS = '\Kirby\Cms\Block'; /** * Return HTML when the collection is * converted to a string * * @return string */ public function __toString(): string { return $this->toHtml(); } /** * Converts the blocks to HTML and then * uses the Str::excerpt method to create * a non-formatted, shortened excerpt from it * * @param mixed ...$args * @return string */ public function excerpt(...$args) { return Str::excerpt($this->toHtml(), ...$args); } /** * Wrapper around the factory to * catch blocks from layouts * * @param array $items * @param array $params * @return \Kirby\Cms\Blocks */ public static function factory(array $items = null, array $params = []) { $items = static::extractFromLayouts($items); $items = BlockConverter::editorBlocks($items); return parent::factory($items, $params); } /** * Pull out blocks from layouts * * @param array $input * @return array */ protected static function extractFromLayouts(array $input): array { if (empty($input) === true) { return []; } if ( // no columns = no layout array_key_exists('columns', $input[0]) === false || // checks if this is a block for the builder plugin array_key_exists('_key', $input[0]) === true ) { return $input; } $blocks = []; foreach ($input as $layout) { foreach (($layout['columns'] ?? []) as $column) { foreach (($column['blocks'] ?? []) as $block) { $blocks[] = $block; } } } return $blocks; } /** * Checks if a given block type exists in the collection * @since 3.6.0 * * @param string $type * @return bool */ public function hasType(string $type): bool { return $this->filterBy('type', $type)->count() > 0; } /** * Parse and sanitize various block formats * * @param array|string $input * @return array */ public static function parse($input): array { if (empty($input) === false && is_array($input) === false) { try { $input = Json::decode((string)$input); } catch (Throwable $e) { try { // try to import the old YAML format $yaml = Yaml::decode((string)$input); $first = A::first($yaml); // check for valid yaml if (empty($yaml) === true || (isset($first['_key']) === false && isset($first['type']) === false)) { throw new Exception('Invalid YAML'); } else { $input = $yaml; } } catch (Throwable $e) { $parser = new Parsley((string)$input, new BlockSchema()); $input = $parser->blocks(); } } } if (empty($input) === true) { return []; } return $input; } /** * Convert all blocks to HTML * * @return string */ public function toHtml(): string { $html = []; foreach ($this->data as $block) { $html[] = $block->toHtml(); } return implode($html); } }