Test project for media files management.
<?php
namespace Illuminate\View\Concerns;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Str;
use InvalidArgumentException;
trait ManagesLayouts
{
/**
* All of the finished, captured sections.
*
* @var array
*/
protected $sections = [];
/**
* The stack of in-progress sections.
*
* @var array
*/
protected $sectionStack = [];
/**
* The parent placeholder for the request.
*
* @var mixed
*/
protected static $parentPlaceholder = [];
/**
* The parent placeholder salt for the request.
*
* @var string
*/
protected static $parentPlaceholderSalt;
/**
* Start injecting content into a section.
*
* @param string $section
* @param string|null $content
* @return void
*/
public function startSection($section, $content = null)
{
if ($content === null) {
if (ob_start()) {
$this->sectionStack[] = $section;
}
} else {
$this->extendSection($section, $content instanceof View ? $content : e($content));
}
}
/**
* Inject inline content into a section.
*
* @param string $section
* @param string $content
* @return void
*/
public function inject($section, $content)
{
$this->startSection($section, $content);
}
/**
* Stop injecting content into a section and return its contents.
*
* @return string
*/
public function yieldSection()
{
if (empty($this->sectionStack)) {
return '';
}
return $this->yieldContent($this->stopSection());
}
/**
* Stop injecting content into a section.
*
* @param bool $overwrite
* @return string
*
* @throws \InvalidArgumentException
*/
public function stopSection($overwrite = false)
{
if (empty($this->sectionStack)) {
throw new InvalidArgumentException('Cannot end a section without first starting one.');
}
$last = array_pop($this->sectionStack);
if ($overwrite) {
$this->sections[$last] = ob_get_clean();
} else {
$this->extendSection($last, ob_get_clean());
}
return $last;
}
/**
* Stop injecting content into a section and append it.
*
* @return string
*
* @throws \InvalidArgumentException
*/
public function appendSection()
{
if (empty($this->sectionStack)) {
throw new InvalidArgumentException('Cannot end a section without first starting one.');
}
$last = array_pop($this->sectionStack);
if (isset($this->sections[$last])) {
$this->sections[$last] .= ob_get_clean();
} else {
$this->sections[$last] = ob_get_clean();
}
return $last;
}
/**
* Append content to a given section.
*
* @param string $section
* @param string $content
* @return void
*/
protected function extendSection($section, $content)
{
if (isset($this->sections[$section])) {
$content = str_replace(static::parentPlaceholder($section), $content, $this->sections[$section]);
}
$this->sections[$section] = $content;
}
/**
* Get the string contents of a section.
*
* @param string $section
* @param string $default
* @return string
*/
public function yieldContent($section, $default = '')
{
$sectionContent = $default instanceof View ? $default : e($default);
if (isset($this->sections[$section])) {
$sectionContent = $this->sections[$section];
}
$sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);
return str_replace(
'--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)
);
}
/**
* Get the parent placeholder for the current request.
*
* @param string $section
* @return string
*/
public static function parentPlaceholder($section = '')
{
if (! isset(static::$parentPlaceholder[$section])) {
$salt = static::parentPlaceholderSalt();
static::$parentPlaceholder[$section] = '##parent-placeholder-'.hash('xxh128', $salt.$section).'##';
}
return static::$parentPlaceholder[$section];
}
/**
* Get the parent placeholder salt.
*
* @return string
*/
protected static function parentPlaceholderSalt()
{
if (! static::$parentPlaceholderSalt) {
return static::$parentPlaceholderSalt = Str::random(40);
}
return static::$parentPlaceholderSalt;
}
/**
* Check if section exists.
*
* @param string $name
* @return bool
*/
public function hasSection($name)
{
return array_key_exists($name, $this->sections);
}
/**
* Check if section does not exist.
*
* @param string $name
* @return bool
*/
public function sectionMissing($name)
{
return ! $this->hasSection($name);
}
/**
* Get the contents of a section.
*
* @param string $name
* @param string|null $default
* @return mixed
*/
public function getSection($name, $default = null)
{
return $this->getSections()[$name] ?? $default;
}
/**
* Get the entire array of sections.
*
* @return array
*/
public function getSections()
{
return $this->sections;
}
/**
* Flush all of the sections.
*
* @return void
*/
public function flushSections()
{
$this->sections = [];
$this->sectionStack = [];
}
}