autoship_add_to_scheduled_order_link_handler (function)

(src/scheduled-orders.php) Used to process the Add to Scheduled Order Link data. It takes the $link (array) as a parameter and returns a boolean or WP_Error. 

Function

/**
 * Processes the Add to Scheduled Order Link Data
 * @param array $link {
 *          The link param in an array
 *          @type int|array $products       Array of woocommerce simple or variation ids or single id
 *          @type int       $qty            The qty to add
 *          @type int       $min            The min cycles
 *          @type int       $max            The max cycles
 *          @type int       $frequency      The frequency
 *          @type string    $frequency_type The frequency type
 *          @type int       $order          The Autoship Scheduled Order ID
 *          @type string    $coupon         The coupon code
 *          @type string    $customer_id    The WC Customer ID hashed
 *          @type float     $discount       The discount amount ( SUPPLIED AS NULL )
 * }
 *
 * @return bool|WP_Error  True on Success, False if no scheduled order exists,
 *                        WP_Error on failure
 */
function autoship_add_to_scheduled_order_link_handler( $link ){

  // The General notice is used for any link failures not related to coupons
  $general_notice = apply_filters( 'autoship_add_to_scheduled_order_link_invalid',
  __( 'The supplied link is no longer valid or has expired.', "autoship" ),
  $link );

  do_action( 'autoship_initiate_add_to_scheduled_order_link_handler', $link );

  // Check for Products / Line Items & validate them
  if ( isset( $link['products'] ) && !empty( $link['products'] ) ){

    $products = is_array( $link['products'] ) ? array_keys( $link['products'] ) : array( $link['products'] );

    // Setup the Query Params for the QPilot call
    // By default we search for only those ids that are enabled to be added to an order.
    $valid_products = apply_filters( 'autoship_add_to_scheduled_order_endpoint_valid_products_params',
    array( 'productIds' => $products ), $link );

    // Make the Search call
    $available_products = autoship_search_available_products( $valid_products );

    if ( !is_wp_error( $available_products ) && !empty( $available_products ) ){

      // Loop through the QPilot products and attach any needed info.
      $link['items'] = array();
      foreach ($available_products as $key => $value) {

        if ( ( is_array( $link['products'] ) && !isset( $link['products'][$value->id] ) ) || ( !is_array( $link['products'] ) && $link['products'] != $value->id ) )
        continue;

        // Grab the prices - runs through the custom filter
        $prices = autoship_get_product_prices( $value->id );

        // Create the min-needed for a line item
        // Devs can adjust on the fly using URL params
        $line = apply_filters('autoship_create_scheduled_order_endpoint_item', array(
          'productId' => $value->id,
          'price'     => $prices['regular_price'],
          'salePrice' => $prices['autoship_recurring_price'],
          'quantity'  => is_array( $link['products'] ) ? $link['products'][$value->id] : $link['qty']
        ), $link );

        // Check for Min Cycle Data
        if ( isset( $link['min'] ) && is_array( $link['min'] ) ){
          $line['minCycles'] = isset( $link['min'][$value->id] ) ? $link['min'][$value->id] : NULL;
        } else if ( isset( $link['min'] ) ){
          $line['minCycles'] = $link['min'];
        }

        // Check for Max Cycle Data
        if (  isset( $link['max'] ) && is_array( $link['max'] ) ){
          $line['maxCycles'] = isset( $link['max'][$value->id] ) ? $link['max'][$value->id] : NULL;
        } else if ( isset( $link['max'] ) ){
          $line['maxCycles'] = $link['max'];
        }

        // Validate Coupon and get discount
        if ( isset( $link['coupon'] ) && !empty( $link['coupon'] ) ){

          $coupon_notice = apply_filters( 'autoship_add_to_scheduled_order_link_invalid_coupon',
          __( 'The supplied discount link is no longer valid or has expired.', "autoship" ),
          $link );

          // Grab the new discount price since there's a coupon
          $link['discount'] = autoship_validate_and_get_autoship_coupon_discount( $link['coupon'], $line['productId'], apply_filters( 'autoship_add_to_scheduled_order_link_coupon_base_price', $line['price'], $line['salePrice'], $line, $link ), $line['quantity'], $line['minCycles'], $line['maxCycles'], $link['customer_id'] );

          if ( is_wp_error( $link['discount'] ) )
          return new WP_Error( 'invalid_or_expired_discount', $coupon_notice );

          // Set the sale price to the new discount price if it exists
          $line['salePrice'] = $link['discount'];

        }

        $link['items'][] = $line;

      }

    }

  }

  // If there are no valid items to add bail.
  if ( !isset( $link['items'] ) || empty( $link['items'] ) )
  return new WP_Error( 'invalid_or_expired_link', $general_notice );

  // Allow Filters to adjust link data on the fly
  $link = apply_filters( 'autoship_add_to_scheduled_order_link_values', $link, $products );

  // Check if a specific order number is specified or a freq and frequency type.
  // Else we add to the next order.
  if ( ( isset( $link['order'] ) && !empty( $link['order'] ) ) ||
       ( isset( $link['frequency'] ) || isset( $link['frequency_type'] ) ) ) {

    // Use specific order if specified.
    if ( isset( $link['order'] ) && !empty( $link['order'] ) ){

      // Since a specific id is supplied we need to validate it belongs to this user.
      $order = autoship_get_scheduled_order( $link['order'] );

      // Bail if no next order exists
      // Also Check the customer info if an order is found.
      if ( is_wp_error( $order ) || ( $order->customerId != $link['customer_id'] ) )
      return false;

    } else {

      // Check the Frequency and Frequency Type and if populated we need to get the next order that matches.
      $type_id = autoship_get_frequencytype_int ( $link['frequency_type'] );

      // Bail if the frequency type doesn't exist
      if ( false === $type_id )
      return new WP_Error( 'invalid_or_expired_link', $general_notice );

      // Get the next scheduled order
      $order = autoship_get_next_scheduled_order( $link['customer_id'], $link['frequency'], $type_id );

      // Bail if no next order exists
      if ( is_wp_error( $order ) )
      return false;

    }

    // Now add the items via the api
    $updated = autoship_create_scheduled_order_items( $order->id, $link['items'] );

    // Since the function returns true on success or WP_Error on false
    // Check it.
    $updated = is_wp_error( $updated ) ? $updated : $order->id;

  } else {

    // Call Autoships add to next scheduled order.
    $updated = autoship_update_next_scheduled_order_with_items ( $link['customer_id'], $link['items'] );

    // Special catch in case next order doesn't exist.
    if ( is_wp_error( $updated ) )
    return false;

  }

  return $updated;
}