HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux ip-172-31-4-197 6.8.0-1036-aws #38~22.04.1-Ubuntu SMP Fri Aug 22 15:44:33 UTC 2025 x86_64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/html/wordpress/wp-content/plugins/trinity-audio/inc/post-hashes-bulk-update.php
<?php
  require_once __DIR__ . '/post-hashes.php';

  const TRINITY_AUDIO_PHBU_BATCH_RETRY       = 'trinity_audio_phbu_batch_retry';
  const TRINITY_AUDIO_PHBU_HEARTBEAT         = 'trinity_audio_phbu_heartbeat';
  const TRINITY_AUDIO_PHBU_IN_PROGRESS       = 'trinity_audio_phbu_in_progress';
  const TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM   = 'trinity_audio_phbu_total_posts_num';
  const TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM = 'trinity_audio_phbu_updated_posts_num';
  const TRINITY_AUDIO_PHBU_BULK_SIZE         = 'trinity_audio_phbu_bulk_size';
  const TRINITY_AUDIO_PHBU_FAILED_POSTS      = 'trinity_audio_phbu_failed_posts';
  // for UI to show at the very end, since we will cleanup our values, so need to keep then for short period of time
  const TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM_UI   = 'trinity_audio_phbu_total_posts_num_ui';
  const TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM_UI = 'trinity_audio_phbu_updated_posts_num_ui';

  const TRINITY_AUDIO_PHBU_BULK_UPDATE_DONE = 'trinity_audio_phbu_bulk_update_done';

  const TRINITY_MAX_POSTS_PER_BATCH = 200;
  const TTL_FOR_UI                  = 4;

  function trinity_phbu_continue() {
    trinity_phbu_start(true);
  }

  // we have a separate function which has nonce checking, since we also run trinity_phbu_start() it via cron which doesn't require nonce checking
  function trinity_phbu_start_from_admin() {
    check_ajax_referer('audio_bulk_update_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    trinity_phbu_start();
  }

  /**
   * Manual triggering bulk update via pressing Save button (if skip HTML tags or shortcodes were changed)
   * or via init wp hook with is_continue flag as true
   * @return void
   */
  function trinity_phbu_start($is_continue = false) {
    // if there's already a running process, exit
    if (trinity_phbu_is_bulk_update_alive()) return;

    if ($is_continue) {
      // if there isn't one in progress, no need to recover
      if (!trinity_phbu_get_in_progress()) return;
      if (!trinity_phbu_is_iteration_allowed()) return;

      // set it ASAP
      trinity_phbu_set_process_in_progress();

      // we were interrupted - so this is a batch retry
      trinity_phbu_set_batch_retry(trinity_phbu_get_batch_retry() + 1);
      trinity_log('Triggered from wp_action to continue bulk update...', '', '', TRINITY_AUDIO_ERROR_TYPES::warn);
      trinity_send_graphite_metric('wordpress.bulk-update.v2.continue');
    } else {
      // set it ASAP
      trinity_phbu_set_process_in_progress();

      trinity_log('Triggered bulk update...', '', '');

      trinity_send_graphite_metric('wordpress.bulk-update.v2.start');
      trinity_phbu_reset();
    }

    // get posts that are remains to process
    $updated_posts = trinity_phbu_get_updated_posts_num();
    $batch_retry   = trinity_phbu_get_batch_retry();
    $bulk_size     = trinity_phbu_get_bulk_size_value($batch_retry);
    $post_ids      = trinity_get_posts($updated_posts, $bulk_size);

    $total_posts = trinity_phbu_get_total_posts();
    trinity_phbu_set_total_posts_num($total_posts);

    while (!empty($post_ids)) {
      trinity_phbu_update_heartbeat();

      $next_posts_count = sizeof($post_ids);
      trinity_log("Updated posts: $updated_posts/$total_posts. Updating next $next_posts_count posts... Batch retry: $batch_retry");

      // perform bulk-update for these posts
      $result_code = trinity_ph_update_bulk_update($post_ids, $total_posts, $updated_posts, $batch_retry);
      if ($result_code === -1) {
        trinity_phbu_stopped_by_server();
        return;
      }

      // update progress
      $updated_posts += count($post_ids);
      trinity_phbu_set_updated_posts_num($updated_posts);
      trinity_phbu_set_batch_retry(0);

      // next batch!
      $post_ids = trinity_get_posts($updated_posts, $bulk_size);
    }

    trinity_send_graphite_metric('wordpress.bulk-update.v2.success');
    trinity_phbu_done();
  }

  function trinity_phbu_stopped_by_server() {
    trinity_log('Stopped by server', '', '', TRINITY_AUDIO_ERROR_TYPES::warn);
    trinity_send_graphite_metric('wordpress.bulk-update.v2.stopped-by-server');
    trinity_phbu_cleanup();
  }

  function trinity_phbu_set_process_in_progress() {
    trinity_phbu_set_in_progress(true);

    // marking as running process to avoid multiple runs
    trinity_phbu_update_heartbeat();
  }

  function trinity_phbu_is_iteration_allowed(): bool {
    $retry               = trinity_phbu_get_batch_retry();
    $max_allowed_retries = 10;

    if ($retry > $max_allowed_retries) {
      trinity_log("Post hashes bulk update reached iteration to max ($max_allowed_retries). Stopping bulk update process", '', '', TRINITY_AUDIO_ERROR_TYPES::warn);
      return false;
    }

    return true;
  }

  function trinity_phbu_done() {
    trinity_log('Bulk update finished ๐ŸŽ‰');

    // send success info to our end
    trinity_phbu_send_bulk_update_result();

    trinity_phbu_sync_data_for_ui();

    trinity_phbu_cleanup();

    // will be indicator later that we've done bulk-update at least once, need for UI
    trinity_phbu_set_bulk_update_done();
  }

  function trinity_phbu_is_bulk_update_in_progress(int $diff): bool {
    $heartbeat_ts = trinity_phbu_get_heartbeat();
    if (!$heartbeat_ts) return false;

    $difference_in_seconds = time() - $heartbeat_ts;

    return $difference_in_seconds < $diff;
  }

  function trinity_phbu_get_total_posts(): int {
    return count(trinity_get_posts());
  }

  /**
   * Send success info to our end
   * @return void
   * @throws Exception
   */
  function trinity_phbu_send_bulk_update_result() {
    $failed_posts = trinity_phbu_get_failed_posts();

    $post_data = [
      'installkey'        => trinity_get_install_key(),
      'num_posts'         => trinity_phbu_get_total_posts_num(),
      'num_posts_success' => trinity_phbu_get_updated_posts_num(),
    ];

    trinity_curl_post(
      [
        'post_data'     => $post_data,
        'url'           => TRINITY_AUDIO_BULK_UPDATE_URL,
        'error_message' => trinity_can_not_connect_error_message('ERROR_UPDATE_ST1'),
      ]
    );

    if (sizeof($failed_posts) > 0) {
      trinity_log('Failed to update the following posts:', implode(',', $failed_posts), '', TRINITY_AUDIO_ERROR_TYPES::warn);
    }
  }

  function trinity_phbu_is_bulk_update_alive(): bool {
    return trinity_phbu_is_bulk_update_in_progress(TRINITY_AUDIO_MAX_HEARTBEAT_TIMEOUT);
  }

  function trinity_phbu_get_status() {
    check_ajax_referer('audio_bulk_update_status_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    header('Content-type: application/json');

    die(wp_json_encode(trinity_phbu_get_status_data()));
  }

  function trinity_phbu_get_status_data(): array {
    $total_posts = get_transient(TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM_UI);

    return [
      'inProgress'     => !!(trinity_phbu_is_bulk_update_in_progress(7) ?: $total_posts), // since heartbeat is removing right away after its done, we can rely on UI synced data
      'totalPosts'     => intval(trinity_phbu_get_total_posts_num() ?: $total_posts),
      'processedPosts' => intval(trinity_phbu_get_updated_posts_num() ?: get_transient(TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM_UI))
    ];
  }

  function trinity_phbu_get_heartbeat(): int {
    return (int)get_option(TRINITY_AUDIO_PHBU_HEARTBEAT);
  }

  function trinity_phbu_update_heartbeat() {
    trinity_phbu_set_heartbeat(time());
  }

  function trinity_phbu_set_heartbeat($value) {
    update_option(TRINITY_AUDIO_PHBU_HEARTBEAT, $value);
  }

  function trinity_phbu_get_total_posts_num(): int {
    return (int)get_option(TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM, 0);
  }

  function trinity_phbu_get_in_progress(): bool {
    return (bool)get_option(TRINITY_AUDIO_PHBU_IN_PROGRESS, false);
  }

  function trinity_phbu_set_in_progress($value) {
    update_option(TRINITY_AUDIO_PHBU_IN_PROGRESS, $value);
  }

  function trinity_phbu_set_total_posts_num($value) {
    update_option(TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM, $value);
  }

  function trinity_phbu_get_updated_posts_num(): int {
    return (int)get_option(TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM, 0);
  }

  function trinity_phbu_set_updated_posts_num($value) {
    return update_option(TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM, $value);
  }

  function trinity_phbu_get_bulk_size_value($retry_count): int {
    $current_value = trinity_phbu_get_bulk_size();

    // this indicates some issue with progress - lets decrease the bulk size
    // why ">=2"? first retry could be after we've done several successful bulks in this iteration, so no need to reduce size (yet)
    if ($retry_count >= 2) {
      $current_value = max($current_value * 0.7, 1); //never less than 1
      trinity_phbu_set_bulk_size($current_value); // setting it for next time
    }

    return $current_value;
  }

  function trinity_phbu_get_bulk_size(): int {
    return (int)get_option(TRINITY_AUDIO_PHBU_BULK_SIZE, TRINITY_MAX_POSTS_PER_BATCH);
  }

  function trinity_phbu_set_bulk_size($value) {
    return update_option(TRINITY_AUDIO_PHBU_BULK_SIZE, $value);
  }

  function trinity_phbu_get_failed_posts(): array {
    return get_option(TRINITY_AUDIO_PHBU_FAILED_POSTS, []);
  }

  function trinity_phbu_set_batch_retry($number) {
    update_option(TRINITY_AUDIO_PHBU_BATCH_RETRY, $number);
  }

  function trinity_phbu_set_bulk_update_done() {
    update_option(TRINITY_AUDIO_PHBU_BULK_UPDATE_DONE, true);
  }

  function trinity_phbu_is_bulk_update_done(): bool {
    return get_option(TRINITY_AUDIO_PHBU_BULK_UPDATE_DONE, false);
  }

  function trinity_phbu_get_batch_retry(): int {
    return (int)get_option(TRINITY_AUDIO_PHBU_BATCH_RETRY, 0);
  }

  function trinity_phbu_sync_data_for_ui() {
    set_transient(TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM_UI, trinity_phbu_get_total_posts_num(), TTL_FOR_UI);
    set_transient(TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM_UI, trinity_phbu_get_updated_posts_num(), TTL_FOR_UI);
  }

  function trinity_phbu_reset() {
    trinity_log('Post hashes bulk update - reset');

    trinity_ph_cleanup();

    delete_option(TRINITY_AUDIO_PHBU_UPDATED_POSTS_NUM);
    delete_option(TRINITY_AUDIO_PHBU_FAILED_POSTS);
  }

  function trinity_phbu_cleanup() {
    trinity_log('Post hashes bulk update - cleanup... ๐Ÿงน');
    trinity_phbu_reset();

    delete_option(TRINITY_AUDIO_PHBU_TOTAL_POSTS_NUM);
    delete_option(TRINITY_AUDIO_PHBU_IN_PROGRESS);
    delete_option(TRINITY_AUDIO_PHBU_BATCH_RETRY);
    delete_option(TRINITY_AUDIO_PHBU_BULK_SIZE);
    delete_option(TRINITY_AUDIO_PHBU_HEARTBEAT);
  }