Show API errors when manually checking for updates.
Introduces a new hook: "puc_api_error". This is an action with up to 4 callback arguments: 1) $error - A WP_Error instance that provides a brief description of the error. 2) $response - The value returned by wp_remote_get(). Can be omitted if the original response is not available at this point. 3) $url - The URL that the update checker requested. Can be omitted. 4) $slug - The plugin or theme slug. Can be omitted. See #151
This commit is contained in:
parent
585f60d91c
commit
ec5ee45379
|
|
@ -2,6 +2,8 @@
|
|||
if ( !class_exists('Puc_v4p3_DebugBar_Extension', false) ):
|
||||
|
||||
class Puc_v4p3_DebugBar_Extension {
|
||||
const RESPONSE_BODY_LENGTH_LIMIT = 4000;
|
||||
|
||||
/** @var Puc_v4p3_UpdateChecker */
|
||||
protected $updateChecker;
|
||||
protected $panelClass = 'Puc_v4p3_DebugBar_Panel';
|
||||
|
|
@ -39,7 +41,7 @@ if ( !class_exists('Puc_v4p3_DebugBar_Extension', false) ):
|
|||
'puc-debug-bar-style-v4',
|
||||
$this->getLibraryUrl("/css/puc-debug-bar.css"),
|
||||
array('debug-bar'),
|
||||
'20161217'
|
||||
'20171124'
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
|
|
@ -66,6 +68,64 @@ if ( !class_exists('Puc_v4p3_DebugBar_Extension', false) ):
|
|||
} else {
|
||||
echo 'No updates found.';
|
||||
}
|
||||
|
||||
$errors = $this->updateChecker->getLastRequestApiErrors();
|
||||
if ( !empty($errors) ) {
|
||||
printf('<p>The update checker encountered %d API error%s.</p>', count($errors), (count($errors) > 1) ? 's' : '');
|
||||
|
||||
foreach (array_values($errors) as $num => $item) {
|
||||
$wpError = $item['error'];
|
||||
/** @var WP_Error $wpError */
|
||||
printf('<h4>%d) %s</h4>', $num + 1, esc_html($wpError->get_error_message()));
|
||||
|
||||
echo '<dl>';
|
||||
printf('<dt>Error code:</dt><dd><code>%s</code></dd>', esc_html($wpError->get_error_code()));
|
||||
|
||||
if ( isset($item['url']) ) {
|
||||
printf('<dt>Requested URL:</dt><dd><code>%s</code></dd>', esc_html($item['url']));
|
||||
}
|
||||
|
||||
if ( isset($item['httpResponse']) ) {
|
||||
if ( is_wp_error($item['httpResponse']) ) {
|
||||
$httpError = $item['httpResponse'];
|
||||
/** @var WP_Error $httpError */
|
||||
printf(
|
||||
'<dt>WordPress HTTP API error:</dt><dd>%s (<code>%s</code>)</dd>',
|
||||
esc_html($httpError->get_error_message()),
|
||||
esc_html($httpError->get_error_code())
|
||||
);
|
||||
} else {
|
||||
//Status code.
|
||||
printf(
|
||||
'<dt>HTTP status:</dt><dd><code>%d %s</code></dd>',
|
||||
wp_remote_retrieve_response_code($item['httpResponse']),
|
||||
wp_remote_retrieve_response_message($item['httpResponse'])
|
||||
);
|
||||
|
||||
//Headers.
|
||||
echo '<dt>Response headers:</dt><dd><pre>';
|
||||
foreach (wp_remote_retrieve_headers($item['httpResponse']) as $name => $value) {
|
||||
printf("%s: %s\n", esc_html($name), esc_html($value));
|
||||
}
|
||||
echo '</pre></dd>';
|
||||
|
||||
//Body.
|
||||
$body = wp_remote_retrieve_body($item['httpResponse']);
|
||||
if ( $body === '' ) {
|
||||
$body = '(Empty response.)';
|
||||
} else if ( strlen($body) > self::RESPONSE_BODY_LENGTH_LIMIT ) {
|
||||
$length = strlen($body);
|
||||
$body = substr($body, 0, self::RESPONSE_BODY_LENGTH_LIMIT)
|
||||
. sprintf("\n(Long string truncated. Total length: %d bytes.)", $length);
|
||||
}
|
||||
|
||||
printf('<dt>Response body:</dt><dd><pre>%s</pre></dd>', esc_html($body));
|
||||
}
|
||||
}
|
||||
echo '<dl>';
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +139,7 @@ if ( !class_exists('Puc_v4p3_DebugBar_Extension', false) ):
|
|||
check_ajax_referer('puc-ajax');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
@ini_set('display_errors','On');
|
||||
@ini_set('display_errors', 'On');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,15 +30,15 @@ if ( !class_exists('Puc_v4p3_Metadata', false) ):
|
|||
/** @var StdClass $apiResponse */
|
||||
$apiResponse = json_decode($json);
|
||||
if ( empty($apiResponse) || !is_object($apiResponse) ){
|
||||
trigger_error(
|
||||
"Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/",
|
||||
E_USER_NOTICE
|
||||
);
|
||||
$errorMessage = "Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/";
|
||||
do_action('puc_api_error', new WP_Error('puc-invalid-json', $errorMessage));
|
||||
trigger_error($errorMessage, E_USER_NOTICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
$valid = $target->validateMetadata($apiResponse);
|
||||
if ( is_wp_error($valid) ){
|
||||
do_action('puc_api_error', $valid);
|
||||
trigger_error($valid->get_error_message(), E_USER_NOTICE);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ if ( !class_exists('Puc_v4p3_Plugin_UpdateChecker', false) ):
|
|||
public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
|
||||
|
||||
private $cachedInstalledVersion = null;
|
||||
private $manualCheckErrorTransient = '';
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
|
|
@ -61,6 +62,8 @@ if ( !class_exists('Puc_v4p3_Plugin_UpdateChecker', false) ):
|
|||
//Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
|
||||
add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
|
||||
|
||||
$this->manualCheckErrorTransient = $this->getUniqueName('manual_check_errors');
|
||||
|
||||
parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +416,7 @@ if ( !class_exists('Puc_v4p3_Plugin_UpdateChecker', false) ):
|
|||
* Returning 'append' places the link after any existing links at the time of the hook.
|
||||
* Returning 'replace' replaces the "Visit plugin site" link
|
||||
* Returning anything else disables the link when there is a "Visit plugin site" link.
|
||||
*
|
||||
*
|
||||
* If there is no "Visit plugin site" link 'append' is always used!
|
||||
*
|
||||
* @param array $pluginMeta Array of meta links.
|
||||
|
|
@ -490,6 +493,34 @@ if ( !class_exists('Puc_v4p3_Plugin_UpdateChecker', false) ):
|
|||
if ( $shouldCheck ) {
|
||||
$update = $this->checkForUpdates();
|
||||
$status = ($update === null) ? 'no_update' : 'update_available';
|
||||
|
||||
if ( ($update === null) && !empty($this->lastRequestApiErrors) ) {
|
||||
//Some errors are not critical. For example, if PUC tries to retrieve the readme.txt
|
||||
//file from GitHub and gets a 404, that's an API error, but it doesn't prevent updates
|
||||
//from working. Maybe the plugin simply doesn't have a readme.
|
||||
//Let's only show important errors.
|
||||
$foundCriticalErrors = false;
|
||||
$questionableErrorCodes = array(
|
||||
'puc-github-http-error',
|
||||
'puc-gitlab-http-error',
|
||||
'puc-bitbucket-http-error',
|
||||
);
|
||||
|
||||
foreach ($this->lastRequestApiErrors as $item) {
|
||||
$wpError = $item['error'];
|
||||
/** @var WP_Error $wpError */
|
||||
if ( !in_array($wpError->get_error_code(), $questionableErrorCodes) ) {
|
||||
$foundCriticalErrors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $foundCriticalErrors ) {
|
||||
$status = 'error';
|
||||
set_site_transient($this->manualCheckErrorTransient, $this->lastRequestApiErrors, 60);
|
||||
}
|
||||
}
|
||||
|
||||
wp_redirect(add_query_arg(
|
||||
array(
|
||||
'puc_update_check_result' => $status,
|
||||
|
|
@ -508,22 +539,69 @@ if ( !class_exists('Puc_v4p3_Plugin_UpdateChecker', false) ):
|
|||
*/
|
||||
public function displayManualCheckResult() {
|
||||
if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->slug) ) {
|
||||
$status = strval($_GET['puc_update_check_result']);
|
||||
$title = $this->getPluginTitle();
|
||||
$status = strval($_GET['puc_update_check_result']);
|
||||
$title = $this->getPluginTitle();
|
||||
$noticeClass = 'updated notice-success';
|
||||
$details = '';
|
||||
|
||||
if ( $status == 'no_update' ) {
|
||||
$message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title);
|
||||
} else if ( $status == 'update_available' ) {
|
||||
$message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title);
|
||||
} else if ( $status === 'error' ) {
|
||||
$message = sprintf(_x('Could not determine if updates are available for %s.', 'the plugin title', 'plugin-update-checker'), $title);
|
||||
$noticeClass = 'error notice-error';
|
||||
|
||||
$details = $this->formatManualCheckErrors(get_site_transient($this->manualCheckErrorTransient));
|
||||
delete_site_transient($this->manualCheckErrorTransient);
|
||||
} else {
|
||||
$message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status));
|
||||
$noticeClass = 'error notice-error';
|
||||
}
|
||||
printf(
|
||||
'<div class="updated notice is-dismissible"><p>%s</p></div>',
|
||||
apply_filters($this->getUniqueName('manual_check_message'), $message, $status)
|
||||
'<div class="notice %s is-dismissible"><p>%s</p>%s</div>',
|
||||
$noticeClass,
|
||||
apply_filters($this->getUniqueName('manual_check_message'), $message, $status),
|
||||
$details
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the list of errors that were thrown during an update check.
|
||||
*
|
||||
* @param array $errors
|
||||
* @return string
|
||||
*/
|
||||
protected function formatManualCheckErrors($errors) {
|
||||
if ( empty($errors) ) {
|
||||
return '';
|
||||
}
|
||||
$output = '';
|
||||
|
||||
$showAsList = count($errors) > 1;
|
||||
if ( $showAsList ) {
|
||||
$output .= '<ol>';
|
||||
$formatString = '<li>%1$s <code>%2$s</code></li>';
|
||||
} else {
|
||||
$formatString = '<p>%1$s <code>%2$s</code></p>';
|
||||
}
|
||||
foreach ($errors as $item) {
|
||||
$wpError = $item['error'];
|
||||
/** @var WP_Error $wpError */
|
||||
$output .= sprintf(
|
||||
$formatString,
|
||||
$wpError->get_error_message(),
|
||||
$wpError->get_error_code()
|
||||
);
|
||||
}
|
||||
if ( $showAsList ) {
|
||||
$output .= '</ol>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translated plugin title.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ if ( !class_exists('Puc_v4p3_UpdateChecker', false) ):
|
|||
*/
|
||||
protected $updateState;
|
||||
|
||||
/**
|
||||
* @var array List of API errors triggered during the last checkForUpdates() call.
|
||||
*/
|
||||
protected $lastRequestApiErrors = array();
|
||||
|
||||
public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
|
||||
$this->debugMode = (bool)(constant('WP_DEBUG'));
|
||||
$this->metadataUrl = $metadataUrl;
|
||||
|
|
@ -214,6 +219,10 @@ if ( !class_exists('Puc_v4p3_UpdateChecker', false) ):
|
|||
return null;
|
||||
}
|
||||
|
||||
//Start collecting API errors.
|
||||
$this->lastRequestApiErrors = array();
|
||||
add_action('puc_api_error', array($this, 'collectApiErrors'), 10, 4);
|
||||
|
||||
$state = $this->updateState;
|
||||
$state->setLastCheckToNow()
|
||||
->setCheckedVersion($installedVersion)
|
||||
|
|
@ -222,6 +231,9 @@ if ( !class_exists('Puc_v4p3_UpdateChecker', false) ):
|
|||
$state->setUpdate($this->requestUpdate());
|
||||
$state->save();
|
||||
|
||||
//Stop collecting API errors.
|
||||
remove_action('puc_api_error', array($this, 'collectApiErrors'), 10);
|
||||
|
||||
return $this->getUpdate();
|
||||
}
|
||||
|
||||
|
|
@ -340,6 +352,34 @@ if ( !class_exists('Puc_v4p3_UpdateChecker', false) ):
|
|||
return $name . '-' . $this->slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store API errors that are generated when checking for updates.
|
||||
*
|
||||
* @internal
|
||||
* @param WP_Error $error
|
||||
* @param array|null $httpResponse
|
||||
* @param string|null $url
|
||||
* @param string|null $slug
|
||||
*/
|
||||
public function collectApiErrors($error, $httpResponse = null, $url = null, $slug = null) {
|
||||
if ( isset($slug) && ($slug !== $this->slug) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->lastRequestApiErrors[] = array(
|
||||
'error' => $error,
|
||||
'httpResponse' => $httpResponse,
|
||||
'url' => $url,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLastRequestApiErrors() {
|
||||
return $this->lastRequestApiErrors;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* PUC filters and filter utilities
|
||||
* -------------------------------------------------------------------
|
||||
|
|
@ -493,6 +533,7 @@ if ( !class_exists('Puc_v4p3_UpdateChecker', false) ):
|
|||
if ( !is_wp_error($status) ){
|
||||
$metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
|
||||
} else {
|
||||
do_action('puc_api_error', $status, $result, $url, $this->slug);
|
||||
$this->triggerError(
|
||||
sprintf('The URL %s does not point to a valid metadata file. ', $url)
|
||||
. $status->get_error_message(),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ if ( !class_exists('Puc_v4p3_Vcs_Api') ):
|
|||
|
||||
abstract class Puc_v4p3_Vcs_Api {
|
||||
protected $tagNameProperty = 'name';
|
||||
protected $slug = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
|
@ -289,6 +290,13 @@ if ( !class_exists('Puc_v4p3_Vcs_Api') ):
|
|||
$this->localDirectory = $directory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*/
|
||||
public function setSlug($slug) {
|
||||
$this->slug = $slug;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ if ( !class_exists('Puc_v4p3_Vcs_BitBucketApi', false) ):
|
|||
$this->repository,
|
||||
ltrim($url, '/')
|
||||
));
|
||||
$baseUrl = $url;
|
||||
|
||||
if ( $this->oauth ) {
|
||||
$url = $this->oauth->sign($url,'GET');
|
||||
|
|
@ -205,6 +206,7 @@ if ( !class_exists('Puc_v4p3_Vcs_BitBucketApi', false) ):
|
|||
}
|
||||
$response = wp_remote_get($url, $options);
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
@ -215,10 +217,13 @@ if ( !class_exists('Puc_v4p3_Vcs_BitBucketApi', false) ):
|
|||
return $document;
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
$error = new WP_Error(
|
||||
'puc-bitbucket-http-error',
|
||||
'BitBucket API error. HTTP status: ' . $code
|
||||
sprintf('BitBucket API error. Base URL: "%s", HTTP status code: %d.', $baseUrl, $code)
|
||||
);
|
||||
do_action('puc_api_error', $error, $response, $url, $this->slug);
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ if ( !class_exists('Puc_v4p3_Vcs_GitHubApi', false) ):
|
|||
* @return mixed|WP_Error
|
||||
*/
|
||||
protected function api($url, $queryParams = array()) {
|
||||
$baseUrl = $url;
|
||||
$url = $this->buildApiUrl($url, $queryParams);
|
||||
|
||||
$options = array('timeout' => 10);
|
||||
|
|
@ -166,6 +167,7 @@ if ( !class_exists('Puc_v4p3_Vcs_GitHubApi', false) ):
|
|||
}
|
||||
$response = wp_remote_get($url, $options);
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
@ -176,10 +178,13 @@ if ( !class_exists('Puc_v4p3_Vcs_GitHubApi', false) ):
|
|||
return $document;
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
$error = new WP_Error(
|
||||
'puc-github-http-error',
|
||||
'GitHub API error. HTTP status: ' . $code
|
||||
sprintf('GitHub API error. Base URL: "%s", HTTP status code: %d.', $baseUrl, $code)
|
||||
);
|
||||
do_action('puc_api_error', $error, $response, $url, $this->slug);
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ if ( !class_exists('Puc_v4p3_Vcs_GitLabApi', false) ):
|
|||
* @return mixed|WP_Error
|
||||
*/
|
||||
protected function api($url, $queryParams = array()) {
|
||||
$baseUrl = $url;
|
||||
$url = $this->buildApiUrl($url, $queryParams);
|
||||
|
||||
$options = array('timeout' => 10);
|
||||
|
|
@ -145,6 +146,7 @@ if ( !class_exists('Puc_v4p3_Vcs_GitLabApi', false) ):
|
|||
|
||||
$response = wp_remote_get($url, $options);
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
@ -154,10 +156,13 @@ if ( !class_exists('Puc_v4p3_Vcs_GitLabApi', false) ):
|
|||
return json_decode($body);
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
$error = new WP_Error(
|
||||
'puc-gitlab-http-error',
|
||||
'GitLab API Error. HTTP status: ' . $code
|
||||
sprintf('GitLab API error. URL: "%s", HTTP status code: %d.', $baseUrl, $code)
|
||||
);
|
||||
do_action('puc_api_error', $error, $response, $url, $this->slug);
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ if ( !class_exists('Puc_v4p3_Vcs_PluginUpdateChecker') ):
|
|||
$this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
|
||||
|
||||
parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
|
||||
|
||||
$this->api->setSlug($this->slug);
|
||||
}
|
||||
|
||||
public function requestInfo($unusedParameter = null) {
|
||||
|
|
@ -61,6 +63,16 @@ if ( !class_exists('Puc_v4p3_Vcs_PluginUpdateChecker') ):
|
|||
}
|
||||
} else {
|
||||
//There's probably a network problem or an authentication error.
|
||||
do_action(
|
||||
'puc_api_error',
|
||||
new WP_Error(
|
||||
'puc-no-update-source',
|
||||
'Could not retrieve version information from the repository. '
|
||||
. 'This usually means that the update checker either can\'t connect '
|
||||
. 'to the repository or it\'s configured incorrectly.'
|
||||
),
|
||||
null, null, $this->slug
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ if ( !class_exists('Puc_v4p3_Vcs_ThemeUpdateChecker', false) ):
|
|||
$this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
|
||||
|
||||
parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
|
||||
|
||||
$this->api->setSlug($this->slug);
|
||||
}
|
||||
|
||||
public function requestUpdate() {
|
||||
|
|
@ -42,6 +44,16 @@ if ( !class_exists('Puc_v4p3_Vcs_ThemeUpdateChecker', false) ):
|
|||
$ref = $updateSource->name;
|
||||
$update->download_url = $updateSource->downloadUrl;
|
||||
} else {
|
||||
do_action(
|
||||
'puc_api_error',
|
||||
new WP_Error(
|
||||
'puc-no-update-source',
|
||||
'Could not retrieve version information from the repository. '
|
||||
. 'This usually means that the update checker either can\'t connect '
|
||||
. 'to the repository or it\'s configured incorrectly.'
|
||||
),
|
||||
null, null, $this->slug
|
||||
);
|
||||
$ref = $this->branch;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,4 +59,12 @@ table.puc-debug-data td {
|
|||
|
||||
.puc-ajax-nonce {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.puc-ajax-response dt {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.puc-ajax-response dd {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2017-05-20 10:53+0300\n"
|
||||
"POT-Creation-Date: 2017-11-24 17:02+0200\n"
|
||||
"PO-Revision-Date: 2016-01-10 20:59+0100\n"
|
||||
"Last-Translator: Tamás András Horváth <htomy92@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -10,34 +10,40 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.2\n"
|
||||
"X-Generator: Poedit 2.0.4\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: Puc/v4p1/Plugin/UpdateChecker.php:358
|
||||
#: Puc/v4p3/Plugin/UpdateChecker.php:395
|
||||
msgid "Check for updates"
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v4p1/Plugin/UpdateChecker.php:405
|
||||
#: Puc/v4p3/Plugin/UpdateChecker.php:548
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v4p1/Plugin/UpdateChecker.php:407
|
||||
#: Puc/v4p3/Plugin/UpdateChecker.php:550
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v4p1/Plugin/UpdateChecker.php:409
|
||||
#: Puc/v4p3/Plugin/UpdateChecker.php:552
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v4p3/Plugin/UpdateChecker.php:558
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
|
||||
#: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
|
||||
msgid "There is no changelog available."
|
||||
msgstr ""
|
||||
|
|
|
|||
Loading…
Reference in New Issue