UpgradeMODX provides a dashboard widget that checks for available upgrades to MODX and (optionally) installs them. The upgrade process is automatic and very simple. It shows you a form with available versions to install (you can set how many it shows). Once you've selected one, UpgradeMODX downloads all the files, puts them in place, and launches Setup. It should upgrade *any* version of MODX except the SDK development version. It should correctly upgrade versions with a moved and/or renamed manager, core, connectors, assets, or processors directory. I think it will upgrade the SDK version to the non-SDK version, but I haven't tested that.

Upgrade MODX is only for upgrades. It will not install a fresh MODX site.

(Jump to Properties Table)

The pl versions of UpgradeMODX has been tested more extensively than the beta and rc versions, but you are still strongly advised to make a full backup of the database and all files and be prepared to restore the site if things go wrong.

For testing purposes, clicking on the "Upgrade MODX" button in the widget will not alter your site in any way (though all users will be logged out). Nothing happens until you click on the green "Upgrade" button in the upgrade form the widget button launches. The danger is that the upgrade script will download and place all the files, but Setup will fail for some reason. I've never had this happen, but if it does, you'll be left with a mixed site that may be broken. You can try to fix the problem and re-run Setup. If Setup completes with no problems, you should be fine.

Also for testing purposes (and for fixing any corrupted MODX files), when an upgrade is available, you can "upgrade" MODX to the version you currently have. UpgradeMODX will go through all of its steps, download and replace all the MODX files, and launch setup. In theory, UpgradeMODX can also be used to "downgrade" MODX to a previous version, though this has not been extensively tested.

If you have moved your core directory, you'll get a red warning message during Setup telling you that your core path is invalid. This is normal. Just correct the core path, and Setup will work fine.

### Installing UpgradeMODX

Go to Extras -> Installer (or System -> Package Management in older versions of MODX) on the main menu in the MODX Manager and click on the "Download Extras" button. That will take you to the Revolution Repository (AKA Web Transport Facility). Put UpgradeMODX in the search box and press Enter. Click on the "Download" button, and once the package is downloaded, click on the "Back to Package Manager" button. That should bring you back to your Package Management grid. Click on the "Install" button next to UpgradeMODX in the grid. The UpgradeMODX package should now be installed.

### Credits

This package was inspired by the work of a number of people and I have borrowed some of their code. Dmytro Lukianenko (dmi3yy) is the original author of the MODX install script. Susan Sottwell, Sharapov, Bumkaka, Inreti, Zaigham Rana, frischnetz, and AgelxNash, also contributed and I'd like to thank all of them for laying the groundwork.

Here is a list of some of the new features I've added to UpgradeMODX as compared to the original Installer script:

- Launches the upgrade and setup from inside the Manager
- Notifies you of available updates
- No need to change the code — the list of versions is dynamic and obtained from GitHub
- Upgrades very old versions of MODX Revolution (tested on 2.0.3)
- Upgrades versions of MODX with moved/renamed directories
- Uses PclZip if ZipArchive is not available
- Uses fopen if cURL is not available
- Adds the `&forcePclZip` property to bypass ZipArchive
- Adds the `&forceFopen` property to bypass cURL for the download
- Logs upgrades to the MODX Manager Actions log
- Adds a snippet property to control cURL SSL_VERIFY_PEER option

### Usage

To upgrade your site, just click on the "Upgrade MODX" button in the widget. That will launch the form where you can select a version to upgrade to. Downloading and extracting the files may take some time, so be patient.

Once you've installed UpgradeMODX, the widget should appear. It's attached to the default dashboard, so if you have another dashboard showing, you'll have to attach it to that dashboard by going to System (gear icon) -> Dashboards.

In very old versions of MODX, creation of the dashboard widget will fail and you'll see a bunch of error messages during the install. The UpgradeMODX installer will attempt to create a resource called `UpgradeMODX` that will show the install check. If no widget appears, view the resource to check for MODX upgrades. When an upgrade is available, it will let you launch the installer.

If the snippet and chunks fail to install (this if fairly rare), your version of PHP is too new for your MODX install and you'll have trouble saving chunks and snippets in the Manager as well. You can either downgrade the version of PHP to version 5.4 or below, or manually make the changes to the three files shown in this commit.

Once you've upgraded MODX to a recent-enough version, you can uninstall and re-install UpgradeMODX to get the widget.

As installed, the widget will only appear for members of the Administrator group. To show it to other groups, change the `&groups` property of the UpgradeMODXWidget snippet. You can also change the `&interval` property if you'd like it to check for upgrades more or less often.

Hint: To get to the Manager's dashboard, you can click on the MODX logo at the upper left.

Note that if you set the interval to 60 seconds (as it is in the beta and rc versions), it won't execute every 60 seconds. It will only execute when you visit the dashboard at least 60 seconds after the last check. The minimum recommendation for the `&interval` property on a production site is `1 day`.

By default, UpgradeMODX considers only pl (stable) versions for upgrade (except in the beta and rc versions). You can change the `&plOnly` property to see all versions. You can change the `&versionsToShow` property to show more versions (the default is 5). Initially, the interval for checking is set to `1 week` (except in the beta and rc versions where it's 60 seconds). You can change that by setting the `&interval` property. That property should always be an integer followed by the name of the unit (e.g., 6 hours, 3 days, 1 week, 1 month.

If you would like to hide the widget when no upgrade is available, change the `&hideWhenNoUpgrade` property. The widget will still check for upgrades at the selected interval, but won't appear in the dashboard(s) unless an upgrade exists and is available for download.

If you would like to fool the widget into thinking there is an upgrade, you can change the `settings_version` System Setting. Make it any earlier version and the widget will show an update. If you install the update (even though it's not an update) and finish Setup, it will restore the System Setting to its correct value. If you don't run an upgrade, be sure to change the System Setting back to its original value.

You can set the language used by the widget with the `&language` property

When checking, the widget will make one cURL or fopen call to GitHub even if there is no upgrade available. If there is a new version, it will make another cURL or fopen call to the MODX site to see if it's available at `modx.com/download`.

If either site is slow to respond, or you're on a slow internet connection, cURL or fopen will time out and the last check value won't be reset (you should see error messages in the widget if it's set to show all the time). UpgradeMODX will check again on the next load of the dashboard. Usually, reloading the dashboard page will solve it. This could happen over and over and cause slow loading of the dashboard until the sites respond within the time limit. If it's a significant issue, change the `&githubTimeout` and `&modxTimeout` properties and/or the `&attempts` property.

You are *strongly* advised not to change anything in the package except the snippet properties. Be aware that the snippet properties will revert to their defaults if you upgrade or re-install UpgradeMODX. This is because, at this writing, snippet-type widgets can't use property sets and have no tag to edit.

### Security

The upgrade script is stored in a chunk. The widget copies it to the MODX root when you click on the "Upgrade MODX" button in the widget. It can't be run in any other way and it's deleted when the upgrade script finishes. Even if it were available to anyone, it wouldn't run because it contains a placeholder that contains the versions of MODX to show. It the placeholder is not set, no version will appear in the form.

The upgrade script downloads everything to the `/ugmtemp` directory in the MODX root directory. It deletes that directory and itself when it finishes successfully so nothing should be left behind after the upgrade.

After upgrading the site, It's a good idea to make sure that the `upgrade.php` file in the MODX root directory, the modx.zip file, and the `/ugmtemp` directory, also in the MODX root directory, have been removed, especially if the script times out or fails. The files are relatively harmless, but their existence could identify your site as a MODX site, and there's no point in giving potential hackers that information.

### GitHub API Rate Limit Exceeded

The default install of UpgradeMODX makes anonymous requests to the MODX repository at GitHub for information. Requests of this type are limited to 60 per hour. If a lot of people are making requests, or your `&interval` setting is very short, or if you are doing a lot of testing, this limit could be hit and you will get the error message: `GitHub API Rate Limit Exceeded`. You can try again later, but to solve this problem permanently, you can get your own GitHub token so your requests will not be anonymous. That will bump your limit up to 5,000 requests per hour.

You can create a free account at GitHub, or use an existing one. To get a token, follow the directions here. Copy your token to the clipboard, then paste it into the `&github_token` property of the UpgradeMODXWidget snippet. Enter your GitHub username in the `github_username` property. Don't forget to save the snippet.

Because the UpgradeMODXWidget snippet properties will be overwritten by upgrades to the UpgradeMODX package, you may choose to leave the `&github_token` and `github_username` properties empty and create matching System Settings. As long as the 'key' fields of the properties are `github_username` and `github_token`, and the 'value' field is correct, the other fields of the System Setting don't matter. You can create System Settings for any of the snippet properties.

### Troubleshooting

If you get frequent timeouts, you can increase the `&githubTimeout` or `&modxTimeout` properties. They set how long the program will wait for a response. The default is 6 seconds. There is also the `&attempts` property, which determines how many times the script will try to connect. By default, the script will make two tries at each site. Feel free to change the value.

By default, UpgradeMODX uses cURL to check for and download files and ZipArchive to unzip them. If cURL isn't working for you, you can set the `&forceFopen` property to `Yes` to avoid using cURL altogether. Similarly, you can set the `&forcePclZip` property to `Yes` to avoid using ZipArchive to unzip the downloaded MODX file.

Version 1.5.1 of UpgradeMODX sets the cURL SSL_VERIFY_PEER option to `true` by default. It also provides a certificate file in the package, so there should be no need to turn it off. Having this setting off leaves you vulnerable to man-in-the-middle attacks where the attacker could pretend to be the MODX repo and lead you to download malicious code instead of MODX.

UpgradeMODX stores the list of the latest available versions of MODX in a file called `versionlist`. That file is used to create the form that allows you to select the version to install. By default, the `versionlist` file is located in the `{core_path}cache/upgrademodx/` directory. You can specify another directory with the `&versionListPath` property. Use only the directory (minus the filename) in the property and be sure it ends with a slash. UpgradeMODX will translate both `{core_path}` and `{assets_path}` in the property value. The path can also be a hard-coded full path. Here's an example:

    {assets_path}components/upgrademodx/

### UpgradeMODX Properties

Property | Description | Default
--- | --- | ---
attempts | Number of tries to get date from MODX or GitHub | 2
forceFopen | Force the use of fopen instead of cURL for the download | No
forcePclZip | Force the use of PclZip instead of ZipArchive | No
github_token | (optional) Token for GitHub - available from your GitHub profile |
github_username | (optional) Your GitHub username |
githubTimeout | Timeout (in seconds) for requests to GitHub | 6
groups | group, or commma-separated list of groups, who will see the widget | Administrator
hideWhenNoUpgrade | Hide widget when no upgrade is available | No
interval | Interval between checks -- Examples: 1 week, 3 days, 6 hours | 1 week
language | Two-letter code of language to use | en
lastCheck | Date and time of last check -- set automatically |
latestVersion | Latest version (at last check) -- set automatically |
modxTimeout | Timeout (in seconds) for requests to MODX | 6
plOnly | Show only pl (stable) versions | Yes
ssl_verify_peer | For security, have cURL verify the identity of the server | Yes (strongly recommended)
versionListPath | Path to versionlist file (minus the filename -- should end in a slash) | {core_path}cache/upgrademodx/
versionsToShow | Number of versions to show in upgrade form (not widget) | 5