* @version 0.0.0 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team * @license GNU GPL 3.0 or any newer version * @link http://www.shipsimu.org * * 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, either version 3 of the License, or * (at your option) any later version. * * 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, see . */ class BaseHelper extends BaseFrameworkSystem { /** * Instance to the class which provides field values */ private $valueInstance = NULL; /** * Extra instance to the class which provides field values */ private $extraInstance = NULL; /** * Rendered content created by the helper class */ private $content = ''; /** * Array with groups */ private $groups = array(); /** * Array with sub group */ private $subGroups = array(); /** * Previously opened group */ private $previousGroupId = ''; /** * Previously opened sub group */ private $previousSubGroupId = ''; /** * Total counter for groups and sub groups */ private $totalCounter = 0; // Exception constants const EXCEPTION_GROUP_NOT_OPENED = 0x1e3; const EXCEPTION_GROUP_ALREADY_FOUND = 0x1e4; const EXCEPTION_SUB_GROUP_ALREADY_FOUND = 0x1e5; const EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED = 0x1e6; const EXCEPTION_NO_PREVIOUS_GROUP_OPENED = 0x1e7; /** * Protected constructor * * @param $className Real name of the class * @return void */ protected function __construct ($className) { // Call parent constructor parent::__construct($className); } /** * Adds content directly * * @param $newContent New content to add * @return void */ protected final function addContent ($newContent) { $this->content .= (string) trim($newContent) . PHP_EOL; } /** * Add header content to the helper * * @param $content Content to to the base * @return void */ protected function addHeaderContent ($content) { // Add the header content $this->groups['header']['content'] = (string) trim($content); } /** * Add footer content to the helper * * @param $content Content to to the base * @return void */ protected function addFooterContent ($content) { // Add the footer content $this->groups['footer']['content'] = (string) trim($content); } /** * Adds content to the previously opened group or sub group. If a sub group * was found it will be taken. If no group/sub group is opened at the moment * the code will be passed to addContent(). * * @param $newContent New content to add * @return void */ protected final function addContentToPreviousGroup ($newContent) { // Check for sub/group if ($this->ifSubGroupOpenedPreviously()) { // Get sub group id $subGroupId = $this->getPreviousSubGroupId(); // Add the content $this->subGroups[$subGroupId]['content'] .= $newContent; } elseif ($this->ifGroupOpenedPreviously()) { // Get group id $groupId = $this->getPreviousGroupId(); // Add the content $this->groups[$groupId]['content'] .= $newContent; } else { // Add it directly $this->addContent($newContent); } } /** * Getter for content * * @return $content The rendered content by this helper */ protected final function getContent () { return $this->content; } /** * Public setter for extra instance * * @param $extraInstance An extra instance of FrameworkInterface to set * @return void */ public final function setExtraInstance (FrameworkInterface $extraInstance) { $this->extraInstance = $extraInstance; } /** * Assigns a field from the value instance with a template variable * * @param $fieldName Name of the field to assign * @return void */ public function assignField ($fieldName) { // Get the value from value instance $fieldValue = $this->getValueField($fieldName); // Assign it with a template variable $this->getTemplateInstance()->assignVariable('block_' . $fieldName, $fieldValue); } /** * Assigns a field from the value instance with a template variable but * parses its content through a given filter method of the value instance * * @param $fieldName Name of the field to assign * @param $filterMethod Method name to call of the value instance * @return void * @todo Rewrite this method using a helper class for filtering data */ public function assignFieldWithFilter ($fieldName, $filterMethod) { // Get the value $fieldValue = $this->getValueField($fieldName); //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.'='.$fieldValue); // Now filter it through the value through the filter method $filteredValue = call_user_func_array(array($this, 'doFilter' . self::convertToClassName($filterMethod)), array($fieldValue)); // Assign it with a template variable $this->getTemplateInstance()->assignVariable('block_' . $fieldName, $filteredValue); } /** * Pre-fetches field default values from the given registry key instance into this class * * @param $registryKey Registry key which holds an object with values * @param $extraKey Extra value instance key used if registryKey is null * @return void * @throws NullPointerException If recovery of requested value instance failed */ public function prefetchValueInstance ($registryKey, $extraKey = NULL) { //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('O:'.$registryKey.'/'.$extraKey); try { // Get the required instance $this->valueInstance = Registry::getRegistry()->getInstance($registryKey); } catch (NullPointerException $e) { // Not set in registry // @TODO Try to log it here //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($registryKey.'=NULL!'); } // Shall we get an extra instance? if (!is_null($extraKey)) { try { // Get the extra instance. $this->extraInstance = Registry::getRegistry()->getInstance($extraKey); } catch (NullPointerException $e) { // Try to create it $this->extraInstance = ObjectFactory::createObjectByConfiguredName($extraKey . '_class', array($this->valueInstance)); } //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($extraKey.'='.$this->extraInstance.' - EXTRA!'); } // END - if // Is the value instance valid? if (is_null($this->valueInstance)) { // Get the requested instance $this->valueInstance = ObjectFactory::createObjectByConfiguredName($registryKey . '_class', array($this->extraInstance)); } // END - if } /** * Opens a helper group with given group id and content or throws an * exception if that group is already found regardless if it is open or * closed. * * @param $groupId Group id to open * @param $content Initial content to add to the group * @param $tag HTML tag used to open this group * @return void * @throws HelperGroupAlreadyCreatedException If the group was already created before */ protected function openGroupByIdContent ($groupId, $content, $tag) { //* DEBUG: */ echo "OPEN:groupId={$groupId},content=
".htmlentities($content)."
\n"; // Is the group already there? if (isset($this->groups[$groupId])) { // Then throw an exception here throw new HelperGroupAlreadyCreatedException(array($this, $groupId), self::EXCEPTION_GROUP_ALREADY_FOUND); } // END - if // Count one up $this->totalCounter++; // Add the group to the stack $this->groups[$this->totalCounter] = $groupId; $this->groups[$groupId]['opened'] = true; $this->groups[$groupId]['content'] = sprintf( '%s' . PHP_EOL, $groupId, strlen($content), $tag, $content ); $this->groups[$groupId]['tag'] = $tag; // Mark this group as previously opened $this->setPreviousGroupId($groupId); } /** * Closes the previously opened group by added given content to it or * throws an exception if no previous group was opened * * @param $content Content for previously opened group, or empty to use tag of opener * @return void * @throws HelperNoPreviousOpenedGroupException If no previously opened group was found */ public function closePreviousGroupByContent ($content = '') { // Check if any sub group was opened before if ($this->ifSubGroupOpenedPreviously()) { // Close it automatically $this->closePreviousSubGroupByContent(); } // END - if // Check if any group was opened before if ($this->ifGroupOpenedPreviously() === false) { // Then throw an exception throw new HelperNoPreviousOpenedGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED); } // END - if // Get previous group $groupId = $this->getPreviousGroupId(); // Is the content empty? if ((empty($content)) && (!empty($this->groups[$groupId]['tag']))) { // Get it from opener $content = sprintf( "", $groupId, $this->groups[$groupId]['tag'] ); } // END - if // Add content to it and mark it as closed $this->groups[$groupId]['content'] .= sprintf( "%s\n", $groupId, strlen($content), $this->groups[$groupId]['tag'], $content ); $this->groups[$groupId]['opened'] = false; // Mark previous group as closed $this->setPreviousGroupId(''); //* DEBUG: */ echo "CLOSE:groupId={$groupId}
\n"; } /** * Opens a helper sub group with given group id and content or throws an * exception if that sub group is already found regardless if it is open or * closed. * * @param $subGroupId Sub group id to open * @param $content Initial content to add to the sub group * @param $tag HTML tag used to open this group * @return void * @throws HelperSubGroupAlreadyCreatedException If the sub group was already created before */ protected function openSubGroupByIdContent ($subGroupId, $content, $tag) { //* DEBUG: */ echo "OPEN:subGroupId={$subGroupId},content=".htmlentities($content)."
\n"; // Is the group already there? if (isset($this->subGroups[$subGroupId])) { // Then throw an exception here throw new HelperSubGroupAlreadyCreatedException(array($this, $subGroupId), self::EXCEPTION_SUB_GROUP_ALREADY_FOUND); } // END - if // Count one up $this->totalCounter++; // Add the group to the stack $this->subGroups[$this->totalCounter] = $subGroupId; $this->subGroups[$subGroupId]['opened'] = true; $this->subGroups[$subGroupId]['content'] = sprintf("%s\n", $subGroupId, strlen($content), $tag, $content); $this->subGroups[$subGroupId]['tag'] = $tag; // Mark this group as previously opened $this->setPreviousSubGroupId($subGroupId); } /** * Closes the previously opened sub group by added given content to it or * throws an exception if no previous sub group was opened * * @param $content Content for previously opened sub group, or leave empty to use div/span of openener * @return void * @throws HelperNoPreviousOpenedSubGroupException If no previously opened sub group was found */ public function closePreviousSubGroupByContent ($content = '') { // Check if any sub group was opened before if ($this->ifSubGroupOpenedPreviously() === false) { // Then throw an exception throw new HelperNoPreviousOpenedSubGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED); } // END - if // Get previous sub group $subGroupId = $this->getPreviousSubGroupId(); // Is the content empty? if ((empty($content)) && (!empty($this->subGroups[$subGroupId]['tag']))) { // Get it from opener $content = sprintf('', $subGroupId, $this->subGroups[$subGroupId]['tag']); } // END - if // Add content to it and mark it as closed $this->subGroups[$subGroupId]['content'] .= sprintf('%s' . PHP_EOL, $subGroupId, strlen($content), $this->subGroups[$subGroupId]['tag'], $content); $this->subGroups[$subGroupId]['opened'] = false ; // Mark previous sub group as closed $this->setPreviousSubGroupId(''); //* DEBUG: */ echo "CLOSE:subGroupId={$subGroupId}
\n"; } /** * Renders all group and sub group in their order * * @return $content Rendered HTML content */ public function renderContent () { // Initialize content $content = ''; // Is header content there? if (isset($this->groups['header'])) { // Then add it $content .= $this->groups['header']['content'] . PHP_EOL; } // END - if // Initiate content $content .= $this->getContent(); // Now "walk" through all groups and sub-groups for ($idx = 1; $idx <= $this->totalCounter; $idx++) { // Is this a sub/group and is it closed? if ((isset($this->groups[$idx])) && ($this->groups[$this->groups[$idx]]['opened'] === false)) { // Then add it's content $groupContent = trim($this->groups[$this->groups[$idx]]['content']); //* DEBUG: */ echo "group={$this->groups[$idx]},content=
".htmlentities($groupContent)."

\n"; $content .= $groupContent; } elseif ((isset($this->subGroups[$idx])) && ($this->subGroups[$this->subGroups[$idx]]['opened'] === false)) { // Then add it's content $subGroupContent = $this->subGroups[$this->subGroups[$idx]]['content']; //* DEBUG: */ echo "subgroup={$this->subGroups[$idx]},content=
".htmlentities($subGroupContent)."

\n"; $content .= trim($subGroupContent); } else { // Something went wrong $this->debugInstance(__METHOD__ . '(): Something unexpected happened here.'); } } // END - for // Is footer content there? if (isset($this->groups['footer'])) { // Then add it $content .= $this->groups['footer']['content'] . PHP_EOL; } // END - if // Return it //* DEBUG: */ echo "content=
".htmlentities($content)."
(".strlen($content).")
\n"; return $content; } /** * Checks whether the specified group is opened * * @param $groupId Id of group to check * @return $isOpened Whether the specified group is open */ protected function ifGroupIsOpened ($groupId) { // Is the group open? $isOpened = ((isset($this->groups[$groupId])) && ($this->groups[$groupId]['opened'] === true)); // Return status return $isOpened; } /** * Getter for direct field values * * @param $fieldName Name of the field we shall fetch * @return $fieldValue Value from field * @throws NullPointerException Thrown if $valueInstance is null */ public function getValueField ($fieldName) { // Init value $fieldValue = NULL; // The $valueInstance attribute should not be null! if (is_null($this->getValueInstance())) { // Throws an exception here throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } // END - if // Is the field set? if ($this->getValueInstance()->isFieldSet($fieldName)) { // Get the field value $fieldValue = $this->getValueInstance()->getField($fieldName); //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.'[]='.gettype($fieldValue).'('.strlen($fieldValue).') - Value instance!'); } elseif ((!is_null($this->extraInstance)) && ($this->extraInstance->isFieldSet($fieldName))) { // So try the extra instance $fieldValue = $this->extraInstance->getField($fieldName); //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.'[]='.gettype($fieldValue).'('.strlen($fieldValue).') - Extra instance!'); } else { // Field is not set $this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] fieldName=' . $fieldName . ' is not set! - @TODO'); } // END - if // Return it return $fieldValue; } /** * Getter for value instance * * @return $valueInstance Instance of the class holding our values */ public final function getValueInstance () { return $this->valueInstance; } /** * Check whether a group was opened previously * * @return $groupOpened Whether any group was opened before */ protected final function ifGroupOpenedPreviously () { $groupOpened = (!empty($this->previousGroupId)); return $groupOpened; } /** * Check whether a group was opened previously * * @return $subGroupOpened Whether any group was opened before */ protected final function ifSubGroupOpenedPreviously () { $subGroupOpened = (!empty($this->previousSubGroupId)); return $subGroupOpened; } /** * Getter for previous group id * * @return $previousGroupId Id of previously opened group */ protected final function getPreviousGroupId () { return $this->previousGroupId; } /** * Setter for previous group id * * @param $previousGroupId Id of previously opened group * @return void */ protected final function setPreviousGroupId ($previousGroupId) { $this->previousGroupId = (string) $previousGroupId; } /** * Getter for previous sub group id * * @return $previousSubGroupId Id of previously opened sub group */ protected final function getPreviousSubGroupId () { return $this->previousSubGroupId; } /** * Setter for previous sub group id * * @param $previousSubGroupId Id of previously opened sub group * @return void */ protected final function setPreviousSubGroupId ($previousSubGroupId) { $this->previousSubGroupId = (string) $previousSubGroupId; } }