PluginProbe
Metricool – Social media and site statistics / trunk
Metricool – Social media and site statistics vtrunk
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 trunk, 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 * Notice-specific display conditions, use this to check for things like
48 * required capabilities, specific admin pages, etc.
49 */
50 abstract protected function canDisplay(): bool;
51
52 /**
53 * Returns the view path for the inner content of the notice
54 */
55 abstract protected function getContentView(): string;
56
57 /**
58 * Returns the variables passed to the content view
59 */
60 abstract protected function getContentVariables(): array;
61
62 /**
63 * Returns whether the notice can be permanently dismissed
64 */
65 public function isDismissable(): bool
66 {
67 return true;
68 }
69
70 /**
71 * Returns whether the notice can be snoozed (remind me later)
72 */
73 public function isSnoozable(): bool
74 {
75 return false;
76 }
77
78 /**
79 * Returns the snooze duration in days
80 */
81 public function getSnoozeDays(): int
82 {
83 return 1;
84 }
85
86 /**
87 * Returns the URL for the call-to-action button, or empty string if none
88 */
89 public function getCtaUrl(): string
90 {
91 return '';
92 }
93
94 /**
95 * Returns the label for the call-to-action button, or empty string if none
96 */
97 public function getCtaLabel(): string
98 {
99 return '';
100 }
101
102 /**
103 * Render the notice
104 */
105 public function render(): void
106 {
107 $this->traitRender('admin/notices/layout', $this->viewData());
108 }
109
110 /**
111 * Get the unique identifier
112 */
113 final public function getId(): string
114 {
115 return static::IDENTIFIER;
116 }
117
118 /**
119 * Returns whether the notice should be displayed
120 */
121 final public function shouldDisplay(): bool
122 {
123 return $this->canDisplay() && !$this->isDismissed() && !$this->isSnoozed();
124 }
125
126 /**
127 * Snooze the notice for the configured number of days
128 */
129 final public function snooze(): void
130 {
131 $snoozedUntil = time() + ($this->getSnoozeDays() * DAY_IN_SECONDS);
132 update_option('metricool_notice_' . $this->getId() . '_snoozed_until', $snoozedUntil, false);
133 }
134
135 /**
136 * Check if the notice has been permanently dismissed
137 */
138 final public function isDismissed(): bool
139 {
140 return (bool) get_option('metricool_notice_' . $this->getId() . '_dismissed', false);
141 }
142
143 /**
144 * Check if the notice is currently snoozed
145 */
146 final public function isSnoozed(): bool
147 {
148 $snoozedUntil = (int) get_option('metricool_notice_' . $this->getId() . '_snoozed_until', 0);
149
150 if ($snoozedUntil === 0) {
151 return false;
152 }
153
154 return time() < $snoozedUntil;
155 }
156
157 /**
158 * Permanently dismiss the notice
159 */
160 final public function dismiss(): void
161 {
162 update_option('metricool_notice_' . $this->getId() . '_dismissed', true, false);
163 }
164
165 /**
166 * Get the data passed to the notice layout view
167 */
168 protected function viewData(): array
169 {
170 $restUrl = rest_url(
171 $this->env->getString('http.namespace')
172 . '/'
173 . $this->env->getString('http.version')
174 . '/admin-notices/'
175 . $this->getId()
176 );
177
178 return [
179 'noticeId' => $this->getId(),
180 'logoUrl' => $this->env->getUrl('plugin.assets_url') . 'img/mc-logo.svg',
181 'restUrl' => $restUrl,
182 'isDismissable' => $this->isDismissable(),
183 'isSnoozable' => $this->isSnoozable(),
184 'ctaUrl' => $this->getCtaUrl(),
185 'ctaLabel' => $this->getCtaLabel(),
186 'nonce' => wp_create_nonce('metricool_nonce'),
187 'wpNonce' => wp_create_nonce('wp_rest'),
188 'content' => $this->view($this->getContentView(), $this->getContentVariables()),
189 ];
190 }
191 }
192