Completed
Push — add/podcast-episode-selector--... ( c034f2...c45f74 )
by
unknown
09:58
created

dialogue.php ➔ build_participant_css_classes()   F

Complexity

Conditions 14
Paths 8192

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
nc 8192
nop 4
dl 0
loc 43
rs 2.1
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
 * Dialogue Block.
4
 *
5
 * @since 9.3.0
6
 *
7
 * @package automattic/jetpack
8
 */
9
10
namespace Automattic\Jetpack\Extensions\Dialogue;
11
12
use Automattic\Jetpack\Blocks;
13
use Jetpack_Gutenberg;
14
15
const FEATURE_NAME = 'dialogue';
16
const BLOCK_NAME   = 'jetpack/' . FEATURE_NAME;
17
18
/**
19
 * Registers the block for use in Gutenberg
20
 * This is done via an action so that we can disable
21
 * registration if we need to.
22
 */
23 View Code Duplication
function register_block() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
24
	$deprecated = function_exists( 'gutenberg_get_post_from_context' );
25
	$uses       = $deprecated ? 'context' : 'uses_context';
26
	Blocks::jetpack_register_block(
27
		BLOCK_NAME,
28
		array(
29
			'render_callback' => __NAMESPACE__ . '\render_block',
30
			$uses             => array(
31
				'jetpack/conversation-participants',
32
				'jetpack/conversation-showTimestamps',
33
			),
34
		)
35
	);
36
}
37
add_action( 'init', __NAMESPACE__ . '\register_block' );
38
39
/**
40
 * Helper function to convert the given time value
41
 * in a time code string with the `HH:MM:SS` shape.
42
 *
43
 * @param {integer} $time - Time, in seconds, to convert.
0 ignored issues
show
Documentation introduced by
The doc-type {integer} could not be parsed: Unknown type name "{integer}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
44
 * @return {string} Time converted in HH:MM:SS.
0 ignored issues
show
Documentation introduced by
The doc-type {string} could not be parsed: Unknown type name "{string}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
45
 */
46
function convert_time_code_to_seconds( $time ) {
47
	$sec = 0;
48
	foreach ( array_reverse( explode( ':', $time ) ) as $k => $v ) {
49
		$sec += pow( 60, $k ) * $v;
50
	}
51
	return $sec;
52
}
53
54
/**
55
 * Helper to check dialogue block attributes.
56
 *
57
 * @param array  $attrs Dialogue block attributes.
58
 * @param object $block Block object data.
59
 * @return array Checked block attribues.
60
 */
61
function check_dialogue_attrs( $attrs, $block ) {
62
	return array(
63
		'slug'           => isset( $attrs['participantSlug'] ) ? $attrs['participantSlug'] : null,
64
		'label'          => isset( $attrs['participant'] ) ? $attrs['participant'] : null,
65
		'timestamp'      => isset( $attrs['timestamp'] ) ? esc_attr( $attrs['timestamp'] ) : '00:00',
66
		'show_timestamp' => isset( $block->context['jetpack/conversation-showTimestamps'] ),
67
	);
68
}
69
/**
70
 * Return participant list.
71
 * It will try to pick them up from the block context.
72
 * Otherwise, it will return the default participants list.
73
 *
74
 * @param object $block Block object data.
75
 * @param array  $default Default conversation data.
76
 * @return array dialogue participants list.
77
 */
78
function get_participantes_list( $block, $default ) {
79
	return ! empty( $block->context['jetpack/conversation-participants'] )
80
		? $block->context['jetpack/conversation-participants']
81
		: $default['list'];
82
}
83
84
/**
85
 * Return participan slug,
86
 * dependng on the slug and label fo the dialogue block,
87
 * and default slug defined in the conversation data.
88
 *
89
 * @param array  $attrs Checked dialogue attributes array.
90
 * @param object $block Block object data.
91
 * @param array  $default Default conversation data.
92
 * @return array Dialoge slug if it's defined. Otherwise, default conversation slug.
93
 */
94
function get_participant_slug( $attrs, $block, $default ) {
95
	return ! $attrs['slug'] && ! $attrs['label']
96
		? $default['slug']
97
		: $attrs['slug'];
98
}
99
100
/**
101
 * Helper function to pick the dialogie participant object.
102
 *
103
 * @param array  $participants Dialogue participants.
104
 * @param string $slug participant slug.
105
 * @return array Dialogue participant when exists. Otherwise, False.
106
 */
107
function get_current_participant( $participants, $slug ) {
108
	// Participant names map.
109
	$participant_names_map = array();
110
	foreach ( $participants as $participant ) {
111
		$participant_names_map[ $participant['participantSlug'] ] = $participant;
112
	}
113
114
	return isset( $participant_names_map[ $slug ] )
115
		? $participant_names_map[ $slug ]
116
		: false;
117
}
118
119
/**
120
 * Helper function to get the participant name.
121
 *
122
 * @param array  $participants Dialogue participants.
123
 * @param string $slug participant slug.
124
 * @param array  $attrs checked dialogue block atteributes.
125
 * @return string Participant name.
126
 */
127
function get_participant_name( $participants, $slug, $attrs ) {
128
	// Try to pick up participant data from context.
129
	$participant = get_current_participant( $participants, $slug );
130
131
	return isset( $participant['participant'] )
132
		? $participant['participant']
133
		: $attrs['label'];
134
}
135
136
/**
137
 * Helper function to build CSS class,
138
 * for the given participant.
139
 *
140
 * @param array  $participants Dialogue participants.
141
 * @param string $slug participant slug.
142
 * @param array  $attrs checked dialogue block atteributes.
143
 * @param string $css_class Base dialogue block CSS classname.
144
 * @return string Participant CSS classnames.
145
 */
146
function build_participant_css_classes( $participants, $slug, $attrs, $css_class ) {
147
	$is_custom_speaker   = $attrs['label'] && ! $attrs['slug'];
148
	$current_participant = get_current_participant( $participants, $slug );
149
150
	$participant_has_bold_style = $is_custom_speaker && isset( $attrs['hasBoldStyle'] )
151
		? $attrs['hasBoldStyle']
152
		: (
153
			isset( $current_participant['hasBoldStyle'] )
154
				? $current_participant['hasBoldStyle']
155
				: false
156
		);
157
158
	$participant_has_italic_style = $is_custom_speaker && isset( $attrs['hasItalicStyle'] )
159
		? $attrs['hasItalicStyle']
160
		: (
161
			isset( $current_participant['hasItalicStyle'] )
162
				? $current_participant['hasItalicStyle']
163
				: false
164
		);
165
166
	$participant_has_uppercase_style = $is_custom_speaker && isset( $attrs['hasUppercaseStyle'] )
167
		? $attrs['hasUppercaseStyle']
168
		: (
169
			isset( $current_participant['hasUppercaseStyle'] )
170
				? $current_participant['hasUppercaseStyle']
171
				: false
172
		);
173
174
	$participant_css_classes = array( $css_class . '__participant' );
175
	if ( $participant_has_bold_style ) {
176
		array_push( $participant_css_classes, 'has-bold-style' );
177
	}
178
179
	if ( $participant_has_italic_style ) {
180
		array_push( $participant_css_classes, 'has-italic-style' );
181
	}
182
183
	if ( $participant_has_uppercase_style ) {
184
		array_push( $participant_css_classes, 'has-uppercase-style' );
185
	}
186
187
	return implode( ' ', $participant_css_classes );
188
}
189
190
/**
191
 * Dialogue block registration/dependency declaration.
192
 *
193
 * @param array  $attrs         Array containing the Dialogue block attributes.
194
 * @param string $block_content String containing the Dialogue block content.
195
 * @param object $block         Block object data.
196
 *
197
 * @return string
198
 */
199
function render_block( $attrs, $block_content, $block ) {
200
	Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );
201
202
	// Pick up conversation data from context.
203
	$default_participants = json_decode(
204
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
205
		file_get_contents( JETPACK__PLUGIN_DIR . 'extensions/blocks/conversation/participants.json' ),
206
		true
207
	);
208
209
	// Dialogue Attributes.
210
	$sanitized_attrs = check_dialogue_attrs( $attrs, $block );
211
212
	// Conversation/Dialogue data.
213
	$participants     = get_participantes_list( $block, $default_participants );
214
	$participant_slug = get_participant_slug( $sanitized_attrs, $block, $default_participants );
215
	$participant_name = get_participant_name( $participants, $participant_slug, $sanitized_attrs );
216
	// Class list includes custom classes defined in block settings.
217
	$block_class_list = Blocks::classes( FEATURE_NAME, $attrs );
218
	// Only the generated class name for the block, without custom classes.
219
	$block_class = explode( ' ', $block_class_list )[0];
220
221
	$markup = sprintf(
222
		'<div class="%1$s"><div class="%2$s__meta"><div class="%3$s">%4$s</div>',
223
		esc_attr( $block_class_list ),
224
		esc_attr( $block_class ),
225
		esc_attr( build_participant_css_classes( $participants, $participant_slug, $sanitized_attrs, $block_class ) ),
226
		esc_html( $participant_name )
227
	);
228
229
	// Display timestamp if we have info about it.
230
	if ( $sanitized_attrs['show_timestamp'] ) {
231
		$markup .= sprintf(
232
			'<div class="%1$s__timestamp"><a href="#" class="%1$s__timestamp_link" data-timestamp="%2$s">%3$s</a></div>',
233
			esc_attr( $block_class ),
234
			convert_time_code_to_seconds( $sanitized_attrs['timestamp'] ),
235
			esc_attr( $sanitized_attrs['timestamp'] )
236
		);
237
	}
238
239
	$markup .= sprintf(
240
		'</div><div>%s</div></div>',
241
		! empty( $attrs['content'] ) ? wp_kses_post( $attrs['content'] ) : ''
242
	);
243
244
	return $markup;
245
}
246