Completed
Push — try/publicize-gutenberg-block-... ( 833468 )
by Bernhard
07:09
created

Jetpack_Publicize_Gutenberg::post_page_enqueue()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 2
nop 1
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
1
<?php
2
/**
3
 * Does setup for Publicize in Gutenberg
4
 *
5
 * Enqueues UI resources and completes REST setup for enabling
6
 * Publicize in Gutenberg.
7
 *
8
 * @package Jetpack
9
 * @subpackage Publicize
10
 * @since 5.9.1
11
 */
12
13
/**
14
 * Class to set up Gutenberg editor support.
15
 *
16
 * @since 5.9.1
17
 */
18
class Jetpack_Publicize_Gutenberg {
19
20
	/**
21
	 * Instance of Publicize used to access data gathering utility methods.
22
	 *
23
	 * @since 5.9.1
24
	 * @var Publicize $publicize Instance of Jetpack Publicize class.
25
	 */
26
	private $publicize;
27
28
	/**
29
	 * Constructor for Jetpack_Publicize_Gutenberg
30
	 *
31
	 * Set up hooks to extend legacy Publicize behavior.
32
	 *
33
	 * @since 5.9.1
34
	 */
35
	public function __construct( $publicize ) {
36
		// Do edit page specific setup.
37
		add_action( 'admin_enqueue_scripts', array( $this, 'post_page_enqueue' ) );
38
39
		add_action( 'rest_api_init', array( $this, 'add_publicize_rest_fields' ) );
40
41
		// Set up publicize flags right before post is actually published.
42
		add_filter( 'rest_pre_insert_post', array( $this, 'process_publicize_from_rest' ), 10, 2 );
43
44
		$this->publicize = $publicize;
45
	}
46
47
	/**
48
	 * Retrieve current list of connected social accounts.
49
	 *
50
	 * Gets current list of connected accounts and send them as
51
	 * JSON encoded data.
52
	 *
53
	 * @see Publicize::get_filtered_connection_data()
54
	 *
55
	 * @since 5.9.1
56
	 *
57
	 * @param WP_REST_Request $request Request instance from REST call.
58
	 *
59
	 * @return string JSON encoded connection list data.
60
	 */
61
	public function rest_get_publicize_connections( $request ) {
62
		$post_id = $request['post_id'];
63
		return wp_json_encode( $this->publicize->get_filtered_connection_data( $post_id ) );
64
	}
65
66
	/**
67
	 * Add rest field to 'post' for Publicize support
68
	 *
69
	 * Sets up 'publicize' schema to submit publicize sharing title
70
	 * and individual connection sharing enables/disables. This schema
71
	 * is registered with the 'post' endpoint REST endpoint so publicize
72
	 * options can be saved when a post is published.
73
	 *
74
	 * @since 5.9.1
75
	 */
76
	public function add_publicize_rest_fields() {
77
		// Schema for wpas.submit[] field.
78
		$publicize_submit_schema = array(
79
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
80
			'title'      => esc_html__( 'Publicize data for publishing post', 'jetpack' ),
81
			'type'       => 'object',
82
			'properties' => array(
83
				'connections' => array(
84
					'description' => esc_html__( 'List of connections to be shared to (or not).', 'jetpack' ),
85
					'type'        => 'array',
86
					'items'       => array(
87
						'type'       => 'object',
88
						'properties' => array(
89
							'unique_id'    => array(
90
								'description' => esc_html__( 'Unique identifier string for a connection', 'jetpack' ),
91
								'type'        => 'string',
92
							),
93
							'should_share' => array(
94
								'description' => esc_html__( 'Whether or not connection should be shared to.', 'jetpack' ),
95
								'type'        => 'boolean',
96
							),
97
98
						),
99
					),
100
				),
101
				'title'       => array(
102
					'description' => esc_html__( 'Optional title to share post with.', 'jetpack' ),
103
					'type'        => 'string',
104
				),
105
			),
106
		);
107
108
		// Registering the publicize field with post endpoint.
109
		register_rest_field(
110
			'post',
111
			'publicize',
112
			array(
113
				'get_callback'    => null,
114
				'update_callback' => null, // Data read/processed before publishing post by 'rest_pre_insert_post' filter.
115
				'schema'          => $publicize_submit_schema,
116
			)
117
		);
118
119
		/**
120
		 * REST endpoint to get connection list data for current user and post id.
121
		 *
122
		 * @see Publicize::get_filtered_connection_data()
123
		 *
124
		 * @since 5.9.1
125
		 */
126
		register_rest_route( 'publicize/', '/posts/(?P<post_id>\d+)/connections', array(
127
			'methods'             => 'GET',
128
			'callback'            => array( $this, 'rest_get_publicize_connections' ),
129
			'post_id'             => array(
130
				'validate_post_id' => array( $this, 'rest_connections_validate_post_id' ),
131
			),
132
			'permission_callback' => array( $this, 'rest_connections_permission_callback' ),
133
		) );
134
	}
135
136
	/**
137
	 * Check user capability for getting Publicize connection list from endpoint.
138
	 *
139
	 * @since 5.9.1
140
	 *
141
	 * @return boolean True if current user has 'publish_post' capability.
142
	 */
143
	public function rest_connections_permission_callback() {
144
		return current_user_can( 'publish_posts' );
145
	}
146
147
	/**
148
	 * Check post id validity for Publicize connection list REST endpoint.
149
	 *
150
	 * @since 5.9.1
151
	 *
152
	 * @param mixed $param post_id parameter from REST call.
153
	 *
154
	 * @return boolean True if post_id is valid integer
155
	 */
156
	public function rest_connections_validate_post_id( $param ) {
157
		return is_int( $param );
158
	}
159
160
	/**
161
	 * Set up Publicize meta fields for publishing post.
162
	 *
163
	 * Process 'publicize' REST field to setup Publicize for publishing
164
	 * post. Sets post meta keys to enable/disable each connection for
165
	 * the post and sets publicize title meta key if a title message
166
	 * is provided.
167
	 *
168
	 * @since 5.9.1
169
	 *
170
	 * @param stdClass        $new_post_obj Updated post object about to be inserted view REST endpoint.
171
	 * @param WP_REST_Request $request      Request object, possibly containing 'publicize' field {@see add_publicize_rest_fields()}.
172
	 *
173
	 * @return WP_Post Returns the original $new_post value unchanged.
174
	 */
175
	public function process_publicize_from_rest( $new_post_obj, $request ) {
176
		global $publicize;
177
		if ( property_exists( $new_post_obj, 'ID' ) ) {
178
			$post = get_post( $new_post_obj->ID );
179
		} else {
180
			return $new_post_obj;
181
		}
182
183
		// If 'publicize' field has been set from editor and post is about to be published.
184
		if ( isset( $request['publicize'] )
185
				&& ( property_exists( $new_post_obj, 'post_status' ) && ( 'publish' === $new_post_obj->post_status ) )
186
				&& ( 'publish' !== $post->post_status ) ) {
187
188
			$publicize_field = $request['publicize'];
189
190 View Code Duplication
			if ( empty( $publicize_field['title'] ) ) {
191
				delete_post_meta( $post->ID, $publicize->POST_MESS );
192
			} else {
193
				update_post_meta( $post->ID, $publicize->POST_MESS, trim( stripslashes( $publicize_field['title'] ) ) );
194
			}
195
			if ( isset( $publicize_field['connections'] ) ) {
196
				foreach ( (array) $publicize->get_services( 'connected' ) as $service_name => $connections ) {
197
					foreach ( $connections as $connection ) {
198 View Code Duplication
						if ( ! empty( $connection->unique_id ) ) {
199
							$unique_id = $connection->unique_id;
200
						} elseif ( ! empty( $connection['connection_data']['token_id'] ) ) {
201
							$unique_id = $connection['connection_data']['token_id'];
202
						}
203
204
						if ( $this->connection_should_share( $publicize_field['connections'], $unique_id ) ) {
205
							// Delete skip flag meta key.
206
							delete_post_meta( $post->ID, $publicize->POST_SKIP . $unique_id );
0 ignored issues
show
Bug introduced by
The variable $unique_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
207
						} else {
208
							// Flag connection to be skipped for this post.
209
							update_post_meta( $post->ID, $publicize->POST_SKIP . $unique_id, 1 );
210
						}
211
					}
212
				}
213
			}
214
		}
215
		// Just pass post object through.
216
		return $new_post_obj;
217
	}
218
219
	/**
220
	 * Checks if a connection should be shared to.
221
	 *
222
	 * Checks $connection_id against $connections_array to see if the connection associated
223
	 * with $connection_id should be shared to. Will return true if $connection_id is in the
224
	 * array and 'should_share' property is set to true, and will default to false otherwise.
225
	 *
226
	 * @since 5.9.1
227
	 *
228
	 * @param array  $connections_array 'connections' from 'publicize' REST field {@see add_publicize_rest_fields()}.
229
	 * @param string $connection_id     Connection identifier string that is unique for each connection.
230
	 * @return boolean True if connection should be shared to, false otherwise.
231
	 */
232
	private function connection_should_share( $connections_array, $connection_id ) {
233
		foreach ( $connections_array as $connection ) {
234
			if ( isset( $connection['unique_id'] )
235
				&& ( $connection['unique_id'] === $connection_id )
236
				&& $connection['should_share'] ) {
237
				return true;
238
			}
239
		}
240
		return false;
241
	}
242
243
	/**
244
	 * Enqueue scripts when they are needed for the edit page
245
	 *
246
	 * Enqueues necessary scripts for edit page for Gutenberg
247
	 * editor only.
248
	 *
249
	 * @since 5.9.1
250
	 *
251
	 * @param string $hook Current page url.
252
	 */
253
	public function post_page_enqueue( $hook ) {
254
		if ( ( 'post-new.php' === $hook || 'post.php' === $hook ) && ! isset( $_GET['classic-editor'] ) ) { // Input var okay.
255
			wp_enqueue_style( 'social-logos', null, array( 'genericons' ) );
256
257
			wp_localize_script( 'jetpack-blocks-editor',
258
				array(
259
					'staticConnectionList' => wp_json_encode( $this->publicize->get_filtered_connection_data() ),
260
					'allServices'          => wp_json_encode( $this->publicize->get_available_service_data() ),
261
					'api_nonce'            => wp_create_nonce( 'wp_rest' ),
262
				)
263
			);
264
265
		}
266
	}
267
}
268