Completed
Push — master ( f4704f...44bcab )
by David
02:52
created

Wordlift_Timeline_Shortcode::render()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 8
nop 1
dl 0
loc 48
rs 7.8901
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * The wl_timeline shortcode displays an interactive timeline of events bound to the current post.
5
 *
6
 * @since 3.1.0
7
 */
8
class Wordlift_Timeline_Shortcode extends Wordlift_Shortcode {
9
10
	const SHORTCODE = 'wl_timeline';
11
12
	/**
13
	 * The list of locales supported by TimelineJS (correspond to the list of
14
	 * files in the locale subfolder).
15
	 *
16
	 * @since 3.7.0
17
	 * @var array An array of two-letters language codes.
18
	 */
19
	private static $supported_locales = array(
20
		'ur',
21
		'uk',
22
		'tr',
23
		'tl',
24
		'th',
25
		'te',
26
		'ta',
27
		'sv',
28
		'sr',
29
		'sl',
30
		'sk',
31
		'si',
32
		'ru',
33
		'ro',
34
		'rm',
35
		'pt',
36
		'pl',
37
		'no',
38
		'nl',
39
		'ne',
40
		'ms',
41
		'lv',
42
		'lt',
43
		'lb',
44
		'ko',
45
		'ka',
46
		'ja',
47
		'iw',
48
		'it',
49
		'is',
50
		'id',
51
		'hy',
52
		'hu',
53
		'hr',
54
		'hi',
55
		'he',
56
		'gl',
57
		'ga',
58
		'fy',
59
		'fr',
60
		'fo',
61
		'fi',
62
		'fa',
63
		'eu',
64
		'et',
65
		'es',
66
		'eo',
67
		'en',
68
		'el',
69
		'de',
70
		'da',
71
		'cz',
72
		'ca',
73
		'bg',
74
		'be',
75
		'ar',
76
		'af'
77
	);
78
79
	/**
80
	 * The Log service.
81
	 *
82
	 * @since 3.1.0
83
	 * @access private
84
	 * @var \Wordlift_Log_Service $log_service The Log service.
85
	 */
86
	private $log_service;
87
88
	/**
89
	 * Create a Wordlift_Timeline_Shortcode instance.
90
	 *
91
	 * @since 3.1.0
92
	 */
93
	public function __construct() {
94
		parent::__construct();
95
96
		$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Timeline_Shortcode' );
97
98
	}
99
100
	public function get_timelinejs_default_options() {
101
		return array(
102
			'debug'                            => defined( 'WP_DEBUG' ) && WP_DEBUG,
103
			'height'                           => NULL,
104
			'width'                            => NULL,
105
			'is_embed'                         => FALSE,
106
			'hash_bookmark'                    => FALSE,
107
			'default_bg_color'                 => 'white',
108
			'scale_factor'                     => 2,
109
			'initial_zoom'                     => NULL,
110
			'zoom_sequence'                    => '[0.5, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]',
111
			'timenav_position'                 => 'bottom',
112
			'optimal_tick_width'               => 100,
113
			'base_class'                       => 'tl-timeline',
114
			'timenav_height'                   => 150,
115
			'timenav_height_percentage'        => NULL,
116
			'timenav_mobile_height_percentage' => 40,
117
			'timenav_height_min'               => 150,
118
			'marker_height_min'                => 30,
119
			'marker_width_min'                 => 100,
120
			'marker_padding'                   => 5,
121
			'start_at_slide'                   => 0,
122
			'start_at_end'                     => FALSE,
123
			'menubar_height'                   => 0,
124
			'use_bc'                           => FALSE,
125
			'duration'                         => 1000,
126
			'ease'                             => 'TL.Ease.easeInOutQuint',
127
			'slide_default_fade'               => '0%',
128
			'language'                         => $this->get_locale(),
129
			'ga_property_id'                   => NULL,
130
			'track_events'                     => "['back_to_start','nav_next','nav_previous','zoom_in','zoom_out']"
131
		);
132
	}
133
134
	/**
135
	 * Renders the Timeline.
136
	 *
137
	 * @since 3.1.0
138
	 *
139
	 * @param array $atts An array of shortcode attributes.
140
	 *
141
	 * @return string The rendered HTML.
142
	 */
143
	public function render( $atts ) {
144
145
		//extract attributes and set default values
146
		$settings = shortcode_atts( array_merge($this->get_timelinejs_default_options(), array(
147
			'global'                           => FALSE,
148
			'display_images_as'                => 'media',
149
			'excerpt_length'                   => 55
150
		)), $atts );
151
152
		// Load the TimelineJS stylesheets and scripts.
153
		wp_enqueue_style( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/css/timeline.css' );
154
		wp_enqueue_script( 'timelinejs', dirname( plugin_dir_url( __FILE__ ) ) . '/timelinejs/js/timeline' . ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ? '-min' : '' ) . '.js' );
155
156
		// Enqueue the scripts for the timeline.
157
		$this->enqueue_scripts();
158
159
		// Provide the script with options.
160
		wp_localize_script( 'timelinejs', 'wl_timeline_params', array(
161
			'ajax_url'          => admin_url( 'admin-ajax.php' ),
162
			// TODO: this parameter is already provided by WP
163
			'action'            => 'wl_timeline',
164
			// These settings apply to our wl_timeline AJAX endpoint.
165
			'display_images_as' => $settings['display_images_as'],
166
			'excerpt_length'    => $settings['excerpt_length'],
167
			// These settings apply to the timeline javascript client.
168
			'settings'          => array_filter( $settings, function ( $value ) {
169
				// Do not set NULL values.
170
				return ( NULL !== $value );
171
			} )
172
		) );
173
174
		// Get the current post id or set null if global is set to true.
175
		$post_id = ( $settings['global'] ? NULL : get_the_ID() );
176
177
		// Escaping atts.
178
		$style        = sprintf( 'style="%s%s"', isset( $settings['width'] ) ? "width:{$settings['width']};" : '', isset( $settings['height'] ) ? "height:{$settings['height']};" : '' );
179
		$data_post_id = ( isset( $post_id ) ? "data-post-id='$post_id'" : '' );
180
181
		// Generate a unique ID for this timeline.
182
		$element_id = uniqid( 'wl-timeline-' );
183
184
		if ( WP_DEBUG ) {
185
			$this->log_service->trace( "Creating a timeline widget [ element id :: $element_id ][ post id :: $post_id ]" );
186
		}
187
188
		// Building template.
189
		return sprintf( '<div class="wl-timeline-container" %s><div class="wl-timeline" id="%s" %s></div></div>', $style, $element_id, $data_post_id );
190
	}
191
192
	/**
193
	 * Return the locale for the TimelineJS according to WP's configured locale and
194
	 * support TimelineJS locales. If WP's locale is not supported, english is used.
195
	 *
196
	 * @since 3.7.0
197
	 * @return string The locale (2 letters code).
198
	 */
199
	private function get_locale() {
200
201
		// Get the first 2 letters.
202
		$locale = substr( get_locale(), 0, 2 );
203
204
		// Check that the specified locale is supported otherwise use English.
205
		return in_array( $locale, self::$supported_locales ) ? $locale : 'en';
206
	}
207
208
}
209
210
/**
211
 * register_block_type for Gutenberg blocks
212
 */
213
add_action( 'init', function() {
214
	// Bail out if the `register_block_type` function isn't available.
215
	if ( ! function_exists( 'register_block_type' ) ) {
216
		return;
217
	}
218
219
	$wordlift_timeline_shortcode = new Wordlift_Timeline_Shortcode();
220
	register_block_type('wordlift/timeline', array(
221
		'editor_script' => 'wordlift-admin-edit-gutenberg',
222
		'render_callback' => function($attributes){
223
			$attr_code = '';
224
			$timelinejs_options = json_decode($attributes['timelinejs_options'], true);
225
			unset($attributes['timelinejs_options']);
226
			$attributes_all = array_merge($attributes, $timelinejs_options);
227
			foreach ($attributes_all as $key => $value) {
228
				if($value && strpos($value, '[') === false && strpos($value, ']') === false) {
229
					$attr_code .= $key.'="'.$value.'" ';
230
				}
231
			}
232
			return '[wl_timeline '.$attr_code.']';
233
		},
234
		'attributes' => array(
235
			'display_images_as' => array(
236
				'type'    => 'string',
237
				'default' => 'media'
238
			),
239
			'excerpt_length' => array(
240
				'type'    => 'number',
241
				'default' => 55
242
			),
243
			'global' => array(
244
				'type'    => 'bool',
245
				'default' => false
246
			),
247
			'timelinejs_options' => array(
248
				'type'    => 'string', // https://timeline.knightlab.com/docs/options.html
249
				'default' => json_encode($wordlift_timeline_shortcode->get_timelinejs_default_options(), JSON_PRETTY_PRINT)
250
			)
251
		)
252
	));
253
} );
254