Pods – Custom Content Types and Fields - Version 2.8.14

Version Description

  • April 15th, 2022 =

  • Added: New $params support in Pods::total_found( $params ) to support Pods::find( $params ) shorthand lookups for getting total number of records found more easily. (@sc0ttkclark)

  • Added: New pods_api_save_field_table_definition_mode filter allows overriding the definition mode when saving a field (bypass/add/drop/change) for schema management. (@sc0ttkclark)

  • Added: New pods_podsrel_enabled() arguments to allow filtering based on the field and context. (@sc0ttkclark)

  • Added: New pods_data_build_pre_traverse_args filter allows for overriding the find/replace/traverse/params arguments for a PodsData::build() request before relationship traversal runs. (@sc0ttkclark)

  • Added: New pods_data_traverse_recurse_handle_join filter allows for overriding the JOIN SQL used for relationship traversal. (@sc0ttkclark)

  • Fixed: Resolved potential PHP issues with path checks in PodsView on certain environments. (@sc0ttkclark)

  • Fixed: When a slug is set on a Pods Page, if the slug value comes through as empty due to a path issue, it will now enforce a 404 as expected. (@sc0ttkclark)

  • Fixed: Resolved a few issues with the old field data coming through to the pods_api_save_field_old_definition filter. (@sc0ttkclark)

  • Fixed: No longer showing WPDB errors from WPDB when query errors are forced off. (@sc0ttkclark)

Download this release

Release Info

Developer sc0ttkclark
Plugin Icon 128x128 Pods – Custom Content Types and Fields
Version 2.8.14
Comparing to
See all releases

Code changes from version 2.8.13 to 2.8.14

classes/Pods.php CHANGED
@@ -2473,11 +2473,19 @@ class Pods implements Iterator {
2473
  *
2474
  * @see PodsData::total_found
2475
  *
 
 
2476
  * @return int Number of rows returned by find(), regardless of the 'limit' parameter
2477
  * @since 2.0.0
2478
  * @link https://docs.pods.io/code/pods/total-found/
2479
  */
2480
- public function total_found() {
 
 
 
 
 
 
2481
 
2482
  /**
2483
  * Runs directly before the value of total_found() is determined and returned.
2473
  *
2474
  * @see PodsData::total_found
2475
  *
2476
+ * @params null|array $params The list of Pods::find() parameters to use, otherwise use current dataset to calculate total found.
2477
+ *
2478
  * @return int Number of rows returned by find(), regardless of the 'limit' parameter
2479
  * @since 2.0.0
2480
  * @link https://docs.pods.io/code/pods/total-found/
2481
  */
2482
+ public function total_found( $params = null ) {
2483
+ // Support find() shorthand to get total_found() for a specific dataset.
2484
+ if ( is_array( $params ) ) {
2485
+ $this->find( $params );
2486
+
2487
+ return $this->total_found();
2488
+ }
2489
 
2490
  /**
2491
  * Runs directly before the value of total_found() is determined and returned.
classes/PodsAPI.php CHANGED
@@ -227,7 +227,7 @@ class PodsAPI {
227
  /**
228
  * Save the meta for a meta type.
229
  *
230
- * @since TBD
231
  *
232
  * @param string $meta_type The meta type.
233
  * @param int $id The object ID.
@@ -2949,6 +2949,7 @@ class PodsAPI {
2949
 
2950
  $params = (object) $params;
2951
 
 
2952
  $field = false;
2953
 
2954
  if ( isset( $params->field ) && $params->field instanceof Field ) {
@@ -3196,6 +3197,11 @@ class PodsAPI {
3196
  $old_options = $field;
3197
  $old_sister_id = pods_v( 'sister_id', $old_options, 0 );
3198
 
 
 
 
 
 
3199
  // When renaming a field, use the old ID for reference if empty.
3200
  if ( ( 'old_name' === $lookup_type || $params->overwrite ) && empty( $params->id ) ) {
3201
  $params->id = $old_id;
@@ -3243,7 +3249,7 @@ class PodsAPI {
3243
  }
3244
 
3245
  if ( false !== $this->field_exists( $params, false ) ) {
3246
- return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that', 'pods' ), $field['name'], $old_name ), $this );
3247
  }
3248
  }
3249
 
@@ -3265,11 +3271,11 @@ class PodsAPI {
3265
  *
3266
  * @param string|false $field_definition The SQL definition to use for the field's table column.
3267
  * @param string $type The field type.
3268
- * @param array $field The field data.
3269
  * @param bool $simple Whether the field is a simple tableless field.
3270
  * @param Pods\Whatsit\Field $field_obj The field object.
3271
  */
3272
- $field_definition = apply_filters( 'pods_api_save_field_old_definition', $field_definition, $old_type, $field, $old_simple, $field_obj );
3273
 
3274
  if ( ! empty( $field_definition ) ) {
3275
  $old_definition = "`{$old_name}` " . $field_definition;
@@ -3629,6 +3635,12 @@ class PodsAPI {
3629
 
3630
  $field['id'] = $params->id;
3631
 
 
 
 
 
 
 
3632
  $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) );
3633
 
3634
  $definition = false;
@@ -3693,6 +3705,35 @@ class PodsAPI {
3693
  }
3694
  }
3695
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3696
  if ( 'bypass' !== $definition_mode ) {
3697
  /**
3698
  * Allow hooking into before the table has been altered for any custom functionality needed.
@@ -9075,7 +9116,7 @@ class PodsAPI {
9075
  if ( ! is_wp_error( $related ) ) {
9076
  $related_ids = $related;
9077
  }
9078
- } elseif ( ! $params->force_meta && ! pods_tableless() && pods_podsrel_enabled() ) {
9079
  $ids = implode( ', ', $params->ids );
9080
 
9081
  $params->field_id = (int) $params->field_id;
227
  /**
228
  * Save the meta for a meta type.
229
  *
230
+ * @since 2.8.11
231
  *
232
  * @param string $meta_type The meta type.
233
  * @param int $id The object ID.
2949
 
2950
  $params = (object) $params;
2951
 
2952
+ /** @var false|array|Field $field */
2953
  $field = false;
2954
 
2955
  if ( isset( $params->field ) && $params->field instanceof Field ) {
3197
  $old_options = $field;
3198
  $old_sister_id = pods_v( 'sister_id', $old_options, 0 );
3199
 
3200
+ // Maybe clone the field object if we need to.
3201
+ if ( $old_options instanceof Field ) {
3202
+ $old_options = clone $old_options;
3203
+ }
3204
+
3205
  // When renaming a field, use the old ID for reference if empty.
3206
  if ( ( 'old_name' === $lookup_type || $params->overwrite ) && empty( $params->id ) ) {
3207
  $params->id = $old_id;
3249
  }
3250
 
3251
  if ( false !== $this->field_exists( $params, false ) ) {
3252
+ return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that on the %3$s pod', 'pods' ), $field['name'], $old_name, $pod['name'] ), $this );
3253
  }
3254
  }
3255
 
3271
  *
3272
  * @param string|false $field_definition The SQL definition to use for the field's table column.
3273
  * @param string $type The field type.
3274
+ * @param array $old_options The field data.
3275
  * @param bool $simple Whether the field is a simple tableless field.
3276
  * @param Pods\Whatsit\Field $field_obj The field object.
3277
  */
3278
+ $field_definition = apply_filters( 'pods_api_save_field_old_definition', $field_definition, $old_type, $old_options, $old_simple, $field_obj );
3279
 
3280
  if ( ! empty( $field_definition ) ) {
3281
  $old_definition = "`{$old_name}` " . $field_definition;
3635
 
3636
  $field['id'] = $params->id;
3637
 
3638
+ if ( $field instanceof Field ) {
3639
+ $field_obj = $field;
3640
+ } elseif ( $field_obj instanceof Field && is_array( $field ) ) {
3641
+ $field_obj->set_args( $field );
3642
+ }
3643
+
3644
  $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) );
3645
 
3646
  $definition = false;
3705
  }
3706
  }
3707
 
3708
+ /**
3709
+ * Allow filtering the definition mode to use for the field definition handling.
3710
+ *
3711
+ * @since 2.8.14
3712
+ *
3713
+ * @param string $definition_mode The definition mode used for the table field.
3714
+ * @param Pods\Whatsit\Pod $pod The pod object.
3715
+ * @param string $type The field type.
3716
+ * @param array $field The field data.
3717
+ * @param array $extra_info {
3718
+ * Extra information about the field.
3719
+ *
3720
+ * @type bool $simple Whether the field is a simple tableless field.
3721
+ * @type string $definition The field definition.
3722
+ * @type null|string $old_name The old field name (if preexisting).
3723
+ * @type null|string $old_definition The old field definition (if preexisting).
3724
+ * @type null|array $old_options The old field options (if preexisting).
3725
+ * @type Pods\Whatsit\Field $field_obj The field object.
3726
+ * }
3727
+ */
3728
+ $definition_mode = apply_filters( 'pods_api_save_field_table_definition_mode', $definition_mode, $pod, $field['type'], $field, [
3729
+ 'simple' => $simple,
3730
+ 'definition' => $definition,
3731
+ 'old_name' => $old_name,
3732
+ 'old_definition' => $old_definition,
3733
+ 'old_options' => $old_options,
3734
+ 'field_obj' => $field_obj,
3735
+ ] );
3736
+
3737
  if ( 'bypass' !== $definition_mode ) {
3738
  /**
3739
  * Allow hooking into before the table has been altered for any custom functionality needed.
9116
  if ( ! is_wp_error( $related ) ) {
9117
  $related_ids = $related;
9118
  }
9119
+ } elseif ( ! $params->force_meta && ! pods_tableless() && pods_podsrel_enabled( $params->field, 'lookup' ) ) {
9120
  $ids = implode( ', ', $params->ids );
9121
 
9122
  $params->field_id = (int) $params->field_id;
classes/PodsData.php CHANGED
@@ -1471,6 +1471,39 @@ class PodsData {
1471
 
1472
  $joins = array();
1473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1474
  if ( ! empty( $find ) ) {
1475
  // See: "#3294 OrderBy Failing on PHP7" Non-zero array keys.
1476
  // here in PHP 7 cause odd behavior so just strip the keys.
@@ -2374,8 +2407,22 @@ class PodsData {
2374
  // Run Query.
2375
  $params->sql = apply_filters( 'pods_data_query', $params->sql, $params );
2376
 
 
 
 
 
 
 
 
 
 
2377
  $result = $wpdb->query( $params->sql );
2378
 
 
 
 
 
 
2379
  $result = apply_filters( 'pods_data_query_result', $result, $params );
2380
 
2381
  if ( false === $result && ! empty( $params->error ) && ! empty( $wpdb->last_error ) ) {
@@ -3466,7 +3513,7 @@ class PodsData {
3466
  LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON
3467
  `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}`
3468
  ";
3469
- } elseif ( pods_podsrel_enabled() ) {
3470
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( ! $is_pickable || ! in_array( $pick_object, $simple_tableless_objects, true ) ) && 'post_author' === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
3471
  $table_info['recurse'] = false;
3472
  }
@@ -3486,6 +3533,39 @@ class PodsData {
3486
  `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id`
3487
  ";
3488
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3489
  }//end if
3490
  } elseif ( 'meta' === $pod_data['storage'] ) {
3491
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( ! $is_pickable || ! in_array( $pick_object, $simple_tableless_objects, true ) ) && $table_info['meta_field_value'] === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
1471
 
1472
  $joins = array();
1473
 
1474
+ $pre_traverse_args = [
1475
+ 'find' => $find,
1476
+ 'replace' => $replace,
1477
+ 'traverse' => $traverse,
1478
+ 'params' => $params,
1479
+ ];
1480
+
1481
+ /**
1482
+ * Allow filtering the pre-traverse arguments that will be used to build the query.
1483
+ *
1484
+ * @since 2.8.14
1485
+ *
1486
+ * @param array $pre_traverse_args The pre-traverse arguments.
1487
+ * @param PodsData $pods_data The PodsData object.
1488
+ */
1489
+ $pre_traverse_args = (array) apply_filters( 'pods_data_build_pre_traverse_args', $pre_traverse_args, $this );
1490
+
1491
+ if ( isset( $pre_traverse_args['find'] ) ) {
1492
+ $find = $pre_traverse_args['find'];
1493
+ }
1494
+
1495
+ if ( isset( $pre_traverse_args['replace'] ) ) {
1496
+ $replace = $pre_traverse_args['replace'];
1497
+ }
1498
+
1499
+ if ( isset( $pre_traverse_args['traverse'] ) ) {
1500
+ $traverse = $pre_traverse_args['traverse'];
1501
+ }
1502
+
1503
+ if ( isset( $pre_traverse_args['params'] ) ) {
1504
+ $params = $pre_traverse_args['params'];
1505
+ }
1506
+
1507
  if ( ! empty( $find ) ) {
1508
  // See: "#3294 OrderBy Failing on PHP7" Non-zero array keys.
1509
  // here in PHP 7 cause odd behavior so just strip the keys.
2407
  // Run Query.
2408
  $params->sql = apply_filters( 'pods_data_query', $params->sql, $params );
2409
 
2410
+ $wpdb_show_errors = null;
2411
+
2412
+ // Maybe disable wpdb errors.
2413
+ if ( false === $params->error && ! empty( $wpdb->show_errors ) ) {
2414
+ $wpdb_show_errors = false;
2415
+
2416
+ $wpdb->show_errors( false );
2417
+ }
2418
+
2419
  $result = $wpdb->query( $params->sql );
2420
 
2421
+ // Maybe show wpdb errors.
2422
+ if ( $wpdb_show_errors ) {
2423
+ $wpdb->show_errors( true );
2424
+ }
2425
+
2426
  $result = apply_filters( 'pods_data_query_result', $result, $params );
2427
 
2428
  if ( false === $result && ! empty( $params->error ) && ! empty( $wpdb->last_error ) ) {
3513
  LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON
3514
  `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}`
3515
  ";
3516
+ } elseif ( pods_podsrel_enabled( $the_field, 'lookup' ) ) {
3517
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( ! $is_pickable || ! in_array( $pick_object, $simple_tableless_objects, true ) ) && 'post_author' === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
3518
  $table_info['recurse'] = false;
3519
  }
3533
  `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id`
3534
  ";
3535
  }
3536
+ } else {
3537
+ $handle_join = [
3538
+ 'recurse' => $table_info['recurse'],
3539
+ 'the_join' => null,
3540
+ ];
3541
+
3542
+ /**
3543
+ * Allow filtering the join parameters to be used for custom traversal logic.
3544
+ *
3545
+ * @since 2.8.14
3546
+ *
3547
+ * @param array $handle_join The join parameters to set.
3548
+ * @param array $args The additional traverse recurse arguments.
3549
+ * @param PodsData $pods_data The PodsData object.
3550
+ */
3551
+ $handle_join = apply_filters( 'pods_data_traverse_recurse_handle_join', $handle_join, [
3552
+ 'traverse' => $traverse,
3553
+ 'traverse_recurse' => $traverse_recurse,
3554
+ 'the_field' => $the_field,
3555
+ 'table_info' => $table_info,
3556
+ 'field_joined' => $field_joined,
3557
+ 'rel_alias' => $rel_alias,
3558
+ 'is_pickable' => $is_pickable,
3559
+ 'pick_object' => $pick_object,
3560
+ ], $this );
3561
+
3562
+ if ( null !== $handle_join['recurse'] ) {
3563
+ $table_info['recurse'] = $handle_join['recurse'];
3564
+ }
3565
+
3566
+ if ( null !== $handle_join['the_join'] ) {
3567
+ $the_join = $handle_join['the_join'];
3568
+ }
3569
  }//end if
3570
  } elseif ( 'meta' === $pod_data['storage'] ) {
3571
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( ! $is_pickable || ! in_array( $pick_object, $simple_tableless_objects, true ) ) && $table_info['meta_field_value'] === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
classes/PodsView.php CHANGED
@@ -584,7 +584,25 @@ class PodsView {
584
 
585
  // Is the view's file somewhere within the plugin directory tree?
586
  // Note: we explicitly whitelist PODS_DIR for the case of symlinks (see issue #2945)
587
- if ( false !== strpos( $_real_view, realpath( WP_PLUGIN_DIR ) ) || false !== strpos( $_real_view, realpath( WPMU_PLUGIN_DIR ) ) || false !== strpos( $_real_view, PODS_DIR ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  if ( file_exists( $_view ) ) {
589
  $located = $_view;
590
  } else {
@@ -598,11 +616,22 @@ class PodsView {
598
  return false;
599
  }
600
 
601
- // Allow views in the theme or child theme
602
- if ( file_exists( realpath( get_stylesheet_directory() . '/' . $_real_view ) ) ) {
603
- $located = realpath( get_stylesheet_directory() . '/' . $_real_view );
604
- } elseif ( file_exists( realpath( get_template_directory() . '/' . $_real_view ) ) ) {
605
- $located = realpath( get_template_directory() . '/' . $_real_view );
 
 
 
 
 
 
 
 
 
 
 
606
  }
607
  }//end if
608
 
584
 
585
  // Is the view's file somewhere within the plugin directory tree?
586
  // Note: we explicitly whitelist PODS_DIR for the case of symlinks (see issue #2945)
587
+ $path_checks = [
588
+ realpath( WP_PLUGIN_DIR ),
589
+ realpath( WPMU_PLUGIN_DIR ),
590
+ realpath( PODS_DIR ),
591
+ ];
592
+
593
+ $path_checks = array_filter( $path_checks );
594
+
595
+ $path_match = false;
596
+
597
+ foreach ( $path_checks as $path_check ) {
598
+ if ( false !== strpos( $_real_view, $path_check ) ) {
599
+ $path_match = true;
600
+
601
+ break;
602
+ }
603
+ }
604
+
605
+ if ( $path_match ) {
606
  if ( file_exists( $_view ) ) {
607
  $located = $_view;
608
  } else {
616
  return false;
617
  }
618
 
619
+ // Allow views in the theme or child theme.
620
+ $path_checks = [
621
+ realpath( get_stylesheet_directory() . DIRECTORY_SEPARATOR . $_real_view ),
622
+ realpath( get_template_directory() . DIRECTORY_SEPARATOR . $_real_view ),
623
+ ];
624
+
625
+ $path_checks = array_filter( $path_checks );
626
+
627
+ $path_match = false;
628
+
629
+ foreach ( $path_checks as $path_check ) {
630
+ if ( file_exists( $path_check ) ) {
631
+ $located = $path_check;
632
+
633
+ break;
634
+ }
635
  }
636
  }//end if
637
 
classes/fields/datetime.php CHANGED
@@ -994,7 +994,7 @@ class PodsField_DateTime extends PodsField {
994
  /**
995
  * Prepare the date/datetime/time field object or options for MomentJS formatting.
996
  *
997
- * @since TBD
998
  *
999
  * @param array|Field $options The field object or options.
1000
  *
@@ -1043,7 +1043,7 @@ class PodsField_DateTime extends PodsField {
1043
  /**
1044
  * Get the format from the options for a specific type (date/datetime/time).
1045
  *
1046
- * @since TBD
1047
  *
1048
  * @param array|Field $options The field object or options.
1049
  * @param string $type The specific field type.
@@ -1144,7 +1144,7 @@ class PodsField_DateTime extends PodsField {
1144
  /**
1145
  * Convert the source format to MomentJS format for PHP / jQuery UI formats.
1146
  *
1147
- * @since TBD
1148
  *
1149
  * @param string|mixed $source_format The source format.
1150
  * @param array $args The list of format arguments including source (php/jquery_ui) and type (date/time).
994
  /**
995
  * Prepare the date/datetime/time field object or options for MomentJS formatting.
996
  *
997
+ * @since 2.8.11
998
  *
999
  * @param array|Field $options The field object or options.
1000
  *
1043
  /**
1044
  * Get the format from the options for a specific type (date/datetime/time).
1045
  *
1046
+ * @since 2.8.11
1047
  *
1048
  * @param array|Field $options The field object or options.
1049
  * @param string $type The specific field type.
1144
  /**
1145
  * Convert the source format to MomentJS format for PHP / jQuery UI formats.
1146
  *
1147
+ * @since 2.8.11
1148
  *
1149
  * @param string|mixed $source_format The source format.
1150
  * @param array $args The list of format arguments including source (php/jquery_ui) and type (date/time).
components/Pages.php CHANGED
@@ -1038,15 +1038,17 @@ class Pods_Pages extends PodsComponent {
1038
  if ( ! is_object( $pods ) && 404 != $pods && 0 < strlen( pods_var( 'pod', self::$exists['options'] ) ) ) {
1039
  $slug = pods_var_raw( 'pod_slug', self::$exists['options'], null, null, true );
1040
 
 
 
1041
  // Handle special magic tags
1042
- if ( 0 < strlen( $slug ) ) {
1043
  $slug = pods_evaluate_tags( $slug, true );
1044
  }
1045
 
1046
  $pods = pods( pods_var( 'pod', self::$exists['options'] ), $slug );
1047
 
1048
  // Auto 404 handling if item doesn't exist
1049
- if ( 0 < strlen( $slug ) && ! $pods->exists() && apply_filters( 'pods_pages_auto_404', true, $slug, $pods, self::$exists ) ) {
1050
  $pods = 404;
1051
  }
1052
  }
@@ -1230,7 +1232,7 @@ class Pods_Pages extends PodsComponent {
1230
  /**
1231
  * Handle overriding the template used for a Pods Page.
1232
  *
1233
- * @since TBD
1234
  *
1235
  * @param string $original_template The template to include.
1236
  *
@@ -1317,7 +1319,7 @@ class Pods_Pages extends PodsComponent {
1317
  /**
1318
  * Allow filtering the template to include for a Pods Page.
1319
  *
1320
- * @since TBD
1321
  *
1322
  * @param string $template The template to use.
1323
  * @param array $exists The Pods Page data.
1038
  if ( ! is_object( $pods ) && 404 != $pods && 0 < strlen( pods_var( 'pod', self::$exists['options'] ) ) ) {
1039
  $slug = pods_var_raw( 'pod_slug', self::$exists['options'], null, null, true );
1040
 
1041
+ $has_slug = 0 < strlen( $slug );
1042
+
1043
  // Handle special magic tags
1044
+ if ( $has_slug ) {
1045
  $slug = pods_evaluate_tags( $slug, true );
1046
  }
1047
 
1048
  $pods = pods( pods_var( 'pod', self::$exists['options'] ), $slug );
1049
 
1050
  // Auto 404 handling if item doesn't exist
1051
+ if ( $has_slug && ( empty( $slug ) || ! $pods->exists() ) && apply_filters( 'pods_pages_auto_404', true, $slug, $pods, self::$exists ) ) {
1052
  $pods = 404;
1053
  }
1054
  }
1232
  /**
1233
  * Handle overriding the template used for a Pods Page.
1234
  *
1235
+ * @since 2.8.11
1236
  *
1237
  * @param string $original_template The template to include.
1238
  *
1319
  /**
1320
  * Allow filtering the template to include for a Pods Page.
1321
  *
1322
+ * @since 2.8.11
1323
  *
1324
  * @param string $template The template to use.
1325
  * @param array $exists The Pods Page data.
includes/data.php CHANGED
@@ -2385,7 +2385,7 @@ function pods_bool_to_int( $value ) {
2385
  /**
2386
  * Make replacements to a string using key=>value pairs.
2387
  *
2388
- * @since TBD
2389
  *
2390
  * @param string|array|mixed $value The value to do replacements on.
2391
  * @param array $replacements The key=>value replacements to make.
2385
  /**
2386
  * Make replacements to a string using key=>value pairs.
2387
  *
2388
+ * @since 2.8.11
2389
  *
2390
  * @param string|array|mixed $value The value to do replacements on.
2391
  * @param array $replacements The key=>value replacements to make.
includes/general.php CHANGED
@@ -184,7 +184,7 @@ function pods_error( $error, $obj = null ) {
184
  /**
185
  * Allow filtering whether to force the error mode in cases where multiple exceptions have been used.
186
  *
187
- * @since TBD
188
  *
189
  * @param bool $error_mode_force Whether to force the error mode in cases where multiple exceptions have been used.
190
  */
@@ -456,9 +456,12 @@ function pods_tableless() {
456
  *
457
  * @since 2.8.0
458
  *
 
 
 
459
  * @return bool Whether the wp_podsrel table is enabled.
460
  */
461
- function pods_podsrel_enabled() {
462
  // Disabled when Pods Tableless mode is on.
463
  if ( pods_tableless() ) {
464
  return false;
@@ -469,9 +472,11 @@ function pods_podsrel_enabled() {
469
  *
470
  * @since 2.8.0
471
  *
472
- * @param bool $enabled Whether the wp_podsrel table is enabled.
 
 
473
  */
474
- return (bool) apply_filters( 'pods_podsrel_enabled', true );
475
  }
476
 
477
  /**
@@ -2940,7 +2945,7 @@ function pods_meta_hook_list( $object_type = 'post', $object = null ) {
2940
  /**
2941
  * Allow filtering the list of actions and filters for a specific object type.
2942
  *
2943
- * @since TBD
2944
  *
2945
  * @param array $hooks List of filters and actions for a specific object type.
2946
  * @param string $object_type The object type.
@@ -3774,7 +3779,7 @@ function pods_svg_icon( $icon_path, $default = 'dashicons-database', $mode = 'ba
3774
  /**
3775
  * Determine whether Pods is being used for content types only.
3776
  *
3777
- * @since TBD
3778
  *
3779
  * @param bool $check_constant_only Whether to only check the constant, unless there's a filter overriding things.
3780
  *
@@ -3797,7 +3802,7 @@ function pods_is_types_only( $check_constant_only = false ) {
3797
  /**
3798
  * Allow filtering whether Pods is being used for content types only.
3799
  *
3800
- * @since TBD
3801
  *
3802
  * @param bool $is_types_only Whether Pods is being used for content types only.
3803
  */
184
  /**
185
  * Allow filtering whether to force the error mode in cases where multiple exceptions have been used.
186
  *
187
+ * @since 2.8.11
188
  *
189
  * @param bool $error_mode_force Whether to force the error mode in cases where multiple exceptions have been used.
190
  */
456
  *
457
  * @since 2.8.0
458
  *
459
+ * @param null|Field $field The field object.
460
+ * @param null|string $context The context of the podsrel check (lookup/save).
461
+ *
462
  * @return bool Whether the wp_podsrel table is enabled.
463
  */
464
+ function pods_podsrel_enabled( $field = null, $context = null ) {
465
  // Disabled when Pods Tableless mode is on.
466
  if ( pods_tableless() ) {
467
  return false;
472
  *
473
  * @since 2.8.0
474
  *
475
+ * @param bool $enabled Whether the wp_podsrel table is enabled.
476
+ * @param null|Field $field The field object.
477
+ * @param null|string $context The context of the podsrel check (lookup/save).
478
  */
479
+ return (bool) apply_filters( 'pods_podsrel_enabled', true, $field, $context );
480
  }
481
 
482
  /**
2945
  /**
2946
  * Allow filtering the list of actions and filters for a specific object type.
2947
  *
2948
+ * @since 2.8.11
2949
  *
2950
  * @param array $hooks List of filters and actions for a specific object type.
2951
  * @param string $object_type The object type.
3779
  /**
3780
  * Determine whether Pods is being used for content types only.
3781
  *
3782
+ * @since 2.8.11
3783
  *
3784
  * @param bool $check_constant_only Whether to only check the constant, unless there's a filter overriding things.
3785
  *
3802
  /**
3803
  * Allow filtering whether Pods is being used for content types only.
3804
  *
3805
+ * @since 2.8.11
3806
  *
3807
  * @param bool $is_types_only Whether Pods is being used for content types only.
3808
  */
init.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: Pods - Custom Content Types and Fields
11
  * Plugin URI: https://pods.io/
12
  * Description: Pods is a framework for creating, managing, and deploying customized content types and fields
13
- * Version: 2.8.13
14
  * Author: Pods Framework Team
15
  * Author URI: https://pods.io/about/
16
  * Text Domain: pods
@@ -43,7 +43,7 @@ if ( defined( 'PODS_VERSION' ) || defined( 'PODS_DIR' ) ) {
43
  add_action( 'init', 'pods_deactivate_pods_ui' );
44
  } else {
45
  // Current version.
46
- define( 'PODS_VERSION', '2.8.13' );
47
 
48
  // Current database version, this is the last version the database changed.
49
  define( 'PODS_DB_VERSION', '2.3.5' );
10
  * Plugin Name: Pods - Custom Content Types and Fields
11
  * Plugin URI: https://pods.io/
12
  * Description: Pods is a framework for creating, managing, and deploying customized content types and fields
13
+ * Version: 2.8.14
14
  * Author: Pods Framework Team
15
  * Author URI: https://pods.io/about/
16
  * Text Domain: pods
43
  add_action( 'init', 'pods_deactivate_pods_ui' );
44
  } else {
45
  // Current version.
46
+ define( 'PODS_VERSION', '2.8.14' );
47
 
48
  // Current database version, this is the last version the database changed.
49
  define( 'PODS_DB_VERSION', '2.3.5' );
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: pods, custom post types, custom taxonomies, content types, custom fields,
5
  Requires at least: 5.5
6
  Tested up to: 5.9
7
  Requires PHP: 5.6
8
- Stable tag: 2.8.13
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -156,6 +156,18 @@ Pods really wouldn't be where it is without all the contributions from our [dono
156
 
157
  == Changelog ==
158
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  = 2.8.13 - April 10th, 2022 =
160
 
161
  * Fixed: Resolved PHP issues with PHP 7.x with the WPML integration. (@sc0ttkclark)
5
  Requires at least: 5.5
6
  Tested up to: 5.9
7
  Requires PHP: 5.6
8
+ Stable tag: 2.8.14
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
156
 
157
  == Changelog ==
158
 
159
+ = 2.8.14 - April 15th, 2022 =
160
+
161
+ * Added: New `$params` support in `Pods::total_found( $params )` to support `Pods::find( $params )` shorthand lookups for getting total number of records found more easily. (@sc0ttkclark)
162
+ * Added: New `pods_api_save_field_table_definition_mode` filter allows overriding the definition mode when saving a field (bypass/add/drop/change) for schema management. (@sc0ttkclark)
163
+ * Added: New `pods_podsrel_enabled()` arguments to allow filtering based on the field and context. (@sc0ttkclark)
164
+ * Added: New `pods_data_build_pre_traverse_args` filter allows for overriding the find/replace/traverse/params arguments for a `PodsData::build()` request before relationship traversal runs. (@sc0ttkclark)
165
+ * Added: New `pods_data_traverse_recurse_handle_join` filter allows for overriding the JOIN SQL used for relationship traversal. (@sc0ttkclark)
166
+ * Fixed: Resolved potential PHP issues with path checks in `PodsView` on certain environments. (@sc0ttkclark)
167
+ * Fixed: When a slug is set on a Pods Page, if the slug value comes through as empty due to a path issue, it will now enforce a 404 as expected. (@sc0ttkclark)
168
+ * Fixed: Resolved a few issues with the old field data coming through to the `pods_api_save_field_old_definition` filter. (@sc0ttkclark)
169
+ * Fixed: No longer showing WPDB errors from WPDB when query errors are forced off. (@sc0ttkclark)
170
+
171
  = 2.8.13 - April 10th, 2022 =
172
 
173
  * Fixed: Resolved PHP issues with PHP 7.x with the WPML integration. (@sc0ttkclark)
src/Pods/REST/V1/Endpoints/Base.php CHANGED
@@ -26,13 +26,13 @@ abstract class Base {
26
  public $route;
27
 
28
  /**
29
- * @since TBD
30
  * @var string
31
  */
32
  public $rest_route;
33
 
34
  /**
35
- * @since TBD
36
  * @var string
37
  */
38
  public $rest_doc_route;
@@ -220,7 +220,7 @@ abstract class Base {
220
  /**
221
  * Get the Pod object for a specific item by ID or slug.
222
  *
223
- * @since TBD
224
  *
225
  * @param int|string $id_or_slug The item ID or slug.
226
  *
@@ -239,7 +239,7 @@ abstract class Base {
239
  /**
240
  * Validate the required params are set.
241
  *
242
- * @since TBD
243
  *
244
  * @param object $params The object params.
245
  * @param array $required_params The list of required params.
@@ -273,7 +273,7 @@ abstract class Base {
273
  /**
274
  * Check whether the user has access to the pod item.
275
  *
276
- * @since TBD
277
  *
278
  * @param Pods $pod The Pods object.
279
  * @param string $author_field The author field to check permissions against.
@@ -715,7 +715,7 @@ abstract class Base {
715
  /**
716
  * Register route for the endpoint automatically based on the supported methods.
717
  *
718
- * @since TBD
719
  *
720
  * @param string $namespace The route namespace.
721
  * @param bool $add_to_docs Whether to add the route to the documentation endpoint.
26
  public $route;
27
 
28
  /**
29
+ * @since 2.8.11
30
  * @var string
31
  */
32
  public $rest_route;
33
 
34
  /**
35
+ * @since 2.8.11
36
  * @var string
37
  */
38
  public $rest_doc_route;
220
  /**
221
  * Get the Pod object for a specific item by ID or slug.
222
  *
223
+ * @since 2.8.11
224
  *
225
  * @param int|string $id_or_slug The item ID or slug.
226
  *
239
  /**
240
  * Validate the required params are set.
241
  *
242
+ * @since 2.8.11
243
  *
244
  * @param object $params The object params.
245
  * @param array $required_params The list of required params.
273
  /**
274
  * Check whether the user has access to the pod item.
275
  *
276
+ * @since 2.8.11
277
  *
278
  * @param Pods $pod The Pods object.
279
  * @param string $author_field The author field to check permissions against.
715
  /**
716
  * Register route for the endpoint automatically based on the supported methods.
717
  *
718
+ * @since 2.8.11
719
  *
720
  * @param string $namespace The route namespace.
721
  * @param bool $add_to_docs Whether to add the route to the documentation endpoint.
src/Pods/REST/V1/Endpoints/Field.php CHANGED
@@ -20,14 +20,14 @@ class Field extends Base implements READ_Interface, UPDATE_Interface, DELETE_Int
20
  /**
21
  * {@inheritdoc}
22
  *
23
- * @since TBD
24
  */
25
  public $rest_route = '/fields/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
- * @since TBD
31
  */
32
  public $rest_doc_route = '/fields/{id}';
33
 
20
  /**
21
  * {@inheritdoc}
22
  *
23
+ * @since 2.8.11
24
  */
25
  public $rest_route = '/fields/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
+ * @since 2.8.11
31
  */
32
  public $rest_doc_route = '/fields/{id}';
33
 
src/Pods/REST/V1/Endpoints/Field_Slug.php CHANGED
@@ -16,14 +16,14 @@ class Field_Slug extends Field {
16
  /**
17
  * {@inheritdoc}
18
  *
19
- * @since TBD
20
  */
21
  public $rest_route = '/pods/(?P<pod>[\w\_\-]+)/fields/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
- * @since TBD
27
  */
28
  public $rest_doc_route = '/pods/{pod}/fields/{slug}';
29
 
16
  /**
17
  * {@inheritdoc}
18
  *
19
+ * @since 2.8.11
20
  */
21
  public $rest_route = '/pods/(?P<pod>[\w\_\-]+)/fields/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
+ * @since 2.8.11
27
  */
28
  public $rest_doc_route = '/pods/{pod}/fields/{slug}';
29
 
src/Pods/REST/V1/Endpoints/Group.php CHANGED
@@ -20,14 +20,14 @@ class Group extends Base implements READ_Interface, UPDATE_Interface, DELETE_Int
20
  /**
21
  * {@inheritdoc}
22
  *
23
- * @since TBD
24
  */
25
  public $rest_route = '/groups/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
- * @since TBD
31
  */
32
  public $rest_doc_route = '/groups/{id}';
33
 
20
  /**
21
  * {@inheritdoc}
22
  *
23
+ * @since 2.8.11
24
  */
25
  public $rest_route = '/groups/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
+ * @since 2.8.11
31
  */
32
  public $rest_doc_route = '/groups/{id}';
33
 
src/Pods/REST/V1/Endpoints/Group_Slug.php CHANGED
@@ -16,14 +16,14 @@ class Group_Slug extends Group {
16
  /**
17
  * {@inheritdoc}
18
  *
19
- * @since TBD
20
  */
21
  public $rest_route = '/pods/(?P<pod>[\w\_\-]+)/groups/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
- * @since TBD
27
  */
28
  public $rest_doc_route = '/pods/{pod}/groups/{slug}';
29
 
16
  /**
17
  * {@inheritdoc}
18
  *
19
+ * @since 2.8.11
20
  */
21
  public $rest_route = '/pods/(?P<pod>[\w\_\-]+)/groups/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
+ * @since 2.8.11
27
  */
28
  public $rest_doc_route = '/pods/{pod}/groups/{slug}';
29
 
src/Pods/REST/V1/Endpoints/Pod.php CHANGED
@@ -20,14 +20,14 @@ class Pod extends Base implements READ_Interface, UPDATE_Interface, DELETE_Inter
20
  /**
21
  * {@inheritdoc}
22
  *
23
- * @since TBD
24
  */
25
  public $rest_route = '/pods/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
- * @since TBD
31
  */
32
  public $rest_doc_route = '/pods/{id}';
33
 
20
  /**
21
  * {@inheritdoc}
22
  *
23
+ * @since 2.8.11
24
  */
25
  public $rest_route = '/pods/(?P<id>\\d+)';
26
 
27
  /**
28
  * {@inheritdoc}
29
  *
30
+ * @since 2.8.11
31
  */
32
  public $rest_doc_route = '/pods/{id}';
33
 
src/Pods/REST/V1/Endpoints/Pod_Slug.php CHANGED
@@ -16,14 +16,14 @@ class Pod_Slug extends Pod {
16
  /**
17
  * {@inheritdoc}
18
  *
19
- * @since TBD
20
  */
21
  public $rest_route = '/pods/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
- * @since TBD
27
  */
28
  public $rest_doc_route = '/pods/{slug}';
29
 
16
  /**
17
  * {@inheritdoc}
18
  *
19
+ * @since 2.8.11
20
  */
21
  public $rest_route = '/pods/(?P<slug>[\w\_\-]+)';
22
 
23
  /**
24
  * {@inheritdoc}
25
  *
26
+ * @since 2.8.11
27
  */
28
  public $rest_doc_route = '/pods/{slug}';
29
 
src/Pods/REST/V1/Service_Provider.php CHANGED
@@ -68,7 +68,7 @@ class Service_Provider extends \tad_DI52_ServiceProvider {
68
  /**
69
  * Get the list of endpoints.
70
  *
71
- * @since TBD
72
  *
73
  * @return string[] The list of endpoints.
74
  */
68
  /**
69
  * Get the list of endpoints.
70
  *
71
+ * @since 2.8.11
72
  *
73
  * @return string[] The list of endpoints.
74
  */
src/Pods/REST/V1/Validator/Base.php CHANGED
@@ -27,7 +27,7 @@ class Base extends Validator_Base implements Validator_Interface {
27
  /**
28
  * Determine whether a Pod / Item ID is valid.
29
  *
30
- * @since TBD
31
  *
32
  * @param string $pod The pod name.
33
  * @param int|string $id_or_slug The Item ID or slug.
@@ -43,7 +43,7 @@ class Base extends Validator_Base implements Validator_Interface {
43
  /**
44
  * Determine whether a Pod / Item ID is valid.
45
  *
46
- * @since TBD
47
  *
48
  * @param string $pod The pod name.
49
  * @param int|string $id The item ID.
@@ -57,7 +57,7 @@ class Base extends Validator_Base implements Validator_Interface {
57
  /**
58
  * Determine whether a Pod / Item slug is valid.
59
  *
60
- * @since TBD
61
  *
62
  * @param string $pod The pod name.
63
  * @param int|string $slug The Item slug.
@@ -172,7 +172,7 @@ class Base extends Validator_Base implements Validator_Interface {
172
  /**
173
  * Handle other potential methods automatically if possible.
174
  *
175
- * @since TBD
176
  *
177
  * @param string $name The method name.
178
  * @param array $arguments The arguments provided to the method.
27
  /**
28
  * Determine whether a Pod / Item ID is valid.
29
  *
30
+ * @since 2.8.11
31
  *
32
  * @param string $pod The pod name.
33
  * @param int|string $id_or_slug The Item ID or slug.
43
  /**
44
  * Determine whether a Pod / Item ID is valid.
45
  *
46
+ * @since 2.8.11
47
  *
48
  * @param string $pod The pod name.
49
  * @param int|string $id The item ID.
57
  /**
58
  * Determine whether a Pod / Item slug is valid.
59
  *
60
+ * @since 2.8.11
61
  *
62
  * @param string $pod The pod name.
63
  * @param int|string $slug The Item slug.
172
  /**
173
  * Handle other potential methods automatically if possible.
174
  *
175
+ * @since 2.8.11
176
  *
177
  * @param string $name The method name.
178
  * @param array $arguments The arguments provided to the method.