<?php
defined('BASEPATH') or exit('No direct script access allowed');

/**
 * Lightweight action/filter system (WordPress-style) for reuse.
 */
if (!isset($GLOBALS['__ci_hooks_actions'])) {
	$GLOBALS['__ci_hooks_actions'] = array();
}
if (!isset($GLOBALS['__ci_hooks_filters'])) {
	$GLOBALS['__ci_hooks_filters'] = array();
}

if (!function_exists('add_action')) {
	function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1)
	{
		$GLOBALS['__ci_hooks_actions'][$tag][$priority][] = array($function_to_add, (int) $accepted_args);
	}
}

if (!function_exists('do_action')) {
	function do_action($tag, ...$args)
	{
		if (empty($GLOBALS['__ci_hooks_actions'][$tag])) {
			return;
		}
		ksort($GLOBALS['__ci_hooks_actions'][$tag]);
		foreach ($GLOBALS['__ci_hooks_actions'][$tag] as $priority => $hooks) {
			foreach ($hooks as $hook) {
				list($fn, $accepted) = $hook;
				if (is_callable($fn)) {
					call_user_func_array($fn, array_slice($args, 0, $accepted));
				}
			}
		}
	}
}

if (!function_exists('add_filter')) {
	function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1)
	{
		$GLOBALS['__ci_hooks_filters'][$tag][$priority][] = array($function_to_add, (int) $accepted_args);
	}
}

if (!function_exists('apply_filters')) {
	function apply_filters($tag, $value, ...$args)
	{
		if (empty($GLOBALS['__ci_hooks_filters'][$tag])) {
			return $value;
		}
		ksort($GLOBALS['__ci_hooks_filters'][$tag]);
		$filtered = $value;
		foreach ($GLOBALS['__ci_hooks_filters'][$tag] as $priority => $hooks) {
			foreach ($hooks as $hook) {
				list($fn, $accepted) = $hook;
				if (is_callable($fn)) {
					$params = array_merge(array($filtered), array_slice($args, 0, $accepted - 1));
					$filtered = call_user_func_array($fn, $params);
				}
			}
		}
		return $filtered;
	}
}

if (!function_exists('remove_action')) {
	function remove_action($tag, $function_to_remove, $priority = 10)
	{
		if (empty($GLOBALS['__ci_hooks_actions'][$tag][$priority])) {
			return;
		}
		$GLOBALS['__ci_hooks_actions'][$tag][$priority] = array_filter(
			$GLOBALS['__ci_hooks_actions'][$tag][$priority],
			function ($hook) use ($function_to_remove) {
				return $hook[0] !== $function_to_remove;
			}
		);
	}
}

if (!function_exists('remove_filter')) {
	function remove_filter($tag, $function_to_remove, $priority = 10)
	{
		if (empty($GLOBALS['__ci_hooks_filters'][$tag][$priority])) {
			return;
		}
		$GLOBALS['__ci_hooks_filters'][$tag][$priority] = array_filter(
			$GLOBALS['__ci_hooks_filters'][$tag][$priority],
			function ($hook) use ($function_to_remove) {
				return $hook[0] !== $function_to_remove;
			}
		);
	}
}
