From ff79968170bc46f0713d78fc77ef722a2e3d8c57 Mon Sep 17 00:00:00 2001 From: airano Date: Wed, 18 Feb 2026 21:57:48 +0330 Subject: [PATCH] feat(wp): rename OpenPanel plugin to OpenPanel Self-Hosted for WP.org - Separate plugin identity for WordPress.org submission - Text domain, folder, and file renamed to openpanel-self-hosted - Description updated as fork of official OpenPanel plugin Co-Authored-By: Claude Opus 4.6 --- README.md | 2 +- wordpress-plugin/openpanel-self-hosted.zip | Bin 0 -> 11992 bytes .../LICENSE | 0 .../index.php | 0 .../openpanel-self-hosted.php} | 74 +++++++++--------- .../readme.txt | 6 +- wordpress-plugin/openpanel.zip | Bin 11702 -> 0 bytes 7 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 wordpress-plugin/openpanel-self-hosted.zip rename wordpress-plugin/{openpanel => openpanel-self-hosted}/LICENSE (100%) rename wordpress-plugin/{openpanel => openpanel-self-hosted}/index.php (100%) rename wordpress-plugin/{openpanel/openpanel.php => openpanel-self-hosted/openpanel-self-hosted.php} (92%) rename wordpress-plugin/{openpanel => openpanel-self-hosted}/readme.txt (94%) delete mode 100644 wordpress-plugin/openpanel.zip diff --git a/README.md b/README.md index e62bae9..36c46a7 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ Some MCP Hub tools require companion WordPress plugins: | SEO tools (`wordpress_get_post_seo`, etc.) | [SEO API Bridge](wordpress-plugin/seo-api-bridge/) ([Download ZIP](wordpress-plugin/seo-api-bridge.zip)) + Rank Math or Yoast SEO | | WP-CLI tools (15 tools: `wp_cache_*`, `wp_db_*`, etc.) | Docker socket + `CONTAINER` env var | | WordPress Advanced database/system tools | Docker socket + `CONTAINER` env var | -| OpenPanel analytics integration | [OpenPanel](wordpress-plugin/openpanel/) ([Download ZIP](wordpress-plugin/openpanel.zip)) | +| OpenPanel analytics integration | [OpenPanel Self-Hosted](wordpress-plugin/openpanel-self-hosted/) ([Download ZIP](wordpress-plugin/openpanel-self-hosted.zip)) | | WooCommerce tools | WooCommerce plugin (separate `WOOCOMMERCE_` config) | **Docker socket** is needed for WP-CLI and WordPress Advanced system tools. Add to your docker-compose: diff --git a/wordpress-plugin/openpanel-self-hosted.zip b/wordpress-plugin/openpanel-self-hosted.zip new file mode 100644 index 0000000000000000000000000000000000000000..4c1e2845248ff1f6fb6e7a7d6cf6918f44d410b4 GIT binary patch literal 11992 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' . esc_html__('Choose between OpenPanel Cloud or your own Self-Hosted instance.', 'openpanel') . '

'; + add_settings_section('op_hosting', __('Hosting Mode', 'openpanel-self-hosted'), function() { + echo '

' . esc_html__('Choose between OpenPanel Cloud or your own Self-Hosted instance.', 'openpanel-self-hosted') . '

'; }, self::OPTION_KEY); - add_settings_field('hosting_mode', __('Mode', 'openpanel'), function() { + add_settings_field('hosting_mode', __('Mode', 'openpanel-self-hosted'), function() { $opts = get_option(self::OPTION_KEY); $mode = isset($opts['hosting_mode']) ? $opts['hosting_mode'] : 'cloud'; ?>
-

+

' . esc_html__('Configure your Self-Hosted OpenPanel URLs. Only required if using Self-Hosted mode.', 'openpanel') . '

'; + add_settings_section('op_selfhosted', __('Self-Hosted Settings', 'openpanel-self-hosted'), function() { + echo '

' . esc_html__('Configure your Self-Hosted OpenPanel URLs. Only required if using Self-Hosted mode.', 'openpanel-self-hosted') . '

'; }, self::OPTION_KEY); - add_settings_field('api_url', __('API URL', 'openpanel'), function() { + add_settings_field('api_url', __('API URL', 'openpanel-self-hosted'), function() { $opts = get_option(self::OPTION_KEY); printf('', esc_attr(self::OPTION_KEY), isset($opts['api_url']) ? esc_attr($opts['api_url']) : '' ); - echo '

' . esc_html__('Your OpenPanel API endpoint (e.g., https://api.openpanel.yourdomain.com)', 'openpanel') . '

'; + echo '

' . esc_html__('Your OpenPanel API endpoint (e.g., https://api.openpanel.yourdomain.com)', 'openpanel-self-hosted') . '

'; }, self::OPTION_KEY, 'op_selfhosted'); - add_settings_field('dashboard_url', __('Dashboard URL', 'openpanel'), function() { + add_settings_field('dashboard_url', __('Dashboard URL', 'openpanel-self-hosted'), function() { $opts = get_option(self::OPTION_KEY); printf('', esc_attr(self::OPTION_KEY), isset($opts['dashboard_url']) ? esc_attr($opts['dashboard_url']) : '' ); - echo '

' . esc_html__('Your OpenPanel Dashboard URL — used to load op1.js from your server instead of the CDN (e.g., https://openpanel.yourdomain.com)', 'openpanel') . '

'; + echo '

' . esc_html__('Your OpenPanel Dashboard URL — used to load op1.js from your server instead of the CDN (e.g., https://openpanel.yourdomain.com)', 'openpanel-self-hosted') . '

'; }, self::OPTION_KEY, 'op_selfhosted'); // Section: Main Settings - add_settings_section('op_main', __('OpenPanel Settings', 'openpanel'), function() { - echo '

' . esc_html__('Set your OpenPanel Client ID. The SDK and requests are served from your domain to avoid ad blockers.', 'openpanel') . '

'; + add_settings_section('op_main', __('OpenPanel Settings', 'openpanel-self-hosted'), function() { + echo '

' . esc_html__('Set your OpenPanel Client ID. The SDK and requests are served from your domain to avoid ad blockers.', 'openpanel-self-hosted') . '

'; }, self::OPTION_KEY); - add_settings_field('client_id', __('Client ID', 'openpanel'), function() { + add_settings_field('client_id', __('Client ID', 'openpanel-self-hosted'), function() { $opts = get_option(self::OPTION_KEY); printf('', esc_attr(self::OPTION_KEY), @@ -110,14 +110,14 @@ final class OP_WP_Proxy { ); }, self::OPTION_KEY, 'op_main'); - add_settings_field('toggles', __('Auto-tracking (optional)', 'openpanel'), function() { + add_settings_field('toggles', __('Auto-tracking (optional)', 'openpanel-self-hosted'), function() { $o = get_option(self::OPTION_KEY); // Default track_screen to true if not set $track_screen = isset($o['track_screen']) ? !empty($o['track_screen']) : true; ?> -
-
- +
+
+

' . - esc_html__('OpenPanel cache cleared successfully. The latest op1.js will be fetched on the next page load.', 'openpanel') . + esc_html__('OpenPanel cache cleared successfully. The latest op1.js will be fetched on the next page load.', 'openpanel-self-hosted') . '

'; }); } @@ -155,18 +155,18 @@ final class OP_WP_Proxy {
-

-

+

+

- +
0) { echo '

' . /* translators: %s: human readable time difference */ - sprintf(esc_html__('Cache expires in %s', 'openpanel'), esc_html(human_time_diff(time(), $cached_time))) . + sprintf(esc_html__('Cache expires in %s', 'openpanel-self-hosted'), esc_html(human_time_diff(time(), $cached_time))) . '

'; } else { echo '

' . - esc_html__('Cache has expired and will refresh on next page load.', 'openpanel') . + esc_html__('Cache has expired and will refresh on next page load.', 'openpanel-self-hosted') . '

'; } } else { echo '

' . - esc_html__('No cached version found. op1.js will be fetched on next page load.', 'openpanel') . + esc_html__('No cached version found. op1.js will be fetched on next page load.', 'openpanel-self-hosted') . '

'; } ?>

- +


-

+

- + - + - + - +
get_api_base()); ?>
get_js_url()); ?>
diff --git a/wordpress-plugin/openpanel/readme.txt b/wordpress-plugin/openpanel-self-hosted/readme.txt similarity index 94% rename from wordpress-plugin/openpanel/readme.txt rename to wordpress-plugin/openpanel-self-hosted/readme.txt index be9cad1..4897d03 100644 --- a/wordpress-plugin/openpanel/readme.txt +++ b/wordpress-plugin/openpanel-self-hosted/readme.txt @@ -1,4 +1,4 @@ -=== OpenPanel === +=== OpenPanel Self-Hosted === Contributors: openpanel, airano Tags: analytics, privacy-friendly, tracking, self-hosted, proxy Requires at least: 5.8 @@ -12,7 +12,9 @@ Privacy-friendly analytics with ad-blocker resistance. Supports OpenPanel Cloud == Description == -**OpenPanel** is an open-source web and product analytics platform that serves as a privacy-friendly alternative to traditional analytics solutions. This WordPress plugin seamlessly integrates [OpenPanel](https://openpanel.dev) with your WordPress site while maximizing reliability and avoiding ad-blocker interference. +**OpenPanel Self-Hosted** is a fork of the [official OpenPanel WordPress plugin](https://wordpress.org/plugins/openpanel/) with full **Self-Hosted instance support**. [OpenPanel](https://openpanel.dev) is an open-source web and product analytics platform — a privacy-friendly alternative to Google Analytics. This plugin seamlessly integrates OpenPanel (Cloud or Self-Hosted) with your WordPress site while maximizing reliability and avoiding ad-blocker interference. + +Designed to work with [MCP Hub](https://github.com/airano-ir/mcphub) for AI-powered analytics management. = Key Features = diff --git a/wordpress-plugin/openpanel.zip b/wordpress-plugin/openpanel.zip deleted file mode 100644 index 2ed37211898c3849641793c24943bae1bf308369..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11702 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 b?;!u7d6Z-!q5ky>;-3xuPoi|Xe|i50R|QEK