Merge branch 'develop' into feature/b3217-2dev

This commit is contained in:
odain
2020-09-08 17:00:41 +02:00
641 changed files with 23943 additions and 4198 deletions

View File

@@ -60,6 +60,7 @@ class MFCompiler
protected $aSnippets;
protected $aRelations;
protected $sEnvironment;
protected $sCompilationTimeStamp;
public function __construct($oModelFactory, $sEnvironment)
{
@@ -74,7 +75,8 @@ class MFCompiler
$this->sMainPHPCode .= " * This file was automatically generated by the compiler on ".date('Y-m-d H:i:s')." -- DO NOT EDIT\n";
$this->sMainPHPCode .= " */\n";
$this->sMainPHPCode .= "\n";
$this->sMainPHPCode .= "define('COMPILATION_TIMESTAMP', '".microtime(true)."');\n";
$this->sCompilationTimeStamp = "".microtime(true);
$this->sMainPHPCode .= "define('COMPILATION_TIMESTAMP', '".$this->sCompilationTimeStamp."');\n";
$this->aSnippets = array();
$this->aRelations = array();
}
@@ -282,8 +284,8 @@ class MFCompiler
}
else
{
$sRelativeDir = '';
$sRealRelativeDir = '';
$sRelativeDir = $sModuleName;
$sRealRelativeDir = $sModuleName;
}
$aModulesInfo[$sModuleName] = array('root_dir' => $sRealRelativeDir, 'version' => $sModuleVersion);
@@ -325,20 +327,7 @@ class MFCompiler
$aAllClasses[] = $sClass;
try
{
$aCompiledClasses = $this->CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sRelativeDir);
foreach ($aCompiledClasses['required_files'] as $sIncludeFile)
{
$sCompiledCode .= "require_once('$sIncludeFile');\n";
}
foreach ($aCompiledClasses['code'] as $sClass => $sCompiledClass)
{
$sClassFileName = DIRECTORY_SEPARATOR.$sRelativeDir.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'Model'.DIRECTORY_SEPARATOR.$sClass.'.php';
$sClassFile = "{$sTempTargetDir}{$sClassFileName}";
$this->WritePHPFile($sClassFile, $sModuleName, $sModuleVersion, $sCompiledClass);
$sCompiledCode .= "require_once ('{$sFinalTargetDir}{$sClassFileName}');\n";
}
$sCompiledCode .= $this->CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sRelativeDir);
}
catch (DOMFormatException $e)
{
@@ -474,7 +463,7 @@ EOF;
{
// We have compiled something: write the code somewhere
//
if (strlen($sRelativeDir) > 0)
if (strlen($sModuleRootDir) > 0)
{
// Write the code into the given module as model.<module>.php
//
@@ -989,13 +978,14 @@ EOF
* @param string $sFinalTargetDir
* @param string $sModuleRelativeDir
*
* @return array
* @return string
* @throws \DOMFormatException
*/
protected function CompileClass($oClass, $sTempTargetDir, $sFinalTargetDir, $sModuleRelativeDir)
{
$sClass = $oClass->getAttribute('id');
$oProperties = $oClass->GetUniqueElement('properties');
$sPHP = '';
// Class caracteristics
//
@@ -1140,6 +1130,33 @@ EOF
}
}
if ($oAdditionalValueForSelect = $oProperties->GetOptionalElement('complement_for_select'))
{
$oNameAttributes = $oAdditionalValueForSelect->GetUniqueElement('attributes');
/** @var \DOMNodeList $oAttributes */
$oAttributes = $oNameAttributes->getElementsByTagName('attribute');
$aNameAttCodes = array();
/** @var \MFElement $oAttribute */
foreach($oAttributes as $oAttribute)
{
$aNameAttCodes[] = $oAttribute->getAttribute('id');
}
if (count($aNameAttCodes) > 0)
{
// New style...
$sNameAttCode = "array('".implode("', '", $aNameAttCodes)."')";
}
else
{
$sNameAttCode = "''";
}
}
else
{
$sNameAttCode = "''";
}
$aClassParams['name_complement_for_select'] = $sNameAttCode;
if ($oUniquenessRules = $oProperties->GetOptionalElement('uniqueness_rules'))
{
$aUniquenessRules = array();
@@ -2001,7 +2018,7 @@ $sZlists;
EOF;
// some other stuff (magical attributes like friendlyName) are done in MetaModel::InitClasses and though not present in the
// generated PHP
$aPHP[$sClassName] = $this->GeneratePhpCodeForClass($sClassName, $sParentClass, $sClassParams, $sInitMethodCalls, $bIsAbstractClass, $sMethods, $sCodeComment);
$sPHP .= $this->GeneratePhpCodeForClass($sClassName, $sParentClass, $sClassParams, $sInitMethodCalls, $bIsAbstractClass, $sMethods, $aRequiredFiles, $sCodeComment);
// N°931 generates TagFieldData classes for AttributeTag fields
if (!empty($aTagFieldsInfo))
@@ -2030,11 +2047,11 @@ EOF
{
$sTagClassName = static::GetTagDataClassName($sClassName, $sTagFieldName);
$sTagClassParams = var_export($aTagClassParams, true);
$aPHP[$sTagClassName] = $this->GeneratePhpCodeForClass($sTagClassName, $sTagClassParentClass, $sTagClassParams, $sTagInitMethodCalls);
$sPHP .= $this->GeneratePhpCodeForClass($sTagClassName, $sTagClassParentClass, $sTagClassParams, $sTagInitMethodCalls);
}
}
return ['code' => $aPHP, 'required_files' => $aRequiredFiles];
return $sPHP;
}
private static function GetTagDataClassName($sClass, $sAttCode)
@@ -2671,6 +2688,7 @@ EOF;
'variables' => array(),
'imports' => array(),
'stylesheets' => array(),
'precompiled_stylesheet' => '',
);
/** @var \DOMNodeList $oVariables */
@@ -2696,7 +2714,7 @@ EOF;
$sStylesheetId = $oStylesheet->getAttribute('id');
$aThemeParameters['stylesheets'][$sStylesheetId] = $oStylesheet->GetText();
}
$aThemeParameters['precompiled_stylesheet'] = $oTheme->GetChildText('precompiled_stylesheet', '');
$aThemes[$sThemeId] = $aThemeParameters;
}
@@ -2708,6 +2726,7 @@ EOF;
}
// Compile themes
$fStart = microtime(true);
foreach($aThemes as $sThemeId => $aThemeParameters)
{
$sThemeDir = $sThemesDir.$sThemeId;
@@ -2715,10 +2734,29 @@ EOF;
{
SetupUtils::builddir($sThemeDir);
}
// Check if a precompiled version of the theme is supplied
$sPrecompiledFile = $sTempTargetDir.$aThemeParameters['precompiled_stylesheet'];
if (file_exists($sPrecompiledFile))
{
copy($sPrecompiledFile, $sThemeDir.'/main.css');
// Make sure that the copy of the precompiled file is older than any other files to force a validation of the signature
touch($sThemeDir.'/main.css', 1577836800 /* 2020-01-01 00:00:00 */);
}
else if ($sPrecompiledFile != '')
{
$this->Log("Precompiled file not found: '$sPrecompiledFile'");
}
$bHasCompiled = ThemeHandler::CompileTheme($sThemeId, true, $this->sCompilationTimeStamp, $aThemeParameters, $aImportsPaths, $sTempTargetDir);
$sInitialPrecompiledFilePath = APPROOT.'datamodels/2.x/'.$aThemeParameters['precompiled_stylesheet'];
if ($bHasCompiled && is_file($sInitialPrecompiledFilePath))
{
SetupLog::Info("Replacing precompiled file $sInitialPrecompiledFilePath for theme $sThemeId for next setup.");
copy($sThemeDir.'/main.css', $sInitialPrecompiledFilePath);
}
ThemeHandler::CompileTheme($sThemeId, $aThemeParameters, $aImportsPaths, $sTempTargetDir);
}
$this->Log(sprintf('Themes compilation took: %.3f ms for %d themes.', (microtime(true) - $fStart)*1000.0, count($aThemes)));
}
/**
@@ -2965,6 +3003,7 @@ EOF;
* @param bool $bIsAbstractClass
* @param string $sMethods
*
* @param array $aRequiredFiles
* @param string $sCodeComment
*
* @return string php code for the class
@@ -2976,10 +3015,16 @@ EOF;
$sInitMethodCalls = '',
$bIsAbstractClass = false,
$sMethods = '',
$aRequiredFiles = [],
$sCodeComment = ''
) {
$sPHP = "\n\n$sCodeComment\n";
foreach ($aRequiredFiles as $sIncludeFile)
{
$sPHP .= "\nrequire_once('$sIncludeFile');\n";
}
if ($bIsAbstractClass)
{
$sPHP .= 'abstract class '.$sClassName;
@@ -3018,6 +3063,10 @@ EOF;
*/
protected function WriteFile($sFilename, $sContent, $flags = null)
{
if (is_file($sFilename) || is_link($sFilename))
{
@unlink($sFilename);
}
$ret = file_put_contents($sFilename, $sContent, $flags);
if ($ret === false)
{