The quickest way to create an Installatron installer, or at least the template for one, is to log into the Installatron Installer Editor (everyone who has an installatron.com account, which you will have if you ever purchased Installatron licenses, can log into the Editor) and use the right-sidebar to create a new installer.
The form asks you for some information about the script and then you press the [Create] button to build it.
All of the values can be easily changed later except for Script Name. If you want to experiment then use a Script Name of "test" and give it some dummy values.
The rest of this document describes what you'll find in an Installatron installer or what you'll need to create if you're making one manually.
An Installatron application package is comprised of several files and directories, placed inside Installatron's "installers" directory:
/var/installatron/installers/installerid/ init.xml // information about the installer and the application locale_en.php // the default (english) locale file button.png // a 88x31 button image for the app logo.png // up to 400x150 logo image for the app icon.png // 175x175 icon image for the app icon64.png // 64x64 icon image for the app (resized icon.png) [ss1.png] // 1024x640 screenshot of the app [ss2.png] // 1024x640 screenshot of the app version1/ // a version sub-directory [LICENSE] // license agreement for this version (optional) init.xml // information for this version (including PHP7 install code) [version2/ // another version sub-directory (optional) [LICENSE] init.xml] // information for this version (including PHP7 install and upgrade code)
installerid is the unique lowercase-alphanumeric id of the installer.
version1, version2, etc are the versions (eg. "2.1.0p1", "2.1.1", etc).
(note that upgrade code is only (optionally) included in the second version and onward)
Each of those files and directories is described in detail below.
The introduction of PHP7 by the The PHP Development Team in 2015 necessitated changes in the way that Installatron installers worked. Specifically, whereas for PHP5 the install and upgrade code for each version of each installer was supplied in separate files for each task (see the package layout diagram above), for PHP7 it was necessary to move the install/upgrade code into the init.xml file.
To maintain backwards compatibility, Installatron now supports both formats; external install.php/upgrade.php files for when Installatron's core is running on PHP5 and internal init.xml elements for when the Installatron core is running on any version of PHP7.
The code used by both formats is very similar and is easy to translate between one format and the other.
Note that the Installatron installer Editor tool lets you edit installers in v2.0 format while it automatically builds the additional v1.0 / PHP5-only files each time you save.
If you're creating an installer by hand then unless you know that the installer will be used on PHP5 servers we recommend ignoring the v1.0 installer format and PHP5 compatibility altogether.
The easiest way to create an Installatron application package is to use the Installer Maker/Editor tool. This tool creates a basic template and has a GUI for editing most of the commonly used features.
See the Reference: Variables, Commands, and How-Tos section for a closer look at the things you can use in application package installer and upgrader code, the Using an Installer section for information on adding the application package to your server, or read The Package Files for a look at each file and directory in an Installatron application package.
What follows is a close look at the 5 main files and functions associated with the installer, where 99% of the work is performed. If you understand the installer init.xml, the version init.xml, the installer, the upgrader, and finally fields, then you know how Installatron installers work.
The top-level init.xml file contains general information about the installer and the application it installs. Here is the format:
<?xml version='2.0'?> <installer> <information> <info id="id" value="{ID}"/> <info id="build" value="{INSTALLER_BUILD_NUMBER}"/> <info id="status" value="{enabled|disabled}"/> <info id="name" value="{NAME}"/> <info id="type" value="{TYPE}"/> <info id="category" value="{CATEGORY}"/> <info id="created" value="{YYYY-MM-DD}"/> <info id="description" value="{INTRODUCTION}"/> <info id="authordescription" value="{APP_AUTHOR'S_DESCRIPTION}"/> </information> <links> <!-- a collection of links associated with this application --> </links> <versions> <branch id="current"> <branch id="current"> <version id="{VERSION3}" upgrade="{auto|skip|manual|none}" install="{auto|none}"/> <version id="{VERSION2}" upgrade="{auto|skip|manual|none}" install="{auto|none}"/> <version id="{VERSION1}" upgrade="none" install="auto"/> </branch> </branch> </versions> </installer>
{ID} is the unique id of the installer.
build_number is the current build number of the installer. Increment this number whenever the installer is edited.
_installer_installerid_* are references to locale entries. You can use plain text here if you don't want to use the locale file.
url_to_* are all optional, though users do like to see at least a website link for the application.
version1, version2, etc are the versions (eg. "2.1.0p1", "2.1.1", etc), with the newest version at the top. If upgrading is not supported then there will be a single version in this area.
What follows is a closer look at each element of the installer init.xml:
Defines information about this version of the application.
<information> todo... </information>
{VERSION} is this version of the application (eg. "2.1.0p1").
{LICENSE} can be any text, or a reference to the application's locale file, or the global locale keys: _apps_free or _apps_opensource
{DEFAULT_DIRECTORY_NAME} is an optional default install directory name. If not present, the default directory when installing the application will be the {ID}.
todo...
The version-level init.xml file contains information specific to this version of the application. Here is the format:
<?xml version='2.0'?> <installer> <information> <!-- the main information about this version of the app --> </information> <changelog[ url="{URL_TO_RELEASE_NOTES}"]> <![CDATA[ <!-- highlights, bug fixes, and security information about this version of the app --> ]]> </changelog> <links> <!-- some links associated with this version of the app --> </links> <requirements> <!-- a list of server and account requirements for this version of the app --> </requirements> <archives> <!-- a list of archives used to install and upgrade this version of the app --> </archives> <skeleton> <!-- a list of this version of the app's top-level files and directories, and its main config file --> <!-- a list of this version of the app's database tables (without table prefix) --> </skeleton> <fields> <!-- definitions for getting and setting fields like the administrative user's password and email address, and the app's version --> </fields> <languages> <!-- a list of languages supported by this version of the app --> </languages> <install> <!-- the code to install this version of the app (when Installatron is running on PHP7+) --> </install> <upgrade> <!-- the code to upgrade to this version of the app (when Installatron is running on PHP7+) --> </upgrade> </installer>
What follows is a closer look at each element of the version init.xml:
Defines information about this version of the application.
<information> <info id="version" value="{VERSION}"/> <info id="license" value="{LICENSE}"/> <info id="date" value="YYYY-MM-DD"/> [<info id="default-dir" value="{DEFAULT_DIRECTORY_NAME}"/>] </information>
{VERSION} is this version of the application (eg. "2.1.0p1").
{LICENSE} can be any text, or a reference to the application's locale file, or the global locale keys: _apps_free or _apps_opensource
{DEFAULT_DIRECTORY_NAME} is an optional default install directory name. If not present, the default directory when installing the application will be the installerid.
Changes from the previous version of this application (as supported by Installatron) to this version of the application.
These notes are provided to the user prior to updating an application.
[<changelog[ url="{URL_TO_RELEASE_NOTES}"]> <![CDATA[ <!-- highlights, bug fixes, and security information about this version of the app --> ]]> </changelog>]
An asterisk ('*') at the beginning of the line will automatically be converted into a bullet-point ('•').
Installatron conventions: while this changelog entry can be anything you like, Installatron roughly follows the following conventions;
Some administration links associated with this version of the application.
All links are optional, and all are in the form of paths relative to the app's main install directory.
[<links> <link id="admin" value="{ADMIN_BACKEND_PATH}"/> </links>]
admin adds an [admin] button to the Installed Apps page and is a link to an "administration" page. config is the same except it is for a [config] button. edit-1, edit-2, etc are files that can be edited inside Installatron (for templates or config files that can't be edited through the application itself). todo...
A list of server requirements for the application
All requirements are optional. Leave empty if the application has no requirements.
<requirements type='2.0'> [<requirement id="itron" value="5.0.0"/>] [<requirement id="diskspace" value="{MEGABYTES}"/>] [<requirement id="diskspace-content" value="{MEGABYTES}"/>] [<requirement id="php" value="{VERSION-RANGE-DEF}"/>] [<requirement id="asp" value="{VERSION-RANGE-DEF}"/>] [<requirement id="perl" value="{VERSION-RANGE-DEF}"/>] [<requirement id="mysql" value="{VERSION-RANGE-DEF}"/>] [<requirement id="mysql-table-prefix" value="{PREFIX}"/>] [<requirement id="mysql-file-format" value="{1|0}"/>] [<requirement id="mysql-max-recursion-depth" value="{INTEGER}"/>] [<requirement id="mssql" value="{VERSION-RANGE-DEF}"/>] [<requirement id="sqlite" value="{VERSION-RANGE-DEF}"/>] [<requirement id="php-allow-url-fopen" value="{1|0}"/>] [<requirement id="php-date-timezone" value="{1|0}"/>] [<requirement id="php-magic-quotes" value="{1|0}"/>] [<requirement id="php-memory-limit" value="{MEGABYTES}"/>] [<requirement id="php-open-basedir" value="{1|0}"/>] [<requirement id="php-register-globals" value="{1|0}"/>] [<requirement id="php-save-mode" value="{1|0}"/>] [<requirement id="php-short-open-tag" value="{1|0}"/>] [<requirement id="php-upload-max-filesize" value="MEGABYTES"/>] [<requirement id="php-bcmath" value="{1|0}"/>] [<requirement id="php-calendar" value="{1|0}"/>] [<requirement id="php-ctype" value="{1|0}"/>] [<requirement id="php-curl" value="{1|0}"/>] [<requirement id="php-exif" value="{1|0}"/>] [<requirement id="php-fileinfo" value="{1|0}"/>] [<requirement id="php-freetype" value="{1|0}"/>] [<requirement id="php-gd" value="{1|0}"/>] [<requirement id="php-iconv" value="{1|0}"/>] [<requirement id="php-intl" value="{1|0}"/>] [<requirement id="php-ioncube" value="{1|0}"/>] [<requirement id="php-mycrypt" value="{1|0}"/>] [<requirement id="php-openssl" value="{1|0}"/>] [<requirement id="php-phar" value="{1|0}"/>] [<requirement id="php-simplexml" value="{1|0}"/>] [<requirement id="php-soap" value="{1|0}"/>] [<requirement id="php-xml" value="{1|0}"/>] [<requirement id="php-xmlreader" value="{1|0}"/>] [<requirement id="php-xmlwriter" value="{1|0}"/>] [<requirement id="php-xsl" value="{1|0}"/>] [<requirement id="php-zend" value="{1|0}"/>] todo... </requirements>
A list of archives associated with this version of the application.
Installatron will download these when they are first used and cache them in /var/installatron/archives/.
The first archive is always, by convention, the application's main archive, which is used to install and also often to upgrade the application too. You can list as many other archives as needed. Uses might include; optional demo content for install, a separate upgrade archive for upgrading, and locale archives.
<archives> <archive id="main" url="{URL}" type="{TYPE}"[ md5="{MD5}"]/> [<archive id="{ID}" url="{URL}" type="{TYPE}"[ md5="{MD5}"]/>] ... </archives>
The first archive always, by convention, uses an id of "main".
The archive type can be either: "zip" or "tar.gz".
The optional md5 hash value can be calculated with PHP's md5() function or an online tool Installatron uses this value to check that the archive has downloaded correctly.
Editor automatically adds md5 values if they are not present.
A list of top-level directories, top-level files, and database tables that Installatron should, by default, associate with this version of the application.
Database tables should be listed without a table prefix.
The skeleton entries are not technically required but you absolutely should try to make these lists as accurate as possible because they affect these tasks: Import, Clone, Backup, Uninstall. So if you want any of those tasks to work you should pay attention to these lists.
Some flags are available to identify key files (and these need not be top level):
<skeleton> [<file id="{FILENAME|DIRECTORY}"/>] [<file id="config/configuration.php" isconfig="true"/>] ... [<table id="{DB_TABLE}"/>] ... </skeleton>
Remember; the files and directories listed here are only the top-level (ie. those in the install directory) items, and you only need to include items in sub-directories if they are flagged.
The order of these lists is not important although by convention the <file> list is usually before the <table> list.
Pro tip: a common question here regards plugins that might add extra files or tables; should you try to anticipate every possible file, directory, and table that might ever be part of this application and include it here? You could and that would be a solution, sure. But that's not how we handle the official installers.
Regarding files/directories; Installatron automatically watches for top-level- files and directories that are created during install/update tasks -- files that are not includes in the installer's skeleton list -- and adds them to the list of files that Installatron will track for the application.
If the user adds files to the main directory outside of install or update tasks then Installatron has no knowledge of those files/dirs and will not track them. This means they will not be included in any Backup, Clone, or Uninstall.
The app's owner can, however, edit the app (in Installatron), go to the 'Files & Tables' tab, and check the files that they want Installatron to start tracking.
Regarding tables; if a table-prefix is used by the application then Installatron will always automatically know which tables belong to the application, regardless when the tables were added. Installatron will just work with all tables beginning with that prefix.
If no table-prefix is used then Installatron falls back to using a combination of the skeleton table list plus it will automatically watch for extra tables added during install/update tasks and track them as well. If no prefix is used then for tables added outside of an Installatron activity, like if the user added a plugin to the app which added its own tables, Installatron will not know about those new tables and they will therefore not be included in any Backup, Clone, or Uninstall.
But as with files; the app's owner can edit the app in Installatron, go to the 'Files & Tables' tab, and check the extra tables that they want Installatron to start tracking.
fields gather information and interface directly with the installed application. Fields can get and/or set values. See A Fields Guide for more.
<fields> <!-- definitions for getting and setting fields like the administrative user's password and email address, and the app's version --> </fields>
List of languages that Installatron can install the application in and switch the application between.
<languages> [<language id="{??}" value="{???}"/>] ... </languages>
todo... provides a way to associate the application's own language IDs with Installatron's internal language identifiers. See the Installatron Language Identifier table for more.
(PHP7+ only) contains the code to install the application. For PHP5, this code would be placed in the separate file named installer.php. See The Installer for more.
<install> <?php
<!-- the code to install this version of the application (when Installatron is running on PHP7+) -->
?> </install>
(PHP7+ only) contains the code to upgrade the application from a previous version. For PHP5, this code would be placed in the separate file named upgradeer.php. See The Upgrader for more.
<upgrade> <?php
<!-- the code to upgrade to this version of the application (when Installatron is running on PHP7+) -->
?> </upgrade>
Applications are, ultimately, installed by installer code, the details of which are documented here.
While the installer code itself has not changed, the location of the installer code changed between versions 1.0 and 2.0 of the Installatron installer format; the version 1.0 format, used when the Installatron core is running on PHP 5, is found in a file named installerid/version/install.php while the version 2.0 format, used when the Installatron core is running on PHP 7+, is included directly in the version's installerid/version/init.xml file (inside <install>...</install> tags).
If you're using Installatron Installer Editor to edit your installer then it will automatically create the PHP5-compatible files, but if you're creating the installer by hand then unless you specifically know it will be used on PHP5 servers we recommend ignoring the v1.0/PHP5 installer files. They won't be needed.
When Installatron's core is running on PHP 7+ it will look for the install code, for this version of the application, in the version's init.xml file (inside a pair of <install>...</install> tags). If Installatron is running on PHP 5 then it will ignore this code (and look for the v1.0 install.php file instead).
This v2.0 formatting of the install code is very simple;
//@INTERNAL - LEGACY STEP BREAK POINT - DO NOT DISTURBThat line is used by the Installatron Installer Editor for internal purposes.
And the rest is up to you.
<install>
<?php
// extract the application's archive(s) HERE
//@INTERNAL - LEGACY STEP BREAK POINT - DO NOT DISTURB
// perform any necessary install steps HERE (chmods, edits, fetches, deletes, etc)
?>
</install>
Applications are, ultimately, upgraded by upgrader code, the details of which are documented here.
While the upgrader code itself has not changed, the location of the upgrader code changed between versions 1.0 and 2.0 of the Installatron upgrader format; the version 1.0 format, used when the Installatron core is running on PHP 5, is found in a file named upgraderid/version/upgrade.php while the version 2.0 format, used when the Installatron core is running on PHP 7+, is included directly in the version's installerid/version/init.xml file (inside <upgrade>...</upgrade> tags).
When Installatron's core is running on PHP 7+ it will look for the upgrade code, for this version of the application, in the version's init.xml file (inside a pair of <upgrade>...</upgrade> tags). If Installatron is running on PHP 5 then it will ignore this code (and look for the v1.0 upgrade.php file instead).
This v2.0 formatting of the upgrade code is very simple;
And the rest is up to you.
<upgrade>
<?php
// perform any necessary upgrade steps HERE (archive extraction, chmods, edits, fetches, deletes, etc)
?>
</upgrade>
Fields are one of the top-level definitions in the installerid/version/init.xml file and they are used to define how Installatron interacts with the application.
For example; if Installatron needs to know what version of an application is currently being used then it calls the code in <fields><field id="version"><get>. This code, for whatever application Installatron is interested in, is expected to be able to find the app's version.
Here is what fields look like in the version's init.xml file (the first field here, for version, is taken from our WordPress installer):
<fields> <field id="version"> <get> <?php return $this->read("wp-includes/version.php", "/wp_version = (['\"])(.+?)\1;/", 2);?> </get> </field> <!-- this is the template of an internal field --> <field {ID}> <get> <?php return /* return the value for this field */ ?> </get> <set> <?php /* code to set this field using the Installatron $this->input["field_{ID}"] value */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field> <!-- this is the template of a custom field --> <field {ID} {TYPE} {DEFAULT_VALUE}> <label>{LOCALE_TAG_1}</label> [<options> <option value="yes">{LOCALE_TAG_2}</option> <option value="no">{LOCALE_TAG_3}</option> </options>] <get> <?php return /* return the value for this field */ ?> </get> <set> <?php /* code to set this field using the Installatron $this->input["field_{ID}"] value */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field> ... </fields>
(One of the great values of WordPress is that in the 15 years or more that Installatron has installed WordPress the method of finding the app's version has never changed. So that particular piece of code has never needed to change in our WordPress installer.)
Also note that there is no <set> for the version field because Installatron never sets an app's version, only ever reads it.
Any PHP code can be used between the <?php ... ?> tags, though we encourage you to use Installatron's internal variables and commands in order to maintain maximum compatibility and portability.
Before looking at the different types of fields we'll quickly look at the optional <verify> element which is common to all fields that include a <set> element. This is used to validate any value entered by the user. Here's the format and an example:
<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>
And now we'll look at the two types of Installatron fields; internal fields (those that Installatron automatically recognises and automates much of), and custom fields:
The version field, seen above, is an example of an internal field type which means that Installatron automatically recognises it and knows how and when to use it. You only need to add its definition to the <fields>...</fields> block in installerid/version/init.xml and Installatron will handle the rest.
All internal fields need only the {ID} parameter; you don't need to provide the {TYPE} and {DEFAULT_VALUE} parameters.
The following is a full list of internal fields that you can add to your installer. Simply add them to the <fields>...</fields> definition, edit the PHP code for each set and get to match your application, and Installatron takes care of the rest.
The internal fields are:
get & set
This gets and sets the application's administrative user's email address. The <get> should return the app's administrative user's current email address and the <set> should use Installatron's $this->input["field_email"] value to set a new email address (usually set somewhere in the app's database).
<field id="email"> <get> <?php return /* return the app's administrative user's email address here */ ?> </get> <set> <?php /* set the app's administrative user's email address as $this->input["field_email"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
get & set
This gets and sets the application's language. This is the most difficult field to support, and we recommend leaving it until everything else is running smoothly.
First, you need to decide whether this is to get and set the application's language and/or the administrative user's language. Installatron itself is, admittedly, inconsistent on this question; we take it on a case-by-case basis, but wherever possible we aim to make this setting change both the application's primary language and the administrtive user's selected language.
Note that this setting does not tend to affect the localisation that visitors will see the website in as most applications will use the visitor's own browser settings to determine the best localisation for them.
With that said, if you include this internal-field then <get> should probably return the app's administrative user's current language setting and the <set> should change both the application's language and the administrative user's language to use Installatron's $this->input["field_language"] value.
<field id="language"> <get> <?php return /* return the app's administrative user's language here */ ?> </get> <set> <?php /* set the app's primary language and/or the administrative user's language as $this->input["field_language"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
Pro tip: what if the application only comes with the English locale files, as many apps do, and the other translations need to be downloaded separately? Changing the database values won't cut it, will it? No, it won't! You will need to expand this code to either:
get & set
This gets and sets the application's administrative user's username. The <get> should return the user's current username and the <set> should use Installatron's $this->input["field_login"] value to set a new username (usually set somewhere in the app's database).
<field id="login"> <get> <?php return /* return the app's administrative user's username here */ ?> </get> <set> <?php /* set the app's administrative user's username as $this->input["field_login"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
set only
This sets the application's administrative user's password.
The <set> should use Installatron's $this->input["field_passwd"] value to set a new password (usually set somewhere in the app's database).
Passwords are almost always encoded in some way so your task here is to replicate the encoding method used by the application. In the example code here, for example, the password is simply encoded with md5() however it's possible that you will need to replicate some of the application's encoding code here in order to match the format perfectly.
The result of encoding it incorrectly is that you won't be able to log in as the administrator after installing the app.
<field id="passwd"> <set> <?php /* set the app's administrative user's password as $this->input["field_passwd"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
get & set
This gets and sets the application's website description (the detailed text that is usually displayed on the website's front page). The <get> should return the current description and the <set> should use Installatron's $this->input["field_sitedescription"] value to set the website's new description (usually set somewhere in the app's database).
<field id="sitedescription"> <get> <?php return /* return the website's description here */ ?> </get> <set> <?php /* set the website's description as $this->input["field_sitedescription"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
get & set
This gets and sets the application's website title (the text that is usually displayed on the website's front page and in the web browser's title bar). The <get> should return the current title and the <set> should use Installatron's $this->input["field_sitetitle"] value to set the website's new title (usually set somewhere in the app's database).
<field id="sitetitle"> <get> <?php return /* return the website's title here */ ?> </get> <set> <?php /* set the website's title as $this->input["field_sitetitle"] here */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
get only
Must return the current version of the installed application.
<field id="version"> <get> <?php return /* find and return the application's version here */ ?> </get> </field>
Installatron also allows you to define your own fields. They are also added to the <fields>...</fields> definition, like their internal counterparts, and they typically look something like this:
<field {ID} {TYPE} {DEFAULT_VALUE}> <label>{LOCALE_TAG_1}</label> [<options> <option value="yes">{LOCALE_TAG_2}</option> <option value="no">{LOCALE_TAG_3}</option> </options>] <get> <?php return /* return the value for this field */ ?> </get> <set> <?php /* code to set this field using the Installatron $this->input["field_{ID}"] value */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
The <label>...</label> element is new here and it is simply the Bold Text that appears directly above this input when you are installing or editing the app (eg. like Administrator Email is the build-in label for the internal email field). We would always add a localisation tag and use that here, but you can also use straight text.
The <options>...</options> element is also new, but you only need that for certain {TYPE}s of fields so let's now have a close look at each custom field type:
When installing the app this let's you collect a text string from the user which you can use for any purpose.
Requires a default value (matching one of its options) and also requires <options>. Shouldn't need to verify the values here but you can add a <verify> element if you wish.
<field id="{ID}" type="radio" value="{DEFAULT_VALUE}"> <options> <option value="{VALUE1}">{LOCALE_TAG_2}</option> <option value="{VALUE2}">{LOCALE_TAG_3}</option> ... </options> <get> <?php return /* return the current value here */ ?> </get> <set> <?php /* use $this->input["field_{ID}"] here to do whatever you want this field to do */ ?> </set> </field>
When installing the app this let's you collect a text string from the user which you can use for any purpose.
Does not require a default value and does not use <options>.
<field id="{ID}" type="text" value=""> <get> <?php return /* return the current value here */ ?> </get> <set> <?php /* use $this->input["field_{ID}"] here to do whatever you want this field to do */ ?> </set> [<verify> <?php /* code code to verify that the user has entered a valid value */ ?> </verify>] </field>
todo...
The installer id is lowercase alphanumeric key that must be unique to the installer. Usually these are named after the application being installed, so for example the id for our own phpBB installer is phpbb, the WordPress installer is wordpress and so on.
The first of the two init.xml files that, together, really hold the important information and functionality of Installatron installers.
This init.xml, the installer init.xml as we refer to it, holds all the information that is specific to the installer or the application as a whole. The version-specific information goes in the version init.xml.
See The Installer init.xml for full details.
The default locale file. You can have as many translations as you wish to support. For example, a French translation would be locale_fr.php. Here is the format:
<?php itron::$locale = array_merge(itron::$locale,array( "_installer_installerid_title" => "app_name", "_installer_installerid_type" => "app_type", "_installer_installerid_category" => "app_category", "_installer_installerid_input_inputid_label" => "input_description", "_installer_installerid_input_inputid_text" => "short_input_description", "_installer_installerid_description" => "formal_description", "_installer_installerid_authordescription" => "author_description", )); ?>
installerid is the unique id of the installer.
app_name is the name of the application (eg. "My Application").
app_type is one of these: or any plain text.
app_category is one of these: or any plain text to create a new category of application.
inputid keys are only used if custom fields are used in the installer. inputid is the id of the input (see fields section below).
formal_description is a description of the application in an formal format. Look at the descriptions in Installatron to see the format used.
authors_description is a longer description of the application, usually quoted from the website of the application.
NOTE: you can also add your own locale keys, using the _installer_installerid_ prefix on any lines that you add.
Any number of screenshot images for the application in GIF, JPG, or PNG format. Most commonly sized at 1024x640.
There is one version/ directory for each version of the application that is supported by the package. If the package installs a single version, or does not support upgrading, then there will be a single version directory. The version should have no spaces, and should only use characters that can be used in a directory name.
The optional LICENSE file contains a plain-text version of the application's license agreement.
The second of the two init.xml files that, together, really hold the important information and functionality of Installatron installers.
This init.xml, the version init.xml as we refer to it, holds all the information that is specific this version of the installer or the application. The version-non-specific information goes in the installer init.xml.
See The Version init.xml for full details.
There are three ways to add your Installatron application package to your server. The three methods are:
Installatron's addon-installer system is the proper way to add an application package to Installatron.
To use the addon-installer system, you must use Application Installer Editor.
An addon-installer is comprised of two files: the first is a tar.gz archive containing the application package (this is created by the editor). The second file is a controller file which looks like this:
<installer> <id>installerid</id> <build>build_number</build> <url>url_to_installer</url> <installer>
installerid is the unique id of the installer.
build_number is the current build number of the installer. Increment this number whenever the installer is edited.
url_to_installer is a URL to the application package archive. The archive must be a gzip-compressed tar archive, and must be created using our Application Installer Editor tool.
Let's create an example application package with the id joomla.
When we're ready to test it we go to the Publisher tab and click the Publish button.
That will create an archive named joomla.tar.gz, which we download to our PC and then upload to a public web location somewhere. Let's upload it to http://my_domain/my_installers/joomla.tar.gz for this example.
Then we create this catalog file (or edit the one provided by Publisher) named joomla.xml:
<installer> <id>joomla</id> <build>1</build> <url>http://my_domain/my_installers/joomla.tar.gz</url> <installer>
Now we upload that catalog file to the same location as the application package, which will make it: http://my_domain/my_installers/joomla.xml
Then we load up Installatron, navigate to Administration > Applications > Catalogs, and add this URL as a new catalog:
<url>http://my_domain/my_installers/joomla.xml</url>
Save that, and finally we navigate to Administration > License & Logs and click run Installatron updater now.
That will add the joomla application package to Installatron. Installatron will check the joomla.xml file each time an update/repair is run to see if the build number has changed. If it has changed, it will download the installer again.
More information is provided on the Publisher page in the editor.
The wget shell command can be used to transfer application packages directly to the /var/installatron/installers directory. Details are provided on the Publisher tab in the editor.
This option is only available for PHP5 because PHP4 uses a different application package format, which must be created using the Publisher tool in the editor.
This approach is also good for quick development, but should only be used during development. Once an application package is finished, you should use method 1 above.
It's also possible to manually upload/make the files and directories directly in the /var/installatron/installers directory.
This option is only available for PHP5 because PHP4 uses a different installer format which is [i]required[/i] to be created using the Publisher tool in the editor.
If you are good with vim then this might be a quick way to edit and test your application package.
This section lists the variables and commands that can be used in application package installer and upgrader code, and some how-to explanations. See the Overview section for a closer look at the packaging format.
Custom fields defined in init.xml are used to collect information such as a password or email address that is then used to configure the install.
While most custom fields are bi-directional and have their own setter, all custom field values can be recalled in subsequent install methods (such as step2_process, etc.). For example:
$this->sr("config.php", "#'username'#", var_export($this->input['field_uname'],true)); $this->sr("config.php", "#'password'#", var_export(md5($this->input['field_passwd']),true)); $this->sr("config.php", "#'your@email.com'#", var_export($this->input['field_email'],true));
The values associated with the application's database. This requires that the "database" requirement is enabled.
These are; the hostname of the MySQL server, the database username, the username's password, the name of the database, the table prefix used by tables in the database, and finally, the type of database.
$this->db_host $this->db_user $this->db_pass $this->db_name $this->db_prefix $this->db_type // individual examples $this->sr("config.php", "#'localhost'#", $this->var_export($this->db_host)); $this->sr("config.php", "#'database_user'#", $this->var_export($this->db_user)); $this->sr("config.php", "#'database_password'#", $this->var_export($this->db_pass)); $this->sr("config.php", "#'database_username'#", $this->var_export($this->db_name)); $this->sr("config.php", "#'table_prefix'#", $this->var_export($this->db_prefix)); // or as a single edit $this->sr("config.php", array( "#'localhost'#" => $this->var_export($this->db_host), "#'database_user'#" => $this->var_export($this->db_user), "#'database_password'#" => $this->var_export($this->db_pass), "#'database_username'#" => $this->var_export($this->db_name), "#'table_prefix'#" => $this->var_export($this->db_prefix), ));
The location of the install as a local server path.
$this->path
// example
$this->sr("config.php", "#install_path#", $this->path);
The location of the install as a URL (webpage location).
$this->url
// example
$this->sr("config.php", "#install_url#", $this->url);
The hostname/domain portion of the URL, as retrieved from PHP's parse_url() function.
$this->url_domain // example $this->sr("config.php", "#'http://installdomain.com'#", $this->var_export($this->url_domain));
The path portion of the URL, as retrieved by PHP's parse_url() function.
$this->url_path
// example
$this->sr("config.php", "#'/install_dir'#", $this->var_export($this->url_path));
The current server time, as a UNIX time stamp.
$this->systime
Add an error message to a field, thus preventing the task from going forward until the error is resolved.
$this->addError("error_message", "field_fieldID");
// examples
<verify>
<?php
if( $this->input["field_login"] === "damn" ) {
$this->addError("Your username cannot be a swear word.", "field_login");
}
if( strlen($this->input["field_passwd"]) < 8 ) {
$this->addError("_errors_tooshort", "field_passwd");
}
if( ($this->input["field_mycustomradiofield"] < 0) || ($this->input["field_mycustomradiofield"] > 5) ) {
$this->addError("The Selected theme is out of range.", "field_mycustomradiofield");
}
?>
</verify>
Set Unix permissions for files or directories.
$this->chmod("file_or_directory", chmod_value [, diff_chmod_value_for_dirs = chmod_value [, recursive = false ]] );
// examples
$this->chmod("config.php", 0666);
$this->chmod("temp/uploads", 0777);
$this->chmod("data", 0666, 0777, true);
Set Unix owner and group for files or directories. Typically files are written with the correct ownership and do not need modification.
$this->chown("file_or_directory", user [, group [, recursive = false ]]);
// examples
$this->chown("config.php", "bob");
$this->chown("config.php", "bob", "apache");
$this->chown("temp/uploads", "bob", null, true);
Clears all Installatron errors that have been set prior to this command.
See also: $this->addError(), $this->hasErrors()
$this->clearErrors();
// example
$this->addError("An error has been set!");
$this->clearErrors();
if( $this->hasErrors() ) {
echo "There are no errors now!";
}
Copy files or directories.
$this->cp("source", "destination");
// examples
$this->cp("config-dist.php", "config.php");
$this->cp("inc/config.php", "admin/data.php");
todo...
See also: $this->enablePlugin(), $this->installPlugin()
$this->disablePlugin("todo...");
// examples
$this->disablePlugin("todo...");
$this->disablePlugin("todo...");
$this->disablePlugin("todo...");
todo...
See also: $this->disablePlugin(), $this->installPlugin()
$this->enablePlugin("todo...");
// examples
$this->enablePlugin("todo...");
$this->enablePlugin("todo...");
$this->enablePlugin("todo...");
Check if a file or directory exists.
[$result = ]$this->enablePlugin("file_or_directory_to_check");
// examples
$result = $this->exists("config.php");
if( $this->exists("admin/includes/version.php") ) {
/* do something */
}
Extract an archive. The archive must be registered in the version's init.xml file.
$this->extract("archive_id", "destination");
// examples
$this->extract("main", ".");
$this->extract("xtra1", "upgradetempdir");
$this->extract("chineselang", "plugins/locale");
Execute an external script via a HTTP call, usually to run an install or upgrade script. This is like loading the page in a web browser, however there is no visual output and no user interaction.
This function is at the core of most Installatron installers and upgraders.
[$result = ]$this->fetch("path_and_scriptname"[[[, array(post_key-value_pairs) ], array(header_key-value_pairs) ], false ]); // examples $this->fetch("install/install.php"); $result = $this->fetch("upgrade.php?step=2&language=en"); // a GET request $result = $this->fetch("upgrade.php", array( // a POST request "step" => "2", "language" => "en", )); $result = $this->fetch("upgrade.php", null, // no 2nd parameter so this will be a GET array( // use optional 3rd parameter to define header values 'header' => array( "Accept-Language: en", "Cookie: PHPSESSID=kb8jdh90jvp5setiq58b8mpfr5; key=abc123ABC", ))); $result = $this->fetch("upgrade.php", null, // no 2nd parameter so this will be a GET null, // no 3rd parameter so only default header included false // set optional 4th parameter false to make this fetch )); // non-fatal, in the case that the fetch fails
Check if any errors have been set prior to this command.
See also: $this->clearErrors(), $this->setError()
$this->hasErrors("{ERROR_MESSAGE}"[, "field_{FIELD_ID}" ]); // example 1 $this->addError("And error has been set!"); if( $this->hasErrors() ) { echo "There are errors!"; } // example 2 if( strlen($this->input['field_passwd']) < 8 ) { $this->addError("Error: administrator password is too short!", "field_passwd"); }
todo...
See also: $this->disablePlugin(), $this->enablePlugin()
$this->installPlugin("todo...", "todo..."); // examples $o->registerArchive('jetpack', 'http://downloads.wordpress.org/plugin/jetpack.zip', 'zip'); $o->installPlugin('jetpack/jetpack.php', 'jetpack');
Create a directory.
$this->mkdir("path_and_dirname");
// examples
$this->mkdir("temp");
$this->mkdir("tmp/upload");
Create a file.
$this->write("path_and_filename", "contents");
// examples
$this->write("config.php", "This is a config file.");
$this->write("inc/config.php", $myContents);
Move files or directories.
$this->mv("source"[, "destination" = "." ]); // examples $this->mv("config-dist.php", "config.php"); $this->mv("inc/config.php", "admin/data.php"); // "move everything to the install directory" examples $this->mv("script-1.5.2/*"); $this->mv("script-1.5.2/upload/*");
Get the contents of a file.
$contents = $this->read("path_and_filename"[, "preg_filter", "preg_filter_capture" ]); // example $contents = $this->read("config.php"); // use a REGEX search to read ONLY the value of a $wp_version variable found in the file $version = $this->read("config.php", "#wp_version\s*=\s*(['\"])(.+?)\\1;#", 2); // 2nd capture starts here ---^ ^--- we want the contents of the 2nd capture
Set ownership of file(s) and directory(s) to the current user.
NOTE: If a directory is selected then this function is automatically recurrent; all files and directories under the chosen directory will also be reclaimed.
$this->_reclaim("path_and_filename"); // examples $this->_reclaim("config.php"); // just this one file $this->_reclaim("wp-content"); // this is a directory so this is automatically recurrent! $this->_reclaim("wp-content/tmp/*"); // globbing works
Pro tip: be aware that this function name begins with the underscore ("_").
Remove (delete) files or directories.
$this->rm("path_and_target");
// examples
$this->rm("install");
$this->rm("*.php");
$this->rm("temp/*");
Edit a file using PHP REGEX search and replace.
$this->sr("path_and_file", "#regex_search#", "replace_value"); $this->sr("path_and_file", array( "#regex_search_1#" => "replace_value_1", "#regex_search_2#" => "replace_value_2", "...", )); // examples $this->sr("config.php", "#false#", "true"); $this->sr("config.php", "#\$installed\s+=\s+'0'#", "$installed = '1'"); $this->sr("config.php", "#(\$installed\s+=\s+')0'#", '${1}0\''); $this->sr("data.php", "#(// SET THESE VALUES)#", "$newContent\n\n$1"); // edit config file with database values example $this->sr("config.php", array( '#(\$hostname\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_host), '#(\$database_name\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_name), '#(\$database_username\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_user), '#(\$database_password\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_pass), '#(\$table_prefix\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_prefix) )); // custom input fields examples $this->sr("install/mysql.sql", "#administrator#", $this->db_escape($this->input['field_username'])); $this->sr("install/mysql.sql", "#548dfjfsd998dfs9kd#", md5($this->input['field_passwd'])); $this->sr("install/mysql.sql", "#your@email.com#", addslashes($this->input['field_email']));
Sets an error, telling Installatron that this task has failed.
See also: $this->clearErrors(), $this->hasErrors()
$this->setError();
// example
if ( strpos($r, "Installation failed") !== false ) {
$this->addError("And error has been set!");
$this->write(".htinstall.txt", $r);
return;
}
Escape a value before using it with database commands, to prevent SQL injections.
$this->db_escape("text");
// example
$escaped_websitename = $this->db_escape($this->field['field_sitename']);
Import/execute a .sql script. This requires that the "database" requirement is enabled.
$this->db_import("path_and_file"[, ???, array(regex_edit_key-value_pairs ]);
// examples
$this->db_import("mysql.sql");
$this->db_import("install/db/populate.sql");
$this->db_import("upgrade/45_to_46.sql");
$this->db_import("upgrade/45_to_46.sql", ???, array( ??? ));
$this->db_import("upgrade/45_to_46.sql", null, array( ??? ) );
Execute a MySQL statement. This requires that the "database" requirement is enabled.
If an array of binded_variables are included, each will replace a corresponding question mark placeholder in the SQL statement.
If select_this is included this method will return the named SELECT value.
$this->db_query("sql_statement" [, binded_variables [, "return_this" ]]); // examples $this->db_query("INSERT INTO {$this->db_prefix}_config (name, age) VALUES('Bob', '20' )"); // examples of the 2nd parameter: binded_variables $this->db_query("UPDATE {$this->db_prefix}users SET username=? WHERE userid='0'", array( "admin" )); $this->db_query("UPDATE {$this->db_prefix}users SET username=? WHERE userid=?", array( "admin", "0" )); // examples of the 3rd parameter: return_this $login = $this->db_query("SELECT login FROM users WHERE ID=?", array("1"), "login"); $login = $this->db_query("SELECT login FROM users WHERE ID='1'", null, "login");
Export a variable to be written to a PHP source file.
$this->var_export("value");
// examples
$ready_to_be_written_to_a_phpfile = $this->var_export($this->path);
This table lists Installatron's Language Identifier for most languages that are in use today (used for the XML <languages> tag). If support is required for a language that is not listed, please contact us.
(the language identifier table is hidden) |
You might have noticed in the entry for Fetch and Search-Replace above that an array() could be optionally provided in order to perform the same task multiple times. The ability to provide an array is available in many of the functions and in many combinations. Here is a dump of ways that array() can be used in the above functions.
// array() in chmod $this->chmod(array( "config.php", "data/level.inc", "..." ), 0644); // array() in chown $this->chown(array( "uploads", "temp", "..." ), "apache", null, true); // array() in mkdir $this->mkdir(array( "cache", "images/upload", "tmp", "..." )); // array() in _reclaim $this->_reclaim(array( "plugins/myPlugin/plugin.php", "plugins/myPlugin/plugin.xml", "..." )); // array() in rm $this->rm(array( "one.php", "temp/two", "admin/advanced/*.inc", "..." )); // array() in sr 1: multiple edits to one file $this->sr("config.php", array( '#(\$hostname\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_host), '#(\$database_name\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_name), '#(\$database_username\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_user), '#(\$database_password\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_pass), '#(\$table_prefix\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_prefix), )); // array() in sr 2: single edit to multiple files $this->sr( array( "config.php", "settings.php" ), '#(\$hostname\s+=\s+)\'.*?\'#', "$1".$this->var_export($this->db_host) ); // array() in sr 3: multiple edits to multiple files $this->sr( array( "config.php", "settings.php", ), array( '#(\$hostname\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_host), '#(\$database_name\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_name), '#(\$database_username\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_user), '#(\$database_password\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_pass), '#(\$table_prefix\s+=\s+)\'.*?\'#' => "$1".$this->var_export($this->db_prefix), ) );
If your application package isn't displaying or installing, the first place to check is the Installatron logs. These can be viewed from Administration, or if you need to see more than just the last few lines you can find them here:
/var/installatron/logs
The filesystem_log is usually the most useful as it logs the result of every $this-> command. The fetch_log logs the result of every call to a URL, so that includes all control panel API calls, all downloads, and all $this->fetch() commands.
Browse below for some of the more common application package problems and their fixes.
Installatron failed to download the 'main' archive.
The causes are usually either a) the archive is not at a publically accessible location, or b) the MD5 checksum is wrong.
Make sure that the URL to the archive can be downloaded with a wget command from the server. If wget can get the file then Installatron can too.
The MD5 checksum, used to verify that the archive has downloaded correctly, is not shown in the Editor GUI at this time so to fix it you need to:
If the application package is listed in Administration > Access Groups > Edit but is not showing in the Application Browser then the cause is usually requirement filtering.
Check the requirements you have configured for the script (Editor > Version Info > Requirements) and compare them with the Administration > Applications > Dependencies configuration in Installatron.