diff --git a/CHANGES.md b/CHANGES.md
index 4188e76b4..d7c3a6b40 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -2,6 +2,7 @@
* update `freemius/wordpress-sdk`
* update `class-parser.php`
* use `is_wp_version_compatible()` and `is_php_version_compatible()` in `GU_Trait::can_update_repo()`
+* update `gu-loader.php` with generic loader
#### 12.3.1 / 2023-10-19
* update `freemius/wordpress-sdk`
diff --git a/composer.lock b/composer.lock
index 3b82520e4..99c6f0a61 100644
--- a/composer.lock
+++ b/composer.lock
@@ -59,12 +59,12 @@
"source": {
"type": "git",
"url": "https://github.com/afragen/wordpress-plugin-readme-parser.git",
- "reference": "0dc64ee6d4cb6d32e3855d016763d9bd08652e0f"
+ "reference": "2a67b37dbdcbb24d5b1d976d039b083c3833b245"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/afragen/wordpress-plugin-readme-parser/zipball/0dc64ee6d4cb6d32e3855d016763d9bd08652e0f",
- "reference": "0dc64ee6d4cb6d32e3855d016763d9bd08652e0f",
+ "url": "https://api.github.com/repos/afragen/wordpress-plugin-readme-parser/zipball/2a67b37dbdcbb24d5b1d976d039b083c3833b245",
+ "reference": "2a67b37dbdcbb24d5b1d976d039b083c3833b245",
"shasum": ""
},
"require": {
@@ -98,7 +98,7 @@
"issues": "https://github.com/afragen/wordpress-plugin-readme-parser/issues",
"source": "https://github.com/afragen/wordpress-plugin-readme-parser/tree/master"
},
- "time": "2024-02-02T17:46:48+00:00"
+ "time": "2024-02-27T16:41:56+00:00"
},
{
"name": "afragen/wp-dependency-installer",
diff --git a/git-updater.php b/git-updater.php
index 3d9e21291..4668b15cb 100644
--- a/git-updater.php
+++ b/git-updater.php
@@ -12,7 +12,7 @@
* Plugin Name: Git Updater
* Plugin URI: https://git-updater.com
* Description: A plugin to automatically update GitHub hosted plugins, themes, and language packs. Additional API plugins available for Bitbucket, GitLab, Gitea, and Gist.
- * Version: 12.3.1.2
+ * Version: 12.3.1.4
* Author: Andy Fragen
* License: MIT
* Domain Path: /languages
diff --git a/mu/gu-loader.php b/mu/gu-loader.php
deleted file mode 100644
index c1a17897d..000000000
--- a/mu/gu-loader.php
+++ /dev/null
@@ -1,110 +0,0 @@
-load_hooks();
- }
-
- /**
- * Load action and filter hooks.
- *
- * @return void
- */
- public function load_hooks() {
- // Deactivate normal plugin as it's loaded as mu-plugin.
- add_action( 'activated_plugin', [ $this, 'deactivate' ], 10, 1 );
-
- /*
- * Remove links and checkbox from Plugins page so user can't delete main plugin.
- */
- add_filter( 'network_admin_plugin_action_links_' . static::$plugin_file, [ $this, 'mu_plugin_active' ] );
- add_filter( 'plugin_action_links_' . static::$plugin_file, [ $this, 'mu_plugin_active' ] );
- add_action(
- 'after_plugin_row_' . static::$plugin_file,
- function () {
- print '';
- print '';
- }
- );
- }
-
- /**
- * Deactivate if plugin in loaded not as mu-plugin.
- *
- * @param string $plugin Plugin slug.
- */
- public function deactivate( $plugin ) {
- if ( static::$plugin_file === $plugin ) {
- deactivate_plugins( static::$plugin_file );
- }
- }
-
- /**
- * Label as mu-plugin in plugin view.
- *
- * @param array $actions Link actions.
- *
- * @return array
- */
- public function mu_plugin_active( $actions ) {
- if ( isset( $actions['activate'] ) ) {
- unset( $actions['activate'] );
- }
- if ( isset( $actions['delete'] ) ) {
- unset( $actions['delete'] );
- }
- if ( isset( $actions['deactivate'] ) ) {
- unset( $actions['deactivate'] );
- }
-
- return array_merge( [ 'mu-plugin' => esc_html__( 'Activated as mu-plugin', 'git-updater' ) ], $actions );
- }
-}
-
-( new MU_Loader() )->run();
diff --git a/mu/mu-loader.php b/mu/mu-loader.php
new file mode 100644
index 000000000..458e3971b
--- /dev/null
+++ b/mu/mu-loader.php
@@ -0,0 +1,124 @@
+load_hooks( $plugin_file );
+ }
+ }
+ add_filter( 'option_active_plugins', [ $this, 'set_as_active' ] );
+ }
+
+ /**
+ * Load action and filter hooks.
+ *
+ * Remove links and disable checkbox from Plugins page so user can't delete main plugin.
+ * Ensure plugin shows as active.
+ *
+ * @param string $plugin_file Plugin file.
+ * @return void
+ */
+ public function load_hooks( $plugin_file ) {
+ add_filter( 'network_admin_plugin_action_links_' . $plugin_file, [ $this, 'mu_plugin_active' ] );
+ add_filter( 'plugin_action_links_' . $plugin_file, [ $this, 'mu_plugin_active' ] );
+ add_action( 'after_plugin_row_' . $plugin_file, [ $this, 'after_plugin_row_updates' ] );
+ add_action( 'after_plugin_row_meta', [ $this, 'display_as_mu_plugin' ], 10, 1 );
+ }
+
+ /**
+ * Make plugin row active and disable checkbox.
+ *
+ * @param string $plugin_file Plugin file.
+ * @return void
+ */
+ public function after_plugin_row_updates( $plugin_file ) {
+ print "";
+ print "";
+ }
+
+ /**
+ * Add 'Activated as mu-plugin' to plugin row meta.
+ *
+ * @param string $plugin_file Plugin file.
+ * @return void
+ */
+ public function display_as_mu_plugin( $plugin_file ) {
+ if ( in_array( $plugin_file, (array) static::$plugin_files, true ) ) {
+ printf(
+ '
%s',
+ esc_html__( 'Activated as mu-plugin', 'mu-loader' )
+ );
+ }
+ }
+
+ /**
+ * Unset action links.
+ *
+ * @param array $actions Link actions.
+ * @return array
+ */
+ public function mu_plugin_active( $actions ) {
+ unset( $actions['activate'], $actions['delete'], $actions['deactivate'] );
+
+ return $actions;
+ }
+
+ /**
+ * Set mu-plugins as active.
+ *
+ * @param array $active_plugins Array of active plugins.
+ * @return array
+ */
+ public function set_as_active( $active_plugins ) {
+ $active_plugins = array_merge( $active_plugins, static::$plugin_files );
+
+ return array_unique( $active_plugins );
+ }
+}
+
+( new MU_Loader() )->run();
diff --git a/vendor/afragen/wordpress-plugin-readme-parser/class-parser.php b/vendor/afragen/wordpress-plugin-readme-parser/class-parser.php
index 835b0fa24..39f88a3e0 100644
--- a/vendor/afragen/wordpress-plugin-readme-parser/class-parser.php
+++ b/vendor/afragen/wordpress-plugin-readme-parser/class-parser.php
@@ -99,7 +99,7 @@ class Parser {
*
* @var array
*/
- private $expected_sections = array(
+ public $expected_sections = array(
'description',
'installation',
'faq',
@@ -114,7 +114,7 @@ class Parser {
*
* @var array
*/
- private $alias_sections = array(
+ public $alias_sections = array(
'frequently_asked_questions' => 'faq',
'change_log' => 'changelog',
'screenshot' => 'screenshots',
@@ -125,7 +125,7 @@ class Parser {
*
* @var array
*/
- private $valid_headers = array(
+ public $valid_headers = array(
'tested' => 'tested',
'tested up to' => 'tested',
'requires' => 'requires',
@@ -149,6 +149,23 @@ class Parser {
'wordpress',
);
+ /**
+ * The maximum field lengths for the readme.
+ *
+ * @var array
+ */
+ public $maximum_field_lengths = array(
+ 'short_description' => 150,
+ 'section' => 1500,
+ );
+
+ /**
+ * The raw contents of the readme file.
+ *
+ * @var string
+ */
+ public $raw_contents = '';
+
/**
* Parser constructor.
*
@@ -196,6 +213,8 @@ protected function parse_readme( $file_or_url ) {
* @return bool
*/
protected function parse_readme_contents( $contents ) {
+ $this->raw_contents = $contents;
+
if ( preg_match( '!!u', $contents ) ) {
$contents = preg_split( '!\R!u', $contents );
} else {
@@ -287,6 +306,24 @@ protected function parse_readme_contents( $contents ) {
$this->tags = array_diff( $this->tags, $this->ignore_tags );
$this->warnings['ignored_tags'] = true;
}
+
+ // Check if the tags are low-quality (ie. little used)
+ if ( $this->tags && taxonomy_exists( 'plugin_tags' ) ) {
+ $tags = get_terms( array(
+ 'taxonomy' => 'plugin_tags',
+ 'name' => $this->tags,
+ ) );
+
+ $low_usage_tags = array_filter(
+ $tags,
+ function( $term ) {
+ return $term->count < 5;
+ }
+ );
+
+ $this->warnings['low_usage_tags'] = wp_list_pluck( $low_usage_tags, 'name' );
+ }
+
if ( count( $this->tags ) > 5 ) {
$this->tags = array_slice( $this->tags, 0, 5 );
$this->warnings['too_many_tags'] = true;
@@ -410,6 +447,14 @@ protected function parse_readme_contents( $contents ) {
unset( $this->sections['upgrade_notice'] );
}
+ foreach ( $this->sections as $section => $content ) {
+ $this->sections[ $section ] = $this->trim_length( $content, 'section', 'words' );
+
+ if ( $content !== $this->sections[ $section ] ) {
+ $this->warnings["trimmed_section_{$section}"] = true;
+ }
+ }
+
// Display FAQs as a definition list.
if ( isset( $this->sections['faq'] ) ) {
$this->faq = $this->parse_section( $this->sections['faq'] );
@@ -431,7 +476,7 @@ protected function parse_readme_contents( $contents ) {
$this->short_description = $this->sanitize_text( $this->short_description );
$this->short_description = $this->parse_markdown( $this->short_description );
$this->short_description = wp_strip_all_tags( $this->short_description );
- $short_description = $this->trim_length( $this->short_description, 150 );
+ $short_description = $this->trim_length( $this->short_description, 'short_description' );
if ( $short_description !== $this->short_description ) {
if ( empty( $this->warnings['no_short_description_present'] ) ) {
$this->warnings['trimmed_short_description'] = true;
@@ -505,9 +550,29 @@ protected function strip_newlines( $line ) {
*
* @param string $desc
* @param int $length
+ * @param string $type The type of the length, 'char' or 'words'.
* @return string
*/
- protected function trim_length( $desc, $length = 150 ) {
+ protected function trim_length( $desc, $length = 150, $type = 'char' ) {
+ if ( is_string( $length ) ) {
+ $length = $this->maximum_field_lengths[ $length ] ?? $length;
+ }
+
+ if ( 'words' === $type ) {
+ // Split by whitespace, capturing it so we can put it back together.
+ $pieces = preg_split( '/(\s+)/u', $desc, -1, PREG_SPLIT_DELIM_CAPTURE );
+
+ $word_count_with_spaces = $length * 2;
+
+ if ( count( $pieces ) < $word_count_with_spaces ) {
+ return $desc;
+ }
+
+ $pieces = array_slice( $pieces, 0, $word_count_with_spaces );
+
+ return implode( '', $pieces ) . ' …';
+ }
+
// Apply the length restriction without counting html entities.
$str_length = mb_strlen( html_entity_decode( $desc ) ?: $desc );
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index fdd3e517c..aa5a65288 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -57,19 +57,19 @@
"source": {
"type": "git",
"url": "https://github.com/afragen/wordpress-plugin-readme-parser.git",
- "reference": "0dc64ee6d4cb6d32e3855d016763d9bd08652e0f"
+ "reference": "2a67b37dbdcbb24d5b1d976d039b083c3833b245"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/afragen/wordpress-plugin-readme-parser/zipball/0dc64ee6d4cb6d32e3855d016763d9bd08652e0f",
- "reference": "0dc64ee6d4cb6d32e3855d016763d9bd08652e0f",
+ "url": "https://api.github.com/repos/afragen/wordpress-plugin-readme-parser/zipball/2a67b37dbdcbb24d5b1d976d039b083c3833b245",
+ "reference": "2a67b37dbdcbb24d5b1d976d039b083c3833b245",
"shasum": ""
},
"require": {
"erusev/parsedown": "^1.7",
"php": ">=5.4"
},
- "time": "2024-02-02T17:46:48+00:00",
+ "time": "2024-02-27T16:41:56+00:00",
"default-branch": true,
"type": "library",
"installation-source": "dist",
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index f16f956f1..deb33ef86 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'afragen/git-updater',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '1dba89c7dde78a114328446848792d3a3df47a54',
+ 'reference' => '6a49a43064a8845e30c29934909152ccedb61f80',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'afragen/git-updater' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '1dba89c7dde78a114328446848792d3a3df47a54',
+ 'reference' => '6a49a43064a8845e30c29934909152ccedb61f80',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -33,7 +33,7 @@
'afragen/wordpress-plugin-readme-parser' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => '0dc64ee6d4cb6d32e3855d016763d9bd08652e0f',
+ 'reference' => '2a67b37dbdcbb24d5b1d976d039b083c3833b245',
'type' => 'library',
'install_path' => __DIR__ . '/../afragen/wordpress-plugin-readme-parser',
'aliases' => array(