PluginProbe
If-So Dynamic Content – Elementor & All Page Builders Personalization / trunk
If-So Dynamic Content – Elementor & All Page Builders Personalization vtrunk
1.10.1 1.10.0.1 1.10 1.9.9 1.9.2.2 1.9.3 1.9.3.1 1.9.3.2 1.9.4 1.9.4.1 1.9.5 1.9.5.1 1.9.6 1.9.7 1.9.8 trunk 0.1 1.0 1.0.1 1.0.2 1.0.3 1.0.5 1.0.6 1.0.7 1.0.8 All 100 releases
if-so / extensions / extension-base / lib / plugin-update-checker / README.md

README.md in If-So Dynamic Content – Elementor & All Page Builders Personalization trunk, at extensions/extension-base/lib/plugin-update-checker/README.md

373 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 Plugin Update Checker
2 =====================
3
4 This is a custom update checker library for WordPress plugins and themes. It lets you add automatic update notifications and one-click upgrades to your commercial plugins, private themes, and so on. All you need to do is put your plugin/theme details in a JSON file, place the file on your server, and pass the URL to the library. The library periodically checks the URL to see if there's a new version available and displays an update notification to the user if necessary.
5
6 From the users' perspective, it works just like with plugins and themes hosted on WordPress.org. The update checker uses the default upgrade UI that is familiar to most WordPress users.
7
8 <!-- START doctoc generated TOC please keep comment here to allow auto update -->
9 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
10 **Table of Contents**
11
12 - [](#getting-startedGetting Started](#getting-started](#getting-started)
13 - [](#self-hosted-plugins-and-themesSelf-hosted Plugins and Themes](#self-hosted-plugins-and-themes](#self-hosted-plugins-and-themes)
14 - [](#how-to-release-an-updateHow to Release an Update](#how-to-release-an-update](#how-to-release-an-update)
15 - [](#notesNotes](#notes](#notes)
16 - [](#github-integrationGitHub Integration](#github-integration](#github-integration)
17 - [](#how-to-release-an-update-1How to Release an Update](#how-to-release-an-update-1](#how-to-release-an-update-1)
18 - [](#notes-1Notes](#notes-1](#notes-1)
19 - [](#bitbucket-integrationBitBucket Integration](#bitbucket-integration](#bitbucket-integration)
20 - [](#how-to-release-an-update-2How to Release an Update](#how-to-release-an-update-2](#how-to-release-an-update-2)
21 - [](#gitlab-integrationGitLab Integration](#gitlab-integration](#gitlab-integration)
22 - [](#how-to-release-a-gitlab-updateHow to Release a GitLab Update](#how-to-release-a-gitlab-update](#how-to-release-a-gitlab-update)
23 - [](#migrating-from-4xMigrating from 4.x](#migrating-from-4x](#migrating-from-4x)
24 - [](#license-managementLicense Management](#license-management](#license-management)
25 - [](#resourcesResources](#resources](#resources)
26
27 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
28
29 Getting Started
30 ---------------
31
32 *Note:* In each of the below examples, part of the instructions is to create an instance of the update checker class. It's recommended to do this either during the `plugins_loaded` action or outside of any hooks. If you do it only during an `admin_*` action, then updates will not be visible to a wide variety of WordPress management tools; they will only be visible to logged-in users on dashboard pages.
33
34 ### Self-hosted Plugins and Themes
35
36 1. Download [](https://github.com/YahnisElsts/plugin-update-checker/releases/latestthe latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
37 2. Go to the `examples` subdirectory and open the .json file that fits your project type. Replace the placeholder data with your plugin/theme details.
38 - Plugin example:
39
40 ```json
41 {
42 "name" : "Plugin Name",
43 "version" : "2.0",
44 "download_url" : "https://example.com/plugin-name-2.0.zip",
45 "sections" : {
46 "description" : "Plugin description here. You can use HTML."
47 }
48 }
49 ```
50
51 This is a minimal example that leaves out optional fields. See [this table](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharing) for a full list of supported fields and their descriptions.
52 - Theme example:
53
54 ```json
55 {
56 "version": "2.0",
57 "details_url": "https://example.com/version-2.0-details.html",
58 "download_url": "https://example.com/example-theme-2.0.zip"
59 }
60 ```
61
62 This is actually a complete example that shows all theme-related fields. `version` and `download_url` should be self-explanatory. The `details_url` key specifies the page that the user will see if they click the "View version 1.2.3 details" link in an update notification.
63 3. Upload the JSON file to a publicly accessible location.
64 4. Add the following code to the main plugin file or to the `functions.php` file:
65
66 ```php
67 require 'path/to/plugin-update-checker/plugin-update-checker.php';
68 use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
69
70 $myUpdateChecker = PucFactory::buildUpdateChecker(
71 'https://example.com/path/to/details.json',
72 __FILE__, //Full path to the main plugin file or functions.php.
73 'unique-plugin-or-theme-slug'
74 );
75 ```
76 Note: If you're using the Composer autoloader, you don't need to explicitly `require` the library.
77
78 #### How to Release an Update
79
80 Change the `version` number in the JSON file and make sure that `download_url` points to the latest version. Update the other fields if necessary. Tip: You can use [](https://github.com/YahnisElsts/wp-update-serverwp-update-server](https://github.com/YahnisElsts/wp-update-server](https://github.com/YahnisElsts/wp-update-server) to automate this process.
81
82 By default, the library will check the specified URL for changes every 12 hours. You can force it to check immediately by clicking the "Check for updates" link on the "Plugins" page (it's next to the "Visit plugin site" link). Themes don't have that link, but you can also trigger an update check like this:
83
84 1. Install [](https://srd.wordpress.org/plugins/debug-bar/Debug Bar](https://srd.wordpress.org/plugins/debug-bar/](https://srd.wordpress.org/plugins/debug-bar/).
85 2. Click the "Debug" menu in the Admin Bar (a.k.a Toolbar).
86 3. Open the "PUC (your-slug)" panel.
87 4. Click the "Check Now" button.
88
89 #### Notes
90 - The second argument passed to `buildUpdateChecker` must be the absolute path to the main plugin file or any file in the theme directory. If you followed the "getting started" instructions, you can just use the `__FILE__` constant.
91 - The third argument - i.e. the slug - is optional but recommended. In most cases, the slug should be the same as the name of your plugin directory. For example, if your plugin lives in `/wp-content/plugins/my-plugin`, set the slug to `my-plugin`. If the slug is omitted, the update checker will use the name of the main plugin file as the slug (e.g. `my-cool-plugin.php` &rarr; `my-cool-plugin`). This can lead to conflicts if your plugin has a generic file name like `plugin.php`.
92
93 This doesn't affect themes because PUC uses the theme directory name as the default slug. Still, if you're planning to use the slug in your own code - e.g. to filter updates or override update checker behaviour - it can be a good idea to set it explicitly.
94
95 ### GitHub Integration
96
97 1. Download [](https://github.com/YahnisElsts/plugin-update-checker/releases/latestthe latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
98 2. Add the following code to the main plugin file or `functions.php`:
99
100 ```php
101 require 'plugin-update-checker/plugin-update-checker.php';
102 use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
103
104 $myUpdateChecker = PucFactory::buildUpdateChecker(
105 'https://github.com/user-name/repo-name/',
106 __FILE__,
107 'unique-plugin-or-theme-slug'
108 );
109
110 //Set the branch that contains the stable release.
111 $myUpdateChecker->setBranch('stable-branch-name');
112
113 //Optional: If you're using a private repository, specify the access token like this:
114 $myUpdateChecker->setAuthentication('your-token-here');
115 ```
116 3. Plugins only: Add a `readme.txt` file formatted according to the [](https://wordpress.org/plugins/readme.txtWordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt](https://wordpress.org/plugins/readme.txt) to your repository. The contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
117
118 #### How to Release an Update
119
120 This library supports a couple of different ways to release updates on GitHub. Pick the one that best fits your workflow.
121
122 - **GitHub releases**
123
124 Create a new release using the "Releases" feature on GitHub. The tag name and release title don't matter. The description is optional, but if you do provide one, it will be displayed when the user clicks the "View version x.y.z details" link on the "Plugins" page. Note that PUC ignores releases marked as "This is a pre-release".
125
126 If you want to use release assets, call the `enableReleaseAssets()` method after creating the update checker instance:
127 ```php
128 $myUpdateChecker->getVcsApi()->enableReleaseAssets();
129 ```
130
131 - **Tags**
132
133 To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`. That's it.
134
135 PUC doesn't require strict adherence to [SemVer](https://semver.org/). These are all valid tag names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5`. However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitHub releases or branches instead.
136
137 - **Stable branch**
138
139 Point the update checker at a stable, production-ready branch:
140 ```php
141 $updateChecker->setBranch('branch-name');
142 ```
143 PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version.
144
145 Caveat: If you set the branch to `master` (the default), the update checker will look for recent releases and tags first. It'll only use the `master` branch if it doesn't find anything else suitable.
146
147 #### Notes
148
149 The library will pull update details from the following parts of a release/tag/branch:
150
151 - Version number
152 - The "Version" plugin header.
153 - The latest GitHub release or tag name.
154 - Changelog
155 - The "Changelog" section of `readme.txt`.
156 - One of the following files:
157 CHANGES.md, CHANGELOG.md, changes.md, changelog.md
158 - GitHub release notes.
159 - Required and tested WordPress versions
160 - The "Requires at least" and "Tested up to" fields in `readme.txt`.
161 - The following plugin headers:
162 `Required WP`, `Tested WP`, `Requires at least`, `Tested up to`
163 - "Last updated" timestamp
164 - The creation timestamp of the latest GitHub release.
165 - The latest commit in the selected tag or branch.
166 - Number of downloads
167 - The `download_count` statistic of the latest release.
168 - If you're not using GitHub releases, there will be no download stats.
169 - Other plugin details - author, homepage URL, description
170 - The "Description" section of `readme.txt`.
171 - Remote plugin headers (i.e. the latest version on GitHub).
172 - Local plugin headers (i.e. the currently installed version).
173 - Ratings, banners, screenshots
174 - Not supported.
175
176 ### BitBucket Integration
177
178 1. Download [](https://github.com/YahnisElsts/plugin-update-checker/releases/latestthe latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
179 2. Add the following code to the main plugin file or `functions.php`:
180
181 ```php
182 require 'plugin-update-checker/plugin-update-checker.php';
183 use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
184
185 $myUpdateChecker = PucFactory::buildUpdateChecker(
186 'https://bitbucket.org/user-name/repo-name',
187 __FILE__,
188 'unique-plugin-or-theme-slug'
189 );
190
191 //Optional: If you're using a private repository, create an OAuth consumer
192 //and set the authentication credentials like this:
193 //Note: For now you need to check "This is a private consumer" when
194 //creating the consumer to work around #134:
195 // https://github.com/YahnisElsts/plugin-update-checker/issues/134
196 $myUpdateChecker->setAuthentication(array(
197 'consumer_key' => '...',
198 'consumer_secret' => '...',
199 ));
200
201 //Optional: Set the branch that contains the stable release.
202 $myUpdateChecker->setBranch('stable-branch-name');
203 ```
204 3. Optional: Add a `readme.txt` file formatted according to the [](https://wordpress.org/plugins/readme.txtWordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt](https://wordpress.org/plugins/readme.txt) to your repository. For plugins, the contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
205
206 #### How to Release an Update
207
208 BitBucket doesn't have an equivalent to GitHub's releases, so the process is slightly different. You can use any of the following approaches:
209
210 - **`Stable tag` header**
211
212 This is the recommended approach if you're using tags to mark each version. Add a `readme.txt` file formatted according to the [WordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt) to your repository. Set the "stable tag" header to the tag that represents the latest release. Example:
213 ```text
214 Stable tag: v1.2.3
215 ```
216 The tag doesn't have to start with a "v" or follow any particular format. You can use any name you like as long as it's a valid Git tag.
217
218 Tip: If you explicitly set a stable branch, the update checker will look for a `readme.txt` in that branch. Otherwise it will only look at the `master` branch.
219
220 - **Tags**
221
222 You can skip the "stable tag" bit and just create a new Git tag named `v1.2.3` or `1.2.3`. The update checker will look at the most recent tags and pick the one that looks like the highest version number.
223
224 PUC doesn't require strict adherence to [SemVer](https://semver.org/). These are all valid tag names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5`. However, be warned that it's not smart enough to filter out alpha/beta/RC versions.
225
226 - **Stable branch**
227
228 Point the update checker at a stable, production-ready branch:
229 ```php
230 $updateChecker->setBranch('branch-name');
231 ```
232 PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version. Caveat: If you set the branch to `master`, the update checker will still look for tags first.
233
234 ### GitLab Integration
235
236 1. Download [](https://github.com/YahnisElsts/plugin-update-checker/releases/latestthe latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
237 2. Add the following code to the main plugin file or `functions.php` and define how you want to check for updates from Gitlab (refer to: [](#how-to-release-a-gitlab-updateGitlab: How to Release an Update](#how-to-release-a-gitlab-update](#how-to-release-a-gitlab-update)):
238
239 ```php
240 require 'plugin-update-checker/plugin-update-checker.php';
241 use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
242
243 $myUpdateChecker = PucFactory::buildUpdateChecker(
244 'https://gitlab.com/user-name/repo-name/',
245 __FILE__,
246 'unique-plugin-or-theme-slug'
247 );
248
249 //Optional: If you're using a private repository, specify the access token like this:
250 $myUpdateChecker->setAuthentication('your-token-here');
251 ```
252
253 Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
254 ```php
255 use YahnisElsts\PluginUpdateChecker\v5p6\Vcs\PluginUpdateChecker;
256 use YahnisElsts\PluginUpdateChecker\v5p6\Vcs\GitLabApi;
257
258 $myUpdateChecker = new PluginUpdateChecker(
259 new GitLabApi('https://myserver.com/user-name/repo-name/'),
260 __FILE__,
261 'unique-plugin-or-theme-slug'
262 );
263 //Optional: Add setAuthentication(...) and setBranch(...) as shown above.
264 ```
265 If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups:
266 ```php
267 use YahnisElsts\PluginUpdateChecker\v5p6\Vcs\PluginUpdateChecker;
268 use YahnisElsts\PluginUpdateChecker\v5p6\Vcs\GitLabApi;
269
270 $myUpdateChecker = new PluginUpdateChecker(
271 new GitLabApi(
272 'https://myserver.com/group-name/subgroup-level1/subgroup-level2/subgroup-level3/repo-name/',
273 null,
274 'subgroup-level1/subgroup-level2/subgroup-level3'
275 ),
276 __FILE__,
277 'unique-plugin-or-theme-slug'
278 );
279 ```
280
281 3. Plugins only: Add a `readme.txt` file formatted according to the [](https://wordpress.org/plugins/readme.txtWordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt](https://wordpress.org/plugins/readme.txt) to your repository. The contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
282
283 #### How to Release a GitLab Update
284
285 A GitLab repository can be checked for updates in 3 different ways.
286
287 - **GitLab releases**
288
289 Create a new release using the "Releases" feature on GitLab. The tag name should match the version number. You can add a `v` prefix to the tag, like `v1.2.3`. Releases that are marked as ["Upcoming Release"](https://docs.gitlab.com/ee/user/project/releases/index.html#upcoming-releases) will be automatically ignored.
290
291 If you want to use custom release assets, call the `enableReleaseAssets()` method after creating the update checker instance:
292 ```php
293 $myUpdateChecker->getVcsApi()->enableReleaseAssets();
294 ```
295
296 By default, PUC will use the first available asset link, regardless of type. You can pass a regular expression to `enableReleaseAssets()` to make it pick the first link where the URL matches the regex. For example:
297 ```php
298 $myUpdateChecker->getVcsApi()->enableReleaseAssets('/\.zip($|[?&#])/i');
299 ```
300
301 **Tip:** You can use a Gitlab CI/CD Pipeline to automatically generate your update on release using a Generic Package. For more information about generic packages, refer to the following links:
302 - [Gitlab CI/CD Release Documentation](https://docs.gitlab.com/ee/user/project/releases/#create-release-from-gitlab-ci)
303 - [Gitlab Release Assets as Generic Package Documentation](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/)
304 - [Example .gitlab-ci.yml file using Release Generic Packages for generating a update package from the Sensei-LMS wordpress plugin](https://gist.github.com/timwiel/9dfd3526c768efad4973254085e065ce)
305
306 - **Tags**
307
308 To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`. The update checker will look at recent tags and use the one that looks like the highest version number.
309
310 PUC doesn't require strict adherence to [SemVer](https://semver.org/). However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitLab branches instead.
311
312 - **Stable branch**
313
314 Point the update checker at any stable, production-ready branch:
315 ```php
316 $myUpdateChecker->setBranch('stable-branch-name');
317 ```
318 PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version. Caveat: Even if you set the branch to `main` (the default) or `master` (the historical default), the update checker will still look for recent releases and tags first.
319
320 Migrating from 4.x
321 ------------------
322
323 Older versions of the library didn't use namespaces. Code that was written for those versions will need to be updated to work with the current version. At a minimum, you'll need to change the factory class name.
324
325 Old code:
326 ```php
327 $myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
328 'https://example.com/info.json',
329 __FILE__,
330 'my-slug'
331 );
332 ```
333
334 New code:
335 ```php
336 use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
337
338 $myUpdateChecker = PucFactory::buildUpdateChecker(
339 'https://example.com/info.json',
340 __FILE__,
341 'my-slug'
342 );
343 ```
344
345 Other classes have also been renamed, usually by simply removing the `Puc_vXpY_` prefix and converting `Category_Thing` to `Category\Thing`. Here's a table of the most commonly used classes and their new names:
346
347 | Old class name | New class name |
348 |-------------------------------------|----------------------------------------------------------------|
349 | `Puc_v4_Factory` | `YahnisElsts\PluginUpdateChecker\v5\PucFactory` |
350 | `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p6\PucFactory` |
351 | `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p6\Plugin\UpdateChecker` |
352 | `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p6\Theme\UpdateChecker` |
353 | `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p6\Vcs\PluginUpdateChecker` |
354 | `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p6\Vcs\ThemeUpdateChecker` |
355 | `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p6\Vcs\GitHubApi` |
356 | `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p6\Vcs\GitLabApi` |
357 | `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p6\Vcs\BitBucketApi` |
358
359 License Management
360 ------------------
361
362 Currently, the update checker doesn't have any built-in license management features. It only provides some hooks that you can use to, for example, append license keys to update requests (`$updateChecker->addQueryArgFilter()`). If you're looking for ways to manage and verify licenses, please post your feedback in [](https://github.com/YahnisElsts/plugin-update-checker/issues/222this issue](https://github.com/YahnisElsts/plugin-update-checker/issues/222](https://github.com/YahnisElsts/plugin-update-checker/issues/222).
363
364 Resources
365 ---------
366
367 - [](https://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/This blog post](https://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/](https://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/) has more information about the update checker API. *Slightly out of date.*
368 - [](https://wordpress.org/plugins/debug-bar/Debug Bar](https://wordpress.org/plugins/debug-bar/](https://wordpress.org/plugins/debug-bar/) - useful for testing and debugging the update checker.
369 - [](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharingUpdate format reference](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharing](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharing) - describes all fields supported by the JSON-based update information format used by the update checker. Only covers plugins. Themes use a similar but more limited format.
370 - [](https://w-shadow.com/blog/2013/03/19/plugin-updates-securing-download-links/Securing download links](https://w-shadow.com/blog/2013/03/19/plugin-updates-securing-download-links/](https://w-shadow.com/blog/2013/03/19/plugin-updates-securing-download-links/) - a general overview.
371 - [](https://open-tools.net/documentation/tutorial-automatic-updates.html#wordpressA GUI for entering download credentials](https://open-tools.net/documentation/tutorial-automatic-updates.html#wordpress](https://open-tools.net/documentation/tutorial-automatic-updates.html#wordpress)
372 - [](https://w-shadow.com/blog/2011/06/02/automatic-updates-for-commercial-themes/Theme Update Checker](https://w-shadow.com/blog/2011/06/02/automatic-updates-for-commercial-themes/](https://w-shadow.com/blog/2011/06/02/automatic-updates-for-commercial-themes/) - an older, theme-only variant of this update checker.
373