<chapter id="dev.events">
	<title>Event System</title>

	<sect1 id="dev.events.concepts">
		<title>General Concepts</title>

		<para>
			The event system in MantisBT uses the concept of signals and hooked events
			to drive dynamic actions.  Functions, or plugin methods, can be hooked
			during runtime to various defined events, which can be signalled at any
			point to initiate execution of hooked functions.
		</para>

		<para>
			Events are defined at runtime by name and event type (covered in the next
			section).  Depending on the event type, signal parameters and return
			values from hooked functions will be handled in different ways to make
			certain types of common communication simplified.
		</para>
	</sect1>

	<sect1 id="dev.events.api">
		<title>API Usage</title>

		<para>
			This is a general overview of the event API.  For more detailed analysis,
			you may reference the file <filename>core/event_api.php</filename> in the
			codebase.
		</para>

		<blockquote id="dev.events.api.declare">
			<title>Declaring Events</title>

			<para>
				When declaring events, the only information needed is the event name
				and event type.  Events can be declared alone using the form:
			</para>

			<programlisting>event_declare( $name, $type=EVENT_TYPE_DEFAULT );</programlisting>

			<para>
				or they can be declared in groups using key/value pairs of name => type
				relations, stored in a single array, such as:
			</para>

			<programlisting>
$events = array(
	$name_1 => $type_1,
	$name_2 => $type_2,
	...
	);

event_declare_many( $events );
			</programlisting>
		</blockquote>

		<blockquote id="dev.events.api.hook">
			<title>Hooking Events</title>

			<para>
				Hooking events requires knowing the name of an already-declared event,
				and the name of the callback function (and possibly associated plugin)
				that will be hooked to the event.  If hooking only a function, it must
				be declared in the global namespace.
			</para>

			<programlisting>event_hook( $event_name, $callback, [$plugin] );</programlisting>

			<para>
				In order to hook many functions at once, using key/value pairs of name
				=> callback relations, in a single array:
			</para>

			<programlisting>
$events = array(
	$event_1 => $callback_1,
	$event_2 => $callback_2,
	...
	);

event_hook( $events, [$plugin] );
			</programlisting>
		</blockquote>

		<blockquote id="dev.events.api.signal">
			<title>Signalling Events</title>

			<para>
				When signalling events, the event type of the target event must be kept in
				mind when handling event parameters and return values.  The general format
				for signalling an event uses the following structure:
			</para>

			<programlisting>$value = event_signal( $event_name, [ array( $param, ... ), [ array( $static_param, ... ) ] ] );</programlisting>

			<para>
				Each type of event (and individual events themselves) will use different
				combinations of parameters and return values, so use of the
				<link linkend="dev.eventref">Event Reference</link> is reccommended for
				determining the unique needs of each event when signalling and hooking them.
			</para>
		</blockquote>
	</sect1>

	<sect1 id="dev.events.types">
		<title>Event Types</title>

		<para>
			There are five standard event types currently defined in MantisBT.  Each type
			is a generalization of a certain "class" of solution to the problems that
			the event system is designed to solve.  Each type allows for simplifying
			a different set of communication needs between event signals and hooked
			callback functions.
		</para>

		<para>
			Each type of event (and individual events themselves) will use different
			combinations of parameters and return values, so use of the
			<link linkend="dev.eventref">Event Reference</link> is reccommended for
			determining the unique needs of each event when signalling and hooking them.
		</para>

		<blockquote id="dev.events.types.execute">
			<title>EVENT_TYPE_EXECUTE</title>

			<para>
				This is the simplest event type, meant for initiating basic hook
				execution without needing to communicate more than a set of
				immutable parameters to the event, and expecting no return of data.
			</para>

			<para>
				These events only use the first parameter array, and return values from
				hooked functions are ignored.  Example usage:
			</para>

			<programlisting>event_signal( $event_name, [ array( $param, ... ) ] );</programlisting>
		</blockquote>

		<blockquote id="dev.events.types.output">
			<title>EVENT_TYPE_OUTPUT</title>

			<para>
				This event type allows for simple output and execution from hooked events.
				A single set of immutable parameters are sent to each callback, and the
				return value is inlined as output.  This event is generally used for an
				event with a specific purpose of adding content or markup to the page.
			</para>

			<para>
				These events only use the first parameter array, and return values from
				hooked functions are immediatly sent to the output buffer via 'echo'.
				Example usage:
			</para>

			<programlisting>event_signal( $event_name, [ array( $param, ... ) ] );</programlisting>
		</blockquote>

		<blockquote id="dev.events.types.chain">
			<title>EVENT_TYPE_CHAIN</title>

			<para>
				This event type is designed to allow plugins to succesively alter the
				parameters given to them, such that the end result returned to the caller
				is a mutated version of the original parameters.  This is very useful
				for such things as output markup parsers.
			</para>

			<para>
				The first set of parameters to the event are sent to the first hooked
				callback, which is then expected to alter the parameters and return the
				new values, which are then sent to the next callback to modify, and this
				continues for all callbacks.  The return value from the last callback is
				then returned to the event signaller.
			</para>

			<para>
				This type allows events to optionally make use of the second parameter set,
				which are sent to every callback in the series, but should not be returned
				by each callback.  This allows the signalling function to send extra,
				immutable information to every callback in the chain.  Example usage:
			</para>

			<programlisting>$value = event_signal( $event_name, $param, [ array( $static_param, ... ) ] );</programlisting>
		</blockquote>

		<blockquote id="dev.events.types.first">
			<title>EVENT_TYPE_FIRST</title>

			<para>
				The design of this event type allows for multiple hooked callbacks to
				'compete' for the event signal, based on priority and execution order.
				The first callback that can satisfy the needs of the signal is the last
				callback executed for the event, and its return value is the only one
				sent to the event caller.  This is very useful for topics like user
				authentication.
			</para>

			<para>
				These events only use the first parameter array, and the first non-null
				return value from a hook function is returned to the caller. Subsequent
				callbacks are never executed.  Example usage:
			</para>

			<programlisting>$value = event_signal( $event_name, [ array( $param, ... ) ] );</programlisting>
		</blockquote>

		<blockquote id="dev.events.types.default">
			<title>EVENT_TYPE_DEFAULT</title>

			<para>
				This is the fallback event type, in which the return values from all
				hooked callbacks are stored in a special array structure.  This allows
				the event caller to gather data separately from all events.
			</para>

			<para>
				These events only use the first parameter array, and return values from
				hooked functions are returned in a multi-dimensional array keyed by plugin
				name and hooked function name.  Example usage:
			</para>

			<programlisting>$values = event_signal( $event_name, [ array( $param, ... ) ] );</programlisting>
		</blockquote>
	</sect1>
</chapter>
