Passed
Push — master ( c72848...3af666 )
by Stephen
03:25 queued 01:13
created

AbstractViewModel::render()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 11
rs 10
1
<?php
2
3
namespace Sfneal\ViewModels;
4
5
use Illuminate\Http\Response;
6
use Illuminate\Support\Facades\Cache;
7
use Illuminate\Support\Facades\View;
8
use RuntimeException;
9
use Spatie\ViewModels\ViewModel;
10
11
12
abstract class AbstractViewModel extends ViewModel
13
{
14
    /**
15
     * @var int Time to live
16
     */
17
    public $ttl = null;
18
19
    /**
20
     * @var string Use manually declare redis_key (warning: can cause issues with caching)
21
     */
22
    public $redis_key = null;
23
24
    /**
25
     * View Directory Prefix
26
     */
27
    public $prefix;
28
29
    public $menu_active = null;
30
    public $has_breadcrumbs = null;
31
    public $pages = null;
32
33
    public $title = null;
34
    public $sub = null;
35
    public $text = null;
36
37
    public $view = null;
38
    public $id = null;
39
40
    public $hideContactForm = false;
41
42
    /**
43
     * Render the View
44
     *
45
     * @return string
46
     */
47
    private function __render() {
48
        return View::make($this->view, $this->toArray())->render();
49
    }
50
51
    /**
52
     * Retrieve the authenticated user's ID from the session
53
     *
54
     *  - avoid executing database query
55
     *
56
     * @return int
57
     */
58
    private function userId(): int {
59
        try {
60
            // Find the 'login_web' session key that holds the authenticated user_id value
61
            // If there's no key containing 'login_web' the user is not logged in
62
            $session_key = collect(request()->session()->all())->keys()->filter(function ($key) {
0 ignored issues
show
Bug introduced by
The function request was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

62
            $session_key = collect(/** @scrutinizer ignore-call */ request()->session()->all())->keys()->filter(function ($key) {
Loading history...
63
                return is_string($key) && inString($key, 'login_web');
0 ignored issues
show
Bug introduced by
The function inString was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

63
                return is_string($key) && /** @scrutinizer ignore-call */ inString($key, 'login_web');
Loading history...
64
            })->first();
65
        } catch (RuntimeException $runtimeException) {
66
            // request and/or session is not set (called from a job)
67
            $session_key = 0;
68
        }
69
70
        // Get the $session_key if it's not null
71
        return (!empty($session_key) ? session()->get($session_key) : 0);
0 ignored issues
show
Bug introduced by
The function session was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

71
        return (!empty($session_key) ? /** @scrutinizer ignore-call */ session()->get($session_key) : 0);
Loading history...
72
    }
73
74
    /**
75
     * Retrieve a unique redis key for caching the view
76
     *
77
     * @return string
78
     */
79
    private function redisViewKey(): string {
80
        return 'views' .
81
            ':' . $this->view .
82
            '#' . $this->userId() .
83
            '#' . (isset($this->redis_key) ? $this->redis_key : request()->fullUrl());
0 ignored issues
show
Bug introduced by
The function request was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

83
            '#' . (isset($this->redis_key) ? $this->redis_key : /** @scrutinizer ignore-call */ request()->fullUrl());
Loading history...
84
    }
85
86
    /**
87
     * Set an override Redis Key
88
     *
89
     * @param string $redis_key
90
     * @return $this
91
     */
92
    public function setRedisKey(string $redis_key) {
93
        $this->redis_key = $redis_key;
94
        return $this;
95
    }
96
97
    /**
98
     * Retrieve/render the ViewModel from/to the application cache
99
     *
100
     * @param string|null $view
101
     * @param int|null $ttl
102
     * @return Response|string|mixed
103
     */
104
    public function render(string $view=null, int $ttl = null)
105
    {
106
        // Set $view if it is not null
107
        if ($view) {
108
            $this->view = $view;
109
        }
110
111
        // Cache the View if it doesn't exist
112
        // todo: add use of Cacheable
113
        return Cache::remember($this->redisViewKey(), $this->getTTL($ttl), function () {
114
            return $this->__render();
115
        });
116
    }
117
118
    /**
119
     * Render the ViewModel without storing or retrieving from the Cache
120
     *
121
     * @param string|null $view
122
     * @return Response|string|mixed
123
     */
124
    public function renderNoCache(string $view=null) {
125
        // Set $view if it is not null
126
        if ($view) {
127
            $this->view = $view;
128
        }
129
130
        return $this->__render();
131
    }
132
133
    /**
134
     * Invalidate the View Cache for this ViewModel
135
     *
136
     * @return $this
137
     */
138
    public function invalidateCache() {
139
        redisDelete('views:'.$this->view);
0 ignored issues
show
Bug introduced by
The function redisDelete was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

139
        /** @scrutinizer ignore-call */ 
140
        redisDelete('views:'.$this->view);
Loading history...
140
        return $this;
141
    }
142
143
    /**
144
     * Return a concatenated route or view name by using the PREFIX const
145
     *
146
     * @param string $string
147
     * @return $this
148
     */
149
    public function viewWithPrefix(string $string) {
150
        $this->view = $this->prefix . $string;
151
        return $this;
152
    }
153
154
    /**
155
     * Extend a view name
156
     *
157
     * @param string $string
158
     * @return $this
159
     */
160
    public function viewExtend(string $string): self {
161
        $this->view .= $string;
162
        return $this;
163
    }
164
165
    /**
166
     * Retrieve the time to live for the cached values
167
     *  - 1. passed $ttl parameter
168
     *  - 2. initialized $this->ttl property
169
     *  - 3. application default cache ttl
170
     *
171
     * @param int|null $ttl
172
     * @return int|mixed
173
     */
174
    private function getTTL(int $ttl = null) {
175
        return $ttl ?? $this->ttl ?? env('REDIS_KEY_EXPIRATION');
176
    }
177
}
178