N°2060 [WIP] Initialisation of the portal application
@@ -1053,6 +1053,15 @@ class utils
|
||||
{
|
||||
return APPROOT.'data/cache-'.MetaModel::GetEnvironment().'/';
|
||||
}
|
||||
/**
|
||||
* Returns a path to a folder into which any module can store log
|
||||
* @return string
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public static function GetLogPath()
|
||||
{
|
||||
return APPROOT.'log/';
|
||||
}
|
||||
/**
|
||||
* Merge standard menu items with plugin provided menus items
|
||||
*/
|
||||
|
||||
19
datamodels/2.x/itop-portal-base/composer.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"symfony/symfony": "^3.4"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "../../../../lib/composer-vendor"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Combodo\\iTop\\Portal\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Combodo\\iTop\\Portal\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,17 @@ if(!defined('PORTAL_ID'))
|
||||
}
|
||||
|
||||
// Defining portal constants
|
||||
define('PORTAL_MODULE_ID', $sPortalId);
|
||||
define('PORTAL_ID', $sPortalId);
|
||||
}
|
||||
|
||||
require_once APPROOT . '/env-' . utils::GetCurrentEnvironment() . '/itop-portal-base/portal/web/index.php';
|
||||
define('PORTAL_CACHE_PATH', utils::GetCachePath() . '/portals/' . PORTAL_ID . '/');
|
||||
|
||||
// Constants to be used in templates and others
|
||||
define('COMBODO_CURRENT_ENVIRONMENT', utils::GetCurrentEnvironment());
|
||||
define('COMBODO_ABSOLUTE_URL', utils::GetAbsoluteUrlAppRoot());
|
||||
define('COMBODO_MODULES_ABSOLUTE_URL', utils::GetAbsoluteUrlAppRoot() . 'env-' . utils::GetCurrentEnvironment());
|
||||
define('COMBODO_PORTAL_BASE_ABSOLUTE_URL', utils::GetAbsoluteUrlAppRoot() . 'env-' . utils::GetCurrentEnvironment() . '/itop-portal-base/portal/public/');
|
||||
define('COMBODO_PORTAL_BASE_ABSOLUTE_PATH', MODULESROOT . '/itop-portal-base/portal/public/');
|
||||
define('COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL', utils::GetAbsoluteUrlAppRoot() . 'env-' . utils::GetCurrentEnvironment() . '/' . PORTAL_ID . '/');
|
||||
|
||||
require_once APPROOT . '/env-' . utils::GetCurrentEnvironment() . '/itop-portal-base/portal/public/index.php';
|
||||
|
||||
@@ -13,11 +13,10 @@ SetupWebPage::AddModule(
|
||||
'visible' => true,
|
||||
// Components
|
||||
'datamodel' => array(
|
||||
'portal/src/controllers/abstractcontroller.class.inc.php',
|
||||
'portal/src/controllers/brickcontroller.class.inc.php',
|
||||
'portal/src/entities/abstractbrick.class.inc.php',
|
||||
'portal/src/entities/portalbrick.class.inc.php',
|
||||
'portal/src/routers/abstractrouter.class.inc.php',
|
||||
// 'portal/src/controllers/brickcontroller.class.inc.php',
|
||||
// 'portal/src/entities/abstractbrick.class.inc.php',
|
||||
// 'portal/src/entities/portalbrick.class.inc.php',
|
||||
// 'portal/src/routers/abstractrouter.class.inc.php',
|
||||
),
|
||||
'webservice' => array(
|
||||
//'webservices.itop-portal-base.php',
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Portal\Controller;
|
||||
|
||||
/**
|
||||
* Class AbstractController
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Controller
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 2.3.0
|
||||
*/
|
||||
abstract class AbstractController
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Portal\Controller;
|
||||
|
||||
use Silex\Application;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Class DefaultController
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Controller
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 2.3.0
|
||||
*/
|
||||
class DefaultController
|
||||
{
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
* @param \Silex\Application $oApp
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function homeAction(Request $oRequest, Application $oApp)
|
||||
{
|
||||
$aData = array();
|
||||
|
||||
// Rendering tiles
|
||||
$aData['aTilesRendering'] = array();
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */
|
||||
foreach($oApp['combodo.portal.instance.conf']['bricks'] as $oBrick)
|
||||
{
|
||||
// Doing it only for tile visible on home page to avoid unnecessary rendering
|
||||
if (($oBrick->GetVisibleHome() === true) && ($oBrick->GetTileControllerAction() !== null))
|
||||
{
|
||||
$aControllerActionParts = explode('::', $oBrick->GetTileControllerAction());
|
||||
if (count($aControllerActionParts) !== 2)
|
||||
{
|
||||
$oApp->abort(500, 'Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "' . $oBrick->GetId() . '"');
|
||||
}
|
||||
|
||||
$sControllerName = $aControllerActionParts[0];
|
||||
$sControllerAction = $aControllerActionParts[1];
|
||||
|
||||
$oController = new $sControllerName($oRequest, $oApp, $oBrick->GetId());
|
||||
$aData['aTilesRendering'][$oBrick->GetId()] = $oController->$sControllerAction($oRequest, $oApp, $oBrick->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
// Home page template
|
||||
$template = $oApp['combodo.portal.instance.conf']['properties']['templates']['home'];
|
||||
|
||||
return $oApp['twig']->render($template, $aData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,618 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
|
||||
use DBSearch;
|
||||
use DBUnionSearch;
|
||||
use DOMFormatException;
|
||||
use DOMNodeList;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
use ProfilesConfig;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class ScopeValidatorHelper
|
||||
*
|
||||
* Inside the portal this service is injected, get the instance using $oApp['scope_validator']
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Helper
|
||||
*/
|
||||
class ScopeValidatorHelper
|
||||
{
|
||||
const ENUM_MODE_READ = 'r';
|
||||
const ENUM_MODE_WRITE = 'w';
|
||||
const ENUM_TYPE_ALLOW = 'allow';
|
||||
const ENUM_TYPE_RESTRICT = 'restrict';
|
||||
const DEFAULT_GENERATED_CLASS = 'PortalScopesValues';
|
||||
const DEFAULT_IGNORE_SILOS = false;
|
||||
|
||||
protected $sCachePath;
|
||||
protected $sFilename;
|
||||
protected $sInstancePrefix;
|
||||
protected $sGeneratedClass;
|
||||
protected $aProfilesMatrix;
|
||||
|
||||
public static function EnumTypeValues()
|
||||
{
|
||||
return array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT);
|
||||
}
|
||||
|
||||
public function __construct($sFilename, $sCachePath = null)
|
||||
{
|
||||
$this->sFilename = $sFilename;
|
||||
$this->sCachePath = $sCachePath;
|
||||
$this->sInstancePrefix = '';
|
||||
$this->sGeneratedClass = static::DEFAULT_GENERATED_CLASS;
|
||||
$this->aProfilesMatrix = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path where to cache the compiled scopes file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetCachePath()
|
||||
{
|
||||
return $this->sCachePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the compiled scopes file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetFilename()
|
||||
{
|
||||
return $this->sFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance prefix used for the generated scopes class name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetInstancePrefix()
|
||||
{
|
||||
return $this->sInstancePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the generated scopes class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetGeneratedClass()
|
||||
{
|
||||
return $this->sGeneratedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scope validator instance prefix.
|
||||
*
|
||||
* This is used to create a unique scope values class in the cache directory (/data/cache-<ENV>) as there can be several instance of the portal.
|
||||
*
|
||||
* @param string $sInstancePrefix
|
||||
* @return \Combodo\iTop\Portal\Helper\ScopeValidatorHelper
|
||||
*/
|
||||
public function SetInstancePrefix($sInstancePrefix)
|
||||
{
|
||||
$sInstancePrefix = preg_replace('/[-_]/', ' ', $sInstancePrefix);
|
||||
$sInstancePrefix = ucwords($sInstancePrefix);
|
||||
$sInstancePrefix = str_replace(' ', '', $sInstancePrefix);
|
||||
|
||||
$this->sInstancePrefix = $sInstancePrefix;
|
||||
$this->sGeneratedClass = $this->sInstancePrefix . static::DEFAULT_GENERATED_CLASS;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the ScopeValidator by generating and caching the scopes compilation in the $this->sCachePath.$this->sFilename file.
|
||||
*
|
||||
* @param DOMNodeList $oNodes
|
||||
* @throws DOMFormatException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
// Checking cache path
|
||||
if ($this->sCachePath === null)
|
||||
{
|
||||
$this->sCachePath = utils::GetCachePath();
|
||||
}
|
||||
// Building full pathname for file
|
||||
$sFilePath = $this->sCachePath . $this->sFilename;
|
||||
|
||||
// Creating file if not existing
|
||||
// Note : This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...)
|
||||
if (!file_exists($sFilePath))
|
||||
{
|
||||
// - Build php array from xml
|
||||
$aProfiles = array();
|
||||
// This will be used to know which classes have been set, so we can set the missing ones.
|
||||
$aProfileClasses = array();
|
||||
// Iterating over the class nodes
|
||||
foreach ($oNodes as $oClassNode)
|
||||
{
|
||||
// retrieving mandatory class id attribute
|
||||
$sClass = $oClassNode->getAttribute('id');
|
||||
if ($sClass === '')
|
||||
{
|
||||
throw new DOMFormatException('Class tag must have an id attribute.', null, null, $oClassNode);
|
||||
}
|
||||
|
||||
// Iterating over scope nodes of the class
|
||||
$oScopesNode = $oClassNode->GetOptionalElement('scopes');
|
||||
if ($oScopesNode !== null)
|
||||
{
|
||||
foreach ($oScopesNode->GetNodes('./scope') as $oScopeNode)
|
||||
{
|
||||
// Retrieving mandatory scope id attribute
|
||||
$sScopeId = $oScopeNode->getAttribute('id');
|
||||
if ($sScopeId === '')
|
||||
{
|
||||
throw new DOMFormatException('Scope tag must have an id attribute.', null, null, $oScopeNode);
|
||||
}
|
||||
|
||||
// Retrieving the type of query
|
||||
// Note : This has been disabled as we don't want deny rules for now
|
||||
// $oOqlViewTypeNode = $oClassNode->GetOptionalElement('oql_view_type');
|
||||
// $sOqlViewType = ($oOqlViewTypeNode !== null && ($oOqlViewTypeNode->GetText() === static::ENUM_TYPE_RESTRICT)) ? static::ENUM_TYPE_RESTRICT : static::ENUM_TYPE_ALLOW;
|
||||
$sOqlViewType = static::ENUM_TYPE_ALLOW;
|
||||
// Retrieving the view query
|
||||
$oOqlViewNode = $oScopeNode->GetUniqueElement('oql_view');
|
||||
$sOqlView = $oOqlViewNode->GetText();
|
||||
if ($sOqlView === null)
|
||||
{
|
||||
throw new DOMFormatException('Scope tag in class must have a not empty oql_view tag', null, null, $oScopeNode);
|
||||
}
|
||||
// Retrieving the edit query
|
||||
$oOqlEditNode = $oScopeNode->GetOptionalElement('oql_edit');
|
||||
$sOqlEdit = ( ($oOqlEditNode !== null) && ($oOqlEditNode->GetText() !== null) ) ? $oOqlEditNode->GetText() : null;
|
||||
// Retrieving ignore allowed org flag
|
||||
$oIgnoreSilosNode = $oScopeNode->GetOptionalElement('ignore_silos');
|
||||
$bIgnoreSilos = ( ($oIgnoreSilosNode !== null) && ($oIgnoreSilosNode->GetText() === 'true') ) ? true : static::DEFAULT_IGNORE_SILOS;
|
||||
|
||||
// Retrieving profiles for the scope
|
||||
$oProfilesNode = $oScopeNode->GetOptionalElement('allowed_profiles');
|
||||
$aProfilesNames = array();
|
||||
// If no profile is specified, we consider that it's for ALL the profiles
|
||||
if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
$aProfilesNames[] = $aValue['name'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode)
|
||||
{
|
||||
// Retrieving mandatory profile id attribute
|
||||
$sProfileId = $oProfileNode->getAttribute('id');
|
||||
if ($sProfileId === '')
|
||||
{
|
||||
throw new DOMFormatException('Scope tag must have an id attribute.', null, null, $oProfileNode);
|
||||
}
|
||||
$aProfilesNames[] = $sProfileId;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
foreach ($aProfilesNames as $sProfileName)
|
||||
{
|
||||
// Scope profile id
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfileName);
|
||||
|
||||
// Now that we have the queries infos, we are going to build the queries for that profile / class
|
||||
$sMatrixPrefix = $iProfileId . '_' . $sClass . '_';
|
||||
// - View query
|
||||
$oViewFilter = DBSearch::FromOQL($sOqlView);
|
||||
// ... We have to union the query if this profile has another scope for that class
|
||||
if (array_key_exists($sMatrixPrefix . static::ENUM_MODE_READ, $aProfiles) && array_key_exists($sOqlViewType, $aProfiles[$sMatrixPrefix . static::ENUM_MODE_READ]))
|
||||
{
|
||||
$oExistingFilter = DBSearch::FromOQL($aProfiles[$sMatrixPrefix . static::ENUM_MODE_READ][$sOqlViewType]);
|
||||
$aFilters = array($oExistingFilter, $oViewFilter);
|
||||
$oResFilter = new DBUnionSearch($aFilters);
|
||||
|
||||
// Applying ignore_silos flag on result filter if necessary (As the union will remove it if it is not on all sub-queries)
|
||||
if ($aProfiles[$sMatrixPrefix . static::ENUM_MODE_READ]['ignore_silos'] === true)
|
||||
{
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oResFilter = $oViewFilter;
|
||||
}
|
||||
$aProfiles[$sMatrixPrefix . static::ENUM_MODE_READ] = array(
|
||||
$sOqlViewType => $oResFilter->ToOQL(),
|
||||
'ignore_silos' => $bIgnoreSilos
|
||||
);
|
||||
// - Edit query
|
||||
if ($sOqlEdit !== null)
|
||||
{
|
||||
$oEditFilter = DBSearch::FromOQL($sOqlEdit);
|
||||
// - If the queries are the same, we don't make an intersect, we just reuse the view query
|
||||
if ($sOqlEdit === $sOqlView)
|
||||
{
|
||||
// Do not intersect, edit query is identical to view query
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($oEditFilter->GetClass() === $oViewFilter->GetClass()) && $oEditFilter->IsAny())
|
||||
{
|
||||
$oEditFilter = $oViewFilter;
|
||||
// Do not intersect, edit query is identical to view query
|
||||
}
|
||||
else
|
||||
{
|
||||
// Intersect
|
||||
$oEditFilter = $oViewFilter->Intersect($oEditFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// ... We have to union the query if this profile has another scope for that class
|
||||
if (array_key_exists($sMatrixPrefix . static::ENUM_MODE_WRITE, $aProfiles) && array_key_exists($sOqlViewType, $aProfiles[$sMatrixPrefix . static::ENUM_MODE_WRITE]))
|
||||
{
|
||||
$oExistingFilter = DBSearch::FromOQL($aProfiles[$sMatrixPrefix . static::ENUM_MODE_WRITE][$sOqlViewType]);
|
||||
$aFilters = array($oExistingFilter, $oEditFilter);
|
||||
$oResFilter = new DBUnionSearch($aFilters);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oResFilter = $oEditFilter;
|
||||
}
|
||||
$aProfiles[$sMatrixPrefix . static::ENUM_MODE_WRITE] = array(
|
||||
$sOqlViewType => $oResFilter->ToOQL(),
|
||||
'ignore_silos' => $bIgnoreSilos
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aProfileClasses[] = $sClass;
|
||||
}
|
||||
}
|
||||
|
||||
// Filling the array with missing classes from MetaModel, so we can have an inheritance principle on the scope
|
||||
// For each class explicitly given in the scopes, we check if its child classes were also in the scope :
|
||||
// If not, we add them with the same OQL
|
||||
foreach ($aProfileClasses as $sProfileClass)
|
||||
{
|
||||
foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass)
|
||||
{
|
||||
// If the child class is not in the scope, we are going to try to add it
|
||||
if (!in_array($sChildClass, $aProfileClasses))
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
$iProfileId = $iKey;
|
||||
foreach (array(static::ENUM_MODE_READ, static::ENUM_MODE_WRITE) as $sAction)
|
||||
{
|
||||
// If the current profile has scope for that class in that mode, we duplicate it
|
||||
if (isset($aProfiles[$iProfileId . '_' . $sProfileClass . '_' . $sAction]))
|
||||
{
|
||||
$aTmpProfile = $aProfiles[$iProfileId . '_' . $sProfileClass . '_' . $sAction];
|
||||
foreach ($aTmpProfile as $sType => $sOql)
|
||||
{
|
||||
// IF condition is just to skip the 'ignore_silos' flag
|
||||
if (in_array($sType, array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT)))
|
||||
{
|
||||
$oTmpFilter = DBSearch::FromOQL($sOql);
|
||||
$oTmpFilter->ChangeClass($sChildClass);
|
||||
|
||||
$aTmpProfile[$sType] = $oTmpFilter->ToOQL();
|
||||
}
|
||||
}
|
||||
|
||||
$aProfiles[$iProfileId . '_' . $sChildClass . '_' . $sAction] = $aTmpProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - Build php class
|
||||
$sPHP = $this->BuildPHPClass($aProfiles);
|
||||
|
||||
// - Write file on disk
|
||||
// - Creating dir if necessary
|
||||
if (!is_dir($this->sCachePath))
|
||||
{
|
||||
mkdir($this->sCachePath, 0777, true);
|
||||
}
|
||||
// -- Then creating the file
|
||||
$ret = file_put_contents($sFilePath, $sPHP);
|
||||
if ($ret === false)
|
||||
{
|
||||
$iLen = strlen($sPHP);
|
||||
$fFree = @disk_free_space(dirname($sFilePath));
|
||||
$aErr = error_get_last();
|
||||
throw new Exception("Failed to write '$sFilePath'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists($this->sGeneratedClass))
|
||||
{
|
||||
require_once $this->sCachePath . $this->sFilename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DBSearch for the $sProfile in $iAction for the class $sClass
|
||||
*
|
||||
* @param string $sProfile
|
||||
* @param string $sClass
|
||||
* @param integer $iAction
|
||||
*
|
||||
* @return \DBSearch
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function GetScopeFilterForProfile($sProfile, $sClass, $iAction = null)
|
||||
{
|
||||
return $this->GetScopeFilterForProfiles(array($sProfile), $sClass, $iAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DBSearch for the $aProfiles in $iAction for the class $sClass.
|
||||
* Profiles are a OR condition.
|
||||
*
|
||||
* @param array $aProfiles
|
||||
* @param string $sClass
|
||||
* @param integer $iAction
|
||||
*
|
||||
* @return \DBSearch
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function GetScopeFilterForProfiles($aProfiles, $sClass, $iAction = null)
|
||||
{
|
||||
$oSearch = null;
|
||||
$aAllowSearches = array();
|
||||
$aRestrictSearches = array();
|
||||
$bIgnoreSilos = static::DEFAULT_IGNORE_SILOS;
|
||||
|
||||
// Checking the default mode
|
||||
if ($iAction === null)
|
||||
{
|
||||
$iAction = UR_ACTION_READ;
|
||||
}
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
// Retrieving matrix informtions
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfile);
|
||||
$sMode = ($iAction === UR_ACTION_READ) ? static::ENUM_MODE_READ : static::ENUM_MODE_WRITE;
|
||||
|
||||
// Retrieving profile OQLs
|
||||
$sScopeValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sScopeValuesClass::GetProfileScope($iProfileId, $sClass, $sMode);
|
||||
if ($aProfileMatrix !== null)
|
||||
{
|
||||
if (isset($aProfileMatrix['allow']) && $aProfileMatrix['allow'] !== null)
|
||||
{
|
||||
$aAllowSearches[] = DBSearch::FromOQL($aProfileMatrix['allow']);
|
||||
}
|
||||
if (isset($aProfileMatrix['restrict']) && $aProfileMatrix['restrict'] !== null)
|
||||
{
|
||||
$aRestrictSearches[] = DBSearch::FromOQL($aProfileMatrix['restrict']);
|
||||
}
|
||||
// If a profile should ignore allowed org, we set it for all its queries no matter the profile
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true)
|
||||
{
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Building the real OQL from all the parts from the differents profiles
|
||||
for ($i = 0; $i < count($aAllowSearches); $i++)
|
||||
{
|
||||
foreach ($aRestrictSearches as $oRestrictSearch)
|
||||
{
|
||||
$aAllowSearches[$i] = $aAllowSearches[$i]->Intersect($oRestrictSearch);
|
||||
}
|
||||
}
|
||||
if (count($aAllowSearches) > 0)
|
||||
{
|
||||
$oSearch = new DBUnionSearch($aAllowSearches);
|
||||
$oSearch = $oSearch->RemoveDuplicateQueries();
|
||||
}
|
||||
if ($bIgnoreSilos === true)
|
||||
{
|
||||
$oSearch->AllowAllData();
|
||||
}
|
||||
|
||||
return $oSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the scope query (view or edit depending on $sAction) for $sClass to the $oQuery.
|
||||
*
|
||||
* @param \DBSearch $oQuery
|
||||
* @param string $sClass
|
||||
* @param int $sAction
|
||||
*
|
||||
* @return bool true if scope exists, false if scope is null
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function AddScopeToQuery(DBSearch &$oQuery, $sClass, $sAction = UR_ACTION_READ)
|
||||
{
|
||||
$oScopeQuery = $this->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sClass, $sAction);
|
||||
if ($oScopeQuery !== null)
|
||||
{
|
||||
$oQuery = $oQuery->Intersect($oScopeQuery);
|
||||
// - Allowing all data if necessary
|
||||
if ($oScopeQuery->IsAllDataAllowed())
|
||||
{
|
||||
$oQuery->AllowAllData();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if at least one of the $aProfiles has the ignore_silos flag set to true for the $sClass.
|
||||
*
|
||||
* @param array $aProfiles
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function IsAllDataAllowedForScope($aProfiles, $sClass)
|
||||
{
|
||||
$bIgnoreSilos = false;
|
||||
|
||||
// Iterating on profiles to retrieving the different OQLs parts
|
||||
foreach ($aProfiles as $sProfile)
|
||||
{
|
||||
// Retrieving matrix informtions
|
||||
$iProfileId = $this->GetProfileIdFromProfileName($sProfile);
|
||||
|
||||
// Retrieving profile OQLs
|
||||
$sScopeValuesClass = $this->sGeneratedClass;
|
||||
$aProfileMatrix = $sScopeValuesClass::GetProfileScope($iProfileId, $sClass, static::ENUM_MODE_READ);
|
||||
if ($aProfileMatrix !== null)
|
||||
{
|
||||
// If a profile should ignore allowed org, we set it for all its queries no matter the profile
|
||||
if (isset($aProfileMatrix['ignore_silos']) && $aProfileMatrix['ignore_silos'] === true)
|
||||
{
|
||||
$bIgnoreSilos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bIgnoreSilos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the profile id from a string being either a constant or its name.
|
||||
*
|
||||
* @param string $sProfile
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GetProfileIdFromProfileName($sProfile)
|
||||
{
|
||||
$iProfileId = null;
|
||||
|
||||
// We try to find the profile from its name in order to retrieve it's id
|
||||
// - If the regular UserRights addon is installed we check the profiles array
|
||||
if (class_exists('ProfilesConfig'))
|
||||
{
|
||||
if (defined($sProfile) && in_array($sProfile, ProfilesConfig::GetProfilesValues()))
|
||||
{
|
||||
$iProfileId = constant($sProfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue)
|
||||
{
|
||||
if ($aValue['name'] === $sProfile)
|
||||
{
|
||||
$iProfileId = $iKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// - Else, we can't find the id from the name as we don't know the used UserRights addon. It has to be a constant
|
||||
else
|
||||
{
|
||||
throw new Exception('Scope validator : Unknown UserRights addon, scope\'s profile must be a constant');
|
||||
}
|
||||
|
||||
// If profile was not found from its name or from a constant, we throw an exception
|
||||
if ($iProfileId === null)
|
||||
{
|
||||
throw new Exception('Scope validator : Could not find "' . $sProfile . '" in the profiles list');
|
||||
}
|
||||
|
||||
return $iProfileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the generated PHP class for the compiled scopes
|
||||
*
|
||||
* @param array $aProfiles
|
||||
* @return string
|
||||
*/
|
||||
protected function BuildPHPClass($aProfiles = array())
|
||||
{
|
||||
$sProfiles = var_export($aProfiles, true);
|
||||
$sClassName = $this->sGeneratedClass;
|
||||
$sPHP = <<<EOF
|
||||
<?php
|
||||
|
||||
// File generated by ScopeValidatorHelper
|
||||
//
|
||||
// Please do not edit manually
|
||||
// List of constant scopes
|
||||
// - used by the portal ScopeValidatorHelper
|
||||
//
|
||||
class $sClassName
|
||||
{
|
||||
protected static \$aPROFILES = $sProfiles;
|
||||
|
||||
/**
|
||||
* @param integer \$iProfileId
|
||||
* @param string \$sClass
|
||||
* @param string \$sAction 'r'|'w'
|
||||
*/
|
||||
public static function GetProfileScope(\$iProfileId, \$sClass, \$sAction)
|
||||
{
|
||||
\$sQuery = null;
|
||||
|
||||
\$sScopeKey = \$iProfileId.'_'.\$sClass.'_'.\$sAction;
|
||||
if (isset(self::\$aPROFILES[\$sScopeKey]))
|
||||
{
|
||||
\$sQuery = self::\$aPROFILES[\$sScopeKey];
|
||||
}
|
||||
|
||||
return \$sQuery;
|
||||
}
|
||||
}
|
||||
|
||||
EOF;
|
||||
|
||||
return $sPHP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Portal\Router;
|
||||
|
||||
|
||||
/**
|
||||
* Class DefaultRouter
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Router
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 2.3.0
|
||||
*/
|
||||
class DefaultRouter extends AbstractRouter
|
||||
{
|
||||
static $aRoutes = array(
|
||||
array('pattern' => '/',
|
||||
'callback' => 'Combodo\\iTop\\Portal\\Controller\\DefaultController::homeAction',
|
||||
'bind' => 'p_home'),
|
||||
// // Example route
|
||||
// array('pattern' => '/url-pattern',
|
||||
// 'hash' => 'string-to-be-append-to-the-pattern-after-a-#',
|
||||
// 'navigation_menu_attr' => array('id' => 'link_id', 'rel' => 'foo'),
|
||||
// 'callback' => 'Combodo\\iTop\\Portal\\Controller\\DefaultController::exampleAction',
|
||||
// 'bind' => 'p_example')
|
||||
);
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Portal\Router;
|
||||
|
||||
/**
|
||||
* Class UserProfileRouter
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Router
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 2.3.0
|
||||
*/
|
||||
class UserProfileRouter extends AbstractRouter
|
||||
{
|
||||
static $aRoutes = array(
|
||||
array('pattern' => '/user/{sBrickId}',
|
||||
'callback' => 'Combodo\\iTop\\Portal\\Controller\\UserProfileBrickController::DisplayAction',
|
||||
'bind' => 'p_user_profile_brick',
|
||||
'values' => array(
|
||||
'sBrickId' => null
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
21
datamodels/2.x/itop-portal-base/portal/.env
Normal file
@@ -0,0 +1,21 @@
|
||||
# In all environments, the following files are loaded if they exist,
|
||||
# the later taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=40ef8b29be00df19cec62edf08f73808
|
||||
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
|
||||
#TRUSTED_HOSTS='^localhost|example\.com$'
|
||||
###< symfony/framework-bundle ###
|
||||
9
datamodels/2.x/itop-portal-base/portal/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
42
datamodels/2.x/itop-portal-base/portal/bin/console
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Debug\Debug;
|
||||
|
||||
if (false === in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {
|
||||
echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.\PHP_SAPI.' SAPI'.\PHP_EOL;
|
||||
}
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
if (!class_exists(Application::class)) {
|
||||
throw new RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.');
|
||||
}
|
||||
|
||||
$input = new ArgvInput();
|
||||
if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) {
|
||||
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
|
||||
}
|
||||
|
||||
if ($input->hasParameterOption('--no-debug', true)) {
|
||||
putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
|
||||
}
|
||||
|
||||
require dirname(__DIR__).'/config/bootstrap.php';
|
||||
|
||||
if ($_SERVER['APP_DEBUG']) {
|
||||
umask(0000);
|
||||
|
||||
if (class_exists(Debug::class)) {
|
||||
Debug::enable();
|
||||
}
|
||||
}
|
||||
|
||||
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
|
||||
$application = new Application($kernel);
|
||||
$application->run($input);
|
||||
60
datamodels/2.x/itop-portal-base/portal/composer.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"symfony/console": "3.4.*",
|
||||
"symfony/dotenv": "3.4.*",
|
||||
"symfony/flex": "^1.1",
|
||||
"symfony/framework-bundle": "3.4.*",
|
||||
"symfony/twig-bundle": "3.4.*",
|
||||
"symfony/yaml": "3.4.*"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "../../../../lib/composer-vendor",
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Combodo\\iTop\\Portal\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Combodo\\iTop\\Portal\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"paragonie/random_compat": "2.*",
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php70": "*",
|
||||
"symfony/polyfill-php56": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "3.4.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
1607
datamodels/2.x/itop-portal-base/portal/composer.lock
generated
Normal file
51
datamodels/2.x/itop-portal-base/portal/config/bootstrap.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
require APPROOT.'/lib/composer-vendor/autoload.php';
|
||||
|
||||
// Load cached env vars if the .env.local.php file exists
|
||||
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
|
||||
if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) {
|
||||
$_ENV += $env;
|
||||
} elseif (!class_exists(Dotenv::class)) {
|
||||
throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
|
||||
} else {
|
||||
$path = dirname(__DIR__).'/.env';
|
||||
$dotenv = new Dotenv(false);
|
||||
|
||||
// load all the .env files
|
||||
if (method_exists($dotenv, 'loadEnv')) {
|
||||
$dotenv->loadEnv($path);
|
||||
} else {
|
||||
// fallback code in case your Dotenv component is not 4.2 or higher (when loadEnv() was added)
|
||||
|
||||
if (file_exists($path) || !file_exists($p = "$path.dist")) {
|
||||
$dotenv->load($path);
|
||||
} else {
|
||||
$dotenv->load($p);
|
||||
}
|
||||
|
||||
if (null === $env = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null))) {
|
||||
$dotenv->populate(array('APP_ENV' => $env = 'dev'));
|
||||
}
|
||||
|
||||
if ('test' !== $env && file_exists($p = "$path.local")) {
|
||||
$dotenv->load($p);
|
||||
$env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : $env);
|
||||
}
|
||||
|
||||
if (file_exists($p = "$path.$env")) {
|
||||
$dotenv->load($p);
|
||||
}
|
||||
|
||||
if (file_exists($p = "$path.$env.local")) {
|
||||
$dotenv->load($p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$_SERVER += $_ENV;
|
||||
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) ?: 'dev';
|
||||
$_SERVER['APP_DEBUG'] = (isset($_SERVER['APP_DEBUG']) ? $_SERVER['APP_DEBUG'] : (isset($_ENV['APP_DEBUG']) ? $_ENV['APP_DEBUG'] : 'prod')) !== $_SERVER['APP_ENV'];
|
||||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
];
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
// Loading file
|
||||
use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Basic;
|
||||
use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Forms;
|
||||
use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Lists;
|
||||
|
||||
// Note: ModuleDesign service is not available yet as this script is processed before service generation,
|
||||
// that's why we have to instantiate it manually.
|
||||
require_once APPROOT . 'core/moduledesign.class.inc.php';
|
||||
$moduleDesign = new \ModuleDesign(PORTAL_ID);
|
||||
|
||||
// TODO: The following code needs to be refactored to more independent and atomic services.
|
||||
|
||||
//append into %combodo.portal.instance.conf%
|
||||
$basicCompat = new Basic($moduleDesign);
|
||||
$basicCompat->process($container);
|
||||
|
||||
//create %combodo.portal.instance.conf%
|
||||
$formsCompat = new Forms($moduleDesign);
|
||||
$formsCompat->process($container);
|
||||
|
||||
//append into %combodo.portal.instance.conf%
|
||||
$listesCompat = new Lists($moduleDesign);
|
||||
$listesCompat->process($container);
|
||||
|
||||
// - Generating CSS files
|
||||
$aImportPaths = array(COMBODO_PORTAL_BASE_ABSOLUTE_PATH.'css/');
|
||||
$aPortalConf = $container->getParameter('combodo.portal.instance.conf');
|
||||
foreach ($aPortalConf['properties']['themes'] as $key => $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
{
|
||||
$aPortalConf['properties']['themes'][$key] = COMBODO_ABSOLUTE_URL.utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, $aImportPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aValues = array();
|
||||
foreach ($value as $sSubvalue)
|
||||
{
|
||||
$aValues[] = COMBODO_ABSOLUTE_URL.utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$sSubvalue, $aImportPaths);
|
||||
}
|
||||
$aPortalConf['properties']['themes'][$key] = $aValues;
|
||||
}
|
||||
}
|
||||
$container->setParameter('combodo.portal.instance.conf', $aPortalConf);
|
||||
|
||||
//TODO: The following needs to be refactored
|
||||
//session messages
|
||||
$aAllMessages = array();
|
||||
if ((array_key_exists('obj_messages', $_SESSION)) && (!empty($_SESSION['obj_messages'])))
|
||||
{
|
||||
foreach ($_SESSION['obj_messages'] as $sMessageKey => $aMessageObjectData)
|
||||
{
|
||||
$aObjectMessages = array();
|
||||
$aRanks = array();
|
||||
foreach ($aMessageObjectData as $sMessageId => $aMessageData)
|
||||
{
|
||||
$sMsgClass = 'alert alert-';
|
||||
switch ($aMessageData['severity'])
|
||||
{
|
||||
case 'info':
|
||||
$sMsgClass .= 'info';
|
||||
break;
|
||||
case 'error':
|
||||
$sMsgClass .= 'danger';
|
||||
break;
|
||||
case 'ok':
|
||||
default:
|
||||
$sMsgClass .= 'success';
|
||||
break;
|
||||
}
|
||||
$aObjectMessages[] = array('cssClass' => $sMsgClass, 'message' => $aMessageData['message']);
|
||||
$aRanks[] = $aMessageData['rank'];
|
||||
}
|
||||
unset($_SESSION['obj_messages'][$sMessageKey]);
|
||||
array_multisort($aRanks, $aObjectMessages);
|
||||
foreach ($aObjectMessages as $aObjectMessage)
|
||||
{
|
||||
$aAllMessages[] = $aObjectMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
$container->setParameter('combodo.current_user.session_messages', $aAllMessages);
|
||||
@@ -0,0 +1,19 @@
|
||||
framework:
|
||||
cache:
|
||||
# Put the unique name of your app here: the prefix seed
|
||||
# is used to compute stable namespaces for cache keys.
|
||||
#prefix_seed: your_vendor_name/app_name
|
||||
|
||||
# The app cache caches to the filesystem by default.
|
||||
# Other options include:
|
||||
|
||||
# Redis
|
||||
#app: cache.adapter.redis
|
||||
#default_redis_provider: redis://localhost
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
#pools:
|
||||
#my.dedicated.cache: ~
|
||||
@@ -0,0 +1,3 @@
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: true
|
||||
@@ -0,0 +1,15 @@
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#default_locale: en
|
||||
#csrf_protection: true
|
||||
#http_method_override: true
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
handler_id: ~
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
@@ -0,0 +1,3 @@
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: ~
|
||||
@@ -0,0 +1,4 @@
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_id: session.storage.mock_file
|
||||
@@ -0,0 +1,3 @@
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: true
|
||||
@@ -0,0 +1,4 @@
|
||||
twig:
|
||||
default_path: '%combodo.modules.absolute_path%'
|
||||
debug: '%kernel.debug%'
|
||||
strict_variables: '%kernel.debug%'
|
||||
40
datamodels/2.x/itop-portal-base/portal/config/routes.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright (C) 2010-2018 Combodo SARL
|
||||
#
|
||||
# This file is part of iTop.
|
||||
#
|
||||
# iTop is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# iTop 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
# This file is the entry point to configure your own HTTP routes.
|
||||
# Files in the routes/ subdirectory configure the routes for your dependencies.
|
||||
|
||||
defaults:
|
||||
resource: 'routes/default.yaml'
|
||||
|
||||
#browse_brick:
|
||||
# resource: 'routes/browse_brick.yaml'
|
||||
#
|
||||
#create_brick:
|
||||
# resource: 'routes/create_brick.yaml'
|
||||
#
|
||||
#manage_brick:
|
||||
# resource: 'routes/manage_brick.yaml'
|
||||
|
||||
user_profile_brick:
|
||||
resource: 'routes/user_profile_brick.yaml'
|
||||
#
|
||||
#object_router:
|
||||
# resource: 'routes/object_router.php'
|
||||
|
||||
extensions_extra_routes:
|
||||
resource: 'routes/extensions_extra_routes.php'
|
||||
@@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2010-2018 Combodo SARL
|
||||
#
|
||||
# This file is part of iTop.
|
||||
#
|
||||
# iTop is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# iTop 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
p_home:
|
||||
path: '/'
|
||||
controller: 'Combodo\iTop\Portal\Controller\DefaultController::homeAction'
|
||||
|
||||
# Example route
|
||||
#p_example:
|
||||
# path: /url-pattern
|
||||
# controller: 'Combodo\iTop\Portal\Controller\DefaultController::exampleAction'
|
||||
# _defaults:
|
||||
# _fragment: 'string-to-be-append-to-the-pattern-after-a-#'
|
||||
@@ -0,0 +1,3 @@
|
||||
_errors:
|
||||
resource: '@TwigBundle/Resources/config/routing/errors.xml'
|
||||
prefix: /_error
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by Bruno DA SILVA, working for Combodo
|
||||
* Date: 30/01/19
|
||||
* Time: 18:06
|
||||
*/
|
||||
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use App\Controller\BlogController;
|
||||
|
||||
|
||||
$aRoutes = \Combodo\iTop\Portal\Routing\ItopExtensionsExtraRoutes::getRoutes();
|
||||
|
||||
$routes = new RouteCollection();
|
||||
|
||||
foreach ($aRoutes as $route) {
|
||||
$route['values'] = (isset($route['values'])) ? $route['values'] : [];
|
||||
$route['asserts'] = (isset($route['asserts'])) ? $route['asserts'] : [];
|
||||
|
||||
$routes->add(
|
||||
$route['bind'],
|
||||
new Route(
|
||||
$route['pattern'],
|
||||
array_merge(
|
||||
['_controller' => $route['callback']],
|
||||
$route['values']
|
||||
),
|
||||
$route['asserts']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $routes;
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2010-2018 Combodo SARL
|
||||
#
|
||||
# This file is part of iTop.
|
||||
#
|
||||
# iTop is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# iTop 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
p_user_profile_brick:
|
||||
path: '/user/{sBrickId}'
|
||||
defaults:
|
||||
_controller: 'Combodo\iTop\Portal\Controller\UserProfileBrickController::DisplayAction'
|
||||
sBrickId: ~
|
||||
121
datamodels/2.x/itop-portal-base/portal/config/services.yaml
Normal file
@@ -0,0 +1,121 @@
|
||||
# Copyright (C) 2010-2018 Combodo SARL
|
||||
#
|
||||
# This file is part of iTop.
|
||||
#
|
||||
# iTop is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# iTop 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
# This file is the entry point to configure your own services.
|
||||
# Files in the packages/ subdirectory configure your dependencies.
|
||||
|
||||
imports:
|
||||
- { resource: "legacy_silex_compat_layer.php" }
|
||||
|
||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
|
||||
parameters:
|
||||
# Replace default url generator service
|
||||
router.options.generator_base_class: Combodo\iTop\Portal\Routing\UrlGenerator
|
||||
|
||||
# Used in templates
|
||||
combodo.current_environment: !php/const COMBODO_CURRENT_ENVIRONMENT
|
||||
combodo.absolute_url: !php/const COMBODO_ABSOLUTE_URL
|
||||
combodo.modules.absolute_url: !php/const COMBODO_MODULES_ABSOLUTE_URL
|
||||
combodo.modules.absolute_path: !php/const MODULESROOT
|
||||
combodo.portal.base.absolute_url: !php/const COMBODO_PORTAL_BASE_ABSOLUTE_URL
|
||||
combodo.portal.base.absolute_path: !php/const COMBODO_PORTAL_BASE_ABSOLUTE_PATH
|
||||
combodo.portal.instance.absolute_url: !php/const COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL
|
||||
combodo.portal.instance.id: !php/const PORTAL_ID
|
||||
|
||||
services:
|
||||
# Default configuration for services in *this* file
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
public: false # Allows optimizing the container by removing unused services; this also means
|
||||
# fetching services directly from the container via $container->get() won't work.
|
||||
# The best practice is to be explicit about your dependencies anyway.
|
||||
bind:
|
||||
$sPortalCachePath: !php/const PORTAL_CACHE_PATH
|
||||
$sPortalId: !php/const PORTAL_ID
|
||||
$sCombodoPortalBaseAbsolutePath: !php/const COMBODO_PORTAL_BASE_ABSOLUTE_PATH
|
||||
|
||||
# Makes classes in src/ available to be used as services
|
||||
# This creates a service per class whose id is the fully-qualified class name
|
||||
Combodo\iTop\Portal\:
|
||||
resource: '../src/*'
|
||||
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
|
||||
|
||||
# Controllers are imported separately to make sure services can be injected
|
||||
# as action arguments even if you don't extend any base controller class
|
||||
Combodo\iTop\Portal\Controller\:
|
||||
resource: '../src/Controller'
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
# Tag services without defining them (see https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags)
|
||||
_instanceof:
|
||||
Combodo\iTop\Portal\EventListener\UserProvider:
|
||||
tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }]
|
||||
Combodo\iTop\Portal\EventListener\ApplicationContextSetUrlMakerClass:
|
||||
tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }]
|
||||
|
||||
|
||||
# Add more service definitions when explicit configuration is needed
|
||||
# Please note that last definitions always *replace* previous ones
|
||||
|
||||
# VariableAccessor: When a service require a parameter, you have to fully declare it: let's create intermediate (& simple) services and have them auto-wired
|
||||
Combodo\iTop\Portal\VariableAccessor\CombodoPortalInstanceConf:
|
||||
arguments:
|
||||
- '%combodo.portal.instance.conf%'
|
||||
combodo.current_contact.photo_url:
|
||||
class: Combodo\iTop\Portal\VariableAccessor\CombodoCurrentContactPhotoUrl
|
||||
arguments:
|
||||
- '@Combodo\iTop\Portal\Security\ItopUser'
|
||||
combodo.current_user:
|
||||
class: Combodo\iTop\Portal\VariableAccessor\CombodoCurrentUser
|
||||
arguments:
|
||||
- '@Combodo\iTop\Portal\Security\ItopUser'
|
||||
|
||||
# Legacy code as a service: since it is not in the auto-wiring path, it needs to be explicitly declared
|
||||
ModuleDesign:
|
||||
class: 'ModuleDesign'
|
||||
arguments:
|
||||
- '%combodo.portal.instance.id%'
|
||||
|
||||
# Decoration
|
||||
# - Compatibility layer with Silex\Application which was used almost everywhere in the portal's templates
|
||||
Combodo\iTop\Portal\Twig\AppVariable:
|
||||
decorates: twig.app_variable
|
||||
arguments:
|
||||
- '@Combodo\iTop\Portal\Twig\AppVariable.inner'
|
||||
- '@service_container'
|
||||
|
||||
# Aliases
|
||||
brick_collection:
|
||||
alias: Combodo\iTop\Portal\Brick\BrickCollection
|
||||
public: true
|
||||
request_manipulator:
|
||||
alias: Combodo\iTop\Portal\Helper\RequestManipulatorHelper
|
||||
public: true
|
||||
scope_validator:
|
||||
alias: Combodo\iTop\Portal\Helper\ScopeValidatorHelper
|
||||
public: true
|
||||
context_manipulator:
|
||||
alias: Combodo\iTop\Portal\Helper\ContextManipulatorHelper
|
||||
public: true
|
||||
lifecycle_validator:
|
||||
alias: Combodo\iTop\Portal\Helper\LifecycleValidatorHelper
|
||||
public: true
|
||||
url_generator:
|
||||
alias: router
|
||||
public: true
|
||||
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 780 B After Width: | Height: | Size: 780 B |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
30
datamodels/2.x/itop-portal-base/portal/public/index.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Portal\Kernel;
|
||||
use Symfony\Component\Debug\Debug;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
require dirname(__DIR__).'/config/bootstrap.php';
|
||||
require_once APPROOT . '/application/loginwebpage.class.inc.php';
|
||||
|
||||
if ($_SERVER['APP_DEBUG']) {
|
||||
umask(0000);
|
||||
|
||||
Debug::enable();
|
||||
}
|
||||
|
||||
// Note: Manually refactored ternary condition to be PHP 5.x compatible
|
||||
if ($trustedProxies = isset($_SERVER['TRUSTED_PROXIES']) ? $_SERVER['TRUSTED_PROXIES'] : (isset($_ENV['TRUSTED_PROXIES']) ? $_ENV['TRUSTED_PROXIES'] : false) ) {
|
||||
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
|
||||
}
|
||||
|
||||
// Note: Manually refactored ternary condition to be PHP 5.x compatible
|
||||
if ($trustedHosts = isset($_SERVER['TRUSTED_HOSTS']) ? $_SERVER['TRUSTED_HOSTS'] : (isset($_ENV['TRUSTED_HOSTS']) ? $_ENV['TRUSTED_HOSTS'] : false) ) {
|
||||
Request::setTrustedHosts([$trustedHosts]);
|
||||
}
|
||||
|
||||
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
|
||||
$request = Request::createFromGlobals();
|
||||
$response = $kernel->handle($request);
|
||||
$response->send();
|
||||
$kernel->terminate($request, $response);
|
||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
|
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
@@ -27,7 +27,7 @@ class AggregatePageBrick extends PortalBrick
|
||||
{
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-dashboard';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-dashboard fa-2x';
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/src/views/bricks/aggregate-page/layout.html.twig';
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig';
|
||||
|
||||
static $sRouteName = 'p_aggregatepage_brick';
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Bruno DA SILVA, working for Combodo
|
||||
* Date: 24/01/19
|
||||
* Time: 17:28
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Brick;
|
||||
|
||||
use UserRights;
|
||||
use ModuleDesign;
|
||||
use Combodo\iTop\Portal\Helper\ApplicationHelper;
|
||||
|
||||
/**
|
||||
* Class BrickCollection
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Brick
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class BrickCollection
|
||||
{
|
||||
/** @var array|null Lazily computed */
|
||||
private $aAllowedBricksData;
|
||||
/** @var \ModuleDesign */
|
||||
private $oModuleDesign;
|
||||
|
||||
public function __construct(ModuleDesign $oModuleDesign)
|
||||
{
|
||||
$this->oModuleDesign = $oModuleDesign;
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
return $this->GetBrickProperty($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
*
|
||||
* @return mixed
|
||||
* @throws PropertyNotFoundException
|
||||
*/
|
||||
private function GetBrickProperty($sId)
|
||||
{
|
||||
if (array_key_exists($sId, $this->getBricks())) {
|
||||
return $this->getBricks()[$sId];
|
||||
}
|
||||
|
||||
throw new PropertyNotFoundException(
|
||||
"The property '$sId' do not exists in BricksCollection with keys: ".array_keys($this->getBricks())
|
||||
);
|
||||
}
|
||||
|
||||
public function getBricks()
|
||||
{
|
||||
if (! isset($this->aAllowedBricksData)) {
|
||||
$this->LazyLoad();
|
||||
}
|
||||
|
||||
return $this->aAllowedBricksData;
|
||||
}
|
||||
|
||||
public function getBrickById($id)
|
||||
{
|
||||
foreach ($this->getBricks()['bricks'] as $brick) {
|
||||
if ($brick->GetId() === $id)
|
||||
{
|
||||
return $brick;
|
||||
}
|
||||
}
|
||||
|
||||
throw new BrickNotFoundException('Brick with id = "'.$id.'" was not found among loaded bricks.');
|
||||
}
|
||||
|
||||
private function LazyLoad()
|
||||
{
|
||||
$aRawBrickList = $this->GetRawBrickList();
|
||||
|
||||
$this->aAllowedBricksData = array(
|
||||
'bricks' => array(),
|
||||
'bricks_total_width' => 0,
|
||||
'bricks_home_count' => 0,
|
||||
'bricks_navigation_menu_count' => 0
|
||||
);
|
||||
|
||||
foreach ($aRawBrickList as $oBrick) {
|
||||
ApplicationHelper::LoadBrickSecurity($oBrick);
|
||||
|
||||
if ($oBrick->GetActive() && $oBrick->IsGrantedForProfiles(UserRights::ListProfiles()))
|
||||
{
|
||||
$this->aAllowedBricksData['bricks'][] = $oBrick;
|
||||
$this->aAllowedBricksData['bricks_total_width'] += $oBrick->GetWidth();
|
||||
if ($oBrick->GetVisibleHome())
|
||||
{
|
||||
$this->aAllowedBricksData['bricks_home_count']++;
|
||||
}
|
||||
if ($oBrick->GetVisibleNavigationMenu())
|
||||
{
|
||||
$this->aAllowedBricksData['bricks_navigation_menu_count']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - Sorting bricks by rank
|
||||
$this->aAllowedBricksData['bricks_ordering'] = array();
|
||||
// - Home
|
||||
$this->aAllowedBricksData['bricks_ordering']['home'] = $this->aAllowedBricksData['bricks'];
|
||||
usort($this->aAllowedBricksData['bricks_ordering']['home'], function (PortalBrick $a, PortalBrick $b) {
|
||||
return $a->GetRankHome() > $b->GetRankHome();
|
||||
});
|
||||
// - Navigation menu
|
||||
$this->aAllowedBricksData['bricks_ordering']['navigation_menu'] = $this->aAllowedBricksData['bricks'];
|
||||
usort($this->aAllowedBricksData['bricks_ordering']['navigation_menu'], function (PortalBrick $a, PortalBrick $b) {
|
||||
return $a->GetRankNavigationMenu() > $b->GetRankNavigationMenu();
|
||||
});
|
||||
}
|
||||
|
||||
private function GetRawBrickList()
|
||||
{
|
||||
$aBricks = array();
|
||||
foreach ($this->oModuleDesign->GetNodes('/module_design/bricks/brick') as $oBrickNode)
|
||||
{
|
||||
$sBrickClass = $oBrickNode->getAttribute('xsi:type');
|
||||
try
|
||||
{
|
||||
if (class_exists($sBrickClass))
|
||||
{
|
||||
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */
|
||||
$oBrick = new $sBrickClass();
|
||||
$oBrick->LoadFromXml($oBrickNode);
|
||||
|
||||
$aBricks[] = $oBrick;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('Unknown brick class "'.$sBrickClass.'" from xsi:type attribute', null,
|
||||
null, $oBrickNode);
|
||||
}
|
||||
}
|
||||
catch (DOMFormatException $e)
|
||||
{
|
||||
throw new Exception('Could not create brick ('.$sBrickClass.') from XML because of a DOM problem : '.$e->getMessage());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('Could not create brick ('.$sBrickClass.') from XML : '.$oBrickNode->Dump().' '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $aBricks;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by Bruno DA SILVA, working for Combodo
|
||||
* Date: 24/01/19
|
||||
* Time: 17:28
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Brick;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class BrickNotFoundException
|
||||
*
|
||||
* @package Combodo\iTop\Portal\Brick
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class BrickNotFoundException extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,21 +1,24 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Brick;
|
||||
|
||||
@@ -266,7 +269,7 @@ class BrowseBrick extends PortalBrick
|
||||
}
|
||||
else
|
||||
{
|
||||
$sTemplatePath = 'itop-portal-base/portal/src/views/bricks/browse/mode_' . $sModeId . '.html.twig';
|
||||
$sTemplatePath = 'itop-portal-base/portal/templates/bricks/browse/mode_' . $sModeId . '.html.twig';
|
||||
}
|
||||
$aModeData['template'] = $sTemplatePath;
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2015 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Brick;
|
||||
|
||||
@@ -31,7 +34,7 @@ class CreateBrick extends PortalBrick
|
||||
{
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-plus';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-plus fa-2x';
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/src/views/bricks/create/modal.html.twig';
|
||||
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig';
|
||||
const DEFAULT_CLASS = '';
|
||||
|
||||
static $sRouteName = 'p_create_brick';
|
||||
@@ -1,21 +1,24 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2018 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Brick;
|
||||
|
||||
@@ -30,7 +33,7 @@ use Combodo\iTop\DesignElement;
|
||||
class FilterBrick extends PortalBrick
|
||||
{
|
||||
const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
|
||||
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/src/views/bricks/filter/tile.html.twig';
|
||||
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig';
|
||||
const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-search';
|
||||
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-search fa-2x';
|
||||
|
||||