A custom update API for WordPress plugins and themes

Overview

WP Update Server

A custom update API for WordPress plugins and themes.

Features

  • Provide updates for plugins and themes.

    From the users perspective, the updates work just like they do with plugins and themes listed in the official WordPress.org directory.

  • Easy to set up.

    Just upload the script directory to your server and drop a plugin or theme ZIP in the packages subdirectory. Now you have a working update API at http://yourserver.com/wp-update-server/?action=get_metadata&slug=your-plugin.

  • Easy to integrate with existing plugins and themes.

    All it takes is about 5 lines of code. See the plugin update checker and theme update checker docs for details, or just scroll down to the "Getting Started" section for the short version.

  • Minimal server requirements.

    The server component requires PHP 5.3+ and the Zip extension. The client library only requires PHP 5.2 - same as the current version of WordPress.

  • Designed for extensibility.

    Want to secure your upgrade download links? Or use a custom logger or cache? Maybe your plugin doesn't have a standard readme.txt and you'd prefer to load the changelog and other update meta from the database instead? Create your own customized server by extending the Wpup_UpdateServer class. See examples below.

Getting Started

Setting Up the Server

This part of the setup process is identical for both plugins and themes. For the sake of brevity, I'll describe it from the plugin perspective.

  1. Upload the wp-update-server directory to your site. You can rename it to something else (e.g. updates) if you want.
  2. Make the cache and logs subdirectories writable by PHP.
  3. Create a Zip archive of your plugin's directory. The name of the archive must be the same as the name of the directory + ".zip".
  4. Copy the Zip file to the packages subdirectory.
  5. Verify that the API is working by visiting /wp-update-server/?action=get_metadata&slug=plugin-directory-name in your browser. You should see a JSON document containing various information about your plugin (name, version, description and so on).

Tip: Use the JSONView extension (Firefox, Chrome) to pretty-print JSON in the browser.

When creating the Zip file, make sure the plugin files are inside a directory and not at the archive root. For example, lets say you have a plugin called "My Cool Plugin" and it lives inside /wp-content/plugins/my-cool-plugin. The ZIP file should be named my-cool-plugin.zip and it should contain the following:

/my-cool-plugin
    /css
    /js
    /another-directory
    my-cool-plugin.php
    readme.txt
    ...

If you put everything at the root, update notifications may show up just fine, but you will run into inexplicable problems when you try to install an update because WordPress expects plugin files to be inside a subdirectory.

Integrating with Plugins

Now that you have the server ready to go, the next step is to make your plugin query it for updates. We'll use the plugin-update-checker library to achieve that.

  1. Download the update checker.

  2. Move the plugin-update-checker directory to your plugin's directory.

  3. Add the following code to your main plugin file:

    require 'path/to/plugin-update-checker/plugin-update-checker.php';
    $MyUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
    	'http://example.com/wp-update-server/?action=get_metadata&slug=plugin-directory-name', //Metadata URL.
    	__FILE__, //Full path to the main plugin file.
    	'plugin-directory-name' //Plugin slug. Usually it's the same as the name of the directory.
    );
  4. When you're ready to release an update, just zip the plugin directory as described above and put it in the packages subdirectory on the server (overwriting the previous version).

The library will check for updates twice a day by default. If the update checker discovers that a new version is available, it will display an update notification in the WordPress Dashboard and the user will be able to install it by clicking the "upgrade now" link. It works just like with plugins hosted on WordPress.org from the users' perspective.

See the update checker docs for detailed usage instructions and and more examples.

Tip: Create a readme.txt file for your plugin. If you have one, the update server will use it to generate the plugin information page that users see when they click the "View version x.y.z details" link in an update notification. The readme must conform to the WordPress.org readme standard.

Note: Your plugin or theme must be active for updates to work. One consequence of this is that on a multisite installation updates will only show up if your plugin is active on the main site. This is because only plugins that are enabled on the main site are loaded in the network admin. For reference, the main site is the one that has the path "/" in the All Sites list.

Integrating with Themes

  1. Download the theme update checker library.

  2. Place the theme-updates directory in your includes or the equivalent.

  3. Add this snippet to your functions.php:

    require 'path/to/theme-updates/theme-update-checker.php';
    $MyThemeUpdateChecker = new ThemeUpdateChecker(
    	'theme-directory-name', //Theme slug. Usually the same as the name of its directory.
    	'http://example.com/wp-update-server/?action=get_metadata&slug=theme-directory-name' //Metadata URL.
    );
  4. Add a Details URI header to your style.css:

    Details URI: http://example.com/my-theme-changelog.html

    This header specifies the page that the user will see if they click the "View version x.y.z details" link in an update notification. Set it to the URL of your "What’s New In Version z.y.z" page or the theme homepage.

Like with plugin updates, the theme update checker will query the server for theme details every 12 hours and display an update notification in the WordPress Dashboard if a new version is available.

See the theme update checker docs for more information.

Update: The plugin-update-checker library now also supports theme updates. The old theme update checker is no longer actively maintained.

Advanced Topics

Logging

The server logs all API requests to the /logs/request.log file. Each line represents one request and is formatted like this:

[timestamp] IP_address	action	slug	installed_version	wordpress_version	site_url	query_string

Missing or inapplicable fields are replaced with a dash "-". The logger extracts the WordPress version and site URL from the "User-Agent" header that WordPress adds to all requests sent via its HTTP API. These fields will not be present if you make an API request via the browser or if the header is removed or overriden by a plugin (some security plugins do that).

Extending the server

To customize the way the update server works, create your own server class that extends Wpup_UpdateServer and edit the init script (that's index.php if you're running the server as a standalone app) to load and use the new class.

For example, lets make a simple modification that disables downloads and removes the download URL from the plugin details returned by the update API. This could serve as a foundation for a custom server that requires authorization to download an update.

Add a new file MyCustomServer.php to wp-update-server:

class MyCustomServer extends Wpup_UpdateServer {
	protected function filterMetadata($meta, $request) {
		$meta = parent::filterMetadata($meta, $request);
		unset($meta['download_url']);
		return $meta;
	}
	
	protected function actionDownload(Wpup_Request $request) {
		$this->exitWithError('Downloads are disabled.', 403);
	}
}

Edit index.php to use the new class:

require __DIR__ . '/loader.php';
require __DIR__ . '/MyCustomServer.php';
$server = new MyCustomServer();
$server->handleRequest();

Running the server from another script

While the easiest way to use the update server is to run it as a standalone application, that's not the only way to do it. If you need to, you can also load it as a third-party library and create your own server instance. This lets you filter and modify query arguments before passing them to the server, run it from a WordPress plugin, use your own server class, and so on.

To run the server from your own application you need to do three things:

  1. Include /wp-update-server/loader.php.
  2. Create an instance of Wpup_UpdateServer or a class that extends it.
  3. Call the handleRequest($queryParams) method.

Here's a basic example plugin that runs the update server from inside WordPress:

updateServer->handleRequest(array_merge($_GET, array( 'action' => get_query_var('update_action'), 'slug' => get_query_var('update_slug'), ))); } } } class MyCustomServer extends Wpup_UpdateServer { protected function generateDownloadUrl(Wpup_Package $package) { $query = array( 'update_action' => 'download', 'update_slug' => $package->slug, ); return self::addQueryArg($query, $this->serverUrl); } } $examplePlugin = new ExamplePlugin();">

/*
Plugin Name: Plugin Update Server
Description: An example plugin that runs the update API.
Version: 1.0
Author: Yahnis Elsts
Author URI: http://w-shadow.com/
*/

require_once __DIR__ . '/path/to/wp-update-server/loader.php';

class ExamplePlugin {
	protected $updateServer;

	public function __construct() {
		$this->updateServer = new MyCustomServer(home_url('/'));
		
		//The "action" and "slug" query parameters are often used by the WordPress core
		//or other plugins, so lets use different parameter names to avoid conflict.
		add_filter('query_vars', array($this, 'addQueryVariables'));
		add_action('template_redirect', array($this, 'handleUpdateApiRequest'));
	}
	
	public function addQueryVariables($queryVariables) {
		$queryVariables = array_merge($queryVariables, array(
			'update_action',
			'update_slug',
		));
		return $queryVariables;
	}
	
	public function handleUpdateApiRequest() {
		if ( get_query_var('update_action') ) {
			$this->updateServer->handleRequest(array_merge($_GET, array(
				'action' => get_query_var('update_action'),
				'slug'   => get_query_var('update_slug'),
			)));
		}
	}
}

class MyCustomServer extends Wpup_UpdateServer {
    protected function generateDownloadUrl(Wpup_Package $package) {
        $query = array(
            'update_action' => 'download',
            'update_slug' => $package->slug,
        );
        return self::addQueryArg($query, $this->serverUrl);
    }
}

$examplePlugin = new ExamplePlugin();

Note: If you intend to use something like the above in practice, you'll probably want to override Wpup_UpdateServer::generateDownloadUrl() to customize the URLs or change the query parameters.

Securing download links

See this blog post for a high-level overview and some brief examples.

Analytics

You can use the wp-update-server-stats tool to parse server logs and display statistics like the number of active installs, active versions, and so on.

Comments
  • Split off metadata

    Split off metadata

    As - unlike with the Headers class -, the static methods in the Package class can not easily be overloaded, I'd suggest splitting them off into a separate Metadata class which can be overloaded.

    This will make it a lot easier to add additional information to the metadata for a package. All you need to do is extend the Metadata class and overload the $cacheTime $headerMap, $readmeMap and/or constructor to add additional data. You will of course also need to overload the Package::fromArchive() method to use your extended class rather than the original, but as it's now a small method, it doesn't break the upgrade path as much as before.

    Simple example code for how this could now be overloaded:

    class My_Metadata extends Wpup_Metadata {
    
        protected $headerMapExtra = array(
            'Text Domain' => 'textdomain',
        );
    
        protected $readmeMapExtra = array(
            'short_description',
        );
    
        public function __construct( $slug, $filename, Wpup_Cache $cache = null ) {
            $this->headerMap = array_merge( $this->headerMap, $this->headerMapExtra );
            $this->readmeMap = array_merge( $this->readmeMap, $this->readmeMapExtra );
    
            parent::__construct( $slug, $filename, $cache );
        }
    
        protected function extractMetadata() {
            $metadata = parent::extractMetadata();
            if ( ! is_array( $metadata ) ) {
                return null;
            }
    
            // Add additional metadata
            $metadata['type'] = $this->packageInfo['type'];
    
            return $metadata;
        }
    }
    
    opened by jrfnl 15
  • Can't use update server as a plugin on a wordpress installation

    Can't use update server as a plugin on a wordpress installation

    includes/WPup/UpdateServer.php:line 148 function validateRequest throws You must specify an action.

    This is not practical when the update server is installed as a WordPress Plugin since it throws:

    400 Bad Request You must specify an action.

    When a visitor is visiting the homepage then the plugin shouldn't check for action. Instead should just let WordPress do its thing and serve the homepage instead of json.

    opened by sharmashivanand 11
  • Updates working but

    Updates working but "progress" gear busy "ad infinitum"

    Good day Yahnis. First of all thanks for the outstanding job. I've followed your instructions and I'm able to download and install my plugin's updates from the wp-update-server. If I fire up the update process from the "update-core" core page (i.e.: http://myexmaplesite.com/wordpress/wp-admin/update-core.php for example), the update process is flawless. Each phase is displayed while in progress (maintenance mode activation, zip file download, decompression, etc.) and, at the end, a message notifies me of the successful update. On the other hand, if I do the same, but from the "installed plugins" page (i.e.: http://myexamplesite.com/wordpress/wp-admin/plugins.php) the process apparently freezes. The page displays correctly an "update available" warning, but after clicking the "update now" button the "progress gear" starts revolving, the "please wait" notice is displayed but nothing more happens. If i try to abandon the page, Wordpress warns me that an update is in progress and if I forcibly leave the page, this could break my plugin. Well, actually this doesn't happen. Actually the plugin is updated correctly. In fact if you forcibly leave the page and reload the plugin page you can see that the plugin has been updated successfully. So the problem is, apparently, that Wordpress is awaiting for some form of notification at the end of the process that the update-server doesn't give. By the way, I'm using wp 4.2.2. Thank you again for your help

    opened by caraffa 11
  • Sudenly I get: Update failed: You have the latest version of the plugin.

    Sudenly I get: Update failed: You have the latest version of the plugin.

    Hi, please help me with this. Everything was working fine, and sudenly when I click "Update now" on the WP Plugins list, i get the message: "Update failed: You have the latest version of the plugin."

    I didn't make any recent changes, and since the begining the only modification was creating a new PHP file: download-auth.php

    
    class UpdateServerAuth extends Wpup_UpdateServer {
    
    	protected $license_key = "my-secret-license-key-xD";
    
    	public function __construct() {
    		parent::__construct();
    	}
    
    	protected function filterMetadata($meta, $request) {
    
    		$meta = parent::filterMetadata($meta, $request);
    
    		//Include license information in the update metadata. This saves an HTTP request
    		//or two since the plugin doesn't need to explicitly fetch license details.
    		if( $request->param('license_key') && $request->param('license_key') == $this->license_key ){
    			$meta['license_status'] = 'License valid';
    		} else {
    			//No license = no download link.
    			$meta['license_status'] = 'License invalid';
    			//unset($meta['download_url']);
    		}
    
    		return $meta;
    
    	}
    
    	protected function checkAuthorization($request) {
    
    		parent::checkAuthorization($request);
    
    		if( $request->action==='download' ) {
    
    			//Prevent download if the user doesn't have a valid license.
    			if( empty($request->param('license_key')) || $request->param('license_key') != $this->license_key ){
    				// Provided @license_key not valid
    				$message = 'Sorry, your license is not valid.';
    				//$this->exitWithError($message, 403);
    			}
    
    		}
    
    	}
    
    }
    
    

    As you can see I tried to comment the line unset($meta['download_url']); and $this->exitWithError($message, 403); which could be causing some problem, but with no luck.

    opened by cristian-dan-f 10
  • Made an Envato Compatible Server

    Made an Envato Compatible Server

    Hello,

    First of all thank you very much for this. It has helped me setup an update server for my envato plugins in just one day. I am really grateful to what you have offered. I have also open sourced my work here https://github.com/WPQuark/wpq-wp-update

    I have a few favors to ask you:

    1. Right now composer package points to an outdated version. The current one has support for banners, which is awesome. So I used the latest commit tag to include in my composer, but would love to have a release.
    2. Instead of logging into file, I am logging into database. Any tips on generating graphs from the database? I have seen your stat package and was wondering where do I need to look for the chart queries?

    Thank you once again.

    opened by swashata 10
  • Problems adding licens to plugin

    Problems adding licens to plugin

    I followed this post! and i manage to fix the server part but when try to access with the web browser says Server error 500

    http://mysite.com/?action=get_metadata&slug=myplugin&installed_version=1.0.0&license_key=3f4324-g32se4-32b

    Warning: The URL http://mysite.com/?action=get_metadata&slug=myplugin&installed_version=1.0.0&license_key=3f4324-g32se4-32b does not point to a valid plugin metadata file. HTTP response code is 500 (expected: 200) in /var/www/mysite/htdocs/wp-content/plugins/myplugin/plugin-update-checker/plugin-update-checker.php on line 246
    
    opened by ghost 10
  • WP-Network Compatibility

    WP-Network Compatibility

    Hi YahnisElsts, I'm experiencing the following issue: Clicking on "check for updates" makes call to update server correctly and get response but there is no "update plugin" afterwards to allow me to install the update. This issue is only present on my wp-network installation on the same server (nginx, not apache). I have tried installing my plugin a wp installation on a godaddy server and it worked perfectly so i think the problem is with wp-network compatibility.

    Here are two log entries, the first is from my wp-network that doesn't work, the second from the godaddy wp that did work

    [2013-03-31 01:31:53] 173.255.201.162 get_metadata wb-sales 0.2 3.5.1 http://wp.home.idea-team.org/findyourgggspot action=get_metadata&slug=wb-sales&checking_for_updates=1&installed_version=0.2 [2013-03-31 01:38:35] 188.121.41.140 get_metadata wb-sales 0.2 3.5.1 http://www.carlyhope.com action=get_metadata&slug=wb-sales&checking_for_updates=1&installed_version=0.2

    could the issue be with the network install path looking like a sub-directory install?

    Please let me know if there are other test i can run that you can think of.

    opened by smira2000 10
  • where I have to put example-theme.zip and which class is correct ?

    where I have to put example-theme.zip and which class is correct ?

    1. my question is, where I have to put example-theme.zip ? in the packages directory? I also like to say that when I place example-theme.zip in packages directory in wp-update-server and check this url : (http://localhost/wp-update-server/?action=get_metadata&slug=example-theme) in the browser, I receive this response json in browser: { "name": "example-theme", "version": "1.8", "homepage": "http://localhost/example-theme/", "author": "the WordPress team", "author_homepage": "http://localhost/", "details_url": "http://localhost/my-theme-changelog/my-theme-changelog.html", "last_updated": "2021-05-21 11:24:06", "slug": "example-theme", "download_url": "http://localhost/wp-update-server/?action=download&slug=example-theme", "request_time_elapsed": "0.018" }
    2. which class is correct ? (Puc_v4_Factory::buildUpdateChecker or ThemeUpdateChecker) for functions.php in my example-theme

    thankyou alot

    opened by Alireza-Ghavabesh 9
  • Server issue

    Server issue

    If I go to the download link in my browser, it downloads it fine, but using cURL, I get the following error

    400 Bad Request

    You must specify a package slug.

    Wordpress reports the download link as 'malformed'

    request.log shows GET download - - - - action=download

    Even though it has the slug in the URL. If I put the slug first and the action secion, the request log would show the slug and no action

    opened by Santana1053 9
  • Make WP Version nr and request url part of the Request class

    Make WP Version nr and request url part of the Request class

    Move the parsing of the HTTP_USER_AGENT request header to the Request class as it is (or should be and now is) a property of the request after all.

    This paves the way to evaluating 'check-for-update' requests based on WP version. I.e. only offer the update if the WP version requesting complies with the 'Requires' minimum WP version for a plugin.

    opened by jrfnl 9
  • Fix serialization issues

    Fix serialization issues

    Fix PHP Notice: unserialize(): Error at offset ... errors.

    These kind of errors are caused most of the time by:

    • unescaped quotes/slashes etc
    • miscounted unicode characters

    The cache files will now no longer be human readable. To still be able to identify them, the new cache filenames now include the package slug.

    This also takes care of compatibility issues when upgrading as the new version will look for the cache files with the new filename pattern and will disregard the old cache files.

    opened by jrfnl 8
  • PHP8 deprecation notices

    PHP8 deprecation notices

    In PHP 8.1, the iterator declarations in /includes/Wpup/Headers.php are throwing a deprecation notice:

    PHP Deprecated:  Return type of Wpup_Headers::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 129
    
    PHP Deprecated:  Return type of Wpup_Headers::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 133
    
    PHP Deprecated:  Return type of Wpup_Headers::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 137
    
    PHP Deprecated:  Return type of Wpup_Headers::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 141
    
    PHP Deprecated:  Return type of Wpup_Headers::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 154
    
    PHP Deprecated:  Return type of Wpup_Headers::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /public_html/wp-update-server/includes/Wpup/Headers.php on line 148
    

    Cheers Rob

    opened by robwoodgate 4
  • Issue with the latest wp-update-server version

    Issue with the latest wp-update-server version

    Have been working for many years fine, but now recently I see that wp-update-server folder is generating error_log file which has quickly grown into a 1GB in size. These are the errors:

    [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 949 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1245 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1270 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1610 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1612 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1833 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 1835 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2098 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2098 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2107 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2145 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2145 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2164 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2165 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2269 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2281 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2281 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2292 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2293 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2651 [23-Feb-2022 11:16:14 Europe/Riga] PHP Deprecated: Array and string offset access syntax with curly braces is deprecated in /wp-content/wp-update-server/includes/extension-meta/markdown.php on line 2969

    So the real issue now is this:

    I tried downloading the latest version, the errors disappeared, however I noticed that now my customers are able to update even if the license key has expired. Using the old version, if the license key had expired and user tried to update, WordPress put out this message: "Automatic update is unavailable for this plugin."

    I guess I should mention that I'm protecting download links by validating license keys and depending on the key, if it is valid and active - the user is returned a plugin update link with the full plugin, but if the license has expired, the user gets a link to .zip file which only includes the readme file (containing information about the latest version and what is included) along with one .php file with the name of the plugin and only plugin header data. This is done because it is good to show users with expired licenses that there are updates and he should renew the license to download the latest version.

    And the interesting issue is that one of my users was allowed to download the empty .zip which contained just the readme and one php file so now he has a plugin but it is just an empty shell :)

    Any way to resolve this issue? I would like to know what could be done to make sure WordPress in these situations simply outputs "Automatic update is unavailable for this plugin." as before so nobody would be able to download the empty shell version, but still would be able to see readme file of the latest version?

    opened by Streamlinelv 5
  • unexpected error

    unexpected error

    I see this error when i send request to [http://localhost/wp-update-server/?action=get_metadata&slug=my_plugin] :

    **Warning: require(C:\xampp\htdocs\wp-update-server/loader.php): failed to open stream: No such file or directory in C:\xampp\htdocs\wp-update-server\index.php on line 2

    Warning: require(C:\xampp\htdocs\wp-update-server/loader.php): failed to open stream: No such file or directory in C:\xampp\htdocs\wp-update-server\index.php on line 2

    Fatal error: require(): Failed opening required 'C:\xampp\htdocs\wp-update-server/loader.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\wp-update-server\index.php on line 2**

    opened by Alireza-Ghavabesh 1
  • 400 Bad Request

    400 Bad Request

    I have uploaded a theme with the order example. How do I specify the slug of the theme? In the CSS it says text domain example and in the backend it recognizes version, theme and name of the theme.

    opened by snaapbacker 11
  • Get API Response

    Get API Response

    Hi there,

    awesome plugin! Is it possible to get the API results after calling the URL? I tried var dumping the class but there is no info about the original response request.

    I need that to show the customer an error that the updater API may return (like no plugin found / license not valid).

    opened by danielbarenkamp 1
  • erroo

    erroo

    What is the cause of the following error? به‌روزرسانی ناموفق شد: {"success":true,"data":{"update":"plugin","slug":"amin_plugin","oldVersion":"\u0646\u06af\u0627\u0631\u0634 1.9","newVersion":"\u0646\u06af\u0627\u0631\u0634 2.9","plugin":"amin_plugin/amin_plugin.php","pluginName":"test aminb"}}

    opened by afagh11943 1
Releases(v2.0.1)
  • v2.0.1(Jan 2, 2023)

  • v2.0(Mar 31, 2021)

    Backwards incompatible changes

    • Moved the icons and banners directories to a new package-assets subdirectory to fix a conflict with some Apache versions.
    • The filterLogInfo() method now receives an associative array with string keys instead of an array with numeric indexes.

    Other changes

    • Added basic IP anonymization support. This feature makes the server partially anonymize IP addresses before writing them to the request log. To enable it, call the enableIpAnonymization() method on the Wpup_UpdateServer instance.
    • Added support for the Requires PHP field.
    • Special characters in request data should now be escaped as hex when writing them to the request log. Props to @dangoodman.
    • Added the ability to detect and log the site URL for update requests sent from WordPress.com sites. Props to @meceware.
    • Fixed a potential security issue where plugin/theme packages could be downloaded directly on Apache 2.4.
    • Fixed some PHP 7 warnings about curly braces.
    • Fixed changelog parsing where lists were not terminated correctly.
    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Mar 8, 2018)

  • v1.3(Sep 1, 2017)

    • Added basic support for plugin banners. To add a banner, create an 772x250 pixel image named $slug-772x250.png or $slug-772x250.jpg and put it in the banners subdirectory.
    • Added optional log rotation. To enable it, call enableLogRotation() and specify the rotation period and the number of old log files to keep. Example:
      $server->enableLogRotation(Wpup_UpdateServer::FILE_PER_MONTH, 6);
      
    • Added the PclZip library as an alternative to the Zip extension. Props to @dcooperdalrymple.
    • Added some more input and output sanitization.
    • Minor code cleanup.
    Source code(tar.gz)
    Source code(zip)
  • v1.2(Sep 2, 2016)

    • Fixed occasional double slashes in download URLs that could cause updates to fail in WP 4.6.
    • Fixed a few notices about deprecated constructors (PHP 7).
    • Fixed a caching bug that caused lots of unnecessary cache updates. Props to @jrfnl, see #23.
    • Fixed an encoding bug where the server incorrectly assumed all readme.txt files would be ISO-8859-1 and tried to re-encode them as UTF-8.
    • Lots of refactoring by @jrfnl and myself.
    • Updated Markdown library.
    • Removed some dead code.
    Source code(tar.gz)
    Source code(zip)
  • v1.1(Dec 16, 2014)

    Refactored HTTP header handling.

    As a stand-alone application, this release is backwards-compatible with 1.0. However, if you subclass Wpup_UpdateServer or Wpup_Request, or call some of their methods from your own code, you may need to update some method signatures.

    Source code(tar.gz)
    Source code(zip)
  • v1.0(Dec 16, 2014)

Owner
Yahnis Elsts
Yahnis Elsts
This WP plugin will update GitHub, Bitbucket, GitLab, and Gitea hosted plugins and themes

Transition from GitHub Updater 9.x to Git Updater 10.x Due to the renaming of the plugin folders and files, after the initial update, the plugin will

Andy Fragen 3k Jan 5, 2023
A custom WordPress nav walker class to fully implement the Twitter Bootstrap 4.0+ navigation style (v3-branch available for Bootstrap 3) in a custom theme using the WordPress built in menu manager.

WP Bootstrap Navwalker This code in the main repo branch is undergoing a big shakeup to bring it in line with recent standards and to merge and test t

WP Bootstrap 3.3k Jan 5, 2023
This Plugin is used to install and activate multiple plugins in one go. I was facing problem uploading plugins one by one so I developed this to solve my problem. Hope you will enjoy using this plugin.

=== Bulk Plugin Installer === Contributors: jawadarshad Donate link: https://jawadarshad.io/ Tags: bulk plugin installer, import multiple plugins, up

Muhammad Jawad Arshad 2 Sep 20, 2022
A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities.

Awesome WordPress A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities. Inspired by bayand

Dropndot Limited 91 Dec 26, 2022
Wordpress advance plugin with multi purposes features like live chat, custom post type, custom forms, word count etc

What is this? This is wordpress plugin which is created for the multi purpose uses. How to use? Simply install the plugin. Go to the plugin settigs pa

Amir Liaqat 2 Jun 23, 2022
Create WordPress themes with beautiful OOP code and the Twig Template Engine

By Jared Novack (@jarednova), Lukas Gächter (@lgaechter), Pascal Knecht (@pascalknecht), Maciej Palmowski (@palmiak_fp), Coby Tamayo (@cobytamayo), Up

Timber 5.2k Jan 5, 2023
A better way to create WordPress themes.

Runway Framework for WordPress Visit the Runway website: RunwayWP.com A better way to create WordPress themes. Runway was built for creating WordPress

Parallelus 214 Nov 18, 2022
Classy is a framework for building WordPress themes, based on Blade template engine

Classy is a framework for building WordPress themes, based on Blade template engine. It's fast with beautiful architecture that allows you to write le

DigitalKwarts 75 Nov 23, 2022
A WordPress plugin to create Blockbase child themes

Create Blockbase Theme A WordPress plugin to create Blockbase child themes Find out more about Blockbase at blockbasetheme.com Step 1 – Setup Install

Automattic 171 Jan 3, 2023
A foundation for WordPress Plugin Development that aims to provide a clear and consistent guide for building your plugins.

WordPress Plugin Boilerplate A standardized, organized, object-oriented foundation for building high-quality WordPress Plugins. Contents The WordPress

Devin 7.2k Jan 4, 2023
📦 A zero-configuration #0CJS developer toolkit for building WordPress Gutenberg block plugins.

create-guten-block is zero configuration dev-toolkit (#0CJS) to develop WordPress Gutenberg blocks in a matter of minutes without configuring React, w

Ahmad Awais ⚡️ 3.1k Dec 23, 2022
Developers tool for WordPress plugins: Wraps all your projects dependencies in your own namespace

Developers tool for WordPress plugins: Wraps all your projects dependencies in your own namespace, in order to prevent conflicts with other plugins loading the same dependencies in different versions.

Coen Jacobs 362 Dec 23, 2022
Rabbit Framework - A modern way of building WordPress plugins

Rabbit Framework - A modern way of building WordPress plugins. About Rabbit Framework is a modern framework designed to be a solid foundation for your

VeronaLabs 8 Nov 20, 2022
Wordless is a junction between a WordPress plugin and a theme boilerplate that dramatically speeds up and enhances your custom theme creation

Wordless is a junction between a WordPress plugin and a theme boilerplate that dramatically speeds up and enhances your custom theme creation. Some of

weLaika 1.4k Dec 9, 2022
Create custom WordPress routes and redirects, restrict access by roles and/or capabilities. Routes made simple

Create custom WordPress routes and redirects, restrict access by roles and/or capabilities. Routes made simple

Joan 9 Oct 10, 2022
A PHP Class for creating Wordpress Custom Post Types easily

N.B I've released an updated version of the project to a new repository, PostTypes. WP Custom Post Type Class v1.4 A single class to help you build mo

Joe Grainger 412 Nov 25, 2022
Custom WordPress theme for DotOrg

wd_s Debt Collective Theme Table of Contents Introduction Getting Started Prerequisites Quick Start Advanced Setup Development Contributing and Suppor

The Debt Collective 1 Oct 31, 2022
Word Count (Custom WordPress Plugin)

word-count (Custom WordPress Plugin) Followed a tutorial to create a plugin that adds word count infos to the frontend (Posts only). I then modified t

null 1 Feb 4, 2022
A super simple abstraction to make creating a custom Taxonomies in WordPress a breeze

A super simple abstraction to make creating a custom Taxonomies in WordPress a breeze

Joe Grant 2 Apr 5, 2022