mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
#439 Make sure that changes made by a plugin get recorded + simplified the change tracking for the plugins. Simply call DBObject::DBInsert (resp. Update and Delete) and the change will be recorded for the current page. This is compatible with the old (not mandatory anymore) way that was requiring DBInsertTracked APIs (resp. Update, Delete). SVN:trunk[2236]
1220 lines
36 KiB
PHP
1220 lines
36 KiB
PHP
<?php
|
|
// Copyright (C) 2011 Combodo SARL
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; version 3 of the License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
|
|
|
class DOMFormatException extends Exception
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Compiler class
|
|
*/
|
|
class MFCompiler
|
|
{
|
|
protected $oFactory;
|
|
protected $sSourceDir;
|
|
|
|
protected $aRootClasses;
|
|
protected $aLog;
|
|
|
|
public function __construct($oModelFactory, $sSourceDir)
|
|
{
|
|
$this->oFactory = $oModelFactory;
|
|
$this->sSourceDir = $sSourceDir;
|
|
|
|
$this->aLog = array();
|
|
}
|
|
|
|
protected function Log($sText)
|
|
{
|
|
$this->aLog[] = $sText;
|
|
}
|
|
|
|
protected function DumpLog($oPage)
|
|
{
|
|
foreach ($this->aLog as $sText)
|
|
{
|
|
$oPage->p($sText);
|
|
}
|
|
}
|
|
|
|
public function Compile($sTargetDir, $oP = null, $bUseSymbolicLinks = false)
|
|
{
|
|
$aAllClasses = array(); // flat list of classes
|
|
|
|
// Determine the target modules for the MENUS
|
|
//
|
|
$aMenuNodes = array();
|
|
$aMenusByModule = array();
|
|
foreach ($this->oFactory->ListActiveChildNodes('menus', 'menu') as $oMenuNode)
|
|
{
|
|
$sMenuId = $oMenuNode->getAttribute('id');
|
|
$aMenuNodes[$sMenuId] = $oMenuNode;
|
|
|
|
$sModuleMenu = $oMenuNode->getAttribute('_created_in');
|
|
$aMenusByModule[$sModuleMenu][] = $sMenuId;
|
|
}
|
|
|
|
// Determine the target module (exactly one!) for USER RIGHTS
|
|
//
|
|
$sUserRightsModule = '';
|
|
$oUserRightsNode = $this->oFactory->GetNodes('user_rights')->item(0);
|
|
if ($oUserRightsNode)
|
|
{
|
|
$sUserRightsModule = $oUserRightsNode->getAttribute('_created_in');
|
|
}
|
|
|
|
// List root classes
|
|
//
|
|
$this->aRootClasses = array();
|
|
foreach ($this->oFactory->ListRootClasses() as $oClass)
|
|
{
|
|
$this->Log("Root class: ".$oClass->getAttribute('id'));
|
|
$this->aRootClasses[$oClass->getAttribute('id')] = $oClass;
|
|
}
|
|
|
|
// Compile, module by module
|
|
//
|
|
$aModules = $this->oFactory->GetLoadedModules();
|
|
foreach($aModules as $foo => $oModule)
|
|
{
|
|
$sModuleName = $oModule->GetName();
|
|
$sModuleVersion = $oModule->GetVersion();
|
|
|
|
$sModuleRootDir = realpath($oModule->GetRootDir());
|
|
$sRelativeDir = substr($sModuleRootDir, strlen($this->sSourceDir) + 1);
|
|
|
|
// Push the other module files
|
|
SetupUtils::copydir($sModuleRootDir, $sTargetDir.'/'.$sRelativeDir, $bUseSymbolicLinks);
|
|
|
|
$sCompiledCode = '';
|
|
|
|
$oClasses = $this->oFactory->ListClasses($sModuleName);
|
|
$iClassCount = $oClasses->length;
|
|
if ($iClassCount == 0)
|
|
{
|
|
$this->Log("Found module without classes declared: $sModuleName");
|
|
}
|
|
else
|
|
{
|
|
foreach($oClasses as $oClass)
|
|
{
|
|
$sClass = $oClass->getAttribute("id");
|
|
$aAllClasses[] = $sClass;
|
|
try
|
|
{
|
|
$sCompiledCode .= $this->CompileClass($oClass, $sRelativeDir, $oP);
|
|
}
|
|
catch (DOMFormatException $e)
|
|
{
|
|
throw new Exception("Failed to process class '$sClass', from '$sModuleRootDir': ".$e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!array_key_exists($sModuleName, $aMenusByModule))
|
|
{
|
|
$this->Log("Found module without menus declared: $sModuleName");
|
|
}
|
|
else
|
|
{
|
|
$sCompiledCode .=
|
|
<<<EOF
|
|
|
|
//
|
|
// Menus
|
|
//
|
|
|
|
EOF;
|
|
// Preliminary: determine parent menus not defined within the current module
|
|
$aMenusToLoad = array();
|
|
$aParentMenus = array();
|
|
foreach($aMenusByModule[$sModuleName] as $sMenuId)
|
|
{
|
|
$oMenuNode = $aMenuNodes[$sMenuId];
|
|
if ($sParent = $oMenuNode->GetChildText('parent', null))
|
|
{
|
|
$aMenusToLoad[] = $sParent;
|
|
$aParentMenus[] = $sParent;
|
|
}
|
|
// Note: the order matters: the parents must be defined BEFORE
|
|
$aMenusToLoad[] = $sMenuId;
|
|
}
|
|
$aMenusToLoad = array_unique($aMenusToLoad);
|
|
foreach($aMenusToLoad as $sMenuId)
|
|
{
|
|
$oMenuNode = $aMenuNodes[$sMenuId];
|
|
if ($oMenuNode->getAttribute("xsi:type") == 'MenuGroup')
|
|
{
|
|
// Note: this algorithm is wrong
|
|
// 1 - the module may appear empty in the current module, while children are defined in other modules
|
|
// 2 - check recursively that child nodes are not empty themselves
|
|
// Future algorithm:
|
|
// a- browse the modules and build the menu tree
|
|
// b- browse the tree and blacklist empty menus
|
|
// c- before compiling, discard if blacklisted
|
|
if (!in_array($oMenuNode->getAttribute("id"), $aParentMenus))
|
|
{
|
|
// Discard empty menu groups
|
|
continue;
|
|
}
|
|
}
|
|
try
|
|
{
|
|
$sCompiledCode .= $this->CompileMenu($oMenuNode, $sRelativeDir, $oP);
|
|
}
|
|
catch (ssDOMFormatException $e)
|
|
{
|
|
throw new Exception("Failed to process menu '$sMenuId', from '$sModuleRootDir': ".$e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
// User rights
|
|
//
|
|
if ($sModuleName == $sUserRightsModule)
|
|
{
|
|
$sCompiledCode .= $this->CompileUserRights($oUserRightsNode);
|
|
}
|
|
|
|
// Create (overwrite if existing) the compiled file
|
|
//
|
|
if (strlen($sCompiledCode) > 0)
|
|
{
|
|
// We have compiled something: write the result file
|
|
//
|
|
$sResultFile = $sTargetDir.'/'.$sRelativeDir.'/model.'.$sModuleName.'.php';
|
|
if (is_file($sResultFile))
|
|
{
|
|
$this->Log("Updating $sResultFile for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
|
|
}
|
|
else
|
|
{
|
|
$sResultDir = dirname($sResultFile);
|
|
if (!is_dir($sResultDir))
|
|
{
|
|
$this->Log("Creating directory $sResultDir");
|
|
mkdir($sResultDir, 0777, true);
|
|
}
|
|
$this->Log("Creating $sResultFile for module $sModuleName in version $sModuleVersion ($iClassCount classes)");
|
|
}
|
|
|
|
// Compile the module into a single file
|
|
//
|
|
$sId = $sModuleName;
|
|
$sCurrDate = date(DATE_ISO8601);
|
|
$sAuthor = 'Combodo compiler';
|
|
$sLicence = 'http://www.opensource.org/licenses/gpl-3.0.html LGPL';
|
|
$sFileHeader =
|
|
<<<EOF
|
|
<?php
|
|
//
|
|
// File generated by ... on the $sCurrDate
|
|
// Please do not edit manually
|
|
//
|
|
//
|
|
// Copyright (C) 2010 Combodo SARL
|
|
//
|
|
// ben on met quoi ici ?
|
|
// Signé: Romain
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; version 3 of the License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
/**
|
|
* Classes and menus for $sModuleName (version $sModuleVersion)
|
|
*
|
|
* @author $sAuthor
|
|
* @license $sLicence
|
|
*/
|
|
|
|
EOF;
|
|
file_put_contents($sResultFile, $sFileHeader.$sCompiledCode);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper to format the flags for an attribute, in a given state
|
|
* @param object $oAttNode DOM node containing the information to build the flags
|
|
* Returns string PHP flags, based on the OPT_ATT_ constants, or empty (meaning 0, can be omitted)
|
|
*/
|
|
protected function FlagsToPHP($oAttNode)
|
|
{
|
|
static $aNodeAttributeToFlag = array(
|
|
'mandatory' => 'OPT_ATT_MANDATORY',
|
|
'read_only' => 'OPT_ATT_READONLY',
|
|
'must_prompt' => 'OPT_ATT_MUSTPROMPT',
|
|
'must_change' => 'OPT_ATT_MUSTCHANGE',
|
|
'hidden' => 'OPT_ATT_HIDDEN',
|
|
);
|
|
|
|
$aFlags = array();
|
|
foreach ($aNodeAttributeToFlag as $sNodeAttribute => $sFlag)
|
|
{
|
|
$bFlag = ($oAttNode->GetOptionalElement($sNodeAttribute) != null);
|
|
if ($bFlag)
|
|
{
|
|
$aFlags[] = $sFlag;
|
|
}
|
|
}
|
|
$sRes = implode(' | ', $aFlags);
|
|
return $sRes;
|
|
}
|
|
|
|
/**
|
|
* Helper to format the tracking level for linkset (direct or indirect attributes)
|
|
* @param string $sTrackingLevel Value set from within the XML
|
|
* Returns string PHP flag
|
|
*/
|
|
protected function TrackingLevelToPHP($sTrackingLevel)
|
|
{
|
|
static $aXmlToPHP = array(
|
|
'none' => 'LINKSET_TRACKING_NONE',
|
|
'list' => 'LINKSET_TRACKING_LIST',
|
|
'details' => 'LINKSET_TRACKING_DETAILS',
|
|
'all' => 'LINKSET_TRACKING_ALL',
|
|
);
|
|
|
|
if (!array_key_exists($sTrackingLevel, $aXmlToPHP))
|
|
{
|
|
throw new exception("Tracking level: unknown value '$sTrackingLevel'");
|
|
}
|
|
return $aXmlToPHP[$sTrackingLevel];
|
|
}
|
|
|
|
|
|
/**
|
|
* Format a path (file or url) as an absolute path or relative to the module or the app
|
|
*/
|
|
protected function PathToPHP($sPath, $sModuleRelativeDir, $bIsUrl = false)
|
|
{
|
|
if ($sPath == '')
|
|
{
|
|
$sPHP = "''";
|
|
}
|
|
elseif (substr($sPath, 0, 2) == '$$')
|
|
{
|
|
// Absolute
|
|
$sPHP = self::QuoteForPHP(substr($sPath, 2));
|
|
}
|
|
elseif (substr($sPath, 0, 1) == '$')
|
|
{
|
|
// Relative to the application
|
|
if ($bIsUrl)
|
|
{
|
|
$sPHP = "utils::GetAbsoluteUrlAppRoot().".self::QuoteForPHP(substr($sPath, 1));
|
|
}
|
|
else
|
|
{
|
|
$sPHP = "APPROOT.".self::QuoteForPHP(substr($sPath, 1));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Relative to the module
|
|
if ($bIsUrl)
|
|
{
|
|
$sPHP = "utils::GetAbsoluteUrlAppRoot().".self::QuoteForPHP($sModuleRelativeDir.''.$sPath);
|
|
}
|
|
else
|
|
{
|
|
$sPHP = "dirname(__FILE__).'/$sPath'";
|
|
}
|
|
}
|
|
return $sPHP;
|
|
}
|
|
|
|
protected function GetPropString($oNode, $sTag, $sDefault = null)
|
|
{
|
|
$val = $oNode->GetChildText($sTag);
|
|
if (is_null($val))
|
|
{
|
|
if (is_null($sDefault))
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
$val = $sDefault;
|
|
}
|
|
}
|
|
return "'".$val."'";
|
|
}
|
|
|
|
protected function GetPropBoolean($oNode, $sTag, $bDefault = null)
|
|
{
|
|
$val = $oNode->GetChildText($sTag);
|
|
if (is_null($val))
|
|
{
|
|
if (is_null($bDefault))
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
return $bDefault ? 'true' : 'false';
|
|
}
|
|
}
|
|
return $val == 'true' ? 'true' : 'false';
|
|
}
|
|
|
|
protected function GetPropNumber($oNode, $sTag, $nDefault = null)
|
|
{
|
|
$val = $oNode->GetChildText($sTag);
|
|
if (is_null($val))
|
|
{
|
|
if (is_null($nDefault))
|
|
{
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
$val = $nDefault;
|
|
}
|
|
}
|
|
return (string)$val;
|
|
}
|
|
|
|
/**
|
|
* Adds quotes and escape characters
|
|
*/
|
|
protected function QuoteForPHP($sStr)
|
|
{
|
|
$sEscaped = str_replace(array('\\', '"', "\n"), array('\\\\', '\\"', '\\n'), $sStr);
|
|
$sRet = '"'.$sEscaped.'"';
|
|
return $sRet;
|
|
}
|
|
|
|
protected function CompileClass($oClass, $sModuleRelativeDir, $oP)
|
|
{
|
|
$sClass = $oClass->getAttribute('id');
|
|
$oProperties = $oClass->GetUniqueElement('properties');
|
|
|
|
// Class caracteristics
|
|
//
|
|
$aClassParams = array();
|
|
$aClassParams['category'] = $this->GetPropString($oProperties, 'category', '');
|
|
$aClassParams['key_type'] = "'autoincrement'";
|
|
|
|
if ($oNaming = $oProperties->GetOptionalElement('naming'))
|
|
{
|
|
$oNameAttributes = $oNaming->GetUniqueElement('attributes');
|
|
$oAttributes = $oNameAttributes->getElementsByTagName('attribute');
|
|
$aNameAttCodes = array();
|
|
foreach($oAttributes as $oAttribute)
|
|
{
|
|
$aNameAttCodes[] = $oAttribute->getAttribute('id');
|
|
}
|
|
if (count($aNameAttCodes) > 1)
|
|
{
|
|
// New style...
|
|
$sNameAttCode = "array('".implode("', '", $aNameAttCodes)."')";
|
|
}
|
|
elseif (count($aNameAttCodes) == 1)
|
|
{
|
|
// New style...
|
|
$sNameAttCode = "'$aNameAttCodes[0]'";
|
|
}
|
|
else
|
|
{
|
|
$sNameAttCode = "''";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sNameAttCode = "''";
|
|
}
|
|
$aClassParams['name_attcode'] = $sNameAttCode;
|
|
|
|
$oLifecycle = $oClass->GetOptionalElement('lifecycle');
|
|
if ($oLifecycle)
|
|
{
|
|
$sStateAttCode = $oLifecycle->GetChildText('attribute');
|
|
}
|
|
else
|
|
{
|
|
$sStateAttCode = "";
|
|
}
|
|
$aClassParams['state_attcode'] = "'$sStateAttCode'";
|
|
|
|
if ($oReconciliation = $oProperties->GetOptionalElement('reconciliation'))
|
|
{
|
|
$oReconcAttributes = $oReconciliation->getElementsByTagName('attribute');
|
|
$aReconcAttCodes = array();
|
|
foreach($oReconcAttributes as $oAttribute)
|
|
{
|
|
$aReconcAttCodes[] = $oAttribute->getAttribute('id');
|
|
}
|
|
$sReconcKeys = "array('".implode("', '", $aReconcAttCodes)."')";
|
|
}
|
|
else
|
|
{
|
|
$sReconcKeys = "array()";
|
|
}
|
|
$aClassParams['reconc_keys'] = $sReconcKeys;
|
|
|
|
$aClassParams['db_table'] = $this->GetPropString($oProperties, 'db_table', '');
|
|
$aClassParams['db_key_field'] = $this->GetPropString($oProperties, 'db_key_field', 'id');
|
|
|
|
if (array_key_exists($sClass, $this->aRootClasses))
|
|
{
|
|
$sDefaultFinalClass = 'finalclass';
|
|
}
|
|
else
|
|
{
|
|
$sDefaultFinalClass = '';
|
|
}
|
|
$aClassParams['db_finalclass_field'] = $this->GetPropString($oProperties, 'db_final_class_field', $sDefaultFinalClass);
|
|
|
|
if (($sDisplayTemplate = $oProperties->GetChildText('display_template')) && (strlen($sDisplayTemplate) > 0))
|
|
{
|
|
$sDisplayTemplate = $sModuleRelativeDir.'/'.$sDisplayTemplate;
|
|
$aClassParams['display_template'] = "utils::GetAbsoluteUrlModulesRoot().'$sDisplayTemplate'";
|
|
}
|
|
|
|
if (($sIcon = $oProperties->GetChildText('icon')) && (strlen($sIcon) > 0))
|
|
{
|
|
$sIcon = $sModuleRelativeDir.'/'.$sIcon;
|
|
$aClassParams['icon'] = "utils::GetAbsoluteUrlModulesRoot().'$sIcon'";
|
|
}
|
|
|
|
$oOrder = $oProperties->GetOptionalElement('order');
|
|
if ($oOrder)
|
|
{
|
|
$oColumnsNode = $oOrder->GetUniqueElement('columns');
|
|
$oColumns = $oColumnsNode->getElementsByTagName('column');
|
|
$aSortColumns = array();
|
|
foreach($oColumns as $oColumn)
|
|
{
|
|
$aSortColumns[] = "'".$oColumn->getAttribute('id')."' => ".(($oColumn->getAttribute('ascending') == 'true') ? 'true' : 'false');
|
|
}
|
|
if (count($aSortColumns) > 0)
|
|
{
|
|
$aClassParams['order_by_default'] = "array(".implode(", ", $aSortColumns).")";
|
|
}
|
|
}
|
|
|
|
|
|
// Finalize class params declaration
|
|
//
|
|
$aClassParamsPHP = array();
|
|
foreach($aClassParams as $sKey => $sPHPValue)
|
|
{
|
|
$aClassParamsPHP[] = " '$sKey' => $sPHPValue,";
|
|
}
|
|
$sClassParams = implode("\n", $aClassParamsPHP);
|
|
|
|
// Comment on top of the class declaration
|
|
//
|
|
$sCodeComment = $oProperties->GetChildText('comment');
|
|
|
|
// Fields
|
|
//
|
|
$sAttributes = '';
|
|
foreach($this->oFactory->ListFields($oClass) as $oField)
|
|
{
|
|
// $oField
|
|
$sAttCode = $oField->getAttribute('id');
|
|
$sAttType = $oField->getAttribute('xsi:type');
|
|
|
|
$aDependencies = array();
|
|
$oDependencies = $oField->GetOptionalElement('dependencies');
|
|
if (!is_null($oDependencies))
|
|
{
|
|
$oDepNodes = $oDependencies->getElementsByTagName('attribute');
|
|
foreach($oDepNodes as $oDepAttribute)
|
|
{
|
|
$aDependencies[] = "'".$oDepAttribute->getAttribute('id')."'";
|
|
}
|
|
}
|
|
$sDependencies = 'array('.implode(', ', $aDependencies).')';
|
|
|
|
$aParameters = array();
|
|
|
|
if ($sAttType == 'AttributeLinkedSetIndirect')
|
|
{
|
|
$aParameters['linked_class'] = $this->GetPropString($oField, 'linked_class', '');
|
|
$aParameters['ext_key_to_me'] = $this->GetPropString($oField, 'ext_key_to_me', '');
|
|
$aParameters['ext_key_to_remote'] = $this->GetPropString($oField, 'ext_key_to_remote', '');
|
|
$aParameters['allowed_values'] = 'null';
|
|
$aParameters['count_min'] = $this->GetPropNumber($oField, 'count_min', 0);
|
|
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
|
$aParameters['duplicates'] = $this->GetPropBoolean($oField, 'duplicates', false);
|
|
$sTrackingLevel = $oField->GetChildText('tracking_level');
|
|
if (!is_null($sTrackingLevel))
|
|
{
|
|
$aParameters['tracking_level'] = $this->TrackingLevelToPHP($sTrackingLevel);
|
|
}
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
elseif ($sAttType == 'AttributeLinkedSet')
|
|
{
|
|
$aParameters['linked_class'] = $this->GetPropString($oField, 'linked_class', '');
|
|
$aParameters['ext_key_to_me'] = $this->GetPropString($oField, 'ext_key_to_me', '');
|
|
$aParameters['allowed_values'] = 'null';
|
|
$aParameters['count_min'] = $this->GetPropNumber($oField, 'count_min', 0);
|
|
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
|
$sTrackingLevel = $oField->GetChildText('tracking_level');
|
|
if (!is_null($sTrackingLevel))
|
|
{
|
|
$aParameters['tracking_level'] = $this->TrackingLevelToPHP($sTrackingLevel);
|
|
}
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
elseif ($sAttType == 'AttributeExternalKey')
|
|
{
|
|
$aParameters['targetclass'] = $this->GetPropString($oField, 'target_class', '');
|
|
// deprecated: $aParameters['jointype'] = 'null';
|
|
if ($sOql = $oField->GetChildText('filter'))
|
|
{
|
|
$sEscapedOql = self::QuoteForPHP($sOql);
|
|
$aParameters['allowed_values'] = "new ValueSetObjects($sEscapedOql)"; // or "new ValueSetObjects('SELECT xxxx')"
|
|
}
|
|
else
|
|
{
|
|
$aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
|
|
}
|
|
$aParameters['sql'] = $this->GetPropString($oField, 'sql', '');
|
|
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
|
$aParameters['on_target_delete'] = $oField->GetChildText('on_target_delete');
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
$aParameters['max_combo_length'] = $this->GetPropNumber($oField, 'max_combo_length');
|
|
$aParameters['min_auto_complete_chars'] = $this->GetPropNumber($oField, 'min_auto_complete_chars');
|
|
$aParameters['allow_target_creation'] = $this->GetPropBoolean($oField, 'allow_target_creation');
|
|
}
|
|
elseif ($sAttType == 'AttributeHierarchicalKey')
|
|
{
|
|
if ($sOql = $oField->GetChildText('filter'))
|
|
{
|
|
$sEscapedOql = self::QuoteForPHP($sOql);
|
|
$aParameters['allowed_values'] = "new ValueSetObjects($sEscapedOql)"; // or "new ValueSetObjects('SELECT xxxx')"
|
|
}
|
|
else
|
|
{
|
|
$aParameters['allowed_values'] = 'null'; // or "new ValueSetObjects('SELECT xxxx')"
|
|
}
|
|
$aParameters['sql'] = $this->GetPropString($oField, 'sql', '');
|
|
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
|
$aParameters['on_target_delete'] = $oField->GetChildText('on_target_delete');
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
$aParameters['max_combo_length'] = $this->GetPropNumber($oField, 'max_combo_length');
|
|
$aParameters['min_auto_complete_chars'] = $this->GetPropNumber($oField, 'min_auto_complete_chars');
|
|
$aParameters['allow_target_creation'] = $this->GetPropBoolean($oField, 'allow_target_creation');
|
|
}
|
|
elseif ($sAttType == 'AttributeExternalField')
|
|
{
|
|
$aParameters['allowed_values'] = 'null';
|
|
$aParameters['extkey_attcode'] = $this->GetPropString($oField, 'extkey_attcode', '');
|
|
$aParameters['target_attcode'] = $this->GetPropString($oField, 'target_attcode', '');
|
|
}
|
|
elseif ($sAttType == 'AttributeURL')
|
|
{
|
|
$aParameters['target'] = $this->GetPropString($oField, 'target', '');
|
|
$aParameters['allowed_values'] = 'null';
|
|
$aParameters['sql'] = $this->GetPropString($oField, 'sql', '');
|
|
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
|
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
elseif ($sAttType == 'AttributeEnum')
|
|
{
|
|
$oValues = $oField->GetUniqueElement('values');
|
|
$oValueNodes = $oValues->getElementsByTagName('value');
|
|
$aValues = array();
|
|
foreach($oValueNodes as $oValue)
|
|
{
|
|
// new style... $aValues[] = self::QuoteForPHP($oValue->textContent);
|
|
$aValues[] = $oValue->textContent;
|
|
}
|
|
// new style... $sValues = 'array('.implode(', ', $aValues).')';
|
|
$sValues = '"'.implode(',', $aValues).'"';
|
|
$aParameters['allowed_values'] = "new ValueSetEnum($sValues)";
|
|
$aParameters['display_style'] = $this->GetPropString($oField, 'display_style', 'list');
|
|
$aParameters['sql'] = $this->GetPropString($oField, 'sql', '');
|
|
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
|
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
elseif ($sAttType == 'AttributeBlob')
|
|
{
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
elseif ($sAttType == 'AttributeStopWatch')
|
|
{
|
|
$oStates = $oField->GetUniqueElement('states');
|
|
$oStateNodes = $oStates->getElementsByTagName('state');
|
|
$aStates = array();
|
|
foreach($oStateNodes as $oState)
|
|
{
|
|
$aStates[] = '"'.$oState->GetAttribute('id').'"';
|
|
}
|
|
$aParameters['states'] = 'array('.implode(', ', $aStates).')';
|
|
|
|
$aParameters['goal_computing'] = $this->GetPropString($oField, 'goal', 'DefaultMetricComputer'); // Optional, no deadline by default
|
|
$aParameters['working_time_computing'] = $this->GetPropString($oField, 'working_time', 'DefaultWorkingTimeComputer'); // Optional, defaults to 24x7
|
|
|
|
$oThresholds = $oField->GetUniqueElement('thresholds');
|
|
$oThresholdNodes = $oThresholds->getElementsByTagName('threshold');
|
|
$aThresholds = array();
|
|
foreach($oThresholdNodes as $oThreshold)
|
|
{
|
|
$iPercent = $this->GetPropNumber($oThreshold, 'percent');
|
|
|
|
$oActions = $oThreshold->GetUniqueElement('actions');
|
|
$oActionNodes = $oActions->getElementsByTagName('action');
|
|
$aActions = array();
|
|
foreach($oActionNodes as $oAction)
|
|
{
|
|
$oParams = $oAction->GetOptionalElement('params');
|
|
$aActionParams = array();
|
|
if ($oParams)
|
|
{
|
|
$oParamNodes = $oParams->getElementsByTagName('param');
|
|
foreach($oParamNodes as $oParam)
|
|
{
|
|
$aActionParams[] = self::QuoteForPHP($oParam->textContent);
|
|
}
|
|
}
|
|
$sActionParams = 'array('.implode(', ', $aActionParams).')';
|
|
$sVerb = $this->GetPropString($oAction, 'verb');
|
|
$aActions[] = "array('verb' => $sVerb, 'params' => $sActionParams)";
|
|
}
|
|
$sActions = 'array('.implode(', ', $aActions).')';
|
|
$aThresholds[] = $iPercent." => array('percent' => $iPercent, 'actions' => $sActions)";
|
|
}
|
|
$aParameters['thresholds'] = 'array('.implode(', ', $aThresholds).')';
|
|
}
|
|
elseif ($sAttType == 'AttributeSubItem')
|
|
{
|
|
$aParameters['target_attcode'] = $this->GetPropString($oField, 'target_attcode');
|
|
$aParameters['item_code'] = $this->GetPropString($oField, 'item_code');
|
|
}
|
|
else
|
|
{
|
|
$aParameters['allowed_values'] = 'null'; // or "new ValueSetEnum('SELECT xxxx')"
|
|
$aParameters['sql'] = $this->GetPropString($oField, 'sql', '');
|
|
$aParameters['default_value'] = $this->GetPropString($oField, 'default_value', '');
|
|
$aParameters['is_null_allowed'] = $this->GetPropBoolean($oField, 'is_null_allowed', false);
|
|
$aParameters['depends_on'] = $sDependencies;
|
|
}
|
|
|
|
// Optional parameters (more for historical reasons)
|
|
// Added if present...
|
|
//
|
|
$aParameters['validation_pattern'] = $this->GetPropString($oField, 'validation_pattern');
|
|
$aParameters['width'] = $this->GetPropNumber($oField, 'width');
|
|
$aParameters['height'] = $this->GetPropNumber($oField, 'height');
|
|
$aParameters['digits'] = $this->GetPropNumber($oField, 'digits');
|
|
$aParameters['decimals'] = $this->GetPropNumber($oField, 'decimals');
|
|
|
|
$aParams = array();
|
|
foreach($aParameters as $sKey => $sValue)
|
|
{
|
|
if (!is_null($sValue))
|
|
{
|
|
$aParams[] = '"'.$sKey.'"=>'.$sValue;
|
|
}
|
|
}
|
|
$sParams = implode(', ', $aParams);
|
|
$sAttributes .= " MetaModel::Init_AddAttribute(new $sAttType(\"$sAttCode\", array($sParams)));\n";
|
|
}
|
|
|
|
// Lifecycle
|
|
//
|
|
$sLifecycle = '';
|
|
if ($oLifecycle)
|
|
{
|
|
$sLifecycle .= "\t\t// Lifecycle (status attribute: $sStateAttCode)\n";
|
|
$sLifecycle .= "\t\t//\n";
|
|
|
|
$oStimuli = $oLifecycle->GetUniqueElement('stimuli');
|
|
foreach ($oStimuli->getElementsByTagName('stimulus') as $oStimulus)
|
|
{
|
|
$sStimulus = $oStimulus->getAttribute('id');
|
|
$sStimulusClass = $oStimulus->getAttribute('xsi:type');
|
|
|
|
$sLifecycle .= " MetaModel::Init_DefineStimulus(new ".$sStimulusClass."(\"".$sStimulus."\", array()));\n";
|
|
}
|
|
|
|
$oStates = $oLifecycle->GetUniqueElement('states');
|
|
foreach ($oStates->getElementsByTagName('state') as $oState)
|
|
{
|
|
$sState = $oState->getAttribute('id');
|
|
|
|
$oInitialStatePath = $oState->GetOptionalElement('initial_state_path');
|
|
if ($oInitialStatePath)
|
|
{
|
|
$aInitialStatePath = array();
|
|
foreach ($oInitialStatePath->getElementsByTagName('state_ref') as $oIntermediateState)
|
|
{
|
|
$aInitialStatePath[] = "'".$oIntermediateState->GetText()."'";
|
|
}
|
|
$sInitialStatePath = 'Array('.implode(', ', $aInitialStatePath).')';
|
|
}
|
|
|
|
$sLifecycle .= " MetaModel::Init_DefineState(\n";
|
|
$sLifecycle .= " \"".$sState."\",\n";
|
|
$sLifecycle .= " array(\n";
|
|
$sLifecycle .= " \"attribute_inherit\" => '',\n";
|
|
$sLifecycle .= " \"attribute_list\" => array(\n";
|
|
|
|
$oFlags = $oState->GetUniqueElement('flags');
|
|
foreach ($oFlags->getElementsByTagName('attribute') as $oAttributeNode)
|
|
{
|
|
$sFlags = $this->FlagsToPHP($oAttributeNode);
|
|
if (strlen($sFlags) > 0)
|
|
{
|
|
$sAttCode = $oAttributeNode->GetAttribute('id');
|
|
$sLifecycle .= " '$sAttCode' => $sFlags,\n";
|
|
}
|
|
}
|
|
|
|
$sLifecycle .= " ),\n";
|
|
if (!is_null($oInitialStatePath))
|
|
{
|
|
$sLifecycle .= " \"initial_state_path\" => $sInitialStatePath,\n";
|
|
}
|
|
$sLifecycle .= " )\n";
|
|
$sLifecycle .= " );\n";
|
|
|
|
$oTransitions = $oState->GetUniqueElement('transitions');
|
|
foreach ($oTransitions->getElementsByTagName('transition') as $oTransition)
|
|
{
|
|
$sStimulus = $oTransition->GetChildText('stimulus');
|
|
$sTargetState = $oTransition->GetChildText('target');
|
|
|
|
$oActions = $oTransition->GetUniqueElement('actions');
|
|
$aVerbs = array();
|
|
foreach ($oActions->getElementsByTagName('action') as $oAction)
|
|
{
|
|
$sVerb = $oAction->GetChildText('verb');
|
|
$aVerbs[] = "'$sVerb'";
|
|
}
|
|
$sActions = implode(', ', $aVerbs);
|
|
$sLifecycle .= " MetaModel::Init_DefineTransition(\"$sState\", \"$sStimulus\", array(\"target_state\"=>\"$sTargetState\", \"actions\"=>array($sActions), \"user_restriction\"=>null));\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// ZLists
|
|
//
|
|
$aListRef = array(
|
|
'details' => 'details',
|
|
'standard_search' => 'search',
|
|
'list' => 'list'
|
|
);
|
|
|
|
$oPresentation = $oClass->GetUniqueElement('presentation');
|
|
$sZlists = '';
|
|
foreach ($aListRef as $sListCode => $sListTag)
|
|
{
|
|
$oListNode = $oPresentation->GetOptionalElement($sListTag);
|
|
if ($oListNode)
|
|
{
|
|
$aAttributes = $oListNode->GetNodeAsArrayOfItems();
|
|
|
|
$sZAttributes = var_export($aAttributes, true);
|
|
$sZlists .= " MetaModel::Init_SetZListItems('$sListCode', $sZAttributes);\n";
|
|
}
|
|
}
|
|
|
|
// Methods
|
|
$sMethods = "";
|
|
$oMethods = $oClass->GetUniqueElement('methods');
|
|
foreach($oMethods->getElementsByTagName('method') as $oMethod)
|
|
{
|
|
$sMethodCode = $oMethod->GetChildText('code');
|
|
if ($sMethodComment = $oMethod->GetChildText('comment', null))
|
|
{
|
|
$sMethods .= "\n\t$sMethodComment\n".$sMethodCode."\n";
|
|
}
|
|
else
|
|
{
|
|
$sMethods .= "\n\n".$sMethodCode."\n";
|
|
}
|
|
}
|
|
|
|
// Let's make the whole class declaration
|
|
//
|
|
$sPHP = "\n\n$sCodeComment\n";
|
|
$sParentClass = $oClass->GetChildText('php_parent');
|
|
$oPhpParent = $oClass->GetUniqueElement('php_parent', false);
|
|
if ($oPhpParent)
|
|
{
|
|
$sParentClass = $oPhpParent->GetChildText('name', '');
|
|
if ($sParentClass == '')
|
|
{
|
|
throw new Exception("Failed to process class '".$oClass->getAttribute('id')."', from '$sRelativeDir': missing required tag 'name' under 'php_parent'.");
|
|
}
|
|
$sIncludeFile = $oPhpParent->GetChildText('file', '');
|
|
if ($sIncludeFile != '')
|
|
{
|
|
$sPHP .= "\nrequire_once('$sIncludeFile'); // Implementation of the class $sParentClass\n";
|
|
}
|
|
$sFullPath = $this->sSourceDir.'/'.$sModuleRelativeDir.'/'.$sIncludeFile;
|
|
if (!file_exists($sFullPath))
|
|
{
|
|
throw new Exception("Failed to process class '".$oClass->getAttribute('id')."', from '$sModuleRelativeDir'. The required include file: '$sFullPath' does not exist.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sParentClass = $oClass->GetChildText('parent', 'DBObject');
|
|
}
|
|
if ($oProperties->GetChildText('abstract') == 'true')
|
|
{
|
|
$sPHP .= 'abstract class '.$oClass->getAttribute('id');
|
|
}
|
|
else
|
|
{
|
|
$sPHP .= 'class '.$oClass->getAttribute('id');
|
|
}
|
|
$sPHP .= " extends $sParentClass\n";
|
|
$sPHP .=
|
|
<<<EOF
|
|
{
|
|
public static function Init()
|
|
{
|
|
\$aParams = array
|
|
(
|
|
$sClassParams
|
|
);
|
|
MetaModel::Init_Params(\$aParams);
|
|
MetaModel::Init_InheritAttributes();
|
|
$sAttributes
|
|
$sLifecycle
|
|
$sZlists
|
|
}
|
|
|
|
$sMethods
|
|
}
|
|
EOF;
|
|
return $sPHP;
|
|
}// function CompileClass()
|
|
|
|
|
|
protected function CompileMenu($oMenu, $sModuleRelativeDir, $oP)
|
|
{
|
|
$sMenuId = $oMenu->getAttribute("id");
|
|
$sMenuClass = $oMenu->getAttribute("xsi:type");
|
|
|
|
$sParent = $oMenu->GetChildText('parent', null);
|
|
if ($sParent)
|
|
{
|
|
$sParentSpec = "\$__comp_menus__['$sParent']->GetIndex()";
|
|
}
|
|
else
|
|
{
|
|
$sParentSpec = '-1';
|
|
}
|
|
|
|
$fRank = $oMenu->GetChildText('rank');
|
|
switch($sMenuClass)
|
|
{
|
|
case 'WebPageMenuNode':
|
|
$sUrl = $oMenu->GetChildText('url');
|
|
$sUrlSpec = $this->PathToPHP($sUrl, $sModuleRelativeDir, true /* Url */);
|
|
$sNewMenu = "new WebPageMenuNode('$sMenuId', $sUrlSpec, $sParentSpec, $fRank);";
|
|
break;
|
|
|
|
case 'DashboardMenuNode':
|
|
$sTemplateFile = $oMenu->GetChildText('definition_file');
|
|
$sTemplateSpec = $this->PathToPHP($sTemplateFile, $sModuleRelativeDir);
|
|
$sNewMenu = "new DashboardMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);";
|
|
break;
|
|
|
|
case 'TemplateMenuNode':
|
|
$sTemplateFile = $oMenu->GetChildText('template_file');
|
|
$sTemplateSpec = $this->PathToPHP($sTemplateFile, $sModuleRelativeDir);
|
|
$sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);";
|
|
break;
|
|
|
|
case 'OQLMenuNode':
|
|
$sOQL = self::QuoteForPHP($oMenu->GetChildText('oql'));
|
|
$bSearch = ($oMenu->GetChildText('do_search') == '1') ? 'true' : 'false';
|
|
$sNewMenu = "new OQLMenuNode('$sMenuId', $sOQL, $sParentSpec, $fRank, $bSearch);";
|
|
break;
|
|
|
|
case 'NewObjectMenuNode':
|
|
$sClass = $oMenu->GetChildText('class');
|
|
$sNewMenu = "new NewObjectMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);";
|
|
break;
|
|
|
|
case 'SearchMenuNode':
|
|
$sClass = $oMenu->GetChildText('class');
|
|
$sNewMenu = "new SearchMenuNode('$sMenuId', '$sClass', $sParentSpec, $fRank);";
|
|
break;
|
|
|
|
case 'MenuGroup':
|
|
default:
|
|
if ($sEnableClass = $oMenu->GetChildText('enable_class'))
|
|
{
|
|
$sEnableAction = $oMenu->GetChildText('enable_action');
|
|
$sEnablePermission = $oMenu->GetChildText('enable_permission');
|
|
$sEnableStimulus = $oMenu->GetChildText('enable_stimulus');
|
|
if (strlen($sEnableStimulus) > 0)
|
|
{
|
|
$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');";
|
|
}
|
|
else
|
|
{
|
|
$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);";
|
|
}
|
|
//$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', UR_ACTION_MODIFY, UR_ALLOWED_YES|UR_ALLOWED_DEPENDS);";
|
|
}
|
|
else
|
|
{
|
|
$sNewMenu = "new MenuGroup('$sMenuId', $fRank);";
|
|
}
|
|
}
|
|
|
|
$sIndent = '';
|
|
$aPHPMenu = array("\$__comp_menus__['$sMenuId'] = $sNewMenu");
|
|
if ($sAutoReload = $oMenu->GetChildText('auto_reload'))
|
|
{
|
|
$sAutoReload = self::QuoteForPHP($sAutoReload);
|
|
$aPHPMenu[] = "\$__comp_menus__['$sMenuId']->SetParameters(array('auto_reload' => $sAutoReload));";
|
|
}
|
|
|
|
$sAdminOnly = $oMenu->GetChildText('enable_admin_only');
|
|
if ($sAdminOnly && ($sAdminOnly == '1'))
|
|
{
|
|
$sPHP = $sIndent."if (UserRights::IsAdministrator())\n";
|
|
$sPHP .= $sIndent."{\n";
|
|
foreach($aPHPMenu as $sPHPLine)
|
|
{
|
|
$sPHP .= $sIndent." $sPHPLine\n";
|
|
}
|
|
$sPHP .= $sIndent."}\n";
|
|
}
|
|
else
|
|
{
|
|
$sPHP = '';
|
|
foreach($aPHPMenu as $sPHPLine)
|
|
{
|
|
$sPHP .= $sIndent.$sPHPLine."\n";
|
|
}
|
|
}
|
|
|
|
return $sPHP;
|
|
} // function CompileMenu
|
|
|
|
protected function CompileUserRights($oUserRightsNode)
|
|
{
|
|
static $aActionsInShort = array(
|
|
'read' => 'r',
|
|
'bulk read' => 'br',
|
|
'write' => 'w',
|
|
'bulk write' => 'bw',
|
|
'delete' => 'd',
|
|
'bulk delete' => 'bd',
|
|
);
|
|
|
|
// Groups
|
|
//
|
|
$aGroupClasses = array();
|
|
$oGroups = $oUserRightsNode->GetUniqueElement('groups');
|
|
foreach($oGroups->getElementsByTagName('group') as $oGroup)
|
|
{
|
|
$sGroupId = $oGroup->getAttribute("id");
|
|
|
|
$aClasses = array();
|
|
$oClasses = $oGroup->GetUniqueElement('classes');
|
|
foreach($oClasses->getElementsByTagName('class') as $oClass)
|
|
{
|
|
|
|
$sClass = $oClass->getAttribute("id");
|
|
$aClasses[] = $sClass;
|
|
|
|
//$bSubclasses = $this->GetPropBoolean($oClass, 'subclasses', true);
|
|
//if ($bSubclasses)...
|
|
}
|
|
|
|
$aGroupClasses[$sGroupId] = $aClasses;
|
|
}
|
|
|
|
// Profiles and grants
|
|
//
|
|
$aProfiles = array();
|
|
// Hardcode the administrator profile
|
|
$aProfiles[1] = array(
|
|
'name' => 'Administrator',
|
|
'description' => 'Has the rights on everything (bypassing any control)'
|
|
);
|
|
|
|
$aGrants = array();
|
|
$oProfiles = $oUserRightsNode->GetUniqueElement('profiles');
|
|
foreach($oProfiles->getElementsByTagName('profile') as $oProfile)
|
|
{
|
|
$iProfile = $oProfile->getAttribute("id");
|
|
$sName = $oProfile->GetChildText('name');
|
|
$sDescription = $oProfile->GetChildText('description');
|
|
|
|
$oGroups = $oProfile->GetUniqueElement('groups');
|
|
foreach($oGroups->getElementsByTagName('group') as $oGroup)
|
|
{
|
|
$sGroupId = $oGroup->getAttribute("id");
|
|
|
|
$aActions = array();
|
|
$oActions = $oGroup->GetUniqueElement('actions');
|
|
foreach($oActions->getElementsByTagName('action') as $oAction)
|
|
{
|
|
$sAction = $oAction->getAttribute("id");
|
|
$sType = $oAction->getAttribute("xsi:type");
|
|
$sGrant = $oAction->GetText();
|
|
$bGrant = ($sGrant == 'allow');
|
|
|
|
if ($sGroupId == '*')
|
|
{
|
|
$aGrantClasses = array('*');
|
|
}
|
|
else
|
|
{
|
|
$aGrantClasses = $aGroupClasses[$sGroupId];
|
|
}
|
|
foreach ($aGrantClasses as $sClass)
|
|
{
|
|
if ($sType == 'stimulus')
|
|
{
|
|
$sGrantKey = $iProfile.'_'.$sClass.'_s_'.$sAction;
|
|
$sGrantKeyPlus = $iProfile.'_'.$sClass.'+_s_'.$sAction; // subclasses inherit this grant
|
|
}
|
|
else
|
|
{
|
|
$sAction = $aActionsInShort[$sType];
|
|
$sGrantKey = $iProfile.'_'.$sClass.'_'.$sAction;
|
|
$sGrantKeyPlus = $iProfile.'_'.$sClass.'+_'.$sAction; // subclasses inherit this grant
|
|
}
|
|
// The class itself
|
|
if (isset($aGrants[$sGrantKey]))
|
|
{
|
|
if (!$bGrant)
|
|
{
|
|
$aGrants[$sGrantKey] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$aGrants[$sGrantKey] = $bGrant;
|
|
}
|
|
// The subclasses
|
|
if (isset($aGrants[$sGrantKeyPlus]))
|
|
{
|
|
if (!$bGrant)
|
|
{
|
|
$aGrants[$sGrantKeyPlus] = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$aGrants[$sGrantKeyPlus] = $bGrant;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$aProfiles[$iProfile] = array(
|
|
'name' => $sName,
|
|
'description' => $sDescription
|
|
);
|
|
}
|
|
|
|
$sProfiles = var_export($aProfiles, true);
|
|
$sGrants = var_export($aGrants, true);
|
|
|
|
$sPHP =
|
|
<<<EOF
|
|
|
|
//
|
|
// List of constant profiles
|
|
// - used by the class URP_Profiles at setup (create/update/delete records)
|
|
// - used by the addon UserRightsProfile to determine user rights
|
|
//
|
|
class ProfilesConfig
|
|
{
|
|
protected static \$aPROFILES = $sProfiles;
|
|
|
|
protected static \$aGRANTS = $sGrants;
|
|
|
|
public static function GetProfileActionGrant(\$iProfileId, \$sClass, \$sAction)
|
|
{
|
|
\$sGrantKey = \$iProfileId.'_'.\$sClass.'_'.\$sAction;
|
|
if (isset(self::\$aGRANTS[\$sGrantKey]))
|
|
{
|
|
return self::\$aGRANTS[\$sGrantKey];
|
|
}
|
|
foreach (MetaModel::EnumParentClasses(\$sClass) as \$sParent)
|
|
{
|
|
\$sGrantKey = \$iProfileId.'_'.\$sParent.'+_'.\$sAction;
|
|
if (isset(self::\$aGRANTS[\$sGrantKey]))
|
|
{
|
|
return self::\$aGRANTS[\$sGrantKey];
|
|
}
|
|
}
|
|
\$sGrantKey = \$iProfileId.'_*_'.\$sAction;
|
|
if (isset(self::\$aGRANTS[\$sGrantKey]))
|
|
{
|
|
return self::\$aGRANTS[\$sGrantKey];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static function GetProfileStimulusGrant(\$iProfileId, \$sClass, \$sStimulus)
|
|
{
|
|
\$sGrantKey = \$iProfileId.'_'.\$sClass.'_s_'.\$sStimulus;
|
|
if (isset(self::\$aGRANTS[\$sGrantKey]))
|
|
{
|
|
return self::\$aGRANTS[\$sGrantKey];
|
|
}
|
|
\$sGrantKey = \$iProfileId.'_*_s_'.\$sStimulus;
|
|
if (isset(self::\$aGRANTS[\$sGrantKey]))
|
|
{
|
|
return self::\$aGRANTS[\$sGrantKey];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// returns an array of id => array of column => php value(so-called "real value")
|
|
public static function GetProfilesValues()
|
|
{
|
|
return self::\$aPROFILES;
|
|
}
|
|
}
|
|
|
|
EOF;
|
|
return $sPHP;
|
|
} // function CompileUserRights
|
|
|
|
}
|
|
|
|
|
|
|
|
?>
|