Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
365a3898b9 | ||
|
|
2bbd2dc7c8 |
@@ -5,3 +5,5 @@ notes/
|
|||||||
vendor/
|
vendor/
|
||||||
phpunit.xml
|
phpunit.xml
|
||||||
.phpunit.result.cache
|
.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) ):
|
if ( !class_exists(PucFactory::class, false) ):
|
||||||
|
|
||||||
class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p4\PucFactory {
|
class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p7\PucFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
endif;
|
endif;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(Autoloader::class, false) ):
|
if ( !class_exists(Autoloader::class, false) ):
|
||||||
|
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory;
|
use YahnisElsts\PluginUpdateChecker\v5p7\PucFactory;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker;
|
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker;
|
||||||
|
|
||||||
if ( !class_exists(Extension::class, false) ):
|
if ( !class_exists(Extension::class, false) ):
|
||||||
|
|
||||||
+19
-11
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?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) ):
|
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 '<h3>Configuration</h3>';
|
||||||
echo '<table class="puc-debug-data">';
|
echo '<table class="puc-debug-data">';
|
||||||
$this->displayConfigHeader();
|
$this->displayConfigHeader();
|
||||||
$this->row('Slug', htmlentities($this->updateChecker->slug));
|
$this->row('Slug', esc_html($this->updateChecker->slug));
|
||||||
$this->row('DB option', htmlentities($this->updateChecker->optionName));
|
$this->row('DB option', esc_html($this->updateChecker->optionName));
|
||||||
|
|
||||||
$requestInfoButton = $this->getMetadataButton();
|
$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;
|
$scheduler = $this->updateChecker->scheduler;
|
||||||
if ( $scheduler->checkPeriod > 0 ) {
|
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 '<h3>Status</h3>';
|
||||||
echo '<table class="puc-debug-data">';
|
echo '<table class="puc-debug-data">';
|
||||||
$state = $this->updateChecker->getUpdateState();
|
$state = $this->updateChecker->getUpdateState();
|
||||||
$checkNowButton = '';
|
$checkButtonId = $this->updateChecker->getUniqueName('check-now-button');
|
||||||
if ( function_exists('get_submit_button') ) {
|
if ( function_exists('get_submit_button') ) {
|
||||||
$checkNowButton = get_submit_button(
|
$checkNowButton = get_submit_button(
|
||||||
'Check Now',
|
'Check Now',
|
||||||
'secondary',
|
'secondary',
|
||||||
'puc-check-now-button',
|
'puc-check-now-button',
|
||||||
false,
|
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));
|
$this->row('Next automatic check', $this->formatTimeWithDelta($nextCheck));
|
||||||
|
|
||||||
if ( $state->getCheckedVersion() !== '' ) {
|
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('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>';
|
echo '</table>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +132,7 @@ if ( !class_exists(Panel::class, false) && class_exists('Debug_Bar_Panel', false
|
|||||||
if ( property_exists($update, $field) ) {
|
if ( property_exists($update, $field) ) {
|
||||||
$this->row(
|
$this->row(
|
||||||
ucwords(str_replace('_', ' ', $field)),
|
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) ) {
|
if ( is_object($value) || is_array($value) ) {
|
||||||
//This is specifically for debugging, so print_r() is fine.
|
//This is specifically for debugging, so print_r() is fine.
|
||||||
//phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
//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) {
|
} else if ($value === null) {
|
||||||
$value = '<code>null</code>';
|
$value = '<code>null</code>';
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(PluginExtension::class, false) ):
|
||||||
|
|
||||||
+11
-5
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(PluginPanel::class, false) ):
|
||||||
|
|
||||||
@@ -12,19 +12,25 @@ if ( !class_exists(PluginPanel::class, false) ):
|
|||||||
protected $updateChecker;
|
protected $updateChecker;
|
||||||
|
|
||||||
protected function displayConfigHeader() {
|
protected function displayConfigHeader() {
|
||||||
$this->row('Plugin file', htmlentities($this->updateChecker->pluginFile));
|
$this->row('Plugin file', esc_html($this->updateChecker->pluginFile));
|
||||||
parent::displayConfigHeader();
|
parent::displayConfigHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getMetadataButton() {
|
protected function getMetadataButton() {
|
||||||
$requestInfoButton = '';
|
$buttonId = $this->updateChecker->getUniqueName('request-info-button');
|
||||||
if ( function_exists('get_submit_button') ) {
|
if ( function_exists('get_submit_button') ) {
|
||||||
$requestInfoButton = get_submit_button(
|
$requestInfoButton = get_submit_button(
|
||||||
'Request Info',
|
'Request Info',
|
||||||
'secondary',
|
'secondary',
|
||||||
'puc-request-info-button',
|
'puc-request-info-button',
|
||||||
false,
|
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;
|
return $requestInfoButton;
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(ThemePanel::class, false) ):
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ if ( !class_exists(ThemePanel::class, false) ):
|
|||||||
protected $updateChecker;
|
protected $updateChecker;
|
||||||
|
|
||||||
protected function displayConfigHeader() {
|
protected function displayConfigHeader() {
|
||||||
$this->row('Theme directory', htmlentities($this->updateChecker->directoryName));
|
$this->row('Theme directory', esc_html($this->updateChecker->directoryName));
|
||||||
parent::displayConfigHeader();
|
parent::displayConfigHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(InstalledPackage::class, false) ):
|
if ( !class_exists(InstalledPackage::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(OAuthSignature::class, false) ):
|
if ( !class_exists(OAuthSignature::class, false) ):
|
||||||
|
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\PucFactory;
|
use YahnisElsts\PluginUpdateChecker\v5p7\PucFactory;
|
||||||
|
|
||||||
if ( !class_exists(Package::class, false) ):
|
if ( !class_exists(Package::class, false) ):
|
||||||
|
|
||||||
+3
-2
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(PluginInfo::class, false) ):
|
||||||
|
|
||||||
@@ -39,6 +39,7 @@ if ( !class_exists(PluginInfo::class, false) ):
|
|||||||
public $downloaded;
|
public $downloaded;
|
||||||
public $active_installs;
|
public $active_installs;
|
||||||
public $last_updated;
|
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.
|
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
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||||
|
|
||||||
if ( !class_exists(Ui::class, false) ):
|
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(
|
array(
|
||||||
'puc_update_check_result' => $status,
|
'puc_update_check_result' => $status,
|
||||||
'puc_slug' => $this->updateChecker->slug,
|
'puc_slug' => $this->updateChecker->slug,
|
||||||
+6
-4
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(Update::class, false) ):
|
||||||
|
|
||||||
@@ -20,9 +20,10 @@ if ( !class_exists(Update::class, false) ):
|
|||||||
public $requires_php = false;
|
public $requires_php = false;
|
||||||
public $icons = array();
|
public $icons = array();
|
||||||
public $filename; //Plugin filename relative to the plugins directory.
|
public $filename; //Plugin filename relative to the plugins directory.
|
||||||
|
public $autoupdate = false;
|
||||||
|
|
||||||
protected static $extraFields = array(
|
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->tested = $this->tested;
|
||||||
$update->requires_php = $this->requires_php;
|
$update->requires_php = $this->requires_php;
|
||||||
$update->plugin = $this->filename;
|
$update->plugin = $this->filename;
|
||||||
|
$update->autoupdate = $this->autoupdate;
|
||||||
|
|
||||||
if ( !empty($this->upgrade_notice) ) {
|
if ( !empty($this->upgrade_notice) ) {
|
||||||
$update->upgrade_notice = $this->upgrade_notice;
|
$update->upgrade_notice = $this->upgrade_notice;
|
||||||
@@ -102,7 +104,7 @@ if ( !class_exists(Update::class, false) ):
|
|||||||
$update->icons = $icons;
|
$update->icons = $icons;
|
||||||
|
|
||||||
//It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
|
//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']) ) {
|
if ( !isset($update->icons['default']) ) {
|
||||||
$update->icons['default'] = current($update->icons);
|
$update->icons['default'] = current($update->icons);
|
||||||
}
|
}
|
||||||
+5
-5
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker as BaseUpdateChecker;
|
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker as BaseUpdateChecker;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Scheduler;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Scheduler;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
use YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||||
|
|
||||||
if ( !class_exists(UpdateChecker::class, false) ):
|
if ( !class_exists(UpdateChecker::class, false) ):
|
||||||
|
|
||||||
+7
-7
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Plugin;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Plugin;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !class_exists(PucFactory::class, false) ):
|
if ( !class_exists(PucFactory::class, false) ):
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ if ( !class_exists(PucFactory::class, false) ):
|
|||||||
throw new \RuntimeException(sprintf(
|
throw new \RuntimeException(sprintf(
|
||||||
'The update checker cannot determine if "%s" is a plugin or a theme. ' .
|
'The update checker cannot determine if "%s" is a plugin or a theme. ' .
|
||||||
'This is a bug. Please contact the PUC developer.',
|
'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.
|
* Normalize a filesystem path. Introduced in WP 3.9.
|
||||||
* Copying here allows use of the class on earlier versions.
|
* 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.
|
* @param string $path Path to normalize.
|
||||||
* @return string Normalized path.
|
* @return string Normalized path.
|
||||||
@@ -239,7 +239,7 @@ if ( !class_exists(PucFactory::class, false) ):
|
|||||||
|
|
||||||
//URI was not found so throw an error.
|
//URI was not found so throw an error.
|
||||||
throw new \RuntimeException(
|
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
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(Scheduler::class, false) ):
|
if ( !class_exists(Scheduler::class, false) ):
|
||||||
|
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(StateStore::class, false) ):
|
if ( !class_exists(StateStore::class, false) ):
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ if ( !class_exists(StateStore::class, false) ):
|
|||||||
* @param Update|null $update
|
* @param Update|null $update
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setUpdate(Update $update = null) {
|
public function setUpdate($update = null) {
|
||||||
$this->lazyLoad();
|
$this->lazyLoad();
|
||||||
$this->update = $update;
|
$this->update = $update;
|
||||||
return $this;
|
return $this;
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(Package::class, false) ):
|
||||||
|
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(Update::class, false) ):
|
||||||
|
|
||||||
+5
-5
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\UpdateChecker as BaseUpdateChecker;
|
use YahnisElsts\PluginUpdateChecker\v5p7\UpdateChecker as BaseUpdateChecker;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\InstalledPackage;
|
use YahnisElsts\PluginUpdateChecker\v5p7\InstalledPackage;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Scheduler;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Scheduler;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\DebugBar;
|
use YahnisElsts\PluginUpdateChecker\v5p7\DebugBar;
|
||||||
|
|
||||||
if ( !class_exists(UpdateChecker::class, false) ):
|
if ( !class_exists(UpdateChecker::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
+172
-20
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use WP_Error;
|
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.
|
//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);
|
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.
|
//DebugBar integration.
|
||||||
if ( did_action('plugins_loaded') ) {
|
if ( did_action('plugins_loaded') ) {
|
||||||
$this->maybeInitDebugBar();
|
$this->maybeInitDebugBar();
|
||||||
@@ -192,6 +196,7 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
|
|
||||||
remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
|
remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
|
||||||
remove_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 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('plugins_loaded', array($this, 'maybeInitDebugBar'));
|
||||||
|
|
||||||
remove_action('init', array($this, 'loadTextDomain'));
|
remove_action('init', array($this, 'loadTextDomain'));
|
||||||
@@ -266,6 +271,76 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
*/
|
*/
|
||||||
abstract protected function createScheduler($checkPeriod);
|
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.
|
* 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
|
* @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) ) {
|
if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -557,7 +632,15 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
if ( !empty($update) ) {
|
if ( !empty($update) ) {
|
||||||
//Let plugins filter the update info before it's passed on to WordPress.
|
//Let plugins filter the update info before it's passed on to WordPress.
|
||||||
$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
|
$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 {
|
} else {
|
||||||
//Clean up any stale update info.
|
//Clean up any stale update info.
|
||||||
$updates = $this->removeUpdateFromList($updates);
|
$updates = $this->removeUpdateFromList($updates);
|
||||||
@@ -655,6 +738,38 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
return true;
|
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
|
* JSON-based update API
|
||||||
* -------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
@@ -698,7 +813,7 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
$result = wp_remote_get($url, $options);
|
$result = wp_remote_get($url, $options);
|
||||||
|
|
||||||
$result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
|
$result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
|
||||||
|
|
||||||
//Try to parse the response
|
//Try to parse the response
|
||||||
$status = $this->validateApiResponse($result);
|
$status = $this->validateApiResponse($result);
|
||||||
$metadata = null;
|
$metadata = null;
|
||||||
@@ -924,25 +1039,62 @@ if ( !class_exists(UpdateChecker::class, false) ):
|
|||||||
return $source;
|
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.
|
//Rename the source to match the existing directory.
|
||||||
$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
|
$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
|
||||||
if ( $source !== $correctedSource ) {
|
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(
|
$upgrader->skin->feedback(sprintf(
|
||||||
'Renaming %s to %s…',
|
'Renaming %s to %s…',
|
||||||
'<span class="code">' . basename($source) . '</span>',
|
'<span class="code">' . basename($source) . '</span>',
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(UpgraderStatus::class, false) ):
|
if ( !class_exists(UpgraderStatus::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
if ( !class_exists(Utils::class, false) ):
|
if ( !class_exists(Utils::class, false) ):
|
||||||
|
|
||||||
+151
-2
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
use Parsedown;
|
use Parsedown;
|
||||||
use PucReadmeParser;
|
use PucReadmeParser;
|
||||||
@@ -51,6 +51,16 @@ if ( !class_exists(Api::class, false) ):
|
|||||||
*/
|
*/
|
||||||
protected $credentials = null;
|
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.
|
* @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".
|
* 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 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.
|
* Set authentication credentials.
|
||||||
*
|
*
|
||||||
@@ -332,7 +358,130 @@ if ( !class_exists(Api::class, false) ):
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function isAuthenticationEnabled() {
|
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
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !interface_exists(BaseChecker::class, false) ):
|
if ( !interface_exists(BaseChecker::class, false) ):
|
||||||
|
|
||||||
+23
-36
@@ -1,18 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\OAuthSignature;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Utils;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Utils;
|
|
||||||
|
|
||||||
if ( !class_exists(BitBucketApi::class, false) ):
|
if ( !class_exists(BitBucketApi::class, false) ):
|
||||||
|
|
||||||
class BitBucketApi extends Api {
|
class BitBucketApi extends Api {
|
||||||
/**
|
|
||||||
* @var OAuthSignature
|
|
||||||
*/
|
|
||||||
private $oauth = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@@ -148,11 +142,19 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getDownloadUrl($ref) {
|
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(
|
return sprintf(
|
||||||
'https://bitbucket.org/%s/%s/get/%s.zip',
|
'https://bitbucket.org/%s/%s/get/',
|
||||||
$this->username,
|
$this->username,
|
||||||
$this->repository,
|
$this->repository
|
||||||
$ref
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,15 +208,7 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
|||||||
));
|
));
|
||||||
$baseUrl = $url;
|
$baseUrl = $url;
|
||||||
|
|
||||||
if ( $this->oauth ) {
|
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||||
$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);
|
|
||||||
if ( is_wp_error($response) ) {
|
if ( is_wp_error($response) ) {
|
||||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||||
return $response;
|
return $response;
|
||||||
@@ -248,25 +242,18 @@ if ( !class_exists(BitBucketApi::class, false) ):
|
|||||||
public function setAuthentication($credentials) {
|
public function setAuthentication($credentials) {
|
||||||
parent::setAuthentication($credentials);
|
parent::setAuthentication($credentials);
|
||||||
|
|
||||||
if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
|
if (
|
||||||
$this->oauth = new OAuthSignature(
|
is_array($credentials)
|
||||||
$credentials['consumer_key'],
|
&& !empty($credentials['username'])
|
||||||
$credentials['consumer_secret']
|
&& !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;
|
endif;
|
||||||
+15
-81
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
use Parsedown;
|
use Parsedown;
|
||||||
|
|
||||||
@@ -29,11 +29,6 @@ if ( !class_exists(GitHubApi::class, false) ):
|
|||||||
*/
|
*/
|
||||||
protected $accessToken;
|
protected $accessToken;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $downloadFilterAdded = false;
|
|
||||||
|
|
||||||
public function __construct($repositoryUrl, $accessToken = null) {
|
public function __construct($repositoryUrl, $accessToken = null) {
|
||||||
$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
|
$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
|
||||||
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
||||||
@@ -248,15 +243,7 @@ if ( !class_exists(GitHubApi::class, false) ):
|
|||||||
$baseUrl = $url;
|
$baseUrl = $url;
|
||||||
$url = $this->buildApiUrl($url, $queryParams);
|
$url = $this->buildApiUrl($url, $queryParams);
|
||||||
|
|
||||||
$options = array('timeout' => wp_doing_cron() ? 10 : 3);
|
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||||
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);
|
|
||||||
if ( is_wp_error($response) ) {
|
if ( is_wp_error($response) ) {
|
||||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||||
return $response;
|
return $response;
|
||||||
@@ -348,11 +335,17 @@ if ( !class_exists(GitHubApi::class, false) ):
|
|||||||
|
|
||||||
public function setAuthentication($credentials) {
|
public function setAuthentication($credentials) {
|
||||||
parent::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;
|
$this->accessToken = is_string($credentials) ? $credentials : null;
|
||||||
|
|
||||||
//Optimization: Instead of filtering all HTTP requests, let's do it only when
|
if ( is_string($credentials) && !empty($credentials) ) {
|
||||||
//WordPress is about to download an update.
|
$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', []);
|
||||||
add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
|
$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) {
|
protected function getUpdateDetectionStrategies($configBranch) {
|
||||||
@@ -393,74 +386,15 @@ if ( !class_exists(GitHubApi::class, false) ):
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function filterUpdateDownloadRequestArgs($requestArgs, $url = '') {
|
||||||
* @param bool $result
|
//Release assets need an "Accept" header. See GitHub Docs:
|
||||||
* @return bool
|
//https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||||
* @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 = '') {
|
|
||||||
//Is WordPress trying to download one of our release assets?
|
//Is WordPress trying to download one of our release assets?
|
||||||
if ( $this->releaseAssetsEnabled && (strpos($url, $this->getAssetApiBaseUrl()) !== false) ) {
|
if ( $this->releaseAssetsEnabled && (strpos($url, $this->getAssetApiBaseUrl()) !== false) ) {
|
||||||
$requestArgs['headers']['Accept'] = 'application/octet-stream';
|
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return parent::filterUpdateDownloadRequestArgs($requestArgs, $url);
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+2
-7
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !class_exists(GitLabApi::class, false) ):
|
if ( !class_exists(GitLabApi::class, false) ):
|
||||||
|
|
||||||
@@ -260,12 +260,7 @@ if ( !class_exists(GitLabApi::class, false) ):
|
|||||||
$baseUrl = $url;
|
$baseUrl = $url;
|
||||||
$url = $this->buildApiUrl($url, $queryParams);
|
$url = $this->buildApiUrl($url, $queryParams);
|
||||||
|
|
||||||
$options = array('timeout' => wp_doing_cron() ? 10 : 3);
|
$response = wp_remote_get($url, $this->getApiRequestHttpOptions());
|
||||||
if ( !empty($this->httpFilterName) ) {
|
|
||||||
$options = apply_filters($this->httpFilterName, $options);
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = wp_remote_get($url, $options);
|
|
||||||
if ( is_wp_error($response) ) {
|
if ( is_wp_error($response) ) {
|
||||||
do_action('puc_api_error', $response, null, $url, $this->slug);
|
do_action('puc_api_error', $response, null, $url, $this->slug);
|
||||||
return $response;
|
return $response;
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?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) ):
|
if ( !class_exists(PluginUpdateChecker::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !class_exists(Reference::class, false) ):
|
if ( !class_exists(Reference::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !trait_exists(ReleaseAssetSupport::class, false) ) :
|
if ( !trait_exists(ReleaseAssetSupport::class, false) ) :
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !trait_exists(ReleaseFilteringFeature::class, false) ) :
|
if ( !trait_exists(ReleaseFilteringFeature::class, false) ) :
|
||||||
|
|
||||||
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Theme;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Theme;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Utils;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Utils;
|
||||||
|
|
||||||
if ( !class_exists(ThemeUpdateChecker::class, false) ):
|
if ( !class_exists(ThemeUpdateChecker::class, false) ):
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4\Vcs;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7\Vcs;
|
||||||
|
|
||||||
if ( !trait_exists(VcsCheckerMethods::class, false) ) :
|
if ( !trait_exists(VcsCheckerMethods::class, false) ) :
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use WP_CLI;
|
use WP_CLI;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ From the users' perspective, it works just like with plugins and themes hosted o
|
|||||||
Getting Started
|
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
|
### 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();
|
$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**
|
- **Tags**
|
||||||
|
|
||||||
To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`. That's it.
|
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'
|
'unique-plugin-or-theme-slug'
|
||||||
);
|
);
|
||||||
|
|
||||||
//Optional: If you're using a private repository, create an OAuth consumer
|
//Optional: If you're using a private repository, create an API token
|
||||||
//and set the authentication credentials like this:
|
//with the "read:repository:bitbucket" scope and set the authentication
|
||||||
//Note: For now you need to check "This is a private consumer" when
|
//credentials like this:
|
||||||
//creating the consumer to work around #134:
|
|
||||||
// https://github.com/YahnisElsts/plugin-update-checker/issues/134
|
|
||||||
$myUpdateChecker->setAuthentication(array(
|
$myUpdateChecker->setAuthentication(array(
|
||||||
'consumer_key' => '...',
|
'username' => 'example@example.com', //Your BitBucket email address.
|
||||||
'consumer_secret' => '...',
|
'api_token' => '...',
|
||||||
));
|
));
|
||||||
|
|
||||||
//Optional: Set the branch that contains the stable release.
|
//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:
|
Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
|
||||||
```php
|
```php
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi;
|
||||||
|
|
||||||
$myUpdateChecker = new PluginUpdateChecker(
|
$myUpdateChecker = new PluginUpdateChecker(
|
||||||
new GitLabApi('https://myserver.com/user-name/repo-name/'),
|
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:
|
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
|
```php
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker;
|
||||||
use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi;
|
use YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi;
|
||||||
|
|
||||||
$myUpdateChecker = new PluginUpdateChecker(
|
$myUpdateChecker = new PluginUpdateChecker(
|
||||||
new GitLabApi(
|
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 |
|
| Old class name | New class name |
|
||||||
|-------------------------------------|----------------------------------------------------------------|
|
|-------------------------------------|----------------------------------------------------------------|
|
||||||
| `Puc_v4_Factory` | `YahnisElsts\PluginUpdateChecker\v5\PucFactory` |
|
| `Puc_v4_Factory` | `YahnisElsts\PluginUpdateChecker\v5\PucFactory` |
|
||||||
| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p4\PucFactory` |
|
| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p7\PucFactory` |
|
||||||
| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Plugin\UpdateChecker` |
|
| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Plugin\UpdateChecker` |
|
||||||
| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Theme\UpdateChecker` |
|
| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Theme\UpdateChecker` |
|
||||||
| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker` |
|
| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\PluginUpdateChecker` |
|
||||||
| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\ThemeUpdateChecker` |
|
| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\ThemeUpdateChecker` |
|
||||||
| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitHubApi` |
|
| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitHubApi` |
|
||||||
| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi` |
|
| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\GitLabApi` |
|
||||||
| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\BitBucketApi` |
|
| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p7\Vcs\BitBucketApi` |
|
||||||
|
|
||||||
License Management
|
License Management
|
||||||
------------------
|
------------------
|
||||||
|
|||||||
@@ -18,6 +18,6 @@
|
|||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"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 ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: plugin-update-checker\n"
|
"Project-Id-Version: plugin-update-checker\n"
|
||||||
"POT-Creation-Date: 2016-02-17 14:21+0100\n"
|
"POT-Creation-Date: 2025-06-12 23:40+0100\n"
|
||||||
"PO-Revision-Date: 2016-10-28 14:30+0330\n"
|
"PO-Revision-Date: 2025-06-12 23:49+0100\n"
|
||||||
"Last-Translator: studio RVOLA <hello@rvola.com>\n"
|
"Last-Translator: Pro Style <info@prostyle.ir>\n"
|
||||||
"Language-Team: Pro Style <info@prostyle.ir>\n"
|
"Language-Team: Alex Javadi <alex@aljm.org>\n"
|
||||||
"Language: fa_IR\n"
|
"Language: fa_IR\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\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"
|
"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-SourceCharset: UTF-8\n"
|
||||||
"X-Poedit-KeywordsList: __;_e\n"
|
"X-Poedit-KeywordsList: __;_e\n"
|
||||||
"X-Poedit-SearchPath-0: .\n"
|
"X-Poedit-SearchPath-0: .\n"
|
||||||
|
|
||||||
#: github-checker.php:120
|
#: Puc/v5p6/Plugin/Ui.php:56
|
||||||
msgid "There is no changelog available."
|
msgid "View details"
|
||||||
msgstr "شرحی برای تغییرات یافت نشد"
|
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"
|
msgid "Check for updates"
|
||||||
msgstr "بررسی برای بروزرسانی "
|
msgstr "بررسی بروزرسانی جدید"
|
||||||
|
|
||||||
#: plugin-update-checker.php:681
|
# The word “ناشناخته” is seems to be translated directly from the word (Un-known), rather than checking for the context.
|
||||||
msgid "This plugin is up to date."
|
# I think “نامشخص” (unknown) might be a suitable version in this scenario.
|
||||||
msgstr "شما از آخرین نسخه استفاده میکنید . بهروز باشید"
|
#: Puc/v5p6/Plugin/Ui.php:227
|
||||||
|
|
||||||
#: plugin-update-checker.php:683
|
|
||||||
msgid "A new version of this plugin is available."
|
|
||||||
msgstr "نسخه جدیدی برای افزونه ارائه شده است ."
|
|
||||||
|
|
||||||
#: plugin-update-checker.php:685
|
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Unknown update checker status \"%s\""
|
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 ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: plugin-update-checker\n"
|
"Project-Id-Version: plugin-update-checker\n"
|
||||||
"POT-Creation-Date: 2022-01-29 12:09+0800\n"
|
"POT-Creation-Date: 2025-11-21 10:40+0800\n"
|
||||||
"PO-Revision-Date: 2022-01-29 12:10+0800\n"
|
"PO-Revision-Date: 2025-11-21 10:40+0800\n"
|
||||||
"Last-Translator: Seaton Jiang <hi@seatonjiang.com>\n"
|
"Last-Translator: Seaton Jiang <hi@seatonjiang.com>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: zh_CN\n"
|
"Language: zh_CN\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: Poedit 2.4.3\n"
|
|
||||||
"X-Poedit-Basepath: ..\n"
|
|
||||||
"Plural-Forms: nplurals=1; plural=0;\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-SourceCharset: UTF-8\n"
|
||||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||||
"X-Poedit-SearchPath-0: .\n"
|
"X-Poedit-SearchPath-0: .\n"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:54
|
#: Puc/v5p6/Plugin/Ui.php:56
|
||||||
msgid "View details"
|
msgid "View details"
|
||||||
msgstr "查看详情"
|
msgstr "查看详情"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:77
|
#: Puc/v5p6/Plugin/Ui.php:79
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "More information about %s"
|
msgid "More information about %s"
|
||||||
msgstr "%s 的更多信息"
|
msgstr "%s 的更多信息"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:128
|
#: Puc/v5p6/Plugin/Ui.php:130
|
||||||
msgid "Check for updates"
|
msgid "Check for updates"
|
||||||
msgstr "检查更新"
|
msgstr "检查更新"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:214
|
#: Puc/v5p6/Plugin/Ui.php:217
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "The %s plugin is up to date."
|
msgid "The %s plugin is up to date."
|
||||||
msgstr "%s 目前是最新版本。"
|
msgstr "%s 目前是最新版本。"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:216
|
#: Puc/v5p6/Plugin/Ui.php:219
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "A new version of the %s plugin is available."
|
msgid "A new version of the %s plugin is available."
|
||||||
msgstr "%s 当前有可用的更新。"
|
msgstr "%s 当前有可用的更新。"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:218
|
#: Puc/v5p6/Plugin/Ui.php:221
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "Could not determine if updates are available for %s."
|
msgid "Could not determine if updates are available for %s."
|
||||||
msgstr "%s 无法确定是否有可用的更新。"
|
msgstr "%s 无法确定是否有可用的更新。"
|
||||||
|
|
||||||
#: Puc/v4p11/Plugin/Ui.php:224
|
#: Puc/v5p6/Plugin/Ui.php:227
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Unknown update checker status \"%s\""
|
msgid "Unknown update checker status \"%s\""
|
||||||
msgstr "未知的更新检查状态:%s"
|
msgstr "未知的更新检查状态:%s"
|
||||||
|
|
||||||
#: Puc/v4p11/Vcs/PluginUpdateChecker.php:100
|
#: Puc/v5p6/Vcs/PluginUpdateChecker.php:113
|
||||||
msgid "There is no changelog available."
|
msgid "There is no changelog available."
|
||||||
msgstr "没有可用的更新日志。"
|
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 ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: plugin-update-checker\n"
|
"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"
|
"PO-Revision-Date: 2016-01-10 20:59+0100\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@@ -11,39 +11,39 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\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-Basepath: ..\n"
|
||||||
"X-Poedit-SourceCharset: UTF-8\n"
|
"X-Poedit-SourceCharset: UTF-8\n"
|
||||||
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
"X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
|
||||||
"X-Poedit-SearchPath-0: .\n"
|
"X-Poedit-SearchPath-0: .\n"
|
||||||
|
|
||||||
#: Puc/v5p4/Plugin/Ui.php:128
|
#: Puc/v5p7/Plugin/Ui.php:130
|
||||||
msgid "Check for updates"
|
msgid "Check for updates"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Puc/v5p4/Plugin/Ui.php:214
|
#: Puc/v5p7/Plugin/Ui.php:217
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "The %s plugin is up to date."
|
msgid "The %s plugin is up to date."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Puc/v5p4/Plugin/Ui.php:216
|
#: Puc/v5p7/Plugin/Ui.php:219
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "A new version of the %s plugin is available."
|
msgid "A new version of the %s plugin is available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Puc/v5p4/Plugin/Ui.php:218
|
#: Puc/v5p7/Plugin/Ui.php:221
|
||||||
#, php-format
|
#, php-format
|
||||||
msgctxt "the plugin title"
|
msgctxt "the plugin title"
|
||||||
msgid "Could not determine if updates are available for %s."
|
msgid "Could not determine if updates are available for %s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Puc/v5p4/Plugin/Ui.php:224
|
#: Puc/v5p7/Plugin/Ui.php:227
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Unknown update checker status \"%s\""
|
msgid "Unknown update checker status \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Puc/v5p4/Vcs/PluginUpdateChecker.php:100
|
#: Puc/v5p7/Vcs/PluginUpdateChecker.php:113
|
||||||
msgid "There is no changelog available."
|
msgid "There is no changelog available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
+6
-6
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace YahnisElsts\PluginUpdateChecker\v5p4;
|
namespace YahnisElsts\PluginUpdateChecker\v5p7;
|
||||||
|
|
||||||
use YahnisElsts\PluginUpdateChecker\v5\PucFactory as MajorFactory;
|
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();
|
new Autoloader();
|
||||||
|
|
||||||
require __DIR__ . '/Puc/v5p4/PucFactory.php';
|
require __DIR__ . '/Puc/v5p7/PucFactory.php';
|
||||||
require __DIR__ . '/Puc/v5/PucFactory.php';
|
require __DIR__ . '/Puc/v5/PucFactory.php';
|
||||||
|
|
||||||
//Register classes defined in this version with the factory.
|
//Register classes defined in this version with the factory.
|
||||||
@@ -26,9 +26,9 @@ foreach (
|
|||||||
)
|
)
|
||||||
as $pucGeneralClass => $pucVersionedClass
|
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
|
//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.
|
//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
|
<?php
|
||||||
/**
|
/**
|
||||||
* Plugin Update Checker Library 5.4
|
* Plugin Update Checker Library 5.7
|
||||||
* http://w-shadow.com/
|
* http://w-shadow.com/
|
||||||
*
|
*
|
||||||
* Copyright 2024 Janis Elsts
|
* Copyright 2026 Janis Elsts
|
||||||
* Released under the MIT license. See license.txt for details.
|
* 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
|
# 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']))
|
if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
|
||||||
{
|
{
|
||||||
@@ -786,7 +786,7 @@ class Parsedown
|
|||||||
#
|
#
|
||||||
# Table
|
# 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']))
|
if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ $myUpdateChecker = PucFactory::buildUpdateChecker(
|
|||||||
__FILE__,
|
__FILE__,
|
||||||
'projects-portfolio'
|
'projects-portfolio'
|
||||||
);
|
);
|
||||||
|
// Note: PUC's setBranch() is only available when the host is recognized as a
|
||||||
// Set the branch that contains the stable release.
|
// VCS provider (GitHub, GitLab, Bitbucket). The Gitea URL here falls back to
|
||||||
$myUpdateChecker->setBranch( 'main' );
|
// PUC's plain JSON metadata mode, so we skip the call rather than throw.
|
||||||
|
|
||||||
// Current plugin version.
|
// Current plugin version.
|
||||||
define( 'PROJECTS_PORTFOLIO_VERSION', '1.1.1' );
|
define( 'PROJECTS_PORTFOLIO_VERSION', '1.1.1' );
|
||||||
|
|||||||
Reference in New Issue
Block a user