Giter Club home page Giter Club logo

automatic-theme-plugin-update's Introduction

Automatic Theme & Plugin Updater for Self-Hosted Themes/Plugins

Support This Developer: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SE9ZVJUS324UC

Any amount is always appreciated

General Info

For themes and plugins that can't be submitted to official WordPress repository, ie ... commercial themes/plugins/, non-gpl licensed, written for one client.

Folder structure

  • api (Folder to upload to server where updates will be housed)

    • .htaccess (set Options+Indexes to allow checking to work properly)
    • index.php (holds code used to check request for new versions)
    • packages.php (file containing all info about plugins and themes)
    • download.php (validates md5 key of date and package zip file)
    • update (folder to hold all zip file updates for url masking - protected by .htaccess to disallow file listings)
  • update (default folder for holding theme and plugin zip files)

    • .htaccess (prevents indexing and viewing of any zip files in directory)
  • plugin (folder for adding plugin update checking)

    • test-plugin-update (simple plugin folder to show how update functions work)
      • test-plugin-update.php (example plugin that only checks for updates to server)
  • theme (folder for theme update checking)

    • update.php (file that can be included from functions.php of theme to check for updates)

Important:

Change $api_url to your api server url in:

/plugin/test-plugin-update/test-plugin-update.php 
/theme/update.php	

Adding new versions

Edit the packages.php under api folder on your server. Commented thoroughly throughout with sections that need to be changed to reflect themes/plugins that are to be updated.

Adding additional themes/plugins

Simply create another $package array with the key of the new theme/plugin slug and add all the appropriate info. When releasing the theme/plugin make sure that functions and variables are prefixed to prevent errors and allow multiple themes/plugins to be updated.

Child theme support

Child themes are now supported. If the theme being updated is meant to be a parent theme the standard theme/update.php from the theme file will work. If the theme is a child theme of another theme comment out the parent theme section and uncomment the child theme section on the theme/update.php

Securing Download location

Downloads are now always secured by a md5 hash of the package file_name and timestamp of current date. When downloading file current timestamp and timestamp of previous day are compared to key received from update request, if either match zip file is passed, and file can be downloaded.

automatic-theme-plugin-update's People

Contributors

foxinni avatar jefferyto avatar jeremyclark13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

automatic-theme-plugin-update's Issues

Multiple Themes

Looking at the codes, it looks more like, it's setup for a single theme or a single plugin.
Are you working on making this a way to be like a central setup to update multiple plugins and themes?

Error when viewing plugin version details

Hi,

I am using your plugin but it work fine if i used on one plugin. if i add two or more plugin array in package.php file and when i click on plugin version details then it gives me error.

"An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums."

Only the first plugin show me version details.

Looking forward to your reply. Thanks

Unknown Error when searching for plugins in admin

After your fix of #12 and #14 I've updated my files and all seemed to work properly.

However, I've got a new issue: when searching for plugins via plugins admin, I type in my search string, hit enter and then I've got a "wp_die()" with the message "Unknown Error". If I deactivate the plugin which contains your code, all runs like it should.

To note: I did non run the code in test mode, so, there's nothing uncommented and also nothing with the update transient.

Really strange. If you could resolve that, I am happy to finally release my plugin.

Thank you very much!

download.tmp

Hello,

Your code is great, but I encountered a problem.After I do an automatic update, the old theme is deleted and the new updated theme is installed inside a folder called download.tmp. Am I doing something wrong?

Thank you in advanced.

Afte update Plugin Folder name is appended with some strings

Am working on a WordPress plugin where the updates will be done on the external server. I added the below code and everything is working good. But once it updated the plugin folder name will be appended with five digit characters followed by dash.

for example : 
before update plugin name - plugin-name
after  update plugin name - plugin-name-IbzGAQ

Am not sure why its auto append at end.

<?php
$api_url = 'http://server_address/update/';
$plugin_slug = 'plugin_slug';
$plugin_name = 'plugin_name';


// Take over the update check
add_filter('pre_set_site_transient_update_plugins', 'check_for_plugin_update');

function check_for_plugin_update($checked_data) {
  global $api_url, $plugin_slug, $wp_version, $plugin_name;
  $response = '';
  //Comment out these two lines during testing.
  if (empty($checked_data->checked))
    return $checked_data;

  $args = array(
      'slug' => $plugin_slug,
      'version' => $checked_data->checked[$plugin_slug .'/'. $plugin_name .'.php'],
  );
  $request_string = array(
      'body' => array(
          'action' => 'basic_check',
          'request' => serialize($args)
      ),
      'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
  );

  // Start checking for an update
  $raw_response = wp_remote_post($api_url, $request_string);

  if (!is_wp_error($raw_response) && ($raw_response['response']['code'] == 200)){
    $response = unserialize($raw_response['body']);
    if($response->version == 'invalid'){
      update_option('bc_rb_payment_info','no');
      return 'invalid';
    }
  }

  if (is_object($response) && !empty($response)) // Feed the update data into WP updater
    $checked_data->response[$plugin_slug .'/'. $plugin_name .'.php'] = $response;

  return $checked_data;
}


// Take over the Plugin info screen
add_filter('plugins_api', 'plugin_api_call', 10, 3);

function plugin_api_call($def, $action, $args) {
  global $plugin_slug, $api_url, $wp_version,$plugin_name;

  if (!isset($args->slug) || ($args->slug != $plugin_slug))
    return false;

  // Get the current version
  $plugin_info = get_site_transient('update_plugins');
  $current_version = $plugin_info->checked[$plugin_slug .'/'. $plugin_name .'.php'];
  $args->version = $current_version;

  $request_string = array(
      'body' => array(
          'action' => $action,
          'request' => serialize($args)
      ),
      'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
  );

  $request = wp_remote_post($api_url, $request_string);


  if (is_wp_error($request)) {
    $res = new WP_Error('plugins_api_failed', __('An Unexpected HTTP Error occurred during the API request.</p> <p><a href="?" onclick="document.location.reload(); return false;">Try again</a>'), $request->get_error_message());
  } else {
    if ($request['response']['message'] == 'OK' || $request['response']['code'] == 200){
      $res = unserialize($request['body']);
    } else {
      $res = new WP_Error('plugins_api_failed', __('An unknown error occurred'), $request['body']);
    }
  }

  return $res;
}

causing a [PHP Fatal error: Call to undefined function auth_redirect()]

Hello.

It seems that this piece of code (for the plugin update.php) is causing a Fatal Error
Call to undefined function auth_redirect() in /var/my/private/path/wp-admin/admin.php on line 80

I wondered if anyone else had this issue?

Strangely the error occurs just from including the update.php file. Even if everything in the update.php is commented out! Naming conflict?

Any ideas?

View version x.x details not showing anything

My plugin shows the update correctly but when clicking on the view version xx details, the information is not populating that popup box
plugin-updater-1

in function check_for_plugin_update the following variables are set at:

$response
stdClass Object ( [version] => 1.1 [date] => 2013-02-18 [author] => Lime Canvas [requires] => 3.0 [tested] => 3.5.1 [homepage] => http://www.limecanvas.com/support-and-maintenance/ [downloaded] => 1 [external] => [package] => https://www.limecanvas.com/download.php?key=579a401b73f2d3cf4af28c1b2d29bdd2 [file_name] => lime-canvas-support-plugin-v1.0.zip [sections] => Array ( [description] => Lime Canvas Support Plugin [installation] => Install, active and enter your Customer ID on the settings page. [screen shots] => na [change log] => na [faq] => na [other notes] => na ) [slug] => test-plugin-update [new_version] => 1.1 )

$checked_data
stdClass Object ( [last_checked] => 1361188025 [response] => Array ( [test-plugin-update/test-plugin-update.php] => stdClass Object ( [version] => 1.1 [date] => 2013-02-18 [author] => Lime Canvas [requires] => 3.0 [tested] => 3.5.1 [homepage] => http://www.limecanvas.com/support-and-maintenance/ [downloaded] => 1 [external] => [package] => https://www.limecanvas.com/download.php?key=579a401b73f2d3cf4af28c1b2d29bdd2 [file_name] => lime-canvas-support-plugin-v1.0.zip [sections] => Array ( [description] => Lime Canvas Support Plugin [installation] => Install, active and enter your Customer ID on the settings page. [screen shots] => na [change log] => na [faq] => na [other notes] => na ) [slug] => test-plugin-update [new_version] => 1.1 ) ) )

It looks like the correct info is being passed back to the WP updater

Wil.

Recent Issues - Wordpress 5.5

I have been using this code for years for Plugins and Themes.
As of Wordpress 5.5 it doesn't seem to look for updates.
Has anyone else experienced this?

Update theme works but wrong theme folder name

Hi guys,

First of all thank you for this marvellous script !

I have a small problem though.

After an update, I got the message : Theme updated successfully.

When I hit the button, Return the Theme page, the parent theme is not there anymore.

Inside the wp-content folder the theme called parent-theme is now replaced by a folder named download.

However, my zip file does contain a folder called parent-theme.

How could I resolve this problem? Is it possible that it is due to the server?

Thanks.

screen shot 2015-11-17 at 20 42 53

plugin update failed

I tried to install 2 plugins (self hosted) and have available for update of those 2 plugins.

On installed plugins page.
It show up there are update for 2 plugins, I clicked on update link and ajax update is working for first plugin and update completed.
Now i try to click on update link on second plugin and it said plugin update failed.

From my investigation it was called Plugin_Upgrader->bulk_upgrade() (wp-admin/includes/class-plugin-upgrader.php) from wp_ajax_update_plugin (wp-admin/includes/ajax-actions.php) function and stuck at if ( !isset( $current->response[ $plugin ] ) ) for second update.

Here is my plugin code:

<?php
/**
 * Plugin Name: V Test plugin 1
 * Plugin URI: http://rundiz.com
 * Description: A very simple 1 file plugin for testing.
 * Version: 0.0.7
 * Author: Vee Winch
 * Author URI: http://rundiz.com
 * License: MIT
 * License URI: https://opensource.org/licenses/MIT
 * Text Domain: testplug1
 * Domain Path: 
 */


namespace TestPlug1;


if (!defined('RDWPPS_URL')) {
    define('RDWPPS_URL', 'http://localhost/wordpress/single-site/rdwpps');
}


class TestPlugin
{


    public $check_self_hosted_log = __DIR__.'/debug/check-self-hosted.txt';
    public $http_request_args_log = __DIR__.'/debug/http-request-args.txt';
    public $upgrade_complete_log = __DIR__.'/debug/upgrade-process-complete.txt';


    public function __construct()
    {
        if (!is_dir(__DIR__.'/debug')) {
            mkdir(__DIR__.'/debug');
        }
    }// __construct


    /**
     * Check for self hosted plugin/theme server.
     * 
     * @param object $checked_data Checked data object.
     * @return object Return checked data object.
     */
    public function checkSelfHostedRepository($checked_data)
    {
        //$this->getOptions();
        //global $plugin_template_optname;

        //if (is_array($plugin_template_optname) && array_key_exists('activation_check_update', $plugin_template_optname) && $plugin_template_optname['activation_check_update'] != '1') {
        //    return $checked_data;
        //}

        global $wp_version;
        $plugin_slug = basename(dirname(__FILE__)); // pluginname
        $plugin_sysname = plugin_basename(__FILE__);// pluginname/pluginname.php
        $this->debugLog($this->check_self_hosted_log, 'plugin_slug:plugin_sysname'."\n".$plugin_slug . ' : ' . $plugin_sysname."\n\n");

        if (empty($checked_data->checked)) {
            $this->debugLog($this->check_self_hosted_log, 'checked data is empty'."\n".print_r($checked_data, true)."\n\n");
            return $checked_data;
        } else {
            $this->debugLog($this->check_self_hosted_log, 'checked data is not empty'."\n".print_r($checked_data, true)."\n\n");
        }

        $args = array(
            'slug' => $plugin_slug,
            'version' => $checked_data->checked[$plugin_sysname],
        );
        $request_string = array(
            'body' => array(
                'action' => 'basic_check',
                'request' => serialize($args),
                'buyer_id' => 'test_buyer_id',
                'serial_number' => 'test_serial_number',
                'website' => get_bloginfo('url'),
            ),
            'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
        );

        // Start checking for an update
        $raw_response = wp_remote_post(RDWPPS_URL, $request_string);
        $this->debugLog($this->check_self_hosted_log, 'raw response after remote post to ' . RDWPPS_URL."\n".print_r($raw_response, true)."\n\n");

        if (!is_wp_error($raw_response) && isset($raw_response['response']['code']) && isset($raw_response['body']) && ($raw_response['response']['code'] == 200)) {
            $response = @unserialize($raw_response['body']);
            $this->debugLog($this->check_self_hosted_log, 'response body: '."\n".print_r($response, true)."\n\n");
        }

        if (isset($response) && is_object($response) && !empty($response)) {
            // Feed the update data into WP updater
            $checked_data->response[$plugin_sysname] = $response;
        }

        $this->debugLog($this->check_self_hosted_log, 'final checked data: '."\n".print_r($checked_data, true)."\n\n");
        return $checked_data;
    }// checkSelfHostedRepository


    /**
     * Simple debug log.
     * 
     * @param string $file
     * @param string $message
     */
    public function debugLog($file, $message)
    {
        if (!is_dir(__DIR__.'/debug')) {
            mkdir(__DIR__.'/debug');
        }

        file_put_contents($file, $message, FILE_APPEND);
    }// debugLog


    /**
     * Remove this plugin slug from request to WordPress.org repository.<br>
     * This method will not work if plugin is not activated.
     *
     * @param array  $request An array of HTTP request arguments.
     * @param string $url The request URL.
     * @return array Return filtered data.
     */
    public function httpRequestArgs($request, $url)
    {
        if (!isset($request['body']['plugins'])) {
            $this->debugLog($this->http_request_args_log, '$request[\'body\'][\'plugins\'] is not set'."\n".print_r($request, true)."\n\n");
            return $request;
        } else {
            $this->debugLog($this->http_request_args_log, '$request[\'body\'][\'plugins\'] is set'."\n".print_r($request, true)."\n\n");
        }

        $plugin_slug = basename(dirname(__FILE__)); // pluginname
        $plugin_sysname = plugin_basename(__FILE__);// pluginname/pluginname.php
        $this->debugLog($this->http_request_args_log, 'plugin_slug:plugin_sysname'."\n".$plugin_slug . ' : ' . $plugin_sysname."\n\n");

        // Plugin update request.
        $this->debugLog($this->http_request_args_log, '$url'."\n".$url."\n\n");
        if (false !== strpos($url, '//api.wordpress.org/plugins/update-check')) {
            //Excluded plugin slugs that should never ping the WordPress API.
            $data = json_decode($request['body']['plugins']);
            $this->debugLog($this->http_request_args_log, '$data value:'."\n".print_r($data, true)."\n\n");
            // Remove the excluded plugins.
            unset($data->plugins->$plugin_sysname);
            if (isset($data->active) && is_array($data->active)) {
                unset($data->active[array_search($plugin_sysname, $data->active)]);
                $data->active = array_values($data->active);
            }
            $this->debugLog($this->http_request_args_log, '$data value after modified:'."\n".print_r($data, true)."\n\n");
            // Encode back into JSON and update the response.
            $request['body']['plugins'] = wp_json_encode($data);
        }
        return $request;
    }// httpRequestArgs


    /**
     * Send plugin information to display in to modal dialog of client website when there is an update for this plugin.
     * 
     * @param mixed $def
     * @param string $action
     * @param object $args
     * @return mixed
     */
    public function pluginInformation($def, $action, $args)
    {
        //$this->getOptions();
        //global $plugin_template_optname;

        global $wp_version;
        $plugin_slug = basename(dirname(__FILE__)); // pluginname
        $plugin_sysname = plugin_basename(__FILE__);// pluginname/pluginname.php

        if (isset($args->slug) && ($args->slug != $plugin_slug)) {
            return $def;
        }

        // Get the current version
        $plugin_info = get_site_transient('update_plugins');
        if (!isset($plugin_info->checked) || !is_array($plugin_info->checked)) {
            return $def;
        }
        $current_version = $plugin_info->checked[$plugin_sysname];
        $args->version = $current_version;

        $request_string = array(
            'body' => array(
                'action' => $action,
                'request' => serialize($args),
                'buyer_id' => 'test_buyer_id',
                'serial_number' => 'test_serial_number',
                'website' => get_bloginfo('url'),
            ),
            'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
        );

        unset($current_version, $plugin_info, $plugin_slug, $plugin_sysname);
        $request = wp_remote_post(RDWPPS_URL, $request_string);

        if (is_wp_error($request)) {
            $res = new \WP_Error('plugins_api_failed', __('An Unexpected HTTP Error occurred during the API request.</p> <p><a href="?" onclick="document.location.reload(); return false;">Try again</a>'), $request->get_error_message());
        } elseif (isset($action) && $action == 'plugin_information' && isset($request['body'])) {
            $res = @unserialize($request['body']);

            if ($res === false) {
                $res = new \WP_Error('plugins_api_failed', __('An unknown error occurred'), $request['body']);
            }
        } else {
            return $def;
        }
        return $res;
    }// pluginInformation


    /**
     * register all plugin actions hooks and add filters or actions.
     */
    public function registerHooks()
    {
        // add filter to row meta. (in plugin page below description)
        add_filter('plugin_row_meta', [&$this, 'rowMeta'], 10, 2);
        // add filter to remove this plugin slug from check update with WordPress repository server. remove this filter if this plugin is on WordPress.
        add_filter('http_request_args', [&$this, 'httpRequestArgs'], 5, 2);
        // add filter to check update from self hosted server.
        add_filter('pre_set_site_transient_update_plugins', [&$this, 'checkSelfHostedRepository'], 10, 1);
        // add filter to display plugin information when there is an update for this plugin. this will be display as modal dialog just like other WordPress plugins.
        add_filter('plugins_api', [&$this, 'pluginInformation'], 10, 3);
        // add filter to update/upgrade plugin.
        //add_filter('upgrader_package_options', [&$this, 'upgraderOptions'], 10, 1);
        // add action after plugin upgrade complete.
        add_action('upgrader_process_complete', [&$this, 'upgradeProcessComplete'], 10, 2);
    }// registerHooks


    /**
     * add links to row meta that is in plugin page under plugin description.
     * 
     * @staticvar string $plugin the plugin file name.
     * @param array $links current meta links
     * @param string $file the plugin file name for checking.
     * @return array return modified links.
     */
    public function rowMeta($links, $file)
    {
        static $plugin;// pluginname/pluginname.php

        $plugin_slug = basename(dirname(__FILE__)); // pluginname
        if (!isset($plugin) || $plugin == null) {
            $plugin = plugin_basename(__FILE__);// pluginname/pluginname.php
        }

        if ($plugin === $file) {
            $new_link[] = '<a class="thickbox open-plugin-details-modal" data-title="one file plugin" aria-label="More information about one file plugin" href="' . admin_url('plugin-install.php?tab=plugin-information&plugin=' . $plugin_slug . '&TB_iframe=true') . '">' . __('View details') . '</a>';
            $links = array_merge($links, $new_link);
            unset($new_link);
        }

        return $links;
    }// rowMeta


    /**
     * Hook after upgrade complete.
     * 
     * @param object $UpgraderObject
     * @param array $options
     */
    public function upgradeProcessComplete($UpgraderObject, $options = [])
    {
        $this->debugLog($this->upgrade_complete_log, 'upgrader object: '.print_r($UpgraderObject, true)."\n\n");
        $this->debugLog($this->upgrade_complete_log, 'upgrade complete options:'."\n".print_r($options, true)."\n\n");
    }// upgradeProcessComplete


    /**
     * Upgrader options
     * 
     * @param array $options
     */
    public function upgraderOptions($options = [])
    {
        if (is_array($options)) {
            if (!isset($options['is_multi'])) {
                $options['is_multi'] = false;
            } else {
                $options['is_multi'] = false;
            }
        }

        return $options;
    }// upgraderOptions


}


// start running the plugin. -----------------------------------------------------------------
$TestPlugin = new \TestPlug1\TestPlugin();
$TestPlugin->registerHooks();
unset($TestPlugin);

The another plugin is the same, just change the number from plug1 to plug2.

How to make ajax update plugin works for 2 or more self hosted plugins?

An error occurred while updating...

I tried to update theme via this plugin, however, some server giving this error:

Downloading update from http://www.domainname.com/updates/download.php?key=26b6d8fec65c87d6af0acc88b274a07a…
Unpacking the update…
Installing the latest version…
Theme update failed.

An error occurred while updating THEME: The package could not be installed. The package contains no files.

I can't be sure why, but this happen on a few server only. Is this anything to do with the server IP being block or something else? I have a few other server that has exact theme, some are working alright.

Wordpress always thinks theres a new version even with greater version numbers than the update api

Hey nice work on the script!
This function needs a tweak however to stop wordpress from thinking theres a new version every time.

if (version_compare($args->version, $latest_package['version'], '<'))
    $update_info->new_version = $update_info->version;

print serialize($update_info);

to:

if (version_compare($args->version, $latest_package['version'], '<')) {
    $update_info->new_version = $update_info->version;
    print serialize($update_info);
}

Thanks :)

Child Theme - theme X update process - no update

Hi, i have make a "theme x" - child theme and i will integrate the update process.
in the update in the Dashboard there are no updates to do. What make i wrong?

Style.css from the child theme

/* CSS Document */

/*
Theme Name:   ENSPowerPack
Description:  ENS Power Pack Security Plugin
Author:       ENS
Author URI:   http://www.ens.gmbh
Version: 1.0
Template: pro
*/

and the packages - that make i wrong?

<?php
// Theme with update info
$packages['ENSPowerPack'] = array( //Replace theme with theme stylesheet slug that the update is for
    'versions' => array(
        '1.0' => array( //Array name should be set to current version of update
            'version' => '1.2', //Current version available
            'date' => '2018-01-26', //Date version was released
            //theme.zip is the same as file_name
            'package' => 'https://update.ens.gmbh/api/download.php?key=' . md5('powerpackpro.zip' . mktime(0,0,0,date("n"),date("j"),date("Y"))),
            //file_name is the name of the file in the update folder.
            'file_name' => 'powerpackpro.zip',	//File name of theme zip file
            'author' => 'ENS', //Author of theme
            'name' => 'ENSPowerPack', //Name of theme
            'requires' => '3.1', //Wordpress version required
            'tested' => '4.9.2', //WordPress version tested up to
            'screenshot_url' => 'http://url_to_your_theme_site/screenshot.png' //url of screenshot of theme
        )
    ),
    'info' => array(
        'url' => 'http://www.ens.gmbh'  // Website devoted to theme if available
    )
);

I have test it with:
'1.1' => array( //Array name should be set to current version of update
'1.2' => array( //Array name should be set to current version of update
etc ...

and my file structur:
https://screencast.com/t/qqe8ty2zK8

what make i wrong?

Check update?

I find it hard to check the update version without uncomment this line: // set_site_transient('update_themes', null);

Is there anyway for the theme itself check the update themselves?

Thank you!

download.tmp

The file downloaded from the server is renamed to download.tmp. I have tried zipping the files separately and then collectively as a folder, but it still happens. Can anybody tell me how to avoid this? Thanks.

404 not found

Hello,

While I testing the plugin in my own server, I don't get any error and plugin works fine. However, when I install the plugin in different server it gives the error.

$raw_response content:

Not Found
The requested URL /update/wp/ was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Apache/2 Server at screets.com Port 80
[response] => Array ( [code] => 404 [message] => Not Found ) [cookies] => Array ( ) [filename] => )

How can I solve this issue ?

Theme update results in new theme folder name of "download-XXXX"

I realize this is a rather old and seemingly stale repository, but I cannot find many options out there for doing this on my own. So I hope someone with a bit more experience than me can help.

I've found a bug (I think) using WordPress 5.6.2. When an update to an existing theme is available, the notice shows. Clicking on "Update now" does result in the updated theme being downloaded, updated, and activated. However, the folder for the theme changes from "themename" to "download-xxxxx". The xxxxx being a random set of characters. This results in the theme no longer recognizing when new updates are available because the theme's "slug" is no longer accurate.

I've dug into this a bit and I don't think it is the direct result of this library. From what I can tell, WordPress uses the run() function within the upgrader and somewhere around lines 776-813 the issue happens. Normally, I would think, WordPress would delete the old directory, replace it with the new updated code. However, it seems to retain the name of the download folder (rather than being renamed to the "themename").

I haven't been able to identify a hook that would allow me to see exactly what parameter(s) may be missing to have this routine run properly.

Any help is appreciated.

Doesn't work with filter 'pre_set_site_transient_update_themes'

For some reason this script doesn't seem to work with my custom Genesis child theme, when using the filter 'pre_set_site_transient_update_themes'.
It does work after i changed it to 'site_transient_update_themes'.

I also tried to change priorities, but it still didn't work.
Any idea why?
Are there any disadvantages when using the 'site_transient_update_themes' filter hook?

Multisite $checked_data->checked[$pluginname] empty

I don't know why, but on a multisite installation a plugin (activate not networkwide, only on a blog into the multisite) the update-check-object $checked_data is everytime empty.

if i make:
var_dump($checked_data)

the result is:
object(stdClass)#4568 (1) {
["last_checked"]=> int(1378304830)
}

What's going wrong here?

domnload.tmp

I'm getting an issue where the file downloads and extracts - Wordpress says it's all good, but it has extracted into a directory called 'download.tmp' instead of the plugin name.

Thoughts?

Help me, it can not run in my theme

Hello all
I was add "include_once('update.php');" in function.php in my theme (slug : bione, version 1.0 )
In update.php, i was edit $api_url = 'http://localhost/api/';
in packages.php in localhost/api, i edit that:

$packages['bione'] = array( //Replace theme with theme stylesheet slug that the update is for
'versions' => array(
'2.0' => array( //Array name should be set to current version of update
'version' => '2.0', //Current version available
'date' => '2010-04-10', //Date version was released
//theme.zip is the same as file_name
'package' => 'http://url_to_your_site/download.php?key=' . md5('theme.zip' . mktime(0,0,0,date("m"),date("d"),date("Y"))),
//file_name is the name of the file in the update folder.
'file_name' => 'theme.zip', //File name of theme zip file
'author' => 'Author Name', //Author of theme
'name' => 'Theme Name', //Name of theme
'requires' => '3.1', //Wordpress version required
'tested' => '3.1', //WordPress version tested up to
'screenshot_url' => 'http://url_to_your_theme_site/screenshot.png' //url of screenshot of theme
)
),
'info' => array(
'url' => 'http://url_to_your_theme_site' // Website devoted to theme if available
)
);

But it not show Updates Noice in wp-admin/update-core.php :((
sory my Englist very bad, pls help me?

Theme update not working with Multisite

I developed a theme that uses the update system, and I LOVE it. Thank you for making this. The update system works as expected on a single WordPress install, but when I tested it on multisite, nothing happens. Is this an unfixable limitation imposed by multisite, or would it be possible for it work with multisite as well?

$wp_version

Hey in the plugin update example the $wp_version is missing causing an error notice. Adding $wp_version to the global calls in both functions sorts this out.

WordPress 3.3?

There's a chance that I'm just an idiot and missing something, but I've ben trying for a few hours to get this to work and it doesn't appear to work on WordPress 3.3.

Do you know if there's any issues with this script and WP 3.3?

If it's an issue with WP 3.3 I won't waste more time trying to make it work. . .but if it should be working on WP 3.3, I guess I'll check my details again and make sure I'm not missing any steps or anything like that.

Thanks,

Jason

License information

Hi Jeremy,

I'm planning to use your code in a GPL project but you have not specified in what kind of license do you like to release this code.
I forked this repo, but I don't understand what a fork means in terms of license.
Can you help me, please?

The

Hi jeremy,
I saw your update meethod. in the update.php for theme update. .my_theme_api_call() was not working and the update was not properly working. kindly check the data and give the solution.

Improvements

just some suggestion, i'm not on my computer right now, so this is only some that i remember.

API Script

index.php
on basic_check we don't need to feed all the data to wp. just "slug", "version" and "package" is needed in transient. i'm not even sure "slug" is needed
(it's for plugins i can't remember what's the req for theme)

on plugin_information it's better to set external to true.
and not all html is allowed in sections. i''ll posted later list of allowed html in sections data. so this need to be sanitized and validate before sending or after recieving the data (or both, just to make sure)

packages.php
theme screenshot is not used, it sill use screenshot from the themes (so it's not needed)

in plugin sections tab, you did it wrong, we cannot create our own tab, the allowed tab are:

  • description
  • installation
  • faq
  • changelog (no space)
  • screenshots (no space)
  • other_notes (with underscore)

everything need to be simplified, you don't need multiple array in there when you array_shift-ed the package in index.php.

something like this might be better:

$packages['slug'] = array(
    '0.1.0' => array(
        'author' => '',
        //other data
        //version in not needed, already in array data
        //external is not needed, add it in index.php before sending
        //need better way to handle sections to easy section input, try file_get_contents or similar solutions.
    );
);

Plugin example

$request_string: don't need api-key, i don't think we use it anywhere.
unserialize: may be better to use maybeunserialize wp functions (it's better)
bad global naming.
not all plugin file name is the same as plugin folder name.

i'm not really sure, but in

$checked_data->response[$plugin_slug .'/'. $plugin_slug .'.php'] = $response;

there's a possibility that response is not set yet (?) since it's transient
so it's better to set it first.
when handling transient data (cause it's temporary data), it's better to assume that the data is not always available.

i guess that's it for today!
i'll try to read it more in depth once i have the time.

Multiple Plugins

I got this working on one plugin and it's great, but I just tried it on a 2nd plugin and it doesn't seem to work for the 2nd plugin. . .it's pulling in the data from the first plugin. . .

Is there anything special I need to do to have 2 plugins on the same WP Install?

f(x) Updater - Auto Update Theme & Plugin With UI

Hi all,
It seems that this project is no longer updated/maintain for over 2 years?

I create a similar project: f(x) Updater: https://genbumedia.com/plugins/fx-updater/
The feature is still limited, but I use it on daily basis.

GitHub Repo: https://github.com/turtlepod/fx-updater/

It's not a PHP script, but a WordPress plugin, so you can use your own site as update server for your private/premium themes and plugins. You can create a "theme repo" and "plugin repo" entry, just like creating post.

I highly recommend you check the screenshot to get ideas how this plugin works.

Some issues, and ideas

bad use of slugs

the code uses the directory and then assumes that the plugin is in the format of slug/slug.php which is not always correct, sometimes the php file has a different name

missing upgrade_notice

Sending this can give a nice effect, and it just needs to be added to packages.php

a suggestion, stop querying wordpress.org when using internal updates.

Why inform and query wordpress.org on irrelevant stuff?
see this code example: (for example, to hide bbpress)


function filter_parse_arr($arr, $url) {
    // hide from wordpress.org
    if ($url == "http://api.wordpress.org/plugins/update-check/1.0/") {
        $plugs = unserialize($arr['body']['plugins']);
        unset($plugs->plugins['bbpress/bbpress.php']);
        $arr['body']['plugins'] = serialize($plugs);
    }
    return $arr;
}```
### another suggestion, add a counter to the download.php

I implemented this locally with mysql, many other ideas can work

Great work, all in all :)

Theme Info

I need to put the changelog.txt in

'info' => array(
        'url' => 'http://domain.com/changelog.txt' 
    )

But the problem is the iframe in dashboard is too big. Is there any good way to display the theme changelog?

Solving WordPress server error message in Add New theme screen

Hi there!

A quick heads up for something that was troubling our setup.

On the Add new theme screen, we were getting this error:

"An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums."

Seems like interfering the themes_api in this screen won't behave nicely. Mostly because not all arguments are present in the request. We've fixed it by adding this:

if ( !property_exists($args, 'slug') ) return false;

right before this line:

if ( $args->slug != $theme_base ) return false;

Just wanted to share it here, in case someone needs that too.
Thanks for this great library!

Cannot modify header information

When I include the Code provided for automatically updating a plugin in my plugin I can't open any link that directly opens a file (like: http://www.domain.com/index.php) because I get
"Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00ea973/wordpress/wp-content/plugins/myPlugin/myPluginphp:1) in /www/htdocs/w00ea973/wordpress/wp-includes/pluggable.php on line 1207" and it doesn't do anything else. The updating procedure on the other hand works flawless and just the way I want it to work but I can not use your almost perfect code if it breaks almost the entire backend of wordpress. I hope you can help me and I can use your code because it's brilliant.

More Clear Directions for Multi-Plugin/Theme Users

I want to use this to distribute updates to my (at current time) 7 plugins and 3 themes. I presume, on the api side, I just need to copy and paste the template for the theme and plugin information over and over and just change the slug contained in packages['slug']. However, what do I need to change on the update.php file. It says that I need to prefix all functions. I presume that only applies to update.php. Although, one question I do have is does it matter what I prefix them with? In other words, if I prefix them with 'ex' do I need to prefix anything on the api side with 'ex'. I am assuming no, because the api side uses the slug of the plugin/theme.
Is this correct?

FYI, I really appreciate the amount of time spent making this, and as soon as I get our new site up and running (just got to get the update feature working), I might spend a couple blog posts on your plugin if you don't mind :) .

Debug Notice: Undefined property: stdClass::$slug

I get this notice when WP_DEBUG is on and I am in the backend searching for new plugins in /wp-admin/plugin-install.php
Undefined property: stdClass::$slug

---> it's mentioning the following code line from "test-plugin-update.php" line 77:

    if ($args->slug != $plugin_slug)

Could you do anything about that?

Thanks, Dave :)

P.S. Otherwise your library is working like a charm!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.