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