Location: PHPKode > projects > Obsessive Website Statistics > ows/docs/plugins.txt
OWS Plugin Development Guide
=============================

TODO: Write this :p
TODO: Example plugins
TODO: HTML/PDF format? Better organization of this.
TODO: What about putting this in a Wiki?

	1. Introduction
	2. Plugin Types
		a. Filter
		b. Analysis
		c. Installable
		d. Limit
		e. Reject
	3. Useful classes & functions
		a. SQLSelect
		b. ResultTable
		c. show_result_table
	4. Naming convention
	

1. Introduction

	The purpose of plugins is to be able to provide easy third party interaction 
	with the OWS database. In OWS, a lot of primary functionality is implemented 
	as different types of plugins. The goal is for the user to have an enormous
	amount of flexibility in specifying the data they want to see (while providing
	sensible defaults as well), and for that flexibility to be implemented in such 
	a way that plugins can be very simple and take advantage of existing 
	functionality.
	
	Due to human error, this document may be dated depending on the changes in the
	source code, because OWS is a constantly evolving product. For the most recent 
	information, you are encouraged to review the source code for existing plugins
	and read the comments in plugin_interfaces.php (which may have newer comments 
	than the plugins).

	All plugins are implemented in class objects that are created once and not 
	destroyed until the script ends. Files implementing plugins should be placed 
	into the ./plugins directory. A file can contain multiple plugins. For plugins 
	to actually work, they must register themselves using the register_plugin
	function. For example:
	
		$bot_analysis = new BotAnalysis();
		register_plugin('analysis',$bot_analysis);
		
	Note that the register_plugin function will already be defined by the plugin 
	loading files, so you will not need to include it yourself.

2. Plugin Types

	OWS plugins are simply PHP classes which implement the interfaces that are defined in 
	plugin_interfaces.inc.php. There are a number of different types of interfaces, all
	of which serve different purposes. All plugins MUST implement iPlugin.

	a. Filter: iFilterPlugin
	
	These plugins are shown to users, and then run at the users request.
	
	b. Analysis : iAnalysisPlugin
	
	These plugins are ALWAYS run when a database upload is performed. They are
	also used to define dimensions and their usage. Refer to dimensions.txt for
	more information on dimension structure.
	
	Analysis is run in a number of rounds (process stages), at the end of which
	the current data is committed to the database.
	
	If any of them return false, then the current transaction is scrapped.
	
	c. Installable : iInstallablePlugin
	
	This is for plugins that require extra information such as tables, field
	alterations, and such to be created for their proper operation. Note that
	while this is useful for analysis plugins, they do NOT have to implement this
	in order to add new dimensions or modify existing ones.
	
	d. Limit : iLimitPlugin

	These plugins implement common limits for all any filter plugins that
	use the SQLSelect class to do SQL queries. It allows the limit plugins to do
	anything it wants to with the SQL queries.
	
	e. Reject : iRejectPlugin
	
	This aids analysis, in that it is used to make the size of the database smaller
	depending on characteristics of the log line. This is useful if you want to write plugins to
	exclude things such as spam, bots, whatever. Its also useful if you get tons of hits each day 
	and only want OWS to keep the history for the last 15 days, or something to that effect.
	
	Rejection plugins should probably just DELETE records from the main fact table. After an analysis, 
	if the user sets $cfg['cleanup_stale'], then the analysis engine will try to automatically resolve 
	all dimension records to see if there is matching data in the main fact table, and delete the 
	dimensional data if it isn't referenced by anything else. It is set to false by default.

	
3. Useful Classes & functions

	It should be noted that the following documentation is directly taken from
	the comments above these classes and functions, so they may be slightly out of
	date. If in doubt, look at the source code for the documentation. Hopefully
	in the near future we can make it all automatic or something. 

	a. SQLSelect()
	
	The point of this is to be able to create SQL queries and being able to modify them 
	easily using a standard set of filter functions without having to parse the contents 
	of said SQL queries. Instead, we just have to add things to this object, then call generate()
	and it will return the SQL string. 
	
	Of course, you don't really have to use this. Its just so we can have standard things like
	bot filtering, filtering by date, etc for every plugin without having to repeat code for it, including
	the SQL interpretation thereof. 
	
	The other useful purpose of this class with the current star schema is to make it so that you
	dont have to manually specify all the needed joins, it can specify them for you. :)
	
	And of course, this will be plugin based. In the future, we can probably implement an optimizer
	
	
	b. ResultTable()
	
 	Shows an associative array in a table format. This is probably way too complicated,
	but it works for the moment. Variables:
 
 	@param array 	$headers	Note: You can specify this option when you use SQLSelect to do a SELECT(). 
 								
 								Note: The inner array of this parameter can be created with col_description();
 
 								This is an array of arrays that denotes each column to be shown at the top 
 								of the table. If it is associative, then the columns will be matched
 								by key. Otherwise, it will be done in numerical order. If an entry is
 								not found in this array for the row, then a default value will be used.
 								The array will be formatted like this:
 
 									array('column_name' => array('Column Name Shown to User', $process_array), ...)
 								
 								or
 
 									array(array('Column Name Shown to User', $process_array), ...)
 								
 								column_name should be the actual SQL column, including things like SUM or distinct.
 								Basically, whatever db_fetch_assoc returns. See global $db_key_map for a better
 								example.
 
 								$process_array is an optional array. It contains a number of option keys, and 
 								if an option key is not set, then the processing is not done. The possible 
  								option keys currently are:
 	
 								ww -> length to wordwrap at, not set means dont wrap
 								href -> this is prefixed to the contents of the column, 
 								and then it is turned into a link
 								bold -> column is made bold
 								filesize -> if set, this interprets the column as a filesize
	
	c. show_result_table
	
	Wrapper around the ResultTable class to echo out the entire tableset of an SQL 
	operation. Of course, this wrapper provides functionality to 'page' through result sets
	as well. 
	
	$query 		SQLSelect object. If false, then result must not be false. If you provide a
				object here, then this routine will attempt to provide 'paging' through the
				result sets. 
				
	$result		Result returned from db_query.

4. Naming Conventions

	Plugins are loaded in alphabetical order, by filename. This is to ensure
	some consistancy in the plugin loading process, particularly in regard
	to the placement of plugins on the OWS menu. In fact, thats probably the
	only part that matters.

	So, plugins should be called something like 

		[number] _ [name] .php
		
	Plugins distributed with OWS by default will be of the format

		[number] _ows_ [name] .php
		
	We ask that you not name your plugins with an ows prefix so that users can 
	more easily distinguish the plugins distributed with OWS. 

	
TODO: More descriptions of each type of plugin. For now, see ./include/plugin_interfaces.inc.php and the
plugins in the plugin directory. 

Plugins are loaded and displayed alphabetically by filename.
Return current item: Obsessive Website Statistics