Fudla! Plugin Core Code Changes [message #165009] |
Fri, 15 April 2011 19:13 |
|
Dayo
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:
- 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.
- 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****
- Changed the attachment as one file was missed out of the changes.
- The database prefix was also hardcoded in one location
- 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 #165014 is a reply to message #165013] |
Sat, 16 April 2011 18:49 |
|
Dayo
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 #165027 is a reply to message #165024] |
Sun, 17 April 2011 14:36 |
|
Dayo
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 #165030 is a reply to message #165029] |
Sun, 17 April 2011 18:23 |
|
Dayo
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
|
|
|
|
|
|
|
|
|