]> git.mxchange.org Git - core.git/blob - framework/main/classes/helper/class_BaseHelper.php
Continued:
[core.git] / framework / main / classes / helper / class_BaseHelper.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Helper;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
7 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
8 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
9 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
10 use Org\Mxchange\CoreFramework\Registry\Object\ObjectRegistry;
11 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
12
13 // Import SPL stuff
14 use \BasMethodCallException;
15 use \InvalidArgumentException;
16
17 /**
18  * A generic helper class with generic methods
19  *
20  * @author              Roland Haeder <webmaster@shipsimu.org>
21  * @version             0.0.0
22  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
23  * @license             GNU GPL 3.0 or any newer version
24  * @link                http://www.shipsimu.org
25  *
26  * This program is free software: you can redistribute it and/or modify
27  * it under the terms of the GNU General Public License as published by
28  * the Free Software Foundation, either version 3 of the License, or
29  * (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34  * GNU General Public License for more details.
35  *
36  * You should have received a copy of the GNU General Public License
37  * along with this program. If not, see <http://www.gnu.org/licenses/>.
38  */
39 abstract class BaseHelper extends BaseFrameworkSystem {
40         /**
41          * Instance to the class which provides field values
42          */
43         private $valueInstance = NULL;
44
45         /**
46          * Extra instance to the class which provides field values
47          */
48         private $extraInstance = NULL;
49
50         /**
51          * Rendered content created by the helper class
52          */
53         private $content = '';
54
55         /**
56          * Array with groups
57          */
58         private $groups = [];
59
60         /**
61          * Array with sub group
62          */
63         private $subGroups = [];
64
65         /**
66          * Previously opened group
67          */
68         private $previousGroupId = '';
69
70         /**
71          * Previously opened sub group
72          */
73         private $previousSubGroupId = '';
74
75         /**
76          * Total counter for groups and sub groups
77          */
78         private $totalCounter = 0;
79
80         // Exception constants
81         const EXCEPTION_GROUP_NOT_OPENED             = 0x1e0;
82         const EXCEPTION_SUB_GROUP_ALREADY_FOUND      = 0x1e1;
83         const EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED = 0x1e2;
84         const EXCEPTION_NO_PREVIOUS_GROUP_OPENED     = 0x1e3;
85
86         /**
87          * Protected constructor
88          *
89          * @param       $className      Real name of the class
90          * @return      void
91          */
92         protected function __construct (string $className) {
93                 // Call parent constructor
94                 parent::__construct($className);
95         }
96
97         /**
98          * Adds content directly
99          *
100          * @param       $newContent             New content to add
101          * @return      void
102          */
103         protected final function addContent (string $newContent) {
104                 $this->content .= trim($newContent) . PHP_EOL;
105         }
106
107         /**
108          * Add header content to the helper
109          *
110          * @param       $content        Content to to the base
111          * @return      void
112          */
113         protected function addHeaderContent (string $content) {
114                 // Add the header content
115                 $this->groups['header']['content'] = trim($content);
116         }
117
118         /**
119          * Add footer content to the helper
120          *
121          * @param       $content        Content to to the base
122          * @return      void
123          */
124         protected function addFooterContent (string $content) {
125                 // Add the footer content
126                 $this->groups['footer']['content'] = trim($content);
127         }
128
129         /**
130          * Adds content to the previously opened group or sub group. If a sub group
131          * was found it will be taken. If no group/sub group is opened at the moment
132          * the code will be passed to addContent().
133          *
134          * @param       $newContent             New content to add
135          * @return      void
136          * @throws      InvalidArgumentException        If a parameter has an invalid value
137          */
138         protected final function addContentToPreviousGroup (string $newContent) {
139                 // Check on parameter
140                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: newContent=%s - CALLED!', $newContent));
141                 if (empty($newContent)) {
142                         // Throw IAE
143                         throw new InvalidArgumentException('Parameter "newContent" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
144                 }
145
146                 // Check for sub/group
147                 if ($this->ifSubGroupOpenedPreviously()) {
148                         // Get sub group id
149                         $subGroupId = $this->getPreviousSubGroupId();
150
151                         // Add the content
152                         $this->subGroups[$subGroupId]['content'] .= $newContent;
153                 } elseif ($this->ifGroupOpenedPreviously()) {
154                         // Get group id
155                         $groupId = $this->getPreviousGroupId();
156
157                         // Add the content
158                         $this->groups[$groupId]['content'] .= $newContent;
159                 } else {
160                         // Add it directly
161                         $this->addContent($newContent);
162                 }
163
164                 // Trace message
165                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-HELPER: EXIT!');
166         }
167
168         /**
169          * Getter for content
170          *
171          * @return      $content        The rendered content by this helper
172          */
173         protected final function getContent () {
174                 return $this->content;
175         }
176
177         /**
178          * Public setter for extra instance
179          *
180          * @param       $extraInstance  An extra instance of FrameworkInterface to set
181          * @return      void
182          */
183         public final function setExtraInstance (FrameworkInterface $extraInstance) {
184                 $this->extraInstance = $extraInstance;
185         }
186
187         /**
188          *  Assigns a field from the value instance with a template variable
189          *
190          * @param       $fieldName      Name of the field to assign
191          * @return      void
192          * @throws      InvalidArgumentException        If a parameter has an invalid value
193          */
194         public function assignField (string $fieldName) {
195                 // Check on parameter
196                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: fieldName=%s - CALLED!', $fieldName));
197                 if (empty($fieldName)) {
198                         // Throw IAE
199                         throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
200                 }
201
202                 // Get the value from value instance
203                 $fieldValue = $this->getValueField($fieldName);
204
205                 // Assign it with a template variable
206                 $this->getTemplateInstance()->assignVariable('block_' . $fieldName, $fieldValue);
207
208                 // Trace message
209                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-HELPER: EXIT!');
210         }
211
212         /**
213          * Assigns a field from the value instance with a template variable but
214          * parses its content through a given filter method of the value instance
215          *
216          * @param       $fieldName              Name of the field to assign
217          * @param       $filterMethod   Method name to call of the value instance
218          * @return      void
219          * @throws      InvalidArgumentException        If a parameter has an invalid value
220          * @todo        Rewrite this method using a helper class for filtering data
221          */
222         public function assignFieldWithFilter (string $fieldName, string $filterMethod) {
223                 // Validate parameter
224                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: fieldName=%s,filterMethod=%s - CALLED!', $fieldName, $filterMethod));
225                 if (empty($fieldName)) {
226                         // Throw IAE
227                         throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
228                 } elseif (empty($filterMethod)) {
229                         // Throw IAE
230                         throw new InvalidArgumentException('Parameter "filterMethod" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
231                 }
232
233                 // Get the value
234                 $fieldValue = $this->getValueField($fieldName);
235
236                 // Now filter it through the value through the filter method
237                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: %s[%s]=%s', $fieldName, gettype($fieldValue), $fieldValue));
238                 $filteredValue = call_user_func_array(array($this, 'doFilter' . StringUtils::convertToClassName($filterMethod)), array($fieldValue));
239
240                 // Assign it with a template variable
241                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: filteredValue[%s]=%s', gettype($filteredValue), $filteredValue));
242                 $this->getTemplateInstance()->assignVariable('block_' . $fieldName, $filteredValue);
243
244                 // Trace message
245                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-HELPER: EXIT!');
246         }
247
248         /**
249          * Pre-fetches field default values from the given registry key instance into this class
250          *
251          * @param       $registryKey    Registry key which holds an object with values
252          * @param       $extraKey               Extra value instance key used if registryKey is null
253          * @return      void
254          * @throws      InvalidArgumentException        If a parameter has an invalid value
255          */
256         public function prefetchValueInstance (string $registryKey, string $extraKey = NULL) {
257                 // Validate parameter
258                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: registryKey=%s,extraKey[%s]=%s - CALLED!', $registryKey, gettype($extraKey), $extraKey));
259                 if (empty($registryKey)) {
260                         // Throw IAE
261                         throw new InvalidArgumentException('Parameter "registryKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
262                 }
263
264                 try {
265                         // Get the required instance
266                         $this->valueInstance = ObjectRegistry::getRegistry('generic')->getInstance($registryKey);
267                 } catch (NullPointerException $e) {
268                         // Not set in registry
269                         //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: registryKey=%s returned no instance (NPE thrown)', $registryKey));
270                 }
271
272                 // Shall we get an extra instance?
273                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: extraKey[%s]=%s', gettype($extraKey), $extraKey));
274                 if (!is_null($extraKey)) {
275                         try {
276                                 // Get the extra instance.
277                                 $this->extraInstance = ObjectRegistry::getRegistry('generic')->getInstance($extraKey);
278                         } catch (NullPointerException $e) {
279                                 // Try to create it
280                                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: extraKey=%s returned no instance (NPE thrown), this->valueInstance[]=%s', $extraKey, gettype($this->valueInstance)));
281                                 $this->extraInstance = ObjectFactory::createObjectByConfiguredName($extraKey . '_class', [$this->valueInstance]);
282                         }
283                         //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: extraKey=%s,this->extraInstance[%s]=%s', $extraKey, gettype($this->extraInstance), $this->extraInstance));
284                 }
285
286                 // Is the value instance valid?
287                 //* NOSIY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: this->valueInstance[]=%s - BEFORE!', gettype($this->valueInstance)));
288                 if (is_null($this->valueInstance)) {
289                         // Get the requested instance
290                         $this->valueInstance = ObjectFactory::createObjectByConfiguredName($registryKey . '_class', array($this->extraInstance));
291                 }
292
293                 // Trace message
294                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: this->valueInstance[]=%s - AFTER/EXIT!', gettype($this->valueInstance)));
295         }
296
297         /**
298          * Opens a helper group with given group id and content or throws an
299          * exception if that group is already found regardless if it is open or
300          * closed.
301          *
302          * @param       $groupId        Group id to open
303          * @param       $content        Initial content to add to the group
304          * @param       $tag            HTML tag used to open this group
305          * @return      void
306          * @throws      InvalidArgumentException        If a parameter has an invalid value
307          * @throws      BadMethodCallException  If the group was already created before
308          */
309         protected function openGroupByIdContent (string $groupId, string $content, string $tag) {
310                 // Is the group already there?
311                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: groupdId=%s,content=%s,tag=%s - CALLED!', $groupdId, $content, $tag));
312                 if (empty($groupId)) {
313                         // Throw IAE
314                         throw new InvalidArgumentException('Parameter "groupId" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
315                 } elseif (isset($this->groups[$groupId])) {
316                         // Then throw an exception here
317                         throw new BadMethodCallException(sprintf('[%s:%d]: groupId=%s is already opened.', $this->__toString(), $groupId), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
318                 } elseif (empty($content)) {
319                         // Throw IAE
320                         throw new InvalidArgumentException('Parameter "content" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
321                 } elseif (empty($tag)) {
322                         // Throw IAE
323                         throw new InvalidArgumentException('Parameter "tag" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
324                 }
325
326                 // Count one up
327                 $this->totalCounter++;
328
329                 // Add the group to the stack
330                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: this->totalCounter=%d', $this->totalCounter));
331                 $this->groups[$this->totalCounter] = $groupId;
332                 $this->groups[$groupId]['opened']  = true;
333                 $this->groups[$groupId]['content'] = sprintf(
334                         '<!-- group %s opened (length: %s, tag: %s) //-->%s' . PHP_EOL,
335                         $groupId,
336                         strlen($content),
337                         $tag,
338                         $content
339                 );
340                 $this->groups[$groupId]['tag'] = $tag;
341
342                 // Mark this group as previously opened
343                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: Setting this->previousGroupId=%s ...', $groupId));
344                 $this->setPreviousGroupId($groupId);
345
346                 // Trace message
347                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-HELPER: EXIT!');
348         }
349
350         /**
351          * Closes the previously opened group by added given content to it or
352          * throws an exception if no previous group was opened
353          *
354          * @param       $content        Content for previously opened group, or empty to use tag of opener
355          * @return      void
356          * @throws      HelperNoPreviousOpenedGroupException    If no previously opened group was found
357          */
358         public function closePreviousGroupByContent (string $content = '') {
359                 // Check if any sub group was opened before
360                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: content(%d)=%s - CALLED!', strlen($content), $content));
361                 if ($this->ifSubGroupOpenedPreviously()) {
362                         // Close it automatically
363                         $this->closePreviousSubGroupByContent();
364                 }
365
366                 // Check if any group was opened before
367                 if ($this->ifGroupOpenedPreviously() === false) {
368                         // Then throw an exception
369                         throw new HelperNoPreviousOpenedGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED);
370                 }
371
372                 // Get previous group
373                 $groupId = $this->getPreviousGroupId();
374
375                 // Is the content empty?
376                 if ((empty($content)) && (!empty($this->groups[$groupId]['tag']))) {
377                         // Get it from opener
378                         $content = sprintf(
379                                 "<!-- group %s auto-closed //--></%s>",
380                                 $groupId,
381                                 $this->groups[$groupId]['tag']
382                         );
383                 }
384
385                 // Add content to it and mark it as closed
386                 $this->groups[$groupId]['content'] .= sprintf(
387                         "<!-- group %s closed (length: %s, tag: %s) //-->%s\n",
388                         $groupId,
389                         strlen($content),
390                         $this->groups[$groupId]['tag'],
391                         $content
392                 );
393                 $this->groups[$groupId]['opened'] = false;
394
395                 // Mark previous group as closed
396                 $this->setPreviousGroupId('');
397                 //* NOISY-DEBUG: */ echo "CLOSE:groupId={$groupId}<br />\n";
398         }
399
400         /**
401          * Opens a helper sub group with given group id and content or throws an
402          * exception if that sub group is already found regardless if it is open or
403          * closed.
404          *
405          * @param       $subGroupId             Sub group id to open
406          * @param       $content                Initial content to add to the sub group
407          * @param       $tag                    HTML tag used to open this group
408          * @return      void
409          * @throws      HelperSubGroupAlreadyCreatedException   If the sub group was already created before
410          */
411         protected function openSubGroupByIdContent (string $subGroupId, string $content, string $tag) {
412                 //* NOISY-DEBUG: */ echo "OPEN:subGroupId={$subGroupId},content=".htmlentities($content)."<br />\n";
413                 // Is the group already there?
414                 if (empty($subGroupId)) {
415                         // Throw IAE
416                         throw new InvalidArgumentException('Parameter "subGroupId" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
417                 } elseif (isset($this->subGroups[$subGroupId])) {
418                         // Then throw an exception here
419                         throw new HelperSubGroupAlreadyCreatedException(array($this, $subGroupId), self::EXCEPTION_SUB_GROUP_ALREADY_FOUND);
420                 }
421
422                 // Count one up
423                 $this->totalCounter++;
424
425                 // Add the group to the stack
426                 $this->subGroups[$this->totalCounter] = $subGroupId;
427                 $this->subGroups[$subGroupId]['opened']  = true;
428                 $this->subGroups[$subGroupId]['content'] = sprintf("<!-- sub-group %s opened (length: %s, tag: %s) //-->%s\n", $subGroupId, strlen($content), $tag, $content);
429                 $this->subGroups[$subGroupId]['tag'] = $tag;
430
431                 // Mark this group as previously opened
432                 $this->setPreviousSubGroupId($subGroupId);
433         }
434
435         /**
436          * Closes the previously opened sub group by added given content to it or
437          * throws an exception if no previous sub group was opened
438          *
439          * @param       $content        Content for previously opened sub group, or leave empty to use div/span of openener
440          * @return      void
441          * @throws      HelperNoPreviousOpenedSubGroupException If no previously opened sub group was found
442          */
443         public function closePreviousSubGroupByContent (string $content = '') {
444                 // Check if any sub group was opened before
445                 if ($this->ifSubGroupOpenedPreviously() === false) {
446                         // Then throw an exception
447                         throw new HelperNoPreviousOpenedSubGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED);
448                 }
449
450                 // Get previous sub group
451                 $subGroupId = $this->getPreviousSubGroupId();
452
453                 // Is the content empty?
454                 if ((empty($content)) && (!empty($this->subGroups[$subGroupId]['tag']))) {
455                         // Get it from opener
456                         $content = sprintf('<!-- sub-group %s auto-closed //--></%s>', $subGroupId, $this->subGroups[$subGroupId]['tag']);
457                 }
458
459                 // Add content to it and mark it as closed
460                 $this->subGroups[$subGroupId]['content'] .= sprintf('<!-- sub-group %s closed (length: %s, tag: %s) //-->%s' . PHP_EOL, $subGroupId, strlen($content), $this->subGroups[$subGroupId]['tag'], $content);
461                 $this->subGroups[$subGroupId]['opened'] = false
462                 ;
463
464                 // Mark previous sub group as closed
465                 $this->setPreviousSubGroupId('');
466                 //* NOISY-DEBUG: */ echo "CLOSE:subGroupId={$subGroupId}<br />\n";
467         }
468
469         /**
470          * Renders all group and sub group in their order
471          *
472          * @return      $content        Rendered HTML content
473          */
474         public function renderContent () {
475                 // Initialize content
476                 $content = '';
477
478                 // Is header content there?
479                 if (isset($this->groups['header'])) {
480                         // Then add it
481                         $content .= $this->groups['header']['content'] . PHP_EOL;
482                 }
483
484                 // Initiate content
485                 $content .= $this->getContent();
486
487                 // Now "walk" through all groups and sub-groups
488                 for ($idx = 1; $idx <= $this->totalCounter; $idx++) {
489                         // Is this a sub/group and is it closed?
490                         if ((isset($this->groups[$idx])) && ($this->groups[$this->groups[$idx]]['opened'] === false)) {
491                                 // Then add it's content
492                                 $groupContent = trim($this->groups[$this->groups[$idx]]['content']);
493                                 //* NOISY-DEBUG: */ echo "group={$this->groups[$idx]},content=<pre>".htmlentities($groupContent)."</pre><br />\n";
494                                 $content .= $groupContent;
495                         } elseif ((isset($this->subGroups[$idx])) && ($this->subGroups[$this->subGroups[$idx]]['opened'] === false)) {
496                                 // Then add it's content
497                                 $subGroupContent = $this->subGroups[$this->subGroups[$idx]]['content'];
498                                 //* NOISY-DEBUG: */ echo "subgroup={$this->subGroups[$idx]},content=<pre>".htmlentities($subGroupContent)."</pre><br />\n";
499                                 $content .= trim($subGroupContent);
500                         } else {
501                                 // Something went wrong
502                                 $this->debugInstance(__METHOD__ . '(): Something unexpected happened here.');
503                         }
504                 }
505
506                 // Is footer content there?
507                 if (isset($this->groups['footer'])) {
508                         // Then add it
509                         $content .= $this->groups['footer']['content'] . PHP_EOL;
510                 }
511
512                 // Return it
513                 //* NOISY-DEBUG: */ echo "content=<pre>".htmlentities($content)."</pre> (".strlen($content).")<br />\n";
514                 return $content;
515         }
516
517         /**
518          * Checks whether the specified group is opened
519          *
520          * @param       $groupId        Id of group to check
521          * @return      $isOpened       Whether the specified group is open
522          * @throws      InvalidArgumentException        If a parameter has an invalid value
523          */
524         protected function ifGroupIsOpened (string $groupId) {
525                 // Check on parameter
526                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: groupId=%s - CALLED!', $groupId));
527                 if (empty($groupId)) {
528                         // Throw IAE
529                         throw new InvalidArgumentException('Parameter "groupId" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
530                 }
531
532                 // Is the group open?
533                 $isOpened = ((isset($this->groups[$groupId])) && ($this->groups[$groupId]['opened'] === true));
534
535                 // Return status
536                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: isOpened=%d - EXIT!', intval($isOpened)));
537                 return $isOpened;
538         }
539
540         /**
541          * Getter for direct field values
542          *
543          * @param       $fieldName              Name of the field we shall fetch
544          * @return      $fieldValue             Value from field
545          * @throws      InvalidArgumentException        If a parameter has an invalid value
546          * @throws      NullPointerException    Thrown if $valueInstance is null
547          */
548         public function getValueField (string $fieldName) {
549                 // Check parameter
550                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: fieldName=%s - CALLED!', $fieldName));
551                 if (empty($fieldName)) {
552                         // Throw IAE
553                         throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
554                 }
555
556                 // Init value
557                 $fieldValue = NULL;
558
559                 // The $valueInstance attribute should not be null!
560                 if (is_null($this->getValueInstance())) {
561                         // Throws an exception here
562                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
563                 }
564
565                 // Is the field set?
566                 if ($this->getValueInstance()->isFieldSet($fieldName)) {
567                         // Get the field value
568                         $fieldValue = $this->getValueInstance()->getField($fieldName);
569                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.'[]='.gettype($fieldValue).'('.strlen($fieldValue).') - Value instance!');
570                 } elseif ((!is_null($this->extraInstance)) && ($this->extraInstance->isFieldSet($fieldName))) {
571                         // So try the extra instance
572                         $fieldValue = $this->extraInstance->getField($fieldName);
573                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.'[]='.gettype($fieldValue).'('.strlen($fieldValue).') - Extra instance!');
574                 } else {
575                         // Field is not set
576                         $this->debugOutput('BASE-HELPER: fieldName=' . $fieldName . ' is not set! - @TODO');
577                 }
578
579                 // Return it
580                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-HELPER: fieldValue[%s]=%s - EXIT!', gettype($fieldValue), $fieldValue));
581                 return $fieldValue;
582         }
583
584         /**
585          * Getter for value instance
586          *
587          * @return      $valueInstance  Instance of the class holding our values
588          */
589         public final function getValueInstance () {
590                 return $this->valueInstance;
591         }
592
593         /**
594          * Check whether a group was opened previously
595          *
596          * @return      $groupOpened    Whether any group was opened before
597          */
598         protected final function ifGroupOpenedPreviously () {
599                 $groupOpened = (!empty($this->previousGroupId));
600                 return $groupOpened;
601         }
602
603         /**
604          * Check whether a group was opened previously
605          *
606          * @return      $subGroupOpened         Whether any group was opened before
607          */
608         protected final function ifSubGroupOpenedPreviously () {
609                 $subGroupOpened = (!empty($this->previousSubGroupId));
610                 return $subGroupOpened;
611         }
612
613         /**
614          * Getter for previous group id
615          *
616          * @return      $previousGroupId        Id of previously opened group
617          */
618         protected final function getPreviousGroupId () {
619                 return $this->previousGroupId;
620         }
621
622         /**
623          * Setter for previous group id
624          *
625          * @param       $previousGroupId        Id of previously opened group
626          * @return      void
627          */
628         protected final function setPreviousGroupId (string $previousGroupId) {
629                 $this->previousGroupId = $previousGroupId;
630         }
631
632         /**
633          * Getter for previous sub group id
634          *
635          * @return      $previousSubGroupId             Id of previously opened sub group
636          */
637         protected final function getPreviousSubGroupId () {
638                 return $this->previousSubGroupId;
639         }
640
641         /**
642          * Setter for previous sub group id
643          *
644          * @param       $previousSubGroupId             Id of previously opened sub group
645          * @return      void
646          */
647         protected final function setPreviousSubGroupId (string $previousSubGroupId) {
648                 $this->previousSubGroupId = $previousSubGroupId;
649         }
650
651 }