Composer Compliant File Name: Mask

This commit is contained in:
2021-06-28 20:35:21 +02:00
parent 7fccf775a5
commit 0ff486f0d0

316
inc/Mask.php Executable file
View File

@@ -0,0 +1,316 @@
<?php
namespace Franzz\Objects;
use \Settings;
/**
* Mask Reader
* @author franzz
* @version 1.2
*/
class Mask extends PhpObject
{
public $sMaskName;
public $sFilePath;
private $sMask;
private $asTags;
private $asTagsParams;
private $asPartsSource;
private $aoInstances;
private $oLang;
private $sTimezone;
const MASK_FOLDER = 'masks/';
const MASK_EXT = '.html';
const START_TAG = 'START';
const END_TAG = 'END';
const TAG_MARK = '[#]';
const LANG_PREFIX = 'lang:';
const TIME_PREFIX = 'time:';
public function __construct($sFileName='', Translator $oLang=null, $sTimezone = '')
{
//init
parent::__construct(__FILE__, Settings::DEBUG);
$this->sMaskName = '';
$this->sFilePath = '';
$this->sMask = '';
$this->asTags = array();
$this->asTagsParams = array();
$this->asPartsSource = array();
$this->aoInstances = array();
$this->sFilePath = '';
$this->setTranslator($oLang);
$this->setTimezone($sTimezone);
//load file
if($sFileName!='') $this->initFile($sFileName);
}
public function setLanguage($sLang, $sDefaultLang='') {
if(is_null($this->oLang)) $this->setTranslator(new Translator($sLang, $sDefaultLang));
else {
$this->oLang->setLanguage($sLang, $sDefaultLang);
foreach($this->aoInstances as &$aoPartInstance) {
foreach($aoPartInstance as $oInstance) $oInstance->setLanguage($sLang, $sDefaultLang);
}
}
}
public function setTimezone($sTimezone) {
$this->sTimezone = ($sTimezone=='')?Settings::TIMEZONE:$sTimezone;
}
private function setTranslator($oLang) {
$this->oLang = $oLang;
foreach($this->aoInstances as &$aoPartInstance) {
foreach($aoPartInstance as $oInstance) $oInstance->setTranslator($this->oLang);
}
}
/**
* Get Mask Translator
* @return Translator
*/
public function getTranslator() {
return $this->oLang;
}
public static function getMaskFile($sFileName)
{
return self::MASK_FOLDER.$sFileName.self::MASK_EXT;
}
public function initFile($sFileName)
{
$sFilePath = self::getMaskFile(basename($sFileName));
if(file_exists($sFilePath))
{
$this->sFilePath = $sFilePath;
$sSource = file_get_contents($this->sFilePath);
$this->initMask($sFileName, $sSource);
}
else
{
$this->addError('Fichier introuvable &agrave; l\'adresse : '.$sFilePath);
}
}
public function initFileFromString($sSource, $sPartName='', $iInstanceNb=0)
{
$this->initMask($sPartName.' (from row) '.$iInstanceNb, $sSource);
}
private function initMask($sMaskName, $sSource)
{
$this->sMaskName = $sMaskName;
$this->sMask = $sSource;
$this->setParts();
$this->setDefaultTagValues();
}
private function setParts()
{
while(preg_match('/\<\!-- \[PART\] (?P<part>\S+) \[START\] --\>/u', $this->sMask, $asMatch))
{
$sPartName = $asMatch['part'];
$this->asPartsSource[$sPartName] = $this->getCleanPart($sPartName);
$this->aoInstances[$sPartName] = array();
}
}
private function getCleanPart($sPartName)
{
$iStartPos = $this->getPartStartPos($sPartName);
$iEndPos = $this->getPartEndPos($sPartName);
$sPart = mb_substr($this->sMask, $iStartPos, $iEndPos-$iStartPos);
$sExtendedPart = $this->getPartPattern($sPartName, self::START_TAG).$sPart. $this->getPartPattern($sPartName, self::END_TAG);
$this->sMask = str_replace($sExtendedPart, $this->getPartTagPattern($sPartName), $this->sMask);
return $sPart;
}
private function getPartStartPos($sPartName)
{
$sPartStartPattern = $this->getPartPattern($sPartName, self::START_TAG);
return mb_strpos($this->sMask, $sPartStartPattern) + strlen($sPartStartPattern);
}
private function getPartEndPos($sPartName)
{
$sPartEndPattern = $this->getPartPattern($sPartName, self::END_TAG);
return mb_strpos($this->sMask, $sPartEndPattern);
}
private function getPartPattern($sPartName, $sAction)
{
return '<!-- [PART] '.$sPartName.' ['.$sAction.'] -->';
}
private function getPartTagPattern($sPartName, $bMark=true)
{
$sPartTag = 'PART '.$sPartName;
return $bMark?$this->addTagMark($sPartTag):$sPartTag;
}
public function addInstance($sPartName, $asTags)
{
$this->newInstance($sPartName);
foreach($asTags as $sTagName=>$sTagValue)
{
$this->setInstanceTag($sPartName, $sTagName, $sTagValue);
}
}
public function newInstance($sPartName)
{
//Finding the part ($oMask is a pointer)
$oMask = $this->findPart($this, $sPartName);
if(!$oMask) $this->addError('No part found : '.$sPartName);
//Retrieving source html
$sPartSource = $oMask->asPartsSource[$sPartName];
//Creating new instance
$oInstance = new Mask('', $this->oLang);
$oInstance->initFileFromString($sPartSource, $sPartName);
$oMask->aoInstances[$sPartName][] = $oInstance;
}
public function setInstanceTag($sPartName, $sTagName, $sTagValue, $asTagParams=array())
{
$oMask = $this->findPart($this, $sPartName);
if(!$oMask) $this->addError('No part found : '.$sPartName);
$oMask->getCurrentInstance($sPartName)->setTag($sTagName, $sTagValue, $asTagParams);
}
public function setInstanceTags($sPartName, $asTags)
{
$oMask = $this->findPart($this, $sPartName);
if(!$oMask) $this->addError('No part found : '.$sPartName);
foreach($asTags as $sTagName=>$sTagValue) {
$oMask->getCurrentInstance($sPartName)->setTag($sTagName, $sTagValue);
}
}
private function findPart($oMask, $sPartName)
{
if(array_key_exists($sPartName, $oMask->aoInstances))
{
return $oMask;
}
else //going deeper to find the part
{
foreach($oMask->aoInstances as $sLevelPartName=>$aoInstances)
{
if(!empty($aoInstances))
{
//take last instances
$oTmpMask = $this->findPart($oMask->getCurrentInstance($sLevelPartName), $sPartName);
if($oTmpMask) return $oTmpMask;
}
}
}
return false;
}
/**
* returns latest instance
* @param String $sPartName
* @return Mask
*/
private function getCurrentInstance($sPartName)
{
if(!empty($this->aoInstances[$sPartName]))
{
return end($this->aoInstances[$sPartName]);
}
else
{
return false;
}
}
private function setDefaultTagValues() {
$asTagNames = $this->getTags();
//Default translations
foreach($asTagNames as $sTagName) {
if(self::isLangTag($sTagName)) $this->setTag($sTagName, $sTagName);
}
}
public function getTags()
{
$asMatches = array('tag'=>array());
$sSafeTagMark = preg_quote(self::TAG_MARK);
$sSafeLangMark = preg_quote(self::LANG_PREFIX);
$sPattern = '/'.$sSafeTagMark.'(?P<tag>('.$sSafeLangMark.'|)[\w\-]+)'.$sSafeTagMark.'/u';
preg_match_all($sPattern, $this->sMask, $asMatches);
return array_unique(array_filter($asMatches['tag']));
}
public function setTag($sTagName, $sTagValue, $asTagParams=array())
{
$this->asTags[$sTagName] = $sTagValue;
$this->asTagsParams[$sTagName] = $asTagParams;
}
public function setTags($asTags)
{
foreach($asTags as $sTagName=>$sTagValue) $this->setTag($sTagName, $sTagValue);
}
private static function isLangTag($sTag) {
return (mb_substr($sTag, 0, 5) == self::LANG_PREFIX);
}
private static function isTimeTag($sTag) {
return (mb_substr($sTag, 0, 5) == self::TIME_PREFIX);
}
public function getMask()
{
$sCompletedMask = $this->sMask;
//Build Parts
foreach($this->aoInstances as $sPart=>$aoParts)
{
$sTagValue = '';
foreach($aoParts as $oInstance)
{
$sTagValue .= $oInstance->getMask();
}
$this->setTag($this->getPartTagPattern($sPart, false), $sTagValue);
}
//Special Tags
$asTags = $this->asTags;
foreach($asTags as $sTagName=>&$sTagValue) {
$sTagActValue = mb_substr($sTagValue, 5);
//Translate Tag
if(!is_null($this->oLang) && self::isLangTag($sTagValue)) $sTagValue = $this->oLang->getTranslation($sTagActValue, $this->asTagsParams[$sTagName]);
//Convert Value to Mask Time Zone
if(self::isTimeTag($sTagValue)) $sTagValue = (new \DateTime('@'.$sTagActValue))->setTimeZone(new \DateTimeZone($this->sTimezone))->format($this->asTagsParams[$sTagName]);;
}
//Replace Tags
if(!empty($asTags)) {
$asMarkedTags = $this->addTagMark(array_keys($asTags));
$sCompletedMask = str_replace($asMarkedTags, $asTags, $sCompletedMask);
}
return $sCompletedMask;
}
private function addTagMark($oData)
{
return ToolBox::array_map_encapsulate($oData, self::TAG_MARK);
}
}
?>