Completed
Push — master ( 9a32a7...c0ece2 )
by
unknown
14s queued 10s
created

MailEclipse::getMailableViewData()   B

Complexity

Conditions 11
Paths 18

Size

Total Lines 45
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 24
nc 18
nop 2
dl 0
loc 45
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Qoraiche\MailEclipse;
4
5
use ErrorException;
6
use Illuminate\Container\Container;
7
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
8
use Illuminate\Mail\Markdown;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Facades\Artisan;
11
use Illuminate\Support\Facades\DB;
12
use Illuminate\Support\Facades\View;
13
use Illuminate\Support\Str;
14
use RecursiveDirectoryIterator;
15
use RecursiveIteratorIterator;
16
use ReeceM\Mocker\Mocked;
17
use ReflectionClass;
18
use ReflectionProperty;
19
use RegexIterator;
20
21
class MailEclipse
22
{
23
    public static $view_namespace = 'maileclipse';
24
25
    /**
26
     * Default type examples for being passed to reflected classes.
27
     *
28
     * @var array TYPES
29
     */
30
    public const TYPES = [
31
        'int' => 31,
32
        // 'string' => 'test_string', // not needed as it can be cast __toString()
33
        'bool' => false,
34
        'float' => 3.14159,
35
    ];
36
37
    public static function getMailables()
38
    {
39
        return self::mailablesList();
40
    }
41
42
    public static function getMailable($key, $name)
43
    {
44
        $filtered = collect(self::getMailables())->where($key, $name);
45
46
        return $filtered;
47
    }
48
49
    public static function deleteTemplate($templateSlug)
50
    {
51
        $template = self::getTemplates()
52
            ->where('template_slug', $templateSlug)->first();
53
54
        if (! is_null($template)) {
55
            self::saveTemplates(self::getTemplates()->reject(function ($value, $key) use ($template) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

55
            self::saveTemplates(self::getTemplates()->reject(function ($value, /** @scrutinizer ignore-unused */ $key) use ($template) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
56
                return $value->template_slug == $template->template_slug;
57
            }));
58
59
            $template_view = self::$view_namespace.'::templates.'.$templateSlug;
60
            $template_plaintext_view = $template_view.'_plain_text';
61
62
            if (View::exists($template_view)) {
63
                unlink(View($template_view)->getPath());
64
65
                if (View::exists($template_plaintext_view)) {
66
                    unlink(View($template_plaintext_view)->getPath());
67
                }
68
69
                return true;
70
            }
71
        }
72
73
        return false;
74
    }
75
76
    public static function getTemplatesFile()
77
    {
78
        $file = config('maileclipse.mailables_dir').'templates.json';
79
        if (! file_exists($file)) {
80
            if (! file_exists(config('maileclipse.mailables_dir'))) {
81
                mkdir(config('maileclipse.mailables_dir'));
82
            }
83
            file_put_contents($file, '[]');
84
        }
85
86
        return $file;
87
    }
88
89
    public static function saveTemplates(Collection $templates)
90
    {
91
        file_put_contents(self::getTemplatesFile(), $templates->toJson());
92
    }
93
94
    public static function updateTemplate($request)
95
    {
96
        $template = self::getTemplates()
97
            ->where('template_slug', $request->templateslug)->first();
98
99
        if (! is_null($template)) {
100
            if (! preg_match("/^[a-zA-Z0-9-_\s]+$/", $request->title)) {
101
                return response()->json([
102
                    'status' => 'failed',
103
                    'message' => 'Template name not valid',
104
                ]);
105
            }
106
107
            $templatename = Str::camel(preg_replace('/\s+/', '_', $request->title));
108
109
            // check if not already exists on db
110
            //
111
            //
112
113
            if (self::getTemplates()->contains('template_slug', '=', $templatename)) {
114
                return response()->json([
115
116
                    'status' => 'failed',
117
                    'message' => 'Template name already exists',
118
119
                ]);
120
            }
121
122
            // Update
123
            //
124
            $oldForm = self::getTemplates()->reject(function ($value, $key) use ($template) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

124
            $oldForm = self::getTemplates()->reject(function ($value, /** @scrutinizer ignore-unused */ $key) use ($template) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
125
                return $value->template_slug == $template->template_slug;
126
            });
127
            $newForm = array_merge($oldForm->toArray(), [array_merge((array) $template, [
128
                'template_slug' => $templatename,
129
                'template_name' => $request->title,
130
                'template_description' => $request->description,
131
            ])]);
132
133
            self::saveTemplates(collect($newForm));
134
135
            $template_view = self::$view_namespace.'::templates.'.$request->templateslug;
136
            $template_plaintext_view = $template_view.'_plain_text';
137
138
            if (View::exists($template_view)) {
139
                $viewPath = View($template_view)->getPath();
140
141
                rename($viewPath, dirname($viewPath)."/{$templatename}.blade.php");
142
143
                if (View::exists($template_plaintext_view)) {
144
                    $textViewPath = View($template_plaintext_view)->getPath();
145
146
                    rename($textViewPath, dirname($viewPath)."/{$templatename}_plain_text.blade.php");
147
                }
148
            }
149
150
            return response()->json([
151
152
                'status' => 'ok',
153
                'message' => 'Updated Successfully',
154
                'template_url' => route('viewTemplate', ['templatename' => $templatename]),
155
156
            ]);
157
        }
158
    }
159
160
    public static function getTemplate($templateSlug)
161
    {
162
        $template = self::getTemplates()
163
            ->where('template_slug', $templateSlug)->first();
164
165
        if (! is_null($template)) {
166
            $template_view = self::$view_namespace.'::templates.'.$template->template_slug;
167
            $template_plaintext_view = $template_view.'_plain_text';
168
169
            // return $template_plaintext_view;
170
171
            if (View::exists($template_view)) {
172
                $viewPath = View($template_view)->getPath();
173
                $textViewPath = View($template_plaintext_view)->getPath();
174
175
                $templateData = collect([
176
                    'template' => self::templateComponentReplace(file_get_contents($viewPath), true),
177
                    'plain_text' => View::exists($template_plaintext_view) ? file_get_contents($textViewPath) : '',
178
                    'slug' => $template->template_slug,
179
                    'name' => $template->template_name,
180
                    'description' => $template->template_description,
181
                    'template_type' => $template->template_type,
182
                    'template_view_name' => $template->template_view_name,
183
                    'template_skeleton' => $template->template_skeleton,
184
                ]);
185
186
                return $templateData;
187
            }
188
        }
189
190
        // return;
191
    }
192
193
    public static function getTemplates()
194
    {
195
        $template = collect(json_decode(file_get_contents(self::getTemplatesFile())));
196
197
        return $template;
198
    }
199
200
    public static function createTemplate($request)
201
    {
202
        if (! preg_match("/^[a-zA-Z0-9-_\s]+$/", $request->template_name)) {
203
            return response()->json([
204
205
                'status' => 'error',
206
                'message' => 'Template name not valid',
207
208
            ]);
209
        }
210
211
        $view = self::$view_namespace.'::templates.'.$request->template_name;
212
213
        $templatename = Str::camel(preg_replace('/\s+/', '_', $request->template_name));
214
215
        if (! view()->exists($view) && ! self::getTemplates()->contains('template_slug', '=', $templatename)) {
216
            self::saveTemplates(self::getTemplates()
217
                ->push([
218
                    'template_name' => $request->template_name,
219
                    'template_slug' => $templatename,
220
                    'template_description' => $request->template_description,
221
                    'template_type' => $request->template_type,
222
                    'template_view_name' => $request->template_view_name,
223
                    'template_skeleton' => $request->template_skeleton,
224
                ]));
225
226
            $dir = resource_path('views/vendor/'.self::$view_namespace.'/templates');
227
228
            if (! \File::isDirectory($dir)) {
229
                \File::makeDirectory($dir, 0755, true);
230
            }
231
232
            file_put_contents($dir."/{$templatename}.blade.php", self::templateComponentReplace($request->content));
233
234
            file_put_contents($dir."/{$templatename}_plain_text.blade.php", $request->plain_text);
235
236
            return response()->json([
237
238
                'status' => 'ok',
239
                'message' => 'Template created<br> <small>Reloading...<small>',
240
                'template_url' => route('viewTemplate', ['templatename' => $templatename]),
241
242
            ]);
243
        }
244
245
        return response()->json([
246
247
            'status' => 'error',
248
            'message' => 'Template not created',
249
250
        ]);
251
    }
252
253
    public static function getTemplateSkeletons()
254
    {
255
        return collect(config('maileclipse.skeletons'));
256
    }
257
258
    public static function getTemplateSkeleton($type, $name, $skeleton)
259
    {
260
        $skeletonView = self::$view_namespace."::skeletons.{$type}.{$name}.{$skeleton}";
261
262
        if (view()->exists($skeletonView)) {
263
            $skeletonViewPath = View($skeletonView)->getPath();
264
            $templateContent = file_get_contents($skeletonViewPath);
265
266
            return [
267
                'type' => $type,
268
                'name' => $name,
269
                'skeleton' => $skeleton,
270
                'template' => self::templateComponentReplace($templateContent, true),
271
                'view' => $skeletonView,
272
                'view_path' => $skeletonViewPath,
273
            ];
274
        }
275
    }
276
277
    protected static function templateComponentReplace($content, $reverse = false)
278
    {
279
        if ($reverse) {
280
            $patterns = [
281
                '/@component/i',
282
                '/@endcomponent/i',
283
                '/@yield/',
284
                '/@section/',
285
                '/@endsection/',
286
                '/@extends/',
287
                '/@parent/',
288
                '/@slot/',
289
                '/@endslot/',
290
            ];
291
292
            $replacements = [
293
                '[component]: # ',
294
                '[endcomponent]: # ',
295
                '[yield]: # ',
296
                '[section]: # ',
297
                '[endsection]: # ',
298
                '[extends]: # ',
299
                '[parent]: # ',
300
                '[slot]: # ',
301
                '[endslot]: # ',
302
            ];
303
        } else {
304
            $patterns = [
305
                '/\[component]:\s?#\s?/i',
306
                '/\[endcomponent]:\s?#\s?/i',
307
                '/\[yield]:\s?#\s?/i',
308
                '/\[section]:\s?#\s?/i',
309
                '/\[endsection]:\s?#\s?/i',
310
                '/\[extends]:\s?#\s?/i',
311
                '/\[parent]:\s?#\s?/i',
312
                '/\[slot]:\s?#\s?/i',
313
                '/\[endslot]:\s?#\s?/i',
314
            ];
315
316
            $replacements = [
317
                '@component',
318
                '@endcomponent',
319
                '@yield',
320
                '@section',
321
                '@endsection',
322
                '@extends',
323
                '@parent',
324
                '@slot',
325
                '@endslot',
326
            ];
327
        }
328
329
        return preg_replace($patterns, $replacements, $content);
330
    }
331
332
    protected static function markdownedTemplate($viewPath)
333
    {
334
        $viewContent = file_get_contents($viewPath);
335
336
        return self::templateComponentReplace($viewContent, true);
337
338
        // return preg_replace($patterns, $replacements, $viewContent);
339
    }
340
341
    /**
342
     * Markdowned template view.
343
     */
344
    public static function markdownedTemplateToView($save = true, $content = '', $viewPath = '', $template = false)
345
    {
346
        if ($template && View::exists(self::$view_namespace.'::templates.'.$viewPath)) {
347
            $viewPath = View(self::$view_namespace.'::templates.'.$viewPath)->getPath();
348
        }
349
350
        $replaced = self::templateComponentReplace($content);
351
352
        if (! $save) {
353
            return $replaced;
354
        }
355
356
        return file_put_contents($viewPath, $replaced) === false ? false : true;
357
    }
358
359
    public static function previewMarkdownViewContent($simpleview, $content, $viewName, $template = false, $namespace = null)
360
    {
361
        $previewtoset = self::markdownedTemplateToView(false, $content);
362
        $dir = dirname(__FILE__, 2).'/resources/views/draft';
363
        $viewName = $template ? $viewName.'_template' : $viewName;
364
365
        if (file_exists($dir)) {
366
            file_put_contents($dir."/{$viewName}.blade.php", $previewtoset);
367
368
            if ($template) {
369
                $instance = null;
370
            } else {
371
                if (! is_null(self::handleMailableViewDataArgs($namespace))) {
372
                    $instance = self::handleMailableViewDataArgs($namespace);
373
                } else {
374
                    $instance = new $namespace;
375
                }
376
            }
377
378
            return self::renderPreview($simpleview, self::$view_namespace.'::draft.'.$viewName, $template, $instance);
379
        }
380
381
        return false;
382
    }
383
384
    public static function previewMarkdownHtml($instance, $view)
385
    {
386
        return self::renderPreview($instance, $view);
387
    }
388
389
    public static function getMailableTemplateData($mailableName)
390
    {
391
        $mailable = self::getMailable('name', $mailableName);
392
393
        if ($mailable->isEmpty()) {
394
            return false;
395
        }
396
397
        $templateData = collect($mailable->first())->only(['markdown', 'view_path', 'text_view_path', 'text_view', 'view_data', 'data', 'namespace'])->all();
398
399
        $templateExists = ! is_null($templateData['view_path']);
400
        $textTemplateExists = ! is_null($templateData['text_view_path']);
401
402
        if ($templateExists) {
403
            $viewPathParams = collect($templateData)->union([
404
405
                'text_template' => $textTemplateExists ? file_get_contents($templateData['text_view_path']) : null,
406
                'template' => file_get_contents($templateData['view_path']),
407
                'markdowned_template' => self::markdownedTemplate($templateData['view_path']),
408
                'template_name' => ! is_null($templateData['markdown']) ? $templateData['markdown'] : $templateData['data']->view,
409
                'is_markdown' => ! is_null($templateData['markdown']) ? true : false,
410
                // 'text_template' => file_get_contents($templateData['text_view_path']),
411
412
            ])->all();
413
414
            return $viewPathParams;
415
        }
416
417
        return $templateData;
418
    }
419
420
    public static function generateMailable($request = null)
421
    {
422
        $name = ucwords(Str::camel(preg_replace('/\s+/', '_', $request->input('name'))));
423
424
        if (! self::getMailable('name', $name)->isEmpty() && ! $request->has('force')) {
425
            // return redirect()->route('createMailable')->with('error', 'mailable already exists! to overide it enable force option.');
426
            //
427
            return response()->json([
428
                'status' => 'error',
429
                'message' => 'This mailable name already exists. names should be unique! to override it, enable "force" option.',
430
            ]);
431
        }
432
433
        if (strtolower($name) === 'mailable') {
434
            return response()->json([
435
                'status' => 'error',
436
                'message' => 'You cannot use this name',
437
            ]);
438
        }
439
440
        $params = collect([
441
            'name' => $name,
442
        ]);
443
444
        if ($request->input('markdown')) {
445
            $params->put('--markdown', $request->markdown);
446
        }
447
448
        if ($request->has('force')) {
449
            $params->put('--force', true);
450
        }
451
452
        $exitCode = Artisan::call('make:mail', $params->all());
453
454
        if ($exitCode > -1) {
455
456
            // return redirect()->route('mailableList');
457
            //
458
            return response()->json([
459
460
                'status' => 'ok',
461
                'message' => 'Mailable Created<br> <small>Reloading...<small>',
462
463
            ]);
464
        }
465
    }
466
467
    /**
468
     * Get mailables list.
469
     *
470
     * @return array
471
     */
472
    protected static function mailablesList()
473
    {
474
        $fqcns = [];
475
476
        if (! file_exists(config('maileclipse.mailables_dir'))):
477
478
            return; else:
479
480
            $allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(config('maileclipse.mailables_dir')));
481
        $phpFiles = new RegexIterator($allFiles, '/\.php$/');
482
        $i = 0;
483
484
        foreach ($phpFiles as $phpFile) {
485
            $i++;
486
            $content = file_get_contents($phpFile->getRealPath());
487
            $tokens = token_get_all($content);
488
            $namespace = '';
489
            for ($index = 0; isset($tokens[$index]); $index++) {
490
                if (! isset($tokens[$index][0])) {
491
                    continue;
492
                }
493
                if (T_NAMESPACE === $tokens[$index][0]) {
494
                    $index += 2; // Skip namespace keyword and whitespace
495
                    while (isset($tokens[$index]) && is_array($tokens[$index])) {
496
                        $namespace .= $tokens[$index++][1];
497
                    }
498
                }
499
                if (T_CLASS === $tokens[$index][0] && T_WHITESPACE === $tokens[$index + 1][0] && T_STRING === $tokens[$index + 2][0]) {
500
                    $index += 2; // Skip class keyword and whitespace
501
502
                    [$name, $extension] = explode('.', $phpFile->getFilename());
503
504
                    $mailableClass = $namespace.'\\'.$tokens[$index][1];
505
506
                    if (! self::mailable_exists($mailableClass)) {
507
                        continue;
508
                    }
509
510
                    $reflector = new ReflectionClass($mailableClass);
511
512
                    if ($reflector->isAbstract()) {
513
                        continue;
514
                    }
515
516
                    $mailable_data = self::buildMailable($mailableClass);
517
518
                    if (! is_null(self::handleMailableViewDataArgs($mailableClass))) {
519
                        $mailable_view_data = self::getMailableViewData(self::handleMailableViewDataArgs($mailableClass), $mailable_data);
520
                    } else {
521
                        $mailable_view_data = self::getMailableViewData(new $mailableClass, $mailable_data);
522
                    }
523
524
                    $fqcns[$i]['data'] = $mailable_data;
525
                    $fqcns[$i]['markdown'] = self::getMarkdownViewName($mailable_data);
526
                    $fqcns[$i]['name'] = $name;
527
                    $fqcns[$i]['namespace'] = $mailableClass;
528
                    $fqcns[$i]['filename'] = $phpFile->getFilename();
529
                    $fqcns[$i]['modified'] = $phpFile->getCTime();
530
                    $fqcns[$i]['viewed'] = $phpFile->getATime();
531
                    $fqcns[$i]['view_data'] = $mailable_view_data;
532
                    // $fqcns[$i]['view_data'] = [];
533
                    $fqcns[$i]['path_name'] = $phpFile->getPathname();
534
                    $fqcns[$i]['readable'] = $phpFile->isReadable();
535
                    $fqcns[$i]['writable'] = $phpFile->isWritable();
536
                    $fqcns[$i]['view_path'] = null;
537
                    $fqcns[$i]['text_view_path'] = null;
538
539
                    if (! is_null($fqcns[$i]['markdown']) && View::exists($fqcns[$i]['markdown'])) {
540
                        $fqcns[$i]['view_path'] = View($fqcns[$i]['markdown'])->getPath();
541
                    }
542
543
                    if (! is_null($fqcns[$i]['data'])) {
544
                        if (! is_null($fqcns[$i]['data']->view) && View::exists($fqcns[$i]['data']->view)) {
545
                            $fqcns[$i]['view_path'] = View($fqcns[$i]['data']->view)->getPath();
546
                        }
547
548
                        if (! is_null($fqcns[$i]['data']->textView) && View::exists($fqcns[$i]['data']->textView)) {
549
                            $fqcns[$i]['text_view_path'] = View($fqcns[$i]['data']->textView)->getPath();
550
                            $fqcns[$i]['text_view'] = $fqcns[$i]['data']->textView;
551
                        }
552
                    }
553
554
                    // break if you have one class per file (psr-4 compliant)
555
                    // otherwise you'll need to handle class constants (Foo::class)
556
                    break;
557
                }
558
            }
559
        }
560
561
        $collection = collect($fqcns)->map(function ($mailable) {
562
            return $mailable;
563
        })->reject(function ($object) {
564
            return ! method_exists($object['namespace'], 'build');
565
        });
566
567
        // return $collection->all();
568
        //
569
        return $collection;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $collection returns the type Illuminate\Support\Collection which is incompatible with the documented return type array.
Loading history...
570
571
        endif;
572
    }
573
574
    /**
575
     * Handle Mailable Constructor arguments and pass the fake ones.
576
     */
577
    public static function handleMailableViewDataArgs($mailable)
578
    {
579
        if (method_exists($mailable, '__construct')) {
580
            $reflection = new ReflectionClass($mailable);
581
582
            $params = $reflection->getConstructor()->getParameters();
583
584
            DB::beginTransaction();
585
586
            $eloquentFactory = app(EloquentFactory::class);
587
588
            $args = collect($params)->map(function ($param) {
589
                if ($param->getType() !== null) {
590
                    if (class_exists($param->getType()->getName())) {
591
                        $parameters = [
592
                            'is_instance' => true,
593
                            'instance' => $param->getType()->getName(),
594
                        ];
595
                    } elseif ($param->getType()->getName() == 'array') {
596
                        $parameters = [
597
                            'is_array' => true,
598
                            'arg' => $param->getName(),
599
                        ];
600
                    } else {
601
                        $parameters = $param->name;
602
                    }
603
604
                    return $parameters;
605
                }
606
607
                return $param->name;
608
            });
609
610
            $filteredparams = [];
611
612
            foreach ($args->all() as $arg) {
613
                $factoryStates = [];
614
615
                if (is_array($arg)) {
616
                    if (isset($arg['is_instance'])) {
617
                        if (isset($eloquentFactory[$arg['instance']]) && config('maileclipse.factory')) {
618
                            $filteredparams[] = factory($arg['instance'])->states($factoryStates)->make();
619
                        } else {
620
                            $filteredparams[] = app($arg['instance']);
621
                        }
622
                    } elseif (isset($arg['is_array'])) {
623
                        $filteredparams[] = [];
624
                    } else {
625
                        return;
626
                    }
627
                } else {
628
                    $filteredparams[] = self::getMissingParams($arg, $params);
629
                }
630
            }
631
632
            $reflector = new ReflectionClass($mailable);
633
634
            if (! $args->isEmpty()) {
635
                $foo = $reflector->newInstanceArgs($filteredparams);
636
637
                return $foo;
638
            }
639
640
            DB::rollBack();
641
        }
642
    }
643
644
    /**
645
     * Gets any missing params that may not be collectable in the reflection.
646
     *
647
     * @param string $arg the argument string|array
648
     * @param array $params the reflection param list
649
     *
650
     * @return array|string|\ReeceM\Mocker\Mocked
651
     */
652
    private static function getMissingParams($arg, $params)
653
    {
654
        /**
655
         * Determine if a builtin type can be found.
656
         * Not a string or object as a Mocked::class can work there.
657
         *
658
         * getName() is undocumented alternative to casting to string.
659
         * https://www.php.net/manual/en/class.reflectiontype.php#124658
660
         *
661
         * @var \ReflectionType $reflection
662
         */
663
        $reflection = collect($params)->where('name', $arg)->first()->getType();
664
665
        if (version_compare(phpversion(), '7.1', '>=')) {
666
            $type = ! is_null($reflection)
667
                ? self::TYPES[$reflection->getName()]
668
                : null;
669
        } else {
670
            $type = ! is_null($reflection)
671
                ? self::TYPES[/** @scrutinizer ignore-deprecated */ $reflection->__toString()]
672
                : null;
673
        }
674
675
        try {
676
            return ! is_null($type)
677
                    ? $type
678
                    : new Mocked($arg, \ReeceM\Mocker\Utils\VarStore::singleton());
679
        } catch (\Exception $e) {
680
            return $arg;
681
        }
682
    }
683
684
    private static function getMailableViewData($mailable, $mailable_data)
685
    {
686
        $traitProperties = [];
687
688
        $data = new ReflectionClass($mailable);
689
690
        foreach ($data->getTraits() as $trait) {
691
            foreach ($trait->getProperties(ReflectionProperty::IS_PUBLIC) as $traitProperty) {
692
                $traitProperties[] = $traitProperty->name;
693
            }
694
        }
695
696
        $properties = $data->getProperties(ReflectionProperty::IS_PUBLIC);
697
        $allProps = [];
698
699
        foreach ($properties as $prop) {
700
            if ($prop->class == $data->getName() || $prop->class == get_parent_class($data->getName()) &&
701
                    get_parent_class($data->getName()) != 'Illuminate\Mail\Mailable' && ! $prop->isStatic()) {
702
                $allProps[] = $prop->name;
703
            }
704
        }
705
706
        $obj = self::buildMailable($mailable);
707
708
        if (is_null($obj)) {
709
            $obj = [];
710
711
            return collect($obj);
712
        }
713
714
        $classProps = array_diff($allProps, $traitProperties);
715
716
        $withFuncData = collect($obj->viewData)->keys();
717
718
        $mailableData = collect($classProps)->merge($withFuncData);
719
720
        $data = $mailableData->map(function ($parameter) use ($mailable_data) {
721
            return [
722
                'key' => $parameter,
723
                'value' => property_exists($mailable_data, $parameter) ? $mailable_data->$parameter : null,
724
                'data' => property_exists($mailable_data, $parameter) ? self::viewDataInspect($mailable_data->$parameter) : null,
725
            ];
726
        });
727
728
        return $data->all();
729
    }
730
731
    protected static function viewDataInspect($param)
732
    {
733
        if ($param instanceof \Illuminate\Database\Eloquent\Model) {
734
            return [
735
                'type' => 'model',
736
                'attributes' => collect($param->getAttributes()),
737
            ];
738
        } elseif ($param instanceof \Illuminate\Database\Eloquent\Collection) {
739
            return [
740
                'type' => 'elequent-collection',
741
                'attributes' => $param->all(),
742
            ];
743
        } elseif ($param instanceof \Illuminate\Support\Collection) {
744
            return [
745
                'type' => 'collection',
746
                'attributes' => $param->all(),
747
            ];
748
        }
749
    }
750
751
    protected static function mailable_exists($mailable)
752
    {
753
        if (! class_exists($mailable)) {
754
            return false;
755
        }
756
757
        return true;
758
    }
759
760
    protected static function getMarkdownViewName($mailable)
761
    {
762
        if ($mailable === null) {
763
            return;
764
        }
765
766
        $reflection = new ReflectionClass($mailable);
767
768
        $property = $reflection->getProperty('markdown');
769
770
        $property->setAccessible(true);
771
772
        return $property->getValue($mailable);
773
    }
774
775
    public static function buildMailable($instance, $type = 'call')
776
    {
777
        if ($type == 'call') {
778
            if (! is_null(self::handleMailableViewDataArgs($instance))) {
779
                return Container::getInstance()->call([self::handleMailableViewDataArgs($instance), 'build']);
780
            }
781
782
            return Container::getInstance()->call([new $instance, 'build']);
783
        }
784
785
        return Container::getInstance()->make($instance);
786
    }
787
788
    public static function renderPreview($simpleview, $view, $template = false, $instance = null)
789
    {
790
        if (! View::exists($view)) {
791
            return;
792
        }
793
794
        if (! $template) {
795
            $obj = self::buildMailable($instance);
796
            $viewData = $obj->viewData;
797
            $_data = array_merge($instance->buildViewData(), $viewData);
798
799
            foreach ($_data as $key => $value) {
800
                if (! is_object($value)) {
801
                    $_data[$key] = '<span class="maileclipse-key" title="Variable">'.$key.'</span>';
802
                }
803
            }
804
        } else {
805
            $_data = [];
806
        }
807
808
        $_view = $view;
809
810
        try {
811
            if ($simpleview) {
812
                return htmlspecialchars_decode(view($_view, $_data)->render());
0 ignored issues
show
Bug introduced by
It seems like view($_view, $_data)->render() can also be of type array; however, parameter $string of htmlspecialchars_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

812
                return htmlspecialchars_decode(/** @scrutinizer ignore-type */ view($_view, $_data)->render());
Loading history...
813
            }
814
815
            $_md = self::buildMailable(Markdown::class, 'make');
816
817
            return htmlspecialchars_decode($_md->render($_view, $_data));
818
        } catch (ErrorException $e) {
819
            $error = '<div class="alert alert-warning">
820
	    	<h5 class="alert-heading">Error:</h5>
821
	    	<p>'.$e->getMessage().'</p>
822
	    	</div>';
823
824
            if ($template) {
825
                $error .= '<div class="alert alert-info">
826
				<h5 class="alert-heading">Notice:</h5>
827
				<p>You can\'t add variables within a template editor because they are undefined until you bind the template with a mailable that actually has data.</p>
828
	    	</div>';
829
            }
830
831
            return $error;
832
        }
833
    }
834
}
835