Skip to content
← Back to Functions
Code

Cart Line Merger

Merges cart lines by product/options and recalculates quantities.

Function signature

ogMergeCartLines(input = array(), options = array())

Categories

  • Ecommerce Workflows

Parameters

inputStructured workflow input array documented by this helper.optionsOptional documented policy controls for the helper.

Return value

Public-safe status string returned by the function for controller branching or logging.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and context-specific escaping; validate file paths, routes, email tokens, cart totals, discount rules, and tax-region rules before production use.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Merges cart lines by product/options and recalculates quantities.
 *
 * Primary use case: Shopping carts.
 * Typical inputs: cart lines, new line, merge rules.
 * Typical output: updated cart lines.
 *
 * Implementation note: Validate ownership, stock, and option IDs separately.
 *
 * @param array $input Structured input values for this helper contract.
 * @param array $options Optional policy and formatting controls.
 * @return array Structured result data with success, message, and data keys.
 */
function ogMergeCartLines($input = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($input)) {
		$result['message'] = 'Input must be an array.';
		return $result;
	}

	if (!is_array($options)) {
		$options = array();
	}

	$lines = array();
	if (!empty($input['lines']) && is_array($input['lines'])) {
		$lines = $input['lines'];
	}
	$new_line = array();
	if (!empty($input['new_line']) && is_array($input['new_line'])) {
		$new_line = $input['new_line'];
	}
	if (empty($new_line)) {
		$result['message'] = 'New cart line is required.';
		return $result;
	}

	$identity_fields = array('product_id', 'sku', 'size', 'color', 'option_hash');
	if (!empty($options['identity_fields']) && is_array($options['identity_fields'])) {
		$identity_fields = $options['identity_fields'];
	}

	$merged = false;
	foreach ($lines as $index => $line) {
		if (!is_array($line)) {
			continue;
		}
		$same = true;
		foreach ($identity_fields as $field) {
			$left = '';
			$right = '';
			if (isset($line[$field])) {
				$left = (string)$line[$field];
			}
			if (isset($new_line[$field])) {
				$right = (string)$new_line[$field];
			}
			if ($left !== $right) {
				$same = false;
			}
		}
		if ($same) {
			$quantity = 0;
			if (!empty($line['quantity'])) {
				$quantity += (int)$line['quantity'];
			}
			if (!empty($new_line['quantity'])) {
				$quantity += (int)$new_line['quantity'];
			} else {
				$quantity++;
			}
			if ($quantity < 1) {
				$quantity = 1;
			}
			$lines[$index]['quantity'] = $quantity;
			$merged = true;
			break;
		}
	}

	if (!$merged) {
		if (empty($new_line['quantity'])) {
			$new_line['quantity'] = 1;
		}
		$lines[] = $new_line;
	}

	$result['success'] = true;
	$result['message'] = 'Cart lines merged.';
	$result['data'] = array('lines' => $lines, 'merged_existing_line' => $merged);

	return $result;
}