1
0
mirror of https://github.com/flarum/core.git synced 2025-07-24 02:01:19 +02:00

Create new Flarum\Frontend namespace

It replaces the old Http\WebApp namespace and swallows other namespaces
and files, such as Flarum\Asset.
This commit is contained in:
Franz Liedke
2017-06-24 11:52:53 +02:00
parent 88d34192f1
commit 5e9308fb4c
22 changed files with 84 additions and 86 deletions

View File

@@ -0,0 +1,188 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Locale\LocaleManager;
use Flarum\Settings\SettingsRepositoryInterface;
abstract class AbstractFrontend
{
/**
* @var FrontendAssetsFactory
*/
protected $assets;
/**
* @var FrontendViewFactory
*/
protected $view;
/**
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var LocaleManager
*/
protected $locales;
/**
* @param FrontendAssetsFactory $assets
* @param FrontendViewFactory $view
* @param SettingsRepositoryInterface $settings
* @param LocaleManager $locales
*/
public function __construct(FrontendAssetsFactory $assets, FrontendViewFactory $view, SettingsRepositoryInterface $settings, LocaleManager $locales)
{
$this->assets = $assets;
$this->view = $view;
$this->settings = $settings;
$this->locales = $locales;
}
/**
* @return FrontendView
*/
public function getView()
{
$view = $this->view->make($this->getLayout(), $this->getAssets());
$this->addDefaultAssets($view);
$this->addCustomLess($view);
$this->addTranslations($view);
return $view;
}
/**
* @return FrontendAssets
*/
public function getAssets()
{
return $this->assets->make($this->getName());
}
/**
* Get the name of the client.
*
* @return string
*/
abstract protected function getName();
/**
* Get the path to the client layout view.
*
* @return string
*/
protected function getLayout()
{
return __DIR__.'/../../../views/'.$this->getName().'.blade.php';
}
/**
* Get a regular expression to match against translation keys.
*
* @return string
*/
protected function getTranslationFilter()
{
return '/^.+(?:\.|::)(?:'.$this->getName().'|lib)\./';
}
/**
* @param FrontendView $view
*/
private function addDefaultAssets(FrontendView $view)
{
$root = __DIR__.'/../../..';
$name = $this->getName();
$view->getJs()->addFile("$root/js/$name/dist/app.js");
$view->getCss()->addFile("$root/less/$name/app.less");
}
/**
* @param FrontendView $view
*/
private function addCustomLess(FrontendView $view)
{
$css = $view->getCss();
$localeCss = $view->getLocaleCss();
$lessVariables = function () {
$less = '';
foreach ($this->getLessVariables() as $name => $value) {
$less .= "@$name: $value;";
}
return $less;
};
$css->addString($lessVariables);
$localeCss->addString($lessVariables);
$css->addString(function () {
return $this->settings->get('custom_less');
});
}
/**
* Get the values of any LESS variables to compile into the CSS, based on
* the forum's configuration.
*
* @return array
*/
private function getLessVariables()
{
return [
'config-primary-color' => $this->settings->get('theme_primary_color') ?: '#000',
'config-secondary-color' => $this->settings->get('theme_secondary_color') ?: '#000',
'config-dark-mode' => $this->settings->get('theme_dark_mode') ? 'true' : 'false',
'config-colored-header' => $this->settings->get('theme_colored_header') ? 'true' : 'false'
];
}
/**
* @param FrontendView $view
*/
private function addTranslations(FrontendView $view)
{
$translations = array_get($this->locales->getTranslator()->getMessages(), 'messages', []);
$translations = $this->filterTranslations($translations);
$view->getLocaleJs()->setTranslations($translations);
}
/**
* Take a selection of keys from a collection of translations.
*
* @param array $translations
* @return array
*/
private function filterTranslations(array $translations)
{
$filter = $this->getTranslationFilter();
if (! $filter) {
return [];
}
$filtered = array_filter(array_keys($translations), function ($id) use ($filter) {
return preg_match($filter, $id);
});
return array_only($translations, $filtered);
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Event\ConfigureClientView;
use Flarum\Event\ConfigureWebApp;
use Flarum\Http\Controller\AbstractHtmlController;
use Illuminate\Contracts\Events\Dispatcher;
use Psr\Http\Message\ServerRequestInterface as Request;
abstract class AbstractFrontendController extends AbstractHtmlController
{
/**
* @var AbstractFrontend
*/
protected $webApp;
/**
* @var Dispatcher
*/
protected $events;
/**
* {@inheritdoc}
*/
public function render(Request $request)
{
$view = $this->getView($request);
$this->events->fire(
new ConfigureClientView($this, $view, $request)
);
$this->events->fire(
new ConfigureWebApp($this, $view, $request)
);
return $view->render($request);
}
/**
* @param Request $request
* @return \Flarum\Frontend\FrontendView
*/
protected function getView(Request $request)
{
return $this->webApp->getView();
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend\Asset;
interface CompilerInterface
{
/**
* @param string $filename
*/
public function setFilename($filename);
/**
* @param string $file
*/
public function addFile($file);
/**
* @param callable $callback
*/
public function addString(callable $callback);
/**
* @return string
*/
public function getFile();
/**
* @return string
*/
public function compile();
public function flush();
}

View File

@@ -0,0 +1,118 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend\Asset;
use Exception;
use Illuminate\Cache\Repository;
use MatthiasMullie\Minify;
use s9e\TextFormatter\Configurator;
use s9e\TextFormatter\Configurator\JavaScript\Minifiers\FirstAvailable;
class JsCompiler extends RevisionCompiler
{
/**
* @var Repository
*/
protected $cache;
/**
* @param string $path
* @param string $filename
* @param bool $watch
* @param Repository $cache
*/
public function __construct($path, $filename, $watch = false, Repository $cache = null)
{
parent::__construct($path, $filename, $watch);
$this->cache = $cache;
}
/**
* {@inheritdoc}
*/
protected function format($string)
{
if (! $this->watch) {
$key = 'js.'.sha1($string);
$string = $this->cache->rememberForever($key, function () use ($string) {
return $this->minify($string);
});
}
return $string.";\n";
}
/**
* {@inheritdoc}
*/
protected function getCacheDifferentiator()
{
return $this->watch;
}
/**
* @param string $source
* @return string
*/
protected function minify($source)
{
set_time_limit(60);
try {
$source = $this->minifyWithClosureCompilerService($source);
} catch (Exception $e) {
$source = $this->minifyWithFallback($source);
}
return $source;
}
/**
* @param string $source
* @return string
*/
protected function minifyWithClosureCompilerService($source)
{
// The minifier may need some classes bundled with the Configurator so we autoload it
class_exists(Configurator::class);
$minifier = new FirstAvailable;
$remoteCache = $minifier->add('RemoteCache');
$remoteCache->url = 'http://s9e-textformatter.rhcloud.com/flarum-minifier/';
$hostedMinifer = $minifier->add('HostedMinifier');
$hostedMinifer->url = 'http://s9e-textformatter.rhcloud.com/flarum-minifier/';
$hostedMinifer->httpClient->timeout = 30;
$ccs = $minifier->add('ClosureCompilerService');
$ccs->compilationLevel = 'SIMPLE_OPTIMIZATIONS';
$ccs->httpClient->timeout = 30;
$minifier->add('MatthiasMullieMinify');
return $minifier->minify($source);
}
/**
* @param string $source
* @return string
*/
protected function minifyWithFallback($source)
{
$minifier = new Minify\JS($source);
return $minifier->minify();
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend\Asset;
use Less_Exception_Parser;
use Less_Parser;
class LessCompiler extends RevisionCompiler
{
/**
* @var string
*/
protected $cachePath;
/**
* @param string $path
* @param string $filename
* @param bool $watch
* @param string $cachePath
*/
public function __construct($path, $filename, $watch, $cachePath)
{
parent::__construct($path, $filename, $watch);
$this->cachePath = $cachePath;
}
/**
* {@inheritdoc}
*/
public function compile()
{
if (! count($this->files) || ! count($this->strings)) {
return;
}
ini_set('xdebug.max_nesting_level', 200);
$parser = new Less_Parser([
'compress' => true,
'cache_dir' => $this->cachePath,
'import_dirs' => [
base_path().'/vendor/components/font-awesome/less' => '',
],
]);
try {
foreach ($this->files as $file) {
$parser->parseFile($file);
}
foreach ($this->strings as $callback) {
$parser->parse($callback());
}
return $parser->getCss();
} catch (Less_Exception_Parser $e) {
// TODO: log an error somewhere?
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend\Asset;
class LocaleJsCompiler extends JsCompiler
{
protected $translations = [];
public function setTranslations(array $translations)
{
$this->translations = $translations;
}
public function compile()
{
$output = "
System.register('locale', [], function(_export) {
return {
execute: function() {
_export('default', function(app) {
app.translator.translations = ".json_encode($this->translations).";\n";
foreach ($this->files as $filename) {
$output .= file_get_contents($filename);
}
$output .= '
});
}
};
});';
return $this->format($output);
}
}

View File

@@ -0,0 +1,203 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend\Asset;
class RevisionCompiler implements CompilerInterface
{
/**
* @var string[]
*/
protected $files = [];
/**
* @var callable[]
*/
protected $strings = [];
/**
* @var bool
*/
protected $watch;
/**
* @param string $path
* @param string $filename
* @param bool $watch
*/
public function __construct($path, $filename, $watch = false)
{
$this->path = $path;
$this->filename = $filename;
$this->watch = $watch;
}
/**
* {@inheritdoc}
*/
public function setFilename($filename)
{
$this->filename = $filename;
}
/**
* {@inheritdoc}
*/
public function addFile($file)
{
$this->files[] = $file;
}
/**
* {@inheritdoc}
*/
public function addString(callable $callback)
{
$this->strings[] = $callback;
}
/**
* {@inheritdoc}
*/
public function getFile()
{
$old = $current = $this->getRevision();
$ext = pathinfo($this->filename, PATHINFO_EXTENSION);
$file = $this->path.'/'.substr_replace($this->filename, '-'.$old, -strlen($ext) - 1, 0);
if ($this->watch || ! $old) {
$cacheDifferentiator = [$this->getCacheDifferentiator()];
foreach ($this->files as $source) {
$cacheDifferentiator[] = [$source, filemtime($source)];
}
$current = hash('crc32b', serialize($cacheDifferentiator));
}
$exists = file_exists($file);
if (! $exists || $old !== $current) {
if ($exists) {
unlink($file);
}
$file = $this->path.'/'.substr_replace($this->filename, '-'.$current, -strlen($ext) - 1, 0);
if ($content = $this->compile()) {
$this->putRevision($current);
file_put_contents($file, $content);
} else {
return;
}
}
return $file;
}
/**
* @return mixed
*/
protected function getCacheDifferentiator()
{
}
/**
* @param string $string
* @return string
*/
protected function format($string)
{
return $string;
}
/**
* {@inheritdoc}
*/
public function compile()
{
$output = '';
foreach ($this->files as $file) {
$output .= $this->formatFile($file);
}
foreach ($this->strings as $callback) {
$output .= $this->format($callback());
}
return $output;
}
/**
* @param string $file
* @return string
*/
protected function formatFile($file)
{
return $this->format(file_get_contents($file));
}
/**
* @return string
*/
protected function getRevisionFile()
{
return $this->path.'/rev-manifest.json';
}
/**
* @return string|null
*/
protected function getRevision()
{
if (file_exists($file = $this->getRevisionFile())) {
$manifest = json_decode(file_get_contents($file), true);
return array_get($manifest, $this->filename);
}
}
/**
* @param string $revision
* @return int
*/
protected function putRevision($revision)
{
if (file_exists($file = $this->getRevisionFile())) {
$manifest = json_decode(file_get_contents($file), true);
} else {
$manifest = [];
}
$manifest[$this->filename] = $revision;
return file_put_contents($this->getRevisionFile(), json_encode($manifest));
}
/**
* {@inheritdoc}
*/
public function flush()
{
$revision = $this->getRevision();
$ext = pathinfo($this->filename, PATHINFO_EXTENSION);
$file = $this->path.'/'.substr_replace($this->filename, '-'.$revision, -strlen($ext) - 1, 0);
if (file_exists($file)) {
unlink($file);
}
}
}

View File

@@ -0,0 +1,165 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Frontend\Asset\JsCompiler;
use Flarum\Frontend\Asset\LessCompiler;
use Flarum\Foundation\Application;
use Flarum\Frontend\Asset\LocaleJsCompiler as LocaleJsCompiler;
use Flarum\Locale\LocaleManager;
use Illuminate\Contracts\Cache\Repository;
class FrontendAssets
{
/**
* @var string
*/
protected $name;
/**
* @var Application
*/
protected $app;
/**
* @var Repository
*/
protected $cache;
/**
* @var LocaleManager
*/
protected $locales;
/**
* @param string $name
* @param Application $app
* @param Repository $cache
* @param LocaleManager $locales
*/
public function __construct($name, Application $app, Repository $cache, LocaleManager $locales)
{
$this->name = $name;
$this->app = $app;
$this->cache = $cache;
$this->locales = $locales;
}
public function flush()
{
$this->flushJs();
$this->flushCss();
}
public function flushJs()
{
$this->getJs()->flush();
$this->flushLocaleJs();
}
public function flushLocaleJs()
{
foreach ($this->locales->getLocales() as $locale => $info) {
$this->getLocaleJs($locale)->flush();
}
}
public function flushCss()
{
$this->getCss()->flush();
$this->flushLocaleCss();
}
public function flushLocaleCss()
{
foreach ($this->locales->getLocales() as $locale => $info) {
$this->getLocaleCss($locale)->flush();
}
}
/**
* @return JsCompiler
*/
public function getJs()
{
return new JsCompiler(
$this->getDestination(),
"$this->name.js",
$this->shouldWatch(),
$this->cache
);
}
/**
* @return LessCompiler
*/
public function getCss()
{
return new LessCompiler(
$this->getDestination(),
"$this->name.css",
$this->shouldWatch(),
$this->getLessStorage()
);
}
/**
* @param $locale
* @return LocaleJsCompiler
*/
public function getLocaleJs($locale)
{
return new LocaleJsCompiler(
$this->getDestination(),
"$this->name-$locale.js",
$this->shouldWatch(),
$this->cache
);
}
/**
* @param $locale
* @return LessCompiler
*/
public function getLocaleCss($locale)
{
return new LessCompiler(
$this->getDestination(),
"$this->name-$locale.css",
$this->shouldWatch(),
$this->getLessStorage()
);
}
protected function getDestination()
{
return $this->app->publicPath().'/assets';
}
protected function shouldWatch()
{
return $this->app->config('debug');
}
protected function getLessStorage()
{
return $this->app->storagePath().'/less';
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
}

View File

@@ -0,0 +1,55 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Foundation\Application;
use Flarum\Locale\LocaleManager;
use Illuminate\Contracts\Cache\Repository;
class FrontendAssetsFactory
{
/**
* @var Application
*/
protected $app;
/**
* @var Repository
*/
protected $cache;
/**
* @var LocaleManager
*/
protected $locales;
/**
* @param Application $app
* @param Repository $cache
* @param LocaleManager $locales
*/
public function __construct(Application $app, Repository $cache, LocaleManager $locales)
{
$this->app = $app;
$this->cache = $cache;
$this->locales = $locales;
}
/**
* @param string $name
* @return FrontendAssets
*/
public function make($name)
{
return new FrontendAssets($name, $this->app, $this->cache, $this->locales);
}
}

View File

@@ -0,0 +1,483 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Api\Client;
use Flarum\Api\Serializer\AbstractSerializer;
use Flarum\Frontend\Asset\CompilerInterface;
use Flarum\Foundation\Application;
use Flarum\Frontend\Asset\LocaleJsCompiler;
use Flarum\Locale\LocaleManager;
use Illuminate\View\Factory;
use Psr\Http\Message\ServerRequestInterface as Request;
use Tobscure\JsonApi\Document;
use Tobscure\JsonApi\Resource;
/**
* This class represents a view which boots up Flarum's client.
*/
class FrontendView
{
/**
* The title of the document, displayed in the <title> tag.
*
* @var null|string
*/
public $title;
/**
* The description of the document, displayed in a <meta> tag.
*
* @var null|string
*/
public $description;
/**
* The language of the document, displayed as the value of the attribute `dir` in the <html> tag.
*
* @var null|string
*/
public $language;
/**
* The text direction of the document, displayed as the value of the attribute `dir` in the <html> tag.
*
* @var null|string
*/
public $direction;
/**
* The path to the client layout view to display.
*
* @var string
*/
public $layout;
/**
* The SEO content of the page, displayed within the layout in <noscript>
* tags.
*
* @var string
*/
public $content;
/**
* An API response to be preloaded into the page.
*
* This should be a JSON-API document.
*
* @var null|array|object
*/
public $document;
/**
* Other variables to preload into the page.
*
* @var array
*/
protected $variables = [];
/**
* An array of JS modules to load before booting the app.
*
* @var array
*/
protected $modules = ['locale'];
/**
* An array of strings to append to the page's <head>.
*
* @var array
*/
protected $head = [];
/**
* An array of strings to prepend before the page's </body>.
*
* @var array
*/
protected $foot = [];
/**
* A map of <link> tags to be generated.
*
* @var array
*/
protected $links = [];
/**
* @var CompilerInterface
*/
protected $js;
/**
* @var CompilerInterface
*/
protected $css;
/**
* @var CompilerInterface
*/
protected $localeJs;
/**
* @var CompilerInterface
*/
protected $localeCss;
/**
* @var FrontendAssets
*/
protected $assets;
/**
* @var Client
*/
protected $api;
/**
* @var Factory
*/
protected $view;
/**
* @var LocaleManager
*/
protected $locales;
/**
* @var AbstractSerializer
*/
protected $userSerializer;
/**
* @var Application
*/
protected $app;
/**
* @param string $layout
* @param FrontendAssets $assets
* @param Client $api
* @param Factory $view
* @param LocaleManager $locales
* @param AbstractSerializer $userSerializer
* @param Application $app
*/
public function __construct($layout, FrontendAssets $assets, Client $api, Factory $view, LocaleManager $locales, AbstractSerializer $userSerializer, Application $app)
{
$this->layout = $layout;
$this->api = $api;
$this->assets = $assets;
$this->view = $view;
$this->locales = $locales;
$this->userSerializer = $userSerializer;
$this->app = $app;
$this->addHeadString('<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700,600">', 'font');
$this->js = $this->assets->getJs();
$this->css = $this->assets->getCss();
$locale = $this->locales->getLocale();
$this->localeJs = $this->assets->getLocaleJs($locale);
$this->localeCss = $this->assets->getLocaleCss($locale);
foreach ($this->locales->getJsFiles($locale) as $file) {
$this->localeJs->addFile($file);
}
foreach ($this->locales->getCssFiles($locale) as $file) {
$this->localeCss->addFile($file);
}
}
/**
* Add a string to be appended to the page's <head>.
*
* @param string $string
* @param null|string $name
*/
public function addHeadString($string, $name = null)
{
if ($name) {
$this->head[$name] = $string;
} else {
$this->head[] = $string;
}
}
/**
* Add a string to be prepended before the page's </body>.
*
* @param string $string
*/
public function addFootString($string)
{
$this->foot[] = $string;
}
/**
* Configure a <link> tag.
*
* @param string $relation
* @param string $target
*/
public function link($relation, $target)
{
$this->links[$relation] = $target;
}
/**
* Configure the canonical URL for this page.
*
* This will signal to search engines what URL should be used for this
* content, if it can be found under multiple addresses. This is an
* important tool to tackle duplicate content.
*
* @param string $url
*/
public function setCanonicalUrl($url)
{
$this->link('canonical', $url);
}
/**
* Set a variable to be preloaded into the app.
*
* @param string $name
* @param mixed $value
*/
public function setVariable($name, $value)
{
$this->variables[$name] = $value;
}
/**
* Add a JavaScript module to be imported before the app is booted.
*
* @param string $module
*/
public function loadModule($module)
{
$this->modules[] = $module;
}
/**
* Get the string contents of the view.
*
* @param Request $request
* @return string
*/
public function render(Request $request)
{
$forum = $this->getForumDocument($request);
$this->view->share('translator', $this->locales->getTranslator());
$this->view->share('allowJs', ! array_get($request->getQueryParams(), 'nojs'));
$this->view->share('forum', array_get($forum, 'data'));
$this->view->share('debug', $this->app->inDebugMode());
$view = $this->view->file(__DIR__.'/../../../views/app.blade.php');
$view->title = $this->buildTitle(array_get($forum, 'data.attributes.title'));
$view->description = $this->description ?: array_get($forum, 'data.attributes.description');
$view->language = $this->language ?: $this->locales->getLocale();
$view->direction = $this->direction ?: 'ltr';
$view->modules = $this->modules;
$view->payload = $this->buildPayload($request, $forum);
$view->layout = $this->buildLayout();
$baseUrl = array_get($forum, 'data.attributes.baseUrl');
$view->cssUrls = $this->buildCssUrls($baseUrl);
$view->jsUrls = $this->buildJsUrls($baseUrl);
$view->head = $this->buildHeadContent();
$view->foot = implode("\n", $this->foot);
return $view->render();
}
protected function buildTitle($forumTitle)
{
return ($this->title ? $this->title.' - ' : '').$forumTitle;
}
protected function buildPayload(Request $request, $forum)
{
$data = $this->getDataFromDocument($forum);
if ($request->getAttribute('actor')->exists) {
$user = $this->getUserDocument($request);
$data = array_merge($data, $this->getDataFromDocument($user));
}
$payload = [
'resources' => $data,
'session' => $this->buildSession($request),
'document' => $this->document,
'locales' => $this->locales->getLocales(),
'locale' => $this->locales->getLocale()
];
return array_merge($payload, $this->variables);
}
protected function buildLayout()
{
$view = $this->view->file($this->layout);
$view->content = $this->buildContent();
return $view;
}
protected function buildContent()
{
$view = $this->view->file(__DIR__.'/../../../views/content.blade.php');
$view->content = $this->content;
return $view;
}
protected function buildCssUrls($baseUrl)
{
return $this->buildAssetUrls($baseUrl, [$this->css->getFile(), $this->localeCss->getFile()]);
}
protected function buildJsUrls($baseUrl)
{
return $this->buildAssetUrls($baseUrl, [$this->js->getFile(), $this->localeJs->getFile()]);
}
protected function buildAssetUrls($baseUrl, $files)
{
return array_map(function ($file) use ($baseUrl) {
return $baseUrl.str_replace(public_path(), '', $file);
}, array_filter($files));
}
protected function buildHeadContent()
{
$html = implode("\n", $this->head);
foreach ($this->links as $rel => $href) {
$html .= "\n<link rel=\"$rel\" href=\"$href\" />";
}
return $html;
}
/**
* @return CompilerInterface
*/
public function getJs()
{
return $this->js;
}
/**
* @return CompilerInterface
*/
public function getCss()
{
return $this->css;
}
/**
* @return LocaleJsCompiler
*/
public function getLocaleJs()
{
return $this->localeJs;
}
/**
* @return CompilerInterface
*/
public function getLocaleCss()
{
return $this->localeCss;
}
/**
* Get the result of an API request to show the forum.
*
* @param Request $request
* @return array
*/
protected function getForumDocument(Request $request)
{
$actor = $request->getAttribute('actor');
$response = $this->api->send('Flarum\Api\Controller\ShowForumController', $actor);
return json_decode($response->getBody(), true);
}
/**
* Get the result of an API request to show the current user.
*
* @param Request $request
* @return array
*/
protected function getUserDocument(Request $request)
{
$actor = $request->getAttribute('actor');
$this->userSerializer->setActor($actor);
$resource = new Resource($actor, $this->userSerializer);
$document = new Document($resource->with('groups'));
return $document->toArray();
}
/**
* Get information about the current session.
*
* @param Request $request
* @return array
*/
protected function buildSession(Request $request)
{
$actor = $request->getAttribute('actor');
$session = $request->getAttribute('session');
return [
'userId' => $actor->id,
'csrfToken' => $session->get('csrf_token')
];
}
/**
* Get an array of data by merging the 'data' and 'included' keys of a
* JSON-API document.
*
* @param array $document
* @return array
*/
private function getDataFromDocument(array $document)
{
$data[] = $document['data'];
if (isset($document['included'])) {
$data = array_merge($data, $document['included']);
}
return $data;
}
}

View File

@@ -0,0 +1,72 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Frontend;
use Flarum\Api\Client;
use Flarum\Api\Serializer\CurrentUserSerializer;
use Flarum\Foundation\Application;
use Flarum\Locale\LocaleManager;
use Illuminate\Contracts\View\Factory;
class FrontendViewFactory
{
/**
* @var Client
*/
protected $api;
/**
* @var Factory
*/
protected $view;
/**
* @var LocaleManager
*/
protected $locales;
/**
* @var CurrentUserSerializer
*/
protected $userSerializer;
/**
* @var Application
*/
protected $app;
/**
* @param Client $api
* @param Factory $view
* @param LocaleManager $locales
* @param CurrentUserSerializer $userSerializer
* @param Application $app
*/
public function __construct(Client $api, Factory $view, LocaleManager $locales, CurrentUserSerializer $userSerializer, Application $app)
{
$this->api = $api;
$this->view = $view;
$this->locales = $locales;
$this->userSerializer = $userSerializer;
$this->app = $app;
}
/**
* @param string $layout
* @param FrontendAssets $assets
* @return FrontendView
*/
public function make($layout, FrontendAssets $assets)
{
return new FrontendView($layout, $assets, $this->api, $this->view, $this->locales, $this->userSerializer, $this->app);
}
}