Файл: concrete5.7.5.6/concrete/src/View/View.php
Строк: 421
<?php
namespace ConcreteCoreView;
use ConcreteCoreAssetAsset;
use ConcreteCoreHttpResponseAssetGroup;
use Environment;
use Events;
use PageTheme;
use Page;
use Config;
class View extends AbstractView
{
protected $viewPath;
protected $innerContentFile;
protected $themeHandle;
protected $themeObject;
protected $themeRelativePath;
protected $themeAbsolutePath;
protected $pkgHandle;
protected $viewRootDirectoryName = DIRNAME_VIEWS;
protected function constructView($path = false)
{
$path = '/'.trim($path, '/');
$this->viewPath = $path;
}
public function setPackageHandle($pkgHandle)
{
$this->pkgHandle = $pkgHandle;
}
public function getThemeDirectory()
{
return $this->themeAbsolutePath;
}
public function getViewPath()
{
return $this->viewPath;
}
/**
* gets the relative theme path for use in templates.
*
* @access public
*
* @return string $themePath
*/
public function getThemePath()
{
return $this->themeRelativePath;
}
public function getThemeHandle()
{
return $this->themeHandle;
}
public function setInnerContentFile($innerContentFile)
{
$this->innerContentFile = $innerContentFile;
}
public function setViewRootDirectoryName($directory)
{
$this->viewRootDirectoryName = $directory;
}
public function inc($file, $args = array())
{
extract($args);
extract($this->getScopeItems());
$env = Environment::get();
include $env->getPath(DIRNAME_THEMES.'/'.$this->themeHandle.'/'.$file, $this->pkgHandle);
}
/**
* A shortcut to posting back to the current page with a task and optional parameters. Only works in the context of.
*
* @param string $action
* @param string $task
*
* @return string $url
*/
public function action($action)
{
$a = func_get_args();
$controllerPath = $this->controller->getControllerActionPath();
array_unshift($a, $controllerPath);
$ret = call_user_func_array(array($this, 'url'), $a);
return $ret;
}
public function setViewTheme($theme)
{
if (is_object($theme)) {
$this->themeHandle = $theme->getThemeHandle();
} else {
$this->themeHandle = $theme;
}
if (isset($this->themeObject)) {
$this->themeObject = null;
$this->loadViewThemeObject();
}
}
/**
* Load all the theme-related variables for which theme to use for this request.
*/
protected function loadViewThemeObject()
{
$env = Environment::get();
if ($this->themeHandle) {
if ($this->themeHandle != VIEW_CORE_THEME && $this->themeHandle != 'dashboard') {
if (!isset($this->themeObject)) {
$this->themeObject = PageTheme::getByHandle($this->themeHandle);
$this->pkgHandle = $this->themeObject->getPackageHandle();
}
}
$this->themeAbsolutePath = $env->getPath(DIRNAME_THEMES.'/'.$this->themeHandle, $this->pkgHandle);
$this->themeRelativePath = $env->getURL(DIRNAME_THEMES.'/'.$this->themeHandle, $this->pkgHandle);
}
}
/**
* Begin the render.
*/
public function start($state)
{
}
public function setupRender()
{
// Set the theme object that we should use for this requested page.
// Only run setup if the theme is unset. Usually it will be but if we set it
// programmatically we already have a theme.
$this->loadViewThemeObject();
$env = Environment::get();
if (!$this->innerContentFile) { // will already be set in a legacy tools file
$this->setInnerContentFile($env->getPath($this->viewRootDirectoryName.'/'.trim($this->viewPath, '/').'.php', $this->pkgHandle));
}
if ($this->themeHandle) {
$templateFile = FILENAME_THEMES_VIEW;
if (is_object($this->controller)) {
$templateFile = $this->controller->getThemeViewTemplate();
}
$this->setViewTemplate($env->getPath(DIRNAME_THEMES.'/'.$this->themeHandle.'/'.$templateFile, $this->pkgHandle));
}
}
public function startRender()
{
$event = new SymfonyComponentEventDispatcherGenericEvent();
$event->setArgument('view', $this);
Events::dispatch('on_start', $event);
parent::startRender();
}
protected function onBeforeGetContents()
{
$event = new SymfonyComponentEventDispatcherGenericEvent();
$event->setArgument('view', $this);
Events::dispatch('on_before_render', $event);
if ($this->themeHandle == VIEW_CORE_THEME) {
$_pt = new ConcreteThemeConcretePageTheme();
$_pt->registerAssets();
} elseif (is_object($this->themeObject)) {
$this->themeObject->registerAssets();
}
}
public function renderViewContents($scopeItems)
{
extract($scopeItems);
if ($this->innerContentFile) {
ob_start();
include $this->innerContentFile;
$innerContent = ob_get_contents();
ob_end_clean();
}
if (file_exists($this->template)) {
ob_start();
$this->onBeforeGetContents();
include $this->template;
$contents = ob_get_contents();
$this->onAfterGetContents();
ob_end_clean();
return $contents;
} else {
return $innerContent;
}
}
public function finishRender($contents)
{
$event = new SymfonyComponentEventDispatcherGenericEvent();
$event->setArgument('view', $this);
Events::dispatch('on_render_complete', $event);
return $contents;
}
/**
* Function responsible for outputting header items.
*
* @access private
*/
public function markHeaderAssetPosition()
{
print '<!--ccm:assets:'.Asset::ASSET_POSITION_HEADER.'//-->';
}
/**
* Function responsible for outputting footer items.
*
* @access private
*/
public function markFooterAssetPosition()
{
print '<!--ccm:assets:'.Asset::ASSET_POSITION_FOOTER.'//-->';
}
protected function getAssetsToOutput()
{
$responseGroup = ResponseAssetGroup::get();
$assets = $responseGroup->getAssetsToOutput();
return $assets;
}
public function postProcessViewContents($contents)
{
$assets = $this->getAssetsToOutput();
$contents = $this->replaceAssetPlaceholders($assets, $contents);
// replace any empty placeholders
$contents = $this->replaceEmptyAssetPlaceholders($contents);
return $contents;
}
protected function postProcessAssets($assets)
{
$c = Page::getCurrentPage();
if (!Config::get('concrete.cache.assets')) {
return $assets;
}
if (!count($assets)) {
return array();
}
// goes through all assets in this list, creating new URLs and post-processing them where possible.
$segment = 0;
$groupedAssets = array();
for ($i = 0; $i < count($assets); $i++) {
$asset = $assets[$i];
$nextasset = isset($assets[$i + 1]) ? $assets[$i + 1] : null;
$groupedAssets[$segment][] = $asset;
if (!($asset instanceof Asset) || !($nextasset instanceof Asset)) {
$segment++;
continue;
}
if ($asset->getOutputAssetType() != $nextasset->getOutputAssetType()) {
$segment++;
continue;
}
if (!$asset->assetSupportsCombination() || !$nextasset->assetSupportsCombination()) {
$segment++;
continue;
}
}
$return = array();
// now we have a sub assets array with different segments split by whether they can be combined.
foreach ($groupedAssets as $assets) {
if (
($assets[0] instanceof Asset)
&&
(
(count($assets) > 1)
||
$assets[0]->assetSupportsMinification()
)
) {
$class = get_class($assets[0]);
$assets = call_user_func(array($class, 'process'), $assets);
}
$return = array_merge($return, $assets);
}
return $return;
}
protected function replaceEmptyAssetPlaceholders($pageContent)
{
foreach (array('<!--ccm:assets:'.Asset::ASSET_POSITION_HEADER.'//-->', '<!--ccm:assets:'.Asset::ASSET_POSITION_FOOTER.'//-->') as $comment) {
$pageContent = str_replace($comment, '', $pageContent);
}
return $pageContent;
}
protected function replaceAssetPlaceholders($outputAssets, $pageContent)
{
$outputItems = array();
foreach ($outputAssets as $position => $assets) {
$output = '';
$transformed = $this->postProcessAssets($assets);
foreach ($transformed as $item) {
$itemstring = (string) $item;
if (!in_array($itemstring, $outputItems)) {
$output .= $this->outputAssetIntoView($item);
$outputItems[] = $itemstring;
}
}
$pageContent = str_replace('<!--ccm:assets:'.$position.'//-->', $output, $pageContent);
}
return $pageContent;
}
protected function outputAssetIntoView($item)
{
return $item."n";
}
public static function element($_file, $args = null, $_pkgHandle = null)
{
if (is_array($args)) {
$collisions = array_intersect(array('_file', '_pkgHandle'), array_keys($args));
if ($collisions) {
throw new Exception(t("Illegal variable name '%s' in element args.", implode(', ', $collisions)));
}
$collisions = null;
extract($args);
}
$view = self::getRequestInstance();
include Environment::get()->getPath(DIRNAME_ELEMENTS.'/'.$_file.'.php', $_pkgHandle);
}
}