PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/controllers/FrmGatedContentController.php +56 -7 6.33 → trunk View file →
@@ -143,8 +143,12 @@
143 143 *
144 144 * @return void
145 145 */
146 146 public static function maybe_unlock_post() {
147 + if ( ! is_singular() ) {
148 + return;
149 + }
150 +
147 151 $post_id = get_queried_object_id();
148 152
149 153 if ( ! $post_id ) {
150 154 return;
@@ -155,10 +159,25 @@
155 159 if ( ! $post ) {
156 160 return;
157 161 }
158 162
163 + $post_item = FrmGatedItem::make(
164 + array(
165 + 'type' => $post->post_type,
166 + 'id' => $post_id,
167 + )
168 + );
169 +
170 + // Only act on posts that are registered in an active gated content action.
171 + // Posts unrelated to gated content must not have their access interfered with.
172 + if ( ! self::has_gated_action_for_item( $post_item ) ) {
173 + return;
174 + }
175 +
159 176 $is_password_protected = '' !== $post->post_password;
160 - $is_restricted_private = 'private' === $post->post_status && ! current_user_can( 'read_private_posts', $post_id );
177 + $post_type_obj = get_post_type_object( $post->post_type );
178 + $read_private_cap = $post_type_obj ? $post_type_obj->cap->read_private_posts : 'read_private_posts';
179 + $is_restricted_private = 'private' === $post->post_status && ! current_user_can( $read_private_cap, $post_id );
161 180 $access_code_from_url = FrmAppHelper::simple_get( 'access_code' );
162 181
163 182 // Nothing to unlock — post is publicly accessible.
164 183 if ( ! $is_password_protected && ! $is_restricted_private ) {
@@ -168,14 +187,8 @@
168 187
169 188 return;
170 189 }
171 190
172 - $post_item = FrmGatedItem::make(
173 - array(
174 - 'type' => $post->post_type,
175 - 'id' => $post_id,
176 - )
177 - );
178 191 $valid_token = FrmGatedTokenHelper::get_valid_token( $post_item );
179 192
180 193 if ( $valid_token ) {
181 194 // Password-protected posts need an explicit filter; private posts are
@@ -198,8 +211,44 @@
198 211 // No valid token — force a 404 to prevent private posts from being exposed.
199 212 if ( $is_restricted_private ) {
200 213 self::force_404();
201 214 }
215 + }
216 +
217 + /**
218 + * Check whether a content item is registered in at least one active gated content action.
219 + *
220 + * Used by maybe_unlock_post() to avoid interfering with private posts that are unrelated
221 + * to gated content — only items explicitly listed in a published gated content action
222 + * should have their access controlled by this plugin.
223 + *
224 + * @param FrmGatedItem $item Content item to look up.
225 + *
226 + * @return bool True if any published gated content action lists this item.
227 + */
228 + private static function has_gated_action_for_item( FrmGatedItem $item ): bool {
229 + global $wpdb;
230 +
231 + // Direct query — FrmDb caches results per-request which would hide newly
232 + // created actions until the cache expires. action_contains_item() already
233 + // handles per-action caching via transients.
234 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
235 + $action_ids = $wpdb->get_col(
236 + $wpdb->prepare(
237 + "SELECT ID FROM %i WHERE post_type = %s AND post_excerpt = %s AND post_status = 'publish'",
238 + $wpdb->posts,
239 + FrmFormActionsController::$action_post_type,
240 + FrmGatedContentAction::$slug
241 + )
242 + );
243 +
244 + foreach ( $action_ids as $action_id ) {
245 + if ( FrmGatedTokenHelper::action_contains_item( (int) $action_id, $item ) ) {
246 + return true;
247 + }
248 + }
249 +
250 + return false;
202 251 }
203 252
204 253 /**
205 254 * Force the current request to a 404 response.