Files
2018-04-02 08:07:38 +02:00

366 lines
9.6 KiB
PHP

<?php
/*
* Copyright notice
*
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project 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; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
*/
namespace Metaseo\Metaseo\Utility;
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
class TypoScript implements \Iterator
{
###########################################################################
## Attributes
###########################################################################
/**
* TYPO3 TypoScript Data
*
* @var array
*/
protected $tsData;
/**
* TYPO3 TypoScript Data Type
*
* @var string
*/
protected $tsType;
/**
* Iterator position
*
* @var mixed
*/
protected $iteratorPosition = false;
/**
* cObj
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
*/
protected $cObj;
###########################################################################
## Constructor
###########################################################################
/**
* Constructor
*
* @param NULL|array $conf TypoScript node configuration
* @param NULL|string $type TypoScript node type
*/
public function __construct($conf = null, $type = null)
{
if ($conf !== null) {
$this->tsData = $conf;
}
if ($type !== null) {
$this->tsType = $type;
}
}
###########################################################################
## Iterator methods
###########################################################################
/**
* Rewind iterator position
*/
public function rewind()
{
reset($this->tsData);
$this->iteratorNextNode();
}
/**
* Check if current node is a valid node
*
* @return boolean
*/
public function valid()
{
return $this->iteratorPosition && array_key_exists($this->iteratorPosition, $this->tsData);
}
/**
* Return current iterator key
*
* @return string TypoScript path-node-key
*/
public function key()
{
return substr($this->iteratorPosition, 0, -1);
}
/**
* Return current iterator node
*
* @return TypoScript
*/
public function current()
{
$nodePath = substr($this->iteratorPosition, 0, -1);
return $this->getNode($nodePath);
}
/**
* Get TypoScript subnode
*
* @param string $tsNodePath TypoScript node-path
*
* @return TypoScript TypoScript subnode-object
*/
public function getNode($tsNodePath)
{
$ret = null;
// extract TypoScript-path information
$nodeSections = explode('.', $tsNodePath);
$nodeValueType = end($nodeSections);
$nodeValueName = end($nodeSections) . '.';
// remove last node from sections because we already got the node name
unset($nodeSections[key($nodeSections)]);
// walk though array to find node
$nodeData = $this->tsData;
if (!empty($nodeSections) && is_array($nodeSections)) {
foreach ($nodeSections as $sectionName) {
$sectionName .= '.';
if (is_array($nodeData) && array_key_exists($sectionName, $nodeData)) {
$nodeData = $nodeData[$sectionName];
} else {
break;
}
}
}
// Fetch TypoScript configuration data
$tsData = array();
if (is_array($nodeData) && array_key_exists($nodeValueName, $nodeData)) {
$tsData = $nodeData[$nodeValueName];
}
// Fetch TypoScript configuration type
$tsType = null;
if (is_array($nodeData) && array_key_exists($nodeValueType, $nodeData)) {
$tsType = $nodeData[$nodeValueType];
}
// Clone object and set values
$ret = clone $this;
$ret->tsData = $tsData;
$ret->tsType = $tsType;
$ret->iteratorPosition = false;
return $ret;
}
/**
* Next iterator node
*/
public function next()
{
next($this->tsData);
$this->iteratorNextNode();
}
###########################################################################
## Public methods
###########################################################################
/**
* Search next iterator node
*/
public function iteratorNextNode()
{
// INIT
$iteratorPosition = null;
$this->iteratorPosition = false;
$nextNode = false;
do {
if ($nextNode) {
next($this->tsData);
}
$currentNode = current($this->tsData);
if ($currentNode !== false) {
// get key
$iteratorPosition = key($this->tsData);
// check if node is subnode or value
if (substr($iteratorPosition, -1) == '.') {
// next subnode fond
$this->iteratorPosition = $iteratorPosition;
break;
}
} else {
$iteratorPosition = false;
$this->iteratorPosition = false;
}
$nextNode = true;
} while ($iteratorPosition !== false);
}
/**
* Get value from node
*
* @param string $tsNodePath TypoScript node-path
* @param mixed $defaultValue Default value
*
* @return mixed Node value (or default value)
*/
public function getValue($tsNodePath, $defaultValue = null)
{
$ret = $defaultValue;
// extract TypoScript-path information
$nodeFound = true;
$nodeSections = explode('.', $tsNodePath);
$nodeValueName = end($nodeSections);
// remove last node from sections because we already got the node name
unset($nodeSections[key($nodeSections)]);
// walk though array to find node
$nodeData = $this->tsData;
if (!empty($nodeSections) && is_array($nodeSections)) {
foreach ($nodeSections as $sectionName) {
$sectionName .= '.';
if (is_array($nodeData) && array_key_exists($sectionName, $nodeData)) {
$nodeData = $nodeData[$sectionName];
} else {
$nodeFound = false;
break;
}
}
}
// check if we got the value of the node
if ($nodeFound && is_array($nodeData) && array_key_exists($nodeValueName, $nodeData)) {
$ret = $nodeData[$nodeValueName];
}
return $ret;
}
/**
* Convert TypoScript to original array
*
* @return array
*/
public function toArray()
{
return $this->tsData;
}
/**
* Check if TypoScript is empty/not set
*
* @return boolean
*/
public function isEmpty()
{
return empty($this->tsData);
}
/**
* Render TypoScript Config
*
* @return mixed Result of cObj
*/
public function render()
{
return $this->getCObj()->cObjGetSingle($this->tsType, $this->tsData);
}
/**
* StdWrap with TypoScript Configuration
*
* @param mixed $value Value for stdWrap
*
* @return mixed Result of stdWrap
*/
public function stdWrap($value = null)
{
return $this->getCObj()->stdWrap($value, $this->tsData);
}
###########################################################################
## Protected methods
###########################################################################
/**
* Return instance of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
*
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
*/
protected function getCObj()
{
if ($this->cObj === null) {
$this->cObj = Typo3GeneralUtility::makeInstance(
'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer'
);
}
return $this->cObj;
}
###########################################################################
## Private methods
###########################################################################
###########################################################################
## Accessors
###########################################################################
public function setTypoScript(Array $conf)
{
$this->tsData = $conf;
return $this;
}
public function getTypoScriptType()
{
return $this->tsType;
}
public function setTypoScriptType($value)
{
$this->tsType = (string)$value;
return $this;
}
}