Creating an e107 plugin

Plugin Overview

Plugins extended the functionality of e107 and allow for endless possibilities. We've aimed to make our plugin architecture as simple as possible. Often you can copy a file from an existing plugin and simply modify a few parameters in order to get similar functionality in your own plugin.

Plugin Builder

By far the quickest and easiest way to develop a plugin for e107 is to use the plugin builder ( Manage -> Plugin Manager -> Plugin Builder).
It will create the plugin.xml (meta-data) file, as well as code most of the admin area of your plugin for you. Additional features may be added in future.

Steps to Use:

  • Create an empty plugin folder in e107_plugins/ (eg. 'myplugin')
  • Create a new text file with the _sql.php extension. (eg. 'myplugin_sql.php')
  • Using PHPMyAdmin, create your database table structure, and then export it in SQL format.
  • Copy/Paste the "CREATE TABLE" data to your your _sql.php file. (see other plugins for examples)
  • Go to Manage -> Plugin Manager -> Plugin Builder and choose 'myplugin' from the dropdown menu and then follow the prompts.
  • Thoroughly check the details of each Table Tab (and Preferences Tab if you need them) before proceeding with the creation process.

Admin-UI

This will summarize the various options which may be used while utilizing the admin-ui class. Please note that the documentation for this is a work-in-progress. Thank you for your patience.

$fields

Database fields are defined by the $fields value in the admin-ui class. Example:

		protected $fields = array(

   'myfield_id'  => array("title"=>"My Title", "type"=>"text", "data"=>"str", "width"=>"auto", "inline"=>true)

   // .....

);
Key Format Description
title string Field Title
type string Type of Field
data string Data Type
width string width of the column (List View)
inline boolean | string  Enable or disable inline editing.
help string  Popup helper text (tooltip)
readParms array  Parameters specific to the 'list' mode.
writeParms array  Parameters specific to the 'edit' and 'create' modes.
validate boolean | string Marks the field as required (*).

type

Type Description
text text box
number text box (number)
checkbox checkbox (0 or 1 is returned)
icon icon (from media manager)
textarea text area (text only)
boolean radio buttons with enable/disable
bbarea right text area (html)
dropdown dropdown list (ie. <select></select> )
userclass drop-down list of userclasses
userclasses checkboxes for multiple userclasses
datestamp date / time text box
user user selection text box. (type 3 letters to find/search)
hidden hidden field
ip text field with ip decoding
email text field for email addresses
url text field for urls (becomes clickable in list mode)
password password field (with optional generator)
image Media-manager image selection tool for a single image
images Media-manager image selection tool for multiple images
file Media-manager file selection tool for a single file
files Media-manager file selection tool for multiple files
media Media-Manager selection tool for images, mp4, youtube and gylphs. (requires type=json)
method custom method
lanlist drop-down list of installed languages
language drop-down list of all languages
templates Dropdown list of templates (from a template file)
null (without quotes) Ignore this field and do not save it's data
false (without quotes) Hide this field but save it's data if a posted key value is found.

data

Value Description
str Posted data is converted to string before saving to the database
safestr Posted data is run through a filter (using filter_var(FILTER_SANITIZE_STRING)) and thus strips HTML.
int Posted data is converted to integer before saving to the database
array Posted data is converted to an e107 array format. (use e107::unserialize() to decode)
json Posted data is converted to json format before saving to the database
false (no quotes) Posted data from this field is not saved to the database

 

readParms (list mode)

Key Value Field-type Comments
thumb (integer)  image  Set the thumbnail width
 url  (string)  e_url.php key value or a field key.  number, text, tags, null  Wrap value in a link
 target  (string) blank | dialog  number, text, tags, null  Target for 'url' above.

 

writeParms (create/edit mode)

Key Value Field-type Comments
pre (html) (all) Render html just before the field
post (html) (all) Render html just after the field
media (string) bbarea Sets the media-owner category to be used by the media-manager
video 0 or 1 image Show video selector tab in media-manager
path 'plugin' or null image When set to 'plugin', images will be stored in the 'plugin' folder within e107_media
glyphs 0 or 1 icon Show glyph selector tab in media-manager
size large, xlarge, xxlarge, block-level  text, url, email, textarea, dropdown Set the size (width) of input field
optArray (array of key=>value pairs) dropdown, checkboxes Set the keys/values to be used in the dropdown or checkboxes.
placeholder (string) text, url, email, textarea Placeholder text
pattern (regexp) text, url, email Regular expression validation
type date or datetime datestamp Choose between date or date and time
readonly 0 or 1 datestamp Make element read-only
auto 0 or 1 datestamp Insert current date/time automatically
label yesno boolean Change "Enabled" and "Disabled" to "Yes" and "No".
inverse 0 or 1 boolean Invert the values of 0 and 1. ie. "Disabled" = 1 and "Enabled" = 0.
enabled (string) boolean Alternate text to replace "Enabled"
disabled (string) boolean Alternate text to replace "Disabled"
classlist public, guest, nobody, member, admin, main, classes
(comma separated)
userclass Set which userclasses should be displayed.
tdClassLeft (string) (all) Set the css class for the left-side table cell.
tdClassRight (string) (all) Set the css class for the right-side table cell.
trClass (string) (all) Set the css class for the table row.
nolabel 0 or 1 (all) Hide the left table cell

Creating a tree structure

The admin UI allows to automatically create a tree structure based on parent/child relationship tables. Examples can be found in the forum and download plugin. In order to add a tree structure, add the following code:

		protected $sortField  = 'field1';
protected $sortParent = 'field2';
protected $treePrefix = 'field3';

In this case, field1 represents the fields which determines the order (for example an ID field). The 'field2' represents the field which is the parent and 'field3' the child. For example:

		protected $sortField  = 'download_category_order';
protected $sortParent = 'download_category_parent';
protected $treePrefix = 'download_category_name';

Setup and Installation

plugin.xml


Here's a simple example of a plugin.xml file.

		<?xml version="1.0" encoding="utf-8"?>
<e107Plugin name="Newsfeeds" version="2.0" date="2012-08-01" compatibility="2.0" installRequired="true">
	<author name="e107 Inc." url="http://e107.org" email="@" />
	<description>This plugin's description.</description>
	<category>content</category>
	<adminLinks>
		<link url='admin_config.php' description='Configure Newsfeeds' icon='images/icon_32.png' iconSmall='images/icon_16.png' >LAN_CONFIGURE</link>	
	</adminLinks>
	<siteLinks>
		<link url="/e107_plugins/newsfeed/newsfeed.php" >Newsfeeds</link>
	</siteLinks>	
</e107Plugin>


Here's an advanced example of a plugin.xml file.

		<?xml version="1.0" encoding="utf-8"?>
<e107Plugin name="FAQs" version="1.1"  lan="LAN_PLUGIN_XXX_NAME" date="2012-08-01" compatibility="2.0" installRequired="true">
	 <author name="e107 Inc" url="http://www.e107.org" email="@" />
	<summary>Add frequently asked questions to your e107 website.</summary>
	<description  lan="LAN_PLUGIN_XXX_DESCRIPTION">A simple plugin to add Frequently Asked Questions to your website.</description>
	 <copyright>Copyright e107 Inc e107.org, Licensed under GPL</copyright>
	<category>content</category>
	<keywords>
		<word>faq</word>
		<word>question</word>
		<word>answer</word>
	</keywords>
	<adminLinks>
		<link url='admin_config.php' description='Configure FAQs' icon='images/icon_32.png' iconSmall='images/icon_16.png' primary='true'>LAN_CONFIGURE</link>		
	</adminLinks>
	<siteLinks>
		<link url='/e107_plugins/faqs/faqs.php' description='FAQs' icon='images/icon_32.png' iconSmall='images/icon_16.png' function="faqCategories">LAN_PLUGIN_FAQS_NAME</link>		
	</siteLinks>
	<pluginPrefs>
		<pref name="add_faq">255</pref>
		<pref name="submit_question">255</pref>
		<pref name="classic_look">0</pref>
	</pluginPrefs>
	<dependencies>
		<plugin name='chatbox_menu' />
		<plugin name='calendar_menu' min_version='3.70' />
		<PHP name='core' min_version='5.2.5' />
		<MySQL name='server' min_version='4.9' />
		<extension name='curl' min_version='1.3' />
		<extension name='mb_string' />
	</dependencies>
	<userClasses>
		<class name="faq_moderator" description="FAQ moderator" />		
	</userClasses>
	<extendedFields>
		<field name="viewed" type='EUF_TEXTAREA' default='0' active="true" />
		<field name="posts" type='EUF_INTEGER' default='0' active="true" />
	</extendedFields>	
</e107Plugin>

 

Tip: If you are developing a commercial plugin, you'll want to add a few extra attributes so that it displays correct in the admin area under "Find Plugins". .
<e107Plugin name="FAQs" .... price="25.00" currency="EUR" url="http://direct-path-to-my-theme-purchase-page.com" >

Just package your plugin.zip file with only the plugin.xml and any images (including plugin icons) , excluding .php files etc. before sharing it. When the user clicks to download your plugin, the url you have provided will be displayed.

plugin_setup.php


More details coming soon. See e107_plugins/gallery/gallery_setup.php for an example.

plugin_sql.php


This contains a "CREATE TABLE" mysql dump of the database tables that your plugin will use.
You can find examples in most of the plugins in e107_plugins/

Languages

File Types

Language File Type Usage
English_front.php The front-end of your plugin.
English_admin.php The admin-area of your plugin
English_global.php Used site-wide - for example, in plugin.xml, a xxxxx_menu.php or e_xxxxxx.php file.

 

Defining Language Terms aka 'LANS'

Avoid duplicating terms, particularly in the admin area. If defining terms for admin, always search lan_admin.php for existing LANs which may match what you require. Never use HTML or URLs inside LAN definitions. Use double quotes within the defines and use str_replace() for variables where needed. See the examples below:

Good:

		define("LAN_XXX", "Thank you Firstname");
define("LAN_XXX", "Go to [x] to see the results."); // Good - replace [ and ] with <a href='...'> and </a> using str_replace()
define("LAN_XXX", "I want to [quote] here"); // Good - replace [ and ] with " " using str_replace()


Bad:

		define("LAN_XXX", "Thank you <b>Firstname</b>"); //Bad contains HTML
define("LAN_XXX", "Thank you <a href='http://somewhere.com'>Firstname</a>"); //Bad contains HTML
define("LAN_XXX", "Thank you Firstname"); //Bad - allows translator to modify link.


Avoid short language strings for words such as 'and', 'to' and so on. There aren't always equivalents in other languages. If embedding values into a phrase, use substitution. Avoid using substitution terms which are real words or known bbcodes.

		define("LAN_EXAMPLE_01", "Update results: [x] records changed, [y] errors, [z] not changed");
$repl = array($changed,$errors,$unchanged);
$text = $tp->lanVars(LAN_EXAMPLE_01,$repl);



Loading Language Files


To load a language file from a plugin folder:

		e107::lan('faqs');
e107::lan('faqs',true);
e107::lan('faqs',false, true);
e107::lan('faqs',true, true);


Will include the following paths:

		e107_plugins/faqs/languages/English_front.php
e107_plugins/faqs/languages/English_admin.php
e107_plugins/faqs/languages/English/English_front.php
e107_plugins/faqs/languages/English/English_admin.php

Extending core functionality

e107 plugin "addons" are files which reside in each plugin's folder and allow a plugin to embed itself inside e107's core pages and functions.
You can recognize these files by their e_xxxxx.php naming format.
By simply placing any or all of the file types below inside your plugin's folder, they will be auto-detected during installation and integrated into the system.
If added after installation you may need to run the Scan Plugin Folders option in admin -> Databases.

e_cron.php

Allows a plugin to add additional scheduled task options to e107. (see admin -> Scheduled Tasks)
Be sure to replace plugindir with your plugin's directory name. eg. class faqs_cron

		class plugindir_cron       // plugin-folder name + '_cron'.
{
    function config() // Setup  
    {
        $cron = array();
	
        $cron[] = array(
            'name'            => "Name of my function",  // Displayed in admin area. . 
            'function'        => "myFunction",    // Name of the function which is defined below. 
            'category'        => 'mail',           // Choose between: mail, user, content, notify, or backup
            'description'     => "Description of what my function does"  // Displayed in admin area. 
        );		
		
        return $cron;
    }
	
    public function myFunction()
    {
        // Do Something. 
    }

}

e_dashboard.php

Adds custom plugin information to the dashboard of e107's admin area. The 'latest', 'status' and 'website stats' areas may all contain information from your plugin.
See e107_plugins/forum/e_dashboard.php for an example of usage.

e_event.php (as of e107 v2.1.2)

Allows a plugin to easily hook into system events and trigger their own methods/functions using data provided by those events. (more coming soon)

e_header.php

Allows a plugin developer to add data to the of every page. This file is loaded in the header of each page of your site. ie. Wherever you see require_once(HEADERF) in a script.
It is used to place elements inside the html tags.
Typically you would use one or all of the following functions within this file: e107::js(), e107::css() or e107::meta().
Output should never be echoed or printed from this file.

e_help.php

Allows plugin developers to add information to the plugin configuration page sidebar.

e_latest.php

Deprecated. Use e_dashboard.php instead.

e_mailout.php

Allows your plugin to use e107's mailout feature for bulk mailing.
See e107_plugins/newsletter/e_mailout.php for an example.

e_menu.php

Provide configuration options for each instance of your plugin's menus. Examples can be found in e107_plugins/banner/e_menu.php and e107_plugins/news/e_menu.php

(This is a replacement for the old config.php file used in v1.x)

e_module.php

This file is loaded every time the core of e107 is included. ie. Wherever you see require_once("class2.php") in a script. It allows a developer to modify or define constants, parameters etc. which should be loaded prior to the header or anything that is sent to the browser as output. It may also be included in Ajax calls.

e_search.php

Adds your plugin to the 'search page' of e107.
See e107_plugins/chatbox_menu/e_search.php for an example.

e_meta.php

Deprecated. Use e_header.php instead.

e_notify.php

Adds your plugin to the email notifications admin area. Replace mytrigger with a unique name of your own, and myplugin with your plugin folder.

		class myplugin_notify extends notify // plugin-folder + '_notify' 
{		
	function config()
	{
		
		$config = array();
	
		$config[] = array(
			'name'			=> "New Trigger Name", // Displayed in admin area. 
			'function'		=> "myplugin_mytrigger",
			'category'		=> ''
		);	
		
		return $config;
	}
	
	function myplugin_mytrigger($data) 
	{
	
		$message = print_a($data,true);
		
		$this->send('myplugin_mytrigger', "My Subject", $message);
	}
	
}

Then add the following to your script when you want to trigger it.

		e107::getEvent()->trigger("myplugin_mytrigger", $data);



e_status.php

Deprecated. Use e_dashboard.php instead.

e_rss.php

Adds your plugin to the RSS plugin, and generates RSS feeds for your plugin.

		class chatbox_menu_rss // plugin-folder + '_rss' 
{
    /**
     * Admin RSS Configuration 
     */        
    function config() 
    {
        $config = array();
    
        $config[] = array(
            'name'            => 'Chatbox Posts',
            'url'            => 'chatbox',
            'topic_id'        => '',
            'description'    => 'this is the rss feed for the chatbox entries', // that's 'description' not 'text' 
            'class'            => '0',
            'limit'            => '9'
        );    
        
        return $config;
    }
    
    /**
     * Compile RSS Data
     * @param $parms array    url, limit, id 
     * @return array
     */
    function data($parms='')
    {
        $sql = e107::getDb();
        
        $rss = array();
        $i=0;
                    
        if($items = $sql->select('chatbox', "*", "cb_blocked=0 ORDER BY cb_datestamp DESC LIMIT 0,".$parms['limit']))
        {

        while($row = $sql->fetch())
            {
                $tmp                        = explode(".", $row['cb_nick']);
                $rss[$i]['author']            = $tmp[1];
                $rss[$i]['author_email']    = ''; 
                $rss[$i]['link']            = "chatbox_menu/chat.php?".$row['cb_id'];
                $rss[$i]['linkid']            = $row['cb_id'];
                $rss[$i]['title']            = '';
                $rss[$i]['description']        = $row['cb_message'];
                $rss[$i]['category_name']    = '';
                $rss[$i]['category_link']    = '';
                $rss[$i]['datestamp']        = $row['cb_datestamp'];
                $rss[$i]['enc_url']            = "";
                $rss[$i]['enc_leng']        = "";
                $rss[$i]['enc_type']        = "";
                $i++;
            }

        }                
                    
        return $rss;
    }
            
        
    
}

e_related.php

Adds your plugin to the search which generates 'related' links in news items and pages of e107. See e107_plugins/news/e_related.php for an example.

e_shortcode.php

Sometimes a plugin developers wishes that his shortcode be available not only to his plugin's templates but to core templates and templates of other plugins. This is the purpose of this file. It's content is identical to that of a regular shortcode class except that all the methods must follow the following naming convention:
sc_plugindir_name() eg. sc_faqs_question()

e_sitelink.php

Adds a sitelink sublink-generating function for your plugin. eg. auto-generated navigation drop-down menus for 'latest articles' etc.
See e107_plugins/news/e_sitelink.php for an example.

e_url.php

Provides a simple way to add mod-rewrite redirects to your plugin's page, without having to edit the .htaccess file. To create search-engine-friendly URLs which utilize this addon, please see the e107::url() method.

		class myplugin_url // plugin-folder + '_url' 
{
	function config() 
	{
		$config = array();
	
		$config[] = array(
			'regex'			=> '^myplugref-(.*)/?$',
			'redirect'		=> '{e_PLUGIN}myplugin/ref.php?ref=$1',
		);
				
		return $config;
	}	
}



e_user.php

Adds information about a specific user to the user's profile page. See e107_plugins/forum/e_user.php for a working example.

Upgrading v1.x Plugins

Your Plugin's Admin Area

We recommend plugin developers to upgrade their admin areas using the 'Plugin Builder' in the 'Plugin Manager" area. It allows you to select your e107 _sql file from your plugin folder, or directly from the database table list and will generate most of the new code for the admin-area of your plugin. It will also generate the new plugin.xml meta-file, which is used during installation of your plugin and also when sharing plugins via this site. The advantages of using the new admin system are numerous - including, but not limited to:

  • No need to code in the HTML or the process of reading or writing to your database.
  • Consistent interface with the rest of admin
  • Users can select which fields from your db table they wish to view - based on your predefined list.
  • Media-Manager is integrated into the system.
  • Easily add drag and drop sorting/re-ordering to your plugin.
  • Easily add batch delete, copy, featurebox creation, sitelink creation, userclass modification, etc. etc.
  • Easily add inline editing to your data.
  • Easily add tabs to keep your plugin's admin-area well organized.

Your Plugin's Front End

Minimum Changes:

  • Include a plugin.xml file

Recommended Changes:

  • Include a plugin.xml file
  • Use e107's form_handler class for all form elements.
  • Use Bootstrap 3 html/css standards in your templates and/or HTML markup
  • Upgrade e_xxxx.php files to v2 standards
  • Upgrade language-file names to new standards

Migrating Plugin Preferences to their own table row.

In e107 v.2x we recommend plugins to save their preferences to their own table row, however old plugins may still be storing them in the core preference table.

To easily migrate from one to the other, we created a simple method called migrateData().

		$oldPluginPrefs = array(
    'myplugin_caption' => 'caption', // old-pref-name => new-pref-name 
    'myplugin_display' => 'display',
    'myplugin_maxage' => 'maxage',
);

if($newPrefs = e107::getConfig()->migrateData($oldPluginPrefs,true)) // returns new array with values and deletes core pref. 
{
    $result = e107::getPlugConfig('myplugin')->setPref($newPrefs)->save(false,true,false); // save new prefs to 'myplugin'. 
}

Social Links