Issues (9)

src/Notif.php (2 issues)

1
<?php
2
/**
3
 * {CLASS SUMMARY}
4
 *
5
 * Date: 7/26/18
6
 * Time: 6:54 PM
7
 * @author Michael Munger <[email protected]>
8
 */
9
10
namespace HPHIO\Farret;
11
12
use \Exception;
13
14
class Notif
15
{
16
    private $tagPattern       = '/\{{2} {0,2}([A-Z]+) {0,2}\}{2}/';
17
    private $hookPattern      = '/(?:{\%\s{0,})([A-Z]+)\s{0,}((\|(?:{{){0,1}[A-Za-z0-9-]+(?:}}){0,1}\s{0,}){0,})(?:\%})/';
18
19
    public $templateDirectory = null;
20
    public $template          = null;
21
    public $fromName          = null;
22
    public $fromAddress       = null;
23
    public $subjectTemplate   = null;
24
    public $body              = null;
25
26
    public $to                = [];
27
    public $cc                = [];
28
    public $bcc               = [];
29
    public $fartDictionary    = [];
30
31
    public $hooks             = [];
32
33 31
    public function __construct()
34
    {
35 31
        $this->addHook('DATE', 'getDate');
36 31
        $this->addHook('HASH', 'hash');
37
38 31
    }
39
40 3
    public function setBody($body) {
41 3
        $this->body = $body;
42 3
    }
43
44 2
    public function getBody() {
45 2
        return $this->body;
46
    }
47
48 1
    public function setTemplate($template) {
49 1
        $this->template = $template;
50 1
    }
51
52 3
    public function getTemplate() {
53 3
        return $this->template;
54
    }
55
56 8
    public function setTemplateDirectory($directory)
57
    {
58 8
        if (file_exists($directory) === false) {
59 1
            return false;
60
        }
61
62 7
        $this->templateDirectory = $directory;
63 7
        return file_exists($this->templateDirectory);
64
    }
65
66
    /**
67
     * Loads a template from the template directory.
68
     * @param $template
69
     * @throws Exception
70
     */
71
72 8
    public function loadTemplate($template)
73
    {
74 8
        $targetTemplate = $this->templateDirectory . "$template.html";
75
76 8
        if (file_exists($this->templateDirectory) === false) {
77 1
            throw new Exception("Template directory not set!");
78
        }
79 7
        if (file_exists($targetTemplate)          === false) {
80 2
            throw new Exception("Requested template does not exist in $targetTemplate");
81
        }
82
83 5
        $this->template = file_get_contents($targetTemplate);
84
85 5
        return strlen($this->template) > 0;
86
    }
87
88 1
    public function setFromName($name)
89
    {
90 1
        $this->fromName = $name;
91 1
    }
92
93
    /**
94
     * Validates an email passed to it, and if valid, sets the from address for the email notification.
95
     * @param $email
96
     * @return bool
97
     * @throws Exception
98
     */
99
100 2
    public function setFromAddress($email)
101
    {
102 2
        $email = filter_var($email, FILTER_VALIDATE_EMAIL);
103
104 2
        if ($email === false) {
105 1
            throw new Exception("$email is not a valid email address!");
106
        }
107
108 1
        $this->fromAddress = $email;
109
110 1
        return true;
111
    }
112
113 1
    public function setSubjectTemplate($subject)
114
    {
115 1
        $this->subjectTemplate = $subject;
116 1
    }
117
118
    /**
119
     * Adds a Find And Replace Template pair. These will be used to find {{ TEMPLATETAGS }} and perform a substitution.
120
     * @param $find
121
     * @param $replace
122
     */
123
124 6
    public function addFart($find, $replace)
125
    {
126 6
        $this->fartDictionary[$find] = $replace;
127 6
    }
128
129
    /**
130
     * Returns unmatched, unreplaced tags from the template.
131
     * @return mixed
132
     * @throws Exception
133
     */
134
135 1
    public function getTemplateTags()
136
    {
137 1
        if (strlen($this->template) == 0) {
138 1
            throw new Exception("Template not set!");
139
        }
140 1
        return $this->getTags($this->template);
141
    }
142
143 1
    public function getBodyTags()
144
    {
145 1
        return $this->getTags($this->body);
146
    }
147
148 2
    public function getTags($body)
149
    {
150 2
        $matches = [];
151 2
        preg_match_all($this->tagPattern, $body, $matches, PREG_PATTERN_ORDER);
152
153 2
        $TagFactory = new TagFactory();
154 2
        $buffer = [];
155
156 2
        foreach($matches[0] as $match) {
157 2
            $tag = $TagFactory->getTag($match);
158 2
            $buffer[] = $tag;
159
        }
160
161 2
        return $buffer;
162
    }
163
164 2
    public function getHooks($body)
165
    {
166 2
        $matches = [];
167 2
        preg_match_all($this->hookPattern, $body, $matches, PREG_PATTERN_ORDER);
168 2
        return $matches[0];
169
    }
170
171 11
    public function makeTag($find)
172
    {
173 11
        return sprintf("{{%s}}", strtoupper($find));
174
    }
175
176 11
    public function matchFind($tag, $find)
177
    {
178
        //Remove spaces
179 11
        $tag = str_replace(" ", '', $tag);
180
        //Decorate the find
181 11
        $find = $this->makeTag($find);
182 11
        return (strcmp($tag, $find) === 0);
183
    }
184
185
    /**
186
     * @param $body
187
     * @throws Exception
188
     */
189
190 1
    private function doFart($body, $tags)
191
    {
192
193 1
        foreach ($tags as $tag) {
194
195 1
            $tag->fart($this->fartDictionary);
196
197 1
            if(strpos($body, $tag->getTag()) === false) {
198
                // @codeCoverageIgnoreStart
199
                continue;
200
                // @codeCoverageIgnoreEnd
201
            }
202
203 1
            $body = str_replace($tag->getTag(), $tag->getReplacement(), $body);
204
        }
205
206 1
        $tags = $this->getTags($body);
207
208 1
        if (count($tags) > 0) {
209 1
            $body = $this->doFart($body, $tags);
210
        }
211
212 1
        return $body;
213
    }
214
215
    /**
216
     * @throws Exception
217
     */
218
219 1
    public function render()
220
    {
221 1
        $this->body = $this->doFart($this->template, $this->getTemplateTags());
222 1
        $this->body = $this->renderAllHooks($this->body);
223 1
    }
224
225
    /**
226
     * @param $body
227
     * @return mixed
228
     * @throws Exception
229
     *
230
     */
231
232 1
    public function renderAllHooks($body) {
233 1
        $hooks = $this->getHooks($body);
234 1
        $TagFactory = new TagFactory();
235 1
        $tags = [];
0 ignored issues
show
The assignment to $tags is dead and can be removed.
Loading history...
236
237 1
        foreach($hooks as $hook) {
238 1
            $Tag = $TagFactory->getTag($hook);
239 1
            $Tag->setReplacement($this->renderHook($hook));
240 1
            $body = str_replace($hook, $Tag->getReplacement(), $body);
241
        }
242
243
        // Hooks are not recursive now. But they could be if we uncomment this.
244
        // $hooks = $this->getHooks($body);
245
        // if(count($hooks) > 0) {
246
        //     $this->renderAllHooks($body);
247
        // }
248
249 1
        return $body;
250
    }
251
252 31
    public function addHook($hook, $callback)
253
    {
254 31
        $this->hooks[$hook] = $callback;
255 31
    }
256
257
    /**
258
     * @param $hook
259
     * @return mixed
260
     * @throws Exception
261
     */
262
263 7
    public function renderHook($hook)
264
    {
265
266 7
        $TagFactory = new TagFactory();
267 7
        $Tag = $TagFactory->getTag($hook);
268 7
        $Tag->fart($this->fartDictionary);
269 7
        $action = $Tag->getLabel();
270
271
        //2. Lookup the callback in the hooks dictionary.
272
273 7
        if(isset($this->hooks[$action]) === false) {
274 1
            throw new Exception('The callback you requested is not registered in the notification hooks.');
275
        }
276
277 7
        $callback = $this->hooks[$action];
278
279 7
        if (method_exists($this, $callback) === false) {
280 1
            throw new Exception("Hook method does not exist! Cannot execute $callback.");
281
        }
282
283 6
        return (count($Tag->getArgs()) == 0 ? $this->$callback() : $this->$callback($Tag->getArgs()));
284
    }
285
286 2
    public function getDate($formatArray)
287
    {
288 2
        $now = new \DateTime();
289 2
        return $now->format($formatArray[0]);
290
    }
291
292 2
    public function getCurrentMonth()
293
    {
294 2
        return $this->getDate(["m"]);
295
    }
296
297 2
    public function getCurrentDay()
298
    {
299 2
        return $this->getDate(["d"]);
300
    }
301
302 2
    public function getCurrentYear()
303
    {
304 2
        return $this->getDate(["Y"]);
305
    }
306
307 3
    public function getArgs($hook) {
308 3
        $Factory = new TagFactory();
309 3
        $Tag = $Factory->getTag($hook);
310 3
        return $Tag->getArgs();
311
    }
312
313 4
    public function hash($args) {
314 4
        $buffer = '';
315 4
        for($x = 0; $x < count($args); $x++ ) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
316 4
            $buffer = md5($buffer.$args[$x]);
317
        }
318
319 4
        return $buffer;
320
    }
321
322
}
323