%PDF- %PDF-
| Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/ui/view/components/ |
| Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/ui/view/components/View.php |
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\ui\view\components;
use humhub\assets\AppAsset;
use humhub\assets\CoreBundleAsset;
use humhub\components\assets\AssetBundle;
use humhub\libs\Html;
use humhub\modules\web\pwa\widgets\LayoutHeader;
use humhub\modules\web\pwa\widgets\SiteIcon;
use humhub\widgets\CoreJsConfig;
use humhub\widgets\LayoutAddons;
use yii\helpers\ArrayHelper;
use Yii;
/**
* Class View
*
* @property Theme $theme the Theme component
* @property ViewMeta $meta The View Meta Service
*
* @inheritdoc
*/
class View extends \yii\web\View
{
/**
* the id of the sidebar block
*/
const BLOCK_SIDEBAR = 'sidebar';
/**
* @var string page title
* @see View::setPageTitle
*/
private $_pageTitle;
/**
* @var array Contains javascript configurations, which will be appended to the view.
* @see View::endBody
*/
private $jsConfig = [];
/**
* @var array contains static core style and script assets which should be pre-loaded as `<link rel="preload">` element.
*/
protected static $preload = [
'theme.css',
'bootstrap.css',
];
/**
* @var array contains already pre-loaded asset urls.
*/
private static $preloaded = [];
/**
* A viewContext is a simple string value which usually is set by a controller to define the context of a resulting view.
* If a viewContext is set, it will be sent to the client in case of pjax and full page loads. The HumHub Client API
* will then use the viewContext in all ajax (non pjax) requests as HTTP request header `HUMHUB-VIEW-CONTEXT`
* until the next pjax or full page load.
*
* The viewContext is usually used to influence the view, e.g. a viewContext 'modal' indicates that the resulting view
* will be contained in a modal, a 'dashboard' context will indicate that the ajax request was sent from the dashboard.
*
* A controller usually sets the viewContext within the init function e.g.:
*
* ```php
* public function init()
* {
* parent::init();
* $this->view->setViewContext('dashboard');
* }
* ```
*
* Note: This variable won't contain the value of the request header but is only used to set the client viewContext.
* Use `Yii::$app->request->getViewContext()` to determine the active viewContext of a request.
*
* @var string defines a view context used in ajax requests
* @since 1.7
*/
private static $viewContext;
private $_viewMeta;
/**
* @return ViewMeta
*/
public function getMeta()
{
if ($this->_viewMeta === null) {
$this->_viewMeta = new ViewMeta(['view' => $this]);
}
return $this->_viewMeta;
}
/**
* Sets current page title
*
* @param string $title
* @param bool $prepend
*/
public function setPageTitle($title, $prepend = false)
{
$this->_pageTitle = ($prepend) ? $title . ' - ' . $this->_pageTitle : $title;
}
/**
* Returns current page title
*
* @return string the page title
*/
public function getPageTitle()
{
return (($this->_pageTitle) ? $this->_pageTitle . " - " : '') . Yii::$app->name;
}
/**
* Registers the javascript module configuration for one or multiple modules.
*
* ```javascript
* $this->registerJsConfig('moduleId', [
* 'someKey' => 'someValue'
* ]);
*
* // or
*
* $this->registerJsConfig([
* 'module1' => [
* 'someKey' => 'someValue'
* ],
* 'module2' => [
* 'someKey' => 'anotherValue';
* ]
* ]);
* ```
* @param $module
* @param null $params
*/
public function registerJsConfig($module, $params = null)
{
if (is_array($module)) {
foreach ($module as $moduleId => $value) {
$this->registerJsConfig($moduleId, $value);
}
return;
}
if (isset($this->jsConfig[$module])) {
$this->jsConfig[$module] = ArrayHelper::merge($this->jsConfig[$module], $params);
} else {
$this->jsConfig[$module] = $params;
}
}
/**
* Renders a string as Ajax including assets.
*
* @param string $content
* @return string Rendered content
*/
public function renderAjaxContent($content)
{
ob_start();
ob_implicit_flush(false);
$this->beginPage();
$this->head();
$this->beginBody();
echo $content;
$this->endBody();
$this->endPage(true);
return ob_get_clean();
}
/**
* Renders a string as Ajax including assets without end page so it can be called several times.
*
* @param string $content
* @return string Rendered content
*/
public function renderAjaxPartial(string $content): string
{
ob_start();
ob_implicit_flush(false);
$this->beginPage();
$this->head();
$this->beginBody();
echo $content;
$this->endBody();
$this->renderEndPage();
return ob_get_clean();
}
/**
* Render of ending page with all attached assets.
* This method doesn't mark a page is ended in order to allow to call it several times.
*/
private function renderEndPage()
{
$this->trigger(self::EVENT_END_PAGE);
$content = ob_get_clean();
echo strtr($content, [
self::PH_HEAD => $this->renderHeadHtml(),
self::PH_BODY_BEGIN => $this->renderBodyBeginHtml(),
self::PH_BODY_END => $this->renderBodyEndHtml(true),
]);
$this->clear();
}
/**
* @inheritdoc
*/
public function renderAjax($view, $params = [], $context = null)
{
$viewFile = $this->findViewFile($view, $context);
ob_start();
ob_implicit_flush(false);
$this->beginPage();
$this->head();
$this->beginBody();
echo $this->renderFile($viewFile, $params, $context);
$this->endBody();
$this->endPage(true);
return ob_get_clean();
}
/**
* @inheritDoc
*/
public function registerAssetBundle($name, $position = null)
{
$bundle = parent::registerAssetBundle($name, $position);
if ($bundle instanceof AssetBundle && !empty($bundle->preload)) {
static::$preload = ArrayHelper::merge(static::$preload, $bundle->preload);
}
return $bundle;
}
protected function registerAssetFiles($name)
{
if (Yii::$app->request->isAjax
&& (in_array($name, AppAsset::STATIC_DEPENDS)
|| in_array($name, CoreBundleAsset::STATIC_DEPENDS)
|| in_array($name, [AppAsset::BUNDLE_NAME, CoreBundleAsset::BUNDLE_NAME]))) {
return;
}
return parent::registerAssetFiles($name);
}
/**
* @inheritdoc
*/
protected function renderBodyBeginHtml()
{
$lines = [];
if (!empty($this->js[self::POS_BEGIN])) {
$lines[] = Html::script(implode("\n", $this->js[self::POS_BEGIN]));
}
$this->js[self::POS_BEGIN] = null;
return parent::renderBodyBeginHtml() . (empty($lines) ? '' : implode("\n", $lines));
}
/**
* @inheritdoc
*/
protected function renderBodyEndHtml($ajaxMode)
{
$lines = [];
if (!empty($this->jsFiles[self::POS_END])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_END]);
}
if ($ajaxMode) {
$scripts = [];
if (!empty($this->js[self::POS_END])) {
$scripts[] = implode("\n", $this->js[self::POS_END]);
}
if (!empty($this->js[self::POS_READY])) {
$scripts[] = implode("\n", $this->js[self::POS_READY]);
}
if (!empty($this->js[self::POS_LOAD])) {
$scripts[] = implode("\n", $this->js[self::POS_LOAD]);
}
if (!empty($scripts)) {
$lines[] = Html::script(implode("\n", $scripts));
}
} else {
if (!empty($this->js[self::POS_END])) {
$lines[] = Html::script(implode("\n", $this->js[self::POS_END]));
}
if (!empty($this->js[self::POS_READY])) {
$js = "jQuery(function ($) {\n" . implode("\n", $this->js[self::POS_READY]) . "\n});";
$lines[] = Html::script($js);
}
if (!empty($this->js[self::POS_LOAD])) {
$js = "jQuery(window).on('load', function () {\n" . implode("\n", $this->js[self::POS_LOAD]) . "\n});";
$lines[] = Html::script($js);
}
}
return empty($lines) ? '' : implode("\n", $lines);
}
/**
* @inheritdoc
*/
protected function renderHeadHtml()
{
if (!Yii::$app->request->isAjax) {
SiteIcon::registerMetaTags($this);
LayoutHeader::registerHeadTags($this);
$this->meta->registerMetaTags($this);
parent::registerCsrfMetaTags();
}
$lines = [];
if (!empty($this->js[self::POS_HEAD])) {
$lines[] = Html::script(implode("\n", $this->js[self::POS_HEAD]));
}
$this->js[self::POS_HEAD] = null;
return parent::renderHeadHtml() . (empty($lines) ? '' : implode("\n", $lines));
}
/**
* @inheritdoc
*/
public function registerJsFile($url, $options = [], $key = null)
{
$cacheBustedUrl = $this->addCacheBustQuery($url);
foreach (static::$preload as $fileName) {
if (strpos($url, $fileName)) {
$this->registerPreload($cacheBustedUrl, 'script');
}
}
Html::setNonce($options);
parent::registerJsFile($this->addCacheBustQuery($url), $options, $key);
}
/**
* @inheritdoc
*/
public function registerCssFile($url, $options = [], $key = null)
{
$cacheBustedUrl = $this->addCacheBustQuery($url);
foreach (static::$preload as $fileName) {
if (strpos($url, $fileName)) {
$this->registerPreload($cacheBustedUrl, 'style');
}
}
parent::registerCssFile($cacheBustedUrl, $options, $key);
}
protected function registerPreload($url, $as)
{
if (!in_array($url, static::$preloaded, true)) {
$this->registerLinkTag((['rel' => 'preload', 'as' => $as, 'href' => $url]));
static::$preloaded[] = $url;
}
}
/**
* Adds cache bust query string to given url if no query is present
*
* @param string $url
* @return string the URL with cache bust paramter
*/
protected function addCacheBustQuery($url)
{
if (strpos($url, '?') === false) {
$file = str_replace('@web', '@webroot', $url);
if (substr($file, 0, 1) === '/') {
$file = '@webroot' . $file;
}
$file = Yii::getAlias($file);
if (file_exists($file)) {
$url .= '?v=' . filemtime($file);
} else {
$url .= '?v=' . urlencode(Yii::$app->version);
}
}
return $url;
}
public function setStatusMessage($type, $message)
{
Yii::$app->getSession()->setFlash('view-status', [$type => $message]);
}
public function saved()
{
$this->success(Yii::t('base', 'Saved'));
}
public function info($message)
{
$this->setStatusMessage('info', $message);
}
public function success($message)
{
$this->setStatusMessage('success', $message);
}
public function error($message)
{
$this->setStatusMessage('error', $message);
}
public function warn($message)
{
$this->setStatusMessage('warn', $message);
}
/**
* @inheritdoc
*/
public function endBody()
{
// Flush jsConfig needed for all types of requests (including pjax/ajax)
$this->flushJsConfig();
// In case of pjax we have to add the title manually, pjax will remove this node
if (Yii::$app->request->isPjax) {
echo '<title>' . $this->getPageTitle() . '</title>';
}
if (Yii::$app->params['installed']) {
if (Yii::$app->getSession()->hasFlash('view-status')) {
$viewStatus = Yii::$app->getSession()->getFlash('view-status');
$type = strtolower(key($viewStatus));
$value = Html::encode(array_values($viewStatus)[0]);
$value = str_replace('"', '', $value);
$value = trim($value);
$this->registerJs('humhub.modules.ui.status.' . $type . '("' . $value . '")', View::POS_END, 'viewStatusMessage');
}
if (Yii::$app->session->hasFlash('executeJavascript')) {
$position = self::POS_READY;
if (Yii::$app->session->hasFlash('executeJavascriptPosition')) {
$position = Yii::$app->session->hasFlash('executeJavascriptPosition');
}
$this->registerJs(Yii::$app->session->getFlash('executeJavascript'), $position);
}
}
if (Yii::$app->request->isPjax) {
$this->registerViewContext();
echo LayoutAddons::widget();
$this->flushJsConfig();
}
if (Yii::$app->request->isAjax) {
return parent::endBody();
}
// Since the JsConfig accesses user queries it fails before installation.
if (Yii::$app->params['installed']) {
CoreJsConfig::widget();
}
// Add LayoutAddons and jsConfig registered by addons
echo LayoutAddons::widget();
$this->registerViewContext();
$this->flushJsConfig();
return parent::endBody();
}
/**
* Registers the client viewContext.
*/
private function registerViewContext()
{
if (!empty(static::$viewContext)) {
$this->registerJs('humhub.modules.ui.view.setViewContext("' . static::$viewContext . '")', View::POS_END, 'viewContext');
}
}
/**
* Writes the currently registered jsConfig entries and flushes the the config array.
*
* @param string $key see View::registerJs
* @since v1.2
*/
protected function flushJsConfig($key = null)
{
if (!empty($this->jsConfig)) {
$this->registerJs("humhub.config.set(" . json_encode($this->jsConfig) . ");", View::POS_BEGIN, $key);
$this->jsConfig = [];
}
}
/**
* @return bool checks if a sidebar exists
*/
public function hasSidebar()
{
return (isset($this->blocks[static::BLOCK_SIDEBAR]) && !ctype_space($this->blocks[static::BLOCK_SIDEBAR]));
}
/**
* Returns the sidebar which is stored in the block called 'sidebar'
*
* @return string returns the rendered sidebar
*/
public function getSidebar()
{
if ($this->hasSidebar()) {
return $this->blocks[static::BLOCK_SIDEBAR];
}
return '';
}
/**
* Sets the currently active viewContext.
* @param $vctx
* @since 1.7
*/
public function setViewContext($vctx)
{
static::$viewContext = $vctx;
}
}