PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 All 256 releases
give / vendor / vendor-prefixed / stellarwp / admin-notices / src / AdminNotices.php

AdminNotices.php in GiveWP – Donation Plugin and Fundraising Platform 4.17.0, at vendor/vendor-prefixed/stellarwp/admin-notices/src/AdminNotices.php

254 lines 7.4 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 Give\Vendors\StellarWP\AdminNotices;
6
7 use Psr\Container\ContainerInterface;
8 use RuntimeException;
9 use Give\Vendors\StellarWP\AdminNotices\Actions\DisplayNoticesInAdmin;
10 use Give\Vendors\StellarWP\AdminNotices\Actions\EnqueueNoticesScriptsAndStyles;
11 use Give\Vendors\StellarWP\AdminNotices\Contracts\NotificationsRegistrarInterface;
12
13 class AdminNotices
14 {
15 /**
16 * @var ContainerInterface|null
17 */
18 protected static $container;
19
20 /**
21 * @var NotificationsRegistrarInterface|null
22 */
23 protected static $registrar;
24
25 /**
26 * @var string used in actions, filters, and data storage
27 */
28 protected static $namespace;
29
30 /**
31 * @var string the URL to the package, used for enqueuing scripts
32 */
33 protected static $packageUrl;
34
35 /**
36 * Registers a notice to be conditionally displayed in the admin
37 *
38 * @since 1.0.0
39 * @since 1.1.0 no longer include namespace in AdminNotice id
40 *
41 * @param string|callable $render
42 */
43 public static function show(string $notificationId, $render): AdminNotice
44 {
45 $notice = new AdminNotice($notificationId, $render);
46
47 self::getRegistrar()->registerNotice($notice);
48
49 return $notice;
50 }
51
52 /**
53 * Renders the notice in the current location while still honoring visibility conditions
54 *
55 * @since 2.0.0 mark notice as inPlace to prevent movement; return null if not being rendered
56 * @since 1.0.0
57 *
58 * @param bool $echo whether to echo or return the notice
59 *
60 * @return string|null
61 */
62 public static function render(AdminNotice $notice, bool $echo = true): ?string
63 {
64 ob_start();
65 (new DisplayNoticesInAdmin(self::$namespace))($notice->inPlace());
66 $output = ob_get_clean();
67
68 if ($echo) {
69 echo $output;
70
71 return null;
72 } else {
73 return $output ?: null;
74 }
75 }
76
77 /**
78 * Removes a registered notice so it will no longer be shown
79 *
80 * @since 1.0.0
81 */
82 public static function removeNotice(string $notificationId): void
83 {
84 self::getRegistrar()->unregisterNotice($notificationId);
85 }
86
87 /**
88 * Sets the container with the register stored to be used for storing notices
89 *
90 * @since 1.0.0
91 */
92 public static function setContainer(ContainerInterface $container): void
93 {
94 self::$container = $container;
95 self::$registrar = null;
96 }
97
98 /**
99 * Removes the container so the register will be stored locally
100 *
101 * @since 1.0.0
102 */
103 public static function removeContainer(): void
104 {
105 self::$container = null;
106 self::$registrar = null;
107 }
108
109 /**
110 * Initializes the package. Required to be called to display the notices.
111 *
112 * This should be called at the beginning of the plugin file along with other configuration.
113 *
114 * @since 1.1.0 added namespace validation
115 * @since 1.0.0
116 */
117 public static function initialize(string $namespace, string $pluginUrl): void
118 {
119 if (empty($namespace)) {
120 throw new RuntimeException('Namespace must be provided');
121 } elseif (preg_match('/[^a-zA-Z0-9_-]/', $namespace)) {
122 throw new RuntimeException('Namespace must only contain letters, numbers, hyphens, and underscores');
123 }
124
125 self::$packageUrl = $pluginUrl;
126 self::$namespace = $namespace;
127
128 add_action('admin_notices', [self::class, 'setUpNotices']);
129 add_action('admin_enqueue_scripts', [self::class, 'enqueueScripts']);
130 }
131
132 /**
133 * Returns the notices stored in the register
134 *
135 * @since 1.0.0
136 *
137 * @return AdminNotice[]
138 */
139 public static function getNotices(): array
140 {
141 return self::getRegistrar()->getNotices();
142 }
143
144 /**
145 * Rests a dismissed notice for a given user so the notice will be shown again
146 *
147 * @since 1.1.0 uses namespacing
148 * @since 1.0.0
149 */
150 public static function resetNoticeForUser(string $notificationId, int $userId): void
151 {
152 global $wpdb;
153
154 $preferencesKey = $wpdb->get_blog_prefix() . 'persisted_preferences';
155 $preferences = get_user_meta($userId, $preferencesKey, true);
156 $packageKey = 'stellarwp/admin-notices/' . self::$namespace;
157
158 if (isset($preferences[$packageKey][$notificationId])) {
159 unset($preferences[$packageKey][$notificationId]);
160 update_user_meta($userId, $preferencesKey, $preferences);
161 }
162 }
163
164 /**
165 * Resets all dismissed notices for a given user so all notices will be shown again
166 *
167 * @since 1.1.0 uses namespacing and simplified the method
168 * @since 1.0.0
169 */
170 public static function resetAllNoticesForUser(int $userId): void
171 {
172 global $wpdb;
173
174 $preferencesKey = $wpdb->get_blog_prefix() . 'persisted_preferences';
175 $preferences = get_user_meta($userId, $preferencesKey, true);
176 $packageKey = 'stellarwp/admin-notices/' . self::$namespace;
177
178 if (isset($preferences[$packageKey])) {
179 unset($preferences[$packageKey]);
180 update_user_meta($userId, $preferencesKey, $preferences);
181 }
182 }
183
184 /**
185 * Hook action to display the notices in the admin
186 *
187 * @since 1.1.0 passes the namespace to the display notices class
188 * @since 1.0.0
189 */
190 public static function setUpNotices(): void
191 {
192 (new DisplayNoticesInAdmin(self::$namespace))(...self::getNotices());
193 }
194
195 /**
196 * Hook action to enqueue the scripts needed for dismissing notices
197 *
198 * @since 1.1.0 added the namespacing attribute to the script tag
199 * @since 1.0.2 use filetime for versioning, which will bust the cache when the library is updated
200 * @since 1.0.0
201 */
202 public static function enqueueScripts(): void
203 {
204 $namespace = self::$namespace;
205 $handle = "stellarwp-$namespace-admin-notices";
206 $version = filemtime(__DIR__ . '/resources/admin-notices.js');
207
208 // Add the namespace to the script tag
209 add_filter('script_loader_tag', static function ($tag, $tagHandle) use ($handle, $namespace) {
210 if ($handle !== $tagHandle) {
211 return $tag;
212 }
213
214 $replacement = "<script data-stellarwp-namespace='$namespace'";
215
216 return str_replace('<script', $replacement, $tag);
217 }, 10, 2);
218
219 wp_enqueue_script(
220 $handle,
221 self::$packageUrl . '/src/resources/admin-notices.js',
222 ['jquery', 'wp-data', 'wp-preferences'],
223 $version,
224 ['strategy' => 'defer']
225 );
226
227 (new EnqueueNoticesScriptsAndStyles($namespace))(...self::getNotices());
228 }
229
230 /**
231 * Returns the registrar instance, from the container if available, otherwise a locally stored instance
232 *
233 * @since 1.0.0
234 */
235 private static function getRegistrar(): NotificationsRegistrarInterface
236 {
237 if (self::$registrar !== null) {
238 return self::$registrar;
239 }
240
241 if (self::$container && !self::$container->has(NotificationsRegistrarInterface::class)) {
242 throw new RuntimeException('NotificationsRegistrarInterface not found in container');
243 }
244
245 if (self::$container) {
246 self::$registrar = self::$container->get(NotificationsRegistrarInterface::class);
247 } else {
248 self::$registrar = new NotificationsRegistrar();
249 }
250
251 return self::$registrar;
252 }
253 }
254