PluginProbe ʕ •ᴥ•ʔ
Redirection / 1.1.9
Redirection v1.1.9
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0
redirect-redirection / analyst / src / Account / Account.php
redirect-redirection / analyst / src / Account Last commit date
Account.php 2 years ago AccountData.php 2 years ago AccountDataFactory.php 2 years ago
Account.php
585 lines
1 <?php
2
3 namespace Account;
4
5 use Analyst\Analyst;
6 use Analyst\ApiRequestor;
7 use Analyst\Cache\DatabaseCache;
8 use Analyst\Collector;
9 use Analyst\Http\Requests\ActivateRequest;
10 use Analyst\Http\Requests\DeactivateRequest;
11 use Analyst\Http\Requests\InstallRequest;
12 use Analyst\Http\Requests\OptInRequest;
13 use Analyst\Http\Requests\OptOutRequest;
14 use Analyst\Http\Requests\UninstallRequest;
15 use Analyst\Notices\Notice;
16 use Analyst\Notices\NoticeFactory;
17 use Analyst\Contracts\TrackerContract;
18 use Analyst\Contracts\RequestorContract;
19
20 /**
21 * Class Account
22 *
23 * This is plugin's account object
24 */
25 class Account implements TrackerContract
26 {
27 /**
28 * Account id
29 *
30 * @var string
31 */
32 protected $id;
33
34 /**
35 * Basename of plugin
36 *
37 * @var string
38 */
39 protected $path;
40
41 /**
42 * Whether plugin is active or not
43 *
44 * @var bool
45 */
46 protected $isInstalled = false;
47
48 /**
49 * Is user sign in for data tracking
50 *
51 * @var bool
52 */
53 protected $isOptedIn = false;
54
55 /**
56 * Is user accepted permissions grant
57 * for collection site data
58 *
59 * @var bool
60 */
61 protected $isSigned = false;
62
63 /**
64 * Is user ever resolved install modal window?
65 *
66 * @var bool
67 */
68 protected $isInstallResolved = false;
69
70 /**
71 * Public secret code
72 *
73 * @var string
74 */
75 protected $clientSecret;
76
77 /**
78 * @var AccountData
79 */
80 protected $data;
81
82 /**
83 * Base plugin path
84 *
85 * @var string
86 */
87 protected $basePluginPath;
88
89 /**
90 * @var RequestorContract
91 */
92 protected $requestor;
93
94 /**
95 * @var Collector
96 */
97 protected $collector;
98
99 /**
100 * Account constructor.
101 * @param $id
102 * @param $secret
103 * @param $baseDir
104 */
105 public function __construct($id, $secret, $baseDir)
106 {
107 $this->id = $id;
108 $this->clientSecret = $secret;
109
110 $this->path = $baseDir;
111
112 $this->basePluginPath = plugin_basename($baseDir);
113 }
114
115 /**
116 * @return string
117 */
118 public function getPath()
119 {
120 return $this->path;
121 }
122
123 /**
124 * @param string $path
125 */
126 public function setPath($path)
127 {
128 $this->data->setPath($path);
129
130 $this->path = $path;
131 }
132
133 /**
134 * @return bool
135 */
136 public function isOptedIn()
137 {
138 return $this->isOptedIn;
139 }
140
141 /**
142 * @param bool $isOptedIn
143 */
144 public function setIsOptedIn($isOptedIn)
145 {
146 $this->data->setIsOptedIn($isOptedIn);
147
148 $this->isOptedIn = $isOptedIn;
149 }
150
151 /**
152 * Whether plugin is active
153 *
154 * @return bool
155 */
156 public function isActive()
157 {
158 return is_plugin_active($this->path);
159 }
160
161 /**
162 * @param string $id
163 */
164 public function setId($id)
165 {
166 $this->id = $id;
167 }
168
169 /**
170 * @return string
171 */
172 public function getId()
173 {
174 return $this->id;
175 }
176
177 /**
178 * @return bool
179 */
180 public function isInstalled()
181 {
182 return $this->isInstalled;
183 }
184
185 /**
186 * @param bool $isInstalled
187 */
188 public function setIsInstalled($isInstalled)
189 {
190 $this->data->setIsInstalled($isInstalled);
191
192 $this->isInstalled = $isInstalled;
193 }
194
195 /**
196 * Should register activation and deactivation
197 * event hooks
198 *
199 * @return void
200 */
201 public function registerHooks()
202 {
203 register_activation_hook($this->basePluginPath, [&$this, 'onActivePluginListener']);
204 register_uninstall_hook($this->basePluginPath, ['Account\Account', 'onUninstallPluginListener']);
205
206 $this->addFilter('plugin_action_links', [&$this, 'onRenderActionLinksHook']);
207
208 $this->addAjax('analyst_opt_in', [&$this, 'onOptInListener']);
209 $this->addAjax('analyst_opt_out', [&$this, 'onOptOutListener']);
210 $this->addAjax('analyst_plugin_deactivate', [&$this, 'onDeactivatePluginListener']);
211 $this->addAjax('analyst_install', [&$this, 'onInstallListener']);
212 $this->addAjax('analyst_skip_install', [&$this, 'onSkipInstallListener']);
213 $this->addAjax('analyst_install_verified', [&$this, 'onInstallVerifiedListener']);
214 }
215
216 /**
217 * Will fire when admin activates plugin
218 *
219 * @return void
220 */
221 public function onActivePluginListener()
222 {
223 if (!$this->isInstallResolved()) {
224 DatabaseCache::getInstance()->put('plugin_to_install', $this->id);
225 }
226
227 if (!$this->isAllowingLogging()) return;
228
229 ActivateRequest::make($this->collector, $this->id, $this->path)
230 ->execute($this->requestor);
231
232 $this->setIsInstalled(true);
233
234 AccountDataFactory::syncData();
235 }
236
237 /**
238 * Will fire when admin deactivates plugin
239 *
240 * @return void
241 */
242 public function onDeactivatePluginListener()
243 {
244 if (!$this->isAllowingLogging()) return;
245
246 $question = isset($_POST['question']) ? sanitize_text_field(stripslashes($_POST['question'])) : null;
247 $reason = isset($_POST['reason']) ? sanitize_text_field(stripslashes($_POST['reason'])) : null;
248
249 DeactivateRequest::make($this->collector, $this->id, $this->path, $question, $reason)
250 ->execute($this->requestor);
251
252 $this->setIsInstalled(false);
253
254 AccountDataFactory::syncData();
255
256 wp_send_json_success();
257 }
258
259 /**
260 * Will fire when user opted in
261 *
262 * @return void
263 */
264 public function onOptInListener()
265 {
266 OptInRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
267
268 $this->setIsOptedIn(true);
269
270 AccountDataFactory::syncData();
271
272 wp_die();
273 }
274
275 /**
276 * Will fire when user opted out
277 *
278 * @return void
279 */
280 public function onOptOutListener()
281 {
282 OptOutRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
283
284 $this->setIsOptedIn(false);
285
286 AccountDataFactory::syncData();
287
288 wp_send_json_success();
289 }
290
291 /**
292 * Will fire when user accept opt-in
293 * at first time
294 *
295 * @return void
296 */
297 public function onInstallListener()
298 {
299 $cache = DatabaseCache::getInstance();
300
301 // Set flag to true which indicates that install is resolved
302 // also remove install plugin id from cache
303 $this->setIsInstallResolved(true);
304 $cache->delete('plugin_to_install');
305
306 InstallRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
307
308 $this->setIsSigned(true);
309
310 $this->setIsOptedIn(true);
311
312 $factory = NoticeFactory::instance();
313
314 $message = sprintf('Please confirm your email by clicking on the link we sent to %s. This makes sure you’re not a bot.', $this->collector->getGeneralEmailAddress());
315
316 $notificationId = uniqid();
317
318 $notice = Notice::make(
319 $notificationId,
320 $this->getId(),
321 $message,
322 $this->collector->getPluginName($this->path)
323 );
324
325 $factory->addNotice($notice);
326
327 AccountDataFactory::syncData();
328
329 // Set email confirmation notification id to cache
330 // se we can extract and remove it when user confirmed email
331 $cache->put(
332 sprintf('account_email_confirmation_%s', $this->getId()),
333 $notificationId
334 );
335
336 wp_send_json_success();
337 }
338
339 /**
340 * Will fire when user skipped installation
341 *
342 * @return void
343 */
344 public function onSkipInstallListener()
345 {
346 // Set flag to true which indicates that install is resolved
347 // also remove install plugin id from cache
348 $this->setIsInstallResolved(true);
349 DatabaseCache::getInstance()->delete('plugin_to_install');
350 }
351
352 /**
353 * Will fire when user delete plugin through admin panel.
354 * This action will happen if admin at least once
355 * activated the plugin.
356 *
357 * @return void
358 * @throws \Exception
359 */
360 public static function onUninstallPluginListener()
361 {
362 $factory = AccountDataFactory::instance();
363
364 $pluginFile = substr(current_filter(), strlen( 'uninstall_' ));
365
366 $account = $factory->getAccountDataByBasePath($pluginFile);
367
368 // If account somehow is not found, exit the execution
369 if (!$account) return;
370
371 $analyst = Analyst::getInstance();
372
373 $collector = new Collector($analyst);
374
375 $requestor = new ApiRequestor($account->getId(), $account->getSecret(), $analyst->getApiBase());
376
377 // Just send request to log uninstall event not caring about response
378 UninstallRequest::make($collector, $account->getId(), $account->getPath())->execute($requestor);
379
380 $factory->sync();
381 }
382
383 /**
384 * Fires when used verified his account
385 */
386 public function onInstallVerifiedListener()
387 {
388 $factory = NoticeFactory::instance();
389
390 $notice = Notice::make(
391 uniqid(),
392 $this->getId(),
393 'Thank you for confirming your email.',
394 $this->collector->getPluginName($this->path)
395 );
396
397 $factory->addNotice($notice);
398
399 // Remove confirmation notification
400 $confirmationNotificationId = DatabaseCache::getInstance()->pop(sprintf('account_email_confirmation_%s', $this->getId()));
401 $factory->remove($confirmationNotificationId);
402
403 AccountDataFactory::syncData();
404
405 wp_send_json_success();
406 }
407
408 /**
409 * Will fire when wp renders plugin
410 * action buttons
411 *
412 * @param $defaultLinks
413 * @return array
414 */
415 public function onRenderActionLinksHook($defaultLinks)
416 {
417 $customLinks = [];
418
419 $customLinks[] = $this->isOptedIn()
420 ? '<a class="analyst-action-opt analyst-opt-out" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt Out</a>'
421 : '<a class="analyst-action-opt analyst-opt-in" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt In</a>';
422
423 // Append anchor to find specific deactivation link
424 if (isset($defaultLinks['deactivate'])) {
425 $defaultLinks['deactivate'] .= '<span analyst-plugin-id="' . $this->getId() . '" analyst-plugin-opted-in="' . (int) $this->isOptedIn() . '"></span>';
426 }
427
428 return array_merge($customLinks, $defaultLinks);
429 }
430
431 /**
432 * @return AccountData
433 */
434 public function getData()
435 {
436 return $this->data;
437 }
438
439 /**
440 * @param AccountData $data
441 */
442 public function setData(AccountData $data)
443 {
444 $this->data = $data;
445
446 $this->setIsOptedIn($data->isOptedIn());
447 $this->setIsInstalled($data->isInstalled());
448 $this->setIsSigned($data->isSigned());
449 $this->setIsInstallResolved($data->isInstallResolved());
450 }
451
452 /**
453 * Resolves valid action name
454 * based on client id
455 *
456 * @param $action
457 * @return string
458 */
459 private function resolveActionName($action)
460 {
461 return sprintf('%s_%s', $action, $this->id);
462 }
463
464 /**
465 * Register action for current plugin
466 *
467 * @param $action
468 * @param $callback
469 */
470 private function addFilter($action, $callback)
471 {
472 $validAction = sprintf('%s_%s', $action, $this->basePluginPath);
473
474 add_filter($validAction, $callback, 10);
475 }
476
477 /**
478 * Add ajax action for current plugin
479 *
480 * @param $action
481 * @param $callback
482 * @param bool $raw Format action ??
483 */
484 private function addAjax($action, $callback, $raw = false)
485 {
486 $validAction = $raw ? $action : sprintf('%s%s', 'wp_ajax_', $this->resolveActionName($action));
487
488 add_action($validAction, $callback);
489 }
490
491 /**
492 * @return bool
493 */
494 public function isSigned()
495 {
496 return $this->isSigned;
497 }
498
499 /**
500 * @param bool $isSigned
501 */
502 public function setIsSigned($isSigned)
503 {
504 $this->data->setIsSigned($isSigned);
505
506 $this->isSigned = $isSigned;
507 }
508
509 /**
510 * @return RequestorContract
511 */
512 public function getRequestor()
513 {
514 return $this->requestor;
515 }
516
517 /**
518 * @param RequestorContract $requestor
519 */
520 public function setRequestor(RequestorContract $requestor)
521 {
522 $this->requestor = $requestor;
523 }
524
525 /**
526 * @return string
527 */
528 public function getClientSecret()
529 {
530 return $this->clientSecret;
531 }
532
533 /**
534 * @return Collector
535 */
536 public function getCollector()
537 {
538 return $this->collector;
539 }
540
541 /**
542 * @param Collector $collector
543 */
544 public function setCollector(Collector $collector)
545 {
546 $this->collector = $collector;
547 }
548
549 /**
550 * Do we allowing logging
551 *
552 * @return bool
553 */
554 public function isAllowingLogging()
555 {
556 return $this->isOptedIn;
557 }
558
559 /**
560 * @return string
561 */
562 public function getBasePluginPath()
563 {
564 return $this->basePluginPath;
565 }
566
567 /**
568 * @return bool
569 */
570 public function isInstallResolved()
571 {
572 return $this->isInstallResolved;
573 }
574
575 /**
576 * @param bool $isInstallResolved
577 */
578 public function setIsInstallResolved($isInstallResolved)
579 {
580 $this->data->setIsInstallResolved($isInstallResolved);
581
582 $this->isInstallResolved = $isInstallResolved;
583 }
584 }
585