From 681147e8e3ccdb6a8397b0ae36df41480e1786ae Mon Sep 17 00:00:00 2001 From: Javier Casares Date: Fri, 14 Aug 2026 07:55:23 +0000 Subject: [PATCH] v0.3.1 --- admin/class-robotstxt-manager-admin.php | 23 +- admin/class-robotstxt-manager-installer.php | 432 ++++++++++++++++++ admin/class-robotstxt-manager-settings.php | 8 +- admin/views/page-catalog.php | 50 +- changelog.txt | 56 +++ .../class-robotstxt-manager-activator.php | 2 +- includes/class-robotstxt-manager-plugin.php | 6 +- readme.txt | 6 +- robotstxt-manager.php | 7 +- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 11 files changed, 567 insertions(+), 25 deletions(-) create mode 100644 admin/class-robotstxt-manager-installer.php diff --git a/admin/class-robotstxt-manager-admin.php b/admin/class-robotstxt-manager-admin.php index b1e8a89..a569212 100644 --- a/admin/class-robotstxt-manager-admin.php +++ b/admin/class-robotstxt-manager-admin.php @@ -68,7 +68,7 @@ class Robotstxt_Manager_Admin { $catalog = $client->get_catalog(); $local = $this->resolve_local_state( $catalog ); - require_once ROBOTSTXT_MANAGER_DIR . 'admin/views/page-catalog.php'; + require ROBOTSTXT_MANAGER_DIR . 'admin/views/page-catalog.php'; } /** @@ -100,6 +100,27 @@ class Robotstxt_Manager_Admin { exit; } + /** + * Builds a nonce-protected admin-post action URL for a plugin row. + * + * @param string $action One of 'install', 'activate', 'update'. + * @param string $slug Plugin slug. + * + * @return string The action URL. + */ + public static function action_url( string $action, string $slug ): string { + return wp_nonce_url( + add_query_arg( + array( + 'action' => 'robotstxt_manager_' . $action, + 'slug' => $slug, + ), + admin_url( 'admin-post.php' ) + ), + 'robotstxt_manager_' . $action . '_' . $slug + ); + } + /** * Resolves local install state for every catalog entry. * diff --git a/admin/class-robotstxt-manager-installer.php b/admin/class-robotstxt-manager-installer.php new file mode 100644 index 0000000..e21be60 --- /dev/null +++ b/admin/class-robotstxt-manager-installer.php @@ -0,0 +1,432 @@ +add_action( 'admin_post_robotstxt_manager_install', $this, 'handle_install' ); + $loader->add_action( 'admin_post_robotstxt_manager_activate', $this, 'handle_activate' ); + $loader->add_action( 'admin_post_robotstxt_manager_update', $this, 'handle_update' ); + } + + /** + * Installs a plugin from the ROBOTSTXT store. + * + * @return void + */ + public function handle_install(): void { + $slug = $this->authorize( 'install' ); + + $entry = $this->find_catalog_entry( $slug ); + + if ( null === $entry ) { + $this->redirect_error( __( 'Plugin not found in catalog.', 'robotstxt-manager' ) ); + } + + $name = $this->entry_name( $entry, $slug ); + $this->ensure_plugin_functions(); + + $result = $this->download_and_install( $slug ); + + if ( is_wp_error( $result ) ) { + $this->redirect_error( $result->get_error_message() ); + } + + $this->redirect_success( + sprintf( + /* translators: %s: plugin name. */ + __( '%s installed. Activate it from the list below.', 'robotstxt-manager' ), + $name + ) + ); + } + + /** + * Activates an installed plugin. + * + * @return void + */ + public function handle_activate(): void { + $slug = $this->authorize( 'activate' ); + + $this->ensure_plugin_functions(); + + $file = $this->find_plugin_file( $slug ); + + if ( '' === $file ) { + $this->redirect_error( __( 'Plugin is not installed.', 'robotstxt-manager' ) ); + } + + $result = activate_plugins( $file ); + + if ( is_wp_error( $result ) ) { + $this->redirect_error( $result->get_error_message() ); + } + + $this->redirect_success( + sprintf( + /* translators: %s: plugin name (slug). */ + __( '%s activated.', 'robotstxt-manager' ), + $slug + ) + ); + } + + /** + * Updates an installed plugin to the latest catalog version. + * + * @return void + */ + public function handle_update(): void { + $slug = $this->authorize( 'update' ); + + $this->ensure_plugin_functions(); + + $file = $this->find_plugin_file( $slug ); + + if ( '' === $file ) { + $this->redirect_error( __( 'Plugin is not installed.', 'robotstxt-manager' ) ); + } + + $result = $this->download_and_install( $slug, true ); + + if ( is_wp_error( $result ) ) { + $this->redirect_error( $result->get_error_message() ); + } + + $this->redirect_success( + sprintf( + /* translators: %s: plugin name (slug). */ + __( '%s updated.', 'robotstxt-manager' ), + $slug + ) + ); + } + + /** + * Validates the capability and action-specific nonce, then returns the slug. + * + * @param string $action One of 'install', 'activate', 'update'. + * + * @return string The sanitized plugin slug. + */ + private function authorize( string $action ): string { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( esc_html__( 'Insufficient permissions.', 'robotstxt-manager' ) ); + } + + $raw_slug = ''; + + if ( isset( $_GET['slug'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verified below; slug only read after. + $unslashed = wp_unslash( $_GET['slug'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized below. + if ( is_string( $unslashed ) ) { + $raw_slug = sanitize_key( $unslashed ); + } + } + + check_admin_referer( 'robotstxt_manager_' . $action . '_' . $raw_slug ); + + return $raw_slug; + } + + /** + * Finds a catalog entry by slug. + * + * @param string $slug Plugin slug. + * + * @return array|null The entry, or null when not found. + */ + private function find_catalog_entry( string $slug ): ?array { + $client = Robotstxt_Manager_Core_Client::from_options(); + + if ( ! $client->is_configured() ) { + return null; + } + + foreach ( $client->get_catalog() as $row ) { + $row_slug = $row['slug'] ?? ''; + if ( is_string( $row_slug ) && $slug === $row_slug ) { + return $row; + } + } + + return null; + } + + /** + * Extracts a display name from a catalog entry. + * + * @param array|null $entry Catalog entry (null tolerated). + * @param string $slug Fallback slug. + * + * @return string The plugin name. + */ + private function entry_name( ?array $entry, string $slug ): string { + $raw_name = ( null !== $entry ) ? ( $entry['name'] ?? '' ) : ''; + $name = is_string( $raw_name ) ? $raw_name : ''; + + return '' !== $name ? $name : $slug; + } + + /** + * Resolves a plugin slug to its installed plugin file. + * + * @param string $slug Plugin slug (directory name). + * + * @return string Plugin file ("slug/file.php") or '' when not installed. + */ + private function find_plugin_file( string $slug ): string { + $all_plugins = get_plugins(); + + foreach ( $all_plugins as $file => $data ) { + $file_slug = dirname( $file ); + if ( '.' === $file_slug ) { + $file_slug = basename( $file, '.php' ); + } + if ( $slug === $file_slug ) { + return $file; + } + } + + return ''; + } + + /** + * Downloads the plugin ZIP from the store and installs it. + * + * @param string $slug Plugin slug. + * @param bool $overwrite Whether to overwrite an existing install (update). + * + * @return true|WP_Error True on success. + */ + private function download_and_install( string $slug, bool $overwrite = false ) { + $client = Robotstxt_Manager_Core_Client::from_options(); + + if ( ! $client->is_configured() ) { + return new WP_Error( 'robotstxt_manager_store', __( 'Store is not configured.', 'robotstxt-manager' ) ); + } + + $entry = $this->find_catalog_entry( $slug ); + + if ( null === $entry ) { + return new WP_Error( 'robotstxt_manager_catalog', __( 'Plugin not found in catalog.', 'robotstxt-manager' ) ); + } + + $raw_kind = $entry['type'] ?? 'free'; + $kind = is_string( $raw_kind ) ? $raw_kind : 'free'; + $raw_dl = $entry['download_url'] ?? ''; + $dl_url = is_string( $raw_dl ) ? $raw_dl : ''; + + $is_free = 'premium' !== $kind; + + // Free plugins that publish a public download URL in the catalog are + // fetched directly (no auth). Everything else goes through Core's + // authenticated download endpoint (account API key as Bearer). + $use_download_endpoint = ! ( $is_free && '' !== $dl_url ); + + $zip_url = $use_download_endpoint + ? $client->get_store_url() . '/wp-json/robotstxt-core/v1/plugins/' . rawurlencode( $slug ) . '/download' + : $dl_url; + + $tmp_file = wp_tempnam( $slug . '.zip' ); + + if ( ! $tmp_file ) { + return new WP_Error( 'robotstxt_manager_temp', __( 'Could not create a temporary file for download.', 'robotstxt-manager' ) ); + } + + $headers = array(); + + if ( $use_download_endpoint ) { + $api_key_raw = get_option( 'robotstxt_manager_api_key', '' ); + $api_key = is_string( $api_key_raw ) ? Robotstxt_Manager_Encryption::decrypt( $api_key_raw ) : ''; + + if ( '' !== $api_key ) { + $headers = array( + 'Authorization' => 'Bearer ' . $api_key, + ); + } + } + + $response = wp_remote_get( + $zip_url, + array( + 'timeout' => 300, + 'stream' => true, + 'filename' => $tmp_file, + 'headers' => $headers, + ) + ); + + if ( is_wp_error( $response ) ) { + wp_delete_file( $tmp_file ); + + return new WP_Error( + 'robotstxt_manager_download', + sprintf( + /* translators: %s: HTTP transport error message. */ + __( 'Download failed: %s', 'robotstxt-manager' ), + $response->get_error_message() + ) + ); + } + + $code = (int) wp_remote_retrieve_response_code( $response ); + + if ( 200 !== $code ) { + wp_delete_file( $tmp_file ); + + return new WP_Error( + 'robotstxt_manager_http', + sprintf( + /* translators: %d: HTTP status code. */ + __( 'Download failed (HTTP %d).', 'robotstxt-manager' ), + $code + ) + ); + } + + if ( ! $this->is_valid_zip( $tmp_file ) ) { + wp_delete_file( $tmp_file ); + + return new WP_Error( 'robotstxt_manager_zip', __( 'The store returned an invalid file.', 'robotstxt-manager' ) ); + } + + $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $result = $upgrader->install( + $tmp_file, + array( + 'overwrite' => $overwrite, + ) + ); + + wp_delete_file( $tmp_file ); + + if ( true !== $result ) { + $detail = ( $result instanceof WP_Error ) ? $result->get_error_message() : ''; + + return new WP_Error( + 'robotstxt_manager_install', + '' !== $detail + ? sprintf( + /* translators: %s: upgrader error message. */ + __( 'Installation failed: %s', 'robotstxt-manager' ), + $detail + ) + : __( 'Installation failed.', 'robotstxt-manager' ) + ); + } + + return true; + } + + /** + * Loads the wp-admin plugin/upgrader dependencies. + * + * @return void + */ + private function ensure_plugin_functions(): void { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + if ( ! class_exists( 'Plugin_Upgrader' ) ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + } + } + + /** + * Redirects back to the catalog page with a success notice. + * + * @param string $message Notice text. + * + * @return void + */ + private function redirect_success( string $message ): void { + $this->redirect( 'success', $message ); + } + + /** + * Redirects back to the catalog page with an error notice. + * + * @param string $message Notice text. + * + * @return void + */ + private function redirect_error( string $message ): void { + $this->redirect( 'error', $message ); + } + + /** + * Redirects back to the catalog page carrying a notice. + * + * @param string $result 'success' or 'error'. + * @param string $message Notice text. + * + * @return void + */ + private function redirect( string $result, string $message ): void { + wp_safe_redirect( + add_query_arg( + array( + 'page' => Robotstxt_Manager_Admin::PAGE_SLUG, + 'robotstxt_manager_result' => $result, + 'robotstxt_manager_message' => rawurlencode( $message ), + ), + admin_url( 'admin.php' ) + ) + ); + exit; + } + + /** + * Validates a downloaded archive: must exist, be non-empty, and start + * with the ZIP magic bytes "PK". + * + * @param string $file Absolute path to the downloaded file. + * + * @return bool True when the file looks like a valid ZIP archive. + */ + private function is_valid_zip( string $file ): bool { + if ( ! file_exists( $file ) ) { + return false; + } + + $size = filesize( $file ); + + if ( false === $size || 0 >= $size ) { + return false; + } + + $magic = file_get_contents( $file, false, null, 0, 2 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- reading 2 bytes of a local temp file. + + return is_string( $magic ) && 'PK' === substr( $magic, 0, 2 ); + } +} diff --git a/admin/class-robotstxt-manager-settings.php b/admin/class-robotstxt-manager-settings.php index aba1c50..1c2d7ac 100644 --- a/admin/class-robotstxt-manager-settings.php +++ b/admin/class-robotstxt-manager-settings.php @@ -83,7 +83,7 @@ class Robotstxt_Manager_Settings { array( 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', - 'default' => 'https://plugins.robotstxt.es', + 'default' => 'https://www.robotstxt.software', ) ); @@ -216,11 +216,11 @@ class Robotstxt_Manager_Settings { * @return void */ public function render_field_store_url(): void { - $raw = get_option( 'robotstxt_manager_store_url', 'https://plugins.robotstxt.es' ); - $value = is_string( $raw ) ? $raw : 'https://plugins.robotstxt.es'; + $raw = get_option( 'robotstxt_manager_store_url', 'https://www.robotstxt.software' ); + $value = is_string( $raw ) ? $raw : 'https://www.robotstxt.software'; printf( - '', + '', esc_attr( $value ) ); echo '

' . esc_html__( 'Base URL of the remote Plugins Core installation that this site will pull the plugin catalog from.', 'robotstxt-manager' ) . '

'; diff --git a/admin/views/page-catalog.php b/admin/views/page-catalog.php index 89738a0..51fc99f 100644 --- a/admin/views/page-catalog.php +++ b/admin/views/page-catalog.php @@ -31,6 +31,24 @@ $refresh_url = add_query_arg( $refresh_url = wp_nonce_url( $refresh_url, 'robotstxt_manager_refresh_catalog' ); $refreshed = isset( $_GET['refreshed'] ) && '1' === $_GET['refreshed']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended +// Action notice from an install/activate/update redirect. +$notice_result = ''; +$notice_message = ''; + +if ( isset( $_GET['robotstxt_manager_result'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only, set by this plugin's own redirects. + $raw_result = wp_unslash( $_GET['robotstxt_manager_result'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized on the next line. + if ( is_string( $raw_result ) ) { + $notice_result = sanitize_key( $raw_result ); + } +} + +if ( isset( $_GET['robotstxt_manager_message'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only, set by this plugin's own redirects. + $raw_message = wp_unslash( $_GET['robotstxt_manager_message'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized on the next line after decoding. + if ( is_string( $raw_message ) ) { + $notice_message = sanitize_text_field( rawurldecode( $raw_message ) ); + } +} + $local_wp_version = (string) get_bloginfo( 'version' ); $local_php_version = (string) PHP_VERSION; $compat_warnings = 0; @@ -43,6 +61,10 @@ $compat_warnings = 0;

+ +

+ +

@@ -186,19 +208,25 @@ $compat_warnings = 0; } ?> - - - - - 0.0 && '' !== $page_url ) : ?> - - - + + + + + + 0.0 && '' !== $page_url ) : ?> + - - + 0.0 && '' !== $page_url ) ? 'button-secondary' : 'button-primary'; + ?> + - + + + + + + diff --git a/changelog.txt b/changelog.txt index c8372af..830c028 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,61 @@ == Changelog == += 0.3.1 = + +_Release date: 2026-08-14_ + +* Default store URL is now `https://www.robotstxt.software` (was `https://plugins.robotstxt.es`). Applies to new activations and fresh installs; existing saved URLs are preserved. The catalog API at the new domain is verified live. +* Plugin version 0.3.0 → 0.3.1. + += 0.3.0 = + +_Release date: 2026-08-13_ + +**Highlights** + +* Classic install/activate/update flow: the catalog actions now run on a full page load (`admin-post.php` with per-action-and-slug nonces) and report the outcome through standard admin notices (green success / red error) at the top of the page, replacing the previous AJAX flow. + +**Added** + +* Activate action — installed-but-inactive plugins show an "Activate" button that calls `activate_plugins()`. +* Update action — plugins with a newer catalog version show an "Update" button that re-downloads the ZIP and runs the `Plugin_Upgrader` with `overwrite` enabled. +* Install/Activate/Update buttons are nonce links (`robotstxt_manager_{action}_{slug}` nonce actions) to `admin-post.php`, all `manage_options`-gated. +* Redirect-based notices: handlers redirect back to the catalog page carrying `robotstxt_manager_result` (success/error) and `robotstxt_manager_message`, rendered as dismissible standard notices. + +**Changed** + +* `Robotstxt_Manager_Installer` rewritten from an AJAX handler to three admin-post handlers (`robotstxt_manager_install`, `robotstxt_manager_activate`, `robotstxt_manager_update`); download logic (Bearer account-key auth, ZIP validation, temp-file cleanup) unchanged. +* Removed the AJAX endpoint, `manager-install.js`, and its script localization. +* Plugin version 0.2.0 → 0.3.0. + +**Compatibility** + +* WordPress: 7.0 - 7.1 (declared floor of the ecosystem; scan-confirmed lower) +* PHP: 8.4 - 8.5 (declared floor of the ecosystem; scan-confirmed lower) + += 0.2.0 = + +_Release date: 2026-08-12_ + +**Highlights** + +* Phase 2: the Install action. Free and premium plugins can be installed directly from the ROBOTSTXT catalog into the local site, authenticated with the account-level API key (requires Plugins Core 1.4.0+). + +**Added** + +* `Robotstxt_Manager_Installer` — AJAX handler (`wp_ajax_robotstxt_manager_install_plugin`, nonce-protected, `manage_options`-gated) that resolves the plugin in the remote catalog, downloads the ZIP (free plugins with a published public `download_url` directly; everything else via Core's authenticated `/download` endpoint with an `Authorization: Bearer ` header), validates the archive (ZIP magic bytes), installs it via `Plugin_Upgrader`, and cleans up the temp file on every path. +* `public/js/manager-install.js` — wires the Install buttons to the AJAX action with in-flight state and result rendering. +* Catalog view: enabled Install buttons for compatible plugins (free and premium). + +**Changed** + +* Plugin version 0.1.3 → 0.2.0. Description updated to reflect Phase 2. + +**Compatibility** + +* WordPress: 7.0 - 7.1 (declared floor of the ecosystem; scan-confirmed lower) +* PHP: 8.4 - 8.5 (declared floor of the ecosystem; scan-confirmed lower) + = 0.1.3 = _Release date: 2026-08-12_ diff --git a/includes/class-robotstxt-manager-activator.php b/includes/class-robotstxt-manager-activator.php index fd4c5fe..c8f5a64 100644 --- a/includes/class-robotstxt-manager-activator.php +++ b/includes/class-robotstxt-manager-activator.php @@ -44,7 +44,7 @@ class Robotstxt_Manager_Activator { */ private static function ensure_defaults(): void { if ( '' === get_option( 'robotstxt_manager_store_url', '' ) ) { - update_option( 'robotstxt_manager_store_url', 'https://plugins.robotstxt.es' ); + update_option( 'robotstxt_manager_store_url', 'https://www.robotstxt.software' ); } if ( '' === get_option( 'robotstxt_manager_cache_ttl_minutes', '' ) ) { diff --git a/includes/class-robotstxt-manager-plugin.php b/includes/class-robotstxt-manager-plugin.php index 9ecf8fc..6252100 100644 --- a/includes/class-robotstxt-manager-plugin.php +++ b/includes/class-robotstxt-manager-plugin.php @@ -59,11 +59,13 @@ final class Robotstxt_Manager_Plugin { private function define_hooks(): void { $this->loader->add_action( 'init', $this, 'load_textdomain' ); - $admin = new Robotstxt_Manager_Admin(); - $settings = new Robotstxt_Manager_Settings(); + $admin = new Robotstxt_Manager_Admin(); + $settings = new Robotstxt_Manager_Settings(); + $installer = new Robotstxt_Manager_Installer(); $admin->register( $this->loader ); $settings->register( $this->loader ); + $installer->register( $this->loader ); } /** diff --git a/readme.txt b/readme.txt index dffe146..9bfe948 100644 --- a/readme.txt +++ b/readme.txt @@ -3,9 +3,9 @@ Contributors: javiercasares, robotstxt Tags: dashboard, catalog, updates, subscriptions, management Requires at least: 4.7 Tested up to: 7.1 -Stable tag: 0.1.3 +Stable tag: 0.3.1 Requires PHP: 7.4 -Version: 0.1.3 +Version: 0.3.1 License: GPL-3.0-or-later License URI: https://www.gnu.org/licenses/gpl-3.0.txt @@ -30,7 +30,7 @@ This plugin does **not** re-implement the per-plugin update mechanism. Every ROB Configure at **ROBOTSTXT → Settings**: -* **Store URL** — Base URL of the remote Plugins Core installation (defaults to `https://plugins.robotstxt.es`). +* **Store URL** — Base URL of the remote Plugins Core installation (defaults to `https://www.robotstxt.software`). * **API Key** — Account-level API key issued by the ROBOTSTXT store. Encrypted before storage; masked in the UI (last 4 characters shown). Use the "Test connection" button to verify connectivity. * **Catalog Cache (minutes)** — How long the catalog response is cached in a transient. Default: 60 minutes. * **Data on Uninstall** — Opt-in checkbox. When enabled, all Manager options and transients are deleted on uninstall. Default: off. diff --git a/robotstxt-manager.php b/robotstxt-manager.php index 03827d5..be2818b 100644 --- a/robotstxt-manager.php +++ b/robotstxt-manager.php @@ -2,8 +2,8 @@ /** * Plugin Name: Manager (by ROBOTSTXT) * Plugin URI: https://git.robotstxt.es/ROBOTSTXT/robotstxt-manager - * Description: Client-side dashboard for the ROBOTSTXT plugin ecosystem. Lists the catalog from a remote Plugins Core install, resolves local install/update state, and surfaces subscription health. Phase 1: read-only catalog view. - * Version: 0.1.3 + * Description: Client-side dashboard for the ROBOTSTXT plugin ecosystem. Lists the catalog from a remote Plugins Core install, resolves local install/update state, and installs, activates, and updates plugins directly from the store. + * Version: 0.3.1 * Requires at least: 4.7 * Requires PHP: 7.4 * Author: ROBOTSTXT @@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) { } /** Plugin version. */ -define( 'ROBOTSTXT_MANAGER_VERSION', '0.1.3' ); +define( 'ROBOTSTXT_MANAGER_VERSION', '0.3.1' ); /** Absolute path to the plugin directory, with trailing slash. */ define( 'ROBOTSTXT_MANAGER_DIR', plugin_dir_path( __FILE__ ) ); @@ -44,6 +44,7 @@ if ( file_exists( ROBOTSTXT_MANAGER_DIR . 'vendor/autoload.php' ) ) { require_once ROBOTSTXT_MANAGER_DIR . 'includes/class-robotstxt-manager-plugin.php'; require_once ROBOTSTXT_MANAGER_DIR . 'admin/class-robotstxt-manager-admin.php'; require_once ROBOTSTXT_MANAGER_DIR . 'admin/class-robotstxt-manager-settings.php'; + require_once ROBOTSTXT_MANAGER_DIR . 'admin/class-robotstxt-manager-installer.php'; } register_activation_hook( __FILE__, array( 'Robotstxt_Manager_Activator', 'activate' ) ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index ba41573..1f39cc6 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -11,6 +11,7 @@ return array( 'Robotstxt_Manager_Admin' => $baseDir . '/admin/class-robotstxt-manager-admin.php', 'Robotstxt_Manager_Core_Client' => $baseDir . '/includes/class-robotstxt-manager-core-client.php', 'Robotstxt_Manager_Encryption' => $baseDir . '/includes/class-robotstxt-manager-encryption.php', + 'Robotstxt_Manager_Installer' => $baseDir . '/admin/class-robotstxt-manager-installer.php', 'Robotstxt_Manager_Loader' => $baseDir . '/includes/class-robotstxt-manager-loader.php', 'Robotstxt_Manager_Plugin' => $baseDir . '/includes/class-robotstxt-manager-plugin.php', 'Robotstxt_Manager_Settings' => $baseDir . '/admin/class-robotstxt-manager-settings.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a22a3d0..9a2f7bf 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -12,6 +12,7 @@ class ComposerStaticInit21193cc5ee16adfbe1fcd1cc267e45ef 'Robotstxt_Manager_Admin' => __DIR__ . '/../..' . '/admin/class-robotstxt-manager-admin.php', 'Robotstxt_Manager_Core_Client' => __DIR__ . '/../..' . '/includes/class-robotstxt-manager-core-client.php', 'Robotstxt_Manager_Encryption' => __DIR__ . '/../..' . '/includes/class-robotstxt-manager-encryption.php', + 'Robotstxt_Manager_Installer' => __DIR__ . '/../..' . '/admin/class-robotstxt-manager-installer.php', 'Robotstxt_Manager_Loader' => __DIR__ . '/../..' . '/includes/class-robotstxt-manager-loader.php', 'Robotstxt_Manager_Plugin' => __DIR__ . '/../..' . '/includes/class-robotstxt-manager-plugin.php', 'Robotstxt_Manager_Settings' => __DIR__ . '/../..' . '/admin/class-robotstxt-manager-settings.php',