8f031a85419d6b31f5616f78b8d6de02c8eaab11
[core.git] / framework / main / classes / template / mail / class_MailTemplateEngine.php
1 <?php
2 // Own namespace
3 namespace CoreFramework\Template\Engine;
4
5 // Import framework stuff
6 use CoreFramework\Registry\Registry;
7 use CoreFramework\Response\Responseable;
8 use CoreFramework\Template\CompileableTemplate;
9
10 /**
11  * The own template engine for loading caching and sending out images
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  * @todo                This template engine does not make use of setTemplateType()
19  *
20  * This program is free software: you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation, either version 3 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program. If not, see <http://www.gnu.org/licenses/>.
32  */
33 class MailTemplateEngine extends BaseTemplateEngine implements CompileableTemplate {
34         /**
35          * Main nodes in the XML tree
36          */
37         private $mainNodes = array(
38                 'mail-data'
39         );
40
41         /**
42          * Sub nodes in the XML tree
43          */
44         private $subNodes = array(
45                 'subject-line',
46                 'sender-address',
47                 'recipient-address',
48                 'message'
49         );
50
51         /**
52          * Mailer instance
53          */
54         private $mailerInstance = NULL;
55
56         /**
57          * Current main node
58          */
59         private $currMainNode = '';
60
61         /**
62          * Protected constructor
63          *
64          * @return      void
65          */
66         protected function __construct () {
67                 // Call parent constructor
68                 parent::__construct(__CLASS__);
69         }
70
71         /**
72          * Creates an instance of the class TemplateEngine and prepares it for usage
73          *
74          * @return      $templateInstance               An instance of TemplateEngine
75          * @throws      BasePathIsEmptyException                If the provided $templateBasePath is empty
76          * @throws      InvalidBasePathStringException  If $templateBasePath is no string
77          * @throws      BasePathIsNoDirectoryException  If $templateBasePath is no
78          *                                                                                      directory or not found
79          * @throws      BasePathReadProtectedException  If $templateBasePath is
80          *                                                                                      read-protected
81          */
82         public static final function createMailTemplateEngine () {
83                 // Get a new instance
84                 $templateInstance = new MailTemplateEngine();
85
86                 // Get the application instance from registry
87                 $applicationInstance = Registry::getRegistry()->getInstance('app');
88
89                 // Determine base path
90                 $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $applicationInstance->getRequestInstance()->getRequestElement('app') . '/';
91
92                 // Is the base path valid?
93                 if (empty($templateBasePath)) {
94                         // Base path is empty
95                         throw new BasePathIsEmptyException($templateInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
96                 } elseif (!is_string($templateBasePath)) {
97                         // Is not a string
98                         throw new InvalidBasePathStringException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING);
99                 } elseif (!is_dir($templateBasePath)) {
100                         // Is not a path
101                         throw new BasePathIsNoDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
102                 } elseif (!is_readable($templateBasePath)) {
103                         // Is not readable
104                         throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
105                 }
106
107                 // Set the base path
108                 $templateInstance->setTemplateBasePath($templateBasePath);
109
110                 // Set template extensions
111                 $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension'));
112                 $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('code_template_extension'));
113
114                 // Absolute output path for compiled templates
115                 $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path'));
116
117                 // Return the prepared instance
118                 return $templateInstance;
119         }
120
121         /**
122          * Getter for current main node
123          *
124          * @return      $currMainNode   Current main node
125          */
126         public final function getCurrMainNode () {
127                 return $this->currMainNode;
128         }
129
130         /**
131          * Getter for main node array
132          *
133          * @return      $mainNodes      Array with valid main node names
134          */
135         public final function getMainNodes () {
136                 return $this->mainNodes;
137         }
138
139         /**
140          * Getter for sub node array
141          *
142          * @return      $subNodes       Array with valid sub node names
143          */
144         public final function getSubNodes () {
145                 return $this->subNodes;
146         }
147
148         /**
149          * Handles the start element of an XML resource
150          *
151          * @param       $resource               XML parser resource (currently ignored)
152          * @param       $element                The element we shall handle
153          * @param       $attributes             All attributes
154          * @return      void
155          * @throws      InvalidXmlNodeException         If an unknown/invalid XML node name was found
156          */
157         public function startElement ($resource, $element, array $attributes) {
158                 // Initial method name which will never be called...
159                 $methodName = 'initEmail';
160
161                 // Make the element name lower-case
162                 $element = strtolower($element);
163
164                 // Is the element a main node?
165                 //* DEBUG: */ echo "START: &gt;".$element."&lt;<br />\n";
166                 if (in_array($element, $this->getMainNodes())) {
167                         // Okay, main node found!
168                         $methodName = 'setEmail' . self::convertToClassName($element);
169                 } elseif (in_array($element, $this->getSubNodes())) {
170                         // Sub node found
171                         $methodName = 'setEmailProperty' . self::convertToClassName($element);
172                 } elseif ($element != 'text-mail') {
173                         // Invalid node name found
174                         throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
175                 }
176
177                 // Call method
178                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
179                 call_user_func_array(array($this, $methodName), $attributes);
180         }
181
182         /**
183          * Ends the main or sub node by sending out the gathered data
184          *
185          * @param       $resource       An XML resource pointer (currently ignored)
186          * @param       $nodeName       Name of the node we want to finish
187          * @return      void
188          * @throws      XmlNodeMismatchException        If current main node mismatches the closing one
189          */
190         public function finishElement ($resource, $nodeName) {
191                 // Make all lower-case
192                 $nodeName = strtolower($nodeName);
193
194                 // Does this match with current main node?
195                 //* DEBUG: */ echo "END: &gt;".$nodeName."&lt;<br />\n";
196                 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
197                         // Did not match!
198                         throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
199                 } elseif (in_array($nodeName, $this->getSubNodes())) {
200                         // Silently ignore sub nodes
201                         return;
202                 }
203
204                 // Construct method name
205                 $methodName = 'finish' . self::convertToClassName($nodeName);
206
207                 // Call the corresponding method
208                 call_user_func_array(array($this, $methodName), array());
209         }
210
211         /**
212          * Adds the message text to the template engine
213          *
214          * @param       $resource               XML parser resource (currently ignored)
215          * @param       $characters             Characters to handle
216          * @return      void
217          */
218         public function characterHandler ($resource, $characters) {
219                 // Trim all spaces away
220                 $characters = trim($characters);
221
222                 // Is this string empty?
223                 if (empty($characters)) {
224                         // Then skip it silently
225                         return;
226                 } // END - if
227
228                 // Add the message now
229                 $this->assignVariable('message', $characters);
230         }
231
232         /**
233          * Intializes the mail
234          *
235          * @return      void
236          * @todo        Add cache creation here
237          */
238         private function initEmail () {
239                 // Unfinished work!
240         }
241
242         /**
243          * Setter for mail data node
244          *
245          * @return      void
246          * @todo        Should we call back the mailer class here?
247          */
248         private function setEmailMailData () {
249                 // Set current main node
250                 $this->currMainNode = 'mail-data';
251         }
252
253         /**
254          * Setter for sender address property
255          *
256          * @param       $senderAddress  Sender address to set in email
257          * @return      void
258          */
259         private function setEmailPropertySenderAddress ($senderAddress) {
260                 // Set the template variable
261                 $this->assignVariable('sender', $senderAddress);
262         }
263
264         /**
265          * Setter for recipient address property
266          *
267          * @param       $recipientAddress       Recipient address to set in email
268          * @return      void
269          */
270         private function setEmailPropertyRecipientAddress ($recipientAddress) {
271                 // Set the template variable
272                 $this->assignVariable('recipient', $recipientAddress);
273         }
274
275         /**
276          * Setter for subject line property
277          *
278          * @return      void
279          */
280         private function setEmailPropertySubjectLine () {
281                 // Empty for now
282         }
283
284         /**
285          * Method stub to avoid output
286          *
287          * @return      void
288          */
289         private function setEmailPropertyMessage () {
290                 // Empty for now
291         }
292
293         /**
294          * Gets the template variable "message", stores it back as raw template data
295          * and compiles all variables so the mail message got prepared for output
296          *
297          * @return      void
298          */
299         private function finishMailData () {
300                 // Get the message and set it as new raw template data back
301                 $message = $this->readVariable('message');
302                 $this->setRawTemplateData($message);
303
304                 // Get some variables to compile
305                 //$sender = $this->compileRawCode($this->readVariable('sender'));
306                 //$this->assignVariable('sender', $sender);
307
308                 // Then compile all variables
309                 $this->compileVariables();
310         }
311
312         /**
313          * Invokes the final mail process
314          *
315          * @return      void
316          */
317         private function finishTextMail () {
318                 $this->getMailerInstance()->invokeMailDelivery();
319         }
320
321         /**
322          * Getter for image cache file (FQFN)
323          *
324          * @return      $fqfn   Full-qualified file name of the image cache
325          * @todo        0% done
326          */
327         public function getMailCacheFqfn () {
328                 // Initialize FQFN
329                 $fqfn = '';
330                 $this->debugBackTrace('Unfinished area!');
331
332                 // Return it
333                 return $fqfn;
334         }
335
336         /**
337          * Setter for mailer instance
338          *
339          * @param       $mailerInstance         A mailer instance
340          * @return      void
341          */
342         public final function setMailerInstance (DeliverableMail $mailerInstance) {
343                 $this->mailerInstance = $mailerInstance;
344         }
345
346         /**
347          * Getter for mailer instance
348          *
349          * @return      $mailerInstance         A mailer instance
350          */
351         protected final function getMailerInstance () {
352                 return $this->mailerInstance;
353         }
354
355         /**
356          * Outputs the mail to the world. This should only the mailer debug class do!
357          *
358          * @param       $responseInstance       An instance of a Responseable class
359          * @return      void
360          */
361         public function transferToResponse (Responseable $responseInstance) {
362                 $responseInstance->writeToBody($this->getCompiledData());
363         }
364
365 }