WPFORMS_PLUGIN_URL . 'assets/lib/lity/lity.min.js',
* Output notifications on Form Overview admin area.
public function output() {
// Leave early if there are no forms.
if ( ! wpforms()->obj( 'form' )->forms_exist() ) {
$notifications = $this->get();
if ( empty( $notifications ) ) {
$notifications_html = '';
$current_class = ' current';
$content_allowed_tags = $this->get_allowed_tags();
foreach ( $notifications as $notification ) {
// Prepare required arguments.
$notification = wp_parse_args(
$title = $this->get_component_data( $notification['title'] );
$content = $this->get_component_data( $notification['content'] );
if ( ! $title && ! $content ) {
$notifications_html .= sprintf(
'<div class="wpforms-notifications-message%5$s" data-message-id="%4$s">
<h3 class="wpforms-notifications-title">%1$s%6$s</h3>
<div class="wpforms-notifications-content">%2$s</div>
wp_kses( wpautop( $content ), $content_allowed_tags ),
$this->get_notification_buttons_html( $notification ),
esc_attr( $notification['id'] ),
esc_attr( $current_class ),
$this->get_video_badge_html( $this->get_component_data( $notification['video'] ) )
// Only first notification is current.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'count' => count( $notifications ),
'html' => $notifications_html,
* Get the allowed HTML tags and their attributes.
public function get_allowed_tags(): array {
* Retrieve notification's buttons HTML.
* @param array $notification Notification data.
private function get_notification_buttons_html( $notification ) {
if ( empty( $notification['btns'] ) || ! is_array( $notification['btns'] ) ) {
foreach ( $notification['btns'] as $btn_type => $btn ) {
$btn = $this->get_component_data( $btn );
$url = $this->prepare_btn_url( $btn );
$target = ! empty( $btn['target'] ) ? $btn['target'] : '_blank';
$target = ! empty( $url ) && strpos( $url, home_url() ) === 0 ? '_self' : $target;
'<a href="%1$s" class="button button-%2$s"%3$s>%4$s</a>',
$btn_type === 'main' ? 'primary' : 'secondary',
$target === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '',
! empty( $btn['text'] ) ? esc_html( $btn['text'] ) : ''
return ! empty( $html ) ? sprintf( '<div class="wpforms-notifications-buttons">%s</div>', $html ) : '';
* Retrieve notification's component data by a license type.
* @param mixed $data Component data.
private function get_component_data( $data ) {
if ( empty( $data['license'] ) ) {
$license_type = $this->get_license_type();
if ( in_array( $license_type, self::LICENSES_ELITE, true ) ) {
return ! empty( $data['license'][ $license_type ] ) ? $data['license'][ $license_type ] : false;
* Retrieve the current installation license type (always lowercase).
private function get_license_type() {
if ( $this->license_type ) {
return $this->license_type;
$this->license_type = wpforms_get_license_type();
if ( ! $this->license_type ) {
$this->license_type = 'lite';
return $this->license_type;
* Dismiss notification via AJAX.
public function dismiss() {
// Check for required param, security and access.
! check_ajax_referer( 'wpforms-admin', 'nonce', false ) ||
$id = sanitize_key( $_POST['id'] );
$type = is_numeric( $id ) ? 'feed' : 'events';
$option = $this->get_option();
$option['dismissed'][] = $id;
$option['dismissed'] = array_unique( $option['dismissed'] );
if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
foreach ( $option[ $type ] as $key => $notification ) {
if ( (string) $notification['id'] === (string) $id ) {
unset( $option[ $type ][ $key ] );
update_option( 'wpforms_notifications', $option );
* @param array $btn Button data.
private function prepare_btn_url( $btn ) {
if ( empty( $btn['url'] ) ) {
'{admin_url}' => admin_url(),
'{license_key}' => wpforms_get_license_key(),
return str_replace( array_keys( $replace_tags ), array_values( $replace_tags ), $btn['url'] );
* Get the notification's video badge HTML.
* @param string $video_url Valid video URL.
private function get_video_badge_html( $video_url ) {
$video_url = wp_http_validate_url( $video_url );
if ( empty( $video_url ) ) {
$data_attr_lity = wp_is_mobile() ? '' : 'data-lity';
'<a class="wpforms-notifications-badge" href="%1$s" %2$s>
<svg fill="none" viewBox="0 0 15 13" aria-hidden="true">
<path fill="#fff" d="M4 2.5h7v8H4z"/>
<path fill="#D63638" d="M14.2 10.5v-8c0-.4-.2-.8-.5-1.1-.3-.3-.7-.5-1.1-.5H2.2c-.5 0-.8.2-1.1.5-.4.3-.5.7-.5 1.1v8c0 .4.2.8.5 1.1.3.3.6.5 1 .5h10.5c.4 0 .8-.2 1.1-.5.3-.3.5-.7.5-1.1Zm-8.8-.8V3.3l4.8 3.2-4.8 3.2Z"/>
esc_attr( $data_attr_lity ),
esc_html__( 'Watch Video', 'wpforms-lite' )