Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
365a3898b9 | ||
|
|
2bbd2dc7c8 |
@@ -5,3 +5,5 @@ notes/
|
||||
vendor/
|
||||
phpunit.xml
|
||||
.phpunit.result.cache
|
||||
# But DO track the vendor/ that ships with the bundled plugin-update-checker library.
|
||||
!/includes/plugin-update-checker/vendor/
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace YahnisElsts\PluginUpdateChecker\v5;
|
||||
|
||||
if ( !class_exists(PucFactory::class, false) ):
|
||||
|
||||
class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p4\PucFactory {
|
||||
class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p7\PucFactory {
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(Autoloader::class, false) ):
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\PucFactory;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker;
|
||||
|
||||
if ( !class_exists(Extension::class, false) ):
|
||||
|
||||
+19
-11
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker;
|
||||
|
||||
if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false) ):
|
||||
|
||||
@@ -41,11 +41,11 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
||||
echo '<h3>Configuration</h3>';
|
||||
echo '<table class="puc-debug-data">';
|
||||
$this->displayConfigHeader();
|
||||
$this->row('Slug', htmlentities($this->updateChecker->slug));
|
||||
$this->row('DB option', htmlentities($this->updateChecker->optionName));
|
||||
$this->row('Slug', esc_html($this->updateChecker->slug));
|
||||
$this->row('DB option', esc_html($this->updateChecker->optionName));
|
||||
|
||||
$requestInfoButton = $this->getMetadataButton();
|
||||
$this->row('Metadata URL', htmlentities($this->updateChecker->metadataUrl) . ' ' . $requestInfoButton . $this->responseBox);
|
||||
$this->row('Metadata URL', esc_html($this->updateChecker->metadataUrl) . ' ' . $requestInfoButton . $this->responseBox);
|
||||
|
||||
$scheduler = $this->updateChecker->scheduler;
|
||||
if ( $scheduler->checkPeriod > 0 ) {
|
||||
@@ -86,14 +86,22 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
||||
echo '<h3>Status</h3>';
|
||||
echo '<table class="puc-debug-data">';
|
||||
$state = $this->updateChecker->getUpdateState();
|
||||
$checkNowButton = '';
|
||||
$checkButtonId = $this->updateChecker->getUniqueName('check-now-button');
|
||||
if ( function_exists('get_submit_button') ) {
|
||||
$checkNowButton = get_submit_button(
|
||||
'Check Now',
|
||||
'secondary',
|
||||
'puc-check-now-button',
|
||||
false,
|
||||
array('id' => $this->updateChecker->getUniqueName('check-now-button'))
|
||||
array('id' => $checkButtonId)
|
||||
);
|
||||
} else {
|
||||
//get_submit_button() is not available in the frontend. Make a button directly.
|
||||
//It won't look the same without admin styles, but it should still work.
|
||||
$checkNowButton = sprintf(
|
||||
'<input type="button" id="%1$s" name="puc-check-now-button" value="%2$s" class="button button-secondary" />',
|
||||
esc_attr($checkButtonId),
|
||||
esc_attr('Check Now')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,10 +115,10 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
||||
$this->row('Next automatic check', $this->formatTimeWithDelta($nextCheck));
|
||||
|
||||
if ( $state->getCheckedVersion() !== '' ) {
|
||||
$this->row('Checked version', htmlentities($state->getCheckedVersion()));
|
||||
$this->row('Checked version', esc_html($state->getCheckedVersion()));
|
||||
$this->row('Cached update', $state->getUpdate());
|
||||
}
|
||||
$this->row('Update checker class', htmlentities(get_class($this->updateChecker)));
|
||||
$this->row('Update checker class', esc_html(get_class($this->updateChecker)));
|
||||
echo '</table>';
|
||||
}
|
||||
|
||||
@@ -124,7 +132,7 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
||||
if ( property_exists($update, $field) ) {
|
||||
$this->row(
|
||||
ucwords(str_replace('_', ' ', $field)),
|
||||
isset($update->$field) ? htmlentities($update->$field) : null
|
||||
isset($update->$field) ? esc_html($update->$field) : null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +170,7 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
||||
if ( is_object($value) || is_array($value) ) {
|
||||
//This is specifically for debugging, so print_r() is fine.
|
||||
//phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
||||
$value = '<pre>' . htmlentities(print_r($value, true)) . '</pre>';
|
||||
$value = '<pre>' . esc_html(print_r($value, true)) . '</pre>';
|
||||
} else if ($value === null) {
|
||||
$value = '<code>null</code>';
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Plugin\UpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Plugin\UpdateChecker;
|
||||
|
||||
if ( !class_exists(PluginExtension::class, false) ):
|
||||
|
||||
+11
-5
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Plugin\UpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Plugin\UpdateChecker;
|
||||
|
||||
if ( !class_exists(PluginPanel::class, false) ):
|
||||
|
||||
@@ -12,19 +12,25 @@ if ( !class_exists(PluginPanel::class, false) ):
|
||||
protected $updateChecker;
|
||||
|
||||
protected function displayConfigHeader() {
|
||||
$this->row('Plugin file', htmlentities($this->updateChecker->pluginFile));
|
||||
$this->row('Plugin file', esc_html($this->updateChecker->pluginFile));
|
||||
parent::displayConfigHeader();
|
||||
}
|
||||
|
||||
protected function getMetadataButton() {
|
||||
$requestInfoButton = '';
|
||||
$buttonId = $this->updateChecker->getUniqueName('request-info-button');
|
||||
if ( function_exists('get_submit_button') ) {
|
||||
$requestInfoButton = get_submit_button(
|
||||
'Request Info',
|
||||
'secondary',
|
||||
'puc-request-info-button',
|
||||
false,
|
||||
array('id' => $this->updateChecker->getUniqueName('request-info-button'))
|
||||
array('id' => $buttonId)
|
||||
);
|
||||
} else {
|
||||
$requestInfoButton = sprintf(
|
||||
'<input type="button" name="puc-request-info-button" id="%1$s" value="%2$s" class="button button-secondary" />',
|
||||
esc_attr($buttonId),
|
||||
esc_attr('Request Info')
|
||||
);
|
||||
}
|
||||
return $requestInfoButton;
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Theme\UpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Theme\UpdateChecker;
|
||||
|
||||
if ( !class_exists(ThemePanel::class, false) ):
|
||||
|
||||
@@ -13,7 +13,7 @@ if ( !class_exists(ThemePanel::class, false) ):
|
||||
protected $updateChecker;
|
||||
|
||||
protected function displayConfigHeader() {
|
||||
$this->row('Theme directory', htmlentities($this->updateChecker->directoryName));
|
||||
$this->row('Theme directory', esc_html($this->updateChecker->directoryName));
|
||||
parent::displayConfigHeader();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(InstalledPackage::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use LogicException;
|
||||
use stdClass;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(OAuthSignature::class, false) ):
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\PucFactory;
|
||||
|
||||
if ( !class_exists(Package::class, false) ):
|
||||
|
||||
+3
-2
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Metadata;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Metadata;
|
||||
|
||||
if ( !class_exists(PluginInfo::class, false) ):
|
||||
|
||||
@@ -39,6 +39,7 @@ if ( !class_exists(PluginInfo::class, false) ):
|
||||
public $downloaded;
|
||||
public $active_installs;
|
||||
public $last_updated;
|
||||
public $autoupdate = false;
|
||||
|
||||
public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
if ( !class_exists(Ui::class, false) ):
|
||||
/**
|
||||
@@ -187,7 +187,7 @@ if ( !class_exists(Ui::class, false) ):
|
||||
}
|
||||
}
|
||||
|
||||
wp_redirect(add_query_arg(
|
||||
wp_safe_redirect(add_query_arg(
|
||||
array(
|
||||
'puc_update_check_result' => $status,
|
||||
'puc_slug' => $this->updateChecker->slug,
|
||||
+6
-4
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Update as BaseUpdate;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Update as BaseUpdate;
|
||||
|
||||
if ( !class_exists(Update::class, false) ):
|
||||
|
||||
@@ -20,9 +20,10 @@ if ( !class_exists(Update::class, false) ):
|
||||
public $requires_php = false;
|
||||
public $icons = array();
|
||||
public $filename; //Plugin filename relative to the plugins directory.
|
||||
public $autoupdate = false;
|
||||
|
||||
protected static $extraFields = array(
|
||||
'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename',
|
||||
'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename', 'autoupdate',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -86,6 +87,7 @@ if ( !class_exists(Update::class, false) ):
|
||||
$update->tested = $this->tested;
|
||||
$update->requires_php = $this->requires_php;
|
||||
$update->plugin = $this->filename;
|
||||
$update->autoupdate = $this->autoupdate;
|
||||
|
||||
if ( !empty($this->upgrade_notice) ) {
|
||||
$update->upgrade_notice = $this->upgrade_notice;
|
||||
@@ -102,7 +104,7 @@ if ( !class_exists(Update::class, false) ):
|
||||
$update->icons = $icons;
|
||||
|
||||
//It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
|
||||
//but lets set it just in case a future release needs it.
|
||||
//but let's set it just in case a future release needs it.
|
||||
if ( !isset($update->icons['default']) ) {
|
||||
$update->icons['default'] = current($update->icons);
|
||||
}
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker as BaseUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Scheduler;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker as BaseUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Scheduler;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
if ( !class_exists(UpdateChecker::class, false) ):
|
||||
|
||||
+7
-7
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !class_exists(PucFactory::class, false) ):
|
||||
|
||||
@@ -86,7 +86,7 @@ if ( !class_exists(PucFactory::class, false) ):
|
||||
throw new \RuntimeException(sprintf(
|
||||
'The update checker cannot determine if "%s" is a plugin or a theme. ' .
|
||||
'This is a bug. Please contact the PUC developer.',
|
||||
htmlentities($fullPath)
|
||||
esc_html($fullPath)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ if ( !class_exists(PucFactory::class, false) ):
|
||||
*
|
||||
* Normalize a filesystem path. Introduced in WP 3.9.
|
||||
* Copying here allows use of the class on earlier versions.
|
||||
* This version adapted from WP 4.8.2 (unchanged since 4.5.4)
|
||||
* This version adapted from WP 4.8.2 (unchanged since 4.5.7)
|
||||
*
|
||||
* @param string $path Path to normalize.
|
||||
* @return string Normalized path.
|
||||
@@ -239,7 +239,7 @@ if ( !class_exists(PucFactory::class, false) ):
|
||||
|
||||
//URI was not found so throw an error.
|
||||
throw new \RuntimeException(
|
||||
sprintf('Unable to locate URI in header of "%s"', htmlentities($fullPath))
|
||||
sprintf('Unable to locate URI in header of "%s"', esc_html($fullPath))
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(Scheduler::class, false) ):
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(StateStore::class, false) ):
|
||||
|
||||
@@ -77,7 +77,7 @@ if ( !class_exists(StateStore::class, false) ):
|
||||
* @param Update|null $update
|
||||
* @return $this
|
||||
*/
|
||||
public function setUpdate(Update $update = null) {
|
||||
public function setUpdate($update = null) {
|
||||
$this->lazyLoad();
|
||||
$this->update = $update;
|
||||
return $this;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||
|
||||
if ( !class_exists(Package::class, false) ):
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Update as BaseUpdate;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Update as BaseUpdate;
|
||||
|
||||
if ( !class_exists(Update::class, false) ):
|
||||
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker as BaseUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Scheduler;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker as BaseUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Scheduler;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||
|
||||
if ( !class_exists(UpdateChecker::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use stdClass;
|
||||
|
||||
+172
-20
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use stdClass;
|
||||
use WP_Error;
|
||||
@@ -171,6 +171,10 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
//Allow HTTP requests to the metadata URL even if it's on a local host.
|
||||
add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
|
||||
|
||||
//Potentially exclude information about this entity from core update check requests to api.wordpress.org.
|
||||
//phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- Doesn't modify timeouts.
|
||||
add_filter('http_request_args', array($this, 'excludeEntityFromWordPressAPI'), 10, 2);
|
||||
|
||||
//DebugBar integration.
|
||||
if ( did_action('plugins_loaded') ) {
|
||||
$this->maybeInitDebugBar();
|
||||
@@ -192,6 +196,7 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
|
||||
remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
|
||||
remove_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10);
|
||||
remove_filter('http_request_args', array($this, 'excludeEntityFromWordPressAPI'));
|
||||
remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
|
||||
|
||||
remove_action('init', array($this, 'loadTextDomain'));
|
||||
@@ -266,6 +271,76 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
*/
|
||||
abstract protected function createScheduler($checkPeriod);
|
||||
|
||||
/**
|
||||
* Remove information about this plugin or theme from the requests that WordPress core sends
|
||||
* to api.wordpress.org when checking for updates.
|
||||
*
|
||||
* @param array $args
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public function excludeEntityFromWordPressAPI($args, $url) {
|
||||
//Is this an api.wordpress.org update check request?
|
||||
$parsedUrl = wp_parse_url($url);
|
||||
if ( !isset($parsedUrl['host']) || (strtolower($parsedUrl['host']) !== 'api.wordpress.org') ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$typePluralised = $this->componentType . 's';
|
||||
$expectedPathPrefix = '/' . $typePluralised . '/update-check/1.'; //e.g. "/plugins/update-check/1.1/"
|
||||
if ( !isset($parsedUrl['path']) || !Utils::startsWith($parsedUrl['path'], $expectedPathPrefix) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
//Plugins and themes can disable this feature by using the filter below.
|
||||
if ( !apply_filters(
|
||||
$this->getUniqueName('remove_from_default_update_checks'),
|
||||
true, $this, $args, $url
|
||||
) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
if ( empty($args['body'][$typePluralised]) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
$reportingItems = json_decode($args['body'][$typePluralised], true);
|
||||
if ( $reportingItems === null ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
//The list of installed items uses different key formats for plugins and themes.
|
||||
//Luckily, we can reuse the getUpdateListKey() method here.
|
||||
$updateListKey = $this->getUpdateListKey();
|
||||
if ( isset($reportingItems[$typePluralised][$updateListKey]) ) {
|
||||
unset($reportingItems[$typePluralised][$updateListKey]);
|
||||
}
|
||||
|
||||
if ( !empty($reportingItems['active']) ) {
|
||||
if ( is_array($reportingItems['active']) ) {
|
||||
foreach ($reportingItems['active'] as $index => $relativePath) {
|
||||
if ( $relativePath === $updateListKey ) {
|
||||
unset($reportingItems['active'][$index]);
|
||||
}
|
||||
}
|
||||
//Re-index the array.
|
||||
$reportingItems['active'] = array_values($reportingItems['active']);
|
||||
} else if ( $reportingItems['active'] === $updateListKey ) {
|
||||
//For themes, the "active" field is a string that contains the theme's directory name.
|
||||
//Pretend that the default theme is active so that we don't reveal the actual theme.
|
||||
if ( defined('WP_DEFAULT_THEME') ) {
|
||||
$reportingItems['active'] = WP_DEFAULT_THEME;
|
||||
}
|
||||
|
||||
//Unfortunately, it doesn't seem to be documented if we can safely remove the "active"
|
||||
//key. So when we don't know the default theme, we'll just leave it as is.
|
||||
}
|
||||
}
|
||||
|
||||
$args['body'][$typePluralised] = wp_json_encode($reportingItems);
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for updates. The results are stored in the DB option specified in $optionName.
|
||||
*
|
||||
@@ -384,7 +459,7 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
*
|
||||
* @param Metadata|null $update
|
||||
*/
|
||||
protected function fixSupportedWordpressVersion(Metadata $update = null) {
|
||||
protected function fixSupportedWordpressVersion($update = null) {
|
||||
if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
|
||||
return;
|
||||
}
|
||||
@@ -557,7 +632,15 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
if ( !empty($update) ) {
|
||||
//Let plugins filter the update info before it's passed on to WordPress.
|
||||
$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
|
||||
$updates = $this->addUpdateToList($updates, $update->toWpFormat());
|
||||
//Convert the update into the format used by WordPress core.
|
||||
$wpUpdate = $update->toWpFormat();
|
||||
//Disable the "autoupdate" flag unless explicitly allowed. This is a safety precaution;
|
||||
//untrusted or compromised update sources could otherwise set this flag to true even
|
||||
//if the plugin/theme developer didn't intend to allow automatic update installation.
|
||||
if ( isset($wpUpdate->autoupdate) && !$this->isAutoupdateFieldAllowed($update) ) {
|
||||
$wpUpdate->autoupdate = false;
|
||||
}
|
||||
$updates = $this->addUpdateToList($updates, $wpUpdate);
|
||||
} else {
|
||||
//Clean up any stale update info.
|
||||
$updates = $this->removeUpdateFromList($updates);
|
||||
@@ -655,6 +738,38 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoupdateFieldAllowed = false;
|
||||
|
||||
/**
|
||||
* Allow the "autoupdate" field in incoming plugin updates to be set to `true`.
|
||||
*
|
||||
* By default, the update checker will parse the field (so it will be available in the update
|
||||
* object), but will set it to `false` before passing the update to WordPress.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowAutoupdateField() {
|
||||
$this->autoupdateFieldAllowed = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the "autoupdate" field for injected updates allowed to be set to true?
|
||||
*
|
||||
* @param object $incomingUpdate
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAutoupdateFieldAllowed($incomingUpdate) {
|
||||
return apply_filters(
|
||||
$this->getUniqueName('autoupdate_field_allowed'),
|
||||
$this->autoupdateFieldAllowed,
|
||||
$incomingUpdate
|
||||
);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* JSON-based update API
|
||||
* -------------------------------------------------------------------
|
||||
@@ -698,7 +813,7 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
$result = wp_remote_get($url, $options);
|
||||
|
||||
$result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
|
||||
|
||||
|
||||
//Try to parse the response
|
||||
$status = $this->validateApiResponse($result);
|
||||
$metadata = null;
|
||||
@@ -924,25 +1039,62 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
||||
return $source;
|
||||
}
|
||||
|
||||
//Fix the remote source structure if necessary.
|
||||
//The update archive should contain a single directory that contains the rest of plugin/theme files.
|
||||
//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
|
||||
//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
|
||||
//after update.
|
||||
if ( $this->isBadDirectoryStructure($remoteSource) ) {
|
||||
//Create a new directory using the plugin slug.
|
||||
$newDirectory = trailingslashit($remoteSource) . $this->slug . '/';
|
||||
|
||||
if ( !$wp_filesystem->is_dir($newDirectory) ) {
|
||||
$wp_filesystem->mkdir($newDirectory);
|
||||
|
||||
//Move all files to the newly created directory.
|
||||
$sourceFiles = $wp_filesystem->dirlist($remoteSource);
|
||||
if ( is_array($sourceFiles) ) {
|
||||
$sourceFiles = array_keys($sourceFiles);
|
||||
$allMoved = true;
|
||||
foreach ($sourceFiles as $filename) {
|
||||
//Skip our newly created folder.
|
||||
if ( $filename === $this->slug ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$previousSource = trailingslashit($remoteSource) . $filename;
|
||||
$newSource = trailingslashit($newDirectory) . $filename;
|
||||
|
||||
if ( !$wp_filesystem->move($previousSource, $newSource, true) ) {
|
||||
$allMoved = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $allMoved ) {
|
||||
//Rename source.
|
||||
$source = $newDirectory;
|
||||
} else {
|
||||
//Delete our newly created folder including all files in it.
|
||||
$wp_filesystem->rmdir($newDirectory, true);
|
||||
|
||||
//And return a relevant error.
|
||||
return new WP_Error(
|
||||
'puc-incorrect-directory-structure',
|
||||
sprintf(
|
||||
'The directory structure of the update was incorrect. All files should be inside ' .
|
||||
'a directory named <span class="code">%s</span>, not at the root of the ZIP archive. Plugin Update Checker tried to fix the directory structure, but failed.',
|
||||
esc_html($this->slug)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Rename the source to match the existing directory.
|
||||
$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
|
||||
if ( $source !== $correctedSource ) {
|
||||
//The update archive should contain a single directory that contains the rest of plugin/theme files.
|
||||
//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
|
||||
//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
|
||||
//after update.
|
||||
if ( $this->isBadDirectoryStructure($remoteSource) ) {
|
||||
return new WP_Error(
|
||||
'puc-incorrect-directory-structure',
|
||||
sprintf(
|
||||
'The directory structure of the update is incorrect. All files should be inside ' .
|
||||
'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
|
||||
htmlentities($this->slug)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** @var \WP_Upgrader_Skin $upgrader ->skin */
|
||||
$upgrader->skin->feedback(sprintf(
|
||||
'Renaming %s to %s…',
|
||||
'<span class="code">' . basename($source) . '</span>',
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(UpgraderStatus::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
if ( !class_exists(Utils::class, false) ):
|
||||
|
||||
+151
-2
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
use Parsedown;
|
||||
use PucReadmeParser;
|
||||
@@ -51,6 +51,16 @@ if ( !class_exists(Api::class, false) ):
|
||||
*/
|
||||
protected $credentials = null;
|
||||
|
||||
/**
|
||||
* @var string|null The value of the "Authorization" header for API requests.
|
||||
*/
|
||||
private $authorizationHeader = null;
|
||||
|
||||
/**
|
||||
* @var string|null If set, add the "Authorization" header to update downloads that start with this prefix.
|
||||
*/
|
||||
private $downloadUrlPrefixRequiringAuth = null;
|
||||
|
||||
/**
|
||||
* @var string The filter tag that's used to filter options passed to wp_remote_get.
|
||||
* For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
|
||||
@@ -322,6 +332,22 @@ if ( !class_exists(Api::class, false) ):
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getApiRequestHttpOptions() {
|
||||
$options = ['timeout' => wp_doing_cron() ? 10 : 3];
|
||||
if ( $this->isAuthenticationEnabled() && !empty($this->authorizationHeader) ) {
|
||||
$options['headers'] = ['Authorization' => $this->authorizationHeader];
|
||||
}
|
||||
|
||||
if ( !empty($this->httpFilterName) ) {
|
||||
$options = apply_filters($this->httpFilterName, $options);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set authentication credentials.
|
||||
*
|
||||
@@ -332,7 +358,130 @@ if ( !class_exists(Api::class, false) ):
|
||||
}
|
||||
|
||||
public function isAuthenticationEnabled() {
|
||||
return !empty($this->credentials);
|
||||
return !empty($this->credentials) || !empty($this->authorizationHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the "Authorization" header for API requests, if any.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthorizationHeader() {
|
||||
return $this->authorizationHeader ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable basic access authentication with the specified username and password.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string|null $downloadUrlPrefix Optionally, add the same Authorization header to update
|
||||
* downloads where the download URL starts with this prefix.
|
||||
*/
|
||||
protected function enableBasicAuth($username, $password, $downloadUrlPrefix = null) {
|
||||
$this->authorizationHeader = 'Basic ' . base64_encode($username . ':' . $password);
|
||||
|
||||
$this->downloadUrlPrefixRequiringAuth = $downloadUrlPrefix;
|
||||
if ( !empty($this->downloadUrlPrefixRequiringAuth) ) {
|
||||
$this->enableDownloadRequestFilter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool Whether the hook that registers download request filter(s) has already been added.
|
||||
*/
|
||||
private $preDownloadHookAdded = false;
|
||||
|
||||
/**
|
||||
* Enable the hooks that let you filter HTTP requests for update downloads.
|
||||
*/
|
||||
protected function enableDownloadRequestFilter() {
|
||||
if ( $this->preDownloadHookAdded ) {
|
||||
return;
|
||||
}
|
||||
$this->preDownloadHookAdded = true;
|
||||
|
||||
//Optimization: Instead of filtering all HTTP requests, let's do it only when
|
||||
//WordPress is about to download an update. So this is a two-step process;
|
||||
//the actual request arg filter is added in the following hook.
|
||||
add_filter('upgrader_pre_download', [$this, 'addDownloadRequestFilters']); //WP 3.7+
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $downloadFiltersAdded = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param bool $result Pass-through value for the "upgrader_pre_download" filter. Ignored by this callback.
|
||||
* @return bool
|
||||
*/
|
||||
public function addDownloadRequestFilters($result) {
|
||||
if ( !$this->downloadFiltersAdded ) {
|
||||
$this->downloadFiltersAdded = true;
|
||||
|
||||
//phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- The callback doesn't change the timeout.
|
||||
add_filter('http_request_args', [$this, 'filterUpdateDownloadRequestArgs'], 10, 2);
|
||||
|
||||
$authorizationHeader = $this->getAuthorizationHeader();
|
||||
if ( $this->isAuthenticationEnabled() && !empty($authorizationHeader) ) {
|
||||
add_action('requests-requests.before_redirect', [$this, 'removeAuthHeaderFromRedirects'], 10, 2);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter request arguments/options for update downloads.
|
||||
*
|
||||
* Note that this callback can potentially be called for *any* update download. You still
|
||||
* need to verify that the URL is one of yours.
|
||||
*
|
||||
* @internal
|
||||
* @param array $requestArgs
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public function filterUpdateDownloadRequestArgs($requestArgs, $url = '') {
|
||||
//Add an authorization header to our downloads if needed.
|
||||
$authHeader = $this->getAuthorizationHeader();
|
||||
if (
|
||||
$this->isAuthenticationEnabled()
|
||||
&& !empty($authHeader)
|
||||
&& !empty($this->downloadUrlPrefixRequiringAuth)
|
||||
&& ((strpos($url, $this->downloadUrlPrefixRequiringAuth)) === 0)
|
||||
) {
|
||||
$requestArgs['headers']['Authorization'] = $authHeader;
|
||||
}
|
||||
return $requestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* At least in older WP versions, when following a redirect, the Requests library will
|
||||
* automatically forward the Authorization header to other hosts. We don't want that
|
||||
* because it breaks AWS downloads and can leak authorization information.
|
||||
*
|
||||
* @param string $location
|
||||
* @param array $headers
|
||||
* @internal
|
||||
*/
|
||||
public function removeAuthHeaderFromRedirects(&$location, &$headers) {
|
||||
if (
|
||||
//If there's no download URL prefix configured, we would not have added an auth header,
|
||||
//and there's also no way to check if this URL needs auth or not.
|
||||
empty($this->downloadUrlPrefixRequiringAuth)
|
||||
//If this request goes to our download URL, we can leave the header.
|
||||
|| ((strpos($location, $this->downloadUrlPrefixRequiringAuth)) === 0)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove the header.
|
||||
$authorizationHeader = $this->getAuthorizationHeader();
|
||||
if ( isset($headers['Authorization']) && ($headers['Authorization'] === $authorizationHeader) ) {
|
||||
unset($headers['Authorization']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !interface_exists(BaseChecker::class, false) ):
|
||||
|
||||
+23
-36
@@ -1,18 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\OAuthSignature;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Utils;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Utils;
|
||||
|
||||
if ( !class_exists(BitBucketApi::class, false) ):
|
||||
|
||||
class BitBucketApi extends Api {
|
||||
/**
|
||||
* @var OAuthSignature
|
||||
*/
|
||||
private $oauth = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -148,11 +142,19 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
||||
* @return string
|
||||
*/
|
||||
protected function getDownloadUrl($ref) {
|
||||
return $this->getDownloadBaseUrl() . $ref . '.zip';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base URL for ZIP downloads from our repo. Includes the trailing slash.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDownloadBaseUrl() {
|
||||
return sprintf(
|
||||
'https://bitbucket.org/%s/%s/get/%s.zip',
|
||||
'https://bitbucket.org/%s/%s/get/',
|
||||
$this->username,
|
||||
$this->repository,
|
||||
$ref
|
||||
$this->repository
|
||||
);
|
||||
}
|
||||
|
||||
@@ -206,15 +208,7 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
||||
));
|
||||
$baseUrl = $url;
|
||||
|
||||
if ( $this->oauth ) {
|
||||
$url = $this->oauth->sign($url,'GET');
|
||||
}
|
||||
|
||||
$options = array('timeout' => wp_doing_cron() ? 10 : 3);
|
||||
if ( !empty($this->httpFilterName) ) {
|
||||
$options = apply_filters($this->httpFilterName, $options);
|
||||
}
|
||||
$response = wp_remote_get($url, $options);
|
||||
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
@@ -248,25 +242,18 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
||||
public function setAuthentication($credentials) {
|
||||
parent::setAuthentication($credentials);
|
||||
|
||||
if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
|
||||
$this->oauth = new OAuthSignature(
|
||||
$credentials['consumer_key'],
|
||||
$credentials['consumer_secret']
|
||||
if (
|
||||
is_array($credentials)
|
||||
&& !empty($credentials['username'])
|
||||
&& !empty($credentials['api_token'])
|
||||
) {
|
||||
$this->enableBasicAuth(
|
||||
$credentials['username'],
|
||||
$credentials['api_token'],
|
||||
$this->getDownloadBaseUrl()
|
||||
);
|
||||
} else {
|
||||
$this->oauth = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function signDownloadUrl($url) {
|
||||
//Add authentication data to download URLs. Since OAuth signatures incorporate
|
||||
//timestamps, we have to do this immediately before inserting the update. Otherwise,
|
||||
//authentication could fail due to a stale timestamp.
|
||||
if ( $this->oauth ) {
|
||||
$url = $this->oauth->sign($url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
+15
-81
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
use Parsedown;
|
||||
|
||||
@@ -29,11 +29,6 @@ if ( !class_exists(GitHubApi::class, false) ):
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $downloadFilterAdded = false;
|
||||
|
||||
public function __construct($repositoryUrl, $accessToken = null) {
|
||||
$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
|
||||
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
||||
@@ -248,15 +243,7 @@ if ( !class_exists(GitHubApi::class, false) ):
|
||||
$baseUrl = $url;
|
||||
$url = $this->buildApiUrl($url, $queryParams);
|
||||
|
||||
$options = array('timeout' => wp_doing_cron() ? 10 : 3);
|
||||
if ( $this->isAuthenticationEnabled() ) {
|
||||
$options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
|
||||
}
|
||||
|
||||
if ( !empty($this->httpFilterName) ) {
|
||||
$options = apply_filters($this->httpFilterName, $options);
|
||||
}
|
||||
$response = wp_remote_get($url, $options);
|
||||
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
@@ -348,11 +335,17 @@ if ( !class_exists(GitHubApi::class, false) ):
|
||||
|
||||
public function setAuthentication($credentials) {
|
||||
parent::setAuthentication($credentials);
|
||||
//This property is no longer used internally, but is kept for backwards compatibility.
|
||||
$this->accessToken = is_string($credentials) ? $credentials : null;
|
||||
|
||||
//Optimization: Instead of filtering all HTTP requests, let's do it only when
|
||||
//WordPress is about to download an update.
|
||||
add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
|
||||
if ( is_string($credentials) && !empty($credentials) ) {
|
||||
$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', []);
|
||||
$this->enableBasicAuth($this->userName, $credentials, $repoApiBaseUrl);
|
||||
}
|
||||
|
||||
//Assets sometimes need an Accept header, so we add a request filter even if basic
|
||||
//authentication isn't enabled.
|
||||
$this->enableDownloadRequestFilter();
|
||||
}
|
||||
|
||||
protected function getUpdateDetectionStrategies($configBranch) {
|
||||
@@ -393,74 +386,15 @@ if ( !class_exists(GitHubApi::class, false) ):
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $result
|
||||
* @return bool
|
||||
* @internal
|
||||
*/
|
||||
public function addHttpRequestFilter($result) {
|
||||
if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
|
||||
//phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- The callback doesn't change the timeout.
|
||||
add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
|
||||
add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
|
||||
$this->downloadFilterAdded = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP headers that are necessary to download updates from private repositories.
|
||||
*
|
||||
* See GitHub docs:
|
||||
*
|
||||
* @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||
* @link https://developer.github.com/v3/auth/#basic-authentication
|
||||
*
|
||||
* @internal
|
||||
* @param array $requestArgs
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public function setUpdateDownloadHeaders($requestArgs, $url = '') {
|
||||
public function filterUpdateDownloadRequestArgs($requestArgs, $url = '') {
|
||||
//Release assets need an "Accept" header. See GitHub Docs:
|
||||
//https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||
//Is WordPress trying to download one of our release assets?
|
||||
if ( $this->releaseAssetsEnabled && (strpos($url, $this->getAssetApiBaseUrl()) !== false) ) {
|
||||
$requestArgs['headers']['Accept'] = 'application/octet-stream';
|
||||
}
|
||||
//Use Basic authentication, but only if the download is from our repository.
|
||||
$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
|
||||
if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
|
||||
$requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
|
||||
}
|
||||
return $requestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* When following a redirect, the Requests library will automatically forward
|
||||
* the authorization header to other hosts. We don't want that because it breaks
|
||||
* AWS downloads and can leak authorization information.
|
||||
*
|
||||
* @param string $location
|
||||
* @param array $headers
|
||||
* @internal
|
||||
*/
|
||||
public function removeAuthHeaderFromRedirects(&$location, &$headers) {
|
||||
$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
|
||||
if ( strpos($location, $repoApiBaseUrl) === 0 ) {
|
||||
return; //This request is going to GitHub, so it's fine.
|
||||
}
|
||||
//Remove the header.
|
||||
if ( isset($headers['Authorization']) ) {
|
||||
unset($headers['Authorization']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the value of the "Authorization" header.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthorizationHeader() {
|
||||
return 'Basic ' . base64_encode($this->userName . ':' . $this->accessToken);
|
||||
return parent::filterUpdateDownloadRequestArgs($requestArgs, $url);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-7
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !class_exists(GitLabApi::class, false) ):
|
||||
|
||||
@@ -260,12 +260,7 @@ if ( !class_exists(GitLabApi::class, false) ):
|
||||
$baseUrl = $url;
|
||||
$url = $this->buildApiUrl($url, $queryParams);
|
||||
|
||||
$options = array('timeout' => wp_doing_cron() ? 10 : 3);
|
||||
if ( !empty($this->httpFilterName) ) {
|
||||
$options = apply_filters($this->httpFilterName, $options);
|
||||
}
|
||||
|
||||
$response = wp_remote_get($url, $options);
|
||||
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||
if ( is_wp_error($response) ) {
|
||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||
return $response;
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||
|
||||
if ( !class_exists(PluginUpdateChecker::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !class_exists(Reference::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !trait_exists(ReleaseAssetSupport::class, false) ) :
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !trait_exists(ReleaseFilteringFeature::class, false) ) :
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Utils;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Utils;
|
||||
|
||||
if ( !class_exists(ThemeUpdateChecker::class, false) ):
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||
|
||||
if ( !trait_exists(VcsCheckerMethods::class, false) ) :
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use WP_CLI;
|
||||
|
||||
@@ -29,7 +29,7 @@ From the users' perspective, it works just like with plugins and themes hosted o
|
||||
Getting Started
|
||||
---------------
|
||||
|
||||
*Note:* In each of the below examples, part of the instructions are to create an instance of the update checker class. It's recommended to do this either during the `plugins_loaded` action or outside of any hooks. If you do it only during an `admin_*` action, then updates will not be visible to a wide variety of WordPress maanagement tools; they will only be visible to logged-in users on dashboard pages.
|
||||
*Note:* In each of the below examples, part of the instructions is to create an instance of the update checker class. It's recommended to do this either during the `plugins_loaded` action or outside of any hooks. If you do it only during an `admin_*` action, then updates will not be visible to a wide variety of WordPress management tools; they will only be visible to logged-in users on dashboard pages.
|
||||
|
||||
### Self-hosted Plugins and Themes
|
||||
|
||||
@@ -128,6 +128,11 @@ This library supports a couple of different ways to release updates on GitHub. P
|
||||
$myUpdateChecker->getVcsApi()->enableReleaseAssets();
|
||||
```
|
||||
|
||||
By default, PUC will simply use the first available asset. You can pass a regular expression to `enableReleaseAssets()` to filter assets by name. For example:
|
||||
```php
|
||||
$myUpdateChecker->getVcsApi()->enableReleaseAssets('/\.zip($|[?&#])/i');
|
||||
```
|
||||
|
||||
- **Tags**
|
||||
|
||||
To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`. That's it.
|
||||
@@ -188,14 +193,12 @@ The library will pull update details from the following parts of a release/tag/b
|
||||
'unique-plugin-or-theme-slug'
|
||||
);
|
||||
|
||||
//Optional: If you're using a private repository, create an OAuth consumer
|
||||
//and set the authentication credentials like this:
|
||||
//Note: For now you need to check "This is a private consumer" when
|
||||
//creating the consumer to work around #134:
|
||||
// https://github.com/YahnisElsts/plugin-update-checker/issues/134
|
||||
//Optional: If you're using a private repository, create an API token
|
||||
//with the "read:repository:bitbucket" scope and set the authentication
|
||||
//credentials like this:
|
||||
$myUpdateChecker->setAuthentication(array(
|
||||
'consumer_key' => '...',
|
||||
'consumer_secret' => '...',
|
||||
'username' => 'example@example.com', //Your BitBucket email address.
|
||||
'api_token' => '...',
|
||||
));
|
||||
|
||||
//Optional: Set the branch that contains the stable release.
|
||||
@@ -252,8 +255,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli
|
||||
|
||||
Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
|
||||
```php
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi;
|
||||
|
||||
$myUpdateChecker = new PluginUpdateChecker(
|
||||
new GitLabApi('https://myserver.com/user-name/repo-name/'),
|
||||
@@ -264,8 +267,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli
|
||||
```
|
||||
If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups:
|
||||
```php
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi;
|
||||
|
||||
$myUpdateChecker = new PluginUpdateChecker(
|
||||
new GitLabApi(
|
||||
@@ -347,14 +350,14 @@ Other classes have also been renamed, usually by simply removing the `Puc_vXpY_`
|
||||
| Old class name | New class name |
|
||||
|-------------------------------------|----------------------------------------------------------------|
|
||||
| `Puc_v4_Factory` | `YahnisElsts\PluginUpdateChecker\v5\PucFactory` |
|
||||
| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p4\PucFactory` |
|
||||
| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Plugin\UpdateChecker` |
|
||||
| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Theme\UpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\ThemeUpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitHubApi` |
|
||||
| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi` |
|
||||
| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\BitBucketApi` |
|
||||
| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p7\PucFactory` |
|
||||
| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Plugin\UpdateChecker` |
|
||||
| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Theme\UpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\ThemeUpdateChecker` |
|
||||
| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitHubApi` |
|
||||
| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi` |
|
||||
| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\BitBucketApi` |
|
||||
|
||||
License Management
|
||||
------------------
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
"ext-json": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"files": ["load-v5p4.php"]
|
||||
"files": ["load-v5p7.php"]
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2022-07-29 15:34+0300\n"
|
||||
"PO-Revision-Date: 2024-05-09 22:22+0000\n"
|
||||
"Last-Translator: theogk\n"
|
||||
"Language-Team: Ελληνικά\n"
|
||||
"Language: el\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Loco https://localise.biz/\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"X-Loco-Version: 2.6.9; wp-6.5.3"
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:128
|
||||
msgid "Check for updates"
|
||||
msgstr "Έλεγχος για ενημερώσεις"
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:214
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr "Το πρόσθετο %s είναι ενημερωμένο."
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:216
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr "Μία νέα έκδοση είναι διαθέσιμη για το πρόσθετο %s."
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:218
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr ""
|
||||
"Δεν ήταν εφικτό να εκτελεστεί ο έλεγχος για νέες ενημερώσεις για το πρόσθετο "
|
||||
"%s."
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:224
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr "Άγνωστο πρόβλημα του ενημερωτή προσθέτων \"%s\""
|
||||
|
||||
#: Puc/v5p4/Vcs/PluginUpdateChecker.php:100
|
||||
msgid "There is no changelog available."
|
||||
msgstr "Δεν υπάρχει διαθέσιμο αρχείο αλλαγών."
|
||||
Binary file not shown.
@@ -1,38 +1,50 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2016-02-17 14:21+0100\n"
|
||||
"PO-Revision-Date: 2016-10-28 14:30+0330\n"
|
||||
"Last-Translator: studio RVOLA <hello@rvola.com>\n"
|
||||
"Language-Team: Pro Style <info@prostyle.ir>\n"
|
||||
"POT-Creation-Date: 2025-06-12 23:40+0100\n"
|
||||
"PO-Revision-Date: 2025-06-12 23:49+0100\n"
|
||||
"Last-Translator: Pro Style <info@prostyle.ir>\n"
|
||||
"Language-Team: Alex Javadi <alex@aljm.org>\n"
|
||||
"Language: fa_IR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.8\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: github-checker.php:120
|
||||
msgid "There is no changelog available."
|
||||
msgstr "شرحی برای تغییرات یافت نشد"
|
||||
#: Puc/v5p6/Plugin/Ui.php:56
|
||||
msgid "View details"
|
||||
msgstr "مشاهده جزئیات"
|
||||
|
||||
#: plugin-update-checker.php:637
|
||||
#: Puc/v5p6/Plugin/Ui.php:79
|
||||
#, php-format
|
||||
msgid "More information about %s"
|
||||
msgstr "اطلاعات بیشتر درباره %s"
|
||||
|
||||
# It had some “potential” grammar issues and also didn’t sound native.
|
||||
# P.S. I know the current translation is literally “Checking for new updates”, however, I thought it might sound more natural and known to others.
|
||||
#: Puc/v5p6/Plugin/Ui.php:130
|
||||
msgid "Check for updates"
|
||||
msgstr "بررسی برای بروزرسانی "
|
||||
msgstr "بررسی بروزرسانی جدید"
|
||||
|
||||
#: plugin-update-checker.php:681
|
||||
msgid "This plugin is up to date."
|
||||
msgstr "شما از آخرین نسخه استفاده میکنید . بهروز باشید"
|
||||
|
||||
#: plugin-update-checker.php:683
|
||||
msgid "A new version of this plugin is available."
|
||||
msgstr "نسخه جدیدی برای افزونه ارائه شده است ."
|
||||
|
||||
#: plugin-update-checker.php:685
|
||||
# The word “ناشناخته” is seems to be translated directly from the word (Un-known), rather than checking for the context.
|
||||
# I think “نامشخص” (unknown) might be a suitable version in this scenario.
|
||||
#: Puc/v5p6/Plugin/Ui.php:227
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr "وضعیت ناشناخته برای بروزرسانی \"%s\""
|
||||
msgstr "وضعیت نامشخص برای بروزرسانی \"%s\""
|
||||
|
||||
# The previous translation was okay, however, it didn’t sound native to me.
|
||||
#: Puc/v5p6/Vcs/PluginUpdateChecker.php:113
|
||||
msgid "There is no changelog available."
|
||||
msgstr "آخرین تغییراتی یافت نشد."
|
||||
|
||||
#~ msgid "This plugin is up to date."
|
||||
#~ msgstr "شما از آخرین نسخه استفاده میکنید . بهروز باشید"
|
||||
|
||||
#~ msgid "A new version of this plugin is available."
|
||||
#~ msgstr "نسخه جدیدی برای افزونه ارائه شده است ."
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2024-12-09 11:45+0100\n"
|
||||
"PO-Revision-Date: 2024-12-09 12:20+0100\n"
|
||||
"Last-Translator: Aleksandar Urošević <urke.kg@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: sr_RS\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.4.3\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:56
|
||||
msgid "View details"
|
||||
msgstr "Види детаље"
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:79
|
||||
#, php-format
|
||||
msgid "More information about %s"
|
||||
msgstr "Више информација о %s"
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:130
|
||||
msgid "Check for updates"
|
||||
msgstr "Провера ажурирања"
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:217
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr "Додатак %s је у најновијем издању."
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:219
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr "Доступно је ново издање за %s."
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:221
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr "Није могуће утврдити да ли су доступне исправке за %s."
|
||||
|
||||
#: Puc/v5p5/Plugin/Ui.php:227
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr "Непознат статус провере ажурирања \"%s\""
|
||||
|
||||
#: Puc/v5p5/Vcs/PluginUpdateChecker.php:113
|
||||
msgid "There is no changelog available."
|
||||
msgstr "Белешке о изменама нису доступне."
|
||||
Binary file not shown.
@@ -1,57 +1,57 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2022-01-29 12:09+0800\n"
|
||||
"PO-Revision-Date: 2022-01-29 12:10+0800\n"
|
||||
"POT-Creation-Date: 2025-11-21 10:40+0800\n"
|
||||
"PO-Revision-Date: 2025-11-21 10:40+0800\n"
|
||||
"Last-Translator: Seaton Jiang <hi@seatonjiang.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4.3\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 3.8\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:54
|
||||
#: Puc/v5p6/Plugin/Ui.php:56
|
||||
msgid "View details"
|
||||
msgstr "查看详情"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:77
|
||||
#: Puc/v5p6/Plugin/Ui.php:79
|
||||
#, php-format
|
||||
msgid "More information about %s"
|
||||
msgstr "%s 的更多信息"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:128
|
||||
#: Puc/v5p6/Plugin/Ui.php:130
|
||||
msgid "Check for updates"
|
||||
msgstr "检查更新"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:214
|
||||
#: Puc/v5p6/Plugin/Ui.php:217
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr "%s 目前是最新版本。"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:216
|
||||
#: Puc/v5p6/Plugin/Ui.php:219
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr "%s 当前有可用的更新。"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:218
|
||||
#: Puc/v5p6/Plugin/Ui.php:221
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr "%s 无法确定是否有可用的更新。"
|
||||
|
||||
#: Puc/v4p11/Plugin/Ui.php:224
|
||||
#: Puc/v5p6/Plugin/Ui.php:227
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr "未知的更新检查状态:%s"
|
||||
|
||||
#: Puc/v4p11/Vcs/PluginUpdateChecker.php:100
|
||||
#: Puc/v5p6/Vcs/PluginUpdateChecker.php:113
|
||||
msgid "There is no changelog available."
|
||||
msgstr "没有可用的更新日志。"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
# Blank Plugin POT Template
|
||||
# Copyright 2025 ...
|
||||
# This file is distributed under the GNU General Public License v3 or later.
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Plugin Update Checker\n"
|
||||
"Report-Msgid-Bugs-To: Alex Lion <learnwithalex@gmail.com>\n"
|
||||
"POT-Creation-Date: 2025-09-19 14:05-0700\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Alex Lion <learnwithalex@gmail.com>\n"
|
||||
"Language-Team: Alex Lion <learnwithalex@gmail.com>\n"
|
||||
"Language: zh_TW\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Poedit-WPHeader: plugin-update-checker.php\n"
|
||||
"X-Textdomain-Support: yesX-Generator: Poedit 1.6.4\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;esc_html_e;esc_html_x:1,2c;esc_html__;esc_attr_e;esc_attr_x:1,2c;esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_x:1,2c;_n:1,2;_n_noop:1,2;__ngettext:1,2;__ngettext_noop:1,2;_c,_nc:4c,1,2\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-Bookmarks: \n"
|
||||
"X-Generator: Poedit 3.7\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:56
|
||||
msgid "View details"
|
||||
msgstr "檢視詳細資料"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:79
|
||||
#, php-format
|
||||
msgid "More information about %s"
|
||||
msgstr "進一步了解 %s 的相關資訊"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:130
|
||||
msgid "Check for updates"
|
||||
msgstr "檢查更新"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:217
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr "%s 外掛已為最新版本。"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:219
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr "%s 外掛已有新版本可供更新。"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:221
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr "無法確定 %s 是否有可用的更新。"
|
||||
|
||||
#: Puc/v5p6/Plugin/Ui.php:227
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr "未知的更新檢查程式狀態: %s"
|
||||
|
||||
#: Puc/v5p6/Vcs/PluginUpdateChecker.php:113
|
||||
msgid "There is no changelog available."
|
||||
msgstr "目前沒有可供檢閱的變更記錄。"
|
||||
@@ -2,7 +2,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plugin-update-checker\n"
|
||||
"POT-Creation-Date: 2022-07-29 15:34+0300\n"
|
||||
"POT-Creation-Date: 2025-05-20 15:27+0300\n"
|
||||
"PO-Revision-Date: 2016-01-10 20:59+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -11,39 +11,39 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.1.1\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:128
|
||||
#: Puc/v5p7/Plugin/Ui.php:130
|
||||
msgid "Check for updates"
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:214
|
||||
#: Puc/v5p7/Plugin/Ui.php:217
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "The %s plugin is up to date."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:216
|
||||
#: Puc/v5p7/Plugin/Ui.php:219
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "A new version of the %s plugin is available."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:218
|
||||
#: Puc/v5p7/Plugin/Ui.php:221
|
||||
#, php-format
|
||||
msgctxt "the plugin title"
|
||||
msgid "Could not determine if updates are available for %s."
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v5p4/Plugin/Ui.php:224
|
||||
#: Puc/v5p7/Plugin/Ui.php:227
|
||||
#, php-format
|
||||
msgid "Unknown update checker status \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: Puc/v5p4/Vcs/PluginUpdateChecker.php:100
|
||||
#: Puc/v5p7/Vcs/PluginUpdateChecker.php:113
|
||||
msgid "There is no changelog available."
|
||||
msgstr ""
|
||||
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
||||
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||
|
||||
use YahnisElsts\PluginUpdateChecker\v5\PucFactory as MajorFactory;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory as MinorFactory;
|
||||
use YahnisElsts\PluginUpdateChecker\v5p7\PucFactory as MinorFactory;
|
||||
|
||||
require __DIR__ . '/Puc/v5p4/Autoloader.php';
|
||||
require __DIR__ . '/Puc/v5p7/Autoloader.php';
|
||||
new Autoloader();
|
||||
|
||||
require __DIR__ . '/Puc/v5p4/PucFactory.php';
|
||||
require __DIR__ . '/Puc/v5p7/PucFactory.php';
|
||||
require __DIR__ . '/Puc/v5/PucFactory.php';
|
||||
|
||||
//Register classes defined in this version with the factory.
|
||||
@@ -26,9 +26,9 @@ foreach (
|
||||
)
|
||||
as $pucGeneralClass => $pucVersionedClass
|
||||
) {
|
||||
MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.4');
|
||||
MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.7');
|
||||
//Also add it to the minor-version factory in case the major-version factory
|
||||
//was already defined by another, older version of the update checker.
|
||||
MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.4');
|
||||
MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.7');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Update Checker Library 5.4
|
||||
* Plugin Update Checker Library 5.7
|
||||
* http://w-shadow.com/
|
||||
*
|
||||
* Copyright 2024 Janis Elsts
|
||||
* Copyright 2026 Janis Elsts
|
||||
* Released under the MIT license. See license.txt for details.
|
||||
*/
|
||||
|
||||
require dirname(__FILE__) . '/load-v5p4.php';
|
||||
require dirname(__FILE__) . '/load-v5p7.php';
|
||||
@@ -648,7 +648,7 @@ class Parsedown
|
||||
#
|
||||
# Setext
|
||||
|
||||
protected function blockSetextHeader($Line, array $Block = null)
|
||||
protected function blockSetextHeader($Line, $Block = null)
|
||||
{
|
||||
if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
|
||||
{
|
||||
@@ -786,7 +786,7 @@ class Parsedown
|
||||
#
|
||||
# Table
|
||||
|
||||
protected function blockTable($Line, array $Block = null)
|
||||
protected function blockTable($Line, $Block = null)
|
||||
{
|
||||
if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
|
||||
{
|
||||
|
||||
@@ -34,9 +34,9 @@ $myUpdateChecker = PucFactory::buildUpdateChecker(
|
||||
__FILE__,
|
||||
'projects-portfolio'
|
||||
);
|
||||
|
||||
// Set the branch that contains the stable release.
|
||||
$myUpdateChecker->setBranch( 'main' );
|
||||
// Note: PUC's setBranch() is only available when the host is recognized as a
|
||||
// VCS provider (GitHub, GitLab, Bitbucket). The Gitea URL here falls back to
|
||||
// PUC's plain JSON metadata mode, so we skip the call rather than throw.
|
||||
|
||||
// Current plugin version.
|
||||
define( 'PROJECTS_PORTFOLIO_VERSION', '1.1.1' );
|
||||
|
||||
Reference in New Issue
Block a user