PluginProbe
Metricool – Social media and site statistics / 2.0.2
Metricool – Social media and site statistics v2.0.2
2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.27 trunk
metricool / app / Features / AdminNotices / AbstractAdminNotice.php

AbstractAdminNotice.php in Metricool – Social media and site statistics 2.0.2, at app/Features/AdminNotices/AbstractAdminNotice.php

192 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Metricool\Features\AdminNotices;
6
7 use Metricool\Support\Helpers\Storages\EnvironmentConfig;
8 use Metricool\Traits\HasViews;
9
10 abstract class AbstractAdminNotice
11 {
12 use HasViews {
13 render as protected traitRender;
14 }
15
16 /**
17 * The unique id of the Notice should be defined in the child class as a
18 * constant. This is used to identify the notice in the database and actions.
19 * @var string
20 */
21 public const IDENTIFIER = '';
22
23 /**
24 * The dismiss value in the REST endpoint's action parameter
25 * @var string
26 */
27 public const DISMISS_NOTICE_ACTION = 'dismiss';
28
29 /**
30 * The snooze value in the REST endpoint's action parameter
31 * @var string
32 */
33 public const SNOOZE_NOTICE_ACTION = 'snooze';
34
35 protected EnvironmentConfig $env;
36
37 public function __construct(EnvironmentConfig $env)
38 {
39 if (!defined('static::IDENTIFIER') || empty(static::IDENTIFIER)) {
40 throw new \InvalidArgumentException('The IDENTIFIER constant must be defined and not empty in the child class.');
41 }
42
43 $this->env = $env;
44 }
45
46 /**
47 * Get the unique identifier
48 */
49 public function getId(): string
50 {
51 return static::IDENTIFIER;
52 }
53
54 /**
55 * Returns whether the notice can be permanently dismissed
56 */
57 public function isDismissable(): bool
58 {
59 return true;
60 }
61
62 /**
63 * Returns whether the notice can be snoozed (remind me later)
64 */
65 public function isSnoozable(): bool
66 {
67 return false;
68 }
69
70 /**
71 * Returns the snooze duration in days
72 */
73 public function getSnoozeDays(): int
74 {
75 return 1;
76 }
77
78 /**
79 * Permanently dismiss the notice
80 */
81 final public function dismiss(): void
82 {
83 update_option('metricool_notice_' . $this->getId() . '_dismissed', true, false);
84 }
85
86 /**
87 * Snooze the notice for the configured number of days
88 */
89 final public function snooze(): void
90 {
91 $snoozedUntil = time() + ($this->getSnoozeDays() * DAY_IN_SECONDS);
92 update_option('metricool_notice_' . $this->getId() . '_snoozed_until', $snoozedUntil, false);
93 }
94
95 /**
96 * Check if the notice has been permanently dismissed
97 */
98 final public function isDismissed(): bool
99 {
100 return (bool) get_option('metricool_notice_' . $this->getId() . '_dismissed', false);
101 }
102
103 /**
104 * Check if the notice is currently snoozed
105 */
106 final public function isSnoozed(): bool
107 {
108 $snoozedUntil = (int) get_option('metricool_notice_' . $this->getId() . '_snoozed_until', 0);
109
110 if ($snoozedUntil === 0) {
111 return false;
112 }
113
114 return time() < $snoozedUntil;
115 }
116
117 /**
118 * Returns the URL for the call-to-action button, or empty string if none
119 */
120 public function getCtaUrl(): string
121 {
122 return '';
123 }
124
125 /**
126 * Returns the label for the call-to-action button, or empty string if none
127 */
128 public function getCtaLabel(): string
129 {
130 return '';
131 }
132
133 /**
134 * Render the notice
135 */
136 public function render(): void
137 {
138 $this->traitRender('admin/notices/layout', $this->viewData());
139 }
140
141 /**
142 * Get the data passed to the notice layout view
143 */
144 protected function viewData(): array
145 {
146 $restUrl = rest_url(
147 $this->env->getString('http.namespace')
148 . '/'
149 . $this->env->getString('http.version')
150 . '/admin-notices/'
151 . $this->getId()
152 );
153
154 return [
155 'noticeId' => $this->getId(),
156 'logoUrl' => $this->env->getUrl('plugin.assets_url') . 'img/mc-logo.svg',
157 'restUrl' => $restUrl,
158 'isDismissable' => $this->isDismissable(),
159 'isSnoozable' => $this->isSnoozable(),
160 'ctaUrl' => $this->getCtaUrl(),
161 'ctaLabel' => $this->getCtaLabel(),
162 'nonce' => wp_create_nonce('metricool_nonce'),
163 'wpNonce' => wp_create_nonce('wp_rest'),
164 'content' => $this->view($this->getContentView(), $this->getContentVariables()),
165 ];
166 }
167
168 /**
169 * Returns whether the notice should be displayed
170 */
171 final public function shouldDisplay(): bool
172 {
173 return $this->canDisplay() && !$this->isDismissed() && !$this->isSnoozed();
174 }
175
176 /**
177 * Notice-specific display conditions, use this to check for things like
178 * required capabilities, specific admin pages, etc.
179 */
180 abstract protected function canDisplay(): bool;
181
182 /**
183 * Returns the view path for the inner content of the notice
184 */
185 abstract protected function getContentView(): string;
186
187 /**
188 * Returns the variables passed to the content view
189 */
190 abstract protected function getContentVariables(): array;
191 }
192