From d369868ea25ffad3fa199eebc40e7c01ef3ddae5 Mon Sep 17 00:00:00 2001 From: oldperl Date: Mon, 14 Nov 2011 15:56:27 +0000 Subject: [PATCH] added plugin update stuff --- trunk/includes/class.upgrademe.php | 198 +++++++++++++++++++++++++++++ trunk/semmelstatzR_startup.php | 8 ++ trunk/test/semr_update.php | 26 ++++ 3 files changed, 232 insertions(+) create mode 100644 trunk/includes/class.upgrademe.php create mode 100644 trunk/test/semr_update.php diff --git a/trunk/includes/class.upgrademe.php b/trunk/includes/class.upgrademe.php new file mode 100644 index 0000000..66c2e71 --- /dev/null +++ b/trunk/includes/class.upgrademe.php @@ -0,0 +1,198 @@ +getMethods(ReflectionMethod::IS_PUBLIC); +foreach($methods as $m) +{ +/** @var ReflectionMethod $m */ +if ($m->isStatic() && strpos($m->getName(), self::$WP_FILTER_PREFIX) === 0) { +add_filter(substr($m->getName(), strlen(self::$WP_FILTER_PREFIX)), array(get_class(), $m->getName()), +10, $m->getNumberOfParameters()); +} +} +} + +public static function wpFilter_http_response($response, $args, $url) +{ +# Control recursion +static $recursion = false; +if ($recursion) +return $response; + +if (empty($response) || !is_array($response) || !isset($response['body'])) +return $response; + +# Guess if it's time to take action +if ($url == 'http://api.wordpress.org/plugins/update-check/1.0/') +$showTime = true; +# Prevent failures if WordPress changes url for updates; we will detect if it still contains "update-check" token +# and called from withing wp_update_plugins() function +elseif (stripos($url, 'update-check') !== false) +{ +$showTime = false; +$trace = debug_backtrace(false); +foreach($trace as $t) +# http request made from within wp_update_plugins +if (isset($t['function']) && $t['function'] == 'wp_update_plugins') +{ +$showTime = true; +break; +} +unset($trace, $t); +} +else +$showTime = false; +if (!$showTime) +return $response; + +# Loop over plugins who provided _upgrademe() function and use returned url to request for up-to-date version signature. +# Collect retrieved (only valid) data into $upgrademe +$plugins = get_plugins(); +$upgrademe = array(); +foreach($plugins as $file => $info) +{ +# Get url if function exists +$slugName = str_replace('-', '_', basename($file, '.php')); + +# Request latest version signature from custom url (non-WP plugins repository api) && validate response variables +$recursion = true; +$vars = self::loadPluginData($slugName); +$recursion = false; +if (empty($vars)) +continue; + +$upgrademe[$file] = $vars; +} +if (!count($upgrademe)) +return $response; + +$body = $response['body']; +if (!empty($body)) +$body = unserialize($body); +if (empty($body)) +$body = array(); +foreach($upgrademe as $file => $upgradeVars) +{ +# Do not override data returned by official WP plugins repository API +if (isset($body[$file])) +continue; + +# If new version is different then current one, only then add info +if (!isset($plugins[$file]['Version']) || $plugins[$file]['Version'] == $upgradeVars['new_version']) +continue; + +$upgradeInfo = new stdClass(); +$upgradeInfo->id = $upgradeVars['id']; +$upgradeInfo->slug = $upgradeVars['slug']; +$upgradeInfo->new_version = $upgradeVars['new_version']; +$upgradeInfo->url = $upgradeVars['url']; +$upgradeInfo->package = $upgradeVars['package']; +$body[$file] = $upgradeInfo; +} +$response['body'] = serialize($body); +return $response; +} + +public static function wpFilter_plugins_api($value, $action, $args) +{ +// If for some reason value available already, do not change it +if (!empty($value)) +return $value; + +if ($action != 'plugin_information' || !is_object($args) || !isset($args->slug) || empty($args->slug)) +return $value; + +$vars = self::loadPluginData($args->slug); +if (empty($vars)) +return $value; + +return (object)$vars['info']; +} + +public static function wpFilter_http_request_args($args, $url) +{ +if (strpos($url, 'wp-upgrademe') === false || !is_array($args)) +return $args; + +$args['sslverify'] = false; +return $args; +} + +private static function loadPluginData($slug) +{ +if (isset(self::$data[$slug])) +return self::$data[$slug]; + +$funcName = $slug.'_upgrademe'; +if (!function_exists($funcName)) +return self::$data[$slug] = null; + +$upgradeUrl = filter_var(call_user_func($funcName), FILTER_VALIDATE_URL); +if (empty($upgradeUrl)) +return self::$data[$slug] = null; + +# Request latest version signature from custom url (non-WP plugins repository api) && validate response variables +$r = wp_remote_post($upgradeUrl, array('method' => 'POST', 'timeout' => 4, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, +'headers' => array(), 'body' => null, 'cookies' => array(), 'sslverify' => false)); + +if( is_wp_error($r) || !isset($r['body']) || empty($r['body'])) +return self::$data[$slug] = null; + +$vars = json_decode($r['body'], true); +if (empty($vars) || !is_array($vars) || count($vars) > 4 +|| !isset($vars['new_version']) || !isset($vars['url']) || !isset($vars['package']) || !isset($vars['info'])) +return self::$data[$slug] = null; + +# 2 147 483 648 - max int32 +# 16 777 215 - ffffff = max possible value of 6-letters hex +# 50 000 000 - reasonable offset +# Finally generate ID between 50 000 000 and 66 777 215 +$vars['id'] = 50000000 + hexdec(substr(md5($slug), 1, 6)); + +$vars['slug'] = $slug; + +# Sanitize variables of "info" +if (!is_array($vars['info'])) +$vars['info'] = array(); + +$info = array(); +foreach($vars['info'] as $key => $val) +{ +if (!in_array($key, array('name','slug','version','author','author_profile','contributors','requires','tested', +'compatibility','rating','rating','num_ratings','downloaded','last_updated','added','homepage', +'sections','download_link','tags'))) +continue; +$info[$key] = $val; +} +$info['slug'] = $slug; +$info['version'] = $vars['new_version']; +$info['download_link'] = $vars['url']; +$vars['info'] = $info; + +return self::$data[$slug] = $vars; +} +} +Upgrademe::register(); +} # class_exists() \ No newline at end of file diff --git a/trunk/semmelstatzR_startup.php b/trunk/semmelstatzR_startup.php index e6ff8d3..d9eacd6 100644 --- a/trunk/semmelstatzR_startup.php +++ b/trunk/semmelstatzR_startup.php @@ -70,4 +70,12 @@ if(!load_plugin_textdomain('semmelstatzR')) { include_once SEMMELSTATZR_SRVPATH.'/includes/functions.semr.php'; include_once SEMMELSTATZR_SRVPATH.'/includes/functions.semr_template.php'; +include_once SEMMELSTATZR_SRVPATH.'/includes/class.upgrademe.php'; +if(class_exists("Upgrademe")) { + function semmelstatzR_upgrademe() { + // will be changed to sf.net soon as website is ready + //return 'http://semmelstatz.sourceforge.net/semr_update.php'; + return 'http://www.php-backoffice.de/updates/semr_update.php'; + } +} ?> \ No newline at end of file diff --git a/trunk/test/semr_update.php b/trunk/test/semr_update.php new file mode 100644 index 0000000..50018b3 --- /dev/null +++ b/trunk/test/semr_update.php @@ -0,0 +1,26 @@ +{ +"new_version": "1.0.0 RC1", +"url": "http://sourceforge.net/projects/semmelstatz", +"package": "http://sourceforge.net/projects/semmelstatz/files", +"info": { +"name": "semmelstatzR", +"author": "SEM-Team", +"author_profile": "", +"requires": "2.8", +"tested": "3.2.1", +"rating": 0, +"num_ratings": 0, +"downloaded": 0, +"last_upated": "2011-07-15", +"added": "2011-07-15", +"homepage": "http://sourceforge.net/projects/semmelstatz", +"tags": {"wordpress":"wordpress","upgrade":"upgrade","update":"update","wp":"wp","repository":"repsitory","plugins":"plugins","hacks":"hacks","trucks":"trucks"}, +"sections":{ +"description": "The best Statz-Tool!", +"installation": "Take a look in the readme file.", +"screenshots":"", +"changelog":"", +"faq":"" +} +} +} \ No newline at end of file