N°2060 [WIP] Initialisation of the portal application

This commit is contained in:
Molkobain
2019-05-28 12:03:55 +02:00
parent 895abde39c
commit 0867d8a3c4
168 changed files with 6988 additions and 1033 deletions

View File

@@ -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
*/

View 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/"
}
}
}

View File

@@ -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';

View File

@@ -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',

View File

@@ -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
{
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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')
);
}

View File

@@ -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
)
)
);
}

View 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 ###

View File

@@ -0,0 +1,9 @@
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###

View 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);

View 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.*"
}
}
}

File diff suppressed because it is too large Load Diff

View 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';

View File

@@ -0,0 +1,6 @@
<?php
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
];

View File

@@ -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);

View File

@@ -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: ~

View File

@@ -0,0 +1,3 @@
framework:
router:
strict_requirements: true

View File

@@ -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

View File

@@ -0,0 +1,3 @@
framework:
router:
strict_requirements: ~

View File

@@ -0,0 +1,4 @@
framework:
test: true
session:
storage_id: session.storage.mock_file

View File

@@ -0,0 +1,3 @@
framework:
router:
strict_requirements: true

View File

@@ -0,0 +1,4 @@
twig:
default_path: '%combodo.modules.absolute_path%'
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'

View 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'

View File

@@ -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-#'

View File

@@ -0,0 +1,3 @@
_errors:
resource: '@TwigBundle/Resources/config/routing/errors.xml'
prefix: /_error

View File

@@ -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;

View File

@@ -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: ~

View 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

View 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);

View File

@@ -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';

View File

@@ -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;
}
}

View File

@@ -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
{
}

View File

@@ -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;

View File

@@ -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';

View File

@@ -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';

Some files were not shown because too many files have changed in this diff Show More