PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-videopress / src / class-caption-tracks.php
jetpack / jetpack_vendor / automattic / jetpack-videopress / src Last commit date
js 2 months ago tus 1 month ago videopress-divi 2 months ago videopress-divi-5 2 months ago class-access-control.php 5 days ago class-admin-ui.php 2 weeks ago class-ajax.php 1 month ago class-attachment-handler.php 1 month ago class-block-editor-content.php 1 month ago class-block-editor-extensions.php 2 weeks ago class-block-replacement.php 9 months ago class-caption-tracks.php 1 month ago class-data.php 1 month ago class-divi.php 2 months ago class-initial-state.php 2 weeks ago class-initializer.php 5 days ago class-jwt-token-bridge.php 2 years ago class-module-control.php 3 years ago class-options.php 2 years ago class-package-version.php 5 days ago class-plan.php 2 years ago class-rest-controller.php 1 month ago class-site.php 3 years ago class-stats.php 1 year ago class-status.php 9 months ago class-upload-exception.php 3 years ago class-uploader-rest-endpoints.php 2 weeks ago class-uploader.php 1 month ago class-utils.php 3 months ago class-video-block-email-renderer.php 2 months ago class-videopress-rest-api-v1-features.php 6 months ago class-videopress-rest-api-v1-settings.php 1 month ago class-videopress-rest-api-v1-site.php 2 weeks ago class-videopress-rest-api-v1-stats.php 3 years ago class-videopresstoken.php 1 month ago class-wpcom-rest-api-v2-attachment-field-videopress.php 9 months ago class-wpcom-rest-api-v2-attachment-videopress-data.php 1 month ago class-wpcom-rest-api-v2-endpoint-videopress-caption-tracks.php 1 month ago class-wpcom-rest-api-v2-endpoint-videopress.php 2 weeks ago class-xmlrpc.php 1 month ago utility-functions.php 4 weeks ago
class-caption-tracks.php
161 lines
1 <?php
2 /**
3 * VideoPress caption track post type and helpers.
4 *
5 * @package automattic/jetpack-videopress
6 */
7
8 namespace Automattic\Jetpack\VideoPress;
9
10 /**
11 * Stores editable caption track documents as private WordPress posts.
12 *
13 * Track content is stored as serialized `videopress/caption-cue` block markup,
14 * matching the block-based editor that produces it. This is a deliberate
15 * trade-off: it keeps the draft round-trippable through the editor without a
16 * bespoke format, at the cost of coupling stored drafts to the block markup
17 * (sanitization re-parses blocks, and replacing the editor later means
18 * migrating stored content).
19 *
20 * The REST routes serving this store live in
21 * {@see WPCOM_REST_API_V2_Endpoint_VideoPress_Caption_Tracks}.
22 */
23 class Caption_Tracks {
24
25 const POST_TYPE = 'vp_caption_track';
26
27 const CUE_BLOCK_NAME = 'videopress/caption-cue';
28
29 const META_GUID = '_videopress_guid';
30 const META_KIND = '_videopress_caption_kind';
31 const META_SRC_LANG = '_videopress_caption_src_lang';
32 const META_LABEL = '_videopress_caption_label';
33 const META_SOURCE_TRACK_KIND = '_videopress_source_track_kind';
34 const META_SOURCE_TRACK_SRC_LANG = '_videopress_source_track_src_lang';
35 const META_SOURCE_TRACK_SRC = '_videopress_source_track_src';
36
37 /**
38 * Initialize the caption track post type.
39 *
40 * @return void
41 */
42 public static function init() {
43 add_action( 'init', array( __CLASS__, 'register_post_type' ) );
44 add_action( 'init', array( __CLASS__, 'register_meta' ) );
45 }
46
47 /**
48 * Register the private caption track post type.
49 *
50 * @return void
51 */
52 public static function register_post_type() {
53 register_post_type(
54 self::POST_TYPE,
55 array(
56 'labels' => array(
57 'name' => __( 'VideoPress caption tracks', 'jetpack-videopress-pkg' ),
58 'singular_name' => __( 'VideoPress caption track', 'jetpack-videopress-pkg' ),
59 ),
60 'public' => false,
61 'exclude_from_search' => true,
62 'publicly_queryable' => false,
63 'show_ui' => false,
64 'show_in_menu' => false,
65 'show_in_rest' => false,
66 // No revisions: there is no restore UI, and each one would copy up to 1MB of content.
67 'supports' => array( 'title', 'editor' ),
68
69 /*
70 * Caption tracks are an internal store reached only through the
71 * /wpcom/v2/videopress/caption-tracks routes, which authorize
72 * each request against the video it targets. The post type itself
73 * is not exposed (no REST, no admin UI), so standard post
74 * capabilities are sufficient.
75 */
76 'capability_type' => 'post',
77 'map_meta_cap' => true,
78 )
79 );
80 }
81
82 /**
83 * Register caption track metadata so values are sanitized when saved.
84 *
85 * @return void
86 */
87 public static function register_meta() {
88 $string_meta = array(
89 self::META_GUID => array( __CLASS__, 'sanitize_guid' ),
90 self::META_KIND => array( __CLASS__, 'sanitize_kind' ),
91 self::META_SRC_LANG => array( __CLASS__, 'sanitize_manual_language' ),
92 self::META_LABEL => 'sanitize_text_field',
93 self::META_SOURCE_TRACK_KIND => array( __CLASS__, 'sanitize_kind' ),
94 self::META_SOURCE_TRACK_SRC_LANG => 'sanitize_text_field',
95 self::META_SOURCE_TRACK_SRC => 'esc_url_raw',
96 );
97
98 foreach ( $string_meta as $key => $sanitize_callback ) {
99 register_post_meta(
100 self::POST_TYPE,
101 $key,
102 array(
103 'type' => 'string',
104 'single' => true,
105 'sanitize_callback' => $sanitize_callback,
106 )
107 );
108 }
109 }
110
111 /**
112 * Sanitize a VideoPress GUID.
113 *
114 * @param string $value Raw value.
115 * @return string
116 */
117 public static function sanitize_guid( $value ) {
118 $value = sanitize_text_field( $value );
119 return preg_match( '/^[a-z0-9]{8}$/i', $value ) ? $value : '';
120 }
121
122 /**
123 * Sanitize a text track kind.
124 *
125 * @param string $value Raw value.
126 * @return string
127 */
128 public static function sanitize_kind( $value ) {
129 $value = sanitize_key( $value );
130 $valid = array( 'subtitles', 'captions', 'descriptions', 'chapters', 'metadata' );
131 return in_array( $value, $valid, true ) ? $value : '';
132 }
133
134 /**
135 * Validate a caption track's BCP-47 language tag.
136 *
137 * The client canonicalizes tags with `Intl.getCanonicalLocales` before
138 * saving, and the "one track per language" lookup matches stored tags by
139 * exact string, so this is a validation gate only: it rejects generated
140 * source keys such as `auto_en` and malformed tags, then keeps the client's
141 * canonical value verbatim. Re-casing here would risk diverging from the
142 * client's canonical form and silently create duplicate tracks.
143 *
144 * @param string $value Raw value.
145 * @return string Validated tag, or empty string when invalid.
146 */
147 public static function sanitize_manual_language( $value ) {
148 $value = trim( sanitize_text_field( $value ) );
149
150 if ( preg_match( '/^auto[_-]/i', $value ) ) {
151 return '';
152 }
153
154 if ( ! preg_match( '/^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$/i', $value ) ) {
155 return '';
156 }
157
158 return $value;
159 }
160 }
161