tao-test/app/tao/models/classes/ThemeRegistry.php

426 lines
12 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2015 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
*
*/
namespace oat\tao\model;
use common_ext_ExtensionsManager;
use oat\oatbox\AbstractRegistry;
use oat\oatbox\service\ServiceManager;
use oat\tao\model\asset\AssetService;
use oat\tao\model\websource\WebsourceManager;
class ThemeRegistry extends AbstractRegistry
{
const WEBSOURCE = 'websource_';
/**
*
* @see \oat\oatbox\AbstractRegistry::getExtension()
*/
protected function getExtension()
{
return common_ext_ExtensionsManager::singleton()->getExtensionById('tao');
}
/**
*
* @see \oat\oatbox\AbstractRegistry::getConfigId()
*/
protected function getConfigId()
{
return 'themes';
}
public function setWebSource($websource)
{
$this->set(ThemeRegistry::WEBSOURCE, $websource);
}
/**
*
* @author Lionel Lecaque, lionel@taotesting.com
* @param string $target
* @param string $themeId
* @throws \common_Exception
*/
public function setDefaultTheme($target, $themeId)
{
$theme = $this->getTheme($target, $themeId);
if (!is_null($theme)) {
$array = $this->get($target);
$array['default'] = $themeId;
$this->set($target, $array);
}
}
/**
* Get the theme array identified by its target and id
*
* @param string $target
* @param string $themeId
* @return array
* @throws \common_Exception
*/
private function getTheme($target, $themeId)
{
$returnValue = null;
if (!$this->isRegistered($target)) {
throw new \common_Exception('Target ' . $target . ' does not exist');
} else {
$array = $this->get($target);
$found = false;
foreach ($array['available'] as $theme) {
if ($theme['id'] == $themeId) {
$found = true;
$returnValue = $theme;
break;
}
}
if (!$found) {
throw new ThemeNotFoundException('Theme ' . $themeId . ' not found for target ' . $target);
}
}
return $returnValue;
}
/**
* Get the default theme array
*/
public function getDefaultTheme($target)
{
$defaultTheme = null;
if (!$this->isRegistered($target)) {
throw new \common_Exception('Target ' . $target . ' does not exist');
} else {
$array = $this->get($target);
if (isset($array['default'])) {
$themeId = $array['default'];
try {
$defaultTheme = $this->getTheme($target, $themeId);
} catch (Exception $e) {
//not found
$defaultTheme = null;
}
}
}
return $defaultTheme;
}
/**
* Adds a new target to the System
*
* @param string $targetId
* @param string|array $base
* @throws \common_Exception
*/
public function createTarget($targetId, $base)
{
if (!is_string($base) && !is_array($base)) {
throw new \common_Exception('Invalid base format');
}
$array = [
'base' => $base,
'available' => []
];
$this->set($targetId, $array);
}
/**
* Adds a theme to the registry
*
* @author Lionel Lecaque, lionel@taotesting.com
* @param string $id
* @param string $name
* @param string $path
* @param array $targets
* @throws \common_Exception
*/
public function registerTheme($id, $name, $path = '', $targets = [], $templates = [])
{
if (preg_match('/^[a-zA-Z0-9]*$/', $id) === 0) {
throw new \common_Exception('Invalid id "' . $id . '"');
}
if (!is_array($targets) || count($targets) === 0) {
throw new \common_Exception('No targets were provided for theme ' . $id);
}
foreach ($targets as $target) {
if (!$this->isRegistered($target)) {
throw new \common_Exception('Target ' . $target . ' does not exist');
} else {
$array = $this->get($target);
foreach ($array['available'] as $theme) {
if ($theme['id'] == $id) {
throw new \common_Exception('Theme ' . $id . ' already exists for target ' . $target);
}
}
$theme = [
'id' => $id,
'name' => $name
];
//the path is optional
if ($path) {
$theme['path'] = $path;
}
//register templates
if (is_array($templates) && count($templates) > 0) {
$theme['templates'] = [];
foreach ($templates as $templateId => $tpl) {
$theme['templates'][$templateId] = $tpl;
}
}
$array['available'][] = $theme;
}
$this->set($target, $array);
}
}
/**
*
* @author Joel Bout, joel@taotesting.com
*
* @param string $id
* @throws \common_Exception
*/
public function unregisterTheme($id)
{
if (preg_match('/^[a-zA-Z0-9]*$/', $id) === 0) {
throw new \common_Exception('Invalid id "' . $id . '"');
}
$isDeleted = false;
$map = $this->getMap();
unset($map[ThemeRegistry::WEBSOURCE]);//still ugly but looks better than 'continue'
foreach ($map as $target => $themes) {
foreach ($themes['available'] as $key => $theme) {
if ($theme['id'] == $id) {
unset($themes['available'][$key]);
$isDeleted = true;
}
}
$this->set($target, $themes);
}
if (!$isDeleted) {
throw new ThemeNotFoundException('Theme ' . $id . ' not found for any target');
}
}
/**
* @param $theme
* @return mixed
*/
private function updatePath($theme)
{
if (isset($theme['path'])) {
if (strpos($theme['path'], ThemeRegistry::WEBSOURCE) === 0) {
$websource = WebsourceManager::singleton()->getWebsource($this->get(ThemeRegistry::WEBSOURCE));
$webUrl = $websource->getAccessUrl(substr($theme['path'], strlen(ThemeRegistry::WEBSOURCE)));
$theme['path'] = $webUrl;
} else {
$assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID);
$theme['path'] = $assetService->getAsset($theme['path']);
}
}
return $theme;
}
/**
* Get the resolved absolute URL for a stylesheet
*
* @param string $path
* @return string
*/
private function resolveStylesheetUrl($path)
{
$websource = WebsourceManager::singleton()->getWebsource($this->get(ThemeRegistry::WEBSOURCE));
if (strpos($path, ThemeRegistry::WEBSOURCE) === 0) {
return $websource->getAccessUrl(substr($path, strlen(ThemeRegistry::WEBSOURCE)));
} else {
$assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID);
return $assetService->getAsset($path);
}
}
/**
* Resolve the template absolute path
*
* @todo make it support templates as data
* @param string $tpl
* @return string
*/
private function resolveTemplatePath($tpl)
{
return ROOT_PATH . $tpl;
}
/**
* Resolve the path and url defined in target "base"
*
* @param string $target
* @return mixed
* @throws common_Exception
*/
private function getResolvedBase($target)
{
$base = null;
$array = $this->get($target);
if (is_string($array['base'])) {
$assetService = $this->getServiceManager()->get(AssetService::SERVICE_ID);
$base = $assetService->getAsset($array['base']);
} elseif (is_array($array['base'])) {
$base = [
'css' => $this->resolveStylesheetUrl($array['base']['css']),
'templates' => []
];
foreach ($array['base']['templates'] as $id => $path) {
$base['templates'][$id] = $this->resolveTemplatePath($path);
}
} else {
throw new common_Exception('invalid type for theme base');
}
return $base;
}
/**
* Get list of available theme
* The available themes have their URL and paths resolved
*
* @author Lionel Lecaque, lionel@taotesting.com
*/
public function getAvailableThemes()
{
$returnValue = [];
foreach ($this->getMap() as $target => $value) {
//ugly
if ($target == ThemeRegistry::WEBSOURCE) {
continue;
}
//retrieve all other value
$returnValue[$target] = $value;
// adapt path for all theme
$returnValue[$target]['available'] = [];
foreach ($value['available'] as $theme) {
$returnValue[$target]['available'][] = $this->updatePath($theme);
}
$returnValue[$target]['base'] = $this->getResolvedBase($target);
}
return $returnValue;
}
/**
* Get the absolute path to a theme template
*
* @deprecated use theme\ThemeService instead
* @param string $target
* @param string $themeId
* @param string $templateId
* @return string
*/
public function getTemplate($target, $themeId, $templateId)
{
$theme = $this->getTheme($target, $themeId);
if (isset($theme['templates']) && isset($theme['templates'][$templateId])) {
return $this->resolveTemplatePath($theme['templates'][$templateId]);
}
return null;
}
/**
* Get the abosolute url to a stylesheet
*
* @deprecated use theme\ThemeService instead
* @param string $target
* @param string $themeId
* @return string
*/
public function getStylesheet($target, $themeId)
{
$theme = $this->getTheme($target, $themeId);
if (isset($theme['path'])) {
return $this->resolveStylesheetUrl($theme['path']);
}
return null;//not found
}
/**
* Get the asbolute path to the base template
*
* @deprecated use theme\ThemeService instead
* @param string $target
* @param string $templateId
* @return string
*/
public function getBaseTemplate($target, $templateId)
{
$base = $this->getResolvedBase($target);
if (is_array($base) && isset($base['templates']) && isset($base['templates'][$templateId])) {
return $base['templates'][$templateId];
}
return null;
}
/**
* Get the absolute url to the base css
*
* @deprecated use theme\ThemeService instead
* @param string $target
* @return string
*/
public function getBaseStylesheet($target)
{
$base = $this->getResolvedBase($target);
if (is_string($base)) {
return $base;
} elseif (is_array($base) && isset($base['css'])) {
return $base['css'];
}
return null;
}
public function getServiceManager()
{
return ServiceManager::getServiceManager();
}
}