Social Media Share Buttons & Social Sharing Icons - Version 2.4.4

Version Description

  • Q3 auto opening and opening of Floating and 'before and after posts' open automatically for new installs
  • Analyst 5.4.
  • Added the spinner for the chart
  • Updated the wp version compatablity
  • Export and import section added
  • Optimized bloc & teh wiget area for blocs (Gutenberg)
Download this release

Release Info

Developer socialdude
Plugin Icon 128x128 Social Media Share Buttons & Social Sharing Icons
Version 2.4.4
Comparing to
See all releases

Code changes from version 2.4.3 to 2.4.4

analyst/autoload.php CHANGED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- require_once __DIR__ . '/src/helpers.php';
4
-
5
- require_once __DIR__ . '/src/Contracts/HttpClientContract.php';
6
- require_once __DIR__ . '/src/Contracts/RequestContract.php';
7
- require_once __DIR__ . '/src/Contracts/RequestorContract.php';
8
- require_once __DIR__ . '/src/Contracts/TrackerContract.php';
9
- require_once __DIR__ . '/src/Contracts/CacheContract.php';
10
-
11
- require_once __DIR__ . '/src/Core/AbstractFactory.php';
12
-
13
- require_once __DIR__ . '/src/Cache/DatabaseCache.php';
14
-
15
- require_once __DIR__ . '/src/Account/Account.php';
16
- require_once __DIR__ . '/src/Account/AccountData.php';
17
- require_once __DIR__ . '/src/Account/AccountDataFactory.php';
18
- require_once __DIR__ . '/src/Contracts/AnalystContract.php';
19
-
20
- require_once __DIR__ . '/src/Http/Requests/AbstractLoggerRequest.php';
21
- require_once __DIR__ . '/src/Http/Requests/ActivateRequest.php';
22
- require_once __DIR__ . '/src/Http/Requests/DeactivateRequest.php';
23
- require_once __DIR__ . '/src/Http/Requests/InstallRequest.php';
24
- require_once __DIR__ . '/src/Http/Requests/OptInRequest.php';
25
- require_once __DIR__ . '/src/Http/Requests/OptOutRequest.php';
26
- require_once __DIR__ . '/src/Http/Requests/UninstallRequest.php';
27
-
28
- require_once __DIR__ . '/src/Http/CurlHttpClient.php';
29
- require_once __DIR__ . '/src/Http/DummyHttpClient.php';
30
- require_once __DIR__ . '/src/Http/WordPressHttpClient.php';
31
-
32
- require_once __DIR__ . '/src/Notices/Notice.php';
33
- require_once __DIR__ . '/src/Notices/NoticeFactory.php';
34
-
35
- require_once __DIR__ . '/src/Analyst.php';
36
- require_once __DIR__ . '/src/ApiRequestor.php';
37
- require_once __DIR__ . '/src/ApiResponse.php';
38
- require_once __DIR__ . '/src/Collector.php';
39
- require_once __DIR__ . '/src/Mutator.php';
40
-
1
+ <?php
2
+
3
+ require_once __DIR__ . '/src/helpers.php';
4
+
5
+ require_once __DIR__ . '/src/Contracts/HttpClientContract.php';
6
+ require_once __DIR__ . '/src/Contracts/RequestContract.php';
7
+ require_once __DIR__ . '/src/Contracts/RequestorContract.php';
8
+ require_once __DIR__ . '/src/Contracts/TrackerContract.php';
9
+ require_once __DIR__ . '/src/Contracts/CacheContract.php';
10
+
11
+ require_once __DIR__ . '/src/Core/AbstractFactory.php';
12
+
13
+ require_once __DIR__ . '/src/Cache/DatabaseCache.php';
14
+
15
+ require_once __DIR__ . '/src/Account/Account.php';
16
+ require_once __DIR__ . '/src/Account/AccountData.php';
17
+ require_once __DIR__ . '/src/Account/AccountDataFactory.php';
18
+ require_once __DIR__ . '/src/Contracts/AnalystContract.php';
19
+
20
+ require_once __DIR__ . '/src/Http/Requests/AbstractLoggerRequest.php';
21
+ require_once __DIR__ . '/src/Http/Requests/ActivateRequest.php';
22
+ require_once __DIR__ . '/src/Http/Requests/DeactivateRequest.php';
23
+ require_once __DIR__ . '/src/Http/Requests/InstallRequest.php';
24
+ require_once __DIR__ . '/src/Http/Requests/OptInRequest.php';
25
+ require_once __DIR__ . '/src/Http/Requests/OptOutRequest.php';
26
+ require_once __DIR__ . '/src/Http/Requests/UninstallRequest.php';
27
+
28
+ require_once __DIR__ . '/src/Http/CurlHttpClient.php';
29
+ require_once __DIR__ . '/src/Http/DummyHttpClient.php';
30
+ require_once __DIR__ . '/src/Http/WordPressHttpClient.php';
31
+
32
+ require_once __DIR__ . '/src/Notices/Notice.php';
33
+ require_once __DIR__ . '/src/Notices/NoticeFactory.php';
34
+
35
+ require_once __DIR__ . '/src/Analyst.php';
36
+ require_once __DIR__ . '/src/ApiRequestor.php';
37
+ require_once __DIR__ . '/src/ApiResponse.php';
38
+ require_once __DIR__ . '/src/Collector.php';
39
+ require_once __DIR__ . '/src/Mutator.php';
40
+
analyst/sdk_resolver.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
-
3
- if (!function_exists('analyst_resolve_sdk')) {
4
-
5
- /**
6
- * Resolve supported sdk versions and load latest supported one
7
- * also bootstrap sdk with autoloader
8
- *
9
- * @since 1.1.3
10
- *
11
- * @param null $thisPluginPath
12
- * @return void
13
- * @throws Exception
14
- */
15
- function analyst_resolve_sdk($thisPluginPath = null) {
16
- static $loaded = false;
17
-
18
- // Exit if we already resolved SDK
19
- if ($loaded) return;
20
-
21
- $plugins = get_option('active_plugins');
22
-
23
- if ($thisPluginPath) {
24
- array_push($plugins, plugin_basename($thisPluginPath));
25
- }
26
-
27
- $pluginsFolder = WP_PLUGIN_DIR;
28
-
29
- $possibleSDKs = array_map(function ($path) use ($pluginsFolder) {
30
- $sdkFolder = sprintf('%s/%s/analyst/', $pluginsFolder, dirname($path));
31
-
32
- $sdkFolder = str_replace('\\', '/', $sdkFolder);
33
-
34
- $versionPath = $sdkFolder . 'version.php';
35
-
36
- if (file_exists($versionPath)) {
37
- return require $versionPath;
38
- }
39
-
40
- return false;
41
- }, $plugins);
42
-
43
- global $wp_version;
44
-
45
- // Filter out plugins which has no SDK
46
- $SDKs = array_filter($possibleSDKs, function ($s) {return is_array($s);});
47
-
48
- // Filter SDKs which is supported by PHP and WP
49
- $supported = array_values(array_filter($SDKs, function ($sdk) use($wp_version) {
50
- $phpSupported = version_compare(PHP_VERSION, $sdk['php']) >= 0;
51
- $wpSupported = version_compare($wp_version, $sdk['wp']) >= 0;
52
-
53
- return $phpSupported && $wpSupported;
54
- }));
55
-
56
- // Sort SDK by version in descending order
57
- uasort($supported, function ($x, $y) {
58
- return version_compare($y['sdk'], $x['sdk']);
59
- });
60
-
61
- // Reset sorted values keys
62
- $supported = array_values($supported);
63
-
64
- if (!isset($supported[0])) {
65
- throw new Exception('There is no SDK which is support current PHP version and WP version');
66
- }
67
-
68
- // Autoload files for supported SDK
69
- $autoloaderPath = str_replace(
70
- '\\',
71
- '/',
72
- sprintf('%s/autoload.php', $supported[0]['path'])
73
- );
74
-
75
- require_once $autoloaderPath;
76
-
77
- $loaded = true;
78
- }
79
- }
1
+ <?php
2
+
3
+ if (!function_exists('analyst_resolve_sdk')) {
4
+
5
+ /**
6
+ * Resolve supported sdk versions and load latest supported one
7
+ * also bootstrap sdk with autoloader
8
+ *
9
+ * @since 1.1.3
10
+ *
11
+ * @param null $thisPluginPath
12
+ * @return void
13
+ * @throws Exception
14
+ */
15
+ function analyst_resolve_sdk($thisPluginPath = null) {
16
+ static $loaded = false;
17
+
18
+ // Exit if we already resolved SDK
19
+ if ($loaded) return;
20
+
21
+ $plugins = get_option('active_plugins');
22
+
23
+ if ($thisPluginPath) {
24
+ array_push($plugins, plugin_basename($thisPluginPath));
25
+ }
26
+
27
+ $pluginsFolder = WP_PLUGIN_DIR;
28
+
29
+ $possibleSDKs = array_map(function ($path) use ($pluginsFolder) {
30
+ $sdkFolder = sprintf('%s/%s/analyst/', $pluginsFolder, dirname($path));
31
+
32
+ $sdkFolder = str_replace('\\', '/', $sdkFolder);
33
+
34
+ $versionPath = $sdkFolder . 'version.php';
35
+
36
+ if (file_exists($versionPath)) {
37
+ return require $versionPath;
38
+ }
39
+
40
+ return false;
41
+ }, $plugins);
42
+
43
+ global $wp_version;
44
+
45
+ // Filter out plugins which has no SDK
46
+ $SDKs = array_filter($possibleSDKs, function ($s) {return is_array($s);});
47
+
48
+ // Filter SDKs which is supported by PHP and WP
49
+ $supported = array_values(array_filter($SDKs, function ($sdk) use($wp_version) {
50
+ $phpSupported = version_compare(PHP_VERSION, $sdk['php']) >= 0;
51
+ $wpSupported = version_compare($wp_version, $sdk['wp']) >= 0;
52
+
53
+ return $phpSupported && $wpSupported;
54
+ }));
55
+
56
+ // Sort SDK by version in descending order
57
+ uasort($supported, function ($x, $y) {
58
+ return version_compare($y['sdk'], $x['sdk']);
59
+ });
60
+
61
+ // Reset sorted values keys
62
+ $supported = array_values($supported);
63
+
64
+ if (!isset($supported[0])) {
65
+ throw new Exception('There is no SDK which is support current PHP version and WP version');
66
+ }
67
+
68
+ // Autoload files for supported SDK
69
+ $autoloaderPath = str_replace(
70
+ '\\',
71
+ '/',
72
+ sprintf('%s/autoload.php', $supported[0]['path'])
73
+ );
74
+
75
+ require_once $autoloaderPath;
76
+
77
+ $loaded = true;
78
+ }
79
+ }
analyst/src/Account/Account.php CHANGED
@@ -1,604 +1,584 @@
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']) ? stripslashes($_POST['question']) : null;
247
- $reason = isset($_POST['reason']) ? stripslashes($_POST['reason']) : null;
248
-
249
- $response = DeactivateRequest::make($this->collector, $this->id, $this->path, $question, $reason)
250
- ->execute($this->requestor);
251
-
252
- // Exit if request failed
253
- if (!$response->isSuccess()) {
254
- wp_send_json_error($response->body);
255
- }
256
-
257
- $this->setIsInstalled(false);
258
-
259
- AccountDataFactory::syncData();
260
-
261
- wp_send_json_success();
262
- }
263
-
264
- /**
265
- * Will fire when user opted in
266
- *
267
- * @return void
268
- */
269
- public function onOptInListener()
270
- {
271
- $response = OptInRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
272
-
273
- // Exit if request failed
274
- if (!$response->isSuccess()) {
275
- wp_send_json_error($response->body);
276
- }
277
-
278
- $this->setIsOptedIn(true);
279
-
280
- AccountDataFactory::syncData();
281
-
282
- wp_die();
283
- }
284
-
285
- /**
286
- * Will fire when user opted out
287
- *
288
- * @return void
289
- */
290
- public function onOptOutListener()
291
- {
292
- $response = OptOutRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
293
-
294
- // Exit if request failed
295
- if (!$response->isSuccess()) {
296
- wp_send_json_error($response->body);
297
- }
298
-
299
- $this->setIsOptedIn(false);
300
-
301
- AccountDataFactory::syncData();
302
-
303
- wp_send_json_success();
304
- }
305
-
306
- /**
307
- * Will fire when user accept opt-in
308
- * at first time
309
- *
310
- * @return void
311
- */
312
- public function onInstallListener()
313
- {
314
- $cache = DatabaseCache::getInstance();
315
-
316
- // Set flag to true which indicates that install is resolved
317
- // also remove install plugin id from cache
318
- $this->setIsInstallResolved(true);
319
- $cache->delete('plugin_to_install');
320
-
321
- $response = InstallRequest::make($this->collector, $this->id, $this->path)->execute($this->requestor);
322
-
323
- // Exit if request failed
324
- if (!$response->isSuccess()) {
325
- wp_send_json_error($response->body);
326
- }
327
-
328
- $this->setIsSigned(true);
329
-
330
- $this->setIsOptedIn(true);
331
-
332
- $factory = NoticeFactory::instance();
333
-
334
- $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());
335
-
336
- $notificationId = uniqid();
337
-
338
- $notice = Notice::make(
339
- $notificationId,
340
- $this->getId(),
341
- $message,
342
- $this->collector->getPluginName($this->path)
343
- );
344
-
345
- $factory->addNotice($notice);
346
-
347
- AccountDataFactory::syncData();
348
-
349
- // Set email confirmation notification id to cache
350
- // se we can extract and remove it when user confirmed email
351
- $cache->put(
352
- sprintf('account_email_confirmation_%s', $this->getId()),
353
- $notificationId
354
- );
355
-
356
- wp_send_json_success();
357
- }
358
-
359
- /**
360
- * Will fire when user skipped installation
361
- *
362
- * @return void
363
- */
364
- public function onSkipInstallListener()
365
- {
366
- // Set flag to true which indicates that install is resolved
367
- // also remove install plugin id from cache
368
- $this->setIsInstallResolved(true);
369
- DatabaseCache::getInstance()->delete('plugin_to_install');
370
- }
371
-
372
- /**
373
- * Will fire when user delete plugin through admin panel.
374
- * This action will happen if admin at least once
375
- * activated the plugin.
376
- *
377
- * @return void
378
- * @throws \Exception
379
- */
380
- public static function onUninstallPluginListener()
381
- {
382
- $factory = AccountDataFactory::instance();
383
-
384
- $pluginFile = substr(current_filter(), strlen( 'uninstall_' ));
385
-
386
- $account = $factory->getAccountDataByBasePath($pluginFile);
387
-
388
- // If account somehow is not found, exit the execution
389
- if (!$account) return;
390
-
391
- $analyst = Analyst::getInstance();
392
-
393
- $collector = new Collector($analyst);
394
-
395
- $requestor = new ApiRequestor($account->getId(), $account->getSecret(), $analyst->getApiBase());
396
-
397
- // Just send request to log uninstall event not caring about response
398
- UninstallRequest::make($collector, $account->getId(), $account->getPath())->execute($requestor);
399
-
400
- $factory->sync();
401
- }
402
-
403
- /**
404
- * Fires when used verified his account
405
- */
406
- public function onInstallVerifiedListener()
407
- {
408
- $factory = NoticeFactory::instance();
409
-
410
- $notice = Notice::make(
411
- uniqid(),
412
- $this->getId(),
413
- 'Thank you for confirming your email.',
414
- $this->collector->getPluginName($this->path)
415
- );
416
-
417
- $factory->addNotice($notice);
418
-
419
- // Remove confirmation notification
420
- $confirmationNotificationId = DatabaseCache::getInstance()->pop(sprintf('account_email_confirmation_%s', $this->getId()));
421
- $factory->remove($confirmationNotificationId);
422
-
423
- AccountDataFactory::syncData();
424
-
425
- wp_send_json_success();
426
- }
427
-
428
- /**
429
- * Will fire when wp renders plugin
430
- * action buttons
431
- *
432
- * @param $defaultLinks
433
- * @return array
434
- */
435
- public function onRenderActionLinksHook($defaultLinks)
436
- {
437
- $customLinks = [];
438
-
439
- $customLinks[] = $this->isOptedIn()
440
- ? '<a class="analyst-action-opt analyst-opt-out" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt Out</a>'
441
- : '<a class="analyst-action-opt analyst-opt-in" analyst-plugin-id="' . $this->getId() . '" analyst-plugin-signed="' . (int) $this->isSigned() . '">Opt In</a>';
442
-
443
- // Append anchor to find specific deactivation link
444
- if (isset($defaultLinks['deactivate'])) {
445
- $defaultLinks['deactivate'] .= '<span analyst-plugin-id="' . $this->getId() . '" analyst-plugin-opted-in="' . (int) $this->isOptedIn() . '"></span>';
446
- }
447
-
448
- return array_merge($customLinks, $defaultLinks);
449
- }
450
-
451
- /**
452
- * @return AccountData
453
- */
454
- public function getData()
455
- {
456
- return $this->data;
457
- }
458
-
459
- /**
460
- * @param AccountData $data
461
- */
462
- public function setData(AccountData $data)
463
- {
464
- $this->data = $data;
465
-
466
- $this->setIsOptedIn($data->isOptedIn());
467
- $this->setIsInstalled($data->isInstalled());
468
- $this->setIsSigned($data->isSigned());
469
- $this->setIsInstallResolved($data->isInstallResolved());
470
- }
471
-
472
- /**
473
- * Resolves valid action name
474
- * based on client id
475
- *
476
- * @param $action
477
- * @return string
478
- */
479
- private function resolveActionName($action)
480
- {
481
- return sprintf('%s_%s', $action, $this->id);
482
- }
483
-
484
- /**
485
- * Register action for current plugin
486
- *
487
- * @param $action
488
- * @param $callback
489
- */
490
- private function addFilter($action, $callback)
491
- {
492
- $validAction = sprintf('%s_%s', $action, $this->basePluginPath);
493
-
494
- add_filter($validAction, $callback, 10);
495
- }
496
-
497
- /**
498
- * Add ajax action for current plugin
499
- *
500
- * @param $action
501
- * @param $callback
502
- * @param bool $raw Format action ??
503
- */
504
- private function addAjax($action, $callback, $raw = false)
505
- {
506
- $validAction = $raw ? $action : sprintf('%s%s', 'wp_ajax_', $this->resolveActionName($action));
507
-
508
- add_action($validAction, $callback);
509
- }
510
-
511
- /**
512
- * @return bool
513
- */
514
- public function isSigned()
515
- {
516
- return $this->isSigned;
517
- }
518
-
519
- /**
520
- * @param bool $isSigned
521
- */
522
- public function setIsSigned($isSigned)
523
- {
524
- $this->data->setIsSigned($isSigned);
525
-
526
- $this->isSigned = $isSigned;
527
- }
528
-
529
- /**
530
- * @return RequestorContract
531
- */
532
- public function getRequestor()
533
- {
534
- return $this->requestor;
535
- }
536
-
537
- /**
538
- * @param RequestorContract $requestor
539
- */
540
- public function setRequestor(RequestorContract $requestor)
541
- {
542
- $this->requestor = $requestor;
543
- }
544
-
545
- /**
546
- * @return string
547
- */
548
- public function getClientSecret()
549
- {
550
- return $this->clientSecret;
551
- }
552
-
553
- /**
554
- * @return Collector
555
- */
556
- public function getCollector()
557
- {
558
- return $this->collector;
559
- }
560
-
561
- /**
562
- * @param Collector $collector
563
- */
564
- public function setCollector(Collector $collector)
565
- {
566
- $this->collector = $collector;
567
- }
568
-
569
- /**
570
- * Do we allowing logging
571
- *
572
- * @return bool
573
- */
574
- public function isAllowingLogging()
575
- {
576
- return $this->isOptedIn;
577
- }
578
-
579
- /**
580
- * @return string
581
- */
582
- public function getBasePluginPath()
583
- {
584
- return $this->basePluginPath;
585
- }
586
-
587
- /**
588
- * @return bool
589
- */
590
- public function isInstallResolved()
591
- {
592
- return $this->isInstallResolved;
593
- }
594
-
595
- /**
596
- * @param bool $isInstallResolved
597
- */
598
- public function setIsInstallResolved($isInstallResolved)
599
- {
600
- $this->data->setIsInstallResolved($isInstallResolved);
601
-
602
- $this->isInstallResolved = $isInstallResolved;
603
- }
604
- }
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']) ? stripslashes($_POST['question']) : null;
247
+ $reason = isset($_POST['reason']) ? 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
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
analyst/src/Account/AccountDataFactory.php CHANGED
@@ -1,125 +1,125 @@
1
- <?php
2
-
3
- namespace Account;
4
-
5
-
6
- use Analyst\Core\AbstractFactory;
7
-
8
- /**
9
- * Class AccountDataFactory
10
- *
11
- * Holds information about this
12
- * wordpress project plugins accounts
13
- *
14
- */
15
- class AccountDataFactory extends AbstractFactory
16
- {
17
- private static $instance;
18
-
19
- CONST OPTIONS_KEY = 'analyst_accounts_data';
20
-
21
- /**
22
- * @var AccountData[]
23
- */
24
- protected $accounts = [];
25
-
26
- /**
27
- * Read factory from options or make fresh instance
28
- *
29
- * @return static
30
- */
31
- public static function instance()
32
- {
33
- if (!static::$instance) {
34
- $raw = get_option(self::OPTIONS_KEY);
35
-
36
- // In case object is already unserialized
37
- // and instance of AccountDataFactory we
38
- // return it, in other case deal with
39
- // serialized string data
40
- if ($raw instanceof self) {
41
- static::$instance = $raw;
42
- } else {
43
- static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
44
- }
45
- }
46
-
47
- return static::$instance;
48
- }
49
-
50
- /**
51
- * Sync this object data with cache
52
- */
53
- public function sync()
54
- {
55
- update_option(self::OPTIONS_KEY, serialize($this));
56
- }
57
-
58
- /**
59
- * Sync this instance data with cache
60
- */
61
- public static function syncData()
62
- {
63
- static::instance()->sync();
64
- }
65
-
66
- /**
67
- * Find plugin account data or create fresh one
68
- *
69
- * @param Account $account
70
- * @return AccountData|null
71
- */
72
- public function resolvePluginAccountData(Account $account)
73
- {
74
- $accountData = $this->findAccountDataById($account->getId());
75
-
76
- if (!$accountData) {
77
- $accountData = new AccountData();
78
-
79
- // Set proper default values
80
- $accountData->setPath($account->getPath());
81
- $accountData->setId($account->getId());
82
- $accountData->setSecret($account->getClientSecret());
83
-
84
- array_push($this->accounts, $accountData);
85
- }
86
-
87
- return $accountData;
88
- }
89
-
90
- /**
91
- * Should return account data by base path
92
- *
93
- * @param $basePath
94
- * @return AccountData
95
- */
96
- public function getAccountDataByBasePath($basePath)
97
- {
98
- foreach ($this->accounts as $iterable) {
99
- $iterableBasePath = plugin_basename($iterable->getPath());
100
-
101
- if ($iterableBasePath === $basePath) {
102
- return $iterable;
103
- }
104
- }
105
-
106
- return null;
107
- }
108
-
109
- /**
110
- * Return account by id
111
- *
112
- * @param $id
113
- * @return AccountData|null
114
- */
115
- private function findAccountDataById($id)
116
- {
117
- foreach ($this->accounts as &$iterable) {
118
- if ($iterable->getId() === $id) {
119
- return $iterable;
120
- }
121
- }
122
-
123
- return null;
124
- }
125
- }
1
+ <?php
2
+
3
+ namespace Account;
4
+
5
+
6
+ use Analyst\Core\AbstractFactory;
7
+
8
+ /**
9
+ * Class AccountDataFactory
10
+ *
11
+ * Holds information about this
12
+ * wordpress project plugins accounts
13
+ *
14
+ */
15
+ class AccountDataFactory extends AbstractFactory
16
+ {
17
+ private static $instance;
18
+
19
+ CONST OPTIONS_KEY = 'analyst_accounts_data';
20
+
21
+ /**
22
+ * @var AccountData[]
23
+ */
24
+ protected $accounts = [];
25
+
26
+ /**
27
+ * Read factory from options or make fresh instance
28
+ *
29
+ * @return static
30
+ */
31
+ public static function instance()
32
+ {
33
+ if (!static::$instance) {
34
+ $raw = get_option(self::OPTIONS_KEY);
35
+
36
+ // In case object is already unserialized
37
+ // and instance of AccountDataFactory we
38
+ // return it, in other case deal with
39
+ // serialized string data
40
+ if ($raw instanceof self) {
41
+ static::$instance = $raw;
42
+ } else {
43
+ static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
44
+ }
45
+ }
46
+
47
+ return static::$instance;
48
+ }
49
+
50
+ /**
51
+ * Sync this object data with cache
52
+ */
53
+ public function sync()
54
+ {
55
+ update_option(self::OPTIONS_KEY, serialize($this));
56
+ }
57
+
58
+ /**
59
+ * Sync this instance data with cache
60
+ */
61
+ public static function syncData()
62
+ {
63
+ static::instance()->sync();
64
+ }
65
+
66
+ /**
67
+ * Find plugin account data or create fresh one
68
+ *
69
+ * @param Account $account
70
+ * @return AccountData|null
71
+ */
72
+ public function resolvePluginAccountData(Account $account)
73
+ {
74
+ $accountData = $this->findAccountDataById($account->getId());
75
+
76
+ if (!$accountData) {
77
+ $accountData = new AccountData();
78
+
79
+ // Set proper default values
80
+ $accountData->setPath($account->getPath());
81
+ $accountData->setId($account->getId());
82
+ $accountData->setSecret($account->getClientSecret());
83
+
84
+ array_push($this->accounts, $accountData);
85
+ }
86
+
87
+ return $accountData;
88
+ }
89
+
90
+ /**
91
+ * Should return account data by base path
92
+ *
93
+ * @param $basePath
94
+ * @return AccountData
95
+ */
96
+ public function getAccountDataByBasePath($basePath)
97
+ {
98
+ foreach ($this->accounts as $iterable) {
99
+ $iterableBasePath = plugin_basename($iterable->getPath());
100
+
101
+ if ($iterableBasePath === $basePath) {
102
+ return $iterable;
103
+ }
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ /**
110
+ * Return account by id
111
+ *
112
+ * @param $id
113
+ * @return AccountData|null
114
+ */
115
+ private function findAccountDataById($id)
116
+ {
117
+ foreach ($this->accounts as &$iterable) {
118
+ if ($iterable->getId() === $id) {
119
+ return $iterable;
120
+ }
121
+ }
122
+
123
+ return null;
124
+ }
125
+ }
analyst/src/Cache/DatabaseCache.php CHANGED
@@ -1,127 +1,127 @@
1
- <?php
2
-
3
- namespace Analyst\Cache;
4
-
5
- use Analyst\Contracts\CacheContract;
6
-
7
- /**
8
- * Class DatabaseCache
9
- *
10
- * @since 1.1.5
11
- */
12
- class DatabaseCache implements CacheContract
13
- {
14
- const OPTION_KEY = 'analyst_cache';
15
-
16
- protected static $instance;
17
-
18
- /**
19
- * Get instance of db cache
20
- *
21
- * @return DatabaseCache
22
- */
23
- public static function getInstance()
24
- {
25
- if (!self::$instance) {
26
- self::$instance = new DatabaseCache();
27
- }
28
-
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Key value pair
34
- *
35
- * @var array[]
36
- */
37
- protected $values = [];
38
-
39
- /**
40
- * DatabaseCache constructor.
41
- */
42
- public function __construct()
43
- {
44
- $raw = get_option(self::OPTION_KEY, serialize([]));
45
-
46
- // Raw data may be an array already
47
- $this->values = is_array($raw) ? $raw : @unserialize($raw);
48
-
49
- // In case serialization is failed
50
- // make sure values is an array
51
- if (!is_array($this->values)) {
52
- $this->values = [];
53
- }
54
- }
55
-
56
- /**
57
- * Save value with given key
58
- *
59
- * @param string $key
60
- * @param string $value
61
- *
62
- * @return static
63
- */
64
- public function put($key, $value)
65
- {
66
- $this->values[$key] = $value;
67
-
68
- $this->sync();
69
-
70
- return $this;
71
- }
72
-
73
- /**
74
- * Get value by given key
75
- *
76
- * @param $key
77
- *
78
- * @param null $default
79
- * @return string
80
- */
81
- public function get($key, $default = null)
82
- {
83
- $value = isset($this->values[$key]) ? $this->values[$key] : $default;
84
-
85
- return $value;
86
- }
87
-
88
- /**
89
- * @param $key
90
- *
91
- * @return static
92
- */
93
- public function delete($key)
94
- {
95
- if (isset($this->values[$key])) {
96
- unset($this->values[$key]);
97
-
98
- $this->sync();
99
- }
100
-
101
- return $this;
102
- }
103
-
104
- /**
105
- * Update cache in DB
106
- */
107
- protected function sync()
108
- {
109
- update_option(self::OPTION_KEY, serialize($this->values));
110
- }
111
-
112
- /**
113
- * Should get value and remove it from cache
114
- *
115
- * @param $key
116
- * @param null $default
117
- * @return mixed
118
- */
119
- public function pop($key, $default = null)
120
- {
121
- $value = $this->get($key);
122
-
123
- $this->delete($key);
124
-
125
- return $value;
126
- }
127
- }
1
+ <?php
2
+
3
+ namespace Analyst\Cache;
4
+
5
+ use Analyst\Contracts\CacheContract;
6
+
7
+ /**
8
+ * Class DatabaseCache
9
+ *
10
+ * @since 1.1.5
11
+ */
12
+ class DatabaseCache implements CacheContract
13
+ {
14
+ const OPTION_KEY = 'analyst_cache';
15
+
16
+ protected static $instance;
17
+
18
+ /**
19
+ * Get instance of db cache
20
+ *
21
+ * @return DatabaseCache
22
+ */
23
+ public static function getInstance()
24
+ {
25
+ if (!self::$instance) {
26
+ self::$instance = new DatabaseCache();
27
+ }
28
+
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Key value pair
34
+ *
35
+ * @var array[]
36
+ */
37
+ protected $values = [];
38
+
39
+ /**
40
+ * DatabaseCache constructor.
41
+ */
42
+ public function __construct()
43
+ {
44
+ $raw = get_option(self::OPTION_KEY, serialize([]));
45
+
46
+ // Raw data may be an array already
47
+ $this->values = is_array($raw) ? $raw : @unserialize($raw);
48
+
49
+ // In case serialization is failed
50
+ // make sure values is an array
51
+ if (!is_array($this->values)) {
52
+ $this->values = [];
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Save value with given key
58
+ *
59
+ * @param string $key
60
+ * @param string $value
61
+ *
62
+ * @return static
63
+ */
64
+ public function put($key, $value)
65
+ {
66
+ $this->values[$key] = $value;
67
+
68
+ $this->sync();
69
+
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * Get value by given key
75
+ *
76
+ * @param $key
77
+ *
78
+ * @param null $default
79
+ * @return string
80
+ */
81
+ public function get($key, $default = null)
82
+ {
83
+ $value = isset($this->values[$key]) ? $this->values[$key] : $default;
84
+
85
+ return $value;
86
+ }
87
+
88
+ /**
89
+ * @param $key
90
+ *
91
+ * @return static
92
+ */
93
+ public function delete($key)
94
+ {
95
+ if (isset($this->values[$key])) {
96
+ unset($this->values[$key]);
97
+
98
+ $this->sync();
99
+ }
100
+
101
+ return $this;
102
+ }
103
+
104
+ /**
105
+ * Update cache in DB
106
+ */
107
+ protected function sync()
108
+ {
109
+ update_option(self::OPTION_KEY, serialize($this->values));
110
+ }
111
+
112
+ /**
113
+ * Should get value and remove it from cache
114
+ *
115
+ * @param $key
116
+ * @param null $default
117
+ * @return mixed
118
+ */
119
+ public function pop($key, $default = null)
120
+ {
121
+ $value = $this->get($key);
122
+
123
+ $this->delete($key);
124
+
125
+ return $value;
126
+ }
127
+ }
analyst/src/Collector.php CHANGED
@@ -1,217 +1,217 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- use Analyst\Contracts\AnalystContract;
6
-
7
- /**
8
- * Class Collector is a set of getters
9
- * to retrieve some data from wp site
10
- */
11
- class Collector
12
- {
13
- /**
14
- * @var AnalystContract
15
- */
16
- protected $sdk;
17
-
18
- /**
19
- * @var \WP_User
20
- */
21
- protected $user;
22
-
23
- public function __construct(AnalystContract $sdk)
24
- {
25
- $this->sdk = $sdk;
26
- }
27
-
28
- /**
29
- * Load current user into memory
30
- */
31
- public function loadCurrentUser()
32
- {
33
- $this->user = wp_get_current_user();
34
- }
35
-
36
- /**
37
- * Get site url
38
- *
39
- * @return string
40
- */
41
- public function getSiteUrl()
42
- {
43
- return get_option('siteurl');
44
- }
45
-
46
- /**
47
- * Get current user email
48
- *
49
- * @return string
50
- */
51
- public function getCurrentUserEmail()
52
- {
53
- return $this->user->user_email;
54
- }
55
-
56
- /**
57
- * Get's email from general settings
58
- *
59
- * @return string
60
- */
61
- public function getGeneralEmailAddress()
62
- {
63
- return get_option('admin_email');
64
- }
65
-
66
- /**
67
- * Is this user administrator
68
- *
69
- * @return bool
70
- */
71
- public function isUserAdministrator()
72
- {
73
- return in_array('administrator', $this->user->roles);
74
- }
75
-
76
- /**
77
- * User name
78
- *
79
- * @return string
80
- */
81
- public function getCurrentUserName()
82
- {
83
- return $this->user ? $this->user->user_nicename : 'unknown';
84
- }
85
-
86
- /**
87
- * WP version
88
- *
89
- * @return string
90
- */
91
- public function getWordPressVersion()
92
- {
93
- global $wp_version;
94
-
95
- return $wp_version;
96
- }
97
-
98
- /**
99
- * PHP version
100
- *
101
- * @return string
102
- */
103
- public function getPHPVersion()
104
- {
105
- return phpversion();
106
- }
107
-
108
- /**
109
- * Resolves plugin information
110
- *
111
- * @param string $path Absolute path to plugin
112
- * @return array
113
- */
114
- public function resolvePluginData($path)
115
- {
116
- if( !function_exists('get_plugin_data') ){
117
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
118
- }
119
-
120
- return get_plugin_data($path);
121
- }
122
-
123
- /**
124
- * Get plugin name by path
125
- *
126
- * @param $path
127
- * @return string
128
- */
129
- public function getPluginName($path)
130
- {
131
- $data = $this->resolvePluginData($path);
132
-
133
- return $data['Name'];
134
- }
135
-
136
- /**
137
- * Get plugin version
138
- *
139
- * @param $path
140
- * @return string
141
- */
142
- public function getPluginVersion($path)
143
- {
144
- $data = $this->resolvePluginData($path);
145
-
146
- return $data['Version'] ? $data['Version'] : null;
147
- }
148
-
149
- /**
150
- * Get server ip
151
- *
152
- * @return string
153
- */
154
- public function getServerIp()
155
- {
156
- return $_SERVER['SERVER_ADDR'];
157
- }
158
-
159
- /**
160
- * @return string
161
- */
162
- public function getSDKVersion()
163
- {
164
- return $this->sdk->version();
165
- }
166
-
167
- /**
168
- * @return string
169
- */
170
- public function getMysqlVersion()
171
- {
172
- $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
173
-
174
- $version = mysqli_get_server_info($conn);
175
-
176
- return $version ? $version : 'unknown';
177
- }
178
-
179
- /**
180
- * @return string
181
- */
182
- public function getSiteLanguage()
183
- {
184
- return get_locale();
185
- }
186
-
187
-
188
- /**
189
- * Current WP theme
190
- *
191
- * @return false|string
192
- */
193
- public function getCurrentThemeName()
194
- {
195
- return wp_get_theme()->get('Name');
196
- }
197
-
198
- /**
199
- * Get active plugins list
200
- *
201
- * @return array
202
- */
203
- public function getActivePluginsList()
204
- {
205
- if (!function_exists('get_plugins')) {
206
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
207
- }
208
-
209
- $allPlugins = get_plugins();
210
-
211
- $activePluginsNames = array_map(function ($path) use ($allPlugins) {
212
- return $allPlugins[$path]['Name'];
213
- }, get_option('active_plugins'));
214
-
215
- return $activePluginsNames;
216
- }
217
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ use Analyst\Contracts\AnalystContract;
6
+
7
+ /**
8
+ * Class Collector is a set of getters
9
+ * to retrieve some data from wp site
10
+ */
11
+ class Collector
12
+ {
13
+ /**
14
+ * @var AnalystContract
15
+ */
16
+ protected $sdk;
17
+
18
+ /**
19
+ * @var \WP_User
20
+ */
21
+ protected $user;
22
+
23
+ public function __construct(AnalystContract $sdk)
24
+ {
25
+ $this->sdk = $sdk;
26
+ }
27
+
28
+ /**
29
+ * Load current user into memory
30
+ */
31
+ public function loadCurrentUser()
32
+ {
33
+ $this->user = wp_get_current_user();
34
+ }
35
+
36
+ /**
37
+ * Get site url
38
+ *
39
+ * @return string
40
+ */
41
+ public function getSiteUrl()
42
+ {
43
+ return get_option('siteurl');
44
+ }
45
+
46
+ /**
47
+ * Get current user email
48
+ *
49
+ * @return string
50
+ */
51
+ public function getCurrentUserEmail()
52
+ {
53
+ return $this->user->user_email;
54
+ }
55
+
56
+ /**
57
+ * Get's email from general settings
58
+ *
59
+ * @return string
60
+ */
61
+ public function getGeneralEmailAddress()
62
+ {
63
+ return get_option('admin_email');
64
+ }
65
+
66
+ /**
67
+ * Is this user administrator
68
+ *
69
+ * @return bool
70
+ */
71
+ public function isUserAdministrator()
72
+ {
73
+ return in_array('administrator', $this->user->roles);
74
+ }
75
+
76
+ /**
77
+ * User name
78
+ *
79
+ * @return string
80
+ */
81
+ public function getCurrentUserName()
82
+ {
83
+ return $this->user ? $this->user->user_nicename : 'unknown';
84
+ }
85
+
86
+ /**
87
+ * WP version
88
+ *
89
+ * @return string
90
+ */
91
+ public function getWordPressVersion()
92
+ {
93
+ global $wp_version;
94
+
95
+ return $wp_version;
96
+ }
97
+
98
+ /**
99
+ * PHP version
100
+ *
101
+ * @return string
102
+ */
103
+ public function getPHPVersion()
104
+ {
105
+ return phpversion();
106
+ }
107
+
108
+ /**
109
+ * Resolves plugin information
110
+ *
111
+ * @param string $path Absolute path to plugin
112
+ * @return array
113
+ */
114
+ public function resolvePluginData($path)
115
+ {
116
+ if( !function_exists('get_plugin_data') ){
117
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
118
+ }
119
+
120
+ return get_plugin_data($path);
121
+ }
122
+
123
+ /**
124
+ * Get plugin name by path
125
+ *
126
+ * @param $path
127
+ * @return string
128
+ */
129
+ public function getPluginName($path)
130
+ {
131
+ $data = $this->resolvePluginData($path);
132
+
133
+ return $data['Name'];
134
+ }
135
+
136
+ /**
137
+ * Get plugin version
138
+ *
139
+ * @param $path
140
+ * @return string
141
+ */
142
+ public function getPluginVersion($path)
143
+ {
144
+ $data = $this->resolvePluginData($path);
145
+
146
+ return $data['Version'] ? $data['Version'] : null;
147
+ }
148
+
149
+ /**
150
+ * Get server ip
151
+ *
152
+ * @return string
153
+ */
154
+ public function getServerIp()
155
+ {
156
+ return $_SERVER['SERVER_ADDR'];
157
+ }
158
+
159
+ /**
160
+ * @return string
161
+ */
162
+ public function getSDKVersion()
163
+ {
164
+ return $this->sdk->version();
165
+ }
166
+
167
+ /**
168
+ * @return string
169
+ */
170
+ public function getMysqlVersion()
171
+ {
172
+ $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
173
+
174
+ $version = mysqli_get_server_info($conn);
175
+
176
+ return $version ? $version : 'unknown';
177
+ }
178
+
179
+ /**
180
+ * @return string
181
+ */
182
+ public function getSiteLanguage()
183
+ {
184
+ return get_locale();
185
+ }
186
+
187
+
188
+ /**
189
+ * Current WP theme
190
+ *
191
+ * @return false|string
192
+ */
193
+ public function getCurrentThemeName()
194
+ {
195
+ return wp_get_theme()->get('Name');
196
+ }
197
+
198
+ /**
199
+ * Get active plugins list
200
+ *
201
+ * @return array
202
+ */
203
+ public function getActivePluginsList()
204
+ {
205
+ if (!function_exists('get_plugins')) {
206
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
207
+ }
208
+
209
+ $allPlugins = get_plugins();
210
+
211
+ $activePluginsNames = array_map(function ($path) use ($allPlugins) {
212
+ return $allPlugins[$path]['Name'];
213
+ }, get_option('active_plugins'));
214
+
215
+ return $activePluginsNames;
216
+ }
217
+ }
analyst/src/Core/AbstractFactory.php CHANGED
@@ -1,27 +1,27 @@
1
- <?php
2
-
3
- namespace Analyst\Core;
4
-
5
- abstract class AbstractFactory
6
- {
7
- /**
8
- * Unserialize to static::class instance
9
- *
10
- * @param $raw
11
- * @return static
12
- */
13
- protected static function unserialize($raw)
14
- {
15
- $instance = @unserialize($raw);
16
-
17
- $isProperObject = is_object($instance) && $instance instanceof static;
18
-
19
- // In case for some reason unserialized object is not
20
- // static::class we make sure it is static::class
21
- if (!$isProperObject) {
22
- $instance = new static();
23
- }
24
-
25
- return $instance;
26
- }
27
- }
1
+ <?php
2
+
3
+ namespace Analyst\Core;
4
+
5
+ abstract class AbstractFactory
6
+ {
7
+ /**
8
+ * Unserialize to static::class instance
9
+ *
10
+ * @param $raw
11
+ * @return static
12
+ */
13
+ protected static function unserialize($raw)
14
+ {
15
+ $instance = @unserialize($raw);
16
+
17
+ $isProperObject = is_object($instance) && $instance instanceof static;
18
+
19
+ // In case for some reason unserialized object is not
20
+ // static::class we make sure it is static::class
21
+ if (!$isProperObject) {
22
+ $instance = new static();
23
+ }
24
+
25
+ return $instance;
26
+ }
27
+ }
analyst/src/Mutator.php CHANGED
@@ -1,103 +1,103 @@
1
- <?php
2
-
3
- namespace Analyst;
4
-
5
- use Analyst\Cache\DatabaseCache;
6
- use Analyst\Contracts\CacheContract;
7
- use Analyst\Notices\NoticeFactory;
8
-
9
- /**
10
- * Class Mutator mutates (modifies) UX with additional
11
- * functional
12
- */
13
- class Mutator
14
- {
15
- protected $notices = [];
16
-
17
- /**
18
- * @var NoticeFactory
19
- */
20
- protected $factory;
21
-
22
- /**
23
- * @var CacheContract
24
- */
25
- protected $cache;
26
-
27
- public function __construct()
28
- {
29
- $this->factory = NoticeFactory::instance();
30
-
31
- $this->notices = $this->factory->getNotices();
32
-
33
- $this->cache = DatabaseCache::getInstance();
34
- }
35
-
36
- /**
37
- * Register filters all necessary stuff.
38
- * Can be invoked only once.
39
- *
40
- * @return void
41
- */
42
- public function initialize()
43
- {
44
- $this->registerLinks();
45
- $this->registerAssets();
46
- $this->registerHooks();
47
- }
48
-
49
- /**
50
- * Register all necessary filters and templates
51
- *
52
- * @return void
53
- */
54
- protected function registerLinks()
55
- {
56
- add_action('admin_footer', function () {
57
- analyst_require_template('optout.php', [
58
- 'shieldImage' => analyst_assets_url('img/shield_question.png')
59
- ]);
60
-
61
- analyst_require_template('optin.php');
62
-
63
- analyst_require_template('forms/deactivate.php', [
64
- 'pencilImage' => analyst_assets_url('img/pencil.png'),
65
- 'smileImage' => analyst_assets_url('img/smile.png'),
66
- ]);
67
-
68
- analyst_require_template('forms/install.php', [
69
- 'pluginToInstall' => $this->cache->get('plugin_to_install'),
70
- 'shieldImage' => analyst_assets_url('img/shield_success.png'),
71
- ]);
72
- });
73
-
74
- add_action('admin_notices',function () {
75
- foreach ($this->notices as $notice) {
76
- analyst_require_template('notice.php', ['notice' => $notice]);
77
- }
78
- });
79
- }
80
-
81
- /**
82
- * Register all assets
83
- */
84
- public function registerAssets()
85
- {
86
- add_action('admin_enqueue_scripts', function () {
87
- wp_enqueue_style('analyst_custom', analyst_assets_url('/css/customize.css'));
88
- wp_enqueue_script('analyst_custom', analyst_assets_url('/js/customize.js'));
89
- });
90
- }
91
-
92
- /**
93
- * Register action hooks
94
- */
95
- public function registerHooks()
96
- {
97
- add_action('wp_ajax_analyst_notification_dismiss', function () {
98
- $this->factory->remove($_POST['id']);
99
-
100
- $this->factory->sync();
101
- });
102
- }
103
- }
1
+ <?php
2
+
3
+ namespace Analyst;
4
+
5
+ use Analyst\Cache\DatabaseCache;
6
+ use Analyst\Contracts\CacheContract;
7
+ use Analyst\Notices\NoticeFactory;
8
+
9
+ /**
10
+ * Class Mutator mutates (modifies) UX with additional
11
+ * functional
12
+ */
13
+ class Mutator
14
+ {
15
+ protected $notices = [];
16
+
17
+ /**
18
+ * @var NoticeFactory
19
+ */
20
+ protected $factory;
21
+
22
+ /**
23
+ * @var CacheContract
24
+ */
25
+ protected $cache;
26
+
27
+ public function __construct()
28
+ {
29
+ $this->factory = NoticeFactory::instance();
30
+
31
+ $this->notices = $this->factory->getNotices();
32
+
33
+ $this->cache = DatabaseCache::getInstance();
34
+ }
35
+
36
+ /**
37
+ * Register filters all necessary stuff.
38
+ * Can be invoked only once.
39
+ *
40
+ * @return void
41
+ */
42
+ public function initialize()
43
+ {
44
+ $this->registerLinks();
45
+ $this->registerAssets();
46
+ $this->registerHooks();
47
+ }
48
+
49
+ /**
50
+ * Register all necessary filters and templates
51
+ *
52
+ * @return void
53
+ */
54
+ protected function registerLinks()
55
+ {
56
+ add_action('admin_footer', function () {
57
+ analyst_require_template('optout.php', [
58
+ 'shieldImage' => analyst_assets_url('img/shield_question.png')
59
+ ]);
60
+
61
+ analyst_require_template('optin.php');
62
+
63
+ analyst_require_template('forms/deactivate.php', [
64
+ 'pencilImage' => analyst_assets_url('img/pencil.png'),
65
+ 'smileImage' => analyst_assets_url('img/smile.png'),
66
+ ]);
67
+
68
+ analyst_require_template('forms/install.php', [
69
+ 'pluginToInstall' => $this->cache->get('plugin_to_install'),
70
+ 'shieldImage' => analyst_assets_url('img/shield_success.png'),
71
+ ]);
72
+ });
73
+
74
+ add_action('admin_notices',function () {
75
+ foreach ($this->notices as $notice) {
76
+ analyst_require_template('notice.php', ['notice' => $notice]);
77
+ }
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Register all assets
83
+ */
84
+ public function registerAssets()
85
+ {
86
+ add_action('admin_enqueue_scripts', function () {
87
+ wp_enqueue_style('analyst_custom', analyst_assets_url('/css/customize.css'));
88
+ wp_enqueue_script('analyst_custom', analyst_assets_url('/js/customize.js'));
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Register action hooks
94
+ */
95
+ public function registerHooks()
96
+ {
97
+ add_action('wp_ajax_analyst_notification_dismiss', function () {
98
+ $this->factory->remove($_POST['id']);
99
+
100
+ $this->factory->sync();
101
+ });
102
+ }
103
+ }
analyst/src/Notices/NoticeFactory.php CHANGED
@@ -1,130 +1,130 @@
1
- <?php
2
-
3
- namespace Analyst\Notices;
4
-
5
- use Analyst\Core\AbstractFactory;
6
-
7
- class NoticeFactory extends AbstractFactory
8
- {
9
- private static $instance;
10
-
11
- CONST OPTIONS_KEY = 'analyst_notices';
12
-
13
- /**
14
- * Application notifications
15
- *
16
- * @var array
17
- */
18
- protected $notices = [];
19
-
20
- /**
21
- * Read factory from options or make fresh instance
22
- *
23
- * @return NoticeFactory
24
- */
25
- public static function instance()
26
- {
27
- if (!static::$instance) {
28
- $raw = get_option(self::OPTIONS_KEY);
29
-
30
- // In case object is already unserialized
31
- // and instance of AccountDataFactory we
32
- // return it, in other case deal with
33
- // serialized string data
34
- if ($raw instanceof self) {
35
- static::$instance = $raw;
36
- } else {
37
- static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
38
- }
39
- }
40
-
41
- return static::$instance;
42
- }
43
-
44
- /**
45
- * Sync this object data with cache
46
- */
47
- public function sync()
48
- {
49
- update_option(self::OPTIONS_KEY, serialize($this));
50
- }
51
-
52
- /**
53
- * Sync this instance data with cache
54
- */
55
- public static function syncData()
56
- {
57
- static::instance()->sync();
58
- }
59
-
60
- /**
61
- * @return array
62
- */
63
- public function getNotices()
64
- {
65
- return $this->notices;
66
- }
67
-
68
- /**
69
- * Filter out notices for certain account
70
- *
71
- * @param $accountId
72
- * @return array
73
- */
74
- public function getNoticesForAccount($accountId)
75
- {
76
- return array_filter($this->notices, function (Notice $notice) use ($accountId) {
77
- return $notice->getAccountId() === $accountId;
78
- });
79
- }
80
-
81
- /**
82
- * Add new notice
83
- *
84
- * @param $notice
85
- *
86
- * @return $this
87
- */
88
- public function addNotice($notice)
89
- {
90
- array_push($this->notices, $notice);
91
-
92
- $this->sync();
93
-
94
- return $this;
95
- }
96
-
97
- /**
98
- * Find notice by id
99
- *
100
- * @param $id
101
- * @return Notice|null
102
- */
103
- public function find($id)
104
- {
105
- $notices = array_filter($this->notices, function (Notice $notice) use ($id) {
106
- return $notice->getId() === $id;
107
- });
108
-
109
- return array_pop($notices);
110
- }
111
-
112
- /**
113
- * Remove notice by it's id
114
- *
115
- * @param $id
116
- */
117
- public function remove($id)
118
- {
119
- // Get key of notice to remove
120
- $key = array_search(
121
- $this->find($id),
122
- $this->notices
123
- );
124
-
125
- // Unset notice with key
126
- unset($this->notices[$key]);
127
-
128
- $this->sync();
129
- }
130
- }
1
+ <?php
2
+
3
+ namespace Analyst\Notices;
4
+
5
+ use Analyst\Core\AbstractFactory;
6
+
7
+ class NoticeFactory extends AbstractFactory
8
+ {
9
+ private static $instance;
10
+
11
+ CONST OPTIONS_KEY = 'analyst_notices';
12
+
13
+ /**
14
+ * Application notifications
15
+ *
16
+ * @var array
17
+ */
18
+ protected $notices = [];
19
+
20
+ /**
21
+ * Read factory from options or make fresh instance
22
+ *
23
+ * @return NoticeFactory
24
+ */
25
+ public static function instance()
26
+ {
27
+ if (!static::$instance) {
28
+ $raw = get_option(self::OPTIONS_KEY);
29
+
30
+ // In case object is already unserialized
31
+ // and instance of AccountDataFactory we
32
+ // return it, in other case deal with
33
+ // serialized string data
34
+ if ($raw instanceof self) {
35
+ static::$instance = $raw;
36
+ } else {
37
+ static::$instance = is_string($raw) ? static::unserialize($raw) : new self();
38
+ }
39
+ }
40
+
41
+ return static::$instance;
42
+ }
43
+
44
+ /**
45
+ * Sync this object data with cache
46
+ */
47
+ public function sync()
48
+ {
49
+ update_option(self::OPTIONS_KEY, serialize($this));
50
+ }
51
+
52
+ /**
53
+ * Sync this instance data with cache
54
+ */
55
+ public static function syncData()
56
+ {
57
+ static::instance()->sync();
58
+ }
59
+
60
+ /**
61
+ * @return array
62
+ */
63
+ public function getNotices()
64
+ {
65
+ return $this->notices;
66
+ }
67
+
68
+ /**
69
+ * Filter out notices for certain account
70
+ *
71
+ * @param $accountId
72
+ * @return array
73
+ */
74
+ public function getNoticesForAccount($accountId)
75
+ {
76
+ return array_filter($this->notices, function (Notice $notice) use ($accountId) {
77
+ return $notice->getAccountId() === $accountId;
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Add new notice
83
+ *
84
+ * @param $notice
85
+ *
86
+ * @return $this
87
+ */
88
+ public function addNotice($notice)
89
+ {
90
+ array_push($this->notices, $notice);
91
+
92
+ $this->sync();
93
+
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * Find notice by id
99
+ *
100
+ * @param $id
101
+ * @return Notice|null
102
+ */
103
+ public function find($id)
104
+ {
105
+ $notices = array_filter($this->notices, function (Notice $notice) use ($id) {
106
+ return $notice->getId() === $id;
107
+ });
108
+
109
+ return array_pop($notices);
110
+ }
111
+
112
+ /**
113
+ * Remove notice by it's id
114
+ *
115
+ * @param $id
116
+ */
117
+ public function remove($id)
118
+ {
119
+ // Get key of notice to remove
120
+ $key = array_search(
121
+ $this->find($id),
122
+ $this->notices
123
+ );