FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » FUDforum Development » Plugins and Code Hacks » Fudla! Plugin Core Code Changes (Requirements for FUD 3.0.2 <-> Joomla integration)
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
Fudla! Plugin Core Code Changes [message #165009] Fri, 15 April 2011 19:13 Go to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
Right. I have managed to get a plugin (to be called Fudla) up and running to integrate Joomla! and FUDforum.

Still some work to do on the user integration but the visual integration is done and user stuff will just be behind the scene database calls.

A few code hacks were needed. Almost as many as my previous non-plugin approach which I abandoned but I suppose I got familiar with the working of FUDforum plugins.
Hopefully these can be rolled into the next release as they have been structured in a generic manner which should make them useful for other plugins.

The main items are:


  1. Two hooks have been added.

    • INITCORE: This allows a plugin to run code before after the program has been loaded but before any output. including headers, have been sent.

      It turned out that core.inc was not the right place for this as some things, such as the fud_theme constant (Why aren't constants in upper case as per convention? Really confusing) have not yet been defined by the end of this loading. So added to the bottom of index.php

    • PROCESS_OUTPUT_DATA: This allows a plugin to run code on the output html before it is sent to the browser. Implementing this created some complications as it needed buffering the output to a variable.

  2. The program worked against implementing the "PROCESS_OUTPUT_DATA" hook as some files flush output to the browser and then run some housekeeping code in the background.

    As the hook needed buffering to a variable, such pages could not be integrated since the buffer got flushed. So I have moved all the housekeeping code to the root index file to be run in the background after the processed output has been sent.

    Basically, we still do the same thing as before but in a different and more flexible way. Hopefully the devs can optimise this if required.


The patch is attached and the plugin will follow in due course. I am a weekend warrior coder so further progress might be next weekend ... depending on how busy I am.


****EDIT 16 Apr 2011****

  1. Changed the attachment as one file was missed out of the changes.
  2. The database prefix was also hardcoded in one location
  3. Also, some headers will have been sent by the time the INITCORE hook is called. So INITCORE hook added back to original proposed location in core.inc (not used by this plugin but potentially for others - more hooks is good) and a replacement added to previous position. Main requirement here is that redirection headers have not been sent and all params initialised.


****EDIT 19 Apr 2011****
Attachment deleted as now out of date.

[Updated on: Tue, 19 April 2011 01:56]

Report message to a moderator

Re: Fudla! Plugin Core Code Changes [message #165013 is a reply to message #165009] Sat, 16 April 2011 18:06 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
I haven't tested it yet, but it looks good!
Can we maybe move the ob_* functions out of core into the plugin code?
Re: Fudla! Plugin Core Code Changes [message #165014 is a reply to message #165013] Sat, 16 April 2011 18:49 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
I was afraid you'll say that.

The ob_x functions cannot be in the plugin as they are used to capture the html output into a variable that will be passed to the plugin by the POST_PROCESS hook. This is because the html is output directly in each of the several .php files in the templates.

Avoiding the functions would mean going into every tmpl file and editing them so that the html is written to a variable which can then be processed as required.

For example, this piece

{SECTION: rate_thread rate thread select}
<form id="RateFrm" action="post">
<select class="SmallText" onchange="if (this.value) topicVote(this.value, {VAR: frm->id}, \'{DEF: s}\', \'{VAR: usr->sq}\');">
<option>{MSG: rate_thread}</option>
<option value="1">1 {MSG: rate_worst}</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5 {MSG: rate_best}</option>
</select>
</form>
{SECTION: END}

would have to be changed to...

{SECTION: rate_thread rate thread select}
<?php 
$htmlData .= "<form id="RateFrm" action="post">\n";
$htmlData .= "<select class="SmallText" onchange="if (this.value) topicVote(this.value, {VAR: frm->id}, \'{DEF: s}\', \'{VAR: usr->sq}\');">\n";
$htmlData .= "<option>{MSG: rate_thread}</option>\n";
$htmlData .= "<option value="1">1 {MSG: rate_worst}</option>\n";
$htmlData .= "<option value="2">2</option>\n";
$htmlData .= "<option value="3">3</option>\n";
$htmlData .= "<option value="4">4</option>\n";
$htmlData .= "<option value="5">5 {MSG: rate_best}</option>\n";
$htmlData .= "</select>\n";
$htmlData .= "</form>\n";
?>
{SECTION: END}


Then, all the quote marks would have to be properly escaped and those with existing "php echo" strings changed etc etc etc.

Possible but a PITA to do when the same effect can be reached in other ways.

Possible draw back of the ob_x is this call earlier in index.php

if ($FUD_OPT_2 & 16384 && $t != 'getfile') {
	ob_start(array('ob_gzhandler', (int)$PHP_COMPRESSION_LEVEL));
}


Which looks like applying gzip which is something that should be left to the web server IMO.

Not sure what the conditions stand for though so not fully up to speed on that particular snippet.
Re: Fudla! Plugin Core Code Changes [message #165017 is a reply to message #165014] Sun, 17 April 2011 04:28 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
We can setup PRE_THEME and POST_THEME hooks.
You can then start output buffering in PRE_THEME and capture & process the output in POST_THEME.

Don't worry too much about the PHP_COMPRESSION (gzip handler), as it is disabled by default. Only sites that cannot use web server compression (the likes of like mod_gzip or mod_deflate) will actually bother to activate it.
Re: Fudla! Plugin Core Code Changes [message #165018 is a reply to message #165017] Sun, 17 April 2011 05:16 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
Patch to introduce PRE_TEMPLATE and POST_TEMPLATE hooks:
http://fudforum.svn.sourceforge.net/fudforum/?rev=5207&view=rev

Here is a sample plugin (file: x.plugin) to capture and process output:
<?php
plugin_add_hook('PRE_TEMPLATE',  'plugin_x_capture_output');
plugin_add_hook('POST_TEMPLATE', 'plugin_x_process_output');

function plugin_x_capture_output($t) {
	ob_start();
	return $t;
}

function plugin_x_process_output() {
	$template_output = ob_get_contents();
	ob_end_clean();
        // Modify output, add headers, footers, go mad...
	echo $template_output;
}
?>


Edit: Changed PRE_THEME to PRE_TEMPLATE and POST_THEME to POST_TEMPLATE as per http://sourceforge.net/apps/trac/fudforum/changeset/5208
Re: Fudla! Plugin Core Code Changes [message #165024 is a reply to message #165018] Sun, 17 April 2011 12:41 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
Looks good.

I'll apply this.
Re: Fudla! Plugin Core Code Changes [message #165027 is a reply to message #165024] Sun, 17 April 2011 14:36 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
Hi.

I think this can be improved by using the following in plugins.inc


/* Execute all registered plugins of a particular hook. */
function plugin_call_hook($type, $data=array()) {
	global $plugin_hooks;

	if (isset($plugin_hooks[$type])) {
		if ($type == 'PRE_TEMPLATE') {
			if (isset($plugin_hooks['POST_TEMPLATE'])) {
				// We only start the buffer if there is a need
				ob_start();
			}
		} elseif ($type == 'POST_TEMPLATE') {
			// Abort if plugins trigger this hook without the PRE_TEMPLATE
			if (!isset($plugin_hooks['PRE_TEMPLATE'])) {
				return null;
			}
			$data = ob_get_contents();
			ob_end_clean();
		}
		foreach ($plugin_hooks[$type] as $func) {
			$data = call_user_func($func, $data);
		}
	}
	return $data;
}


root_index.php.t gets changed to read ...
 	/* Call themed template. */
	if (defined('plugins')) {
		plugin_call_hook('PRE_TEMPLATE');
	}
	require($WWW_ROOT_DISK . fud_theme .'language.inc');	// Initialize theme's language helper functions.
	require($WWW_ROOT_DISK . fud_theme . $t .'.php');
	if (defined('plugins')) {
		$htmlData = plugin_call_hook('POST_TEMPLATE');
		if (isset($plugin_hooks['POST_TEMPLATE']) && !empty($htmlData)) {
			// We only send output if process was not aborted
			echo $htmlData;
		}
	}


The sample plugin (file: x.plugin) to capture and process output becomes:

<?php
plugin_add_hook('PRE_TEMPLATE',  'plugin_x_capture_output');
plugin_add_hook('POST_TEMPLATE', 'plugin_x_process_output');

function plugin_x_capture_output() {
	//Run some code if desired.
}

function plugin_x_process_output($data) {
	//$modified_data = Modify $data, add headers, footers, go mad...
	return $modified_data;
}
?>



Yes it means the application is doing some hand holding but that exactly is what good applications do and the user does not have to worry about stuff as the hook behaves consistently with others.

In this case, html is passed in, user processes, returns and sees processed html displayed without having to do anything special.

PRE_TEMPLATE remains flexible as a user might want this without wanting to change the output

What do you think?

[Updated on: Sun, 17 April 2011 15:16]

Report message to a moderator

Re: Fudla! Plugin Core Code Changes [message #165028 is a reply to message #165027] Sun, 17 April 2011 17:03 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
We can maybe accommodate some of this, but preferably not in plugins.inc (too difficult to follow what's going on).

Please also remember that this code will execute on each request. It should remain as mean and lean as possible. Especially for users that don't need this functionality.
Re: Fudla! Plugin Core Code Changes [message #165029 is a reply to message #165028] Sun, 17 April 2011 17:55 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member

I think it should be quite quick as there is nothing major going on there and plugins.inc is a good place to apply some simple logic tests to the plugins as done here.

The flow I defined helps the user and makes the application easier to use without any major loops etc that will slow things down. There are a few if statements which will take a billionth of a second to run.

For users that don't need the functionality, their output would have been displayed after "require($WWW_ROOT_DISK . fud_theme . $t .'.php');" runs.

Definitely an imperceptible time impact for a big improvement in usability.

Sounds like a winner to me.

Maybe when you look at the code again, you'll see what I am talking about.

The current proposal works as it is. Just not as user friendly as it could be.

If a hook function always needs ob_xyz to work properly, why should a plugin writer have to type it in? A good application would take care of this. That is what this proposed flow does.


Up to you though.
Re: Fudla! Plugin Core Code Changes [message #165030 is a reply to message #165029] Sun, 17 April 2011 18:23 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
Taking this further, imagine these two pieces of documentation for the hooks

DOCUMENTATION 1 (Current Proposal)

PRE_TEMPLATE HOOK
This hook action is called just before the output html is put together and is a prerequisite if you wish to use the POST_TEMPLATE Hook to modify output later.

To run it, initialise it in your plugin as follows "plugin_add_hook('PRE_TEMPLATE',  'plugin_x_capture_output');"
Then, define the function with your code as follows...
function plugin_x_capture_output($t) {
	//YOUR CODE GOES HERE IF REQUIRED
	ob_start();
	return $t;
}

If you simply want to run some code before the output html is put together but do not wish to use the POST_TEMPLATE Hook to modify output later, define the function as follows ....
function plugin_x_capture_output($t) {
	//YOUR CODE GOES HERE
	return $t;
}
P.S: Try not to change the value of "$t", as we need it intact to use later on in the process.

POST_TEMPLATE HOOK
This hook action is called just before the output html is sent to the browser and requires the PRE_TEMPLATE Hook.

To run it, initialise it in your plugin as follows "plugin_add_hook('POST_TEMPLATE', 'plugin_x_process_output');"

Then, define the function with your code as follows...
function plugin_x_process_output() {
	$template_output = ob_get_contents();
	ob_end_clean();
    $template_output = YOUR CODE TO MODIFY OUTPUT
	echo $template_output;
}



Compare that to
DOCUMENTATION 2 (Revised Proposal)

PRE_TEMPLATE HOOK
This hook action is called just before the output html is put together and is a prerequisite if you wish to use the POST_TEMPLATE Hook to modify output later.

To run it, initialise it in your plugin as follows "plugin_add_hook('PRE_TEMPLATE',  'plugin_x_capture_output');"
Then, define the function with your code as follows...
function plugin_x_capture_output() {
	//YOUR CODE GOES HERE IF REQUIRED
	return null;
}

POST_TEMPLATE HOOK
This hook action is called just before the output html is sent to the browser and requires the PRE_TEMPLATE Hook.

To run it, initialise it in your plugin as follows "plugin_add_hook('POST_TEMPLATE', 'plugin_x_process_output');"
Then, define the function with your code as follows...
function plugin_x_process_output($input_html) {
    $output_html = YOUR CODE TO MODIFY $input_html
	return $output_html;
}


Look to me like one of them is a bit more simple and straightforward although I suppose it is not the end of the world. I just prefer high usability levels particularly if the cost is low.

[Updated on: Mon, 18 April 2011 00:49]

Report message to a moderator

Re: Fudla! Plugin Core Code Changes [message #165035 is a reply to message #165030] Mon, 18 April 2011 14:43 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
Can you please move the code you've added to plugins.inc to root_index.php.t, ensure it's optimized, and post it here?
Re: Fudla! Plugin Core Code Changes [message #165036 is a reply to message #165035] Mon, 18 April 2011 15:36 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
This should do the job and decouples PRE_TEMPLATE from the output processing.
It is now there simply if the user wants to run code before the template is put together and before redirection headers are sent.
I.E. it does not need to be initialised to capture and process output html which is now all done by the POST_TEMPLATE hook.

			/* Call themed template. */
			if (defined('plugins')) {
				plugin_call_hook('PRE_TEMPLATE');
				if (isset($plugin_hooks['POST_TEMPLATE'])) {
					ob_start();
				}
			}
			require($WWW_ROOT_DISK . fud_theme .'language.inc');    // Initialize theme's language helper functions.
			require($WWW_ROOT_DISK . fud_theme . $t .'.php');
			if (defined('plugins') && isset($plugin_hooks['POST_TEMPLATE'])) {
					echo plugin_call_hook('POST_TEMPLATE', ob_get_contents());
					ob_end_clean();
				}
			}



The sample plugin (file: x.plugin) to capture and process output becomes:
<?php
plugin_add_hook('POST_TEMPLATE', 'plugin_x_process_output');

function plugin_x_process_output($data) {
	//$modified_data = Modify $data, add headers, footers, go mad...
	return $modified_data;
}
?>



PRE_TEMPLATE could be used in another sample plugin (file: y.plugin):
<?php
plugin_add_hook('PRE_TEMPLATE', 'plugin_y_background_work');

function plugin_y_background_work() {
	//Do whatever....
}
?>


Not tested though.
Re: Fudla! Plugin Core Code Changes [message #165037 is a reply to message #165036] Mon, 18 April 2011 15:53 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
Much better!

PRE_TEMPLATE can be used to direct the user to a custom template and several POST_TEMPLATE plugings can be activated to change the HTML before it is outputted.
Re: Fudla! Plugin Core Code Changes [message #165038 is a reply to message #165037] Mon, 18 April 2011 16:02 Go to previous messageGo to next message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
naudefj wrote on Mon, 18 April 2011 18:53
Much better!

... several POST_TEMPLATE plugings can be activated to change the HTML before it is outputted.


In that case, it'll be better to do ...

			/* Call themed template. */
			if (defined('plugins')) {
				plugin_call_hook('PRE_TEMPLATE');
				if (isset($plugin_hooks['POST_TEMPLATE'])) {
					ob_start();
				}
			}
			require($WWW_ROOT_DISK . fud_theme .'language.inc');    // Initialize theme's language helper functions.
			require($WWW_ROOT_DISK . fud_theme . $t .'.php');
			if (defined('plugins') && isset($plugin_hooks['POST_TEMPLATE'])) {
					$htmlData = ob_get_contents();
					ob_end_clean();
					$htmlData = plugin_call_hook('POST_TEMPLATE', $htmlData);
					echo $htmlData;
				}
			}


Question: How can a user influence the order in which multiple plugins are run on the same hook?
Re: Fudla! Plugin Core Code Changes [message #165039 is a reply to message #165038] Mon, 18 April 2011 17:05 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3771
Registered: December 2004
Karma: 28
Senior Member
Administrator
Core Developer
Change committed at
http://fudforum.svn.sourceforge.net/fudforum/?rev=5209&view=rev

Pluging ordering isn't currently implemented.
If you have extra time, it would be great if you can start working on it.
Re: Fudla! Plugin Core Code Changes [message #165040 is a reply to message #165039] Tue, 19 April 2011 03:01 Go to previous message
Dayo is currently offline  Dayo   Bahrain
Messages: 101
Registered: April 2011
Karma: 0
Senior Member
I can take a look at plugin ordering but need to finish the Joomla plugin, port it to Gallery2 and do a three week trip with limited personal internet access starting next week.

I suppose the best way is to add a drop down list (0-9) to each items in the plugin manager. This would default to "0" and when a hook function is registered by a plugin, this plugin weight is stored alongside.
If a user wants a plugin to run later than another if they call the same hook, he selects a larger value.
The application does a sort when a hook is called so that "heavier" instances sink to the bottom and it then runs from lightest to heaviest.
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Tips for higher iPhone/Andriod/Pre compatibility
Next Topic: Help Needed - fud_user_reg class
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Wed Nov 27 15:13:24 GMT 2024

Total time taken to generate the page: 0.02713 seconds