env = $env; } /** * Get the unique identifier */ public function getId(): string { return static::IDENTIFIER; } /** * Returns whether the notice can be permanently dismissed */ public function isDismissable(): bool { return true; } /** * Returns whether the notice can be snoozed (remind me later) */ public function isSnoozable(): bool { return false; } /** * Returns the snooze duration in days */ public function getSnoozeDays(): int { return 1; } /** * Permanently dismiss the notice */ final public function dismiss(): void { update_option('metricool_notice_' . $this->getId() . '_dismissed', true, false); } /** * Snooze the notice for the configured number of days */ final public function snooze(): void { $snoozedUntil = time() + ($this->getSnoozeDays() * DAY_IN_SECONDS); update_option('metricool_notice_' . $this->getId() . '_snoozed_until', $snoozedUntil, false); } /** * Check if the notice has been permanently dismissed */ final public function isDismissed(): bool { return (bool) get_option('metricool_notice_' . $this->getId() . '_dismissed', false); } /** * Check if the notice is currently snoozed */ final public function isSnoozed(): bool { $snoozedUntil = (int) get_option('metricool_notice_' . $this->getId() . '_snoozed_until', 0); if ($snoozedUntil === 0) { return false; } return time() < $snoozedUntil; } /** * Returns the URL for the call-to-action button, or empty string if none */ public function getCtaUrl(): string { return ''; } /** * Returns the label for the call-to-action button, or empty string if none */ public function getCtaLabel(): string { return ''; } /** * Render the notice */ public function render(): void { $this->traitRender('admin/notices/layout', $this->viewData()); } /** * Get the data passed to the notice layout view */ protected function viewData(): array { $restUrl = rest_url( $this->env->getString('http.namespace') . '/' . $this->env->getString('http.version') . '/admin-notices/' . $this->getId() ); return [ 'noticeId' => $this->getId(), 'logoUrl' => $this->env->getUrl('plugin.assets_url') . 'img/mc-logo.svg', 'restUrl' => $restUrl, 'isDismissable' => $this->isDismissable(), 'isSnoozable' => $this->isSnoozable(), 'ctaUrl' => $this->getCtaUrl(), 'ctaLabel' => $this->getCtaLabel(), 'nonce' => wp_create_nonce('metricool_nonce'), 'wpNonce' => wp_create_nonce('wp_rest'), 'content' => $this->view($this->getContentView(), $this->getContentVariables()), ]; } /** * Returns whether the notice should be displayed */ final public function shouldDisplay(): bool { return $this->canDisplay() && !$this->isDismissed() && !$this->isSnoozed(); } /** * Notice-specific display conditions, use this to check for things like * required capabilities, specific admin pages, etc. */ abstract protected function canDisplay(): bool; /** * Returns the view path for the inner content of the notice */ abstract protected function getContentView(): string; /** * Returns the variables passed to the content view */ abstract protected function getContentVariables(): array; }