-
-
Save Medalink/2208769 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Theme Updater | |
Plugin URI: https://github.com/UCF/Theme-Updater | |
Description: A theme updater for GitHub hosted Wordpress themes. This Wordpress plugin automatically checks GitHub for theme updates and enables automatic install. For more information read <a href="https://github.com/UCF/Theme-Updater/blob/master/readme.markdown">plugin documentation</a>. | |
Author: Douglas Beck | |
Author: UCF Web Communications | |
Version: 1.3.4 | |
*/ | |
require_once('assets.php'); | |
// register the custom stylesheet header | |
add_action( 'extra_theme_headers', 'github_extra_theme_headers' ); | |
function github_extra_theme_headers( $headers ) { | |
$headers['Github Theme URI'] = 'Github Theme URI'; | |
return $headers; | |
} | |
add_filter('site_transient_update_themes', 'transient_update_themes_filter'); | |
function transient_update_themes_filter($data){ | |
$installed_themes = get_themes( ); | |
foreach ( (array) $installed_themes as $theme_title => $theme ) { | |
// get the Github URI header, skip if not set | |
if(isset($theme['Stylesheet Files'][0]) && is_readable($theme['Stylesheet Files'][0])){ | |
$stylesheet = $theme['Stylesheet Dir'] . '/style.css'; | |
$theme_data = get_theme_data($stylesheet); | |
if(empty($theme_data['Github Theme URI'])){ | |
continue; | |
} | |
} | |
$theme['Github Theme URI'] = $theme_data['Github Theme URI']; | |
$theme_key = $theme['Stylesheet']; | |
// Add Github Theme Updater to return $data and hook into admin | |
remove_action( "after_theme_row_" . $theme['Stylesheet'], 'wp_theme_update_row'); | |
add_action( "after_theme_row_" . $theme['Stylesheet'], 'github_theme_update_row', 11, 2 ); | |
// Grab Github Tags | |
preg_match( | |
'/http(s)?:\/\/github.com\/(?<username>[\w-]+)\/(?<repo>[\w-]+)\/(?<branch>[\w-]+)$/', | |
$theme['Github Theme URI'], | |
$matches); | |
if(!isset($matches['username']) or !isset($matches['repo']) or !isset($matches['branch'])){ | |
$data->response[$theme_key]['error'] = 'Incorrect github project url. Format should be (no trailing slash): <code style="background:#FFFBE4;">https://github.com/<username>/<repo></code>'; | |
continue; | |
} | |
$url = 'https://api.github.com/repos/' . | |
// $matches['username'] . '/' . $matches['repo'] . '/' . $matches['branch'] . '/tags'; | |
$matches['username'] . '/' . $matches['repo'] . '/tags'; | |
$response = get_transient(md5($url)); // Note: WP transients fail if key is long than 45 characters | |
if(empty($response)){ | |
$raw_response = wp_remote_get($url, array('sslverify' => false, 'timeout' => 10)); | |
if ( is_wp_error( $raw_response ) ){ | |
$data->response[$theme_key]['error'] = "Error response from " . $url; | |
continue; | |
} | |
$response = json_decode($raw_response['body']); | |
if(isset($response->error)){ | |
if(is_array($response->error)){ | |
$errors = ''; | |
foreach ( $response->error as $error) { | |
$errors .= ' ' . $error; | |
} | |
} else { | |
$errors = print_r($response->error, true); | |
} | |
$data->response[$theme_key]['error'] = sprintf('While <a href="%s">fetching tags</a> api error</a>: <span class="error">%s</span>', $url, $errors); | |
continue; | |
} | |
if(!isset($response->tags) or count(get_object_vars($response->tags)) < 1){ | |
$data->response[$theme_key]['error'] = "Github theme does not have any tags"; | |
continue; | |
} | |
//set cache, just 60 seconds | |
set_transient(md5($url), $response, 30); | |
} | |
// Sort and get latest tag | |
$tags = array_keys(get_object_vars($response->tags)); | |
usort($tags, "version_compare"); | |
// check for rollback | |
if(isset($_GET['rollback'])){ | |
$data->response[$theme_key]['package'] = | |
$theme['Github Theme URI'] . '/zipball/' . $matches['branch'] . '/' . urlencode($_GET['rollback']); | |
continue; | |
} | |
// check and generate download link | |
$newest_tag = array_pop($tags); | |
if(version_compare($theme['Version'], $newest_tag, '>=')){ | |
// up-to-date! | |
$data->up_to_date[$theme_key]['rollback'] = $tags; | |
continue; | |
} | |
// new update available, add to $data | |
$download_link = $theme['Github Theme URI'] . '/zipball/' . $matches['branch'] . '/' . $newest_tag; | |
$update = array(); | |
$update['new_version'] = $newest_tag; | |
$update['url'] = $theme['Github Theme URI']; | |
$update['package'] = $download_link; | |
$data->response[$theme_key] = $update; | |
} | |
return $data; | |
} | |
add_filter('upgrader_source_selection', 'upgrader_source_selection_filter', 10, 3); | |
function upgrader_source_selection_filter($source, $remote_source=NULL, $upgrader=NULL){ | |
/* | |
Github delivers zip files as <Username>-<TagName>-<Hash>.zip | |
must rename this zip file to the accurate theme folder | |
*/ | |
if(isset($source, $remote_source, $upgrader->skin->theme)){ | |
$corrected_source = $remote_source . '/' . $upgrader->skin->theme . '/'; | |
if(@rename($source, $corrected_source)){ | |
return $corrected_source; | |
} else { | |
$upgrader->skin->feedback("Unable to rename downloaded theme."); | |
return new WP_Error(); | |
} | |
} | |
return $source; | |
} | |
/* | |
Function to address the issue that users in a standalone WordPress installation | |
were receiving SSL errors and were unable to install themes. | |
https://github.com/UCF/Theme-Updater/issues/3 | |
*/ | |
add_action('http_request_args', 'no_ssl_http_request_args', 10, 2); | |
function no_ssl_http_request_args($args, $url) { | |
$args['sslverify'] = false; | |
return $args; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/<username>/<repo>
'; continue; } $url = 'https://github.com/api/v2/json/repos/show/' . $matches['username'] . '/' . $matches['repo'] . '/tags'; $response = get_transient(md5($url)); // Note: WP transients fail if key is long than 45 characters if(empty($response)){ $raw_response = wp_remote_get($url, array('sslverify' => false, 'timeout' => 10)); if ( is_wp_error( $raw_response ) ){ $data->response[$theme_key]['error'] = "Error response from " . $url; continue; } $response = json_decode($raw_response['body']); if(isset($response->error)){ if(is_array($response->error)){ $errors = ''; foreach ( $response->error as $error) { $errors .= ' ' . $error; } } else { $errors = print_r($response->error, true); } $data->response[$theme_key]['error'] = sprintf('While fetching tags api error: %s', $url, $errors); continue; } if(!isset($response->tags) or count(get_object_vars($response->tags)) < 1){ $data->response[$theme_key]['error'] = "Github theme does not have any tags"; continue; } //set cache, just 60 seconds set_transient(md5($url), $response, 30); } // Sort and get latest tag $tags = array_keys(get_object_vars($response->tags)); usort($tags, "version_compare"); // check for rollback if(isset($_GET['rollback'])){ $data->response[$theme_key]['package'] = $theme['Github Theme URI'] . '/zipball/' . urlencode($_GET['rollback']); continue; } // check and generate download link $newest_tag = array_pop($tags); if(version_compare($theme['Version'], $newest_tag, '>=')){ // up-to-date! $data->up_to_date[$theme_key]['rollback'] = $tags; continue; } // new update available, add to $data $download_link = $theme['Github Theme URI'] . '/zipball/' . $newest_tag; $update = array(); $update['new_version'] = $newest_tag; $update['url'] = $theme['Github Theme URI']; $update['package'] = $download_link; $data->response[$theme_key] = $update; } return $data; ``` } add_filter('upgrader_source_selection', 'upgrader_source_selection_filter', 10, 3); function upgrader_source_selection_filter($source, $remote_source=NULL, $upgrader=NULL){ /* Github delivers zip files as --.zip must rename this zip file to the accurate theme folder */ if(isset($source, $remote_source, $upgrader->skin->theme)){ $corrected_source = $remote_source . '/' . $upgrader->skin->theme . '/'; if(@rename($source, $corrected_source)){ return $corrected_source; } else { $upgrader->skin->feedback("Unable to rename downloaded theme."); return new WP_Error(); } } return $source; } /* Function to address the issue that users in a standalone WordPress installation were receiving SSL errors and were unable to install themes. https://github.com/UCF/Theme-Updater/issues/3 */ add_action('http_request_args', 'no_ssl_http_request_args', 10, 2); function no_ssl_http_request_args($args, $url) { $args['sslverify'] = false; return $args; }