PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.3
Presto Player v4.3.3
4.3.3 4.3.2 4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / inc / Models / Post.php
presto-player / inc / Models Last commit date
AudioPreset.php 2 months ago Block.php 11 months ago CurrentUser.php 2 years ago EmailCollection.php 2 years ago Model.php 1 month ago ModelInterface.php 2 years ago Player.php 1 month ago Post.php 6 days ago Preset.php 2 months ago ReusableVideo.php 2 months ago Setting.php 2 years ago Video.php 2 weeks ago Webhook.php 2 years ago
Post.php
201 lines
1 <?php
2 /**
3 * Post model for finding the presto player video in post content.
4 *
5 * @package PrestoPlayer
6 */
7
8 namespace PrestoPlayer\Models;
9
10 /**
11 * Finds the presto player video id in a post's content.
12 */
13 class Post {
14
15 /**
16 * The post being searched.
17 *
18 * @var \WP_Post
19 */
20 protected $post;
21
22 /**
23 * Ids of posts we have already followed a shortcode into.
24 *
25 * A [presto_player id=...] can point back at its own post, or at a post
26 * that points back here. Without this we'd recurse until memory runs out.
27 *
28 * @var array<int, bool>
29 */
30 protected $visited = array();
31
32 /**
33 * Constructor.
34 *
35 * @param \WP_Post $post The post to search.
36 */
37 public function __construct( \WP_Post $post ) {
38 $this->post = $post;
39 $this->visited[ (int) $post->ID ] = true;
40 }
41
42 /**
43 * Find video id in post using multiple methods
44 *
45 * @return int|false
46 */
47 public function findVideoId() {
48 // first check for id in block.
49 $id = $this->getVideoIdFromBlock();
50 if ( $id ) {
51 return (int) $id;
52 }
53
54 $id = $this->getVideoIdFromShortcode();
55 if ( $id ) {
56 return (int) $id;
57 }
58
59 $id = $this->getVideoIdFromContent();
60 if ( $id ) {
61 return (int) $id;
62 }
63
64 return false;
65 }
66
67 /**
68 * Find the video id from the shortcode
69 *
70 * @return int|false
71 */
72 public function getVideoIdFromShortcode() {
73 // Scope the regex to our own tag so the shortcode is still found when
74 // nested inside an enclosing shortcode (e.g. [trp_language]).
75 $pattern = get_shortcode_regex( array( 'presto_player' ) );
76 $content = $this->post->post_content;
77
78 // false when PCRE hits a backtrack/JIT limit on huge content, 0 when there is no shortcode.
79 if ( ! preg_match_all( "/$pattern/", $content, $matches ) ) {
80 return false;
81 }
82
83 // the regex only matches our own tag, so every match is a candidate.
84 foreach ( array_keys( $matches[2] ) as $index ) {
85 // [[presto_player]] is escaped: it renders as literal text, so there is no video.
86 if ( '[' === $matches[1][ $index ] && ']' === $matches[6][ $index ] ) {
87 continue;
88 }
89
90 if ( empty( $matches[3][ $index ] ) ) {
91 continue;
92 }
93
94 // get media hub id.
95 $atts = shortcode_parse_atts( $matches[3][ $index ] );
96 if ( empty( $atts['id'] ) ) {
97 continue;
98 }
99
100 // already been here - it's a self-reference or a loop.
101 $id = (int) $atts['id'];
102 if ( isset( $this->visited[ $id ] ) ) {
103 continue;
104 }
105
106 $post = get_post( $id );
107 // the id can point at a deleted media hub item.
108 if ( ! $post instanceof \WP_Post ) {
109 continue;
110 }
111
112 $this->visited[ $id ] = true;
113 $original = $this->post;
114 $this->post = $post;
115
116 $video_id = $this->findVideoId();
117 if ( $video_id ) {
118 return $video_id;
119 }
120
121 // put our own post back, or findVideoId() carries on searching the
122 // post we just followed instead of this one.
123 $this->post = $original;
124 }
125
126 return false;
127 }
128
129 /**
130 * Get the video id from the block
131 */
132 public function getVideoIdFromBlock() {
133 $blocks = parse_blocks( $this->post->post_content );
134 foreach ( $blocks as $block ) {
135 // inside wrapper block.
136 if ( 'presto-player/reusable-edit' === $block['blockName'] && ! empty( $block['innerBlocks'] ) ) {
137 $block = $block['innerBlocks'][0];
138 }
139
140 // we have a reusable display block.
141 if ( 'presto-player/reusable-display' === $block['blockName'] ) {
142 // find the media hub post.
143 if ( ! empty( $block['attrs']['id'] ) ) {
144 $block = self::getMediaHubBlockFromPost( $block['attrs']['id'] );
145 }
146 }
147
148 // in case block needs to be filtered.
149 $block = apply_filters( 'presto_player_get_block_from_content', $block );
150
151 // find the id attribute.
152 if ( ! empty( $block ) && in_array( $block['blockName'], Block::getBlockTypes() ) ) {
153 if ( ! empty( $block['attrs']['id'] ) ) {
154 return $block['attrs']['id'];
155 }
156 }
157 }
158
159 return false;
160 }
161
162 /**
163 * Fallback - get video id from comment in content
164 */
165 public function getVideoIdFromContent() {
166 $content = $this->post->post_content;
167
168 preg_match_all( '/(?<=<!--presto-player:video_id=)(.*)(?=-->)/', $content, $matches );
169 if ( ! empty( $matches[0][0] ) ) {
170 return (int) $matches[0][0];
171 }
172
173 return false;
174 }
175
176 /**
177 * Retrieve the inner block from media hub post.
178 *
179 * @param int $id id of the post.
180 * @return array|false
181 */
182 public static function getMediaHubBlockFromPost( $id ) {
183 if ( ! $id ) {
184 return false;
185 }
186
187 // get the media hub post.
188 $block_post = get_post( $id );
189
190 // if it has content, get the first block.
191 if ( ! empty( $block_post->post_content ) ) {
192 $inner_blocks = parse_blocks( $block_post->post_content );
193 if ( ! empty( $inner_blocks[0]['innerBlocks'][0] ) ) {
194 return $inner_blocks[0]['innerBlocks'][0] ?? false;
195 }
196 }
197
198 return false;
199 }
200 }
201