haxorqt
Home
Console
Upload
information
Create File
Create Folder
About
:
/
home
/
sc1jaqa5103
/
prod.puv-editions.fr
/
wp-content
/
plugins
/
pods
/
src
/
Pods
/
Tools
/
Filename :
Repair.php
back
Copy
<?php namespace Pods\Tools; // Don't load directly. if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } use Exception; use Throwable; use PodsForm; use Pods\Whatsit\Field; use Pods\Whatsit\Group; use Pods\Whatsit\Pod; /** * Repair tool functionality. * * @since 2.9.4 */ class Repair extends Base { /** * Repair Pod configurations. * * @since 3.1.0 * * @param string $mode The repair mode (preview, upgrade, or full). * * @return array The results with information about the repair done. */ public function repair_pods( $mode ) { $this->setup(); $this->errors = []; $is_preview_mode = 'preview' === $mode; $results = []; $results[ __( 'Check for duplicate Pods in the database', 'pods' ) ] = $this->maybe_resolve_pod_conflicts( $mode ); // Check if changes were made to the Pod. $changes_made = [] !== array_filter( $results ); if ( ! $is_preview_mode && $changes_made ) { $this->api->cache_flush_pods(); } $tool_heading = __( 'Repair results', 'pods' ); $results['message_html'] = $this->get_message_html( $tool_heading, $results, $mode ); return $results; } /** * Maybe resolve pod conflicts. * * @since 3.1.0 * * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each pod resolved. */ protected function maybe_resolve_pod_conflicts( $mode ) { $this->setup(); // Find any pod that has the same name as another pod. global $wpdb; $duplicate_pods = $wpdb->get_results( $wpdb->prepare( " SELECT DISTINCT `primary`.`ID` AS `primary_id`, `primary`.`post_name` AS `primary_name`, `duplicate`.`ID` AS `duplicate_id`, `duplicate`.`post_name` AS `duplicate_name` FROM `{$wpdb->posts}` AS `primary` LEFT JOIN `{$wpdb->posts}` AS `duplicate` ON `duplicate`.`post_name` = `primary`.`post_name` WHERE `primary`.`post_type` = %s AND `duplicate`.`ID` != `primary`.`ID` AND `duplicate`.`post_type` = `primary`.`post_type` ORDER BY `primary`.`ID` ", '_pods_pod' ) ); $pods_to_resolve = []; $duplicate_ids = []; foreach ( $duplicate_pods as $duplicate_pod ) { // Skip if we have already referenced a primary pod. if ( isset( $duplicate_ids[ $duplicate_pod->duplicate_id ] ) && $duplicate_ids[ $duplicate_pod->duplicate_id ] === $duplicate_pod->primary_id ) { continue; } $duplicate_ids[ $duplicate_pod->primary_id ] = $duplicate_pod->duplicate_id; if ( ! isset( $pods_to_resolve[ $duplicate_pod->primary_name ] ) ) { $pods_to_resolve[ $duplicate_pod->primary_name ] = []; } try { $pod = $this->api->load_pod( [ 'id' => $duplicate_pod->duplicate_id ] ); if ( $pod ) { $pods_to_resolve[ $duplicate_pod->primary_name ][] = $pod; } else { throw new Exception( __( 'Failed to load duplicate pod to resolve.', 'pods' ) ); } } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $duplicate_pod->duplicate_name . ' - #' . $duplicate_pod->duplicate_id . ' - Primary: ' . $duplicate_pod->primary_name . ' - #' . $duplicate_pod->primary_id . ')'; } } $resolved_pods = []; foreach ( $pods_to_resolve as $primary_pod_name => $pods ) { foreach ( $pods as $pod ) { /** @var Pod $pod */ try { if ( 'preview' !== $mode ) { // Prevent renaming the original pod data by using a temp one first, then renaming that. wp_update_post( [ 'ID' => $pod->get_id(), 'post_name' => '_temp_' . $primary_pod_name . '_' . $pod->get_id(), ] ); // Flush the pod cache. $this->api->cache_flush_pods(); // Save the pod with the new name. $this->api->save_pod( [ 'id' => $pod->get_id(), 'old_name' => '_temp_' . $primary_pod_name . '_' . $pod->get_id(), 'name' => $primary_pod_name . '_' . $pod->get_id(), 'label' => $pod->get_label() . ' (' . $pod->get_id() . ')', ], false ); $pod->flush(); } $resolved_pods[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$d)', $pod->get_label(), __( 'Old Name', 'pods' ), $primary_pod_name, __( 'New Name', 'pods' ), $primary_pod_name . '_' . $pod->get_id(), __( 'ID', 'pods' ), $pod->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $pod->get_name() . ' - #' . $pod->get_id() . ')'; } } } return $resolved_pods; } /** * Repair Groups and Fields for a Pod. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return array The results with information about the repair done. */ public function repair_groups_and_fields_for_pod( Pod $pod, $mode ) { $this->setup(); $this->errors = []; $is_preview_mode = 'preview' === $mode; $is_upgrade_mode = 'upgrade' === $mode; $is_migrated = 1 === (int) $pod->get_arg( '_migrated_28' ); // Maybe set up a new group if no groups are found for the Pod. $group_id = $this->maybe_setup_group_if_no_groups( $pod, $mode ); $results = []; // Maybe fix fields with invalid pod/storage type. $results[ __( 'Fixed pod with invalid pod type', 'pods' ) ] = $this->maybe_fix_pod_with_invalid_pod_type( $pod, $mode ); $results[ __( 'Fixed pod with invalid pod storage type', 'pods' ) ] = $this->maybe_fix_pod_with_invalid_pod_storage_type( $pod, $mode ); // If no group needed to be created, attempt to find the first group ID. if ( null === $group_id ) { $groups = $pod->get_groups( [ 'fallback_mode' => false, 'limit' => 1, ] ); $groups = wp_list_pluck( $groups, 'id' ); $groups = array_filter( $groups ); // Get the first group ID. if ( ! empty( $groups ) ) { $group_id = reset( $groups ); } } else { $results[ __( 'Setup group if there were no groups', 'pods' ) ] = __( 'First group created.', 'pods' ); } if ( ! $is_upgrade_mode || $is_migrated ) { // Maybe resolve group conflicts. $results[ __( 'Resolved group conflicts', 'pods' ) ] = $this->maybe_resolve_group_conflicts( $pod, $mode ); // Maybe resolve field conflicts. $results[ __( 'Resolved field conflicts', 'pods' ) ] = $this->maybe_resolve_field_conflicts( $pod, $mode ); } // If we have a group to work with, use that. if ( null !== $group_id ) { if ( ! $is_upgrade_mode || $is_migrated ) { // Maybe reassign fields with invalid groups. $results[ __( 'Reassigned fields with invalid groups', 'pods' ) ] = $this->maybe_reassign_fields_with_invalid_groups( $pod, $group_id, $mode ); } // Maybe reassign orphan fields to the first group. $results[ __( 'Reassigned orphan fields', 'pods' ) ] = $this->maybe_reassign_orphan_fields( $pod, $group_id, $mode ); } // Maybe fix fields with invalid field type. $results[ __( 'Fixed fields with invalid field type', 'pods' ) ] = $this->maybe_fix_fields_with_invalid_field_type( $pod, $mode ); // Maybe fix fields with invalid arguments. $results[ __( 'Fixed fields with invalid arguments', 'pods' ) ] = $this->maybe_fix_fields_with_invalid_args( $pod, $mode ); // Check if changes were made to the Pod. $changes_made = [] !== array_filter( $results ); // Mark the pod as migrated if upgrading and only save the Pod if changes were made or the migrated tag is not set. if ( $is_upgrade_mode && ( $changes_made || 0 === (int) $pod->get_arg( '_migrated_28', 0 ) ) ) { $pod->set_arg( '_migrated_28', 1 ); try { $this->api->save_pod( $pod ); } catch ( Throwable $exception ) { pods_debug_log( $exception ); } // Refresh pod object. $pod->flush(); } elseif ( ! $is_preview_mode && $changes_made ) { $this->api->cache_flush_pods( $pod ); // Refresh pod object. $pod->flush(); } $tool_heading = sprintf( // translators: %s: The Pod label. __( 'Repair results for %s', 'pods' ), $pod->get_label() . ' (' . $pod->get_name() . ')' ); $results['message_html'] = $this->get_message_html( $tool_heading, $results, $mode ); if ( $is_upgrade_mode ) { $results['upgraded_pod'] = $pod; } return $results; } /** * Maybe fix pods with invalid pod type. * * @since 2.9.15 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each pod fixed. */ protected function maybe_fix_pod_with_invalid_pod_type( Pod $pod, $mode ) { $this->setup(); $supported_pod_types = pods_api()->get_pod_types(); $old_type = $pod->get_type(); $messages = []; if ( ! isset( $supported_pod_types[ $old_type ] ) ) { try { if ( $pod->get_id() <= 0 ) { $this->errors[] = __( 'Unable to repair a Pod that was not registered in the database.', 'pods' ); return []; } if ( 'preview' !== $mode ) { $this->api->save_pod( [ 'id' => $pod->get_id(), 'type' => 'post_type', ] ); $pod->set_arg( 'type', 'post_type' ); } $messages[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$d)', $pod->get_label(), __( 'Old Type', 'pods' ), $old_type, __( 'Name', 'pods' ), $pod->get_name(), __( 'ID', 'pods' ), $pod->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $pod->get_name() . ' - #' . $pod->get_id() . ')'; } } return $messages; } /** * Maybe fix pods with invalid pod storage type. * * @since 2.9.15 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each pod fixed. */ protected function maybe_fix_pod_with_invalid_pod_storage_type( Pod $pod, $mode ) { $this->setup(); $supported_storage_types = pods_api()->get_storage_types(); $old_storage_type = $pod->get_storage( true ); if ( empty( $old_storage_type ) ) { $old_storage_type = 'n/a'; } $pod_type = $pod->get_type(); $force_storage_update = false; if ( 'meta' === $old_storage_type && in_array( $pod_type, [ 'pod', 'table', 'settings' ], true ) ) { $force_storage_update = true; } $new_storage_type = $pod->get_default_storage(); $messages = []; if ( $force_storage_update || ! isset( $supported_storage_types[ $old_storage_type ] ) ) { try { if ( $pod->get_id() <= 0 ) { $this->errors[] = __( 'Unable to repair a Pod that was not registered in the database.', 'pods' ); return []; } if ( 'preview' !== $mode ) { // Save the pod but don't overwrite the DB table schema if it exists. $this->api->save_pod( [ 'id' => $pod->get_id(), 'storage' => $new_storage_type, 'overwrite_table_schema' => false, ] ); $pod->set_arg( 'storage', $new_storage_type ); } $messages[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$s | %8$s: %9$s | %10$s: %11$d)', $pod->get_label(), __( 'Old Storage Type', 'pods' ), $old_storage_type, __( 'New Storage Type', 'pods' ), $new_storage_type, __( 'Name', 'pods' ), $pod->get_name(), __( 'Type', 'pods' ), $pod_type, __( 'ID', 'pods' ), $pod->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $pod->get_name() . ' - #' . $pod->get_id() . ')'; } } return $messages; } /** * Maybe setup group if there are no groups. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (upgrade or full). * * @return int|null The group ID if created, otherwise null if repair not needed. */ protected function maybe_setup_group_if_no_groups( Pod $pod, $mode ) { $this->setup(); $groups = $pod->get_groups( [ 'fallback_mode' => false, ] ); // Groups exist, no need to create a group. if ( ! empty( $groups ) ) { return null; } // For upgrade mode, we create the first group even if there are no fields. if ( 'upgrade' !== $mode ) { $fields = $pod->get_fields( [ 'fallback_mode' => false, ] ); // No fields, no need to create a group. if ( empty( $fields ) ) { return null; } } $group_label = __( 'Details', 'pods' ); if ( in_array( $pod->get_type(), [ 'post_type', 'taxonomy', 'user', 'comment', 'media' ], true ) ) { $group_label = __( 'More Fields', 'pods' ); } /** * Filter the title of the Pods Metabox used in the post editor. * * @since unknown * * @param string $title The title to use, default is 'More Fields'. * @param obj|Pod $pod Current Pods Object. * @param array $fields Array of fields that will go in the metabox. * @param string $type The type of Pod. * @param string $name Name of the Pod. */ $group_label = apply_filters( 'pods_meta_default_box_title', $group_label, $pod, $pod->get_fields(), $pod->get_type(), $pod->get_name() ); $group_name = sanitize_key( pods_js_name( sanitize_title( $group_label ) ) ); try { $new_group_name = $group_name; $counter = 2; do { $conflicting_group_found = $this->api->load_group( [ 'pod' => $pod, 'name' => $group_name, ] ); if ( $conflicting_group_found ) { $group_name = $new_group_name . '-' . $counter; } $counter ++; } while ( $this->api->load_group( [ 'pod' => $pod, 'name' => $group_name, ] ) ); if ( 'preview' !== $mode ) { // Setup first group. $group_id = $this->api->save_group( [ 'pod' => $pod, 'name' => $group_name, 'label' => $group_label, ] ); } else { $group_id = 1234567890123456789; } if ( $group_id && is_numeric( $group_id ) ) { return $group_id; } throw new Exception( __( 'Failed to create new default group.', 'pods' ) ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $group_name . ')'; } return null; } /** * Maybe resolve group conflicts. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each group resolved. */ protected function maybe_resolve_group_conflicts( Pod $pod, $mode ) { $this->setup(); // Find any group on the pod that has the same name as another group. global $wpdb; $duplicate_groups = $wpdb->get_results( $wpdb->prepare( " SELECT DISTINCT `primary`.`ID`, `primary`.`post_name` FROM `{$wpdb->posts}` AS `primary` LEFT JOIN `{$wpdb->posts}` AS `duplicate` ON `duplicate`.`post_name` = `primary`.`post_name` WHERE `primary`.`post_type` = %s AND `primary`.`post_parent` = %d AND `duplicate`.`ID` != `primary`.`ID` AND `duplicate`.`post_type` = `primary`.`post_type` AND `duplicate`.`post_parent` = `primary`.`post_parent` ORDER BY `primary`.`ID` ", [ '_pods_group', $pod->get_id(), ] ) ); $groups_to_resolve = []; foreach ( $duplicate_groups as $duplicate_group ) { if ( ! isset( $groups_to_resolve[ $duplicate_group->post_name ] ) ) { $groups_to_resolve[ $duplicate_group->post_name ] = []; } try { $group = $this->api->load_group( [ 'id' => $duplicate_group->ID ] ); if ( $group ) { $groups_to_resolve[ $duplicate_group->post_name ][] = $group; } else { throw new Exception( __( 'Failed to load duplicate group to resolve.', 'pods' ) ); } } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $duplicate_group->post_name . ' - #' . $duplicate_group->ID . ')'; } } $resolved_groups = []; foreach ( $groups_to_resolve as $group_name => $groups ) { if ( 1 < count( $groups ) ) { // Remove the first group. array_shift( $groups ); } foreach ( $groups as $group ) { /** @var Group $group */ try { if ( 'preview' !== $mode ) { $this->api->save_group( [ 'id' => $group->get_id(), 'pod_data' => $pod, 'group' => $group, 'new_name' => $group_name . '_' . $group->get_id(), ] ); } $resolved_groups[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$d)', $group->get_label(), __( 'Old Name', 'pods' ), $group_name, __( 'New Name', 'pods' ), $group_name . '_' . $group->get_id(), __( 'ID', 'pods' ), $group->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $group->get_name() . ' - #' . $group->get_id() . ')'; } } } return $resolved_groups; } /** * Maybe resolve field conflicts. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field resolved. */ protected function maybe_resolve_field_conflicts( Pod $pod, $mode ) { $this->setup(); // Find any field on the pod that has the same name as another field. global $wpdb; $duplicate_fields = $wpdb->get_results( $wpdb->prepare( " SELECT DISTINCT `primary`.`ID` AS `primary_id`, `primary`.`post_name` AS `primary_name`, `duplicate`.`ID` AS `duplicate_id`, `duplicate`.`post_name` AS `duplicate_name` FROM `{$wpdb->posts}` AS `primary` LEFT JOIN `{$wpdb->posts}` AS `duplicate` ON `duplicate`.`post_name` = `primary`.`post_name` WHERE `primary`.`post_type` = %s AND `primary`.`post_parent` = %d AND `duplicate`.`ID` != `primary`.`ID` AND `duplicate`.`post_type` = `primary`.`post_type` AND `duplicate`.`post_parent` = `primary`.`post_parent` ORDER BY `primary`.`ID` ", [ '_pods_field', $pod->get_id(), ] ) ); $fields_to_resolve = []; foreach ( $duplicate_fields as $duplicate_field ) { if ( ! isset( $fields_to_resolve[ $duplicate_field->primary_name ] ) ) { $fields_to_resolve[ $duplicate_field->primary_name ] = []; } try { $field = $this->api->load_field( [ 'id' => $duplicate_field->duplicate_id ] ); if ( $field ) { $fields_to_resolve[ $duplicate_field->primary_name ][] = $field; } else { throw new Exception( __( 'Failed to load duplicate field to resolve.', 'pods' ) ); } } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $duplicate_field->duplicate_name . ' - #' . $duplicate_field->duplicate_id . ' - Primary: ' . $duplicate_field->primary_name . ' - #' . $duplicate_field->primary_id . ')'; } } $resolved_fields = []; foreach ( $fields_to_resolve as $primary_field_name => $fields ) { foreach ( $fields as $field ) { /** @var Field $field */ try { if ( 'preview' !== $mode ) { // Prevent renaming the original field data by using a temp one first, then renaming that. wp_update_post( [ 'ID' => $field->get_id(), 'post_name' => '_temp_' . $primary_field_name . '_' . $field->get_id(), ] ); // Flush the field cache. $this->api->cache_flush_fields(); // Save the field with the new name. $this->api->save_field( [ 'id' => $field->get_id(), 'pod_data' => $pod, 'field' => $field, 'new_name' => $primary_field_name . '_' . $field->get_id(), ], false ); } $resolved_fields[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$d)', $field->get_label(), __( 'Old Name', 'pods' ), $primary_field_name, __( 'New Name', 'pods' ), $primary_field_name . '_' . $field->get_id(), __( 'ID', 'pods' ), $field->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $field->get_name() . ' - #' . $field->get_id() . ')'; } } } return $resolved_fields; } /** * Maybe reassign fields with invalid groups. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param int $group_id The group ID. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field reassigned. */ protected function maybe_reassign_fields_with_invalid_groups( Pod $pod, $group_id, $mode ) { $this->setup(); // Get all known group IDs. $groups = $pod->get_groups( [ 'fallback_mode' => false, ] ); $groups = wp_list_pluck( $groups, 'id' ); $groups = array_values( array_filter( $groups ) ); if ( $group_id ) { $groups[] = $group_id; } $groups = array_unique( $groups ); $fields = $pod->get_fields( [ 'fallback_mode' => false, 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query [ 'key' => 'group', 'value' => $groups, 'compare' => 'NOT IN', ], ], ] ); return $this->reassign_fields_to_group( $fields, $group_id, $pod, $mode ); } /** * Maybe reassign orphan fields. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param int $group_id The group ID. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field reassigned. */ protected function maybe_reassign_orphan_fields( Pod $pod, $group_id, $mode ) { $this->setup(); $fields = $pod->get_fields( [ 'fallback_mode' => false, 'group' => null, ] ); return $this->reassign_fields_to_group( $fields, $group_id, $pod, $mode ); } /** * Reassign fields to a specific group. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param int $group_id The group ID. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field reassigned. */ protected function reassign_fields_to_group( $fields, $group_id, $pod, $mode ) { $this->setup(); $reassigned_fields = []; foreach ( $fields as $field ) { if ( $field->get_arg( 'group' ) === $group_id ) { continue; } try { if ( 'preview' !== $mode ) { $this->api->save_field( [ 'id' => $field->get_id(), 'pod_data' => $pod, 'field' => $field, 'new_group_id' => $group_id, ] ); $field->set_arg( 'group', $group_id ); } $reassigned_fields[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$d)', $field->get_label(), __( 'Name', 'pods' ), $field->get_name(), __( 'ID', 'pods' ), $field->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $field->get_name() . ' - #' . $field->get_id() . ')'; } } return $reassigned_fields; } /** * Maybe fix fields with invalid field type. * * @since 2.9.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field fixed. */ protected function maybe_fix_fields_with_invalid_field_type( Pod $pod, $mode ) { $this->setup(); $supported_field_types = PodsForm::field_types_list(); $fields = $pod->get_fields( [ 'fallback_mode' => false, 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'relation' => 'OR', [ 'key' => 'type', 'value' => $supported_field_types, 'compare' => 'NOT IN', ], [ 'key' => 'type', 'compare' => 'NOT EXISTS', ], ], ] ); $fixed_fields = []; foreach ( $fields as $field ) { try { $old_type = $field->get_type(); if ( empty( $old_type ) ) { $old_type = __( 'N/A', 'pods' ); } if ( 'preview' !== $mode ) { $this->api->save_field( [ 'id' => $field->get_id(), 'pod_data' => $pod, 'field' => $field, 'type' => 'text', ] ); $field->set_arg( 'type', 'text' ); } $fixed_fields[] = sprintf( '%1$s (%2$s: %3$s | %4$s: %5$s | %6$s: %7$d)', $field->get_label(), __( 'Old Type', 'pods' ), $old_type, __( 'Name', 'pods' ), $field->get_name(), __( 'ID', 'pods' ), $field->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $field->get_name() . ' - #' . $field->get_id() . ')'; } } return $fixed_fields; } /** * Maybe fix pod fields with invalid arguments. * * @since 3.0.4 * * @param Pod $pod The Pod object. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[] The label, name, and ID for each field fixed. */ protected function maybe_fix_fields_with_invalid_args( Pod $pod, $mode ) { $this->setup(); $invalid_args = [ 'conditional_logic', 'attributes', 'grouped', 'depends-on', 'depends-on-any', 'depends-on-multi', 'excludes-on', 'wildcard-on', ]; $fixed_fields = []; foreach ( $invalid_args as $invalid_arg ) { $meta_query_check = [ 'key' => $invalid_arg, 'compare' => 'EXISTS', ]; if ( 'conditional_logic' === $invalid_arg ) { $meta_query_check['value'] = 'a:0:{}'; $meta_query_check['compare'] = 'LIKE'; } $fields = $pod->get_fields( [ 'fallback_mode' => false, 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query $meta_query_check, ], ] ); foreach ( $fields as $field ) { $fixed_field = $this->maybe_fix_fields_with_invalid_args_for_field( $pod, $field, $invalid_arg, $mode ); if ( $fixed_field ) { $fixed_fields[] = $fixed_field; } } } return $fixed_fields; } /** * Maybe fix a field with invalid arguments. * * @since 3.0.4 * * @param Pod $pod The Pod object. * @param Field $field The Field object. * @param string $invalid_arg The invalid argument. * @param string $mode The repair mode (preview, upgrade, or full). * * @return string[]|false The label, name, and ID for the field fixed, or false if not fixed. */ protected function maybe_fix_fields_with_invalid_args_for_field( Pod $pod, Field $field, string $invalid_arg, $mode ) { $this->setup(); $field_id = $field->get_id(); if ( empty( $field_id ) ) { return false; } $invalid_args = [ 'conditional_logic', 'attributes', 'grouped', 'depends-on', 'depends-on-any', 'depends-on-multi', 'excludes-on', 'wildcard-on', ]; try { $found_invalid_args = [ $invalid_arg => null, ]; foreach ( $invalid_args as $other_invalid_arg ) { $arg_value = $field->get_arg( $other_invalid_arg, null, false, true ); if ( null !== $arg_value ) { if ( 'conditional_logic' !== $invalid_arg && 'conditional_logic' === $other_invalid_arg && ( empty( $arg_value ) || is_array( $arg_value ) ) ) { continue; } $found_invalid_args[ $other_invalid_arg ] = $arg_value; } } if ( 'preview' !== $mode ) { foreach ( $found_invalid_args as $found_invalid_arg => $arg_value ) { if ( 'conditional_logic' === $found_invalid_arg ) { update_post_meta( $field_id, 'enable_conditional_logic', 0 ); $field->set_arg( 'enable_conditional_logic', 0 ); } delete_post_meta( $field_id, $found_invalid_arg ); $field->set_arg( $found_invalid_arg, null ); } pods_api()->cache_flush_fields(); } return sprintf( '%1$s (%2$s: [%3$s] | %4$s: %5$s | %6$s: %7$d)', $field->get_label(), __( 'Fixed invalid conditional logic args', 'pods' ), implode( ', ', array_keys( $found_invalid_args ) ), __( 'Name', 'pods' ), $field->get_name(), __( 'ID', 'pods' ), $field->get_id() ); } catch ( Throwable $exception ) { $this->errors[] = ucwords( str_replace( '_', ' ', __FUNCTION__ ) ) . ' > ' . $exception->getMessage() . ' (' . $field->get_name() . ' - #' . $field->get_id() . ')'; } return false; } }