Getting Started

Note: This is just a tutorial, PHPDevShell offers advanced methods while coding. To keep this tutorial simple we used standard PHP code. In this tutorial, we'll use the folder phpdev as the folder where your installation of PHPDevShell resides (if you have not installed yet, follow this link). Change it to fit your actual folder name.

Starting with a new framework is always both a thrill and daunting task. You might feel what you have in front of you is interesting, but how can you get started with the most basics and work with it in its simplest form?

The getting started guide only focuses to get you started on what you are familiar with. For this tutorial we don't want to confuse you with new methods and methodologies, we just want to get you started using "good ol' PHP" for now :). We will guide you and give you a glimpse of why PHPDevShell is ready to get you going in 5 Minutes!

Screenshot_2.png

To follow this tutorial, you'll need:

  • a working installation of PHPDevShell (I'll assume it's accessible at http://localhost/phpdev/)
  • an administrator account (a registration on this installation allowing you to manage plugins)
  • a text editor or IDE to code in (we recommend free NetBeans or free Eclipse),
  • you must also have access to create folders upload files to your installation.

Now lets pick a name for your plugin. In PHPDevShell, every script belongs to a plugin. This allows you to stay consistent within a structure and have a whole site inside a single plugin folder. Let's say you name your plugin "tutorial" (all lowercase). Create a folder with this name inside the "/phpdev/plugins/" folder, e.g. "/phpdev/plugins/tutorial"

Hello world

Of course our first script will be the classic (yet fancier) hello world application, using only code you are familiar with.

Once you have created the tutorial folder in "phpdev/plugins/", you will be placing your new script (lets call it first.php for now) "first.php" inside it. Open/create your first.php script with your favorite PHP editor and start writing code, lets do the promised hello world:

<?php
	// Hello world heading.
	echo "

Hello, world!

"; // But don't feel limited. You have access to absolutely all standard PHP functions, even queries: $query = mysql_query('SELECT * FROM pds_core_users WHERE user_id = 1'); // Or use object queries if Models are not going to be used. $query = $db->newQuery('SELECT * FROM pds_core_users WHERE user_id = 1'); // You can build HTML right here. $html = "

Some HTML

"; echo $html; ?>
Every execution point in PHPDevShell is connected from the menu system as a node. The menu system has node types, this can be seen as an execution point for simple scripts, plugins, websites, widgets, ajax etc. For instance a widget node type can be called from inside a controller node type. This means that when this controller node type is access, the widget inside that node will also be loaded if the widgets node permission allows it.

Adding a menu to open your script in your Browser

The most common way of executing a script is to create a menu item. Creating a menu in PHPDevShell makes an item appears in the dashboard which when clicked will run your script. Go to System Management -> Menu Admin -> New Menu -> Fill the fields in as:

Plugin Item: Standard Plugin (leave rest of left column blank).

Name: The display name visible to the user ; let's try "Hello, World!" (note that this name can be different based on the user's language)

Alias: an alternate name, which can be used from the code to refer to the menu whatever the user's language ; let's try "hello-world"

Plugin Name/Folder: the name of the folder our script reside in; we chose "tutorial" earlier

URL or path: this will tell the engine where exactly to find our script file ; it's "first.php"

Leave the rest to their default values and click "Save". Then click on "Dashboard" in the upper menu: our new menu item "Hello, World!" should appear.

Screenshot-2_0.png

First run

OK we're ready! click on the menu icon "Hello, World!" and you should see your nice greeting. Basically any PHP script can be run that way; we call this "legacy mode" because it's way scripts where written before version 3.0.

But anyone can see my script :(

Ah, so you want to quickly protect your secretive Hello World with some magic using the Access Control? That is not a problem, simply add this line at the top of your script:

	// Stop people from seeing my highly secretive menu.
	(is_object($this->security)) ? $this->security->securityIni() : exit('Access Denied!');

Now remember to give your menu item the right permissions using by going to System Management->Policy Admin->Access Control

Sample Plugin

PHPDevShell is packaged with a sample plugin called ExamplePlugin, be sure to have a look at it in order to get started as quickly as possible with more advanced coding techniques.

Plugins

heading_Screenshot-3_0.png

Plugins play an extremely important role when you decide to create a project using PHPDevShell. Plugins are the main location of your source code for your project. We provide a fairly solid and stable MVC structure for your plugins, however, you are free to follow your own (if any MVC is even required).

You will use your plugin as the main folder of your projects, your project may have multiple plugins, with multiple shared classes per plugin. To highlight some point of what a plugin Can be:

  • a Small script that executes when a connected menu is accessed.
  • a Set of classes that can be created instances.
  • a Complete complex application with a totally different look and feel.
  • a Complete complex website with a totally different look and feel.
*PHPDevShell resources is a powerful set of objects that contain not only useful methods but also full sets of data on just about anything about the current user, system settings and much more. Resources can be shared with anything inside a plugin (classes, models, controllers etc).

PHPDevShell Plugins support both upgrades and install through an easy to read XML base;

  • Automatic Upgrades
  • Version Checking
  • Menus
  • Settings Installation
  • Class Registration
  • Dependency Checking
  • Installing, Upgrading, Uninstalling

Introduction to Plugins

All plugins are located in the plugins folder of PHPDevShell. In general anything can be done in your own plugins folder from APIs to UIs. If you are used to one standard that is fine, use your own standards. If you want to use APIs from another framework, that is very possible too. First thing to do is to give your plugin a name. This is done by creating a folder in the PHPDevShells plugin folder. Call it whatever you like. You can follow this tutorial by opening ExamplePlugin found in the standard PHPDevShell distribution folder.

Looking at the folders and files

config

In general, you can use the config folder to contain any type of configuration files your project might require, this can be in any format or form. The config folder also contains the most important file for PHPDevShell to understand your plugin. This XML file is name plugin.config.xml. This simple yet very advanced makes your plugin both installable by the plugin manager and upgradeable.

controllers

Controllers contains... erm controllers. But not necessarily in an MVC fashion. Controllers can also be plain php scripts. It does not matter, it is up to the coder to decide what he will use. Controller is also the starting point for a menu item to be executed. If a plugin menu is selected it will load a controller file located herein. Controllers can be named general descriptive names with my-example.php being a perfect example.

The controller can contain a simple script as:

<?php
	print "Hello World";
?>

images

The image folder will contain your plugins logo (logo.png) and controller icons and any general graphics. The logo.png is read automatically for each plugin, so is the controller icons. The controller icons (48x48px) needs to be named the same as the controller file. In this case my-example.png. This will give the user interface an elegant flow.

includes

The includes folder contains helper and registered public classes. Please read all about plugin.config.xml about registering and sharing classes. a Class always has ".class.php" at the end of the file. a Class name is also named the same as the file name. Looking at the example supportExample.class.php under includes:

class supportExample extends PHPDS_dependant
{
	/**
	 * The cool thing about supporting/helper classes is the ability to reuse code over and over again,
	 * PHPDevShell offers and extemely easy way to do this.
	 * Extend with PHPDS_dependant to share core object from PHPDevShell.
	 */

	/**
	 * Properties are used like normal.
	 * @var string
	 */
	public $somevar = 'Hello World';

	/**
	 * This just shows that you can reuse html too, this is ethically correct.
	 * @return string
	 */
	public function someReusedMethodwithHTML()
	{
		// Well what do you know, we have access to all PHPDevShell object.
		$name = $this->configuration['user_display_name'];
		$date = $this->core->formatTimeDate(time());

		// Obviously this method can be extended, but lets keep it simple.
		return sprintf('
			
				Hi %s, as you can see, this can now be reused. Todays date is %s.
			', $name, $date);
	}

	/**
	 * Support classes can have their own models. Models will be looked for in the models folder,
	 * with relation to the class file name, in this case it will be models/supportExample.query.php
	 * @return string
	 */
	public function someReusedModel()
	{
		// Obviously this method can be extended, but lets keep it simple.
		// Calling a model from within a support class.
		return $this->db->invokeQuery('ExamplePlugin_someExampleQuery');
	}
}

As soon as this class is registered after install, any plugin will be able to call it with:

		$helper = $this->factory('supportExample');
		$helper->someReusedMethodwithHTML();
		$helper->someReusedModel();
Did you know classes can also have models. Just like normal controller models, class models sits in the root of the models folder. In this case, this model would have been called models/supportExample.query.php. This allows you to split model relation to a separate file.

language

The language folder is there to serve your plugins translation needs. It houses different files to make translation possible. The first file to focus on is gettext.lang.php, this file has no real purpose other then making xgettex extract english strings for menus out of it for translation. So if you want to be able to translate your menus, make sure this file is there with all your default installed menu names. It would typically look like this.

<?php
_('Menu Name');
?>

Files that are more important are the .pot and compiled .mo files which contains actual translation.

models

The models folder contains query and data models for your controllers and helper classes. a Model contains multiple classes inside one file. Files are named in relation to the controller. In this example it would be models/my-example.query.php. Its should be noted that if the controller is in sub folders, the same folder should be followed for its model counterpart. Models generally contains content like this.

class ExamplePlugin_someExampleQuery extends PHPDS_query
{
	protected $sql = "
		SELECT
			example_name
		FROM
			_db_ExamplePlugin_example
    ";
	protected $singleValue = true;
}

views

The view holds your typical view for the controller. Views are also named in accordance with its controller spouse. In this example it would be view/my-example.tpl. The view may be used in conjuntion with a template engine. You are free to use clean php views or a template engine of your choice.

Conclusion

Following this article and its informative links should give you a much better understanding of how PHPDevShell plugins work. If you feel something is missing, comment here and it will be added.

Example Plugin

article_example.jpg

If you are anything like me, you would want examples to just get started. PHPDevShell ships with a neat ExamplePlugin that shows you exactly how to get the ball rolling in a matter of minutes. It should be remembered that PHPDevShell will in no way dictate how you work, it does offer you guidelines on how some things could be done to organize your work in a neat way.

Following by example is most often the simples and most affective form of learning.

Screenshot - 23122011 - 10:06:36.png

After installing PHPDevShell simply go to System Management->Plugins Admin, next to ExamplePlugin hit the install option. After the Example Plugin installation you will find a new set of menus in the root navigation. Here you will find results of coding examples and a sandbox to play around with. You can also view the plugins code under plugins/ExamplePlugin.

Plugin Config File

plugin.config.xml

The plugin config file is the most important part of your plugin for PHPDevShell to understand what it is your plugin should install. This powerful yet simple to use system allows both installing and upgrading of plugins, it even supports automated upgrades (downloads and installs without any uploading from your side). Your config file consists of standard XML;

<?xml version="1.0" encoding="UTF-8" ?>

Plugin XML code here

In the end, your plugin will have depending on your needs the following structure;

<?xml version="1.0" encoding="UTF-8" ?>

	
	
	
	
	
	
	
	
	
	
	
	http://version.phpdevshell.org/ExamplePlugin.xml
	
		
			
		
		
			
		
		
			
		
		
			
			
		
		
			
		
	
	
		
			
		
		
			
		
		
			
		
	
	
		
	

Don't copy above xml though, use the EmptyPlugin provided with the PHPDevShell distribution package to get a foundation on your xml.

Basic plugin information

The first group of information is about your plugin. This information is previewed in the plugin manager information page for each plugin. Quite simple and self explanatory. With this information your plugin will be fully readable and will display correctly in the plugin manager.

	continue from inside the config tags

	Use a proper plugin name without using special characters (same as folder).
	ExamplePlugin

	Human readable version number of your plugin.
	3.0.0

	a Short description of your plugin (what does it do?).
	This plugin is purely meant for examples on how to use PHPDevShell.

	If this plugin is based on another and only modification by you, place the original authors names here.
	Jason Schoeman

	Name of the developer/modifier for this plugin.
	Jason Schoeman

	Email address of the developer for this plugin.
	titan@phpdevshell.org

	Plugin developers web address.
	http://www.phpdevshell.org

	Date the plugin was developed or updated.
	10 November 2010

	Copyright notice you would like to amend to your plugin.
	Copyright 2009 PHPDevShell.org All rights reserved.

	License this plugin is released under.
	http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU/LGPL

	Detailed information and help for this plugin.
	
			

See some features and getting started with plugins. This plugin can actually be installed and is working. It will install a few simple menus, hooks, queries and settings serving you with the basics in writing a plugin.

The rest of the config follows here...

Checking plugin for updates

The plugin manager offers a simple yet effective way for a admin to check for updates for your plugin. It even support automatic upgrading of plugins if this configuration is completed and the file is hosted somewhere.

Now, looking at how the next line of XML looks, this simply shows that we are showing the plugin manager where to look for XML file for possible hosts.

	Code Version XML URL check.
	Version (current) below is used to check for new releases and has little to do with database version.
	See end of file to learn how the upgrade xml should look.
	http://version.phpdevshell.org/ExamplePlugin.xml
Note the "current" property, this is purely a number based on nothing more the to check if a version is newer. This number has nothing to do with the plugins version. It purely means that if your first plugin current="10" your next plugin release can be name current="11". This will allow the system to return true if there is an update.

Looking at the update xml file

The update xml is quite simple. It is hosted publicly so that the plugin manager can find it. The XML file is named the same as what you used in your versionurl property.

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

	Check against version number and human readable version number of plugin.
	3.0.1-Stable
	The URL where the latest version can be downloaded.
	http://version.phpdevshell.org/ExamplePlugin.zip
	Release note regarding plugin update.
	This is just an example remote upgrade.

This is all that needs to be presented in the update XML file. Now if versionurl current property is lower then update xml version current property then the update will trigger "true" in the sense that an update is available. The update will then download from the download url tag. This will in turn trigger the FTP update and attempt to update the whole system.

For the auto upgrade to be a success, FTP must be setup correctly and the ZIP must contain the root folder of the plugin. So if extracted, it will extract as per example to folder ExamplePlugin.

This covers the basics of how a config should look. We will however continue to install menus, api registration and more with the rest of the xml file.

Installing plugin resources

The plugin resources install is all wrapped under one parent tag, which handles the installation of:

  • Database Queries
  • Dependencies
  • Settings
  • Menus
  • Supporting Class APIs

Lets look at the parent tag. You will note the version property. PHPDevShell plugins have two version sets for each plugin. Software version and Database version. They are unrelated, software version focuses on source code changes where the database version focuses on actual data changes contained within the database. So the version property of the install tag will always be updated as soon as a new version of a plugin is released only when there are database changes. Else simply the general informations version tag needs to be changed.

The version property will also tell the upgrade tags to stop when it reaches the value of this number. Meaning each database upgrade tag will be executed while the upgrade tag version is smaller then the install tag version.

It is very important to note that the install tag will always contain the most up to date changes in it. Meaning. Don't just rely on the upgrade part which we will discuss later. Make sure the menus, settings and queries are all up to date in the install tag.

So above discussed will look like this:

	Version here represents the database version that should be install.
	If your database version needs no update, this number can stay the same.
	Upgrades further down will only be executed up to this number.
	This is the current database version that will be installed.
	Below is a series of example upgrade procedures.
	
		Most up to date install tags here...
	

Install Tag: dependency

The install tag tells the reports what other plugin classes this plugin depends on. It does not play a vital role, except to help prevent broken installation when a required plugin is not installed yet.

		[contains][All query, menu, dependencies, settings installation tags.]
		[param][class][string][mandatory][The class call it depends on, the call must be registered.]
		[param][plugin][string][mandatory][The default plugin the class is available in, it can be override with another class with the same call.]
		[note][This is how the plugin manager will know to what version upgrade scripts should be executed.]
		[note][Always keep install maintained to the latest menu, query, hooks and setting versions.]
		
			
			
			
			
			
		

Install Tag: queries

These tags are used to run multiple database queries. Each query is placed in its own queries->query tag. The installer will run them in order and will execute then in series. You have complete freedom in running any query you like.

Typical queries as per the example will look like this (remember that install->queries should contain the plugins most recent and complete sql):


			[contains][All install queries to create the tables for your plugin.]
			[note][If there is a SQL query error, the plugin will not install.]
			
				[string][This is a single actual sql query that will be executed]
				[note][SQL query be placed in [CDATA tags.]
				
					CREATE TABLE `_db_ExamplePlugin_example` (
						`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
						`example_name` varchar(255) DEFAULT NULL,
						`example_note` tinytext,
						`alias` varchar(255) DEFAULT NULL,
						PRIMARY KEY (`id`),
						KEY `index` (`alias`)
					) ENGINE=InnoDB DEFAULT CHARSET=utf8;
			
			
				[note][SQL queries can be repeated.]

					CREATE TABLE `_db_examplepluginanothertable` (
						`id` int(20) unsigned NOT NULL auto_increment,
						`user_id` int(20) default NULL,
						`message` varchar(255) default NULL,
						PRIMARY KEY  (`id`)
					) ENGINE=InnoDB DEFAULT CHARSET=utf8;
			
			
				[note][SQL queries can be duplicated.]
					REPLACE INTO `_db_ExamplePlugin_example` VALUES ('1', 'Toyota', 'Reliable Toyota', 'car');
			
			
				[note][SQL queries can be duplicated.]
					REPLACE INTO `_db_ExamplePlugin_example` VALUES ('2', 'Mazda', 'Legend Mazda', 'car');
			
			
				[note][SQL queries can be duplicated.]
					REPLACE INTO `_db_ExamplePlugin_example` VALUES ('3', 'Ford', 'Muscle Ford', 'car');
			
			
				[note][SQL queries can be duplicated.]
					REPLACE INTO `_db_ExamplePlugin_example` VALUES ('4', 'Citroen', 'French Citroen', 'car');
			
			
				[note][SQL queries can be duplicated.]
					REPLACE INTO `_db_ExamplePlugin_example` VALUES ('5', 'Mercedes', 'Quality Mercedes', 'car');
			
		

Install Tag: settings

PHPDevShell has a nifty settings repository to quickly and with a low footprint get an array of settings for a particular task. The Config Manager allows end users to easily change these settings. To add important settings to the database you can simply do:


			[contains][Contains tags of all settings that needs to be installed to the general PHPDevShell settings database.]
			
				This is a sample setting (1)!
				[string][Actual value of setting that needs to be stored.]
				[param][write][string][mandatory][The parameter id of the value to be stored.]
			
			
				Yet another sample setting (2)!
				[note][Setting tag needs to be repeated for each setting.]
			
			
				true
				[note][Setting tag needs to be repeated for each setting.]
			
		

The write property is the key of the setting, the content of the tags are the values. Getting settings in code is quite easy.

		// Looking at a simple $this->db method.
		// Lets get sample ExamplePlugin settings that we added during the install.
		$setting = $this->db->getSettings(array('sampleSetting1', 'sampleSetting2'), 'ExamplePlugin');

Install Tag: menus

We tried to make menu installation as simple as possible. Using the depth of the tags to structure the menus, because of this menus in the xml is easy to setup and very readable. The menu xml has multiple properties to adjust, however it works in its simplest form.

		
			
			[contains][All types of menu items that needs to be installed.]
			[note][Tags inside menus can be nested and repeated.]
			[note][Here we link to an existing menu item from another plugin, in this case the control-panel aka dashboard.]
			
			
				
				[contains][Menu items can be contained in itself, this will create a menu tree.]
				[param][name][string][not-mandatory][The name of the menu item, if empty the pluginName.menu.lang.php will be used.]
				[param][type][int][not-mandatory][There are 8 menu types, 1 is the default if left empty.]
								[1][Plugin script] normal plugin menu item in your plugin folder.
								[2][Link existing menu] item while staying in its own menu group when clicked.
								[3][Link existing menu] item while jumping to original scripts menu group when clicked.
								[4][External file] Include external PHP web applications into PHPDevShell.
								[5][HTTP URL] Normal url to outside web.
								[6][Empty Place Holder] This item will only serve as a unclickable menu place holder.
								[7][iFrame] Link url to both external url or onsite url.
								[8][Cronjob Menu Type] The same as a plugin script but is set as cronjob.
				[param][link][string][mandatory][The url, controller location or symlink holder will be entered here depending on type.]
				[param][hide][int][not-mandatory][There are 4 hide types, 0 is the default if left empty.]
								[0] Do not hide menu item.
								[1] Hide menu item from both Menu System and Control Panel.
								[2] Hide menu item from Control Panel only.
								[3] Hide menu item from Menu System only.
								[4] Hide menu only when inactive.
				[param][rank][string][not-mandatory][If you want to ensure ranking positions, will auto rank if left empty.]
								[int] Can be ranked with integer.
								[last] Will be ranked last in a menu group.
								[first] Will be ranked first in a menu group.
				[param][newwindow][int][not-mandatory][To make item open in new window set to 1, will not open in new if left empty.]
				[param][plugin][string][not-mandatory][Plugin name, use to install menu item to a different plugins menu structure.]
				[param][alias][string][not-mandatory][When switching on friendly urls in the settings and renaming rename.htaccess in the root, sef url will use this alias.]
				[param][parentlink][string][not-mandatory][Use with [param][plugin] or without to install in different structure.]
				[param][symlink][string][not-mandatory][Url or location with [param][plugin] or without to link to another menu item duplicating its use.]
								[note][Symlink is mandatory for menu types 1,2,6]
				[param][template][string][not-mandatory][Set template to use with plugin, if template is unavailable it will be installed.]
				[param][template][string][not-mandatory][Set the height of an iframe menu type.]
								[note][Height is mandatory for menu types 7]
				[param][layout][string][not-mandatory][Set a custom template.tpl location for a certain script.]
				[param][noautopermission][int][not-mandatory][Set to 1 to not add the installer of the plugin to permit menu item access.]
				-
				
					[note][Can be nested to present a deeper menu tree.]
					
					
					
					
					
						
							[note][Can be repeated.]
							
						
					
				
				[note][New menus on upgrades should be added here, this will always be the model on upgrades.]
				[note][Let us add some other odd menu types for examples sake as well.]
				
				[note][Installing a menu item to another plugins menu structure is easy as well.]
				
			
		
You should note that when using the link property, this is the location of the controller file under the controllers folder. This does not need to be a controller as such. It can be a plain php too.

Install Tag: classes

Registering classes plays a very important role. This makes the classes publicly accessible to other plugins. Not only that, these plugin calls can be override by other higher priority classes to manipulate original shared plugin class functionality. All classes registered with the classes tags should be available in the plugins includes folder and named something like exampleClass.class.php, the shared class must have this structure in order for it to share PHPDevShell resources:

class supportExample extends PHPDS_dependant
{
	// Normal class code here.
}

Plugins can then call a class using:

		$helper = $this->factory('supportExample');
		$helper->someReusedMethodwithHTML();
		$helper->someReusedModel();

To register a class, simply add the following xml, you can have multiple class tags to register multiple classes per plugin.

		[contains][Register classes to be publicly available and shared. There can be multiple classes of the same name in different plugins, they can overwrite each other by rank.]
		[note][Class name must be the same as what the file is called, groupTree.class.php and must be containded within includes folder.]
		[param][name][string][mandatory][The name of the class to be called by factory('groupTree') and the filename that contains the class groupTree.class.php]
		[param][alias][string][mandatory][Alternative callname for factory('PHPDS_groupTree'), will call same class though.]
		[param][plugin][string][mandatory][The plugin name/folder where the class belongs to.]
		[param][rank][mixed][not-mandatory][The lower in integer the rank the higher the chance is that this class will overwrite classes of the same names.]
			   [int] Can be ranked with integer.
			   [last] Will be ranked last and any preceding class will overwrite it.
               [first] Will be ranked first and will be overwriting lower ranked classes.
		
		
			
			
		

The upgrade tag

All plugins receive updates. An update is easy to accomplish if there are no data changes. PHPDevShell makes it just as easy to do data upgrade. You can easy database upgrades for multiple versions behind. Meaning, if a user only updates after 5 versions later, the system will run all datbase queries from the first version. This is very usefull to keep the upgrading process flawless.

The upgrade tag supports lesser functions then the install tag, seeing that allot of updates are taken from the install tag rather. So there is no need to design an upgrade for everything. As long as your install tag is up to date, allot of the updates will be taken from there.

Looking at the simplicity of the upgrade tag, you will with this example clearly see what it is capable of. Again, upgrades will run until the version is matched with the install versions tag;

	Upgrades only upgrade to the point where  is set.
	To preview how upgrade works set  to 2801 or higher.
	
		[contains][All query, menu, settings upgrade tags.]
		[param][version][int][mandatory][This upgrade version, will upgrade until install[version] is met.]
		[note][This is how the plugin manager will know to what version upgrade scripts should be executed.]
		
			[contains][All upgrade queries to create the tables for your plugin.]
			
				[string][This is a single actual sql query that will be executed on upgrade.]
				[note][SQL query be placed in  tags.]
				ALTER TABLE `_db_examplepluginanothertable` MODIFY COLUMN `user_id` int(40) unsigned NOT NULL;
			
			
				[note][The query tag should be repeated for each upgrade query.]
				ALTER TABLE `_db_examplepluginanothertable` MODIFY COLUMN `message` varchar(200) default NULL;
			
		
		
			[contains][Contains tags of all settings that needs to be upgraded or removed from the general PHPDevShell settings database.]
			
				More Settings (3)
				[string][Actual value of setting that needs to be stored.]
				[param][write][string][mandatory][The parameter id of the value to be stored.]
			
			
				We can do this all day long (4)
				[note][Setting tag needs to be repeated for each setting added.]
			
			
				[note][Setting tag needs to be repeated for each setting to be deleted.]
			
			
				[contains][Nothing, works from parameters only.]
				[param][delete][string][mandatory][The parameter id of the value to be deleted.]
			
		
		
			[contains][All menus that should be deleted.]
			[note][To add menus on upgrades the master install must always be modified with latest menus.]
			[note][Old menus should still be deleted even though they have been removed from install.]
			
				[contains][Nothing, works from parameters only.]
				[param][delete][string][mandatory][The link to the item that needs to be deleted.]
				[note][It does not matter where link for this menu item exists, it will find it automatically.]
			
			
				[note][This tag can be repeated to delete multiple menus.]
			
		
	
	To preview how upgrade works set  to 2802 or higher.
	
		[note][This tag can be repeated with all child tags for each release that needs upgrade action.]
		
			
				[string][This is a single actual sql query that will be executed on upgrade.]
				[note][SQL query be placed in  tags.]
				ALTER TABLE `_db_examplepluginanothertable` MODIFY COLUMN `user_id` int(30) unsigned NOT NULL;
			
		
		
			
				[contains][Nothing, works from parameters only.]
				[param][delete][string][mandatory][The link to the item that needs to be deleted.]
				[note][It does not matter where link for this menu item exists, it will find it automatically.]
			
			
		
	
	To preview how upgrade works set  to 2803 or higher.
	
		[note][Will run through all upgrade on upgrade until install version is met.]
		
			
				[note][The query tag should be repeated for each upgrade query.]
				DROP TABLE IF EXISTS _db_examplepluginanothertable;
			
		
		
			
		
		
			
				We can do this all day long (5)
				[note][Setting tag needs to be repeated for each setting added.]
			
		
	

The uninstall tag

The uninstall tag will mostly uninstall everything automatically, except for the queries. You need to explicitly tell the system what tables needs to be removed if any. Menus, classes, settings will all be permanently removed automatically.

	
		[contains][All actions that will be executed on uninstalling a plugin.]
		[note][Menus, settings and hooks will be uninstalled automatically for this plugin.]
		
			[contains][All uninstall queries that will be executed when requested.]
			
				[string][This is a single actual sql query that will be executed on uninstalling plugin.]
				[note][SQL uninstall query be placed in  tags.]
				DROP TABLE IF EXISTS _db_ExamplePlugin_example;
			
			
				[note][The query tag should be repeated for each uninstall query.]
				DROP TABLE IF EXISTS _db_examplepluginanothertable;
			
		
	
As you can see, no version information needs to be provided for the uninstall to take place. Just the latest SQL is needed.

Conclusion

That covers it for the configuration file for plugins. If you are still hesitant about features, just comment here and we will add continued help regarding your question. Happy coding.