Completed
Push — update/nested-upgrade-nudges ( e1e842...baea19 )
by
unknown
132:36 queued 123:22
created

Pre_Connection_JITM   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 159
rs 10
c 0
b 0
f 0
wmc 18
lcom 1
cbo 2

5 Methods

Rating   Name   Duplication   Size   Complexity  
A filter_messages() 0 42 3
A validate_messages() 0 16 4
A get_message_icon() 0 17 3
B get_messages() 0 27 7
A dismiss() 0 4 1
1
<?php
2
/**
3
 * Jetpack's Pre-Connection JITM class.
4
 *
5
 * @package automattic/jetpack-jitm
6
 */
7
8
namespace Automattic\Jetpack\JITMS;
9
10
/**
11
 * Jetpack pre-connection just in time messaging through out the admin.
12
 */
13
class Pre_Connection_JITM extends JITM {
14
15
	/**
16
	 * Filters and formats the messages for the client-side JS renderer
17
	 *
18
	 * @param string $message_path Current message path.
19
	 *
20
	 * @return array Formatted messages.
21
	 */
22
	private function filter_messages( $message_path ) {
23
		/**
24
		 * Allows filtering of the pre-connection JITMs.
25
		 *
26
		 * This filter allows plugins to add pre-connection JITMs that will be
27
		 * displayed by the JITM package.
28
		 *
29
		 * @since 9.6.0
30
		 *
31
		 * @param array An array of pre-connection messages.
32
		 */
33
		$messages = apply_filters( 'jetpack_pre_connection_jitms', array() );
34
35
		$messages = $this->validate_messages( $messages );
36
37
		$formatted_messages = array();
38
39
		foreach ( $messages as $message ) {
40
			if ( ! preg_match( $message['message_path'], $message_path ) ) {
41
				continue;
42
			}
43
44
			$obj                 = new \stdClass();
45
			$obj->CTA            = array( // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
46
				'message'   => $message['button_caption'],
47
				'newWindow' => false,
48
			);
49
			$obj->url            = $message['button_link'];
50
			$obj->id             = $message['id'];
51
			$obj->is_dismissible = true;
52
			$obj->content        = array(
53
				'message'     => $message['message'],
54
				'description' => $message['description'],
55
				'list'        => array(),
56
				'icon'        => $this->get_message_icon( $message ),
57
			);
58
59
			$formatted_messages[] = $obj;
60
		}
61
62
		return $formatted_messages;
63
	}
64
65
	/**
66
	 * Validates that each of the messages contains all of the required keys:
67
	 *   - id
68
	 *   - message_path
69
	 *   - message
70
	 *   - description
71
	 *   - button_link
72
	 *   - button_caption
73
	 *
74
	 * @param array $messages An array of JITM messages.
75
	 *
76
	 * @return array An array of JITM messages that contain all of the required keys.
77
	 */
78
	private function validate_messages( $messages ) {
79
		if ( ! is_array( $messages ) ) {
80
			return array();
81
		}
82
83
		$expected_keys = array_flip( array( 'id', 'message_path', 'message', 'description', 'button_link', 'button_caption' ) );
84
85
		foreach ( $messages as $index => $message ) {
86
			if ( count( array_intersect_key( $expected_keys, $message ) ) !== count( $expected_keys ) ) {
87
				// Remove any messages that are missing expected keys.
88
				unset( $messages[ $index ] );
89
			}
90
		}
91
92
		return $messages;
93
	}
94
95
	/**
96
	 * Get the icon for the message.
97
	 *
98
	 * The message may contain an 'icon' key. If the value of the 'icon' key matches a supported icon (or empty string), the value is used.
99
	 * If the message does not contain an icon key or if the value does not match a supported icon, the Jetpack icon is used by default.
100
	 *
101
	 * @param array $message A pre-connection JITM.
102
	 *
103
	 * @return string The icon to use in the JITM.
104
	 */
105
	private function get_message_icon( $message ) {
106
		// Default to the Jetpack icon.
107
		$icon = 'jetpack';
108
109
		if ( ! isset( $message['icon'] ) ) {
110
			return $icon;
111
		}
112
113
		$supported_icons = $this->get_supported_icons();
114
115
		if ( in_array( $message['icon'], $supported_icons, true ) ) {
116
			// Only use the message icon if it's a supported icon or an empty string (for no icon).
117
			$icon = $message['icon'];
118
		}
119
120
		return $icon;
121
	}
122
123
	/**
124
	 * Retrieve the current message to display keyed on query string and message path
125
	 *
126
	 * @param string $message_path The message path to ask for.
127
	 * @param string $query The query string originally from the front end. Unused in this subclass.
128
	 * @param bool   $full_jp_logo_exists If there is a full Jetpack logo already on the page.
129
	 *
130
	 * @return array The JITMs to show, or an empty array if there is nothing to show
131
	 */
132
	public function get_messages( $message_path, $query, $full_jp_logo_exists ) {
133
		if ( ! current_user_can( 'install_plugins' ) ) {
134
			return array();
135
		}
136
137
		$messages = $this->filter_messages( $message_path );
138
139
		if ( empty( $messages ) ) {
140
			return array();
141
		}
142
143
		$hidden_jitms = \Jetpack_Options::get_option( 'hide_jitm' );
144
145
		foreach ( $messages as $idx => &$envelope ) {
146
			$dismissed_feature = isset( $hidden_jitms[ 'pre-connection-' . $envelope->id ] ) &&
147
				is_array( $hidden_jitms[ 'pre-connection-' . $envelope->id ] ) ? $hidden_jitms[ 'pre-connection-' . $envelope->id ] : null;
148
149
			if ( is_array( $dismissed_feature ) ) {
150
				unset( $messages[ $idx ] );
151
				continue;
152
			}
153
154
			$envelope->content['icon'] = $this->generate_icon( $envelope->content['icon'], $full_jp_logo_exists );
155
		}
156
157
		return $messages;
158
	}
159
160
	/**
161
	 * Dismisses a JITM ID so that it will no longer be shown.
162
	 *
163
	 * @param string $id The id of the JITM that was dismissed.
164
	 *
165
	 * @return bool Always true
166
	 */
167
	public function dismiss( $id ) {
168
		$this->save_dismiss( 'pre-connection-' . $id );
169
		return true;
170
	}
171
}
172