<?php
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
/**
 * Misc Functions
 *
 * @package     RPRESS
 * @subpackage  Functions
 * @copyright   Copyright (c) 2018, Magnigenie
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.0
 */
// Exit if accessed directly
if (!defined('ABSPATH'))
  exit;
/**
 * Get Cart Items By Key
 *
 * @since       1.0
 * @param       int | key
 * @return      array | cart items array
 */
function rpress_get_cart_items_by_key($key)
{
  $cart_items_arr = array();
  if ($key !== '') {
    $cart_items = rpress_get_cart_contents();
    if (is_array($cart_items) && !empty($cart_items)) {
      $items_in_cart = $cart_items[$key];
      if (is_array($items_in_cart)) {
        if (isset($items_in_cart['addon_items'])) {
          $cart_items_arr = $items_in_cart['addon_items'];
        }
      }
    }
  }
  return $cart_items_arr;
}
/**
 * Get Cart Items Price
 *
 * @since       1.0
 * @param       int | key
 * @return      int | total price for cart
 */
function rpress_get_cart_item_by_price($key)
{
  $cart_items_price = array();
  if ($key !== '') {
    $cart_items = rpress_get_cart_contents();
    if (is_array($cart_items) && !empty($cart_items)) {
      $items_in_cart = $cart_items[$key];
      if (is_array($items_in_cart)) {
        $item_price = rpress_get_fooditem_price($items_in_cart['id']);
        if ($items_in_cart['quantity'] > 0) {
          $item_price = $item_price * $items_in_cart['quantity'];
        }
        array_push($cart_items_price, $item_price);
        if (isset($items_in_cart['addon_items']) && is_array($items_in_cart['addon_items'])) {
          foreach ($items_in_cart['addon_items'] as $item_list) {
            array_push($cart_items_price, $item_list['price']);
          }
        }
      }
    }
  }
  $cart_item_total = array_sum($cart_items_price);
  return $cart_item_total;
}
function addon_category_taxonomy_custom_fields($tag)
{
  $t_id = $tag->term_id;
  $addon_type = get_term_meta($t_id, '_type', true);
  $addon_type = empty($addon_type) ? 'multiple' : $addon_type;
  $addon_price = !empty(get_term_meta($t_id, '_price', true)) ? rpress_sanitize_amount(get_term_meta($t_id, '_price', true)) : '';
  ?>
  <?php if ($tag->parent != 0): ?>
    <tr class="form-field">
      <th scope="row" valign="top">
        <label for="price_id"><?php esc_html_e('Price', 'restropress'); ?></label>
      </th>
      <td>
        <input type="number" min="0" step=".01" name="addon_meta[price]" id="addon_meta[price]" size="25" style="width:15%;"
          value="<?php echo esc_html($addon_price); ?>"><br />
        <span class="description"><?php esc_html_e('Price for this addon item', 'restropress'); ?></span>
      </td>
    </tr>
  <?php endif; ?>
  <?php if ($tag->parent == 0): ?>
    <tr class="form-field">
      <th scope="row" valign="top">
        <label for="addon-type">
          <?php esc_html_e('Addon item selection type', 'restropress'); ?></label>
      </th>
      <td>
        <div class="addon-type-wrap">
          <label for="addon-type-single">
            <input id="addon-type-single" type="radio" value="single" name="addon_meta[type]" <?php checked($addon_type, 'single'); ?>>
            <?php esc_html_e('Single item', 'restropress'); ?>
          </label>
          <br /><br />
          <label for="addon-type-multiple">
            <input id="addon-type-multiple" type="radio" value="multiple" name="addon_meta[type]" <?php checked($addon_type, 'multiple'); ?>>
            <?php esc_html_e('Multiple Items', 'restropress'); ?>
          </label>
        </div>
      </td>
    </tr>
  <?php endif; ?>
<?php
}
/**
 * Update addon metadata
 *
 * @since       1.0
 * @param       int | term_id
 * @return      null
 */
function save_addon_category_custom_fields($term_id)
{
  if (isset($_POST['addon_meta'])) {
    if (!empty($_POST['addon_meta']['type']))
      update_term_meta($term_id, '_type', sanitize_text_field($_POST['addon_meta']['type']));

    if (!empty($_POST['addon_meta']['price']))
      update_term_meta($term_id, '_price', sanitize_text_field($_POST['addon_meta']['price']));
  }
}
// Add the fields to the "addon_category" taxonomy, using our callback function
add_action('addon_category_edit_form_fields', 'addon_category_taxonomy_custom_fields', 10, 2);
// Save the changes made on the "addon_category" taxonomy, using our callback function
add_action('edited_addon_category', 'save_addon_category_custom_fields', 10, 2);
/**
 * Get food item quantity in the cart by key
 *
 * @since       1.0
 * @param       int | cart_key
 * @return      array | cart items array
 */
function rpress_get_item_qty_by_key($cart_key)
{
  if ((!empty($cart_key)) || $cart_key == '0') {
    $cart_items = rpress_get_cart_contents();
    if (isset($cart_items[$cart_key])) {
      $cart_items = $cart_items[$cart_key];
    }
    if (!isset($cart_items['quantity'])) {
      return 0;
    }
    return $cart_items['quantity'];
  }
}
add_action('wp_footer', 'rpress_popup');
if (!function_exists('rpress_popup')) {
  function rpress_popup()
  {
    rpress_get_template_part('rpress', 'popup');
  }
}
add_action('wp_footer', 'rpress_datetime_popup');
if (!function_exists('rpress_datetime_popup')) {
  function rpress_datetime_popup()
  {
    rpress_get_template_part('rpress', 'datetime-popup');
  }
}
add_action('rp_get_categories', 'get_fooditems_categories');
if (!function_exists('get_fooditems_categories')) {
  function get_fooditems_categories($params)
  {
    global $data;
    $data = $params;
    rpress_get_template_part('rpress', 'get-categories');
  }
}
if (!function_exists('rpress_search_form')) {
  function rpress_search_form()
  {
    ?>
    <div class="rpress-search-wrap rpress-live-search">
      <input id="rpress-food-search" type="text" placeholder="<?php esc_html_e('Search', 'restropress'); ?>" aria-label="<?php esc_attr_e('Search food items', 'restropress'); ?>">
    </div>
    <?php
  }
}
add_action('before_fooditems_list', 'rpress_search_form');
add_shortcode('foodsearch', 'rpress_foodsearch_callback');
function rpress_foodsearch_callback()
{
  ob_start();
  rpress_search_form();
  $data = ob_get_contents();
  ob_get_clean();
  return $data;
}
add_shortcode('rpress_cart', 'rpress_rpress_cart_callback');
function rpress_rpress_cart_callback()
{
  ob_start();
  do_action('rpress_get_cart');
  $data = ob_get_contents();
  ob_get_clean();
  return $data;
}
add_shortcode('custom_forgot_password', 'myplugin_custom_forgot_password_form');

function myplugin_custom_forgot_password_form()
{
  ob_start();

  if (!is_user_logged_in()) {
    ?>
    <div class="custom-reset-password">
      <h2>Forgot your password?</h2>
      <p>A code will be sent to your email to help reset password</p>

      <form method="post">
        <label for="user_login">Username or Email Address</label>
        <input type="text" name="user_login" id="user_login" required placeholder="Enter your email address" />

        <?php wp_nonce_field('custom_forgot_password_action', 'custom_forgot_password_nonce'); ?>

        <input type="submit" name="custom_forgot_password_submit" class="reset-button" value="Get New Password" />

        <div class="login-link">
          <a href="<?php echo esc_url(site_url('/login')); ?>">â† Back to Login</a>
        </div>
      </form>

      <?php
      if (isset($_POST['custom_forgot_password_submit'])) {
        if (isset($_POST['custom_forgot_password_nonce']) && wp_verify_nonce($_POST['custom_forgot_password_nonce'], 'custom_forgot_password_action')) {
          $user_login = sanitize_text_field($_POST['user_login']);
          $user = get_user_by('login', $user_login);
          if (!$user && is_email($user_login)) {
            $user = get_user_by('email', $user_login);
          }

          if ($user) {
            $reset = retrieve_password($user->user_login);
            if ($reset) {
              echo '<p class="success">Check your email for the confirmation link.</p>';
            } else {
              echo '<p class="error">Could not reset password. Try again later.</p>';
            }
          } else {
            echo '<p class="error">No user found with that email or username.</p>';
          }
        }
      }
      ?>
    </div>
    <?php
  } else {
    echo '<p>You are already logged in.</p>';
  }

  return ob_get_clean();
}
if (!function_exists('rpress_product_menu_tab')) {
  /**
   * Output the rpress menu tab content.
   */
  function rpress_product_menu_tab()
  {
    echo do_shortcode('[rpress_items]');
  }
}
/**
 * Get special instruction for food items
 *
 * @since       1.0
 * @param       array | food items
 * @return      string | Special instruction string
 */
function get_special_instruction($items)
{
  $instruction = '';
  if (is_array($items)) {
    if (isset($items['options'])) {
      $instruction = $items['options']['instruction'];
    } else {
      if (isset($items['instruction'])) {
        $instruction = $items['instruction'];
      }
    }
  }
  return apply_filters('rpress_sepcial_instruction', $instruction);
}
/**
 * Get instruction in the cart by key
 *
 * @since       1.0
 * @param       int | cart_key
 * @return      string | Special instruction string
 */
function rpress_get_instruction_by_key($cart_key)
{
  $instruction = '';
  if ($cart_key !== '') {
    $cart_items = rpress_get_cart_contents();
    $cart_items = $cart_items[$cart_key];
    if (isset($cart_items['instruction'])) {
      $instruction = !empty($cart_items['instruction']) ? $cart_items['instruction'] : '';
    }
  }
  return $instruction;
}
/**
 * Show delivery options in the cart
 *
 * @since       1.0.2
 * @param       void
 * @return      string | Outputs the html for the delivery options with texts
 */
function get_delivery_options($changeble)
{
  $service_date = isset($_COOKIE['delivery_date']) ? sanitize_text_field(wp_unslash($_COOKIE['delivery_date'])) : '';
  $service_type_cookie = isset( $_COOKIE['service_type'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['service_type'] ) ) : '';
  $hide_service_time = function_exists( 'rp_otil_is_service_time_hidden' ) ? rp_otil_is_service_time_hidden( $service_type_cookie ) : false;
  $current_time = current_time('timestamp');
  $close_time = !empty(rpress_get_option('close_time')) ? rpress_get_option('close_time') : '11:30pm';
  $close_time = strtotime(date_i18n('Y-m-d') . ' ' . $close_time);
  if (!empty(rpress_get_option('enable_always_open')) && $current_time > $close_time) {
    $service_date = new DateTime($service_date);
    $service_date->add(new DateInterval('P1D'));
    $service_date = $service_date->format('F d, Y');
  }

  // Assume the cookie 'service_time_text' is set to 'ASAP- 50 min'
  $service_time_str = isset($_COOKIE['service_time_text']) ? sanitize_text_field(wp_unslash($_COOKIE['service_time_text'])) : '';

  // Check if the string contains 'ASAP'
  if (strpos($service_time_str, 'ASAP') !== false) {
    // Remove 'ASAP' from the string
    $service_time_str = str_replace('ASAP', '', $service_time_str);
    // Trim any leading or trailing whitespace
    $service_time_str = __('ASAP', 'restropress') . $service_time_str;
  }
  ob_start();
  ?>
  <div class="delivery-wrap">
    <div class="delivery-opts">
      <?php if (!empty($_COOKIE['service_type'])): ?>
        <span
          class="delMethod"><?php echo esc_html(rpress_service_label(sanitize_text_field(wp_unslash($_COOKIE['service_type'])))) . ', ' . esc_html($service_date); ?></span>
        <?php if ( ! $hide_service_time && !empty($_COOKIE['service_time']) ): ?>
          <span
            class="delTime"><?php printf(esc_html__(', %s', 'restropress'), esc_html(sanitize_text_field($service_time_str))); ?></span>
        <?php endif; ?>
      <?php endif; ?>
    </div>
    <?php if ($changeble && !empty($_COOKIE['service_type'])): ?>
      <a href="#" class="delivery-change">
        <span class="rp-ajax-toggle-text">
          <?php esc_html_e('Change?', 'restropress'); ?>
        </span>
      </a>
    <?php endif; ?>
  </div>
  <?php
  $data = ob_get_contents();
  ob_get_clean();
  return $data;
}

function get_date_time_options($changeble)
{
  $service_date = isset($_COOKIE['delivery_date']) ? sanitize_text_field(wp_unslash($_COOKIE['delivery_date'])) : '';
  $service_type_cookie = isset( $_COOKIE['service_type'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['service_type'] ) ) : '';
  $hide_service_time = function_exists( 'rp_otil_is_service_time_hidden' ) ? rp_otil_is_service_time_hidden( $service_type_cookie ) : false;
  $current_time = current_time('timestamp');
  $close_time = !empty(rpress_get_option('close_time')) ? rpress_get_option('close_time') : '11:30pm';
  $close_time = strtotime(date_i18n('Y-m-d') . ' ' . $close_time);
  if (!empty(rpress_get_option('enable_always_open')) && $current_time > $close_time) {
    $service_date = new DateTime($service_date);
    $service_date->add(new DateInterval('P1D'));
    $service_date = $service_date->format('F d, Y');
  }

  // Assume the cookie 'service_time_text' is set to 'ASAP- 50 min'
  $service_time_str = isset($_COOKIE['service_time_text']) ? sanitize_text_field(wp_unslash($_COOKIE['service_time_text'])) : '';

  // Check if the string contains 'ASAP'
  if (strpos($service_time_str, 'ASAP') !== false) {
    // Remove 'ASAP' from the string
    $service_time_str = str_replace('ASAP', '', $service_time_str);
    // Trim any leading or trailing whitespace
    $service_time_str = __('ASAP', 'restropress') . $service_time_str;
  }
  ob_start();
  ?>
  <div class="delivery-wrap">
    <div class="delivery-opts">
      <?php if (!empty($_COOKIE['service_type'])): ?>
        <span class="delMethod"><?php echo esc_html($service_date); ?></span>
        <?php if ( ! $hide_service_time && !empty($_COOKIE['service_time']) ): ?>
          <span
            class="delTime"><?php printf(esc_html__(', %s', 'restropress'), esc_html(sanitize_text_field($service_time_str))); ?></span>
        <?php endif; ?>
      <?php endif; ?>
    </div>
    <?php if ($changeble && !empty($_COOKIE['service_type'])): ?>
      <a href="#" class="delivery-change">
        <span class="rp-ajax-toggle-text">
          <?php esc_html_e('Change?', 'restropress'); ?>
        </span>
      </a>
    <?php endif; ?>
  </div>
  <?php
  $data = ob_get_contents();
  ob_get_clean();
  return $data;
}
/**
 * Stores delivery address meta
 *
 * @since       1.0.3
 * @param       array | Delivery address meta array
 * @return      array | Custom data with delivery address meta array
 */
function rpress_store_custom_fields($delivery_address_meta)
{
  $delivery_address_meta['address'] = !empty($_POST['rpress_street_address']) ? sanitize_text_field($_POST['rpress_street_address']) : '';
  $delivery_address_meta['flat'] = !empty($_POST['rpress_apt_suite']) ? sanitize_text_field($_POST['rpress_apt_suite']) : '';
  $delivery_address_meta['city'] = !empty($_POST['rpress_city']) ? sanitize_text_field($_POST['rpress_city']) : '';
  $delivery_address_meta['postcode'] = !empty($_POST['rpress_postcode']) ? sanitize_text_field($_POST['rpress_postcode']) : '';
  return $delivery_address_meta;
}
add_filter('rpress_delivery_address_meta', 'rpress_store_custom_fields');
/**
 * Add order note to the order
 */
add_filter('rpress_order_note_meta', 'rpress_order_note_fields');
function rpress_order_note_fields($order_note)
{
  $order_note = isset($_POST['rpress_order_note']) ? sanitize_text_field($_POST['rpress_order_note']) : '';
  return $order_note;
}
/**
 * Add phone number to payment meta
 */
add_filter('rpress_payment_meta', 'rpress_add_phone');
function rpress_add_phone($payment_meta)
{
  if (!empty($_POST['rpress_phone']))
    $payment_meta['phone'] = sanitize_text_field($_POST['rpress_phone']);
  return $payment_meta;
}
/**
 * Get Service type
 *
 * @since       1.0.4
 * @param       Int | Payment_id
 * @return      string | Service type string
 */
function rpress_get_service_type($payment_id)
{
  if ($payment_id) {
    $service_type = get_post_meta($payment_id, '_rpress_delivery_type', true);
    return strtolower($service_type);
  }
}
/* Remove View Link From Food Items */
add_filter('post_row_actions', 'rpress_remove_view_link', 10, 2);
function rpress_remove_view_link($actions, $post)
{
  if ($post->post_type == "fooditem") {
    unset($actions['view']);
  }
  return $actions;
}
/* Remove View Link From Food Addon Category */
add_filter('addon_category_row_actions', 'rpress_remove_tax_view_link', 10, 2);
function rpress_remove_tax_view_link($actions, $taxonomy)
{
  if ($taxonomy->taxonomy == 'addon_category') {
    unset($actions['view']);
  }
  return $actions;
}
/* Remove View Link From Food Category */
add_filter('food-category_row_actions', 'rpress_remove_food_cat_view_link', 10, 2);
function rpress_remove_food_cat_view_link($actions, $taxonomy)
{
  if ($taxonomy->taxonomy == 'food-category') {
    unset($actions['view']);
  }
  return $actions;
}
/**
 * Get store timings for the store
 *
 * @since       1.0.0
 * @return      array | store timings
 */
function rp_get_store_timings($hide_past_time = true, $service_type = null)
{
  $current_time = current_time('timestamp');
  $prep_time = !empty(rpress_get_option('prep_time')) ? rpress_get_option('prep_time') : 30;
  $open_time = !empty(rpress_get_option('open_time')) ? rpress_get_option('open_time') : '9:00am';
  $close_time = !empty(rpress_get_option('close_time')) ? rpress_get_option('close_time') : '11:30pm';
  $time_interval = apply_filters('rp_store_time_interval', '30', $service_type);
  $time_interval = $time_interval * 60;
  $prep_time = $prep_time * 60;
  $open_time = strtotime(date_i18n('Y-m-d') . ' ' . $open_time);
  $close_time = strtotime(date_i18n('Y-m-d') . ' ' . $close_time);
  $time_today = apply_filters('rpress_timing_for_today', true);
  $store_times = range($open_time, $close_time, $time_interval);
  $store_time_format = rpress_get_option('store_time_format');
  $date_format = get_option('time_format');
  if ("24hrs" === $store_time_format) {
    $date_format = "H:i";
  }

  if ("12hrs" === $store_time_format) {
    $date_format = "h:i A";
  }

  //If not today then return normal time
  if (!$time_today)
    return $store_times;
  //Add prep time to current time to determine the time to display for the dropdown
  if ($prep_time > 0) {
    $current_time = $current_time + $prep_time;
  }
  //Store timings for today.
  $store_timings = [];


  foreach ($store_times as $store_time) {
    if ($hide_past_time) {
        if ($store_time > $current_time) {
            $store_timings[] = date_i18n($date_format, $store_time);
        }
    } else {
        $store_timings[] = date_i18n($date_format, $store_time);
    }
}
  return $store_timings;
}
/**
 * Get current time
 *
 * @since       1.0.0
 * @return      string | current time
 */
function rp_get_current_time()
{
  $current_time = '';
  $timezone = get_option('timezone_string');
  if (!empty($timezone)) {
    $tz = new DateTimeZone($timezone);
    $dt = new DateTime("now", $tz);
    $current_time = $dt->format("H:i:s");
  }
  return $current_time;
}
/**
 * Get current date
 *
 * @since       1.0.0
 * @return      string | current date
 */
function rp_current_date($format = '')
{
  $date_format = empty($format) ? get_option('date_format') : $format;
  $date_i18n = date_i18n($date_format);
  return apply_filters('rpress_current_date', $date_i18n);
}
/**
 * Get local date from date string
 *
 * @since       1.0.0
 * @return      string | localized date based on date string
 */
function rpress_local_date($date)
{
  $date_format = apply_filters('rpress_date_format', get_option('date_format', true));
  $timestamp = strtotime($date);
  $local_date = empty(get_option('timezone_string')) ? date_i18n($date_format, $timestamp) : wp_date($date_format, $timestamp);
  return apply_filters('rpress_local_date', $local_date, $date);
}

/**
 * Format a service date using the WordPress date format.
 *
 * @since 3.2.8.4
 * @param string $date Raw date string (Y-m-d).
 * @return string
 */
function rpress_format_service_date($date)
{
  $date = trim((string) $date);
  if ($date === '') {
    return '';
  }

  $timestamp = strtotime($date);
  if (!$timestamp) {
    return $date;
  }

  $date_format = get_option('date_format');
  return empty(get_option('timezone_string')) ? date_i18n($date_format, $timestamp) : wp_date($date_format, $timestamp);
}

/**
 * Format a service time for display using WP time format.
 *
 * @since 3.2.8.3
 * @param string $service_time Raw service time (may include ASAP label).
 * @param string $service_date Optional service date (Y-m-d) for timezone-aware formatting.
 * @return string
 */
function rpress_format_service_time($service_time, $service_date = '')
{
  $service_time = trim((string) $service_time);
  if ($service_time === '') {
    return '';
  }

  if (stripos($service_time, 'ASAP') !== false) {
    return trim(str_ireplace('ASAP', __('ASAP', 'restropress'), $service_time));
  }

  $time_format = get_option('time_format');
  $timestamp = $service_date ? strtotime($service_date . ' ' . $service_time) : strtotime($service_time);
  if (!$timestamp) {
    return $service_time;
  }

  return date_i18n($time_format, $timestamp);
}
/**
 * Get list of categories
 *
 * @since 2.2.4
 * @return array of categories
 */
function rpress_get_categories($params = array())
{
  if (!empty($params['ids'])) {
    $params['include'] = $params['ids'];
    $params['orderby'] = 'include';
  }
  unset($params['ids']);
  $defaults = array(
    'taxonomy' => 'food-category',
    'hide_empty' => true,
    'orderby' => 'name',
    'order' => 'ASC',
  );
  $term_args = wp_parse_args($params, $defaults);
  $term_args = apply_filters('rpress_get_categories', $term_args);
  $get_all_items = get_terms($term_args);
  return $get_all_items;
}
function rpress_get_service_types()
{
  $service_types = array(
    'delivery' => __('Delivery', 'restropress'),
    'pickup' => __('Pickup', 'restropress')
  );
  return apply_filters('rpress_service_type', $service_types);
}
/**
 * Get enabled service slugs based on the stored service setting.
 *
 * @since 3.0.0
 * @return array
 */
function rpress_get_enabled_services()
{
  $enabled_service = sanitize_key((string) rpress_get_option('enable_service', 'delivery_and_pickup'));
  $enabled_services = 'delivery_and_pickup' === $enabled_service
    ? array('delivery', 'pickup')
    : array($enabled_service);

  $enabled_services = apply_filters('rpress_enable_services', $enabled_services);
  $enabled_services = array_filter(array_map('sanitize_key', (array) $enabled_services));
  $enabled_services = array_values(array_unique($enabled_services));

  if (empty($enabled_services)) {
    $enabled_services = 'delivery_and_pickup' === $enabled_service
      ? array('delivery', 'pickup')
      : array($enabled_service);
  }

  return $enabled_services;
}
/**
 * Get the default service slug from the active services list.
 *
 * @since 3.0.0
 * @return string
 */
function rpress_get_default_enabled_service()
{
  $enabled_service  = sanitize_key((string) rpress_get_option('enable_service', 'delivery_and_pickup'));
  $enabled_services = rpress_get_enabled_services();

  if ('delivery_and_pickup' === $enabled_service) {
    $configured_default = sanitize_key((string) rpress_get_option('default_service', 'delivery'));

    if (!empty($configured_default) && in_array($configured_default, $enabled_services, true)) {
      return $configured_default;
    }
  } elseif (!empty($enabled_service) && in_array($enabled_service, $enabled_services, true)) {
    return $enabled_service;
  }

  return !empty($enabled_services) ? (string) reset($enabled_services) : 'delivery';
}
/**
 * Get enabled service types based on the stored service setting.
 *
 * @since 3.0.0
 * @return array
 */
function rpress_get_enabled_service_types()
{
  $service_types         = rpress_get_service_types();
  $enabled_service       = sanitize_key((string) rpress_get_option('enable_service', 'delivery_and_pickup'));
  $enabled_services      = rpress_get_enabled_services();
  $enabled_service_types = array();

  foreach ($enabled_services as $enabled_service_slug) {
    if (isset($service_types[$enabled_service_slug])) {
      $enabled_service_types[$enabled_service_slug] = $service_types[$enabled_service_slug];
      continue;
    }

    $service_label = rpress_service_label($enabled_service_slug);
    $enabled_service_types[$enabled_service_slug] = $service_label !== $enabled_service_slug
      ? $service_label
      : ucwords(str_replace(array('-', '_'), ' ', $enabled_service_slug));
  }

  return apply_filters('rpress_enabled_service_types', $enabled_service_types, $enabled_service, $service_types, $enabled_services);
}
/**
 * Get Store service hours
 * @since 3.0
 * @param string $service_type Select service type
 * @param bool $current_time_aware if current_time_aware is set true then it would show the next time from now otherwise it would show the default store timings
 * @return store time
 */
function rp_get_store_service_hours(
  $service_type,
  $current_time_aware = true,
  $selected_time = null,
  $asap_option = null,
  $service_date = null
) {

  if (empty($service_type)) {
    return;
  }

  // -----------------------------
  // Get Store Time Format
  // -----------------------------
  $store_time_format = rpress_get_option('store_time_format');

  if ("24hrs" === $store_time_format) {
    $date_format = "H:i";
  } else {
    $date_format = "h:i A";
  }

  // -----------------------------
  // Current timestamp (WP timezone aware)
  // -----------------------------
  $current_timestamp = current_time('timestamp');

  // -----------------------------
  // Get Store Timings
  // -----------------------------
  $store_times = rp_get_store_timings(false, $service_type);

  $store_timings = apply_filters(
    'rpress_store_timings',
    $store_times,
    $service_type,
    $service_date
  );

  $store_timings_for_today = apply_filters('rpress_timing_for_today', true);

  // ASAP option
  $asap_option = rpress_get_option('enable_asap_option', '');

  // Selected timestamp
  $selected_timestamp = 0;
  if (!empty($selected_time) && $selected_time !== 'ASAP') {

    // Fix dot format like 7.00 AM â†’ 7:00 AM
    $selected_time = str_replace('.', ':', $selected_time);

    $selected_timestamp = strtotime($selected_time);
  }

  if (empty($store_timings) || !is_array($store_timings)) {
    return;
  }

  foreach ($store_timings as $time) {

    if (empty($time)) {
      continue;
    }

    // Convert to timestamp
    $time_int = is_numeric($time) ? (int) $time : strtotime($time);

    if (!$time_int) {
      continue;
    }

    // Format for display (WP timezone aware)
    $formatted_time = date_i18n($date_format, $time_int);

    // Skip past times if current_time_aware enabled
    if ($store_timings_for_today && $current_time_aware) {

      if ($time_int <= $current_timestamp) {
        continue;
      }
    }

    // Check selected
    $is_selected = false;

    if ($asap_option && $key === 0 && $selected_time === 'ASAP') {
      $is_selected = true;
    } elseif ($selected_timestamp && $selected_timestamp === $time_int) {
      $is_selected = true;
    }

    ?>

    <option <?php selected($is_selected, true); ?>
      value="<?php echo esc_attr(($asap_option && $key === 0) ? 'ASAP' : $formatted_time); ?>">
      <?php echo esc_html(($asap_option && $key === 0) ? __('ASAP', 'restropress') : $formatted_time); ?>
    </option>

    <?php
  }
}

/**
 * Get list of categories/subcategories
 *
 * @since 2.3
 * @return array of Get list of categories/subcategories
 */
function rpress_get_child_cats($category)
{
  $taxonomy_name = 'food-category';
  $parent_term = $category[0];
  $get_child_terms = get_terms(
    $taxonomy_name,
    ['child_of' => $parent_term]
  );
  if (empty($get_child_terms)) {
    $parent_terms = array(
      'taxonomy' => $taxonomy_name,
      'hide_empty' => true,
      'include' => $category,
    );
    $get_child_terms = get_terms($parent_terms);
  }
  return $get_child_terms;
}
add_filter('post_updated_messages', 'rpress_fooditem_update_messages');
function rpress_fooditem_update_messages($messages)
{
  global $post, $post_ID;
  $post_types = get_post_types(array('show_ui' => true, '_builtin' => false), 'objects');
  foreach ($post_types as $post_type => $post_object) {
    if ($post_type == 'fooditem') {
      $messages[$post_type] = array(
        0 => '', // Unused. Messages start at index 1.
        1 => sprintf(__('%s updated.'), $post_object->labels->singular_name),
        2 => __('Custom field updated.'),
        3 => __('Custom field deleted.'),
        4 => sprintf(__('%s updated.'), $post_object->labels->singular_name),
        5 => isset($_GET['revision']) ? sprintf(__('%s restored to revision from %s'), $post_object->labels->singular_name, wp_post_revision_title((int) sanitize_text_field($_GET['revision']), false)) : false,
        6 => sprintf(__('%s published.'), $post_object->labels->singular_name),
        7 => sprintf(__('%s saved.'), $post_object->labels->singular_name),
        8 => sprintf(__('%s submitted'), $post_object->labels->singular_name),
        9 => sprintf(__('%s scheduled for: <strong>%1$s</strong>'), $post_object->labels->singular_name, date_i18n(__('M j, Y @ G:i'), strtotime($post->post_date)), $post_object->labels->singular_name),
        10 => sprintf(__('%s draft updated.'), $post_object->labels->singular_name),
      );
    }
  }
  return $messages;
}
/**
 * Return the html selected attribute if stringified $value is found in array of stringified $options
 * or if stringified $value is the same as scalar stringified $options.
 *
 * @param string|int       $value   Value to find within options.
 * @param string|int|array $options Options to go through when looking for value.
 * @return string
 */
function rp_selected($value, $options)
{
  if (is_array($options)) {
    $options = array_map('strval', $options);
    return selected(in_array((string) $value, $options, true), true, false);
  }
  return selected($value, $options, false);
}
/**
 * Return the currently selected service type
 *
 * @since       2.5
 * @param       string | type
 * @return      string | Currently selected service type
 */
function rpress_selected_service($type = '')
{
  $service_type = isset($_COOKIE['service_type']) ? sanitize_text_field(wp_unslash($_COOKIE['service_type'])) : '';
  //Return service type label when $type is label
  if ($type == 'label')
    $service_type = rpress_service_label($service_type);
  return $service_type;
}
/**
 * Return the service type label based on the service slug.
 *
 * @since       2.5
 * @param       string | service type
 * @return      string | Service type label
 */
function rpress_service_label($service)
{
  $service_types = array(
    'delivery' => __('Delivery', 'restropress'),
    'pickup' => __('Pickup', 'restropress'),
  );
  //Allow to filter the service types.
  $service_types = apply_filters('rpress_service_types', $service_types);
  //Check for the service key in the service types and return the service type label
  if (array_key_exists($service, $service_types))
    $service = $service_types[$service];
  return $service;
}
/**
 * Save order type in session
 *
 * @since       1.0.4
 * @param       string | Delivery Type
 * @param           string | Delivery Time
 * @return      array  | Session array for delivery type and delivery time
 */
function rpress_checkout_delivery_type($service_type, $service_time)
{
  $_COOKIE['service_type'] = $service_type;
  $_COOKIE['service_time'] = $service_time;
}
/**
 * Build normalized service slots for a given service/date.
 *
 * @since 3.2.9
 *
 * @param string $service_type Service type.
 * @param string $service_date Service date in Y-m-d.
 * @param bool   $hide_past_time Hide past slots.
 * @return array
 */
function rpress_get_available_service_slots( $service_type, $service_date = '', $hide_past_time = true ) {
  $service_type = sanitize_key( (string) $service_type );
  if ( empty( $service_type ) ) {
    return array();
  }

  $service_date = rp_row_date( $service_date, $service_type );
  $today        = wp_date( 'Y-m-d' );
  $hide_past_time = $hide_past_time && ( $service_date === $today );
  $store_times  = rp_get_store_timings( $hide_past_time, $service_type );
  $store_times  = apply_filters( 'rpress_store_timings', $store_times, $service_type, $service_date );

  if ( empty( $store_times ) || ! is_array( $store_times ) ) {
    return array();
  }

  $normalized_slots = array();
  foreach ( $store_times as $slot ) {
    if ( ! is_scalar( $slot ) ) {
      continue;
    }

    $slot = trim( (string) $slot );
    if ( '' === $slot ) {
      continue;
    }

    $filtered_slot = apply_filters( 'rpress_store_delivery_timings_slot_remaining', $slot );
    if ( ! is_scalar( $filtered_slot ) ) {
      continue;
    }

    $filtered_slot = trim( (string) $filtered_slot );
    if ( '' === $filtered_slot ) {
      continue;
    }

    $normalized_slots[] = $filtered_slot;
  }

  if ( empty( $normalized_slots ) ) {
    return array();
  }

  return array_values( array_unique( $normalized_slots ) );
}
/**
 * Resolve first valid date for the service type.
 *
 * @since 3.2.9
 *
 * @param string $service_type Service type.
 * @param string $requested_date Requested date.
 * @param int    $lookahead_days Max days to inspect.
 * @return string
 */
function rpress_get_first_available_service_date( $service_type, $requested_date = '', $lookahead_days = 30 ) {
  $service_type = sanitize_key( (string) $service_type );
  $seed_date    = rp_row_date( $requested_date, $service_type );
  $seed_ts      = strtotime( $seed_date );

  if ( false === $seed_ts ) {
    $seed_ts = current_time( 'timestamp' );
  }

  $lookahead_days      = max( 0, (int) $lookahead_days );
  $service_time_hidden = function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $service_type );

  for ( $offset = 0; $offset <= $lookahead_days; $offset++ ) {
    $candidate_date = wp_date( 'Y-m-d', strtotime( '+' . $offset . ' day', $seed_ts ) );

    if ( ! rpress_is_store_open( $service_type, $candidate_date ) ) {
      continue;
    }

    if ( $service_time_hidden ) {
      return $candidate_date;
    }

    $candidate_slots = rpress_get_available_service_slots( $service_type, $candidate_date, true );
    if ( ! empty( $candidate_slots ) ) {
      return $candidate_date;
    }
  }

  return wp_date( 'Y-m-d', $seed_ts );
}
/**
 * Match service time with available slots.
 *
 * @since 3.2.9
 *
 * @param string $requested_time Requested slot.
 * @param array  $available_slots Available slots.
 * @param bool   $allow_asap Allow ASAP values.
 * @return string
 */
function rpress_match_service_time_to_slot( $requested_time, array $available_slots, $allow_asap = false ) {
  $requested_time = trim( (string) $requested_time );
  if ( '' === $requested_time ) {
    return '';
  }

  if ( $allow_asap && 0 === stripos( $requested_time, 'asap' ) ) {
    return $requested_time;
  }

  if ( in_array( $requested_time, $available_slots, true ) ) {
    return $requested_time;
  }

  foreach ( $available_slots as $slot ) {
    if ( 0 === strcasecmp( $slot, $requested_time ) ) {
      return $slot;
    }
  }

  $requested_timestamp = strtotime( $requested_time );
  if ( false !== $requested_timestamp ) {
    foreach ( $available_slots as $slot ) {
      $slot_timestamp = strtotime( $slot );
      if ( false !== $slot_timestamp && $slot_timestamp === $requested_timestamp ) {
        return $slot;
      }
    }
  }

  return '';
}
/**
 * Get next available slot from available service slots.
 *
 * @since 3.2.9
 *
 * @param string $service_date Service date.
 * @param array  $available_slots Available slots.
 * @param int    $minimum_timestamp Minimum required timestamp.
 * @return string
 */
function rpress_get_next_available_service_time( $service_date, array $available_slots, $minimum_timestamp = 0 ) {
  if ( empty( $available_slots ) ) {
    return '';
  }

  foreach ( $available_slots as $slot ) {
    $slot_timestamp = strtotime( $service_date . ' ' . $slot );
    if ( false === $slot_timestamp ) {
      continue;
    }

    if ( ! empty( $minimum_timestamp ) && $slot_timestamp < $minimum_timestamp ) {
      continue;
    }

    return $slot;
  }

  return (string) reset( $available_slots );
}
/**
 * Validates the cart before checkout
 *
 * @since       2.5
 * @param       void
 * @return      array | Respose as success/error
 */
function rpress_pre_validate_order() {

    $service_type = !empty($_COOKIE['service_type'])
        ? sanitize_text_field(wp_unslash($_COOKIE['service_type'])) 
        : '';

    $normalized_service_type = sanitize_key( $service_type );
    $allowed_services = rpress_get_enabled_services();

    if ( empty( $normalized_service_type ) || ! in_array( $normalized_service_type, $allowed_services, true ) ) {
        $normalized_service_type = rpress_get_default_enabled_service();
    }

    if ( empty( $normalized_service_type ) || ! in_array( $normalized_service_type, $allowed_services, true ) ) {
        return array(
            'status' => 'error',
            'error_type' => 'service_type_not_set',
            'error_msg' => __( 'Please select a service type.', 'restropress' ),
        );
    }

    $service_type = $normalized_service_type;
    setcookie( 'service_type', $service_type, time() + ( 86400 * 30 ), '/' );
    $_COOKIE['service_type'] = $service_type;

    $service_time_raw = !empty($_COOKIE['service_time'])
        ? sanitize_text_field(wp_unslash($_COOKIE['service_time']))
        : '';

    $service_date_raw = !empty($_COOKIE['service_date'])
        ? sanitize_text_field(wp_unslash($_COOKIE['service_date']))
        : '';

    $service_date = rpress_get_first_available_service_date( $service_type, $service_date_raw );
    setcookie( 'service_date', $service_date, time() + ( 86400 * 30 ), '/' );
    $_COOKIE['service_date'] = $service_date;

    $service_display_date = date_i18n( 'F j', strtotime( $service_date ) );
    setcookie( 'delivery_date', $service_display_date, time() + ( 86400 * 30 ), '/' );
    $_COOKIE['delivery_date'] = $service_display_date;

    if ( ! rpress_is_store_open( $service_type, $service_date ) ) {
        return array(
            'status' => 'error',
            'error_type' => 'service_closed',
            'error_msg' => rpress_store_closed_message( $service_type ),
        );
    }

    $service_time_hidden = function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $service_type );

    // Preparation Time.
    $prep_time = (int) rpress_get_option('prep_time', 0) * 60;

    $current_time = current_time('timestamp') + $prep_time;
    $allow_asap = ! empty( rpress_get_option( 'enable_asap_option' ) );
    $available_slots = rpress_get_available_service_slots( $service_type, $service_date, true );

    if ( ! $service_time_hidden ) {
      $service_time_raw = rpress_match_service_time_to_slot( $service_time_raw, $available_slots, $allow_asap );

      if ( empty( $service_time_raw ) ) {
        $service_time_raw = rpress_get_next_available_service_time( $service_date, $available_slots, $current_time );
      }

      if ( empty( $service_time_raw ) ) {
        return array(
          'status' => 'error',
          'error_type' => 'service_time_not_set',
          'error_msg' => __( 'Please select a service time.', 'restropress' ),
        );
      }

      setcookie( 'service_time', $service_time_raw, time() + ( 86400 * 30 ), '/' );
      setcookie( 'service_time_text', $service_time_raw, time() + ( 86400 * 30 ), '/' );
      $_COOKIE['service_time'] = $service_time_raw;
      $_COOKIE['service_time_text'] = $service_time_raw;
    }

    $service_time = empty( $service_time_raw ) ? 0 : strtotime( $service_date . ' ' . $service_time_raw );

    /* ==============================
       Minimum Order Validation
    ============================== */

    $enable_minimum_order = rpress_get_option('allow_minimum_order');

    $minimum_delivery = (float) rpress_get_option('minimum_order_price');
    $minimum_pickup   = (float) rpress_get_option('minimum_order_price_pickup');

    $cart_total = rpress_get_cart_subtotal();

    if ( $enable_minimum_order ) {

        if ( $service_type === 'delivery' && $cart_total < $minimum_delivery ) {

            $error = rpress_get_option('minimum_order_error');
            $formatted = rpress_currency_filter(rpress_format_amount($minimum_delivery));
            $error = str_replace('{min_order_price}', $formatted, $error);

            return array(
                'status' => 'error',
                'minimum_price' => $minimum_delivery,
                'error_msg' => $error
            );
        }

        if ( $service_type === 'pickup' && $cart_total < $minimum_pickup ) {

            $error = rpress_get_option('minimum_order_error_pickup');
            $formatted = rpress_currency_filter(rpress_format_amount($minimum_pickup));
            $error = str_replace('{min_order_price}', $formatted, $error);

            return array(
                'status' => 'error',
                'minimum_price' => $minimum_pickup,
                'error_msg' => $error
            );
        }
    }

    /* ==============================
       Time Slot Validation
    ============================== */

    $should_validate_time_slot = apply_filters(
        'rpress_should_validate_time_slot',
        function_exists( 'rp_otil_is_service_time_hidden' ) && ( defined( 'RP_OTIAL_VERSION' ) || class_exists( 'RP_Order_Time_intervals_Limit_Functions', false ) ),
        $service_type,
        $service_date,
        $service_time_raw
    );

    if ( $should_validate_time_slot && ! $service_time_hidden && ! $allow_asap && ( empty( $service_time ) || $service_time < $current_time ) ) {
        $fallback_slot = rpress_get_next_available_service_time( $service_date, $available_slots, $current_time );

        if ( empty( $fallback_slot ) ) {
            return array(
                'status' => 'error',
                'error_msg' => __('Selected time slot is no longer available. Please choose another time.', 'restropress')
            );
        }

        $service_time_raw = $fallback_slot;
        $service_time = strtotime( $service_date . ' ' . $service_time_raw );
        setcookie( 'service_time', $service_time_raw, time() + ( 86400 * 30 ), '/' );
        setcookie( 'service_time_text', $service_time_raw, time() + ( 86400 * 30 ), '/' );
        $_COOKIE['service_time'] = $service_time_raw;
        $_COOKIE['service_time_text'] = $service_time_raw;
    }

    /* ==============================
       Success
    ============================== */

    return array(
        'status' => 'success'
    );
}

/**
 * Is Test Mode
 *
 * @since 1.0
 * @return bool $ret True if test mode is enabled, false otherwise
 */
function rpress_is_test_mode()
{
  $ret = rpress_get_option('test_mode', false);
  return (bool) apply_filters('rpress_is_test_mode', $ret);
}
/**
 * Is Debug Mode
 *
 * @since 1.0
 * @return bool $ret True if debug mode is enabled, false otherwise
 */
function rpress_is_debug_mode()
{
  $ret = rpress_get_option('debug_mode', false);
  if (defined('RPRESS_DEBUG_MODE') && RPRESS_DEBUG_MODE) {
    $ret = true;
  }
  return (bool) apply_filters('rpress_is_debug_mode', $ret);
}
/**
 * Checks if Guest checkout is enabled
 *
 * @since 1.0
 * @return bool $ret True if guest checkout is enabled, false otherwise
 */
function rpress_no_guest_checkout()
{
  $login_method = rpress_get_option('login_method', 'login_guest');
  $ret = $login_method == 'login_only' ? true : false;
  return (bool) apply_filters('rpress_no_guest_checkout', $ret);
}
/**
 * Redirect to checkout immediately after adding items to the cart?
 *
 * @since 1.0.0
 * @return bool $ret True is redirect is enabled, false otherwise
 */
function rpress_straight_to_checkout()
{
  $ret = rpress_get_option('redirect_on_add', false);
  return (bool) apply_filters('rpress_straight_to_checkout', $ret);
}
/**
 * Verify credit card numbers live?
 *
 * @since  1.0.0
 * @return bool $ret True is verify credit cards is live
 */
function rpress_is_cc_verify_enabled()
{
  $ret = true;
  /*
   * Enable if use a single gateway other than PayPal or Manual. We have to assume it accepts credit cards
   * Enable if using more than one gateway if they aren't both PayPal and manual, again assuming credit card usage
   */
  $gateways = rpress_get_enabled_payment_gateways();
  if (count($gateways) == 1 && !isset($gateways['paypal']) && !isset($gateways['manual'])) {
    $ret = true;
  } else if (count($gateways) == 1) {
    $ret = false;
  } else if (count($gateways) == 2 && isset($gateways['paypal']) && isset($gateways['manual'])) {
    $ret = false;
  }
  return (bool) apply_filters('rpress_verify_credit_cards', $ret);
}
/**
 * Check if the current page is a RestroPress Page or not
 */
function is_restropress_page()
{
  global $post;
  $rp_page = false;

  $menu_page     = absint( rpress_get_option( 'food_items_page', 0 ) );
  $checkout_page = absint( rpress_get_option( 'purchase_page', 0 ) );
  $success_page  = absint( rpress_get_option( 'success_page', 0 ) );

  if ( ! is_object( $post ) ) {
    $queried_id = absint( get_queried_object_id() );
    if ( $queried_id > 0 ) {
      $post = get_post( $queried_id );
    }
  }

  if ( is_object( $post ) ) {
    $post_id = absint( $post->ID );
    if ( $post_id > 0 && in_array( $post_id, array( $menu_page, $checkout_page, $success_page ), true ) ) {
      $rp_page = true;
    } else {
      $shortcodes = array( 'fooditems', 'fooditem_checkout', 'fooditem_cart', 'order_history', 'rpress_receipt' );
      foreach ( $shortcodes as $shortcode ) {
        if ( rpress_post_has_shortcode_content( $post, $shortcode ) ) {
          $rp_page = true;
          break;
        }
      }
    }
  }

  return apply_filters('is_a_restropress_page', $rp_page);
}

/**
 * Check if a post contains the shortcode in classic content or Elementor data.
 *
 * @since 3.0.1
 * @param WP_Post $post      Post object.
 * @param string  $shortcode Shortcode tag.
 * @return bool
 */
function rpress_post_has_shortcode_content( $post, $shortcode ) {
  if ( ! is_object( $post ) || empty( $shortcode ) ) {
    return false;
  }

  $content = isset( $post->post_content ) ? (string) $post->post_content : '';
  if ( ! empty( $content ) && has_shortcode( $content, $shortcode ) ) {
    return true;
  }

  $elementor_data = get_post_meta( $post->ID, '_elementor_data', true );
  if ( ! empty( $elementor_data ) && strpos( (string) $elementor_data, '[' . $shortcode ) !== false ) {
    return true;
  }

  return false;
}
/**
 * Is Odd
 *
 * Checks whether an integer is odd.
 *
 * @since 1.0
 * @param int     $int The integer to check
 * @return bool Is the integer odd?
 */
function rpress_is_odd($int)
{
  return (bool) ($int & 1);
}
/**
 * Get File Extension
 *
 * Returns the file extension of a filename.
 *
 * @since 1.0
 *
 * @param unknown $str File name
 *
 * @return mixed File extension
 */
function rpress_get_file_extension($str)
{
  $parts = explode('.', $str);
  return end($parts);
}
/**
 * Checks if the string (filename) provided is an image URL
 *
 * @since 1.0
 * @param string  $str Filename
 * @return bool Whether or not the filename is an image
 */
function rpress_string_is_image_url($str)
{
  $ext = rpress_get_file_extension($str);
  switch (strtolower($ext)) {
    case 'jpg';
      $return = true;
      break;
    case 'png';
      $return = true;
      break;
    case 'gif';
      $return = true;
      break;
    default:
      $return = false;
      break;
  }
  return (bool) apply_filters('rpress_string_is_image', $return, $str);
}
/**
 * Get User IP
 *
 * Returns the IP address of the current visitor
 *
 * @since 1.0
 * @return string $ip User's IP address
 */
function rpress_get_ip()
{
  $ip = '127.0.0.1';
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    //check ip from share internet
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    //to check ip is pass from proxy
    // can include more than 1 ip, first is the public one
    $ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $ip = trim($ip[0]);
  } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
  }
  // Fix potential CSV returned from $_SERVER variables
  $ip_array = explode(',', $ip);
  $ip_array = array_map('trim', $ip_array);
  return apply_filters('rpress_get_ip', $ip_array[0]);
}
/**
 * Get user host
 *
 * Returns the webhost this site is using if possible
 *
 * @since  1.0.0
 * @return mixed string $host if detected, false otherwise
 */
function rpress_get_host()
{
  $host = false;
  if (defined('WPE_APIKEY')) {
    $host = 'WP Engine';
  } elseif (defined('PAGELYBIN')) {
    $host = 'Pagely';
  } elseif (DB_HOST == 'localhost:/tmp/mysql5.sock') {
    $host = 'ICDSoft';
  } elseif (DB_HOST == 'mysqlv5') {
    $host = 'NetworkSolutions';
  } elseif (strpos(DB_HOST, 'ipagemysql.com') !== false) {
    $host = 'iPage';
  } elseif (strpos(DB_HOST, 'ipowermysql.com') !== false) {
    $host = 'IPower';
  } elseif (strpos(DB_HOST, '.gridserver.com') !== false) {
    $host = 'MediaTemple Grid';
  } elseif (strpos(DB_HOST, '.pair.com') !== false) {
    $host = 'pair Networks';
  } elseif (strpos(DB_HOST, '.stabletransit.com') !== false) {
    $host = 'Rackspace Cloud';
  } elseif (strpos(DB_HOST, '.sysfix.eu') !== false) {
    $host = 'SysFix.eu Power Hosting';
  } elseif (strpos($_SERVER['SERVER_NAME'], 'Flywheel') !== false) {
    $host = 'Flywheel';
  } else {
    // Adding a general fallback for data gathering
    $host = 'DBH: ' . DB_HOST . ', SRV: ' . $_SERVER['SERVER_NAME'];
  }
  return $host;
}
/**
 * Check site host
 *
 * @since  1.0.0
 * @param $host The host to check
 * @return bool true if host matches, false if not
 */
function rpress_is_host($host = false)
{
  $return = false;
  if ($host) {
    $host = str_replace(' ', '', strtolower($host));
    switch ($host) {
      case 'wpengine':
        if (defined('WPE_APIKEY'))
          $return = true;
        break;
      case 'pagely':
        if (defined('PAGELYBIN'))
          $return = true;
        break;
      case 'icdsoft':
        if (DB_HOST == 'localhost:/tmp/mysql5.sock')
          $return = true;
        break;
      case 'networksolutions':
        if (DB_HOST == 'mysqlv5')
          $return = true;
        break;
      case 'ipage':
        if (strpos(DB_HOST, 'ipagemysql.com') !== false)
          $return = true;
        break;
      case 'ipower':
        if (strpos(DB_HOST, 'ipowermysql.com') !== false)
          $return = true;
        break;
      case 'mediatemplegrid':
        if (strpos(DB_HOST, '.gridserver.com') !== false)
          $return = true;
        break;
      case 'pairnetworks':
        if (strpos(DB_HOST, '.pair.com') !== false)
          $return = true;
        break;
      case 'rackspacecloud':
        if (strpos(DB_HOST, '.stabletransit.com') !== false)
          $return = true;
        break;
      case 'sysfix.eu':
      case 'sysfix.eupowerhosting':
        if (strpos(DB_HOST, '.sysfix.eu') !== false)
          $return = true;
        break;
      case 'flywheel':
        if (strpos($_SERVER['SERVER_NAME'], 'Flywheel') !== false)
          $return = true;
        break;
      default:
        $return = false;
    }
  }
  return $return;
}
/**
 * Get Currencies
 *
 * @since 1.0
 * @return array $currencies A list of the available currencies
 */
function rpress_get_currencies()
{
  $currencies = array(
    'USD' => __('US Dollars (&#36;)', 'restropress'),
    'EUR' => __('Euros (&euro;)', 'restropress'),
    'GBP' => __('Pound Sterling (&pound;)', 'restropress'),
    'AUD' => __('Australian Dollars (&#36;)', 'restropress'),
    'BRL' => __('Brazilian Real (R&#36;)', 'restropress'),
    'CAD' => __('Canadian Dollars (&#36;)', 'restropress'),
    'CZK' => __('Czech Koruna (K&#269;)', 'restropress'),
    'DKK' => __('Danish Krone (kr)', 'restropress'),
    'HKD' => __('Hong Kong Dollar (&#36;)', 'restropress'),
    'HUF' => __('Hungarian Forint (Ft)', 'restropress'),
    'ILS' => __('Israeli Shekel (&#8362;)', 'restropress'),
    'JPY' => __('Japanese Yen (&yen;)', 'restropress'),
    'MYR' => __('Malaysian Ringgits (RM)', 'restropress'),
    'MXN' => __('Mexican Peso (&#36;)', 'restropress'),
    'NZD' => __('New Zealand Dollar (&#36;)', 'restropress'),
    'NOK' => __('Norwegian Krone (kr)', 'restropress'),
    'PKR' => __('Pakistani Rupee (Rs)', 'restropress'),
    'PHP' => __('Philippine Pesos (&#8369;)', 'restropress'),
    'PLN' => __('Polish Zloty (z&#322;)', 'restropress'),
    'SGD' => __('Singapore Dollar (&#36;)', 'restropress'),
    'SEK' => __('Swedish Krona (kr)', 'restropress'),
    'CHF' => __('Swiss Franc', 'restropress'),
    'TWD' => __('Taiwan New Dollars ($)', 'restropress'),
    'THB' => __('Thai Baht (&#3647;)', 'restropress'),
    'INR' => __('Indian Rupee (&#8377;)', 'restropress'),
    'TRY' => __('Turkish Lira (&#8378;)', 'restropress'),
    'RIAL' => __('Iranian Rial (&#65020;)', 'restropress'),
    'RUB' => __('Russian Rubles (&#8381;)', 'restropress'),
    'AOA' => __('Angolan Kwanza (Kz)', 'restropress'),
    'NGN' => __('Nigerian Naira (&#8358;)', 'restropress'),
    'AED' => __('UAE Dirham (&#1583;.&#1573;)', 'restropress'),
    'AFN' => __('Afghani (&#1547;)', 'restropress'),
    'AMD' => __('Armenian Dram (&#1423;)', 'restropress'),
    'VND' => __('Vietnamese dong (&#8363;)', 'restropress'),
    'CNY' => __('Renminbi (&yen;)', 'restropress'),
    'KRW' => __('South Korean won (&#8361;)', 'restropress'),
    'BDT' => __('Bangladeshi taka (&#2547;)', 'restropress'),
    'NPR' => __('Nepalese rupee (Rs)', 'restropress'),
    'AZN' => __('Azerbaijani manat (&#8380;)', 'restropress'),
  );

  return apply_filters('rpress_currencies', $currencies);
}
/**
 * Get the store's set currency
 *
 * @since 1.0
 * @return string The currency code
 */
function rpress_get_currency()
{
  $currency = rpress_get_option('currency', 'USD');
  return apply_filters('rpress_currency', $currency);
}
/**
 * Given a currency determine the symbol to use. If no currency given, site default is used.
 * If no symbol is determine, the currency string is returned.
 *
 * @since 1.0
 * @param  string $currency The currency string
 * @return string           The symbol to use for the currency
 */
function rpress_currency_symbol($currency = '')
{
  if (empty($currency)) {
    $currency = rpress_get_currency();
  }

  switch ($currency):
    case "GBP":
      $symbol = html_entity_decode('&pound;', ENT_QUOTES, 'UTF-8');
      break;
    case "BRL":
      $symbol = 'R$';
      break;
    case "EUR":
      $symbol = html_entity_decode('&euro;', ENT_QUOTES, 'UTF-8');
      break;
    case "INR":
      $symbol = html_entity_decode('&#8377;', ENT_QUOTES, 'UTF-8');
      break;
    case "USD":
    case "AUD":
    case "NZD":
    case "CAD":
    case "HKD":
    case "MXN":
    case "SGD":
    case "TWD":
      $symbol = '$';
      break;
    case "JPY":
    case "CNY":
      $symbol = html_entity_decode('&yen;', ENT_QUOTES, 'UTF-8');
      break;
    case "AOA":
      $symbol = 'Kz';
      break;
    case "NGN":
      $symbol = html_entity_decode('&#8358;', ENT_QUOTES, 'UTF-8');
      break;
    case "CZK":
      $symbol = html_entity_decode('K&#269;', ENT_QUOTES, 'UTF-8');
      break;
    case "HUF":
      $symbol = 'Ft';
      break;
    case "ILS":
      $symbol = html_entity_decode('&#8362;', ENT_QUOTES, 'UTF-8');
      break;
    case "MYR":
      $symbol = 'RM';
      break;
    case "NOK":
    case "SEK":
      $symbol = 'kr';
      break;
    case "PKR":
    case "NPR":
      $symbol = 'Rs';
      break;
    case "PHP":
      $symbol = html_entity_decode('&#8369;', ENT_QUOTES, 'UTF-8');
      break;
    case "PLN":
      $symbol = html_entity_decode('z&#322;', ENT_QUOTES, 'UTF-8');
      break;
    case "THB":
      $symbol = html_entity_decode('&#3647;', ENT_QUOTES, 'UTF-8');
      break;
    case "RIAL":
      $symbol = html_entity_decode('&#65020;', ENT_QUOTES, 'UTF-8');
      break;
    case "RUB":
      $symbol = html_entity_decode('&#8381;', ENT_QUOTES, 'UTF-8');
      break;
    case "AZN":
      $symbol = html_entity_decode('&#8380;', ENT_QUOTES, 'UTF-8');
      break;
    case "AED":
      $symbol = html_entity_decode('&#1583;.&#1573;', ENT_QUOTES, 'UTF-8');
      break;
    case "AFN":
      $symbol = html_entity_decode('&#1547;', ENT_QUOTES, 'UTF-8');
      break;
    case "AMD":
      $symbol = html_entity_decode('&#1423;', ENT_QUOTES, 'UTF-8');
      break;
    case "VND":
      $symbol = html_entity_decode('&#8363;', ENT_QUOTES, 'UTF-8');
      break;
    case "KRW":
      $symbol = html_entity_decode('&#8361;', ENT_QUOTES, 'UTF-8');
      break;
    case "BDT":
      $symbol = html_entity_decode('&#2547;', ENT_QUOTES, 'UTF-8');
      break;
    case "TRY":
      $symbol = html_entity_decode('&#8378;', ENT_QUOTES, 'UTF-8');
      break;
    default:
      $symbol = $currency;
      break;
  endswitch;

  return apply_filters('rpress_currency_symbol', $symbol, $currency);
}
/**
 * Get the name of a currency
 *
 * @since  1.0.0
 * @param  string $code The currency code
 * @return string The currency's name
 */
function rpress_get_currency_name($code = 'USD')
{
  $currencies = rpress_get_currencies();
  $name = isset($currencies[$code]) ? $currencies[$code] : $code;
  return apply_filters('rpress_currency_name', $name);
}
/**
 * Month Num To Name
 *
 * Takes a month number and returns the name three letter name of it.
 *
 * @since 1.0
 *
 * @param integer $n
 * @return string Short month name
 */
function rpress_month_num_to_name($n)
{
  $timestamp = mktime(0, 0, 0, $n, 1, 2005);
  return date_i18n("M", $timestamp);
}
/**
 * Get PHP Arg Separator Output
 *
 * @since 1.0
 * @return string Arg separator output
 */
function rpress_get_php_arg_separator_output()
{
  return ini_get('arg_separator.output');
}
/**
 * Get the current page URL
 *
 * @since 1.0
 * @param  bool   $nocache  If we should bust cache on the returned URL
 * @return string $page_url Current page URL
 */
function rpress_get_current_page_url($nocache = false)
{
  global $wp;
  if (get_option('permalink_structure')) {
    $base = trailingslashit(home_url($wp->request));
  } else {
    $base = add_query_arg($wp->query_string, '', trailingslashit(home_url($wp->request)));
    $base = remove_query_arg(array('post_type', 'name'), $base);
  }
  $scheme = is_ssl() ? 'https' : 'http';
  $uri = set_url_scheme($base, $scheme);
  if (is_front_page()) {
    $uri = home_url('/');
  } elseif (rpress_is_checkout()) {
    $uri = rpress_get_checkout_uri();
  }
  $uri = apply_filters('rpress_get_current_page_url', $uri);
  if ($nocache) {
    $uri = rpress_add_cache_busting($uri);
  }
  return $uri;
}
/**
 * Adds the 'nocache' parameter to the provided URL
 *
 * @since  1.0.0
 * @param  string $url The URL being requested
 * @return string      The URL with cache busting added or not
 */
function rpress_add_cache_busting($url = '')
{
  $no_cache_checkout = rpress_get_option('no_cache_checkout', false);
  if (rpress_is_caching_plugin_active() || (rpress_is_checkout() && $no_cache_checkout)) {
    $url = add_query_arg('nocache', 'true', $url);
  }
  return $url;
}
/**
 * Marks a function as deprecated and informs when it has been used.
 *
 * There is a hook rpress_deprecated_function_run that will be called that can be used
 * to get the backtrace up to what file and function called the deprecated
 * function.
 *
 * The current behavior is to trigger a user error if WP_DEBUG is true.
 *
 * This function is to be used in every function that is deprecated.
 *
 * @uses do_action() Calls 'rpress_deprecated_function_run' and passes the function name, what to use instead,
 *   and the version the function was deprecated in.
 * @uses apply_filters() Calls 'rpress_deprecated_function_trigger_error' and expects boolean value of true to do
 *   trigger or false to not trigger error.
 *
 * @param string  $function    The function that was called
 * @param string  $version     The version of RestroPress that deprecated the function
 * @param string  $replacement Optional. The function that should have been called
 * @param array   $backtrace   Optional. Contains stack backtrace of deprecated function
 */
function _rpress_deprecated_function($function, $version, $replacement = null, $backtrace = null)
{
  do_action('rpress_deprecated_function_run', $function, $replacement, $version);
  $show_errors = current_user_can('manage_options');
  // Allow plugin to filter the output error trigger
  if (WP_DEBUG && apply_filters('rpress_deprecated_function_trigger_error', $show_errors)) {
    if (!is_null($replacement)) {
      trigger_error(sprintf(
        /* translators: 1: function name, 2: version, 3: replacement function */
        '%1$s is deprecated since RestroPress version %2$s! Use %3$s instead.',
        esc_html($function),
        esc_html($version),
        esc_html($replacement)
      ));

      trigger_error(esc_html(print_r($backtrace, true))); // Safe for logs
    } else {
      trigger_error(sprintf(
        /* translators: 1: function name, 2: version */
        '%1$s is deprecated since RestroPress version %2$s with no alternative available.',
        esc_html($function),
        esc_html($version)
      ));

      trigger_error(esc_html(print_r($backtrace, true))); // Safe for logs
    }
  }
}
/**
 * Marks an argument in a function deprecated and informs when it's been used
 *
 * There is a hook rpress_deprecated_argument_run that will be called that can be used
 * to get the backtrace up to what file and function called the deprecated
 * function.
 *
 * The current behavior is to trigger a user error if WP_DEBUG is true.
 *
 * This function is to be used in every function that has an argument being deprecated.
 *
 * @uses do_action() Calls 'rpress_deprecated_argument_run' and passes the argument, function name, what to use instead,
 *   and the version the function was deprecated in.
 * @uses apply_filters() Calls 'rpress_deprecated_argument_trigger_error' and expects boolean value of true to do
 *   trigger or false to not trigger error.
 *
 * @param string  $argument    The arguemnt that is being deprecated
 * @param string  $function    The function that was called
 * @param string  $version     The version of WordPress that deprecated the function
 * @param string  $replacement Optional. The function that should have been called
 * @param array   $backtrace   Optional. Contains stack backtrace of deprecated function
 */
function _rpress_deprected_argument($argument, $function, $version, $replacement = null, $backtrace = null)
{
  do_action('rpress_deprecated_argument_run', $argument, $function, $replacement, $version);
  $show_errors = current_user_can('manage_options');
  // Allow plugin to filter the output error trigger
  if (WP_DEBUG && apply_filters('rpress_deprecated_argument_trigger_error', $show_errors)) {
    if (!is_null($replacement)) {
      trigger_error(sprintf(
        /* translators: 1: argument, 2: function, 3: version, 4: replacement */
        'The %1$s argument of %2$s is deprecated since RestroPress version %3$s! Please use %4$s instead.',
        esc_html($argument),
        esc_html($function),
        esc_html($version),
        esc_html($replacement)
      ));

      trigger_error(esc_html(print_r($backtrace, true))); // Safe for logs
    } else {
      trigger_error(sprintf(
        /* translators: 1: argument, 2: function, 3: version */
        'The %1$s argument of %2$s is deprecated since RestroPress version %3$s with no alternative available.',
        esc_html($argument),
        esc_html($function),
        esc_html($version)
      ));

      trigger_error(esc_html(print_r($backtrace, true))); // Safe for logs
    }
  }
}
/**
 * Checks whether function is disabled.
 *
 * @since 1.0.5
 *
 * @param string  $function Name of the function.
 * @return bool Whether or not function is disabled.
 */
function rpress_is_func_disabled($function)
{
  $disabled = explode(',', ini_get('disable_functions'));
  return in_array($function, $disabled);
}
/**
 * RPRESS Let To Num
 *
 * Does Size Conversions
 *
 * @since  1.0.0
 * @usedby rpress_settings()
 * @author Chris Christoff
 *
 * @param unknown $v
 * @return int
 */
function rpress_let_to_num($v)
{
  $l = substr($v, -1);
  $ret = substr($v, 0, -1);
  switch (strtoupper($l)) {
    case 'P': // fall-through
    case 'T': // fall-through
    case 'G': // fall-through
    case 'M': // fall-through
    case 'K': // fall-through
      $ret *= 1024;
      break;
    default:
      break;
  }
  return (int) $ret;
}
/**
 * Retrieve the URL of the symlink directory
 *
 * @since 1.0
 * @return string $url URL of the symlink directory
 */
function rpress_get_symlink_url()
{
  $wp_upload_dir = wp_upload_dir();
  wp_mkdir_p($wp_upload_dir['basedir'] . '/rpress/symlinks');
  $url = $wp_upload_dir['baseurl'] . '/rpress/symlinks';
  return apply_filters('rpress_get_symlink_url', $url);
}
/**
 * Retrieve the absolute path to the symlink directory
 *
 * @since 1.0
 * @return string $path Absolute path to the symlink directory
 */
function rpress_get_symlink_dir()
{
  $wp_upload_dir = wp_upload_dir();
  wp_mkdir_p($wp_upload_dir['basedir'] . '/rpress/symlinks');
  $path = $wp_upload_dir['basedir'] . '/rpress/symlinks';
  return apply_filters('rpress_get_symlink_dir', $path);
}
/**
 * Retrieve the absolute path to the file upload directory without the trailing slash
 *
 * @since 1.0
 * @return string $path Absolute path to the RPRESS upload directory
 */
function rpress_get_upload_dir()
{
  $wp_upload_dir = wp_upload_dir();
  wp_mkdir_p($wp_upload_dir['basedir'] . '/rpress');
  $path = $wp_upload_dir['basedir'] . '/rpress';
  return apply_filters('rpress_get_upload_dir', $path);
}
/**
 * Delete symbolic links after they have been used
 *
 * This function is only intended to be used by WordPress cron.
 *
 * @since 1.0
 * @return void
 */
function rpress_cleanup_file_symlinks()
{
  // Bail if not in WordPress cron
  if (!rpress_doing_cron()) {
    return;
  }
  $path = rpress_get_symlink_dir();
  $dir = opendir($path);
  while (($file = readdir($dir)) !== false) {
    if ($file == '.' || $file == '..')
      continue;
    $transient = get_transient(md5($file));
    if ($transient === false)
      @unlink($path . '/' . $file);
  }
}
add_action('rpress_cleanup_file_symlinks', 'rpress_cleanup_file_symlinks');
/**
 * Checks if SKUs are enabled
 *
 * @since  1.0.0
 * @author Daniel J Griffiths
 * @return bool $ret True if SKUs are enabled, false otherwise
 */
function rpress_use_skus()
{
  $ret = rpress_get_option('enable_skus', false);
  return (bool) apply_filters('rpress_use_skus', $ret);
}
/**
 * Retrieve timezone
 *
 * @since  1.0.0
 * @return string $timezone The timezone ID
 */
function rpress_get_timezone_id()
{
  // if site timezone string exists, return it
  if ($timezone = get_option('timezone_string'))
    return $timezone;
  // get UTC offset, if it isn't set return UTC
  if (!($utc_offset = 3600 * get_option('gmt_offset', 0)))
    return 'UTC';
  // attempt to guess the timezone string from the UTC offset
  $timezone = timezone_name_from_abbr('', $utc_offset);
  // last try, guess timezone string manually
  if ($timezone === false) {
    $is_dst = gmdate('I');
    foreach (timezone_abbreviations_list() as $abbr) {
      foreach ($abbr as $city) {
        if ($city['dst'] == $is_dst && $city['offset'] == $utc_offset)
          return $city['timezone_id'];
      }
    }
  }
  // fallback
  return 'UTC';
}
/**
 * Given an object or array of objects, convert them to arrays
 *
 * @since 1.0
 * @internal Updated in 2.6
 * @param    object|array $object An object or an array of objects
 * @return   array                An array or array of arrays, converted from the provided object(s)
 */
function rpress_object_to_array($object = array())
{
  if (empty($object) || (!is_object($object) && !is_array($object))) {
    return $object;
  }
  if (is_array($object)) {
    $return = array();
    foreach ($object as $item) {
      if ($object instanceof RPRESS_Payment) {
        $return[] = $object->array_convert();
      } else {
        $return[] = rpress_object_to_array($item);
      }
    }
  } else {
    if ($object instanceof RPRESS_Payment) {
      $return = $object->array_convert();
    } else {
      $return = get_object_vars($object);
      // Now look at the items that came back and convert any nested objects to arrays
      foreach ($return as $key => $value) {
        $value = (is_array($value) || is_object($value)) ? rpress_object_to_array($value) : $value;
        $return[$key] = $value;
      }
    }
  }
  return $return;
}
/**
 * Set Upload Directory
 *
 * Sets the upload dir to rpress. This function is called from
 * rpress_change_fooditems_upload_dir()
 *
 * @since 1.0
 * @return array Upload directory information
 */
function rpress_set_upload_dir($upload)
{
  // Override the year / month being based on the post publication date, if year/month organization is enabled
  if (get_option('uploads_use_yearmonth_folders')) {
    // Generate the yearly and monthly dirs
    $time = current_time('mysql');
    $y = substr($time, 0, 4);
    $m = substr($time, 5, 2);
    $upload['subdir'] = "/$y/$m";
  }
  $upload['subdir'] = '/rpress' . $upload['subdir'];
  $upload['path'] = $upload['basedir'] . $upload['subdir'];
  $upload['url'] = $upload['baseurl'] . $upload['subdir'];
  return $upload;
}
/**
 * Check if the upgrade routine has been run for a specific action
 *
 * @since  1.0.0
 * @param  string $upgrade_action The upgrade action to check completion for
 * @return bool                   If the action has been added to the copmleted actions array
 */
function rpress_has_upgrade_completed($upgrade_action = '')
{
  if (empty($upgrade_action)) {
    return false;
  }
  $completed_upgrades = rpress_get_completed_upgrades();
  return in_array($upgrade_action, $completed_upgrades);
}
/**
 * Get's the array of completed upgrade actions
 *
 * @since  1.0.0
 * @return array The array of completed upgrades
 */
function rpress_get_completed_upgrades()
{
  $completed_upgrades = get_option('rpress_completed_upgrades');
  if (false === $completed_upgrades) {
    $completed_upgrades = array();
  }
  return $completed_upgrades;
}
if (!function_exists('cal_days_in_month')) {
  // Fallback in case the calendar extension is not loaded in PHP
  // Only supports Gregorian calendar
  function cal_days_in_month($calendar, $month, $year)
  {
    return gmdate('t', mktime(0, 0, 0, $month, 1, $year));
  }
}
if (!function_exists('hash_equals')):
  /**
   * Compare two strings in constant time.
   *
   * This function was added in PHP 5.6.
   * It can leak the length of a string.
   *
   * @since 1.0
   *
   * @param string $a Expected string.
   * @param string $b Actual string.
   * @return bool Whether strings are equal.
   */
  function hash_equals($a, $b)
  {
    $a_length = strlen($a);
    if ($a_length !== strlen($b)) {
      return false;
    }
    $result = 0;
    // Do not attempt to "optimize" this.
    for ($i = 0; $i < $a_length; $i++) {
      $result |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $result === 0;
  }
endif;
if (!function_exists('getallheaders')):
  /**
   * Retrieve all headers
   *
   * Ensure getallheaders function exists in the case we're using nginx
   *
   * @since 1.0
   * @return array
   */
  function getallheaders()
  {
    $headers = array();
    foreach ($_SERVER as $name => $value) {
      if (substr($name, 0, 5) == 'HTTP_') {
        $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
      }
    }
    return $headers;
  }
endif;
/**
 * Determines the receipt visibility status
 *
 * @return bool Whether the receipt is visible or not.
 */
function rpress_can_view_receipt($payment_key = '')
{
  $return = false;
  if (empty($payment_key)) {
    return $return;
  }
  global $rpress_receipt_args;
  $rpress_receipt_args['id'] = rpress_get_purchase_id_by_key($payment_key);
  $user_id = (int) rpress_get_payment_user_id($rpress_receipt_args['id']);
  $payment_meta = rpress_get_payment_meta($rpress_receipt_args['id']);
  if (is_user_logged_in()) {
    if ($user_id === (int) get_current_user_id()) {
      $return = true;
    } elseif (wp_get_current_user()->user_email === rpress_get_payment_user_email($rpress_receipt_args['id'])) {
      $return = true;
    } elseif (current_user_can('view_shop_sensitive_data')) {
      $return = true;
    }
  }
  $session = rpress_get_purchase_session();
  if (!empty($session) && !is_user_logged_in()) {
    if ($session['purchase_key'] === $payment_meta['key']) {
      $return = true;
    }
  }
  return (bool) apply_filters('rpress_can_view_receipt', $return, $payment_key);
}
/**
 * Given a Payment ID, generate a link to IP address provider (ipinfo.io)
 *
 * @since 1.0
 * @param  int    $payment_id The Payment ID
 * @return string A link to the IP details provider
 */
function rpress_payment_get_ip_address_url($payment_id)
{
  $payment = new RPRESS_Payment($payment_id);
  $base_url = 'https://ipinfo.io/';
  $provider_url = '<a href="' . esc_url($base_url) . esc_attr($payment->ip) . '" target="_blank">' . esc_attr($payment->ip) . '</a>';
  return apply_filters('rpress_payment_get_ip_address_url', $provider_url, $payment->ip, $payment_id);
}
/**
 * Abstraction for WordPress cron checking, to avoid code duplication.
 *
 * In future versions of RPRESS, this function will be changed to only refer to
 * RPRESS specific cron related jobs. You probably won't want to use it until then.
 *
 * @since 1.0
 *
 * @return boolean
 */
function rpress_doing_cron()
{
  // Bail if not doing WordPress cron (>4.8.0)
  if (function_exists('wp_doing_cron') && wp_doing_cron()) {
    return true;
    // Bail if not doing WordPress cron (<4.8.0)
  } elseif (defined('DOING_CRON') && (true === DOING_CRON)) {
    return true;
  }
  // Default to false
  return false;
}
/**
 * Display a RestroPress help tip.
 *
 * @since  3.0
 *
 * @param  string $tip        Help tip text.
 * @param  bool   $allow_html Allow sanitized HTML if true or escape.
 * @return string
 */
function rp_help_tip($tip, $allow_html = false)
{
  if ($allow_html) {
    $tip = rpress_sanitize_tooltip($tip);
  } else {
    $tip = esc_attr($tip);
  }
  return '<span class="restropress-help-tip" data-tip="' . $tip . '"></span>';
}
/**
 * Is pickup/delivery time enabled
 *
 * @since 1.0
 * @return bool $ret True if test mode is enabled, false otherwise
 */
function rpress_is_service_enabled($service)
{
  $service               = sanitize_key((string) $service);
  $enabled_service_types = rpress_get_enabled_service_types();
  $is_enabled            = !empty($service) && isset($enabled_service_types[$service]);

  return (bool) apply_filters('rpress_is_service_enabled', $is_enabled, $service, $enabled_service_types);
}
function rpress_fooditem_available($fooditem_id)
{
  return (bool) apply_filters('rpress_is_orderable', true, $fooditem_id);
}
/** Get Singular Label
 *  @since 2.0.7
 *
 *  @param bool $lowercase
 *  @return string $defaults['singular'] Singular label
 */
function rp_get_label_singular($lowercase = false)
{
  $defaults = rp_get_default_labels();
  return ($lowercase) ? strtolower($defaults['singular']) : $defaults['singular'];
}
/**
 * Get Plural Label
 *
 * @since 1.0
 * @return string $defaults['plural'] Plural label
 */
function rp_get_label_plural($lowercase = false)
{
  $defaults = rp_get_default_labels();
  return ($lowercase) ? strtolower($defaults['plural']) : $defaults['plural'];
}
/**
 * Get Default Labels
 *
 * @since 1.0
 * @return array $defaults Default labels
 */
function rp_get_default_labels()
{
  $defaults = array(
    'singular' => __('Food Item', 'restropress'),
    'plural' => __('Food Items', 'restropress')
  );
  return apply_filters('rp_default_fooditems_name', $defaults);
}
/**
 * Get food type icon from id
 *
 * @since 2.7.2
 * @return string image source for the icon
 */
function rpress_get_fooditem_icon($id = '')
{
  if (empty($id))
    $id = get_the_ID();
  $food_type = get_post_meta($id, 'rpress_food_type', true);
  $icon_url = apply_filters('rpress_food_type_icon', RP_PLUGIN_URL . 'assets/images/' . $food_type . '.png');
  if (!empty($food_type) && !empty($icon_url))
    return '<img src="' . $icon_url . '" class="rpress-food-type-icon">';
}
/**
 * Get defalut checkout fields
 *
 * @since 2.8
 * @return array
 */
function rp_get_checkout_fields()
{
  $customer = RPRESS()->session->get('customer');
  $customer = wp_parse_args($customer, array(
    'delivery_address' => array(
      'address' => '',
      'flat' => '',
      'city' => '',
      'postcode' => '',
    )
  ));
  $customer['delivery_address'] = array_map('sanitize_text_field', $customer['delivery_address']);
  if (is_user_logged_in()) {
    $user_address = get_user_meta(get_current_user_id(), '_rpress_user_delivery_address', true);
    foreach ($customer['delivery_address'] as $key => $field) {
      if (empty($field) && !empty($user_address[$key])) {
        $customer['delivery_address'][$key] = $user_address[$key];
      } else {
        $customer['delivery_address'][$key] = '';
      }
    }
  }
  $customer['delivery_address'] = apply_filters('rpress_customer_delivery_address', $customer['delivery_address']);
  $checkout_fields = array(
    'rpress_street_address' => array(
      'id' => 'rpress-street-address',
      'title' => __('Street Address', 'restropress'),
      'is_required' => true,
      'is_hidden' => false,
      'name' => 'rpress_street_address',
      'placeholder' => __('Street Address', 'restropress'),
      'value' => $customer['delivery_address']['address'],
    ),
    'rpress_apt_suite' => array(
      'id' => 'rpress-apt-suite',
      'title' => __('Apartment, suite, unit etc. (optional)', 'restropress'),
      'is_required' => false,
      'is_hidden' => false,
      'name' => 'rpress_apt_suite',
      'placeholder' => __('Apartment, suite, unit etc. (optional)', 'restropress'),
      'value' => $customer['delivery_address']['flat'],
    ),
    'rpress_city' => array(
      'id' => 'rpress_city',
      'title' => __('Town / City', 'restropress'),
      'is_required' => true,
      'is_hidden' => false,
      'name' => 'rpress_city',
      'placeholder' => __('Town / City', 'restropress'),
      'value' => $customer['delivery_address']['city'],
    ),
    'rpress_postcode' => array(
      'id' => 'rpress-postcode',
      'title' => __('Postcode / ZIP', 'restropress'),
      'is_required' => true,
      'is_hidden' => false,
      'name' => 'rpress_postcode',
      'placeholder' => __('Postcode / ZIP', 'restropress'),
      'value' => $customer['delivery_address']['postcode'],
    ),
  );
  return apply_filters('rpress_checkout_fields', $checkout_fields, $customer['delivery_address']);
}
/**
 *  Get order count based on order status
 *  @since 2.8.4
 *
 *  @param string $status
 *  @return int $order_count 
 */
function rp_get_order_count($status = 'pending')
{
  global $wpdb;

  $query = $wpdb->prepare(
    "SELECT COUNT(DISTINCT pm.post_id) AS count
    FROM {$wpdb->postmeta} pm
    INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
    WHERE pm.meta_key = %s
      AND pm.meta_value = %s
      AND p.post_type = %s
      AND p.post_status <> %s",
    '_order_status',
    $status,
    'rpress_payment',
    'trash'
  );

  $order_count = (int) $wpdb->get_var($query);

  return apply_filters('rpress_order_count', $order_count, $status);
}

add_action('admin_init', 'my_plugin_handle_setup_form');
function my_plugin_handle_setup_form()
{
  if (
    isset($_GET['page']) && $_GET['page'] === 'rpress-setup' &&
    isset($_POST['my_plugin_setup_nonce']) &&
    wp_verify_nonce($_POST['my_plugin_setup_nonce'], 'my_plugin_save_setup')
  ) {
    // Get existing settings
    $options = get_option('rpress_settings', array());

    // Update with new values
    $options['enable_service'] = sanitize_text_field($_POST['enable_service']);
    $options['default_service'] = sanitize_text_field($_POST['default_service']);

    // Save back
    update_option('rpress_settings', $options);

    wp_safe_redirect(admin_url());
    exit;
  }
}
add_filter('body_class', function ($classes) {
  // Get current post object
  global $post;

  // Add custom class only if page slug is NOT "checkout"
  if (isset($post->post_name) && $post->post_name !== 'checkout') {
    if (!in_array('order-online', $classes, true)) {
      $classes[] = 'order-online';
    }
  }
  return $classes;
});

/**
 * Check if store is open based on current time and settings
 * @since 3.2.2.1
 */
function rpress_is_store_open($service_type, $selected_date = '')
{
  $current_time = current_time('timestamp');
  $current_day = date_i18n('Y-m-d', $current_time);

  if (!empty(rpress_get_option('enable_always_open'))) {
    $open_time = strtotime($current_day . ' 00:00');
    $close_time = strtotime($current_day . ' 23:59');
    $is_open = true;
  } else {
    $open_time_raw = !empty(rpress_get_option('open_time')) ? rpress_get_option('open_time') : '9:00am';
    $close_time_raw = !empty(rpress_get_option('close_time')) ? rpress_get_option('close_time') : '11:30pm';

    $open_time = strtotime($current_day . ' ' . $open_time_raw);
    $close_time = strtotime($current_day . ' ' . $close_time_raw);

    if ($open_time === false || $close_time === false) {
      $is_open = false;
    } elseif ($close_time < $open_time) {
      // Overnight window (for example 6:00pm to 2:00am).
      $is_open = ($current_time >= $open_time || $current_time <= $close_time);
    } elseif ($close_time === $open_time) {
      // Same open/close values are treated as closed unless "always open" is enabled.
      $is_open = false;
    } else {
      $is_open = ($current_time >= $open_time && $current_time <= $close_time);
    }
  }
  if (empty($selected_date)) {
    $selected_date = date_i18n('Y-m-d', $current_time);
  }
  // Apply filter to allow other plugins to modify the status
  $is_open = apply_filters('rpress_is_store_open', $is_open, $service_type, $selected_date, $current_time, $open_time, $close_time);

  return $is_open;
}
/**
 * Store closed message
 * @since 3.2.2.1
 */
function rpress_store_closed_message($service_type)
{
  $close_message = rpress_get_option('store_closed_msg', __('Sorry, we are closed for ordering now.', 'restropress'));
  $close_message = apply_filters('rpress_store_closed_message', $close_message, $service_type);
  return $close_message;
}

/**
 * Nessery cookies and   time slot for RPRESS
 * @since 3.2.3
 */
function rpress_get_service_context( $service_type_override = '' ): array
{

  $context = [
    'service_type' => '',
    'service_date_raw' => '',
    'service_date' => '',
    'service_time' => '',
    'delivery_address' => '',
    'selected_time' => '',
    'store_timings' => [],
    'is_store_open' => true,
  ];

  /* ---------------- Cookies / Request ---------------- */

  $context['service_type'] = isset($_GET['service_type'])
    ? sanitize_text_field(wp_unslash($_GET['service_type']))
    : ($_COOKIE['service_type'] ?? '');

  $context['service_type'] = sanitize_text_field(wp_unslash($context['service_type']));

  $context['service_time'] = isset($_COOKIE['service_time'])
    ? sanitize_text_field(wp_unslash($_COOKIE['service_time']))
    : '';

  if ( function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $context['service_type'] ) ) {
    $context['service_time'] = '';
  }

  $context['service_date_raw'] = isset($_COOKIE['service_date'])
    ? sanitize_text_field(wp_unslash($_COOKIE['service_date']))
    : '';

  $delivery_address = isset($_COOKIE['branch_name'])
    ? sanitize_text_field(wp_unslash($_COOKIE['branch_name']))
    : (isset($_COOKIE['delivery_address']) ? sanitize_text_field(wp_unslash($_COOKIE['delivery_address'])) : '');

  $context['delivery_address'] = apply_filters(
    'rpress_service_context_delivery_address',
    $delivery_address,
    $context
  );

  /* ---------------- Service Type ---------------- */

  $enabled = rpress_get_option('enable_service', 'delivery_and_pickup');
  $context["service_enabled"] = $enabled;
  $context['services'] = rpress_get_enabled_services();

  if (!in_array($context['service_type'], $context['services'], true)) {
    $default_service = rpress_get_default_enabled_service();
    $context['service_type'] = in_array($default_service, $context['services'], true)
      ? $default_service
      : (!empty($context['services']) ? (string) reset($context['services']) : '');
  }

  $service_type_override = strtolower( sanitize_text_field( (string) $service_type_override ) );
  if ( ! empty( $service_type_override ) && in_array( $service_type_override, $context['services'], true ) ) {
    $context['service_type'] = $service_type_override;
  }

  $context['service_type'] = apply_filters(
    'rpress_current_service_type',
    $context['service_type']
  );

  /* ---------------- Date Formatting ---------------- */
  $raw = rpress_get_first_available_service_date( $context['service_type'], $context['service_date_raw'] );
  $context['service_date_raw'] = $raw;

  if (!empty($raw)) {
    $date = DateTime::createFromFormat('Y-m-d', $raw);
    $context['service_date'] = $date
      ? $date->format('F j')
      : date_i18n('F j');
  } else {
    $context['service_date'] = date_i18n('F j');
  }

  /* ---------------- Time Handling ---------------- */

  if (stripos($context['service_time'], 'ASAP') !== false) {
    $context['service_time'] = str_ireplace(
      'ASAP',
      'ASAP ',
      $context['service_time']
    );
  }

  /* ---------------- Store Timings ---------------- */
  $context['store_timings'] = rpress_get_available_service_slots(
    $context['service_type'],
    $context['service_date_raw'],
    true
  );

  $service_time_hidden = function_exists( 'rp_otil_is_service_time_hidden' ) && rp_otil_is_service_time_hidden( $context['service_type'] );
  if ( $service_time_hidden ) {
    $context['selected_time'] = '';
  } else {
    $allow_asap = ! empty( rpress_get_option( 'enable_asap_option' ) );
    $context['selected_time'] = rpress_match_service_time_to_slot(
      $context['service_time'],
      $context['store_timings'],
      $allow_asap
    );

    if ( empty( $context['selected_time'] ) && ! empty( $context['store_timings'] ) ) {
      $context['selected_time'] = rpress_get_next_available_service_time(
        $context['service_date_raw'],
        $context['store_timings'],
        0
      );
    }

    if ( empty( $context['selected_time'] ) ) {
      $context['selected_time'] = rpress_get_option( 'default_time' );
    }
  }
  /* ---------------- Store Open Check ---------------- */

  $service_date_for_checks = !empty($context['service_date_raw'])
    ? rp_row_date($context['service_date_raw'], $context['service_type'])
    : date_i18n('Y-m-d');

  if (!rpress_is_store_open($context['service_type'], $service_date_for_checks)) {
    $context['is_store_open'] = false;
  }

  return $context;
}

function rp_row_date($raw_date, $service_type): string
{
  $raw = apply_filters(
    'rpress_service_date_raw',
    $raw_date,
    $service_type
  );
  if (empty($raw)) {
    return date_i18n('Y-m-d');
  }
  return $raw;
}
