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