<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.x2crm.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Derek+Mueller</id>
		<title>X2Engine - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.x2crm.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Derek+Mueller"/>
		<link rel="alternate" type="text/html" href="http://wiki.x2crm.com/wiki/Special:Contributions/Derek_Mueller"/>
		<updated>2026-05-20T19:35:59Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.28.0</generator>

	<entry>
		<id>http://wiki.x2crm.com/index.php?title=Installation&amp;diff=1948</id>
		<title>Installation</title>
		<link rel="alternate" type="text/html" href="http://wiki.x2crm.com/index.php?title=Installation&amp;diff=1948"/>
				<updated>2016-02-04T20:40:26Z</updated>
		
		<summary type="html">&lt;p&gt;Derek Mueller: /* System Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Support]]&lt;br /&gt;
This article covers manual installation of X2Engine on a webserver. If this is your first time working with a web server, it is recommended that you first try installing via an automatic full-stack installer that will set up a self-contained web server environment for you. See [http://bitnami.org/stack/X2CRM Bitnami's X2Engine stack installers] for download links.&lt;br /&gt;
&lt;br /&gt;
= Before Installation =&lt;br /&gt;
Before installing X2Engine, you should first ensure that&lt;br /&gt;
* You have a web server&lt;br /&gt;
* You understand the basics of installing a PHP web application&lt;br /&gt;
* Your hosting environment is properly configured and meets all the minimum requirements&lt;br /&gt;
&lt;br /&gt;
== Required Knowledge ==&lt;br /&gt;
Installing X2Engine requires you are able to perform the following taks (and have basic knowledge of how to perform them):&lt;br /&gt;
# Upload files to a web server via a hosting file manager, FTP/SFTP, or otherwise&lt;br /&gt;
# Creating a MySQL database and a database user, if they aren't available already&lt;br /&gt;
# Using a web browser, and knowing what URL to use to access a location on the server&lt;br /&gt;
&lt;br /&gt;
If you are unsure of how to perform any of these, please ask for assistance on [http://x2community.com The X2Engine Forums].&lt;br /&gt;
&lt;br /&gt;
== System Requirements ==&lt;br /&gt;
You can quickly determine if your web server can run X2Engine by downloading the requirements checking script (link: [[requirements:|requirements.php]]), uploading it to your web server, and opening it in a web browser. When finished using the script, delete it; it displays detailed information about the server's PHP configuration. Displaying it publicly for indefinite time can pose a security risk; it could be useful to attackers. In general, the following are the absolute minimum requirements for installation:&lt;br /&gt;
&lt;br /&gt;
* A web server that can execute PHP.&lt;br /&gt;
* A password-protected '''MySQL''' database server connection, and a database on which the user of the connection has all rights (i.e. select, drop, create and update).&lt;br /&gt;
* '''PHP version 5.3-5.6 (PHP 7 support will be introduced in X2CRM 5.4.4)'''&lt;br /&gt;
* PHP must be run as the same system user that owns the directory where X2Engine will be installed.&lt;br /&gt;
&lt;br /&gt;
== If Requirements Are Not Met ==&lt;br /&gt;
=== Directory Ownership ===&lt;br /&gt;
If you are running a dedicated web server and/or have administrative access, please refer to [[Preparing_a_Linux_Server_Environment#Server_Preparation|Preparing a Webserver]].&lt;br /&gt;
&lt;br /&gt;
This is a hosting environment misconfiguration wherein files uploaded to the server are owned by a different system user than the user as whom PHP executes. It is an ease-of-use issue that many shared hosting providers still haven't gotten right. It can in most cases be resolved by changing the PHP gateway interface, i.e. from SuPHP to FCGI, using your hosting control panel ('''To correct this issue in CPanel''': see [http://docs.cpanel.net/twiki/bin/vief/EasyApache3/ApachePHPRequestHandling Apache PHP Request Handling]).&lt;br /&gt;
&lt;br /&gt;
You should also use a method of uploading files to the server that results in them having the same ownership as the &amp;quot;domain owner&amp;quot; (this terminology is used by most shared hosting providers). FTP services have been known to fail in this regard, whereas web-based file managers available in hosting control panels are often much more consistent. Uploading files with proper ownership will completely circumvent file permission and ownership issues.&lt;br /&gt;
&lt;br /&gt;
In any case, refer to your hosting provider's documentation. If the option to change the PHP execution mode does not appear to be available, contact the system administrator or customer service department of the hosting provider. If they don't give you a satisfactory answer, consider switching to a better web host. &amp;lt;ref&amp;gt;In a discussion on our forums, [http://x2community.com/topic/703-hosting-that-works/ &amp;quot;Hosting that works&amp;quot;], some users propose or advocate web hosts that they have had experiences with. A general consensus on GoDaddy (and our own professional opinion, based on repeated bad experiences) is that it is a very poor choice for hosting X2Engine.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP Version ===&lt;br /&gt;
In some cases, it may be possible to enable PHP 5.3+ using an [http://httpd.apache.org/docs/2.2/howto/htaccess.html Apache override]; see &lt;br /&gt;
* [http://www.velvetblues.com/web-development-blog/activate-php-5-3-hostgator-godaddy/ Velvet Blues: How to Activate PHP 5.3 on HostGator and GoDaddy]&lt;br /&gt;
* [http://kb.siteground.com/article/How_to_have_different_Php__MySQL_versions.html SiteGround knowledge base: How to switch to a different PHP version]&lt;br /&gt;
By adding the appropriate directives to the &amp;lt;tt&amp;gt;.htaccess&amp;lt;/tt&amp;gt; file in the web root of X2Engine (NOT replacing the file, but changing it), the PHP version can ideally be set. You can test whether this method succeeds by re-visiting the requirements checker script and verifying that the PHP version in use is 5.3 or later.&lt;br /&gt;
&lt;br /&gt;
In other cases, it may be possible to enable later versions of PHP via the web hosting control interface (i.e. CPanel or Webmin). Otherwise, the only option will be to contact the hosting provider and request that version 5.3 be made available.&lt;br /&gt;
&lt;br /&gt;
=== PHP Extensions ===&lt;br /&gt;
If your server does not meet the minimum system requirements for running X2Engine, and you are a system administrator of your server, you will be able to install the necessary modules. Note, however, that as of the most recent version, the MySQL PDO extension is the only extension used by X2Engine that isn't included by default and always enabled in PHP 5.3; the reflection class and extensions SPL, PCRE and Ctype should all be available if PHP is at version 5.3 or later.&lt;br /&gt;
&lt;br /&gt;
In most distributions of Linux, PHP extensions can be easily installed by the distribution's default [[wikipedia:Package management system|Package management system]]. That is the recommended method of installing them; in most cases, the package manager will automatically configure and reload the HTTP server to enable them.&lt;br /&gt;
&lt;br /&gt;
On Ubuntu &amp;amp;amp; Debian: the extension &amp;lt;tt&amp;gt;mbstring&amp;lt;/tt&amp;gt; will typically be included in the Apache module package.&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo apt-get install php5-mysql php5-curl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On CentOS (6+), the mbstring extension must be installed separately with other missing modules:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo yum install php-pdo php-mbstring php-common curl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing Without All Requirements: What Won't Work ==&lt;br /&gt;
'''This section is obsolete as of 3/26/2013.''' The severity of each missing requirement, in addition to explanation of what functionality will be unavailable/broken for each missing requirement, has been written directly into the requirements check script and should be displayed there. Thus, it is no longer necessary to list them here, although the list as it was last maintained is left here for archival/demonstrative purposes.&lt;br /&gt;
&lt;br /&gt;
If your server environment does not meet the minimum system requirements, and it is not possible to add PHP extensions, you can still install X2Engine, though it is '''not''' recommended. Note the following issues that can occur:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; align=&amp;quot;left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Deficiency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Severity&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Problems/Notes&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | IMAP extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow&amp;quot;&amp;gt;Minor&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
The email manager depends on the IMAP extension.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | Zip extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow&amp;quot;&amp;gt;Minor&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Cannot import or export custom modules.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | cURL extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:yellow&amp;quot;&amp;gt;Minor&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
* Google integration will not work&lt;br /&gt;
* Time zone widget will not work&lt;br /&gt;
* Contact views may be inaccessible &amp;lt;ref&amp;gt;[http://x2community.com/index.php?/topic/386-cant-open-contact-view/ X2Community Forums: &amp;quot;Can't open contact View&amp;quot;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Cannot use local scripts that make API calls&lt;br /&gt;
* Cannot use built-in error reporter&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | allow_url_fopen set to &amp;quot;No&amp;quot;/0 in PHP configuration&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:orange&amp;quot;&amp;gt;Major&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Cannot receive software updates using the built-in update utility, and cannot receive notifications of new software versions from within the app.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | Directory ownership mismatch&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:orange&amp;quot;&amp;gt;Major&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Application cannot be updated and cannot run unless the permissions on all files and directories are set to allow any system user to read/write &amp;lt;strong&amp;gt;(not recommended)&amp;lt;/strong&amp;gt;. The application uses file-based caching and also creates files and folders during software updates, both of which require write access to the filesystem.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | json extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:orange&amp;quot;&amp;gt;Major&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Numerous components and features will not work; the json_encode function is used throughout the application&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | PHP version earlier than 5.3&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:red; color:white; font-weight:bold;&amp;quot;&amp;gt;Fatal&amp;lt;/span&amp;gt;&lt;br /&gt;
|Numerous fatal errors, including errors that inhibit installation&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | mbstring extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:red; color:white; font-weight:bold;&amp;quot;&amp;gt;Fatal&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Application crashes upon login with &amp;quot;invalid unicode sequence&amp;quot; error.&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | pdo_mysql extension missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:red; color:white; font-weight:bold;&amp;quot;&amp;gt;Fatal&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Application cannot run; no database connection is possible. It is a requirement of [http://www.yiiframework.com/ Yii Framework].&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | Any other PHP extensions listed as required but missing&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:red; color:white; font-weight:bold;&amp;quot;&amp;gt;Fatal&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Application cannot run (requirements of Yii)&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | Outdated PCRE library version&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color:red; color:white; font-weight:bold;&amp;quot;&amp;gt;Fatal&amp;lt;/span&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
Application cannot run. Regex used in URL rules requires the &amp;quot;?J&amp;quot; group type, which was added to PCRE in version 7.4 (September 21, 2007)&amp;lt;ref&amp;gt;[http://www.pcre.org/changelog.txt PCRE Changelog]&amp;lt;/ref&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Recommended System ==&lt;br /&gt;
The following attributes of the hosting environment are by no means required. However, they are the same as the primary servers on which X2Engine is most commonly developed and tested, and thus would be the most likely to never cause problems:&lt;br /&gt;
* PHP 5.3.10 and later&lt;br /&gt;
* MySQL 5.5&lt;br /&gt;
* Apache 2.2 with [http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html mod_rewrite] enabled. &lt;br /&gt;
* Ubuntu 12.04 LTS, CentOS 6.3, or Amazon Linux&lt;br /&gt;
&lt;br /&gt;
If only Windows is available, the environment provided by [http://www.wampserver.com/ WampServer] is recommended, especially for development.&lt;br /&gt;
&lt;br /&gt;
= Installing =&lt;br /&gt;
== Using The Installation Page ==&lt;br /&gt;
Browser-based installation generally proceeds as follows:&lt;br /&gt;
# Make sure a MySQL database and a database user with full permissions to that database are available from the web server.&lt;br /&gt;
# Upload the contents of the &amp;lt;tt&amp;gt;x2engine&amp;lt;/tt&amp;gt; folder to the document root of the web server, or a subdirectory if desired.&lt;br /&gt;
# Navigate to the webroot (or subdirectory) where the contents of the folder were uploaded.&lt;br /&gt;
# Fill out the installation form. '''Note the following:'''&lt;br /&gt;
#* If you leave &amp;quot;Create Sample Data&amp;quot; checked, the installer will insert fictitious contact, user, account and action records into the initial installation for testing purposes. Uncheck the box if this is not desired.&lt;br /&gt;
#* You can first test the database connection without losing the installation form by using the &amp;quot;Test Connection&amp;quot; button. Doing this before clicking the install button is highly recommended.&lt;br /&gt;
&lt;br /&gt;
== Using The Command Line Installer == &lt;br /&gt;
It is possible to install X2Engine from the command line via SSH or otherwise. This is performed as follows:&lt;br /&gt;
# There is a script in the root of the web application named &amp;lt;tt&amp;gt;installConfig.php&amp;lt;/tt&amp;gt;. Fill it with the same information that would be submitted by the installation page form. If you are installing a commercial edition of X2Engine, fill the variable &amp;lt;tt&amp;gt;$unique_id&amp;lt;/tt&amp;gt; with your product key.&lt;br /&gt;
# Change directory into the root folder of the web application.&lt;br /&gt;
# Run: &amp;lt;pre&amp;gt;php initialize.php silent&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The configuration variables in &amp;lt;tt&amp;gt;installConfig.php&amp;lt;/tt&amp;gt; are as follows:&lt;br /&gt;
;host&lt;br /&gt;
: The (MySQL) database hostname&lt;br /&gt;
;db&lt;br /&gt;
: The database name&lt;br /&gt;
;user&lt;br /&gt;
: The database username&lt;br /&gt;
;pass&lt;br /&gt;
: The database password&lt;br /&gt;
;app&lt;br /&gt;
: The application name (i.e. &amp;quot;Company X CRM&amp;quot;) that shows up in various places throughout the app.&lt;br /&gt;
;currency&lt;br /&gt;
: The 3-letter code for the currency to be used in quotes and opportunities. Currently supported currencies include: USD,EUR,GBP,CAD,JPY,CNY,CHF,INR, and BRL.&lt;br /&gt;
;lang&lt;br /&gt;
: The application's language.&lt;br /&gt;
;timezone&lt;br /&gt;
: The time zone. It must be a valid timezone alias; see [http://php.net/manual/en/timezones.php List of supported time zones] for more info.&lt;br /&gt;
;adminEmail&lt;br /&gt;
: The email address of the application's owner&lt;br /&gt;
;adminPassword&lt;br /&gt;
: The administrator's application password&lt;br /&gt;
;adminUsername&lt;br /&gt;
: The username of the administrator&lt;br /&gt;
;dummyData&lt;br /&gt;
: Whether to include sample data in the installation, for evaluative purposes&lt;br /&gt;
;webLeadUrl&lt;br /&gt;
: The base URL of the web application.&lt;br /&gt;
;unique_id&lt;br /&gt;
: The product key, if installing a commercial edition. In Open Source Edition, it can simply be left &amp;quot;none&amp;quot;. If it is &amp;quot;none&amp;quot; in Open Source Edition, the user will need to enable software updates separately by going to &amp;quot;Updater Settings&amp;quot; in the administrative index, in the &amp;quot;System Settings&amp;quot; section.&lt;br /&gt;
;visibleModules&lt;br /&gt;
: Initial module visibility setting; a comma-delineated list of modules to be displayed in the menu at the top of the CRM.&lt;br /&gt;
;test_db&lt;br /&gt;
: Set this to 1 if constructing a unit/functional testing environment (see [[Test-Driven_Development#Preparing_a_testing_database|Test-driven Development: preparing a testing database]])&lt;br /&gt;
;test_url&lt;br /&gt;
: If installing a testing environment, the URL to the &amp;quot;index-test.php&amp;quot; entry script that web tests will use.&lt;br /&gt;
;installType&lt;br /&gt;
: Installation type to report to the updates server. This is a setting that is used for internal reporting/statistical purposes and should be left as-is.&lt;br /&gt;
&lt;br /&gt;
= Miscellaneous Post-Installation Tasks =&lt;br /&gt;
== Configuring the &amp;quot;Email Dropbox&amp;quot; ==&lt;br /&gt;
This section has been moved to the article: &amp;quot;[[E-Mail Configuration]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Derek Mueller</name></author>	</entry>

	<entry>
		<id>http://wiki.x2crm.com/index.php?title=MediaWiki:Sitenotice&amp;diff=1937</id>
		<title>MediaWiki:Sitenotice</title>
		<link rel="alternate" type="text/html" href="http://wiki.x2crm.com/index.php?title=MediaWiki:Sitenotice&amp;diff=1937"/>
				<updated>2015-09-16T02:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;Derek Mueller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;amp;copy; 2015 [http://www.x2engine.com X2Engine Inc.]&lt;/div&gt;</summary>
		<author><name>Derek Mueller</name></author>	</entry>

	<entry>
		<id>http://wiki.x2crm.com/index.php?title=Preparing_a_Linux_Server_Environment&amp;diff=1935</id>
		<title>Preparing a Linux Server Environment</title>
		<link rel="alternate" type="text/html" href="http://wiki.x2crm.com/index.php?title=Preparing_a_Linux_Server_Environment&amp;diff=1935"/>
				<updated>2015-06-23T01:49:52Z</updated>
		
		<summary type="html">&lt;p&gt;Derek Mueller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Support]]&lt;br /&gt;
&lt;br /&gt;
This aims to be a generic guide for manually preparing a Linux-based web server, which applies both to physical servers and virtual servers, i.e. Amazon EC2 instances. It will cover two main families of Linux distributions: RHEL (Red Hat Enterprise Linux) based and Debian-based. RHEL-based distributions include, most notably: CentOS, Oracle Linux and Amazon Linux. Debian-based distributions include the popular Ubuntu and Ubuntu derivatives, as well as Linux Mint, Knopper Linux and many others&amp;lt;ref&amp;gt;See: [http://wiki.debian.org/Derivatives/Census|the Debian Derivatives Census]&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
It will be assumed in this guide, unless otherwise noted: &lt;br /&gt;
* Command line operations are being performed as the root user&lt;br /&gt;
* Names enclosed in angle brackets (&amp;amp;lt; &amp;amp;gt;) are intended as placeholders for actual input and should not be used verbatim&lt;br /&gt;
* The server is ''dedicated,'' i.e. will be used mainly for X2CRM on a single domain name, and will not be set up with multiple virtual hosts.&lt;br /&gt;
* The Linux system's ''[http://en.wikipedia.org/wiki/Package_manager software package manager]'' has been configured properly&lt;br /&gt;
* Software will be installed using pre-built packages available through the particular distribution's software package repositories.&lt;br /&gt;
* A distribution of Linux based on Red Hat Enterprise Linux or Debian is in use.&lt;br /&gt;
&lt;br /&gt;
'''When installing packages, note:''' there may be slight differences in the names of software packages between distributions of Linux. Thus, in cases where a package name copied verbatim from this guide does not exist, the package manager's ''search'' utility should be used to determine the proper package name.&lt;br /&gt;
&lt;br /&gt;
The command for searching for packages by name is as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-cache search &amp;lt;package name&amp;gt; # (Debian-like)&lt;br /&gt;
yum search &amp;lt;package name&amp;gt; # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
In each case, use parts of the full name to increase the likelihood of getting search results. Note that Debian's &amp;lt;tt&amp;gt;apt-cache search&amp;lt;/tt&amp;gt; utility will accept regular expressions (if quoted properly). To search for packages on RHEL-based systems with regular expressions, search results from &amp;lt;tt&amp;gt;yum&amp;lt;/tt&amp;gt; can be simply piped to grep:&lt;br /&gt;
&amp;lt;pre&amp;gt;yum search &amp;lt;package name&amp;gt; | grep &amp;lt;package regex&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Installing the Web Server =&lt;br /&gt;
== Acquiring Software Packages ==&lt;br /&gt;
To begin, refresh the software package database:&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get update # (Debian-like)&lt;br /&gt;
yum update # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
There may also be software updates. If any are available, &amp;lt;tt&amp;gt;yum&amp;lt;/tt&amp;gt; will download prompt you if you want to install them. Debian's apt, on the other hand, only updates the package databases. To install software updates, if any are available, run &amp;lt;tt&amp;gt;apt-get upgrade&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Next install Apache, PHP and MySQL. '''Debian-based systems''' should have a utility called &amp;quot;tasksel&amp;quot; that can begin installation of all the necessary packages for a LAMP (Linux, Apache, MySQL &amp;amp; PHP) server in one command:&lt;br /&gt;
&amp;lt;pre&amp;gt;tasksel install lamp-server&amp;lt;/pre&amp;gt;&lt;br /&gt;
However, this task usually does not include the package for the PHP cURL extension, so it must be installed separately via &amp;lt;pre&amp;gt;apt-get install php5-curl&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On '''RHEL-based systems:''' run&lt;br /&gt;
&amp;lt;pre&amp;gt;yum install mysql mysql-server php-mysql php httpd php-mbstring php-curl&amp;lt;/pre&amp;gt;&lt;br /&gt;
''On many RHEL-based systems,'' PHP will be built without POSIX support (the compile flag '--disable-posix' should appear in the &amp;quot;Configure Command&amp;quot; section of &amp;lt;tt&amp;gt;phpinfo()&amp;lt;/tt&amp;gt; ). Thus, the requirements checker script will not display the proper warning when the apache UID doesn't match the ownership of the web document root. Although it is not necessary (the next steps will ensure that this requirement is met anyway), the POSIX extension can be added if desired by installing the package &amp;lt;tt&amp;gt;php-process&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;php-posix&amp;lt;/tt&amp;gt; (depending on the distribution and release version).&lt;br /&gt;
&lt;br /&gt;
There are two more optional but useful PHP extensions: APC (caching extension) and Suhosin (PHP security). These packages should be available in most Debian-based distributions and can be installed via &amp;lt;tt&amp;gt;apt-get install php5-suhosin php-apc&amp;lt;/tt&amp;gt;. In CentOS, they can be acquired by enabling the EPEL software repository &amp;lt;ref&amp;gt;[http://www.cyberciti.biz/faq/fedora-sl-centos-redhat6-enable-epel-repo/ CentOS / RHEL / Scientific Linux 6 Enable (Install) EPEL Repo]&amp;lt;/ref&amp;gt; and then running &amp;lt;tt&amp;gt;yum install php-suhosin php-pecl-apc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Starting the Server ==&lt;br /&gt;
To start the server, run:&lt;br /&gt;
&amp;lt;pre&amp;gt;service apache2 start # (Debian-like)&lt;br /&gt;
service httpd start # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
Navigate to the server with a web browser to verify that the web server is running and responding to requests on its IP address / fully-qualified domain name.&lt;br /&gt;
&lt;br /&gt;
== Assigning a Domain Name ==&lt;br /&gt;
Due to the great diversity of DNS services and tools, the exact procedure for associating a domain name with the web server is beyond the scope of this guide. However, the most important facts are:&lt;br /&gt;
* To direct a domain name to an IP address, use the &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; type DNS record.&lt;br /&gt;
* To direct a domain name to another domain name, use the &amp;lt;tt&amp;gt;CNAME&amp;lt;/tt&amp;gt; type DNS record. &lt;br /&gt;
For instance, given the hostname of an Amazon Web Services EC2 instance, one would associate a domain name with it via a &amp;lt;TT&amp;gt;CNAME&amp;lt;/tt&amp;gt; record (to ensure proper resolution).&lt;br /&gt;
&lt;br /&gt;
= Server Preparation =&lt;br /&gt;
The default [http://httpd.apache.org/docs/current/mod/core.html#documentroot DocumentRoot] of Apache Webserver on most distributions of Linux will be owned by the &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; user immediately after installation, whereas its default [http://httpd.apache.org/docs/current/mod/mod_unixd.html#user User] and [http://httpd.apache.org/docs/current/mod/mod_unixd.html#group Group] will be set to &amp;quot;www-data&amp;quot; (Debian) or &amp;quot;apache&amp;quot; (RHEL). This configuration makes it so that no web application whatsoever will have write permissions to the directory it runs in (which is problematic). Thus, the first step of preparation once the server has been installed and started is to ensure the ownership of the files and Apache process are the same.&lt;br /&gt;
&lt;br /&gt;
== Determining the DocumentRoot ==&lt;br /&gt;
This is a rather important aspect of a web server is where the files to be served are stored in the local filesystem, and will be necessary in the next steps of this process. To obtain it, search for the DocumentRoot directive in the configuration as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;grep -r '^ DocumentRoot' /etc/apache2/ # (Debian-like)&lt;br /&gt;
grep -r '^ DocumentRoot' /etc/httpd/ # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
In most cases, the directive will be set to &amp;lt;tt&amp;gt;/var/www&amp;lt;/tt&amp;gt; on Debian-based distributions and &amp;lt;tt&amp;gt;/var/www/html&amp;lt;/tt&amp;gt; on RHEL-based ones.&lt;br /&gt;
&lt;br /&gt;
== Determining the Apache User/Group ==&lt;br /&gt;
On Debian-based systems, these directives are typically set to &amp;quot;www-data&amp;quot;, and on RHEL-based systems, to &amp;quot;apache&amp;quot;. However, if in doubt, there are at least three methods of finding out the values to which the User/Group directives set.&lt;br /&gt;
&lt;br /&gt;
=== Direct Method ===&lt;br /&gt;
The most reliable way of finding out what they are is by searching the configuration files for the directives:&lt;br /&gt;
&amp;lt;pre&amp;gt;grep -r '^ *\(User\|Group\)' /etc/apache2/ # (Debian-like)&lt;br /&gt;
grep -r '^ *\(User\|Group\)' /etc/httpd/ # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that on Debian-based systems you may see that, in place of literal strings, there are references to environment variables, i.e. &amp;lt;tt&amp;gt;${APACHE_RUN_USER}&amp;lt;/tt&amp;gt;. To find their actual values, search for them in the same manner:&lt;br /&gt;
&amp;lt;pre&amp;gt;grep -r '^ *export *APACHE_RUN_' /etc/apache2/&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using ps ===&lt;br /&gt;
One can search for the process and see its user, if Apache is already running, using &amp;lt;tt&amp;gt;ps&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;ps aux | grep '\(apache\|httpd\)'&amp;lt;/pre&amp;gt;&lt;br /&gt;
The first column of output should be the user name or id of the running process, whereas the last should be the executable file of the process. Locate the web server process (the path to the executable should be something like &amp;lt;tt&amp;gt;/usr/sbin/apache2&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;/usr/sbin/httpd&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
=== Using PHP's POSIX Library ===&lt;br /&gt;
If the POSIX library is available in PHP, you can find the UID by creating a PHP script in the [http://httpd.apache.org/docs/current/mod/core.html#documentroot DocumentRoot] with the following contents and opening it in a web browser:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php &lt;br /&gt;
echo 'UID (Server): '.posix_geteuid().'&amp;lt;br&amp;gt;';&lt;br /&gt;
echo 'UID (Directory owner): '.fileowner(realpath(dirname(__FILE__)));&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If the web server is properly set up, both of the numbers displayed should be equal.&lt;br /&gt;
&lt;br /&gt;
== Changing DocumentRoot Ownership ==&lt;br /&gt;
Once the UID of the webserver has been determined, change the ownership of the public web directory as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;chown -R &amp;lt;user&amp;gt;:&amp;lt;group&amp;gt; &amp;lt;DocumentRoot&amp;gt; # (Debian-like)&lt;br /&gt;
chown -R &amp;lt;user&amp;gt;:&amp;lt;group&amp;gt; &amp;lt;DocumentRoot&amp;gt; # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
Use the user name or ID of the running webserver process in place of &amp;lt;tt&amp;gt;&amp;amp;lt;user&amp;amp;gt;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;&amp;amp;lt;group&amp;amp;gt;&amp;lt;/tt&amp;gt;, and the server's DocumentRoot  in place of &amp;lt;tt&amp;gt;&amp;amp;lt;DocumentRoot&amp;amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Testing the Webserver ==&lt;br /&gt;
When done, download the requirements checking script: &lt;br /&gt;
&amp;lt;pre&amp;gt;cd &amp;lt;DocumentRoot&amp;gt;&lt;br /&gt;
wget http://x2planet.com/installs/download/requirements.php&lt;br /&gt;
chown &amp;lt;apache user&amp;gt;:&amp;lt;apache user&amp;gt; requirements.php&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, open the file in a web browser to verify that the system meets all of the requirements. Note that, if you see no &amp;quot;posix&amp;quot; section in the phpinfo() output and the flag &amp;quot;--disable-posix&amp;quot; appears in the configure command, and you skipped [[#Changing DocumentRoot Ownership|changing ownership]], the results of the requirements check will not be accurate.&lt;br /&gt;
&lt;br /&gt;
= Preparing a Database =&lt;br /&gt;
X2CRM needs a MySQL database for storing persistent data. To prepare this final requirement, you will first need to start the MySQL server daemon:&lt;br /&gt;
&amp;lt;pre&amp;gt;service mysql start # (Debian-like)&lt;br /&gt;
service mysqld start # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, log into the database server as the database administrator (typically root).&lt;br /&gt;
&amp;lt;pre&amp;gt;mysql -u root -p&amp;lt;/pre&amp;gt;&lt;br /&gt;
You may have to enter a password. On Debian systems, during the installation of the MySQL server, you should have been prompted for a root password, and thus you will need to use it for logging in. On Amazon Linux and some other RHEL derivatives, the root password won't be set, and so you can log in without the &amp;lt;tt&amp;gt;-p&amp;lt;/tt&amp;gt; flag.&lt;br /&gt;
&lt;br /&gt;
Once you have logged in, create the database, and create a non-admin user with full access to it. The database name &amp;quot;x2crm&amp;quot; and user name &amp;quot;x2crmuser&amp;quot; will be used in this example.&lt;br /&gt;
&amp;lt;pre&amp;gt;mysql&amp;gt; CREATE DATABASE x2crm;&lt;br /&gt;
Query OK, 1 row affected (0.00 sec)&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt; CREATE USER x2crmuser@localhost IDENTIFIED BY '&amp;lt;password&amp;gt;';&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt; GRANT ALL ON x2crm.* TO x2crmuser@localhost;&lt;br /&gt;
Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;
&lt;br /&gt;
mysql&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you install X2CRM on the server, user &amp;quot;localhost&amp;quot; in the database &amp;quot;Host Name&amp;quot; settings, the database name you used in place of &amp;quot;x2crm&amp;quot;, and the username/password you used in place of &amp;quot;x2crmuser&amp;quot; and &amp;quot;&amp;lt;password&amp;gt;.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Finally, if the root user on your MySQL server does not have a password set, it is a very good idea security-wise to set a password to protect the server. Do so using the following command (from the system shell, logged out of &amp;lt;tt&amp;gt;mysql&amp;gt;&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;mysqladmin -u root password &amp;lt;newpassword&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Enabling Login as the Webserver User =&lt;br /&gt;
To greatly ease the process of installing and maintaining X2CRM, the default Apache web user (assumed &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; in the Debian family and &amp;lt;tt&amp;gt;apache&amp;lt;/tt&amp;gt; in the RHEL family, and denoted &amp;lt;tt&amp;gt;&amp;amp;lt;apache user&amp;amp;gt;&amp;lt;/tt&amp;gt; in the general case) can also be used for logging into the server and uploading / altering files, thus avoiding all permissions issues. In many cases, the ability to log in as the web server user will be disabled for security purposes. This is mostly due to how the usernames are easy to guess in brute-force remote login attempts, although this problem can be circumvented. See [[#Securing Login|Securing Login]] for details.&lt;br /&gt;
&lt;br /&gt;
== Setting the Shell ==&lt;br /&gt;
In most cases, login as the user is disabled via the shell environment variable. To check that this is so, use the &amp;lt;tt&amp;gt;getent&amp;lt;/tt&amp;gt; command as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;getent passwd &amp;lt;apache user&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should see output that looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;www-data:x:33:33:www-data:/var/www:/bin/false&amp;lt;/pre&amp;gt;&lt;br /&gt;
Or:&lt;br /&gt;
&amp;lt;pre&amp;gt;apache:x:48:48:Apache:/var/www:/sbin/nologin&amp;lt;/pre&amp;gt;&lt;br /&gt;
In both cases, the last field in the (colon-delinated) line indicates the login shell; &amp;lt;tt&amp;gt;/bin/false&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/sbin/nologin&amp;lt;/tt&amp;gt; each make it impossible to run a shell as the user. Note also that the second-to-last field is the home directory of the user. If the field is blank (i.e. there are two colons side-by-side before the login shell) it is recommended at this stage to set the home directory of the user as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;usermod -d &amp;lt;DocumentRoot&amp;gt; &amp;lt;apache user&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
If that command returns the error message that the user is currently logged in, try again after shutting down the web server as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;service apache2 stop # (Debian-like)&lt;br /&gt;
service httpd stop # (RHEL-like)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, to change the login shell, use &amp;lt;tt&amp;gt;chsh&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;chsh &amp;lt;apache user&amp;gt; -s /bin/bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Securing Login ==&lt;br /&gt;
The risk of brute-force logins can be avoided by ensuring that the main method of logging into the server and transferring files is through the secure shell daemon (SSHD), and that SSHD is configured to disallow password-based logins. SSHD will then require asymmetric key pairs to log in instead of passwords, thus making brute-force password attempts a non-issue. '''If your server is an Amazon Web Services EC2 instance, this will be the case already;''' the key pair is selected/generated before instantiation as the primary means of accessing the virtual server.&lt;br /&gt;
&lt;br /&gt;
=== Configuring SSH For Key-based Authentication ===&lt;br /&gt;
On a generic Linux server:&lt;br /&gt;
# Begin a shell session as the web server user: &amp;lt;pre&amp;gt;sudo -u &amp;lt;apache user&amp;gt; -i&amp;lt;/pre&amp;gt; All of the following commands will be run as this user.&lt;br /&gt;
# Create a &amp;quot;.ssh&amp;quot; directory in the user's home: &amp;lt;pre&amp;gt;mkdir -p ~/.ssh&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Ensure the directory has the proper permissions: &amp;lt;pre&amp;gt;chmod 700 ~/.ssh&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Run: &amp;lt;pre&amp;gt;ssh-keygen -t rsa&amp;lt;/pre&amp;gt; and (optionally) enter a passphrase to protect the key. The keypair, when done, should be stored as the files &amp;lt;tt&amp;gt;~/.ssh/id_rsa&amp;lt;/tt&amp;gt; (private) and &amp;lt;tt&amp;gt;~/.ssh/id_rsa.pub&amp;lt;/tt&amp;gt; (public). &lt;br /&gt;
# Create the authorized_keys file with the public key to enable authenticating with the private key on the remote end: &amp;lt;pre&amp;gt;cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Ensure the authorized_keys file has the proper permissions: &amp;lt;pre&amp;gt;chmod 600 ~/.ssh/authorized_keys&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Download the private key (&amp;lt;tt&amp;gt;~/.ssh/id_rsa&amp;lt;/tt&amp;gt;) and delete it from the server as soon as possible.&lt;br /&gt;
&lt;br /&gt;
'''If the server is an Amazon EC2 instance,''' it is not necessary to create a new key pair; the existing key pair can be used for authentication, if desired, by using the existing authorized_hosts file in the &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt; directory of &amp;quot;ec2-user&amp;quot; (Amazon Linux) or &amp;quot;ubuntu&amp;quot; (Ubuntu) into the &amp;lt;tt&amp;gt;.ssh/&amp;lt;/tt&amp;gt;, as follows:&lt;br /&gt;
# Make the directory and copy the files: &amp;lt;pre&amp;gt;mkdir -p ~&amp;lt;apache user&amp;gt;/.ssh; cp ~&amp;lt;default user&amp;gt;/.ssh/authorized_keys ~&amp;lt;apache user&amp;gt;/.ssh/&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Ensure proper user/group ownership of the files: &amp;lt;pre&amp;gt;chown -R &amp;lt;apache user&amp;gt;:&amp;lt;apache group&amp;gt; ~&amp;lt;apache user&amp;gt;/.ssh&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Ensure proper permissions of the files: &amp;lt;pre&amp;gt;chmod 700 ~&amp;lt;apache user&amp;gt;/.ssh; chmod 600 ~&amp;lt;apache user&amp;gt;/.ssh/*&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you may still have to protect the &amp;lt;tt&amp;gt;.ssh&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
=== Protecting ~/.ssh ===&lt;br /&gt;
If the user's home directory is the same as (or lies within) the web server's DocumentRoot (this is the case for the default LAMP configuration on Ubuntu 12.04), it is generally a very good idea to prevent all HTTP access to the directory storing the public key, regardless of whether the key pair is password-protected. The most straightforward way of doing this is by editing the main Apache configuration (&amp;lt;tt&amp;gt;/etc/apache2/apache2.conf&amp;lt;/tt&amp;gt; Debian, &amp;lt;tt&amp;gt;/etc/http/conf/httpd.conf&amp;lt;/tt&amp;gt; RHEL ) and adding the following lines to it (for Apache versions 2.0-2.2):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Directory /var/www/.ssh&amp;gt;&lt;br /&gt;
Order allow,deny&lt;br /&gt;
Deny from all&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If using Apache 2.4 or later, you can use the non-deprecated configuration directive &amp;quot;Require&amp;quot;&amp;lt;ref&amp;gt;See: [http://httpd.apache.org/docs/2.4/howto/access.html Apache 2.4 Documentation: Access Control]&amp;lt;/ref&amp;gt; as follows :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Directory /var/www/.ssh&amp;gt;&lt;br /&gt;
Require All Denied&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In both of these examples, it is assumed that the home directory is &amp;lt;tt&amp;gt;/var/www&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For extra privacy and security, it may also be desirable to deny access to all hidden dotfiles and directories used by the user shell and local programs (i.e. &amp;lt;tt&amp;gt;.bashrc&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.bash_history&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.viminfo&amp;lt;/tt&amp;gt; etc.), in which case you can use the following directive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;DirectoryMatch /var/www/\..*&amp;gt;&lt;br /&gt;
# Denial directives i.e. &amp;quot;Require All Denied&amp;quot; go here&lt;br /&gt;
&amp;lt;/DirectoryMatch&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disabling Password-based Authentication ===&lt;br /&gt;
To verify that password authentication is disabled, search for the directive in the SSHD configuration (which should be in the same place on almost every Linux and Unix system&amp;lt;ref&amp;gt;Assuming the ubiquitous [http://www.openssh.com/ OpenSSH] server is the software in use. All RHEL-based and Debian-based Linux systems, as well as FreeBSD, use OpenSSH as their chosen SSH server, and as of this writing none of the mainstream distributions are known to build OpenSSH such that the path to the daemon's configuration file is any different.&amp;lt;/ref&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;grep '^PasswordAuthentication' /etc/ssh/sshd_config&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the output of &amp;lt;tt&amp;gt;grep&amp;lt;/tt&amp;gt; you should see this:&lt;br /&gt;
&amp;lt;pre&amp;gt;PasswordAuthentication no&amp;lt;/pre&amp;gt;&lt;br /&gt;
If this is not the case, i.e. if it reads &amp;quot;yes&amp;quot; instead of &amp;quot;no&amp;quot;, or the only instance of &amp;quot;PasswordAuthentication&amp;quot; is commented in the file by having its line begin with a hash symbol (&amp;quot;#&amp;quot;), edit the file &amp;lt;tt&amp;gt;/etc/ssh/sshd_config&amp;lt;/tt&amp;gt; so that it contains a line that reads &amp;lt;tt&amp;gt;PasswordAuthentication no&amp;lt;/tt&amp;gt; and then restart the SSH daemon to enact the changes via &amp;lt;tt&amp;gt;service ssh stop&amp;lt;/tt&amp;gt; (Debian) or &amp;lt;tt&amp;gt;service sshd stop&amp;lt;/tt&amp;gt; (RHEL). However, '''before doing this,''' ensure that the primary administrative user already has a key pair set up for remote access; you will otherwise be locked out of your server. To do this, the same method that was used for creating a key pair for the web server user can be used to do so for the administrative user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Notes &amp;amp;amp; References =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Derek Mueller</name></author>	</entry>

	<entry>
		<id>http://wiki.x2crm.com/index.php?title=Software_Updates_and_Upgrades&amp;diff=1927</id>
		<title>Software Updates and Upgrades</title>
		<link rel="alternate" type="text/html" href="http://wiki.x2crm.com/index.php?title=Software_Updates_and_Upgrades&amp;diff=1927"/>
				<updated>2014-12-04T00:32:22Z</updated>
		
		<summary type="html">&lt;p&gt;Derek Mueller: /* Updating to Beta Versions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Support]]&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
The following things happen in typical a software update (or upgrade):&lt;br /&gt;
* Files that are new in the new version are added&lt;br /&gt;
* Files that have been changed in the new version are replaced with the new versions of those files &lt;br /&gt;
* Files that are no longer used in the new version are deleted&lt;br /&gt;
* Changes to the database are made to make the database compatible with the new version of X2Engine&lt;br /&gt;
* The main configuration file, &amp;lt;tt&amp;gt;X2Config.php&amp;lt;/tt&amp;gt;, is edited to reflect the new state of the application.&lt;br /&gt;
* X2Engine data caches are cleared&lt;br /&gt;
&lt;br /&gt;
These operations are typically handled by the updater utility component [[x2doc:UpdaterBehavior|UpdaterBehavior]] and controlled via the in-app web-based updater or the command line updater. This article will cover both how to use said interfaces to the updater, and how to perform updates manually or with the &amp;quot;offline&amp;quot; method if the need arises, in addition to troubleshooting and recovering from an update that did not complete cleanly.&lt;br /&gt;
&lt;br /&gt;
= Disclaimer =&lt;br /&gt;
This article covers the standard and recommended update/upgrade methods, in addition to alternate methods and supplemental procedures. As general rules and precautions for using this article:&lt;br /&gt;
# ''If you do not fully and completely understand any step of any instructions given in this article, '''do not''' follow them''; ask for help instead on [http://x2community.com the forums] or through contacting X2Engine Technical Support if you are an existing customer.&lt;br /&gt;
# You should always make a backup of all of your files ''and'' a full backup copy of your database, preferably in a format (i.e. SQL script) that can be used to create a verbatim/carbon copy of the original database, with all of the features of the original schema, '''before''' attempting any steps of the update process manually.&lt;br /&gt;
# Some of the procedures outlined in this article involve manually creating or modifying files. Note that the same filesystem prerequisite for installation, namely that the file ownership must match the user under which PHP executes on the web server, applies to these steps.&lt;br /&gt;
&lt;br /&gt;
Furthermore, '''in regard to uploading files:''' note that any instructions to upload folders into X2Engine, and replace/merge contents, refer to replacing files in X2Engine with files in the archive at analogous paths. For example, if you have a zip file that contains a folder &amp;lt;tt&amp;gt;protected&amp;lt;/tt&amp;gt;, and inside of that is a folder &amp;lt;tt&amp;gt;components&amp;lt;/tt&amp;gt;, and inside of that is a file &amp;lt;tt&amp;gt;UpdaterBehavior.php&amp;lt;/tt&amp;gt;, and the instructions are to upload/replace in X2Engine, you should upload &amp;lt;tt&amp;gt;UpdaterBehavior.php&amp;lt;/tt&amp;gt; to replace the existing file of the same name in &amp;lt;tt&amp;gt;protected/components&amp;lt;/tt&amp;gt; inside of X2Engine.&lt;br /&gt;
&lt;br /&gt;
X2Engine Inc. cannot be held accountable for damage/errors caused by any missteps or mistakes in manually-performed update operations. If in doubt, make a sandbox/clone of your X2Engine installation by copying the files and database to a different server, and test performing the operations on that before proceeding with your production install of X2Engine.&lt;br /&gt;
&lt;br /&gt;
= Update Notifications =&lt;br /&gt;
[[File:Update Notification.png|200px|frame|right|System flash message displaying software update notification.]]&lt;br /&gt;
To get notified of software updates, unless already using X2Engine Professional Edition, one must first &amp;quot;subscribe&amp;quot; to them. This can be done via checking the box &amp;quot;Notify me of software updates&amp;quot; in the installation form. If X2Engine is already installed, this can be done by going to &amp;quot;Updater Settings&amp;quot; from the Admin page and enabling them. If using Professional Edition, these steps are not not necessary.&lt;br /&gt;
&lt;br /&gt;
Once that has been completed, set the update notification interval as desired in &amp;quot;Updater Settings&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Update Methods =&lt;br /&gt;
[[File:Update_Process.svg|200px|thumb|right|Top-level overview of the update process]]&lt;br /&gt;
There are, in essence, just three basic methods of updating, and variations on each. The three main methods are: &lt;br /&gt;
# web updater,&lt;br /&gt;
# command line updater, and&lt;br /&gt;
# manually.&lt;br /&gt;
In each case, an update package from the update data server is used as the authoritative list of changes to apply, but in the non-manual methods, X2Engine's own updater class does all the work applying changes from said package.&lt;br /&gt;
&lt;br /&gt;
In web and command line updates, there is also the option to first download and unpack the package manually (see [[#Performing_.22Offline.22_Updates|performing &amp;quot;offline&amp;quot; updates]]). This circumvents the need for the local server (on which X2Engine is hosted) to be connected to the internet. Similarly, in the case of manual updates, it is not necessary for the web server to actually have an internet connection.&lt;br /&gt;
&lt;br /&gt;
== Using the Web Updater ==&lt;br /&gt;
[[File:Updater-1.png|300px|thumb|right|The updater utility page.]]&lt;br /&gt;
The web updater can be accessed by any of the following methods:&lt;br /&gt;
* Using the link in the notification message at the top of the window in versions later than 3.5.5&lt;br /&gt;
* By going to the Admin page and clicking the &amp;quot;Update&amp;quot; button at the top, in earlier versions, with update notifications enabled&lt;br /&gt;
* Through &amp;quot;Update X2Engine&amp;quot; under &amp;quot;System Settings&amp;quot; in the Admin page&lt;br /&gt;
&lt;br /&gt;
=== How to use ===&lt;br /&gt;
First, navigate to the web updater page, and '''do not''' cancel the request (stop or hit your browser's &amp;quot;back&amp;quot; button) until the page has loaded. If the updater utility has undergone changes and needs to self-update to be compatible with the software updates server, this is when it will do so. Thus, it is critical that you do not interrupt this process. If the page does not load, or displays the error message that dependencies could not be retrieved, you may have to [[#Performing_.22Offline.22_Updates|perform an &amp;quot;offline&amp;quot; update]].&lt;br /&gt;
&lt;br /&gt;
There are three ways of getting to the updater page. One is to simply click the link given in the update notification flash message, if available. The other is to click on the &amp;quot;Update&amp;quot; button at the top of the admin page. If software update notifications are not enabled, one can manually check for and install an update by going to &amp;quot;Update X2Engine&amp;quot; under &amp;quot;System Settings&amp;quot; in the Admin page.&lt;br /&gt;
&lt;br /&gt;
Next, make a backup of the database and files (recommended), follow the instructions on the page, and click the &amp;quot;Update&amp;quot; button when ready.&lt;br /&gt;
&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
It is generally quick and is the easiest method to use, and it does not require shell/SSH access to the web server.&lt;br /&gt;
&lt;br /&gt;
=== Disadvantages ===&lt;br /&gt;
It is not recommended for use on large installations of X2Engine, i.e. containing over a million records, or for updating from very old versions (i.e. a version more than five months old). This is because, in such cases, the final update process will take a very long time. It will thus be more likely that the process will be cut short by a server gateway timeout or an interruption in the network connection. '''This can result in an incomplete/broken update''' that requires [[#Recovering_From_Failed_Updates|recovering manually]] at best, or actual loss of data at worst. &lt;br /&gt;
&lt;br /&gt;
==== Explanation ====&lt;br /&gt;
The inherent weakness of the web updater (or any web-based updater to any web application) is that it must always rely upon web requests to the server, and it thus must perform extremely critical operations for the update all within the scope of a web request. Web requests, it goes without saying, are not always reliable. &lt;br /&gt;
&lt;br /&gt;
For example, one's internet connection might get cut off due to being on a wireless network and encountering interference, i.e. from a 5.8 GHz cordless phone or microwave oven. Furthermore, if any operations take an exceedingly long amount of time, e.g. because of the size of the data set (and thus indexes) on which the update must operate, or the number of database changes that need to be applied, the web request for those operations may take longer than the PHP execution time limit as configured on the webserver. &lt;br /&gt;
&lt;br /&gt;
In the event of a failed request to the server, the update could be cut short at a critical update stage, and thus require manual recovery at best, or completely restoring  X2Engine to a backup at worst.&lt;br /&gt;
&lt;br /&gt;
==== How to Avoid Timeouts ====&lt;br /&gt;
You can usually get around this by setting the value of &amp;lt;tt&amp;gt;'''max_execution_time'''&amp;lt;/tt&amp;gt; to a higher value in the web server's PHP configuration. It is highly recommended that you either disable the timeout or set it to a very generous value (such as 300 or more seconds) while attempting to update via the web updater, especially if you are many versions behind or have a high volume of data in your CRM.&lt;br /&gt;
Also, it is generally always a good idea to create a backup copy ''before'' updating, and to download it.&lt;br /&gt;
&lt;br /&gt;
==== Recovering From Crashes ====&lt;br /&gt;
If you downloaded the backup copy of your database, then after you encounter a failure/timeout, you can use the .sql backup script to restore the database to its original form. However, be aware, that if there are any '''&amp;lt;tt&amp;gt;CREATE TABLE&amp;lt;/tt&amp;gt;''' commands in the update data (expand the ''Database Commands to Run'' list to see), you will need to manually drop the created tables in order to once again make your installation compatible with the update.&lt;br /&gt;
&lt;br /&gt;
See [[#Recovering_From_Failed_Updates|Recovering From Failed Updates]] for comprehensive information on this process.&lt;br /&gt;
&lt;br /&gt;
== Using the Command Line Updater ==&lt;br /&gt;
This update method uses all of the same thoroughly-tested underpinnings and processes as the web updater, but does so all within a system command to the Yii console.&lt;br /&gt;
&lt;br /&gt;
=== How to use ===&lt;br /&gt;
While in via SSH, or in a terminal emulator, or in a script, run the following command in the &amp;lt;tt&amp;gt;protected&amp;lt;/tt&amp;gt; subdirectory of X2Engine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;./yiic update app&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note the following optional arguments to the command line updater:&lt;br /&gt;
;&amp;lt;tt&amp;gt;--force&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Use &amp;quot;1&amp;quot; for this option (i.e. &amp;lt;tt&amp;gt;--force=1&amp;lt;/tt&amp;gt;) to proceed with the update even if compatibility issues were detected. Default: 0 (halt if compatibility issues were detected).&lt;br /&gt;
;&amp;lt;tt&amp;gt;--backup&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Use &amp;quot;1&amp;quot; to specify that a database backup should be performed first before updating, &amp;quot;0&amp;quot; to proceed without creating a backup first. Default: 1.&lt;br /&gt;
;&amp;lt;tt&amp;gt;--lock&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Use &amp;quot;1&amp;quot; to specify that the application should be locked during the final installation of the update package to prevent data entry during the sensitive moments when the database is being altered and the files updated, &amp;quot;0&amp;quot; to permit use even when changes to the app are being applied. Default: 0.&lt;br /&gt;
&lt;br /&gt;
If running the command gives you the following message:&lt;br /&gt;
&amp;lt;pre&amp;gt;The updater is now up-to-date and compliant with the updates server. Re-run the command to proceed.&amp;lt;/pre&amp;gt;&lt;br /&gt;
That indicates that the updater first needed to self-update, and succeeded in doing so. You should then run the same command again to complete the update.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
Safer to use on large, mission-critical systems, and is in general the simplest and most reliable update method. The success of a software update (or upgrade) does not hinge upon a single web request completing successfully, like it does with the web updater.&lt;br /&gt;
&lt;br /&gt;
=== Disadvantages ===&lt;br /&gt;
More difficult to use; requires shell access to the web server. The console command must be run as the same system user that owns all the files and directories of X2Engine, in order to circumvent permission issues when manipulating file system objects.&lt;br /&gt;
&lt;br /&gt;
== Using the Automatic Updater ==&lt;br /&gt;
[[File:Auto-Update.png|400px|thumb|right|Auto-update scheduler on the Updater Settings page]]&lt;br /&gt;
This method uses the command line updater, but runs the command on your behalf using the local cron daemon. To configure, go to the Updater Settings Page, check the box titled &amp;quot;Update Automatically&amp;quot;, and save. If you have Professional Edition, you can manage the update schedule in addition to other automated tasks from the Cron Table settings page, which can also be found under &amp;quot;System Settings&amp;quot; in the Admin page.&lt;br /&gt;
&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
Automates the entire process of updating.&lt;br /&gt;
&lt;br /&gt;
=== Disadvantages ===&lt;br /&gt;
Only available on UNIX-like systems that have a local cron service running, and which permit user access to the cron table.&lt;br /&gt;
&lt;br /&gt;
== Performing &amp;quot;Offline&amp;quot; Updates ==&lt;br /&gt;
In some server environments, the updater may not be able to access the updates server by itself, due to (for example) the PHP or network configuration, or because the &amp;quot;zip&amp;quot; PHP extension (requried) is unavailable or has been disabled. It is in these situations necessary to download the update package manually, unpack on the server (or unpack and upload the files to the server), and then run the updater. When performing updates in this way, the updater will not need to access the updates server, but will use the manually-downloaded and extracted package files present in the local filesystem.&lt;br /&gt;
&lt;br /&gt;
=== Refreshing and Updating the Updater Utility ===&lt;br /&gt;
Before starting, note that the updater itself may have undergone changes; the X2Engine update process is subject to change. To address this technical challenge, the updater utility within X2Engine would normally first attempt to download the latest version of itself, in order to be compatible with the updates server. However, this sometimes will not work properly. If your X2Engine installation is running in a hosting environment that prevents it from making outbound HTTP requests (the [[requirements:|requirements check script]] should tell you if this is the case), you will need to do this manually. Also, in version 3.5.5, there was a bug in the updater utility's self-update methods.&lt;br /&gt;
&lt;br /&gt;
To update the updater utility:&lt;br /&gt;
# '''Determine the version of the updater utility package''' by visiting [https://x2planet.com/installs/updates/updateCheck this link]. You should see a page that's entirely blank except for a version number.&lt;br /&gt;
# '''Download the updater package.''' In versions 3.6 and later, a download link for this should be available through the ''Updater Settings'' page. Otherwise, use the following URL (if in Open Source Edition): &amp;lt;pre&amp;gt;https://x2planet.com/installs/updater.zip&amp;lt;/pre&amp;gt; Otherwise, if using Professional Edition, paste the following url, after replacing {key} with your license key, into your browser's address bar: &amp;lt;pre&amp;gt;https://x2planet.com/installs/{key}/updater-pro.zip&amp;lt;/pre&amp;gt;&lt;br /&gt;
# '''Extract the downloaded zip archive and upload''' the &amp;quot;protected&amp;quot; folder to your server. Merge folders and overwrite existing files when prompted.&lt;br /&gt;
# '''Open the file &amp;lt;tt&amp;gt;protected/config/X2Config.php&amp;lt;/tt&amp;gt; in a text editor''' and find the line that looks like this:&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$updaterVersion = '3.5.2';&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# '''Change the text inside the pair of single quotes''' on that line so that it is the current updater version obtained in step #1. &lt;br /&gt;
# '''Save the file.'''&lt;br /&gt;
&lt;br /&gt;
=== Obtaining the Update Package ===&lt;br /&gt;
First, use the link in the ''Updater Settings'' page entitled &amp;quot;Latest Update Package for Version...&amp;quot;, to download the update package. If the link in the Updater Settings page does not work, use the following URL to download the update package (if using Open Source Edition), replacing &amp;lt;tt&amp;gt;{version}&amp;lt;/tt&amp;gt; with your X2Engine installation's version:&lt;br /&gt;
&amp;lt;pre&amp;gt;https://x2planet.com/installs/updates/{version}/none&amp;lt;/pre&amp;gt;&lt;br /&gt;
You should receive, from that URL, a zip archive file called &amp;quot;update.zip&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If using Professional Edition, and your download link is not working, contact [mailto:customersupport@x2engine.com customer support].&lt;br /&gt;
&lt;br /&gt;
=== Unpacking the Update ===&lt;br /&gt;
[[File:Update-in-Progress.png|200px|frame|right|System flash message displaying notification of pending update.]]&lt;br /&gt;
The update package will be a zip archive. The ''contents'' of this archive must be extracted ''into'' a folder called &amp;quot;update&amp;quot; in the installation directory. So, in other words, after extracting and uploading to the server, there should be a folder called &amp;lt;tt&amp;gt;update&amp;lt;/tt&amp;gt; alongside &amp;lt;tt&amp;gt;protected&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;assets&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;framework&amp;lt;/tt&amp;gt; (etc). Within that folder (&amp;lt;tt&amp;gt;update&amp;lt;/tt&amp;gt;) should be the following contents:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;manifest.json&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A file containing important data to be used by the updater&lt;br /&gt;
;&amp;lt;tt&amp;gt;contents.md5&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A message digest file containing MD5 checksums of all files in the archive excluding itself.&lt;br /&gt;
;&amp;lt;tt&amp;gt;source&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A sub-folder/directory, whose internal structure mimics that of X2Engine, containing files that were changed in the update. If there were no files changed (i.e. only database changes were in the update), this directory will not be present.&lt;br /&gt;
;&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A directory containing flat data files. These files are typically not used by the updater, but are useful if performing manual updates or recovery.&lt;br /&gt;
&lt;br /&gt;
=== Applying the Update ===&lt;br /&gt;
[[File:Steps-post-Unpack.png|200px|frame|right|Steps of the update process in the event of manually-extracted package (or resuming a preexisting update)]]&lt;br /&gt;
After unpacking, if you run the command line updater, it should (if no problems arise, i.e. incompatible package version) apply the update straight away. Otherwise, log into X2Engine, and you should see a system flash message notifying you of an update in progress. This message shows up whenever there is an update package folder (&amp;quot;update&amp;quot;) present on the server. If you then go to the updater page, once the page has finished loading, you should see that there only remain the steps &amp;quot;Review and confirm changes&amp;quot;, &amp;quot;Apply changes&amp;quot; and &amp;quot;Reload&amp;quot; remain to be completed. To complete the update, when ready, click &amp;quot;Update&amp;quot;; otherwise, to delete the &amp;quot;update&amp;quot; folder and cancel the update, click &amp;quot;Cancel&amp;quot; either on the updater page or in the system flash message.&lt;br /&gt;
&lt;br /&gt;
== Performing Updates Manually ==&lt;br /&gt;
While it is preferable to avoid manually applying changes to X2Engine, and you may never need to, it may in some circumstance or another actually be necessary to do so. For all such situations, the raw update data files generated by the X2Engine update build process are bundled with every update package to help you perform the operations described in [[#Introduction|&amp;quot;Introduction&amp;quot;]]. This section will describe how to perform each of those operations. &lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
First and foremost, all shell commands listed here, and in general, any operations that create or modify files, ''must be run as the same system user under which the server runs PHP scripts.'' Otherwise, the ownership and/or permissions of files and directories will have to be changed after completing all changes.&lt;br /&gt;
&lt;br /&gt;
To obtain the update package (which will be necessary), refer to &amp;quot;[[#Obtaining_the_Update_Package|Obtaining the Update Package]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Furthermore, it is strongly advised that you first make a back-up copy of all files and of X2Engine's database. Your database backup would best be a full, exact copy, such as one that would be made by [http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html mysqldump], or the built-in export tools of [http://www.phpmyadmin.net/home_page/index.php PHPMyAdmin].&lt;br /&gt;
&lt;br /&gt;
The X2Engine global import/export utility (&amp;quot;Import All Data&amp;quot;/&amp;quot;Export All Data&amp;quot;) in Admin '''is not recommended by itself as the sole backup tool'''. This is especially important to note because of how this tool cannot re-create ancillary data such as tags or relationships, or user roles. However, using it to ''supplement'' your standard database backup method will prove useful in the event that you:&lt;br /&gt;
# don't have any custom roles, relationships, tags, etc.&lt;br /&gt;
# cannot manage to update X2Engine with success, and&lt;br /&gt;
# wish to start over with a fresh installation.&lt;br /&gt;
In such a case, you will then be able to import your old data into the new installation.&lt;br /&gt;
&lt;br /&gt;
=== Introduction: Data Files ===&lt;br /&gt;
In [[#Unpacking_the_Update|Unpacking the update]], a rough overview of an update package's contents were given. In this section, the anatomy and purpose of each of the data files will be introduced.&lt;br /&gt;
&lt;br /&gt;
Included in every update package is two copies of the following data:&lt;br /&gt;
* Files to copy&lt;br /&gt;
* Files to delete&lt;br /&gt;
* Database changes to enact&lt;br /&gt;
* Migration scripts to run, if any&lt;br /&gt;
&lt;br /&gt;
The first, immediately visible place where all of this data is stored is in the file &amp;lt;tt&amp;gt;manifest.json&amp;lt;/tt&amp;gt;, as a JSON-encoded array. See the next section for how to use this file.&lt;br /&gt;
&lt;br /&gt;
The second place, which can be useful to users who do not wish to automate or script any step of a manual update, is in the files contained in the &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; directory. Each file is named after the version to which it corresponds, and contains the data required to update ''to'' that version ''from the version immediately preceding it.''' Thus, the versions you should see in each file name are the versions above your X2Engine installation's current version, up to and including the version being updated to.&lt;br /&gt;
&lt;br /&gt;
In an update, the directory will contain the following subdirectories:&lt;br /&gt;
;&amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Contains files for each version, each containing the list of files to copy. The format is each line containing a file path in the list.&lt;br /&gt;
;&amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Contains files for each version, each containing the list of obsolete files for that version which will need to be deleted. The format is the same as in &amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Contains .sql scripts corresponding to each version. Each file is formatted such that it can be directly run on the database as an SQL script, although this is not generally recommended. The list of SQL commands to run is a of the following format: &lt;br /&gt;
  [query 1];&lt;br /&gt;
  /*&amp;amp;*/&lt;br /&gt;
  [query 2];&lt;br /&gt;
  /*&amp;amp;*/&lt;br /&gt;
  [etc]&lt;br /&gt;
;&amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Contains .sql scripts with similar naming and formatting conventions to the &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt; scripts. See [[#The_structure_of_the_.22data.22_array|The structure of the &amp;quot;data&amp;quot; array]] for explanation of the purpose of &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How to use the manifest for updating manually ===&lt;br /&gt;
If you so choose, you may write a script to perform all of the operations for an update in one fell swoop. If so, and if the preferred scripting language of choice has a JSON-parsing library available, you will be able to save yourself a lot of effort by using the main data file (&amp;lt;tt&amp;gt;manifest.json&amp;lt;/tt&amp;gt;) to load all of the necessary data for the update.&lt;br /&gt;
&lt;br /&gt;
==== The structure the manifest ====&lt;br /&gt;
In updates, the contents of the plain-text file manifest.json are a JSON-encoded object containing the following properties:&lt;br /&gt;
;&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;&lt;br /&gt;
: An array containing the data corresponding to each intermediate version. It is, in essence, all the data stored in the files in &amp;lt;tt&amp;gt;update/data&amp;lt;/tt&amp;gt;. If the update is for an installation of X2Engine that is only one version behind, it will contain only one element. Each element of this array is itself an array containing respective data for the intermediate version.&lt;br /&gt;
;&amp;lt;tt&amp;gt;versions&amp;lt;/tt&amp;gt;&lt;br /&gt;
: An array listing the version numbers of each intermediate version in the update. Similar to &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;, this array will contain only one element if updating to the next version, and that version ''will be the next version''.&lt;br /&gt;
;&amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: An array containing the cumulative list of deletions of obsolete files across versions through which the update traverses.&lt;br /&gt;
;&amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: An array containing the cumulative list of files added or changed across versions through which the update traverses.&lt;br /&gt;
;&amp;lt;tt&amp;gt;fromVersion&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string, containing the version number that the update is ''from'', or in other words, the version of X2Engine before the package is applied. '''This must be the same as the version of installation to which the package is being applied.''' If this is not so, the updater utility would exit immediately, as applying the changes in the update would have potentially harmful results to data and/or compatibility with future updates.&lt;br /&gt;
;&amp;lt;tt&amp;gt;targetVersion&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string, containing the version number that the update is ''to'', or in other words, the version of X2Engine before the package is applied.&lt;br /&gt;
;&amp;lt;tt&amp;gt;updaterVersion&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string denoting the version of the updater utility for which the package was compiled. If the structure of the update package or of the manifest changes, the updater must also change to accommodate and recognize the changes; else it might try to access properties that don't exist, or ignore important ones that do. This is the single property of manifest.json that should never change.&lt;br /&gt;
;&amp;lt;tt&amp;gt;scenario&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string, which should be &amp;quot;update&amp;quot; if the package is for an update. In the case of upgrades, which use most of the same functionality of the updater, it should be &amp;quot;upgrade&amp;quot;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;targetEdition&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string denoting the edition of the X2Engine installation after the package is applied. It should be &amp;quot;opensource&amp;quot; for open source edition, &amp;quot;pro&amp;quot; for professional edition. In the case of an upgrade package, it differs from the &amp;lt;tt&amp;gt;fromEdition&amp;lt;/tt&amp;gt; property.&lt;br /&gt;
;&amp;lt;tt&amp;gt;fromEdition&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A string denoting the edition of the X2Engine installation before the package is applied. &lt;br /&gt;
;&amp;lt;tt&amp;gt;buildDate&amp;lt;/tt&amp;gt;&lt;br /&gt;
: An integer denoting the timestamp of the release date of the version of X2Engine denoted by &amp;lt;tt&amp;gt;targetVersion&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The structure of the &amp;quot;data&amp;quot; array ====&lt;br /&gt;
In updates, each version's data, contained in each element of the &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;, contains the following nested array properties:&lt;br /&gt;
;&amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The list of files added for the version&lt;br /&gt;
;&amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The list of files deleted in the version&lt;br /&gt;
;&amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A list of SQL commands to bring the database structure and contents into compliance with the version from the previous version&lt;br /&gt;
;&amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A prerequisite list of SQL commands that should be run before those in &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;, and if any fail, the failures should be ignored. These are added to updates whenever it is necessary to normalize the database schema, i.e. in the event that some installations' databases may not be consistent with others, but the commands might fail on every other system. These SQL commands were intended to be &amp;quot;attempted&amp;quot;; they are not guaranteed to succeed on all installations. An example of when this is necessary would be adding a foreign key constraint when in previous versions the storage engine was left to the database's default settings in old versions. MyISAM does not natively support foreign key constraints. Thus, to standardize this across all installations, including installations on servers where the storage engine defaulted to MyISAM, the constraint must first be dropped (in a &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt; command) before the relevant tables are changed to the InnoDB storage engine, and the constraint is added back again, in the usual &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;version&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The version number&lt;br /&gt;
;&amp;lt;tt&amp;gt;edition&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The edition&lt;br /&gt;
;&amp;lt;tt&amp;gt;migrationScripts&amp;lt;/tt&amp;gt;&lt;br /&gt;
: A list of PHP scripts that would be run in an update for this version. These are a subset of fileList and are typically used for advanced database operations, i.e. restructuring values of JSON-encoded fields, which are extremely impractical (or impossible) to perform using raw SQL commands. The files contained in the list all have paths that look like &amp;quot;&amp;lt;tt&amp;gt;protected/migrations/{version}/{timestamp}-name-of-operations.php&amp;lt;/tt&amp;gt;&amp;quot;. Note, if this array is not empty, and the &amp;lt;tt&amp;gt;'''runmigrationscript'''&amp;lt;/tt&amp;gt; Yii command does not work (or isn't available yet), you may need to reverse-engineer or otherwise copy and re-purpose/re-write any migration scripts listed in order to perform their necessary operations. This is because they often depend on running within a Yii Framework environment, i.e. will contain references to components of the Yii application singleton such as &amp;quot;db&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Also note that in upgrades, &amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt; are replaced by &amp;lt;tt&amp;gt;fileUpgrade&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;sqlUpgrade&amp;lt;/tt&amp;gt; (respectively), and &amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;migrationScripts&amp;lt;/tt&amp;gt; are missing (because they aren't necessary).&lt;br /&gt;
&lt;br /&gt;
==== What you will need for the update, if using the manifest ====&lt;br /&gt;
''Among this data, what you will need:'' &amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt;, which will give you the full list of files that need to be deleted, &amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;, which will give you the full list of files to copy from the &amp;lt;tt&amp;gt;update/source&amp;lt;/tt&amp;gt; directory, &amp;lt;tt&amp;gt;updaterVersion&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;targetVersion&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;buildDate&amp;lt;/tt&amp;gt;, which give you values with which to update the main X2Engine configuration file, and, within each element of &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;, the sub-array properties &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;migrationScripts&amp;lt;/tt&amp;gt;, with which you will construct the list of database commands to run. &lt;br /&gt;
&lt;br /&gt;
A procedure for manually updating X2Engine, with data from manifest.json, thus might look like this:&lt;br /&gt;
# For each element of &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; (or in other words, each version's changes):&lt;br /&gt;
## Run all the SQL commands in its corresponding &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt; sub-array, ignoring errors&lt;br /&gt;
## Run all SQL commands in its &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt; array&lt;br /&gt;
## Perform database operations that would be equivalent to those performed in migration scripts&lt;br /&gt;
# For each file in the cumulative list &amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;, copy it from the &amp;lt;tt&amp;gt;update/source&amp;lt;/tt&amp;gt; directory into its analogous location in the installation directory of X2Engine, creating parent directories as necessary if they don't already exist.&lt;br /&gt;
# Delete all files in the cumulative list &amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt; from the installation directory&lt;br /&gt;
# Clear the data cache files in &amp;lt;tt&amp;gt;protected/runtime/cache&amp;lt;/tt&amp;gt; and the temporary asset folders in &amp;lt;tt&amp;gt;assets/&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Clear all session data (&amp;lt;tt&amp;gt;x2_sessions&amp;lt;/tt&amp;gt;) and auth cache data (&amp;lt;tt&amp;gt;x2_auth_cache&amp;lt;/tt&amp;gt;).&lt;br /&gt;
# Update the main X2Engine configuration (&amp;lt;tt&amp;gt;protected/config/X2Config.php&amp;lt;/tt&amp;gt;) file, setting:&lt;br /&gt;
## &amp;lt;tt&amp;gt;$buildDate&amp;lt;/tt&amp;gt; to the &amp;lt;tt&amp;gt;buildDate&amp;lt;/tt&amp;gt; property,&lt;br /&gt;
## &amp;lt;tt&amp;gt;$version&amp;lt;/tt&amp;gt; to the &amp;lt;tt&amp;gt;targetVersion&amp;lt;/tt&amp;gt; property, and &lt;br /&gt;
## &amp;lt;tt&amp;gt;$updaterVersion&amp;lt;/tt&amp;gt; to the &amp;lt;tt&amp;gt;updaterVersion&amp;lt;/tt&amp;gt; property.&lt;br /&gt;
&lt;br /&gt;
=== Enacting Database Changes ===&lt;br /&gt;
Inside the &amp;lt;tt&amp;gt;update/sqlList&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;update/sqlForce&amp;lt;/tt&amp;gt; folder is a list of &amp;lt;tt&amp;gt;.sql&amp;lt;/tt&amp;gt; files, named according to their corresponding version's update, that can essentially be run as SQL scripts to perform the update. Note, however, that '''if the update traverses more than one version, the scripts must be run in the order of their corresponding version.''' This is because, in the database changes for any version, it is assumed that the database schema and contents conform to the version that immediately preceded it. The PHP function [[phpfunc:version-compare|version_compare]], and the method &amp;quot;[http://pythonhosted.org/setuptools/pkg_resources.html#parsing-utilities parse_version]&amp;quot;, in the pkg_resources module of setuptools, should correctly identify which version should come first. Note, the [[#The_structure_the_manifest|&amp;quot;versions&amp;quot; property of the manifest]] will contain the list of versions in the correct order.&lt;br /&gt;
&lt;br /&gt;
Furthermore, note, &amp;quot;sqlList&amp;quot; and &amp;quot;sqlForce&amp;quot; may not encompass all necessary database changes; if there are any migration scripts in the update, the operations they perform will similarly need to be performed in the current update (see the description of &amp;lt;tt&amp;gt;migrationScripts&amp;lt;/tt&amp;gt; in [[#The_structure_of_the_.22data.22_array|&amp;quot;the structure of the 'data' array&amp;quot;]]).&lt;br /&gt;
&lt;br /&gt;
In summary, for each version traversed in the update, the following operations should be run in order, with &amp;lt;tt&amp;gt;{version}&amp;lt;/tt&amp;gt; being the version number of the version in question:&lt;br /&gt;
# '''Run all of the SQL commands in the &amp;lt;tt&amp;gt;data/sqlForce/{version}.sql&amp;lt;/tt&amp;gt; file,''' in the order they appear in the file. Ignore if any commands fail. Note, if passed to the MySQL client as a script, any failures might trigger a halt in execution and thus skip the remainder of the commands.&lt;br /&gt;
# '''Run all of the SQL commands in the &amp;lt;tt&amp;gt;data/sqlList/{version}.sql&amp;lt;/tt&amp;gt; file.'''&lt;br /&gt;
# '''Run migration scripts using &amp;lt;tt&amp;gt;./yiic runmigrationscript {path}&amp;lt;/tt&amp;gt;, if any.''' The first part of a script file name is the timestamp it was added to the codebase, and this also dictates the order in which they should be run.&lt;br /&gt;
&lt;br /&gt;
=== Copying new files ===&lt;br /&gt;
Files added/changed in the new version are stored in the &amp;lt;tt&amp;gt;update/source&amp;lt;/tt&amp;gt; directory. In an update, they should be copied into the installation directory, replacing any existing files of the same name/path. If the &amp;lt;tt&amp;gt;rsync&amp;lt;/tt&amp;gt; utility is available on the system, you can use one command to safely copy these files into the installation directory as follows (executed in that same directory):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rsync -avc update/source/ ./&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Otherwise, you will need to use &amp;lt;tt&amp;gt;cat&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;cp&amp;lt;/tt&amp;gt;, two utilities that should be available on every UNIX-like system, and the lists of files added in each intermediate version. These lists are stored in the folder &amp;lt;tt&amp;gt;update/data/fileList&amp;lt;/tt&amp;gt; and named like &amp;quot;{version}.txt&amp;quot; (&amp;lt;tt&amp;gt;{version}&amp;lt;/tt&amp;gt; being the version to which it applies), each file on its own line in that file. Run the following command, ignoring errors:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for f in update/data/fileList/*; do for l in $(cat $f); do cp update/source/&amp;quot;$l&amp;quot; ./&amp;quot;$l&amp;quot; ; done ; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Deleting old files ===&lt;br /&gt;
Files to be deleted are listed in a similar manner as the files to be added: one file per line. The list of files to delete are located at files with paths that look like this: &amp;lt;tt&amp;gt;update/data/deletionList/{version}.txt&amp;lt;/tt&amp;gt;&lt;br /&gt;
So, for an update from 5.5 to 5.7 with intermediate version 5.6 (for instance), the files would be &amp;lt;tt&amp;gt;update/data/deletionList/5.6&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;update/data/deletionList/5.7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If there is only one version through which to update, the operation is very simple, and can be performed in one UNIX/Linux (bash) shell command as follows (if the version is 3.6.3, for example):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
xargs -a update/data/deletionList/3.6.3.txt -d&amp;quot;\n&amp;quot; rm -fv&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Otherwise, if there are multiple versions, this may be a more tricky proposition. The necessity arises to create a cumulative list, because there might be the possibility that a file is deleted in one version and re-established in a new version. Nevertheless, while this is possible, it is highly unlikely, and in most cases it is safe to simply iterate over all the &amp;lt;tt&amp;gt;deletionList&amp;lt;/tt&amp;gt; data files and delete all the files listed therein. As a bash command:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for f in update/data/deletionList/*; do xargs -a $f -d&amp;quot;\n&amp;quot; rm -fv ; done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Editing the Configuration File ===&lt;br /&gt;
This final step in the update process, before refreshing, should not be done manually unless you are completely certain that all the files (not counting customizations) and the structure of the database are equivalent to a fresh installation at the same version as the one to which you have updated.&lt;br /&gt;
&lt;br /&gt;
To update the configuration manually:&lt;br /&gt;
# Open the file &amp;lt;tt&amp;gt;protected/config/X2Config.php&amp;lt;/tt&amp;gt; in a text editor&lt;br /&gt;
# Find the line with the &amp;lt;tt&amp;gt;$version&amp;lt;/tt&amp;gt; variable in it. It should look like this (but with the version from which you are updating): &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$version = '3.5.2';&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Change the value in quotes to the current version being updated to, and save the file.&lt;br /&gt;
&lt;br /&gt;
=== Clearing caches and refreshing the application ===&lt;br /&gt;
It is generally always a good idea to clear the application's server-side cache and other ephemeral files/data after updating. This is taken care of automatically by the built-in updater, but barring proper use and functioning of that, the operations can be performed manually as follows: &lt;br /&gt;
;clear the data cache&lt;br /&gt;
: delete all &amp;quot;&amp;lt;tt&amp;gt;.bin&amp;lt;/tt&amp;gt;&amp;quot; files in &amp;lt;tt&amp;gt;protected/runtime/cache&amp;lt;/tt&amp;gt;: &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;rm -fv protected/runtime/cache/*.bin&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;clear web assets&lt;br /&gt;
: delete all sub-folders of &amp;lt;tt&amp;gt;assets&amp;lt;/tt&amp;gt; by running this command (in the installation directory): &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;rm -r assets/*/&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;clear the &amp;quot;auth cache&amp;quot;&lt;br /&gt;
: Flush the auth cache table, i.e. run the following command on the database:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELETE FROM `x2_auth_cache` WHERE 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
;log all users out&lt;br /&gt;
: Flush the sessions table, i.e. run the following command on the database:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;DELETE FROM `x2_sessions` WHERE 1;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Upgrading =&lt;br /&gt;
&lt;br /&gt;
== Using the Web Interface ==&lt;br /&gt;
[[File:Software-Upgrade-Registration.png|400px|thumb|right|Software upgrade page, in the first step (registration)]]&lt;br /&gt;
To upgrade to Professional Edition&lt;br /&gt;
# Purchase X2Engine Professional Edition Download. Note the registration info in the activation email.&lt;br /&gt;
# Go to the Admin page in X2Engine and find &amp;quot;Upgrade X2Engine&amp;quot; under &amp;quot;System Settings&amp;quot;.&lt;br /&gt;
# In the ''Upgrade'' page, enter your registration info into the form and click &amp;quot;Register&amp;quot; to continue. Once complete, you will see a list of changes similar to those displayed when performing an update.&lt;br /&gt;
# Review the changes to be applied and then proceed by clicking &amp;quot;Upgrade&amp;quot;, similar to performing an update.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Offline&amp;quot; Upgrading ==&lt;br /&gt;
This works in exactly the same way as offline updating. However, to obtain your upgrade package, which you will extract into a folder called &amp;quot;update&amp;quot; on the X2Engine web server, contact [mailto:customersupport@x2engine.com customer support]. Furthermore, you will need to run the following database command on your X2Engine database when done with the upgrade, replacing &amp;lt;tt&amp;gt;{product key}&amp;lt;/tt&amp;gt; with your product key, to allow your installation to receive Professional Edition software updates:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;UPDATE `x2_admin` SET `unique_id`='{product key}' WHERE `id`=1;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manually Upgrading ==&lt;br /&gt;
The process of upgrading is very similar to that of updating, and uses all of the same underpinnings as the updater. Thus, almost all of the above information and procedures will apply to upgrades. However, note the following crucial differences:&lt;br /&gt;
&lt;br /&gt;
* '''X2Engine must be at the latest available version in order to upgrade.'''&lt;br /&gt;
* '''To obtain the upgrade package, you must be an owner of an X2Engine Professional Edition Download-type license.''' Contact [mailto:customersupport@x2engine.com customer support] for further details.&lt;br /&gt;
* '''There will be only one &amp;quot;intermediate&amp;quot; version.''' The changes to apply will move X2Engine from a version to that same version, applying instead the necessary changes to switch its ''edition'' from Open Source to Professional.&lt;br /&gt;
* '''There are no file deletions.'''&lt;br /&gt;
* '''The properties of the package manifest differ slightly.''' In upgrades, the properties of the data object are &amp;lt;tt&amp;gt;sqlUpgrade&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;fileUpgrade&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;sqlList&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;fileList&amp;lt;/tt&amp;gt;, etc. Note also, the update data is in aptly-named sub-folders of &amp;lt;tt&amp;gt;update/data&amp;lt;/tt&amp;gt; as well, and there are no &amp;lt;tt&amp;gt;sqlForce&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;migrationScripts&amp;lt;/tt&amp;gt; lists to handle.&lt;br /&gt;
* '''The configuration is not changed.''' Instead, the value stored in the field &amp;lt;tt&amp;gt;unique_id&amp;lt;/tt&amp;gt; of the admin record in the database table &amp;lt;tt&amp;gt;x2_admin&amp;lt;/tt&amp;gt; must be changed to the license key, and the &amp;lt;tt&amp;gt;edition&amp;lt;/tt&amp;gt; field must be changed to &amp;quot;pro&amp;quot;. To perform these both, run the following command on the X2Engine database: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;UPDATE `x2_admin` SET `unique_id`='{license key}',`edition`='pro' WHERE `id`=1;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* '''It is not necessary to clear caches or user sessions when done.''' These operations are performed in updates to eliminate ephemeral (session-ingrained) data that may no longer be applicable and thus cause problems. Upgrades will rarely, if ever, invalidate this data.&lt;br /&gt;
&lt;br /&gt;
= Updating to Beta Versions =&lt;br /&gt;
'''Please note: Beta versions are for testing purposes only and are not intended to be deployed in your production environment.''' &lt;br /&gt;
 &lt;br /&gt;
Beginning at version 4.1.2, after much advocacy to adopt this practice, X2Engine began a two-phase release process in which each version would be released first as a beta, then to the broader public after initial bug finds. The purpose behind this is to avoid updating production installations of X2Engine to new versions that have had zero public exposure, and thus avoid introducing bugs that were not found in initial QA testing (due to a incompatibility with a particular server environment or configuration of X2Engine) into sensitive production environments.&lt;br /&gt;
&lt;br /&gt;
By default, the updater will not update to beta versions. The updater must be configured to use the proper URL on the update server for beta release data, by the following procedure:&lt;br /&gt;
# Create a file &amp;quot;constants-custom.php&amp;quot; in the root level of X2Engine. You can easily do this by renaming &amp;quot;constants-custom.example.php&amp;quot; to that name (remove &amp;quot;.custom&amp;quot;).&lt;br /&gt;
# Look for the following line, and in it, change &amp;quot;false&amp;quot; to &amp;quot;true&amp;quot;: &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;defined('X2_UPDATE_BETA') or define('X2_UPDATE_BETA',false);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The advantage of enabling beta releases is that new features will be available much sooner. Additionally, fixes to bugs will also be available sooner. The main disadvantage of enabling beta releases is that they are never guaranteed to be as stable as non-beta releases. We encourage users to clone their installations of X2Engine and use beta versions on them, and report any issues they encounter for their particular server environment/special configuration/custom implementation of X2Engine. This way, any issues that arise can be fixed in the stable release. The more users participate in beta testing, the more stable the non-beta releases will become.&lt;br /&gt;
&lt;br /&gt;
= Recovering From Failed Updates =&lt;br /&gt;
Uh-oh. You attempted to update, and found out too late that the database was incompatible with the changes. You might have used the web updater and experienced a server timeout, or made changes to the schema outside of X2Engine that conflicts with the update. Your backup is either out of date or nonexistent.&lt;br /&gt;
&lt;br /&gt;
Fortunately, recovery from such a scenario is fairly straightforward provided one has basic knowledge of MySQL, but it requires hands-on work with the files and MySQL database. If you have no experience managing databases either through a MySQL command console or a web UI (i.e. [http://www.phpmyadmin.net/home_page/index.php PHPMyAdmin]), it is recommended you seek help with this process. Furthermore, like manually updating, this process requires access to the file system. If all that is available to you is accessing your application via the web, i.e. pure SAAS, you will need to contact your hosting provider or system administrator for assistance.&lt;br /&gt;
&lt;br /&gt;
== Recovery Checklist ==&lt;br /&gt;
In summary, before beginning, you're going to need the following:&lt;br /&gt;
&lt;br /&gt;
* '''Access to the file system and database of X2Engine.''' Without these, your hands are tied, and you cannot effectively do anything. You will need someone else who does have access to fix X2Engine on your behalf.&lt;br /&gt;
* '''The exact error message given by the updater in its entirety.''' It explains what went wrong.&lt;br /&gt;
* '''The updater package for the version you attempted updating/upgrading from.''' This contains not just the important data but also flat data files that should prove helpful in diagnosing and fixing the problems. See &amp;quot;[[#Obtaining_the_Update_Package|Obtaining the Update Package]].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== If The Update Failed After Applying Database Changes ==&lt;br /&gt;
If this happened, the update is almost complete, and it is less effort to simply perform the final steps manually than trying to recover/reset the installation and start over. You will know if this is the case when it is explicitly indicated by an updater error message that begins with &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;color:red&amp;quot;&amp;gt;Encountered an issue after applying database changes.&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
You can, in nearly all such cases, complete the update by performing the final steps of a manual update from [[#Copying_new_files|copying the new files]] through [[#Clearing_caches_and_refreshing_the_application|cleaning up]]. Note, however, that if the error indicates that it failed to modify the configuration, i.e.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote style=&amp;quot;color:red&amp;quot;&amp;gt;Failed to set version info in the configuration.&amp;lt;/blockquote&amp;gt; &lt;br /&gt;
&lt;br /&gt;
then the task at hand is even easier. All that would required in that case is updating the configuration and cleaning up, because at this stage of the update all the necessary changes to the local filesystem have already been enacted.&lt;br /&gt;
&lt;br /&gt;
== Using Backups ==&lt;br /&gt;
If a backup copy of the database is available, and the update failed in the middle of database changes, restoring the database to the backup can prove to be the easiest way to reset the database to a known state and saving effort in the recovery process. Doing so is recommended unless your database is exceedingly large (i.e. several hundred megabytes or more), in which case the restore operation will take a long time and possibly cause more damage if done improperly.&lt;br /&gt;
&lt;br /&gt;
=== Backup Validity and Applicability ===&lt;br /&gt;
Note that, when making a backup copy of the database, whether using the button in the updater's web interface or some third-party tool, that ''the backup represents the exact state of the database when it is created.'' Furthermore, if the backup-database button is used after attempting to update unsuccessfully, that will overwrite the old backup. Thus, it should go without saying: '''DO NOT back up again if your first attempt failed.''' You should back up your files and database '''before you attempt to update,''' and only then; nothing after that is useful. After the first attempt, any backup made will reflect the broken/intermediate state, in which case it does no good and only returns you to the broken state when you use it.&lt;br /&gt;
&lt;br /&gt;
=== Restoring a SQL Backup Manually ===&lt;br /&gt;
Database backup copies, especially those made with MySQLDump and the built-in database backup utility of X2Engine, retain both the schema and content of the database. They can be run as SQL scripts to completely restore the database to its previous state. How exactly to do this depends entirely on the end user's preferred method and thus is not covered here (there are many possible ways).&lt;br /&gt;
&lt;br /&gt;
If using a backup copy that is in the form of a SQL script, it is vitally important to first drop all tables in the target database that were not created in the backup script. This is important because the restore script will not drop any tables in the current database that aren't in the backup (which need to be dropped before re-creating them in the backed-up state). This will include any tables created since the time that the backup was made. The reasoning behind this is that if the error is &amp;quot;''Base table or view already exists'',&amp;quot; restoring in itself will not help, because the offending table will still remain in the database after restoring. Note, the auto-restore operation in the updater takes care of this automatically.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Examine the Files ==&lt;br /&gt;
The first appropriate step is to look at the modification times of the files that were supposed to be updated or added in the update. Lists of such files, one per line, are in the files stored in &amp;lt;tt&amp;gt;data/fileList&amp;lt;/tt&amp;gt; within the update package. Pick one of them and see if it was changed today. Compare, i.e. using &amp;lt;tt&amp;gt;diff&amp;lt;/tt&amp;gt;, the files in the update package versus the files in the installation.&lt;br /&gt;
&lt;br /&gt;
=== Bulk Comparison of Files ===&lt;br /&gt;
''To compare all files in one command:'' assuming you are in a Unix/Linux shell session (i.e. bash) on the web server, and you are in the base directory of X2Engine, and the updater package has been unpacked into the &amp;quot;update&amp;quot; directory, run&lt;br /&gt;
&lt;br /&gt;
  diff -rq update/source/ ./&lt;br /&gt;
&lt;br /&gt;
=== Get a List of Migration Scripts ===&lt;br /&gt;
Migration scripts perform ancillary data transformation after a version's worth of updates that cannot be performed using pure SQL. They are PHP source files, and can be found in the directory &amp;lt;tt&amp;gt;source/protected/migrations&amp;lt;/tt&amp;gt; within the unzipped update package. If any migration scripts are present, this will impact how one must proceed, if finishing the update manually rather than restoring the database to the backup copy and modifying the database for update compatibility.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Examine the Database ==&lt;br /&gt;
If any of the files differ and have not been updated, this indicates that the update halted in the middle of database changes, and thus, you will need to determine the state that it is in. On the other hand, if all of the files are identical to the copies in the update package, the chances are good that all of the database ''and'' file changes have already been applied, and all that remains to be done is [[#Editing_the_Configuration_File|update the configuration]] with the new version. However, checking that the database is in the expected state is still recommended in this case.&lt;br /&gt;
&lt;br /&gt;
What will essentially be accomplished in this step is choosing the best possible option for actions to take in manually altering the database.&lt;br /&gt;
&lt;br /&gt;
=== Read the Update Error Output ===&lt;br /&gt;
In many cases, the error output from the updater will tell you exactly what went wrong in the update. If it is a simple problem, i.e. table/column already exists, and you are mostly certain that this is the only compatibility issue, you can skip a full database comparison and opt rather to try removing any incompatibilities in the database first before attempting to update a second time.&lt;br /&gt;
&lt;br /&gt;
=== Compile The Full Update SQL ===&lt;br /&gt;
To make subsequent tasks easier, one can compile the full list of SQL statements into one file. First, however, it is necessary to compile the chronologically-ordered list of versions. This is important because, while one can iterate over files in data/sqlList, the ordering of files may not result in a listing that accurately reflects the order in which the versions were released.&lt;br /&gt;
&lt;br /&gt;
So, to get the list of files, look for the &amp;quot;versions&amp;quot; property of the json object stored in &amp;lt;tt&amp;gt;update/manifest.json&amp;lt;/tt&amp;gt;, or run the following command to extract it into a file &amp;quot;versionList.txt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  php -r '$m = json_decode(file_get_contents(&amp;quot;update/manifest.json&amp;quot;),1); echo implode(&amp;quot;\n&amp;quot;,$m[&amp;quot;versions&amp;quot;]);' &amp;gt; versionList.txt&lt;br /&gt;
&lt;br /&gt;
Now, with the list of files in &amp;lt;tt&amp;gt;versionList.txt&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
  for v in `cat versionList.txt`; do echo &amp;quot;/* VERSION $v */&amp;quot;; cat update/data/sqlList/$v.sql; done &amp;gt; update.sql&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;update.sql&amp;lt;/tt&amp;gt; will now contain a list of all SQL commands, in chronological order, that are part of the update.&lt;br /&gt;
&lt;br /&gt;
=== Perform a Binary Search for the Current State ===&lt;br /&gt;
This may only be necessary in cases where the database changes were cut short, i.e. a server timeout in the web updater. In this process, one determines which changes have been applied in the update and which have not. It will reveal what if any action is necessary to &amp;quot;repair&amp;quot; the database.&lt;br /&gt;
&lt;br /&gt;
For those unfamiliar with the term, a binary search works as follows:&lt;br /&gt;
# Start with an &amp;quot;upper&amp;quot; and &amp;quot;lower&amp;quot; limit item in the ordered list being searched.&lt;br /&gt;
# Pick an item in the middle of the list, between the upper and lower limits.&lt;br /&gt;
# If the item is before the item we want, change the lower limit to that item. Otherwise, change the upper limit to that item.&lt;br /&gt;
# Repeat steps 1-3 until the desired point in the list is found.&lt;br /&gt;
&lt;br /&gt;
In our case, the ordered list is the full list of SQL to be run in the update, and the desired item is the first database change that didn't get applied. That leaves the binary condition, which is ''choose the lower bound if the change appears to have already been applied, and choose the upper bound if it hasn't been applied.''&lt;br /&gt;
&lt;br /&gt;
To begin, open the .sql file created in the previous part of this step, and:&lt;br /&gt;
# Find the first and last SQL statements.&lt;br /&gt;
# Look in the database schema (and, if necessary, data) for those changes, i.e. the presence of those columns/records. Note:&lt;br /&gt;
#* ''If neither of them have been applied:'' the problem to be fixed is not an incomplete update; it is an incompatible schema, in which case the best option is removing the incompatibilities.&lt;br /&gt;
#* ''If both of them have been applied:'' the issue is that the database is already up-to-date and at the latter version, and so no other action need be taken.&lt;br /&gt;
&lt;br /&gt;
Finding out if a given change has been applied requires basic knowledge of MySQL; for instance, given an &amp;lt;tt&amp;gt;INSERT&amp;lt;/tt&amp;gt; command in the update, one will need to know how to compose an appropriate &amp;lt;tt&amp;gt;SELECT&amp;lt;/tt&amp;gt; statement (or know which buttons to press) to search for and find the records that would be inserted by it.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Determining the Appropriate Course of Action ==&lt;br /&gt;
&lt;br /&gt;
=== If The Database Is Already Up To Date ===&lt;br /&gt;
If this is the case, and you have determined that the database changes have all been applied, then all that remains to be done are the final steps in [[#Performing_Updates_Manually|manually updating]]. Those steps include everything from [[#Copying_new_files|copying the new files]] through [[#Clearing_caches_and_refreshing_the_application|the final clean-up process]], and they are all the easier steps in the process.&lt;br /&gt;
&lt;br /&gt;
=== If The Schema Includes a Known Incompatibility ===&lt;br /&gt;
In this scenario, you have a feature which you know that you added, but it somehow conflicts with a database change to be applied. The way to recover from or get around this this could range from very simple to very complex. For the simpler case, i.e. a column name conflict, you can get around this by renaming the column to something else temporarily, and then copying the data into the newly-created column as desired after the update.&lt;br /&gt;
&lt;br /&gt;
=== If The Schema/Data Contains an Unknown Incompatibility ===&lt;br /&gt;
If the database is incompatible vis-a-vis the updater error messages, and you have no idea why the offending database feature is there (i.e. primary key conflict, table, column, etc), try removing the feature from the database and re-attempting the update. This may have to include anything from dropping tables to deleting records; again, this requires knowledge of MySQL.&lt;br /&gt;
&lt;br /&gt;
=== If The Update Is In a State Between Versions ===&lt;br /&gt;
In this scenario, there are two options worth considering. First, you could try manually applying each subsequent database change and running accompanying migration scripts for each version. In other words, pick up where the database changes left off, as though in the middle of a [[#Performing_Updates_Manually|manual update]].&lt;br /&gt;
&lt;br /&gt;
If there are a very large number of database changes between the state of the database and the final change, one might consider reverting the changes instead, i.e. remove columns that get added. Note, however, that migration scripts cannot be applied in reverse, and so this task may be far less simple if any migration scripts have been run already at the stage that the database is currently in.&lt;br /&gt;
&lt;br /&gt;
In either case, if a working/compatible and sufficiently up-to-date database backup has been made ''before the update attempt'' and is available, one should try to use that and re-attempt the update first, provided that it does not take too long to restore the database.&lt;br /&gt;
&lt;br /&gt;
= Troubleshooting =&lt;br /&gt;
&lt;br /&gt;
== User interface (UI) &amp;quot;bugs&amp;quot; after the update ==&lt;br /&gt;
It is extremely common (and easily remedied) that after an important update, certain features of the user interface of X2Engine may not work properly. This is caused, in nearly all cases, by the web browser's cache, which contains out-of-date copies of X2Engine's essential user interface files. To solve these problems, the first step to try is clearing the cache. A step-by-step guide to doing so is given in [[wikihow:Clear-Your-Browser%27s-Cache]].&lt;br /&gt;
&lt;br /&gt;
== Errors in the updater itself == &lt;br /&gt;
When all else fails, the updater may have to be patched due to an irreconcilable backwards compatibility issue. Fortunately, if one has read/write access to the source files on the webserver, this is straightforward to fix. See [[#Refreshing_and_Updating_the_Updater_Utility|Refreshing and Updating the Updater Utility]].&lt;br /&gt;
&lt;br /&gt;
== Professional Edition not in effect after upgrading ==&lt;br /&gt;
This may be caused by Professional Edition not getting &amp;quot;switched on&amp;quot; properly, despite all the necessary filesystem and database changes already being in effect. First, to see if this scenario applies to you, look for a folder &amp;quot;&amp;lt;tt&amp;gt;reports&amp;lt;/tt&amp;gt;&amp;quot; inside &amp;lt;tt&amp;gt;protected/modules&amp;lt;/tt&amp;gt;, and a table &amp;lt;tt&amp;gt;x2_reports&amp;lt;/tt&amp;gt; in the X2Engine database. If you find these things, you can try the following to enable Professional Edition:&lt;br /&gt;
# Find the file &amp;lt;tt&amp;gt;constants.php&amp;lt;/tt&amp;gt; in the installation directory. Open it in a text editor, and look for the following line: &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;defined('PRO_VERSION') or define('PRO_VERSION',false);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Change &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; on that line, and save the file.&lt;br /&gt;
# Run the following SQL command (replacing &amp;lt;tt&amp;gt;{license key}&amp;lt;/tt&amp;gt; with your X2Engine license key) on the X2Engine database: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;UPDATE `x2_admin` SET `unique_id`='{license key}',`edition`='pro' WHERE `id`=1;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General Procedures to Try ==&lt;br /&gt;
It may sometimes be possible that the update did not finish cleanly. In such cases, it will be necessary to manually re-perform some of the final operations in the update, described in [[#Introduction|Introduction]]. &lt;br /&gt;
&lt;br /&gt;
=== Refresh the Source Code ===&lt;br /&gt;
This step is not really the best step to try first, as it is usually more time-consuming. It entails re-uploading the entire application, in order to reset all non-ephemeral (source code) files to what they should be in a fresh installation of X2Engine. To do this:&lt;br /&gt;
# Download the refresh package. There should be a download link for this in the ''Updater Settings'' page. Otherwise, if that doesn't work and you're using Open Source edition, use [https://x2planet.com/installs/refresh.zip this link], or if using Professional Edition, paste the following url (after replacing {key} with your license key) into your browser's address bar: &amp;lt;pre&amp;gt;https://x2planet.com/installs/{key}/refresh-pro.zip&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Upload the ''contents'' of the downloaded zip archive to the installation directory, overwriting existing files.&lt;br /&gt;
&lt;br /&gt;
=== Clear Caches ===&lt;br /&gt;
See &amp;quot;[[#Clearing_caches_and_refreshing_the_application|Clearing Caches...]]&amp;quot; for details.&lt;br /&gt;
&lt;br /&gt;
=== Regenerate the Configuration ===&lt;br /&gt;
Again, this should not be done unless you are completely certain that all the files (not counting customizations) and the structure of the database are equivalent to a new installation at the same version as the one you updated to. Refer to [[#Editing_the_Configuration_File|Editing the Configuration File]].&lt;/div&gt;</summary>
		<author><name>Derek Mueller</name></author>	</entry>

	</feed>