Skip to content
← Back to Functions
Code

Sef Url Generator

Generates SEF URLs for item types, categories, search, and pagination.

Function signature

ogGenerateSefUrl(route_type, route_data = array(), options = array())

Categories

  • Search and Discovery

Parameters

route_typeApproved route type used to choose the canonical or SEF URL pattern.route_dataClean route values used to generate a SEF URL.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.
 */

/**
 * Generates SEF URLs for item types, categories, search, and pagination.
 *
 * Primary use case: Links and canonical tags.
 * Typical inputs: route type, route data.
 * Typical output: path string.
 *
 * Implementation note: Use one generator for visible links and canonicals.
 *
 * @param string $route_type Route family such as function, functions, search, or category.
 * @param array $route_data Route values such as id, slug, page, query, or category.
 * @param array $options Options including host and absolute flag.
 * @return array Structured URL result.
 */
function ogGenerateSefUrl($route_type, $route_data = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$route_type = trim((string)$route_type);
	if (!is_array($route_data)) {
		$route_data = array();
	}
	if (!is_array($options)) {
		$options = array();
	}

	$host = 'phpog.com';
	if (!empty($options['host'])) {
		$host = trim((string)$options['host']);
	}
	$host = preg_replace('/^https?:\/\//i', '', $host);
	$host = preg_replace('/^\/\//', '', $host);
	$host = preg_replace('/^www\./i', '', $host);
	$host = trim($host, '/');

	$absolute = true;
	if (isset($options['absolute']) && $options['absolute'] === false) {
		$absolute = false;
	}

	$path = '';
	switch ($route_type) {
		case 'home':
			$path = '/';
		break;

		case 'functions':
		case 'snippets':
		case 'objects':
		case 'scripts':
		case 'resources':
		case 'portfolio':
		case 'turnkey':
			$path = '/' . $route_type;
		break;

		case 'function':
		case 'snippet':
		case 'object':
		case 'script':
		case 'resource':
			if (empty($route_data['id']) || empty($route_data['slug'])) {
				$result['message'] = 'Detail route requires id and slug.';
				return $result;
			}
			$path = '/' . $route_type . '/' . (int)$route_data['id'] . '/' . trim((string)$route_data['slug'], '/');
		break;

		case 'search':
			$path = '/search';
			if (!empty($route_data['query'])) {
				$path .= '/' . rawurlencode(trim((string)$route_data['query']));
			}
		break;

		case 'category':
			if (empty($route_data['section']) || empty($route_data['slug'])) {
				$result['message'] = 'Category route requires section and slug.';
				return $result;
			}
			$path = '/' . trim((string)$route_data['section'], '/') . '/category/' . trim((string)$route_data['slug'], '/');
		break;

		default:
			$result['message'] = 'Unknown route type.';
			return $result;
	}

	if (!empty($route_data['page'])) {
		$page = (int)$route_data['page'];
		if ($page > 1) {
			$path .= '/page/' . $page;
		}
	}

	$url = $path;
	if ($absolute) {
		$url = '//' . $host . $path;
	}

	$result['success'] = true;
	$result['message'] = 'SEF URL generated.';
	$result['data'] = array(
		'url' => $url,
		'path' => $path
	);

	return $result;
}