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/common.php
<?php
  require_once ABSPATH . 'wp-admin/includes/plugin.php'; // for get_plugin_data()
  require_once __DIR__ . '/constants.php';

  function trinity_curl_get($url, $error_message = '', $die = true, $async = false, $http_args = []) {
    $start = microtime(true);

    $args = [
      'timeout'     => $async ? 0.01 : TRINITY_AUDIO_MAX_HTTP_REQ_TIMEOUT,
      'blocking'    => !$async,
      'httpversion' => '1.1',
      'sslverify'   => false,
    ];

    $args = array_merge($args, $http_args);

    $response = wp_remote_get($url, $args);

    trinity_report_long_requests($start, $url);

    if ($async) {
      return;
    }
    trinity_handle_error($response, $url, '', $error_message, $die);

    return wp_remote_retrieve_body($response);
  }

  /**
   * function used to make post request, handle `long requests`
   * params description:
   * string error_message
   * boolean async - mode doesn't return anything
   * boolean die - enable die function if request failed
   * array http_args
   * boolean throw_exception - if `die` is false and there is request error throw exception *
   *
   * @param array $options options should contain 'post_data' and 'url' params, other parameters error_message, die, async, http_args, throw_exception are optional
   * @return object|void
   * @throws Exception
   */
  function trinity_curl_post(array $options) {
    $start           = microtime(true);
    $post_data       = $options['post_data'];
    $url             = $options['url'];
    $error_message   = isset($options['error_message']) ? $options['error_message'] : '';
    $die             = isset($options['die']) ? $options['die'] : true;
    $async           = isset($options['async']) ? $options['async'] : false;
    $http_args       = isset($options['http_args']) ? $options['http_args'] : [];
    $throw_exception = isset($options['throw_exception']) ? $options['throw_exception'] : false;

    $args = [
      'body'        => $post_data,
      'timeout'     => $async ? 0.01 : TRINITY_AUDIO_MAX_HTTP_REQ_TIMEOUT,
      'blocking'    => !$async,
      'httpversion' => '1.1',
      'sslverify'   => false
    ];

    $args = array_merge($args, $http_args);

    $response = wp_remote_post($url, $args);

    trinity_report_long_requests($start, $url);

    if ($async) {
      return;
    }
    $ok = trinity_handle_error($response, $url, $post_data, $error_message, $die);
    if (!$ok && $throw_exception && !$die) {
      throw new Exception('Request failed');
    }

    $body = wp_remote_retrieve_body($response);
    return json_decode($body, true);
  }

  function trinity_is_user_admin() {
    return current_user_can('manage_options');
  }

  function trinity_get_install_key() {
    return get_option(TRINITY_AUDIO_INSTALLKEY);
  }

  function trinity_get_view_key() {
    return get_option(TRINITY_AUDIO_VIEWKEY);
  }

  function trinity_get_db_plugin_version() {
    return get_option(TRINITY_AUDIO_PLUGIN_VERSION, []);
  }

  function trinity_get_plugin_migration() {
    return get_option(TRINITY_AUDIO_PLUGIN_MIGRATION, []);
  }

  function trinity_get_source_language() {
    return get_option(TRINITY_AUDIO_SOURCE_LANGUAGE);
  }

  function trinity_get_new_posts_default() {
    return get_option(TRINITY_AUDIO_SOURCE_NEW_POSTS_DEFAULT);
  }

  function trinity_get_powered_by() {
    return !!get_option(TRINITY_AUDIO_POWERED_BY);
  }

  function trinity_get_preconnect() {
    return !!get_option(TRINITY_AUDIO_PRECONNECT);
  }

  function trinity_get_player_label() {
    return get_option(TRINITY_AUDIO_PLAYER_LABEL);
  }

  function trinity_get_skip_tags() {
    return get_option(TRINITY_AUDIO_SKIP_TAGS, []);
  }

  function trinity_get_allowed_shortcodes() {
    return get_option(TRINITY_AUDIO_ALLOW_SHORTCODES, []);
  }

  function trinity_get_is_first_changes_saved() {
    return get_option(TRINITY_AUDIO_FIRST_CHANGES_SAVE);
  }

  function trinity_get_check_for_loop() {
    return get_option(TRINITY_AUDIO_CHECK_FOR_LOOP);
  }

  function trinity_get_enable_for_api() {
    return get_option(TRINITY_AUDIO_ACTIVATE_ON_API_POST_CREATION);
  }

  function trinity_set_is_account_key_linked() {
    return add_option(TRINITY_AUDIO_IS_ACCOUNT_KEY_LINKED, true);
  }

  function trinity_get_is_account_key_linked() {
    return get_option(TRINITY_AUDIO_IS_ACCOUNT_KEY_LINKED);
  }

  function trinity_get_first_time_install() {
    return get_transient(TRINITY_AUDIO_FIRST_TIME_INSTALL);
  }

  function trinity_is_enabled_for_post($post_id) {
    return get_post_meta($post_id, TRINITY_AUDIO_ENABLED, true);
  }

  function trinity_get_plugin_version() {
    $plugin_data = get_plugin_data(__DIR__ . '/../trinity.php');
    return $plugin_data['Version'];
  }

  function trinity_include_audio_player($page_content) {
    $date    = trinity_get_date();
    $post_id = $GLOBALS['post']->ID;

    $post_hash = trinity_ph_get_audio_posthash($post_id);

    $whitelist_shortcodes = trinity_get_allowed_shortcodes();
    $title                = trinity_get_clean_text(get_the_title($post_id), '', $whitelist_shortcodes);
    $content              = get_post_field('post_content', $post_id);

    // TODO: change it
    $clean_text               = trinity_get_clean_text($title, $content, $whitelist_shortcodes);
    $clean_text_without_title = trinity_get_clean_text('', $content, $whitelist_shortcodes);
    $is_no_text               = (bool)trinity_is_text_empty($clean_text);

    if ($is_no_text) {
      return false;
    }

    $viewkey = trinity_get_view_key();

    $source_language = get_post_meta($post_id, TRINITY_AUDIO_SOURCE_LANGUAGE, true);

    if (isset($language_code_map[$source_language])) {
      $source_language = $language_code_map[$source_language];
    }

    $trinity_tts_wp_config = [
      'cleanText'     => $clean_text, // old approach

      'headlineText'  => $title,
      'articleText'   => $clean_text_without_title,
      'metadata'      => [
        'author' => trinity_get_author_of_post_id($post_id)
      ],
      'pluginVersion' => trinity_get_plugin_version(),
    ];

    $response = "<script nitro-exclude data-wpfc-render='false' data-cfasync='false' data-no-optimize='1' data-no-defer='1' data-no-minify='1' data-trinity-mount-date='$date' id='trinity_tts_wp_config'>var TRINITY_TTS_WP_CONFIG = " . json_encode($trinity_tts_wp_config) . ';</script>';

    $player_query_params = [
      'integrationType' => 'wordpress',
      'postHashV2'  => $post_hash,
      'language'    => $source_language,
      'pageURL'     => get_permalink()
    ];

    $post_voice_id = get_post_meta($post_id, TRINITY_AUDIO_VOICE_ID, true);
    if ($post_voice_id) $player_query_params['voiceId'] = $post_voice_id;

    // do NOT include trinityAudioPlaceholder with PB when we already have in source code, because of using shortcodes, themes, etc... otherwise it will be flashing in wrong position
    if (!strstr($page_content, 'trinityAudioPlaceholder')) {
      $response .= "<div class='trinityAudioPlaceholder' data-trinity-mount-date='$date'>
                      <div class='trinity-tts-pb' dir='ltr' style='font: 12px / 18px Verdana, Arial; height: 80px; line-height: 80px; text-align: left; margin: 0 0 0 82px;'>
                          <strong style='font-weight: 400'>Getting your <a href='//trinityaudio.ai' style='color: #4b4a4a; text-decoration: none; font-weight: 700;'>Trinity Audio</a> player ready...</strong>
                      </div>
                    </div>";
    }

    $trinity_url = TRINITY_AUDIO_STARTUP . $viewkey . '/';

    add_filter('perfmatters_delay_js_exclusions', function($exclusions) {
      $exclusions[] = '/player/trinity-audio/';
      $exclusions[] = '/plugins/trinity-audio/';
      $exclusions[] = 'trinity_tts_wp_config'; // inline script with ID="trinity_tts_wp_config" which injects TRINITY_TTS_WP_CONFIG

      return $exclusions;
    });
    add_filter('script_loader_tag', 'trinity_exclude_player_from_caching_plugins', 10, 2);

    wp_enqueue_script('trinity-player', add_query_arg($player_query_params, $trinity_url));

    return $response;
  }

  function trinity_get_author_of_post_id($post_id) {
    $post_author_id = get_post_field('post_author', $post_id);
    return get_the_author_meta('display_name', $post_author_id);
  }

  function trinity_exclude_player_from_caching_plugins($tag, $handle) {
    $date = trinity_get_date();

    if ($handle === 'trinity-player') {
      remove_filter('script_loader_tag', 'trinity_exclude_player_from_caching_plugins', 10, 2);
      return str_replace('<script', "<script nitro-exclude data-wpfc-render='false' data-cfasync='false' data-no-optimize='1' data-no-defer='1' data-no-minify='1' data-trinity-mount-date='$date'", $tag);
    }
    return $tag;
  }

  function trinity_save_publisher_token() {
    check_ajax_referer('assign_account_key_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    $data = trinity_get_env_details();

    $postData = [
      'installkey'      => trinity_get_install_key(),
      'publisher_token' => $_POST['publisher_token'],
      'top_domain'      => $data['site_domain']
    ];

    $response = trinity_curl_post(
      [
        'post_data' => $postData,
        'url'       => TRINITY_AUDIO_PUBLISHER_TOKEN_URL
      ]
    );

    if (!$response) send_response('ERROR_NETWORK');

    if ($response['code'] === 'SUCCESS' || $response['code'] === 'ALREADY_ASSIGNED_PUBLISHER_TOKEN') {
      trinity_set_is_account_key_linked();
    }

    send_response($response['code']);
  }

  function trinity_audio_ajax_contact_us() {
    check_ajax_referer('contact_us_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

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

    $is_include_log = isset($_POST['include_log']);

    $data = trinity_get_env_details();

    /*
      The code below uses cURL because we need to send 2 files and some data
      along with them as multipart/form-data for which there is not an option
      with wp_remote_post. The use-case of cURL in the plugin here was discussed
      with and approved by the WordPress Plugin Review Team in an email
    */
    if ($is_include_log && file_exists(TRINITY_AUDIO_LOG)) {
      $data['log'] = curl_file_create(TRINITY_AUDIO_LOG);
    }
    if ($is_include_log && file_exists(TRINITY_AUDIO_INFO_HTML)) {
      $data['info'] = curl_file_create(TRINITY_AUDIO_INFO_HTML);
    }

    $postData = array_merge($data, array_map('sanitize_text_field', $_POST));
    $ch = curl_init(TRINITY_AUDIO_CONTACT_US_URL);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);

    $response     = curl_exec($ch);
    $responseData = json_decode($response);

    if (!isset($responseData->ok) || $ch === false) {
      http_response_code(500);
      echo esc_html('Error Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE));
      echo esc_html('Error Body: ' . curl_error($ch));
    }

    wp_send_json($responseData);
  }

  function trinity_get_posts($offset = 0, $size = -1): array {
    $result = get_posts(
      [
        'fields'         => 'ids', // Only get post IDs
        'orderby'        => 'ID',
        'order'          => 'DESC',
        'posts_per_page' => $size,
        'offset'         => $offset,
        'post_type'      => ['post'],
      ]
    );

    return $result;
  }

  function trinity_get_all_plugins_installed(): string {
    if (is_admin()) {
      if (!function_exists('get_plugins')) {
        require_once ABSPATH . 'wp-admin/includes/plugin.php';
      }

      $all_plugins = get_plugins();
      $plugins     = [];

      foreach ($all_plugins as $plugin) {
        array_push($plugins, $plugin['Name'] . '-' . $plugin['Version']);
      }

      return implode(', ', $plugins);
    }

    return 'unknown';
  }

  function trinity_get_user_email(): string {
    $current_user = wp_get_current_user();
    if (!($current_user instanceof WP_User)) {
      return 'NOT_LOGIN';
    }

    return $current_user->user_email;
  }

  function trinity_get_user_name(): string {
    $current_user = wp_get_current_user();
    if (!($current_user instanceof WP_User)) {
      return '';
    }

    return trim($current_user->user_firstname . ' ' . $current_user->user_lastname);
  }

  function trinity_get_wp_version(): ?string {
    global $wp_version;

    return $wp_version;
  }

  function trinity_get_env_details(): array {
    return [
      'wp_version'         => trinity_get_wp_version(),
      'plugin_version'     => trinity_get_plugin_version(),
      'php_version'        => phpversion(),
      'all_plugins'        => trinity_get_all_plugins_installed(),
      'installkey'         => trinity_get_install_key(),
      'site_domain'        => parse_url(get_site_url(), PHP_URL_HOST),
      'email'              => trinity_get_user_email(),
      'details_event_type' => 'not_set'
    ];
  }

  function trinity_update_details($url, $event_type = '', $die = true) {
    $data = trinity_get_env_details();
    if ($event_type) {
      $data['details_event_type'] = $event_type;
    }

    if ($event_type = 'activating' && empty($data['installkey']) && !empty($_POST['recover_installkey'])) {
      $data['installkey'] = $_POST['recover_installkey'];
    }

    if (!empty($_POST['publisher_token'])) $data['publisher_token'] = $_POST['publisher_token'];
    if (!empty($_POST['email_subscription'])) $data['email_subscription'] = $_POST['email_subscription'];

    return trinity_curl_post(
      [
        'post_data'     => $data,
        'url'           => $url,
        'error_message' => trinity_can_not_connect_error_message('Can\'t update plugin details.'),
        'die'           => $die
      ]
    );
  }

  function trinity_audio_ajax_update_unit_config() {
    check_ajax_referer('update_unit_config_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    $data = [
      'installkey'   => trinity_get_install_key(),
      'speed'        => $_GET['speed'],
      'language'     => $_GET['language'],
      'voiceStyle'   => $_GET['voiceStyle'],
      'themeId'      => $_GET['themeId'],
      'voice'        => $_GET['voice'],
      'fab'          => $_GET['fab'],
      'powered_by'   => $_GET['poweredBy'],
      'showSettings' => $_GET['showSettings'],
      'shareEnabled' => $_GET['shareEnabled'],
      'audioVariantId' => $_GET['audioVariantId']
    ];

    trinity_curl_post(
      [
        'post_data'     => $data,
        'url'           => TRINITY_AUDIO_UPDATE_FULL_UNIT_CONFIG_URL,
        'error_message' => trinity_can_not_connect_error_message('Can\'t update plugin details.'),
        'die'           => false
      ]
    );
  }

  function trinity_send_graphite_metric($metric) {
    return trinity_curl_post(
      [
        'post_data' => [
          'metric' => $metric
        ],
        'url'       => TRINITY_AUDIO_METRICS_URL,
        'die'       => false
      ]
    );
  }

  function trinity_send_stat_metrics() {
    check_ajax_referer('send_metric_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    $data = [
      'metric'         => $_POST['metric'],
      'additionalData' => $_POST['additionalData'] ?? null
    ];

    return trinity_curl_post(
      [
        'post_data' => $data,
        'url'       => TRINITY_AUDIO_METRICS_URL,
        'die'       => false
      ]
    );
  }

  function trinity_audio_ajax_remove_post_banner() {
    check_ajax_referer('remove_post_banner_action', TRINITY_AUDIO_AJAX_NONCE_NAME);

    update_option(TRINITY_AUDIO_REMOVE_POST_BANNER, '0');
  }

  function send_response($code) {
    $env_details = trinity_get_env_details();
    $site        = $env_details['site_domain'];

    $register_response = [
      'ERROR_NETWORK' => 'Can\'t activate plugin. Please contact us ' . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . " and provide your domain: <strong>{$site}</strong>",

      'ERROR' => 'Can\'t activate plugin. Please contact us ' . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . " and provide your domain: <strong>{$site}</strong>",

      'ALREADY_REGISTERED' => "It seems like your site <strong>{$site}</strong> is already registered to our services. In order to protect your assets, we do not allow duplicated registrations. <br/> If you've registered before and migrated into a new database/hosting service - please use the form below to insert the <span class='trinity-bold-text'>Install Key</span> if you have one, otherwise contact us at " . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . ' to help resolve this issue.',

      'WRONG_INSTALLKEY' => 'We can see that the following value has changed in your database <strong>wp_options.trinity_audio_installkey</strong>. If you know how to revert the change, please do. If not, please write to us at ' . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . ' and we will respond as fast as we can.',

      'WRONG_PUBLISHER_TOKEN' => '<span class="trinity-bold-text">Account Key</span> is not found - please verify you have the correct one. If the problem persists, please write to us at ' . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . ' and we will respond as fast as we can.',

      'ALREADY_ASSIGNED_PUBLISHER_TOKEN' => "It seems like your installation is already assigned to your Trinity Account. If it's not reflected on the <a href='" . trinity_add_utm_to_url(TRINITY_AUDIO_DASHBOARD_URL) . "' target='_blank'>Trinity Dashboard</a> please contact us at " . TRINITY_AUDIO_SUPPORT_EMAIL_LINK . ' to help resolve this issue.',

      'SUCCESS' => NULL
    ];

    die(json_encode(
      [
        'code'    => $code,
        'message' => $register_response[$code]
      ]));
  }

  function handle_register_response($response) {
    $response_code = 'ERROR_NETWORK'; // if there is a `response`, $response_code should be overridden

    if (!$response) {
      send_response($response_code);
    }

    $response_code = $response['code'];

    if ($response_code === 'SUCCESS') {
      $response_install_key = $response['data']['installkey'];
      $response_view_key    = $response['data']['viewkey'];

      /*
      Check if response exists, so we don't override with empty values if smth went wrong.
      User can have installkey and could want to restore viewkey.
      */
      if ($response_install_key) {
        update_option(TRINITY_AUDIO_INSTALLKEY, $response_install_key);
      }
      if ($response_view_key) {
        update_option(TRINITY_AUDIO_VIEWKEY, $response_view_key);
      }

      set_transient(TRINITY_AUDIO_FIRST_TIME_INSTALL, true, 60);

      send_response($response_code);
    }

    send_response($response_code);
  }

  function trinity_register() {
    $install_key = trinity_get_install_key();
    $view_key    = trinity_get_view_key();

    if ($install_key && $view_key) {
      trinity_update_details(TRINITY_AUDIO_UPDATE_PLUGIN_DETAILS_URL, 'reactivating', false);
      return true;
    }

    $response = trinity_update_details(TRINITY_AUDIO_KEYS_URL, 'activating', false);

    handle_register_response($response);
  }

  function trinity_is_text_empty($text) {
    $text = str_replace('.', '', $text);
    return !trim(preg_replace('/\s+/', ' ', $text));
  }

  function trinity_hook_header() {
    if (trinity_get_preconnect()) {
      echo '<link href="https://trinitymedia.ai/" rel="preconnect" crossorigin="anonymous" />' . "\n";
      echo '<link href="https://vd.trinitymedia.ai/" rel="preconnect" crossorigin="anonymous" />' . "\n";
    }
  }

  function trinity_can_not_connect_error_message($error = '') {
    return $error . ' Can\'t connect to Trinity Audio! Please check <a href="/wp-admin/admin.php?page=trinity_audio_logs">logs</a> or contact ' . TRINITY_AUDIO_SUPPORT_MESSAGE;
  }

  function trinity_get_notice_error_message($error = '') {
    return trinity_can_not_connect_error_message("<div class='notice notice-error'><p>" . $error . "<br>") . "</p><p></p></div>";
  }

  function trinity_registered() {
    $install_key = trinity_get_install_key();
    $view_key    = trinity_get_view_key();
    if (empty($install_key) || empty($view_key)) {
      return false;
    }
    return true;
  }

  function trinity_get_package_data() {
    $error_msg = trinity_get_notice_error_message("Can't get plan data.");
    $result    = trinity_curl_get(TRINITY_AUDIO_CREDITS_URL . '?installkey=' . trinity_get_install_key(), $error_msg, false);

    if (!$result) die(esc_html($error_msg));

    return json_decode($result);
  }

  function trinity_get_unit_config_from_trinity() {
    $error_msg = trinity_get_notice_error_message("Can't get plugin configuration.");
    $result    = trinity_curl_get(TRINITY_AUDIO_UPDATE_PLUGIN_CONFIG_URL . '?installkey=' . trinity_get_install_key(), $error_msg, false);

    if (!$result) die(esc_html($error_msg));

    return json_decode($result);
  }

  function notifications($package_data) {
    $response = trinity_curl_get(TRINITY_AUDIO_NOTIFICATIONS_URL . '/?type=general', '', false);

    if ($response) {
      $notification = json_decode($response);
      if (property_exists($notification, 'message')) {
        $notification = json_decode($notification->message);
      }

      if ($notification && property_exists($notification, 'message_html')) {
        echo wp_kses_post($notification->message_html);
      }
    }

    if (!$package_data) return;

    if ($package_data->capType === 'articles'
      && is_numeric($package_data->used)
      && is_numeric($package_data->packageLimit)
      && $package_data->used >= $package_data->packageLimit)
      echo "<div class='trinity-notification'>
              <span>
                You have a maxed out your plan usage!
                <a class='trinity-bold-text' target='_blank' href='" . esc_html(trinity_add_utm_to_url(TRINITY_AUDIO_PRICING_URL)) . "'>Upgrade your plan</a>        
              </span>
              <span class='trinity-notification-close'></span>
            </div>";
  }

  function trinity_add_utm_to_url($url, $utm_medium = 'wp_admin', $utm_campaign = '') {
    return add_query_arg(array(
      'utm_medium'   => urlencode($utm_medium),
      'utm_source'   => urlencode(get_site_url()),
      'utm_campaign' => urlencode($utm_campaign)
    ), $url);
  }

  function trinity_get_upgrade_url() {
    if (trinity_get_is_account_key_linked()) return TRINITY_AUDIO_UPGRADE_URL;
    return TRINITY_AUDIO_PRICING_URL;
  }

  function trinity_check_post_nonce($action) {
    if (!wp_verify_nonce($_POST[TRINITY_AUDIO_NONCE_NAME], $action)) die(esc_html("Security check failed for $action"));
  }