Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > vBulletin 3 Articles
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools
Advanced Plugin Optimization System
Darkwaltz4's Avatar
Darkwaltz4
Join Date: Oct 2002
Posts: 1,538

Known Technologies: PHP MySQL Javascript XML AJAX SOAP Java C jQuery Drupal Wordpress

Chicago
Show Printable Version Email this Page Subscription
Darkwaltz4 Darkwaltz4 is offline 03-22-2008, 10:00 PM

New! Attached prototype files to get you started Also updated to address a bug

This is a method you should use to optimize the way your plugins work in your hacks!

Background


After writing hacks with many many plugins, you run into a couple problems...
  • Finding a particular plugin to edit is a nightmare in the Plugin Manager
  • Bad on memory, especially for sites with dozens of hacks installed
So, I just recently perfected a plugin optimization system which solves both problems very admirably, and I am converting all of my hacks to use it.

Every coder should be familiar with this clever optimization technique, it is even in the vBulletin manual: https://vborg.vbsupport.ru/showthrea...ghlight=plugin
Basically: move plugins to the file system! There is also a "Plugin Accelerator" which does that too.

However, now you have a couple dozen FILES to watch after, and it still is too messy for my taste. My next step was to put them all into a single file that gets included in every plugin, but the plugin also has to set some global indicator before including, because the vB system doesn't declare what plugin it is writing to the plugin code itself. It was either many files and 1 code line per plugin, or 1 file and 2 code lines per plugin. I wanted 1 file and 1 line per plugin So begins tutorial proper...

Advanced Plugin Optimization System
You should know what code is in your plugins, how they work, how to find hooks, etc - I'm not getting into that. I'm also assuming you know how to code PHP in general, and know what functions/OOP I'm talking about, and can look up any you don't.

First create the file that will house the plugin code and put it somewhere. I will use the file myhack_plugins.php in the plugins subfolder in the forum root.

Create all of your plugins in the ACP plugin manager that you would normally use, and put the exact same single line in each them:
PHP Code:
include(DIR '/plugins/myhack_plugins.php'); 
Remember which hooks they use and what code you want to put in them. This optimization is best applied after creating your hack, but not necessarily. Adjust the path to whatever you named it of course. You can also use require to put up errors if the plugins file is missing, but don't use **_once functions if you have more than 1 plugin or it won't work.

Create a functions file that has this in it:
PHP Code:
class vBulletinHook_MyHack extends vBulletinHook
{
    function 
vBulletinHook_MyHack(&$pluginlist, &$hookusage)
    {
        
$this->pluginlist =& $pluginlist;
        
$this->hookusage =& $hookusage;
    }
    function 
fetch_hook_object($hookname)
    {
        if (!isset(
$this->hookusage["$hookname"]))
        {
            
$this->hookusage["$hookname"] = !empty($this->pluginlist["$hookname"]);
        }
 
        return 
str_replace('include('"\$hookname = '$hookname';\r\ninclude("strval($this->pluginlist["$hookname"]));
    }

This could also be put in the plugins file itself, but then you have to deal with duplicate definition errors, so easier to then refer to the file with
PHP Code:
require_once(DIR '/includes/functions_myhack.php'); 
at the top of the plugins file. Remember to change the 'myhack' everywhere to match your hack, preferably to your product identifier. Doing that will also ensure that you don't conflict with other people doing this.

Figure out which hook executes very first in your hack. The very first in vBulletin at all is init_startup, and you might want to add a plugin at that hook just to make sure the system works. Remember what your first hook is.

Now, in the plugins file, it works like this:
PHP Code:
$vbulletin $GLOBALS['vbulletin'];
$foruminfo $GLOBALS['foruminfo'];
$db $vbulletin->db;
 
if (!
defined('VB_AREA'))
{
    exit;
}
 
require_once(
DIR '/includes/functions_myhack.php');
 
switch (
strval($hookname)
{
    case 
'some_hook_name':
        {
            
//code that runs at this hook
        
}
        break;
    case 
'someother_hook_name':
        {
            
//code that runs at this hook
        
}
        break;
//and so on, one per plugin doing that
    
default:
        {
            
//code that runs at the very first hook determined above
            
$hookobj =& vBulletinHook::init();
            
$hookobj = new vBulletinHook_MyHack($hookobj->pluginlist$hookobj->hookusage);
        }
        break;

That's it! Keep in mind your names and paths of course. The way it works is that it picks out which hook is executing in a big switch statement, with each entry its own plugin code. However the name of the hook is only reported by extending the vBulletinHook class, so the very first hook executed not only won't have the hookname reported (which is why it is in the default block) but it should also be the place where you extend the vBulletinHook class to begin reporting the hookname for all the rest. Note that at the top the only important lines are the $hookobj line and the require_once line, but the other lines are a good example of what you can do for ALL plugins, such as globalizing $vbulletin and checking for illegal loading of the file by itself with VB_AREA. Use and expand as you see fit (but some sort of acknowledgement would be awesome)



Benefits
  • As optimized of a plugin system as possible - 1 line per plugin and 1 file for code
  • You can work on all plugins at once in your favorite code editor
  • Plugins can be easily encrypted in their single file
  • Works on ALL 3.6.x through 3.7.x without ANY end-user file edits (3.5.x untested)
  • Code applicable to all plugins can be done once at the top of the plugins file
  • Include the plugins file with any other files for your hack
  • Won't interfere with other hacks that use this or other systems, or regular vB
  • You and others only edit and replace that one file
  • Works on all plugin types even within functions and classes
  • Allows you to write plugins that define functions and use the return command!
Demo
You can see this optimization system in use in my vBCredits 1.4rc2 hack here or here. The older version of this (not quite as good, but what I was doing before perfecting this system) is in use in my vBTracker LITE hack here.
Attached Files
File Type: zip Plugins System Prototype.zip (1.5 KB, 50 views)
Reply With Quote
  #2  
Old 03-23-2008, 06:58 PM
ringleader's Avatar
ringleader ringleader is offline
 
Join Date: Dec 2006
Location: Dublin, Ireland
Posts: 192
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Excellent article!

Easy enough to understand (even for me, only starting out!), and a great idea for creators of some of the larger hacks.

Just let me get this straight though.

You should end up having:

1) ./includes/functions_myhack.php that collates the plugins called by your hack, last one first.
2.) ./plugins/myhack_plugins.php that calls ./includes/functions_myhack.php and switches between the plugin locations for the correct code to insert.
3. All your hooks that you use in myhack_plugins.php switch set in the plugin manager, but with the code to include myhacks_plugin.php

And that's it?!

Would there be a number of plugins you recommend having in a hack before using this method?
Reply With Quote
  #3  
Old 03-23-2008, 10:28 PM
Darkwaltz4's Avatar
Darkwaltz4 Darkwaltz4 is offline
 
Join Date: Oct 2002
Location: Chicago
Posts: 1,538
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

very glad you understood it as a beginner - I really didn't want to explain every little detail as the big picture is a little abstract itself.

You have it down pretty well! Again if you want to see real application of this, look at my demo links of hacks I've used it with.

This actually wouldn't be necessary if vBulletin reported the hook that is currently executing, but it doesn't, and the hook class needs to be edited to do so. My other goal I guess, was to provide a solution that end-users wouldnt have to do anything out of the ordinary to install, and certainly not do any file edits.

As for the minimum number of plugins "needed" is kind of blurry. One of the things this allows you to do is work on your plugins all at once in your favorite code editor. You could have one huge plugin in total, but would still be really useful to not copy/paste between the vB Plugin system. Of course, any extras like that would simply compound the problem. Then there is the fact that vB caches ALL active plugins in the datastore which are loaded on every single page as text stored in memory. You help your end-users with database memory, RAM, and speed by using this system, that much more so when they have dozens of hacks installed at once (One site in particular had over 250 hacks installed, and getting anything to load was a ten minute affair - imagine if all of his 1,000 plugins weren't sitting in memory in all their glory?)

About the only time you shouldn't bother putting plugin code in this system is if the line of code is one line long anyway and you don't intend to change it very often. About the only thing I can think of like that is the templategroup definition plugin :-p Finally, if at the end of development you see some plugins ended up as one line, then move those ones back into the vb plugin space

Thanks for reading!
Reply With Quote
  #4  
Old 03-23-2008, 11:10 PM
ringleader's Avatar
ringleader ringleader is offline
 
Join Date: Dec 2006
Location: Dublin, Ireland
Posts: 192
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Darkwaltz4 View Post
You have it down pretty well! Again if you want to see real application of this, look at my demo links of hacks I've used it with.
Some of these articles are so old I've been learning by downloading others' hacks and dissecting them, and using a bit of the old standby of trial and error

Quote:
Originally Posted by Darkwaltz4 View Post
This actually wouldn't be necessary if vBulletin reported the hook that is currently executing, but it doesn't, and the hook class needs to be edited to do so. My other goal I guess, was to provide a solution that end-users wouldnt have to do anything out of the ordinary to install, and certainly not do any file edits.
Yeah, the file edits (and number of myhack_functions files are another reason this is great.
(But mostly that was gibberish to me! Talk about hooks and I'm pretty vague except for the notion they exist!)

Now all that's needed (for me anyway) is to put hooks in the files that have few or none, and use this.

Quote:
Originally Posted by Darkwaltz4 View Post
Then there is the fact that vB caches ALL plugins, active or not, in the datastore which is loaded on every single page as text stored in memory.
Hmm, I didn't know it stored the nonactive ones as well.
I think I'll be using this to convert two of the hacks I have with the most plugins (Andreas' TMS & Interactive Profiles)

Quote:
Originally Posted by Darkwaltz4 View Post
About the only time you shouldn't bother putting plugin code in this system is if the line of code is one line long anyway and you don't intend to change it very often. About the only thing I can think of like that is the templategroup definition plugin :-p
I just use one liners to include function files at the first hook of a file, and for template things - couldn't think of anything else that would go in there and be shortish.

Quote:
Originally Posted by Darkwaltz4 View Post
Thanks for reading!
Thanks for writing it! The sharing of knowledge helps everyone. For one thing, we'll not dependent on others to make every little hack we may want or need!

I think I'll be using this to convert two of the hacks I have with the most plugins (Andreas' TMS & Interactive Profiles) - should be more educational to try it with someone elses before my own
Reply With Quote
  #5  
Old 03-23-2008, 11:43 PM
Darkwaltz4's Avatar
Darkwaltz4 Darkwaltz4 is offline
 
Join Date: Oct 2002
Location: Chicago
Posts: 1,538
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Aha, you are right: I would like to rescind the statement about inactive plugins being cached. They are not. Doesn't change much of anything else though :-p

Let me know how conversion of those hacks goes I havent tried it on someone else's hack, but you shouldnt have any issues at all. Just make sure the namespaces are unique and everything will work out
Reply With Quote
  #6  
Old 10-24-2008, 08:33 PM
Darkwaltz4's Avatar
Darkwaltz4 Darkwaltz4 is offline
 
Join Date: Oct 2002
Location: Chicago
Posts: 1,538
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

A few weeks ago it was brought to my attention that the system gets messed up if a plugin that executes before your plugins contains other hooks...

So, this new version which I updated the first post with, takes care of that issue. I have also uploaded some prototype files to get you started with, so dont be afraid to use this The couple of people who have tried it ended up really liking how well it works.

As always, if you use this in your hack with success I would love to see it, or if you have questions dont hesitate to ask here or through any method on my profile.
Reply With Quote
  #7  
Old 11-04-2008, 09:54 AM
AWJunkies AWJunkies is offline
 
Join Date: Jan 2005
Location: San Diego
Posts: 947
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I highly recommend this system it is a developers dream Helped me out so much and made things so much easier. Especially when you have thousand line code snippets hooked this makes it so much easier to edit and test things and so on. If you don't use this your wasting hours of your time.
Reply With Quote
  #8  
Old 11-11-2008, 05:57 PM
K4GAP K4GAP is offline
 
Join Date: Mar 2008
Posts: 1,255
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

As a newbie to any type of coding I'm trying to wrap my head around this... I think I know whats going on but am afraid to attempt any of it.

Is this something I should wait to attempt until I have made the transition to the stable release of 3.8?

Thanks'
Gary
Reply With Quote
  #9  
Old 11-11-2008, 06:18 PM
Darkwaltz4's Avatar
Darkwaltz4 Darkwaltz4 is offline
 
Join Date: Oct 2002
Location: Chicago
Posts: 1,538
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

This will work with vb3.6/7/8. It might also work with vb3.5, but I havent tried it so cant say with certainty.

In a nutshell, what this system does is report to your plugins what hook they belong to. While it seems unneccesary, it allows you to move all of your plugins into a single file with just one repeated include line in your plugins. Doing this has all of the benefits listed in the top post.

Note, you may run into problems when trying to use hacks using the two different plugin systems (the one i posted previously, and this current one) if you do, send me a PM and I will explain the solution. I dont want to further confuse people with it unless it applies to them :-/
Reply With Quote
  #10  
Old 10-18-2011, 04:26 AM
EgyKit EgyKit is offline
 
Join Date: Apr 2011
Location: Egypt
Posts: 8
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Thank you really this helped me out! I will transfer to plugin file system because I have many plugins, of course will test it on a vBulletin test forum with test database
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 08:35 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.04675 seconds
  • Memory Usage 2,349KB
  • Queries Executed 24 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (4)bbcode_php
  • (5)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (10)post_thanks_box
  • (10)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (10)post_thanks_postbit_info
  • (9)postbit
  • (1)postbit_attachment
  • (10)postbit_onlinestatus
  • (10)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_attachment
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete