1 | <?php |
||||
2 | |||||
3 | namespace awssat\Visits; |
||||
4 | |||||
5 | use awssat\Visits\Traits\Lists; |
||||
6 | use awssat\Visits\Traits\Periods; |
||||
7 | use awssat\Visits\Traits\Record; |
||||
8 | use awssat\Visits\Traits\Setters; |
||||
9 | use Carbon\Carbon; |
||||
10 | use Illuminate\Database\Eloquent\Model; |
||||
11 | use Illuminate\Support\Facades\Redis; |
||||
12 | use Jaybizzle\CrawlerDetect\CrawlerDetect; |
||||
13 | |||||
14 | class Visits |
||||
15 | { |
||||
16 | use Record, Lists, Periods, Setters; |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
17 | |||||
18 | /** |
||||
19 | * @var mixed |
||||
20 | */ |
||||
21 | protected $ipSeconds; |
||||
22 | /** |
||||
23 | * @var null |
||||
24 | */ |
||||
25 | protected $subject; |
||||
26 | /** |
||||
27 | * @var bool|mixed |
||||
28 | */ |
||||
29 | protected $fresh = false; |
||||
30 | /** |
||||
31 | * @var null |
||||
32 | */ |
||||
33 | protected $country = null; |
||||
34 | /** |
||||
35 | * @var null |
||||
36 | */ |
||||
37 | protected $referer = null; |
||||
38 | /** |
||||
39 | * @var mixed |
||||
40 | */ |
||||
41 | protected $periods; |
||||
42 | /** |
||||
43 | * @var Keys |
||||
44 | */ |
||||
45 | protected $keys; |
||||
46 | /** |
||||
47 | * @var Redis |
||||
48 | */ |
||||
49 | public $redis; |
||||
50 | /** |
||||
51 | * @var boolean |
||||
52 | */ |
||||
53 | public $ignoreCrawlers = false; |
||||
54 | |||||
55 | /** |
||||
56 | * Visits constructor. |
||||
57 | * @param $subject |
||||
58 | * @param string $tag|null |
||||
59 | */ |
||||
60 | public function __construct($subject = null, $tag = 'visits') |
||||
61 | { |
||||
62 | $config = config('visits'); |
||||
63 | $this->redis = Redis::connection($config['connection']); |
||||
64 | $this->periods = $config['periods']; |
||||
65 | $this->ipSeconds = $config['remember_ip']; |
||||
66 | $this->fresh = $config['always_fresh']; |
||||
67 | $this->ignoreCrawlers = $config['ignore_crawlers']; |
||||
68 | $this->subject = $subject; |
||||
69 | $this->keys = new Keys($subject, $tag); |
||||
70 | |||||
71 | $this->periodsSync(); |
||||
72 | } |
||||
73 | |||||
74 | /** |
||||
75 | * @param $subject |
||||
76 | * @return $this |
||||
77 | */ |
||||
78 | public function by($subject) |
||||
79 | { |
||||
80 | if($subject instanceof Model) { |
||||
81 | $this->keys->append($this->keys->modelName($subject), $subject->{$subject->getKeyName()}); |
||||
82 | } else if (is_array($subject)) { |
||||
83 | $this->keys->append(array_keys($subject)[0], array_first($subject)); |
||||
84 | } |
||||
85 | |||||
86 | return $this; |
||||
87 | } |
||||
88 | |||||
89 | /** |
||||
90 | * Reset methods |
||||
91 | * |
||||
92 | * @param $method |
||||
93 | * @param string $args |
||||
94 | * @return Reset |
||||
95 | */ |
||||
96 | public function reset($method = 'visits', $args = '') |
||||
97 | { |
||||
98 | return new Reset($this, $method, $args); |
||||
99 | } |
||||
100 | |||||
101 | /** |
||||
102 | * Check for the ip is has been recorded before |
||||
103 | * |
||||
104 | * @return bool |
||||
105 | * @internal param $subject |
||||
106 | */ |
||||
107 | public function recordedIp() |
||||
108 | { |
||||
109 | return ! $this->redis->set($this->keys->ip(request()->ip()), true, 'EX', $this->ipSeconds, 'NX'); |
||||
110 | } |
||||
111 | |||||
112 | /** |
||||
113 | * Get visits of model instance. |
||||
114 | * |
||||
115 | * @return mixed |
||||
116 | * @internal param $subject |
||||
117 | */ |
||||
118 | public function count() |
||||
119 | { |
||||
120 | if ($this->country) { |
||||
121 | return $this->redis->zscore($this->keys->visits . "_countries:{$this->keys->id}", $this->country); |
||||
122 | } else if ($this->referer) { |
||||
123 | return $this->redis->zscore($this->keys->visits . "_referers:{$this->keys->id}", $this->referer); |
||||
124 | } |
||||
125 | |||||
126 | return intval( |
||||
127 | (!$this->keys->instanceOfModel) ? |
||||
128 | $this->redis->get($this->keys->visits . '_total') : |
||||
129 | $this->redis->zscore($this->keys->visits, $this->keys->id) |
||||
130 | ); |
||||
131 | } |
||||
132 | |||||
133 | /** |
||||
134 | * use diffForHumans to show diff |
||||
135 | * @param $period |
||||
136 | * @return Carbon |
||||
137 | */ |
||||
138 | public function timeLeft($period = false) |
||||
139 | { |
||||
140 | return Carbon::now()->addSeconds($this->redis->ttl( |
||||
0 ignored issues
–
show
The method
ttl() does not exist on Illuminate\Support\Facades\Redis .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||||
141 | $period ? $this->keys->period($period) : $this->keys->ip(request()->ip()) |
||||
142 | )); |
||||
143 | } |
||||
144 | |||||
145 | protected function isCrawler() |
||||
146 | { |
||||
147 | return $this->ignoreCrawlers && app(CrawlerDetect::class)->isCrawler(); |
||||
148 | } |
||||
149 | |||||
150 | /** |
||||
151 | * Increment a new/old subject to the cache. |
||||
152 | * |
||||
153 | * @param int $inc |
||||
154 | * @param bool $force |
||||
155 | * @param bool $periods |
||||
156 | * @param bool $country |
||||
157 | * @param bool $refer |
||||
158 | */ |
||||
159 | public function increment($inc = 1, $force = false, $periods = true, $country = true, $refer = true) |
||||
160 | { |
||||
161 | if ($force OR !$this->isCrawler() && !$this->recordedIp()) { |
||||
162 | $this->redis->zincrby($this->keys->visits, $inc, $this->keys->id); |
||||
163 | $this->redis->incrby($this->keys->visits . '_total', $inc); |
||||
164 | |||||
165 | //NOTE: $method is parameter also .. ($periods,$country,$refer) |
||||
166 | foreach (['country', 'refer', 'periods'] as $method) { |
||||
167 | $$method && $this->{'record' . studly_case($method)}($inc); |
||||
168 | } |
||||
169 | } |
||||
170 | } |
||||
171 | |||||
172 | /** |
||||
173 | * @param int $inc |
||||
174 | * @param bool $periods |
||||
175 | */ |
||||
176 | public function forceIncrement($inc = 1, $periods = true) |
||||
177 | { |
||||
178 | $this->increment($inc, true, $periods); |
||||
179 | } |
||||
180 | |||||
181 | /** |
||||
182 | * Decrement a new/old subject to the cache cache. |
||||
183 | * |
||||
184 | * @param int $dec |
||||
185 | * @param bool $force |
||||
186 | */ |
||||
187 | public function decrement($dec = 1, $force = false) |
||||
188 | { |
||||
189 | $this->increment(-$dec, $force); |
||||
190 | } |
||||
191 | |||||
192 | /** |
||||
193 | * @param int $dec |
||||
194 | * @param bool $periods |
||||
195 | */ |
||||
196 | public function forceDecrement($dec = 1, $periods = true) |
||||
197 | { |
||||
198 | $this->increment(-$dec, true, $periods); |
||||
199 | } |
||||
200 | |||||
201 | /** |
||||
202 | * @param $period |
||||
203 | * @param int $time |
||||
204 | * @return bool |
||||
205 | */ |
||||
206 | public function expireAt($period, $time) |
||||
207 | { |
||||
208 | $periodKey = $this->keys->period($period); |
||||
209 | return $this->redis->expire($periodKey, $time); |
||||
210 | } |
||||
211 | } |
||||
212 |