Completed
Push — update/videopress-gutenberg-up... ( d4746b )
by
unknown
07:52
created

render_video_block_with_videopress()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 10
nop 2
dl 0
loc 43
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Block Editor functionality for VideoPress users.
4
 *
5
 * @package Jetpack
6
 */
7
8
/**
9
 * Register a VideoPress extension to replace the default Core Video block.
10
 */
11
class VideoPress_Gutenberg {
12
13
	/**
14
	 * Singleton
15
	 */
16
	public static function init() {
17
		static $instance = false;
18
19
		if ( ! $instance ) {
20
			$instance = new VideoPress_Gutenberg();
21
		}
22
23
		return $instance;
24
	}
25
26
	/**
27
	 * VideoPress_Gutenberg constructor.
28
	 *
29
	 * Initialize the VideoPress Gutenberg extension
30
	 */
31
	private function __construct() {
32
		add_action( 'init', array( $this, 'register_video_block_with_videopress' ) );
33
		add_action( 'jetpack_register_gutenberg_extensions', array( $this, 'set_extension_availability' ) );
34
		add_action( 'enqueue_block_editor_assets', array( $this, 'override_video_upload' ) );
35
	}
36
37
	/**
38
	 * Used to check whether VideoPress is enabled for given site.
39
	 *
40
	 * @todo Create a global `jetpack_check_module_availability( $module )` helper so we can re-use it on other modules.
41
	 *       This global helper should be created in a file synced with WordPress.com so we can use it there too.
42
	 * @see https://github.com/Automattic/jetpack/pull/11321#discussion_r255477815
43
	 *
44
	 * @return array Associative array indicating if the module is available (key `available`) and the reason why it is
45
	 * unavailable (key `unavailable_reason`)
46
	 */
47
	public function check_videopress_availability() {
48
		// It is available on Simple Sites having the appropriate a plan.
49
		if (
50
			defined( 'IS_WPCOM' ) && IS_WPCOM
51
			&& method_exists( 'Store_Product_List', 'get_site_specific_features_data' )
52
		) {
53
			$features = Store_Product_List::get_site_specific_features_data();
54
			if ( in_array( 'videopress', $features['active'], true ) ) {
55
				return array( 'available' => true );
56
			} else {
57
				return array(
58
					'available'          => false,
59
					'unavailable_reason' => 'missing_plan',
60
				);
61
			}
62
		}
63
64
		// It is available on Jetpack Sites having the module active.
65
		if (
66
			method_exists( 'Jetpack', 'is_active' ) && Jetpack::is_active()
67
			&& method_exists( 'Jetpack', 'is_module_active' )
68
			&& method_exists( 'Jetpack_Plan', 'supports' )
69
		) {
70
			if ( Jetpack::is_module_active( 'videopress' ) ) {
71
				return array( 'available' => true );
72
			} elseif ( ! Jetpack_Plan::supports( 'videopress' ) ) {
73
				return array(
74
					'available'          => false,
75
					'unavailable_reason' => 'missing_plan',
76
				);
77
			} else {
78
				return array(
79
					'available'          => false,
80
					'unavailable_reason' => 'missing_module',
81
				);
82
			}
83
		}
84
85
		return array(
86
			'available'          => false,
87
			'unavailable_reason' => 'unknown',
88
		);
89
	}
90
91
	/**
92
	 * Set the Jetpack Gutenberg extension availability.
93
	 */
94
	public function set_extension_availability() {
95
		$availability = $this->check_videopress_availability();
96
		if ( $availability['available'] ) {
97
			Jetpack_Gutenberg::set_extension_available( 'jetpack/videopress' );
98
		} else {
99
			Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/videopress', $availability['unavailable_reason'] );
0 ignored issues
show
Bug introduced by
It seems like $availability['unavailable_reason'] can also be of type boolean; however, Jetpack_Gutenberg::set_extension_unavailable() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
100
		}
101
	}
102
103
	/**
104
	 * Register the core video block as a dynamic block.
105
	 *
106
	 * It defines a server-side rendering that adds VideoPress support to the core video block.
107
	 */
108
	public function register_video_block_with_videopress() {
109
		jetpack_register_block(
110
			'core/video',
111
			array(
112
				'render_callback' => array( $this, 'render_video_block_with_videopress' ),
113
			)
114
		);
115
	}
116
117
	/**
118
	 * Render the core video block replacing the src attribute with the VideoPress URL
119
	 *
120
	 * @param array  $attributes Array containing the video block attributes.
121
	 * @param string $content    String containing the video block content.
122
	 *
123
	 * @return string
124
	 */
125
	public function render_video_block_with_videopress( $attributes, $content ) {
126
		if ( ! isset( $attributes['id'] ) || isset( $attributes['guid'] ) ) {
127
			return $content;
128
		}
129
130
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
131
			$blog_id = get_current_blog_id();
132
		} elseif ( method_exists( 'Jetpack', 'is_active' ) && Jetpack::is_active() ) {
133
			/**
134
			 * We're intentionally not using `get_current_blog_id` because it was returning unexpected values.
135
			 *
136
			 * @see https://github.com/Automattic/jetpack/pull/11193#issuecomment-457883886
137
			 * @see https://github.com/Automattic/jetpack/pull/11193/commits/215cf789f3d8bd03ff9eb1bbdb693acb8831d273
138
			 */
139
			$blog_id = Jetpack_Options::get_option( 'id' );
140
		}
141
142
		if ( ! isset( $blog_id ) ) {
143
			return $content;
144
		}
145
146
		$post_id         = absint( $attributes['id'] );
147
		$videopress_id   = video_get_info_by_blogpostid( $blog_id, $post_id )->guid;
148
		$videopress_data = videopress_get_video_details( $videopress_id );
149
150
		if ( empty( $videopress_data->file_url_base->https ) || empty( $videopress_data->files->hd->mp4 ) ) {
151
			return $content;
152
		}
153
154
		$videopress_url = $videopress_data->file_url_base->https . $videopress_data->files->hd->mp4;
155
156
		$pattern = '/(\s)src=([\'"])(?:(?!\2).)+?\2/';
157
158
		return preg_replace(
159
			$pattern,
160
			sprintf(
161
				'\1src="%1$s"',
162
				esc_url_raw( $videopress_url )
163
			),
164
			$content,
165
			1
166
		);
167
	}
168
169
	/**
170
	 * Replaces the video uploaded in the block editor.
171
	 *
172
	 * Enqueues a script that registers an API fetch middleware replacing the video uploads in Gutenberg so they are
173
	 * uploaded against the WP.com API media endpoint and thus transcoded by VideoPress.
174
	 */
175
	public function override_video_upload() {
176
		if (
177
			method_exists( 'Jetpack', 'is_active' ) && Jetpack::is_active()
178
			&& method_exists( 'Jetpack', 'is_module_active' )
179
			&& Jetpack::is_module_active( 'videopress' )
180
		) {
181
			wp_enqueue_script(
182
				'jetpack-videopress-gutenberg-override-video-upload',
183
				plugin_dir_url( __FILE__ ) . 'js/gutenberg-video-upload.js',
184
				array( 'wp-api-fetch' ),
185
				JETPACK__VERSION,
186
				false
187
			);
188
		}
189
	}
190
}
191
192
VideoPress_Gutenberg::init();
193