gabetu

Voxel calculate and save completition score as meta field

Jul 30th, 2025
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.46 KB | None | 0 0
  1. /**
  2.  * ===================================================================
  3.  * PART 1: The Central Calculation Function
  4.  * This function holds all the scoring logic and works when a place is updated or newly created.
  5.  * ===================================================================
  6.  */
  7. function vx_update_single_place_score( $post_id ) {
  8.     // Get the Voxel post object.
  9.     $post = \Voxel\Post::get( $post_id );
  10.  
  11.     // Ensure the post exists and is the correct post type.
  12.     if ( ! $post || $post->post_type->get_key() !== 'places' ) {
  13.         return;
  14.     }
  15.  
  16.     // Initialize score.
  17.     $score = 0;
  18.  
  19.     // --- Start of your calculation logic ---
  20.  
  21.     // Define fields to check and their point values.
  22.     $fields = [
  23.         'logo'     => 5,
  24.         '_thumbnail_id' => 5,
  25.         'text-2'   => 5,
  26.         'location' => 5,
  27.         'phone'    => 5,
  28.         'email'    => 5,
  29.         'website'  => 5,
  30.         'url'      => 5,
  31.         'url-2'    => 5,
  32.         'taxonomy' => 5,
  33.         'amenities' => 5,
  34.         'taxonomy-2' => 5,
  35.         'taxonomy-4' => 5,
  36.         'work-hours' => 5,
  37.     ];
  38.  
  39.     // Loop through standard fields and add points if they are not empty.
  40.     foreach ( $fields as $field_key => $points ) {
  41.         $field_object = $post->get_field( $field_key );
  42.         if ( ! $field_object ) {
  43.             continue;
  44.         }
  45.  
  46.         $value = $field_object->get_value();
  47.         if ( ! empty( $value ) ) {
  48.             $score += $points;
  49.         }
  50.     }
  51.  
  52.     // Handle gallery field separately.
  53.     $gallery_field = $post->get_field( 'gallery' );
  54.     if ( $gallery_field ) {
  55.         $gallery_value = $gallery_field->get_value();
  56.         if ( ! empty( $gallery_value ) && is_array( $gallery_value ) ) {
  57.             $gallery_count = count( $gallery_value );
  58.             if ( $gallery_count <= 3 ) {
  59.                 $score += 5;
  60.             } else {
  61.                 $score += 15;
  62.             }
  63.         }
  64.     }
  65.  
  66.     // Handle services repeater field.
  67.     $services_field = $post->get_field( 'services' );
  68.     if ( $services_field ) {
  69.         $services_value = $services_field->get_value();
  70.         $services_count = 0;
  71.         if ( ! empty( $services_value ) ) {
  72.             // Voxel usually returns an array, but this handles JSON strings just in case.
  73.             $services_data = is_string( $services_value ) ? json_decode( $services_value, true ) : $services_value;
  74.             if ( is_array( $services_data ) ) {
  75.                 foreach ( $services_data as $service ) {
  76.                     if ( ! empty( $service['text'] ) ) {
  77.                         $services_count++;
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.        
  83.         if ( $services_count > 0 && $services_count <= 3 ) {
  84.             $score += 5;
  85.         } elseif ( $services_count > 3 ) {
  86.             $score += 15;
  87.         }
  88.     }
  89.  
  90.     // --- End of your calculation logic ---
  91.  
  92.     // Update the score field with the final calculated score.
  93.     $score_field = $post->get_field( 'score' );
  94.     if ( $score_field ) {
  95.         $score_field->update( $score );
  96.     }
  97. }
  98.  
  99. add_action( 'voxel/app-events/post-types/places/post:submitted', function( $event ) {
  100.     vx_update_single_place_score( $event->post->get_id() );
  101. } );
  102.  
  103. add_action( 'voxel/app-events/post-types/places/post:updated', function( $event ) {
  104.     vx_update_single_place_score( $event->post->get_id() );
  105. } );
  106.  
  107.  
  108. /**
  109.  * ===================================================================
  110.  * PART 2: Update existing places
  111.  * Delete this function after updating score meta field for all places.
  112.  * ===================================================================
  113.  */
  114.  
  115. function update_all_places_posts() {
  116.     // Initialize result array
  117.     $results = array(
  118.         'updated' => 0,
  119.         'errors' => 0,
  120.         'error_messages' => array(),
  121.         'debug' => array()
  122.     );
  123.  
  124.     // Query arguments to get all 'places' posts
  125.     $args = array(
  126.         'post_type' => 'places',
  127.         'posts_per_page' => -1, // Get all posts
  128.         'post_status' => 'any', // Include all statuses
  129.         'fields' => 'ids' // Only need post IDs for efficiency
  130.     );
  131.  
  132.     // Get all places posts
  133.     $places_query = new WP_Query($args);
  134.     $place_ids = $places_query->posts;
  135.  
  136.     if (empty($place_ids)) {
  137.         $results['error_messages'][] = 'No places posts found.';
  138.         return $results;
  139.     }
  140.  
  141.     // Loop through each post
  142.     foreach ($place_ids as $post_id) {
  143.         try {
  144.             // Call the custom function to update the score
  145.             $result = vx_update_single_place_score($post_id);
  146.            
  147.             if ($result === false) {
  148.                 $results['errors']++;
  149.                 $results['error_messages'][] = "Failed to update score for post ID {$post_id} using vx_update_single_place_score.";
  150.                 $results['debug'][] = "Post ID {$post_id}: vx_update_single_place_score returned false.";
  151.             } else {
  152.                 // Update post modified date
  153.                 $post_update = array(
  154.                     'ID' => $post_id,
  155.                     'post_modified' => current_time('mysql'),
  156.                     'post_modified_gmt' => current_time('mysql', 1)
  157.                 );
  158.                 $update_result = wp_update_post($post_update);
  159.                
  160.                 if (is_wp_error($update_result)) {
  161.                     $results['errors']++;
  162.                     $results['error_messages'][] = "Failed to update modified date for post ID {$post_id}: " . $update_result->get_error_message();
  163.                 } else {
  164.                     $results['updated']++;
  165.                     $results['debug'][] = "Post ID {$post_id}: Successfully updated score.";
  166.                 }
  167.             }
  168.         } catch (Exception $e) {
  169.             $results['errors']++;
  170.             $results['error_messages'][] = "Error processing post ID {$post_id}: " . $e->getMessage();
  171.         }
  172.     }
  173.  
  174.     // Reset post data
  175.     wp_reset_postdata();
  176.  
  177.     // Log debug information to a file
  178.     if (!empty($results['debug'])) {
  179.         error_log("Places Bulk Update Debug (" . current_time('mysql') . "):\n" . implode("\n", $results['debug']) . "\n", 3, WP_CONTENT_DIR . '/places-update-debug.log');
  180.     }
  181.  
  182.     return $results;
  183. }
  184.  
  185. /**
  186.  * Add admin menu item for manual bulk updating
  187.  */
  188. function add_places_update_menu() {
  189.     add_submenu_page(
  190.         'edit.php?post_type=places',
  191.         'Bulk Update Places Scores',
  192.         'Bulk Update Scores',
  193.         'manage_options',
  194.         'bulk-update-places',
  195.         'render_places_update_page'
  196.     );
  197. }
  198. add_action('admin_menu', 'add_places_update_menu');
  199.  
  200. /**
  201.  * Render the admin page for manual bulk updating
  202.  */
  203. function render_places_update_page() {
  204.     if (!current_user_can('manage_options')) {
  205.         wp_die('You do not have sufficient permissions to access this page.');
  206.     }
  207.  
  208.     $message = '';
  209.    
  210.     if (isset($_POST['bulk_update_places']) && check_admin_referer('bulk_update_places_action')) {
  211.         $results = update_all_places_posts();
  212.        
  213.         $message = sprintf(
  214.             'Update complete. Updated %d posts. Encountered %d errors.',
  215.             $results['updated'],
  216.             $results['errors']
  217.         );
  218.        
  219.         if (!empty($results['error_messages'])) {
  220.             $message .= '<br>Errors:<ul>';
  221.             foreach ($results['error_messages'] as $error) {
  222.                 $message .= '<li>' . esc_html($error) . '</li>';
  223.             }
  224.             $message .= '</ul>';
  225.         }
  226.  
  227.         if (!empty($results['debug'])) {
  228.             $message .= '<br>Debug Info:<ul>';
  229.             foreach ($results['debug'] as $debug) {
  230.                 $message .= '<li>' . esc_html($debug) . '</li>';
  231.             }
  232.             $message .= '</ul>';
  233.             $message .= '<p>Additional debug information has been logged to ' . WP_CONTENT_DIR . '/places-update-debug.log</p>';
  234.         }
  235.     }
  236.     ?>
  237.     <div class="wrap">
  238.         <h1>Bulk Update Places Scores</h1>
  239.         <?php if ($message) : ?>
  240.             <div class="notice notice-info is-dismissible">
  241.                 <p><?php echo $message; ?></p>
  242.             </div>
  243.         <?php endif; ?>
  244.         <form method="post" action="">
  245.             <?php wp_nonce_field('bulk_update_places_action'); ?>
  246.             <p>This will recalculate and update the 'score' meta field for all Places posts using the vx_update_single_place_score function.</p>
  247.             <?php submit_button('Update All Places Scores', 'primary', 'bulk_update_places'); ?>
  248.         </form>
  249.     </div>
  250.     <?php
  251. }
Advertisement
Add Comment
Please, Sign In to add comment