/home/techb158/immovalet.com/vendor/botble/theme/src
Edit: /home/techb158/immovalet.com/vendor/botble/theme/src/Theme.php (25214B)
config = $config;
$this->events = $events;
$this->view = $view;
$this->asset = $asset;
$this->files = $files;
$this->breadcrumb = $breadcrumb;
self::uses($this->getThemeName())->layout(setting('layout', 'default'));
SeoHelper::meta()
->setGoogle(setting('google_analytics'))
->addWebmaster('google', setting('google_site_verification'));
}
/**
* Set up a layout name.
*
* @param string $layout
* @return Theme
*/
public function layout(string $layout)
{
// If layout name is not set, so use default from config.
if ($layout != false) {
$this->layout = $layout;
}
return $this;
}
/**
* Alias of theme method.
*
* @param string $theme
* @return Theme
* @throws FileNotFoundException
*/
public function uses(?string $theme = null)
{
return $this->theme($theme);
}
/**
* Set up a theme name.
*
* @param string $theme
* @return Theme
* @throws UnknownThemeException
* @throws FileNotFoundException
*/
public function theme(?string $theme = null)
{
// If theme name is not set, so use default from config.
if ($theme != false) {
$this->theme = $theme;
}
// Is theme ready?
if (!$this->exists($theme)) {
throw new UnknownThemeException('Theme [' . $theme . '] not found.');
}
// Add location to look up view.
$this->addPathLocation($this->path());
// Fire event before set up a theme.
$this->fire('before', $this);
// Before from a public theme config.
$this->fire('appendBefore', $this);
// Add asset path to asset container.
$this->asset->addPath($this->path() . '/' . $this->getConfig('containerDir.asset'));
return $this;
}
/**
* Check theme exists.
*
* @param string $theme
* @return boolean
* @throws FileNotFoundException
*/
public function exists(?string $theme): bool
{
$path = platform_path($this->path($theme)) . '/';
return File::isDirectory($path);
}
/**
* Get theme path.
*
* @param string $forceThemeName
* @return string
* @throws FileNotFoundException
*/
public function path(?string $forceThemeName = null): string
{
$themeDir = $this->getConfig('themeDir');
$theme = $this->theme;
if ($forceThemeName != false) {
$theme = $forceThemeName;
}
return $themeDir . '/' . $theme;
}
/**
* Get theme config.
*
* @param string $key
* @return mixed
* @throws FileNotFoundException
*/
public function getConfig(?string $key = null)
{
// Main package config.
if (!$this->themeConfig) {
$this->themeConfig = $this->config->get('packages.theme.general');
}
// Config inside a public theme.
// This config having buffer by array object.
if ($this->theme && !isset($this->themeConfig['themes'][$this->theme])) {
$this->themeConfig['themes'][$this->theme] = [];
// Require public theme config.
$minorConfigPath = theme_path($this->theme . '/config.php');
$this->themeConfig['themes'][$this->theme] = $this->files->getRequire($minorConfigPath);
}
// Evaluate theme config.
$this->themeConfig = $this->evaluateConfig($this->themeConfig);
return empty($key) ? $this->themeConfig : Arr::get($this->themeConfig, $key);
}
/**
* Evaluate config.
*
* Config minor is at public folder [theme]/config.php,
* they can be override package config.
*
* @param mixed $config
* @return mixed
*/
protected function evaluateConfig(array $config): array
{
if (!isset($config['themes'][$this->theme])) {
return $config;
}
// Config inside a public theme.
$minorConfig = $config['themes'][$this->theme];
// Before event is special case, It's combination.
if (isset($minorConfig['events']['before'])) {
$minorConfig['events']['appendBefore'] = $minorConfig['events']['before'];
unset($minorConfig['events']['before']);
}
// Merge two config into one.
$config = array_replace_recursive($config, $minorConfig);
// Reset theme config.
$config['themes'][$this->theme] = [];
return $config;
}
/**
* Add location path to look up.
*
* @param string $location
* @throws FileNotFoundException
*/
protected function addPathLocation(string $location)
{
// First path is in the selected theme.
$hints[] = platform_path($location);
// This is nice feature to use inherit from another.
if ($this->getConfig('inherit')) {
// Inherit from theme name.
$inherit = $this->getConfig('inherit');
// Inherit theme path.
$inheritPath = platform_path($this->path($inherit));
if ($this->files->isDirectory($inheritPath)) {
array_push($hints, $inheritPath);
}
}
// Add namespace with hinting paths.
$this->view->addNamespace($this->getThemeNamespace(), $hints);
}
/**
* Get theme namespace.
*
* @param string $path
* @return string
*/
public function getThemeNamespace(string $path = ''): string
{
// Namespace relate with the theme name.
$namespace = static::$namespace . '.' . $this->getThemeName();
if ($path != false) {
return $namespace . '::' . $path;
}
return $namespace;
}
/**
* Get current theme name.
*
* @return string
*/
public function getThemeName()
{
if ($this->theme) {
return $this->theme;
}
$theme = setting('theme');
if ($theme) {
return $theme;
}
$theme = Arr::first(scan_folder(theme_path()));
if (Helper::isConnectedDatabase()) {
setting()->set('theme', $theme)->save();
}
return $theme;
}
/**
* Fire event to config listener.
*
* @param string $event
* @param mixed $args
* @return void
* @throws FileNotFoundException
*/
public function fire(string $event, $args)
{
$onEvent = $this->getConfig('events.' . $event);
if ($onEvent instanceof Closure) {
$onEvent($args);
}
}
/**
* Return breadcrumb instance.
*
* @return Breadcrumb
*/
public function breadcrumb(): Breadcrumb
{
return $this->breadcrumb;
}
/**
* Append a place to existing region.
*
* @param string $region
* @param string $value
* @return Theme
*/
public function append(string $region, $value): self
{
return $this->appendOrPrepend($region, $value);
}
/**
* Append or prepend existing region.
*
* @param string $region
* @param string $value
* @param string $type
* @return Theme
*/
protected function appendOrPrepend(string $region, $value, string $type = 'append'): self
{
// If region not found, create a new region.
if (isset($this->regions[$region])) {
switch ($type) {
case 'prepend':
$this->regions[$region] = $value . $this->regions[$region];
break;
case 'append':
$this->regions[$region] .= $value;
break;
}
} else {
$this->set($region, $value);
}
return $this;
}
/**
* Set a place to regions.
*
* @param string $region
* @param string $value
* @return Theme
*/
public function set(string $region, $value): self
{
// Content is reserve region for render sub-view.
if ($region != 'content') {
$this->regions[$region] = $value;
}
return $this;
}
/**
* Prepend a place to existing region.
*
* @param string $region
* @param string $value
* @return Theme
*/
public function prepend(string $region, $value): self
{
return $this->appendOrPrepend($region, $value, 'prepend');
}
/**
* Binding data to view.
*
* @param string $variable
* @param mixed $callback
* @return mixed
*/
public function bind(string $variable, $callback = null)
{
$name = 'bind.' . $variable;
// If callback pass, so put in a queue.
if (!empty($callback)) {
// Preparing callback in to queues.
$this->events->listen($name, function () use ($callback) {
return ($callback instanceof Closure) ? $callback() : $callback;
});
}
// Passing variable to closure.
$events =& $this->events;
$bindings =& $this->bindings;
// Buffer processes to save request.
return Arr::get($this->bindings, $name, function () use (&$events, &$bindings, $name) {
$response = current($events->dispatch($name));
Arr::set($bindings, $name, $response);
return $response;
});
}
/**
* Check having binded data.
*
* @param string $variable
* @return boolean
*/
public function binded(string $variable)
{
$name = 'bind.' . $variable;
return $this->events->hasListeners($name);
}
/**
* Assign data across all views.
*
* @param mixed $key
* @param mixed $value
* @return mixed
*/
public function share(string $key, $value)
{
return $this->view->share($key, $value);
}
/**
* The same as "partial", but having prefix layout.
*
* @param string $view
* @param array $args
* @return mixed
* @throws UnknownPartialFileException
* @throws FileNotFoundException
*/
public function partialWithLayout(string $view, array $args = [])
{
$view = $this->getLayoutName() . '.' . $view;
return $this->partial($view, $args);
}
/**
* Get current layout name.
*
* @return string
*/
public function getLayoutName()
{
return $this->layout;
}
/**
* Set up a partial.
*
* @param string $view
* @param array $args
* @return mixed
* @throws UnknownPartialFileException
* @throws FileNotFoundException
*/
public function partial(string $view, array $args = [])
{
$partialDir = $this->getThemeNamespace($this->getConfig('containerDir.partial'));
return $this->loadPartial($view, $partialDir, $args);
}
/**
* Load a partial
*
* @param string $view
* @param string $partialDir
* @param array $args
* @return mixed
* @throws UnknownPartialFileException
*/
public function loadPartial(string $view, string $partialDir, array $args)
{
$path = $partialDir . '.' . $view;
if (!$this->view->exists($path)) {
throw new UnknownPartialFileException('Partial view [' . $view . '] not found.');
}
$partial = $this->view->make($path, $args)->render();
$this->regions[$view] = $partial;
return $this->regions[$view];
}
/**
* Watch and set up a partial from anywhere.
*
* This method will first try to load the partial from current theme. If partial
* is not found in theme then it loads it from app (i.e. app/views/partials)
*
* @param string $view
* @param array $args
* @return mixed
* @throws UnknownPartialFileException
* @throws FileNotFoundException
*/
public function watchPartial(string $view, array $args = [])
{
try {
return $this->partial($view, $args);
} catch (UnknownPartialFileException $e) {
$partialDir = $this->getConfig('containerDir.partial');
return $this->loadPartial($view, $partialDir, $args);
}
}
/**
* Hook a partial before rendering.
*
* @param mixed $view
* @param closure $callback
* @param string $layout
* @return void
* @throws FileNotFoundException
*/
public function partialComposer($view, $callback, ?string $layout = null)
{
$partialDir = $this->getConfig('containerDir.partial');
if (!is_array($view)) {
$view = [$view];
}
// Partial path with namespace.
$path = $this->getThemeNamespace($partialDir);
// This code support partialWithLayout.
if (!empty($layout)) {
$path = $path . '.' . $layout;
}
$view = array_map(function ($item) use ($path) {
return $path . '.' . $item;
}, $view);
$this->view->composer($view, $callback);
}
/**
* Hook a partial before rendering.
*
* @param mixed $view
* @param closure $callback
* @param string $layout
* @return void
*
* @throws FileNotFoundException
*/
public function composer($view, $callback, ?string $layout = null)
{
$partialDir = $this->getConfig('containerDir.view');
if (!is_array($view)) {
$view = [$view];
}
// Partial path with namespace.
$path = $this->getThemeNamespace($partialDir);
// This code support partialWithLayout.
if (!empty($layout)) {
$path = $path . '.' . $layout;
}
$view = array_map(function ($item) use ($path) {
return $path . '.' . $item;
}, $view);
$this->view->composer($view, $callback);
}
/**
* Render a region.
*
* @param string $region
* @param mixed $default
* @return string
*/
public function place(string $region, ?string $default = null)
{
return $this->get($region, $default);
}
/**
* Render a region.
*
* @param string $region
* @param mixed $default
* @return string
*/
public function get(string $region, ?string $default = null)
{
if ($this->has($region)) {
return $this->regions[$region];
}
return $default ?: '';
}
/**
* Check region exists.
*
* @param string $region
* @return boolean
*/
public function has(string $region): bool
{
return (boolean)isset($this->regions[$region]);
}
/**
* Place content in sub-view.
*
* @return string
*/
public function content()
{
return $this->regions['content'];
}
/**
* Return asset instance.
*
* @return Asset|AssetContainer
*/
public function asset()
{
return $this->asset;
}
/**
* The same as "of", but having prefix layout.
*
* @param string $view
* @param array $args
* @param string $type
* @return Theme
* @throws Exception
*/
public function ofWithLayout($view, $args = [])
{
$view = $this->getLayoutName() . '.' . $view;
return $this->of($view, $args);
}
/**
* Set up a content to template.
*
* @param string $view
* @param array $args
* @return Theme
* @throws FileNotFoundException
* @throws Exception
*/
public function of($view, $args = []): self
{
// Fire event global assets.
$this->fire('asset', $this->asset);
// Fire event before render theme.
$this->fire('beforeRenderTheme', $this);
// Fire event before render layout.
$this->fire('beforeRenderLayout.' . $this->layout, $this);
// Keeping arguments.
$this->arguments = $args;
$content = $this->view->make($view, $args)->render();
// View path of content.
$this->content = $view;
// Set up a content regional.
$this->regions['content'] = $content;
return $this;
}
/**
* Container view.
*
* Using a container module view inside a theme, this is
* useful when you separate a view inside a theme.
*
* @param string $view
* @param array $args
* @return Theme|void
* @throws FileNotFoundException
*/
public function scope($view, $args = [], $default = null)
{
$viewDir = $this->getConfig('containerDir.view');
// Add namespace to find in a theme path.
$path = $this->getThemeNamespace($viewDir . '.' . $view);
if ($this->view->exists($path)) {
return $this->setUpContent($path, $args);
}
if (!empty($default)) {
return $this->of($default, $args);
}
$this->handleViewNotFound($path);
}
/**
* Set up a content to template.
*
* @param string $view
* @param array $args
* @return Theme
* @throws FileNotFoundException
*/
public function setUpContent($view, $args = [])
{
// Fire event global assets.
$this->fire('asset', $this->asset);
// Fire event before render theme.
$this->fire('beforeRenderTheme', $this);
// Fire event before render layout.
$this->fire('beforeRenderLayout.' . $this->layout, $this);
// Keeping arguments.
$this->arguments = $args;
$content = $this->view->make($view, $args)->render();
// View path of content.
$this->content = $view;
// Set up a content regional.
$this->regions['content'] = $content;
return $this;
}
/**
* @param string $path
*/
protected function handleViewNotFound($path)
{
if (app()->isLocal()) {
$path = str_replace($this->getThemeNamespace(), $this->getThemeName(), $path);
$file = str_replace('::', '/', str_replace('.', '/', $path));
dd('This theme has not supported this view, please create file "' . theme_path($file) . '.blade.php" to render this page!');
}
abort(404);
}
/**
* Load subview from direct path.
*
* @param string $view
* @param array $args
* @return Theme
* @throws FileNotFoundException
*/
public function load($view, $args = [])
{
$view = ltrim($view, '/');
$segments = explode('/', str_replace('.', '/', $view));
// Pop file from segments.
$view = array_pop($segments);
// Custom directory path.
$pathOfView = app('path.base') . '/' . implode('/', $segments);
// Add temporary path with a hint type.
$this->view->addNamespace('custom', $pathOfView);
return $this->setUpContent('custom::' . $view, $args);
}
/**
* Get all arguments assigned to content.
*
* @return mixed
*/
public function getContentArguments()
{
return $this->arguments;
}
/**
* Get a argument assigned to content.
*
* @param string $key
* @param null $default
* @return mixed
*/
public function getContentArgument($key, $default = null)
{
return Arr::get($this->arguments, $key, $default);
}
/**
* Checking content argument existing.
*
* @param string $key
* @return boolean
*/
public function hasContentArgument($key): bool
{
return isset($this->arguments[$key]);
}
/**
* Find view location.
*
* @param boolean $realPath
* @return string
*/
public function location($realPath = false)
{
if ($this->view->exists($this->content)) {
return $realPath ? $this->view->getFinder()->find($this->content) : $this->content;
}
return null;
}
/**
* Return a template with content.
*
* @param integer $statusCode
* @return Response | Response | \Response
* @throws UnknownLayoutFileException
* @throws FileNotFoundException
*/
public function render($statusCode = 200)
{
// Fire the event before render.
$this->fire('after', $this);
// Flush asset that need to serve.
$this->asset->flush();
// Layout directory.
$layoutDir = $this->getConfig('containerDir.layout');
$path = $this->getThemeNamespace($layoutDir . '.' . $this->layout);
if (!$this->view->exists($path)) {
$this->handleViewNotFound($path);
}
$content = $this->view->make($path)->render();
// Append status code to view.
$content = new Response($content, $statusCode);
// Having cookie set.
if ($this->cookie) {
$content->withCookie($this->cookie);
}
$content->withHeaders([
'CMS-Version' => get_cms_version(),
'Authorization-At' => setting('membership_authorization_at'),
'Activated-License' => !empty(setting('licensed_to')) ? 'Yes' : 'No',
]);
return $content;
}
/**
* @return string
*/
public function header(): string
{
return $this->view->make('packages/theme::partials.header')->render();
}
/**
* @return string
*/
public function footer(): string
{
return $this->view->make('packages/theme::partials.footer')->render();
}
/**
* Magic method for set, prepend, append, has, get.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters = [])
{
$callable = preg_split('|[A-Z]|', $method);
if (in_array($callable[0], ['set', 'prepend', 'append', 'has', 'get'])) {
$value = lcfirst(preg_replace('|^' . $callable[0] . '|', '', $method));
array_unshift($parameters, $value);
return call_user_func_array([$this, $callable[0]], $parameters);
}
return trigger_error('Call to undefined method ' . __CLASS__ . '::' . $method . '()', E_USER_ERROR);
}
/**
* @return mixed
*/
public function routes()
{
return File::requireOnce(package_path('theme/routes/public.php'));
}
}