diff --git a/admin/class-admin-upload.php b/admin/class-admin-upload.php
deleted file mode 100644
index d08ce4b..0000000
--- a/admin/class-admin-upload.php
+++ /dev/null
@@ -1,91 +0,0 @@
- false );
- $uploaded_file = wp_handle_upload( $file, $upload_overrides );
-
- if ( isset( $uploaded_file['error'] ) ) {
- wp_safe_redirect( add_query_arg( 'message', 'upload_error', wp_get_referer() ) );
- exit;
- }
-
- // Create an attachment for the uploaded file.
- $attachment = array(
- 'post_mime_type' => $uploaded_file['type'],
- 'post_title' => sanitize_file_name( $file['name'] ),
- 'post_content' => '',
- 'post_status' => 'inherit',
- );
-
- $attachment_id = wp_insert_attachment( $attachment, $uploaded_file['file'] );
-
- // Generate and update attachment metadata.
- $attach_data = wp_generate_attachment_metadata( $attachment_id, $uploaded_file['file'] );
- wp_update_attachment_metadata( $attachment_id, $attach_data );
-
- wp_safe_redirect( add_query_arg( 'message', 'upload_success', wp_get_referer() ) );
- exit;
- }
-}
diff --git a/exelearning.php b/exelearning.php
index df721cf..27ff2a1 100644
--- a/exelearning.php
+++ b/exelearning.php
@@ -39,12 +39,8 @@
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-activator.php';
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-deactivator.php';
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-exelearning.php';
-require_once EXELEARNING_PLUGIN_DIR . 'includes/class-hooks.php';
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-i18n.php';
-require_once EXELEARNING_PLUGIN_DIR . 'includes/class-filters.php';
-require_once EXELEARNING_PLUGIN_DIR . 'includes/class-post-types.php';
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-mime-types.php';
-require_once EXELEARNING_PLUGIN_DIR . 'includes/class-elp-list-table.php';
// Load the eXeLearning file upload handler.
require_once EXELEARNING_PLUGIN_DIR . 'includes/class-elp-upload-handler.php';
@@ -63,7 +59,6 @@
// Admin classes.
require_once EXELEARNING_PLUGIN_DIR . 'admin/class-admin-settings.php';
require_once EXELEARNING_PLUGIN_DIR . 'admin/class-admin-styles.php';
-require_once EXELEARNING_PLUGIN_DIR . 'admin/class-admin-upload.php';
// Public classes.
require_once EXELEARNING_PLUGIN_DIR . 'public/class-shortcodes.php';
@@ -103,8 +98,7 @@ function exelearning_run() {
$viewer_enhancements = new ExeLearning_Viewer_Enhancements();
$viewer_enhancements->register_hooks();
- $plugin = new ExeLearning();
- $plugin->run();
+ new ExeLearning();
}
exelearning_run();
diff --git a/includes/class-elp-list-table.php b/includes/class-elp-list-table.php
deleted file mode 100644
index ccf05f9..0000000
--- a/includes/class-elp-list-table.php
+++ /dev/null
@@ -1,132 +0,0 @@
- 'exelearning_file',
- 'plural' => 'exelearning_files',
- 'ajax' => false,
- )
- );
- }
-
- /**
- * Returns the list table columns.
- *
- * @return array List of columns.
- */
- public function get_columns() {
- $columns = array(
- 'cb' => '',
- 'title' => __( 'Title', 'exelearning' ),
- 'date' => __( 'Date', 'exelearning' ),
- 'status' => __( 'Status', 'exelearning' ),
- );
- return $columns;
- }
-
- /**
- * Prepares the list of items.
- */
- public function prepare_items() {
- // Static data for demonstration. Replace with data from the database.
- $data = array(
- array(
- 'ID' => 1,
- 'title' => 'Example File 1',
- 'date' => '2025-01-01',
- 'status' => 'Active',
- ),
- array(
- 'ID' => 2,
- 'title' => 'Example File 2',
- 'date' => '2025-01-02',
- 'status' => 'Blocked',
- ),
- );
-
- $columns = $this->get_columns();
- $hidden = array();
- $sortable = array();
-
- $this->_column_headers = array( $columns, $hidden, $sortable );
-
- $this->items = $data;
- }
-
- /**
- * Renders the checkbox column.
- *
- * @param array $item Current item.
- * @return string HTML for the checkbox.
- */
- protected function column_cb( $item ) {
- return sprintf(
- '',
- esc_attr( $item['ID'] )
- );
- }
-
- /**
- * Renders the title column.
- *
- * @param array $item Current item.
- * @return string HTML for the title with row actions.
- */
- protected function column_title( $item ) {
- $edit_url = '#'; // Define edit URL as required.
-
- $actions = array(
- 'edit' => sprintf( '%s', esc_url( $edit_url ), __( 'Edit', 'exelearning' ) ),
- 'delete' => sprintf( '%s', esc_url( '#' ), __( 'Delete', 'exelearning' ) ),
- );
-
- return sprintf(
- '%1$s %2$s',
- esc_html( $item['title'] ),
- $this->row_actions( $actions )
- );
- }
-
- /**
- * Default column rendering.
- *
- * @param array $item Current item.
- * @param string $column_name Column name.
- * @return string Column content.
- */
- protected function column_default( $item, $column_name ) {
- if ( isset( $item[ $column_name ] ) ) {
- return esc_html( $item[ $column_name ] );
- }
- return '';
- }
-}
diff --git a/includes/class-exelearning-rest-api.php b/includes/class-exelearning-rest-api.php
index 8c7eaba..567253e 100644
--- a/includes/class-exelearning-rest-api.php
+++ b/includes/class-exelearning-rest-api.php
@@ -626,25 +626,6 @@ private function validate_elp_file_path( $attachment_id ) {
return $file_path;
}
- /**
- * Clean up old extracted folder for an attachment.
- *
- * @param int $attachment_id Attachment ID.
- */
- private function cleanup_old_extraction( $attachment_id ) {
- $old_extracted = get_post_meta( $attachment_id, '_exelearning_extracted', true );
- if ( ! $old_extracted ) {
- return;
- }
-
- $upload_dir = wp_upload_dir();
- $old_folder = trailingslashit( $upload_dir['basedir'] ) . 'exelearning/' . $old_extracted . '/';
-
- if ( is_dir( $old_folder ) ) {
- $this->recursive_delete( $old_folder );
- }
- }
-
/**
* Clean up extraction directory by hash.
*
@@ -785,26 +766,4 @@ private function extract_elp_to_new_dir( $file_path ) {
private function apply_elp_metadata( $attachment_id, $elp_service, $hash, $has_preview ) {
$this->reprocessor->apply_metadata( $attachment_id, $elp_service, $hash, $has_preview );
}
-
- /**
- * Recursively delete a directory.
- *
- * @param string $dir Directory path.
- */
- private function recursive_delete( $dir ) {
- if ( ! file_exists( $dir ) ) {
- return;
- }
-
- if ( is_file( $dir ) || is_link( $dir ) ) {
- wp_delete_file( $dir );
- } else {
- $files = array_diff( scandir( $dir ), array( '.', '..' ) );
- foreach ( $files as $file ) {
- $this->recursive_delete( $dir . DIRECTORY_SEPARATOR . $file );
- }
- // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Direct filesystem access needed for cleanup.
- rmdir( $dir );
- }
- }
}
diff --git a/includes/class-exelearning.php b/includes/class-exelearning.php
index 9dae0a4..905a3c6 100644
--- a/includes/class-exelearning.php
+++ b/includes/class-exelearning.php
@@ -41,35 +41,21 @@ class ExeLearning {
*/
public function __construct() {
$this->version = EXELEARNING_VERSION;
- $this->load_dependencies();
$this->init_components();
$this->setup_hooks();
$this->load_i18n();
}
- /**
- * Loads required dependencies.
- *
- * Additional dependencies can be loaded here if needed.
- */
- private function load_dependencies() {
- // All required files are loaded via require_once in the main plugin file.
- }
-
/**
* Initializes all plugin components.
*/
private function init_components() {
$this->components = array(
- 'hooks' => new ExeLearning_Hooks(),
- 'filters' => new ExeLearning_Filters(),
- 'post_types' => new ExeLearning_Post_Types(),
'mime_types' => new ExeLearning_Mime_Types(),
'shortcodes' => new ExeLearning_Shortcodes(),
'media_library' => new ExeLearning_Media_Library(),
'i18n' => new ExeLearning_I18n(),
'admin_settings' => new ExeLearning_Admin_Settings(),
- 'admin_upload' => new ExeLearning_Admin_Upload(),
'elp_upload_handler' => new ExeLearning_Elp_Upload_Handler(),
'elp_upload_block' => new ExeLearning_Elp_Upload_Block(),
'editor' => new ExeLearning_Editor(),
@@ -89,10 +75,7 @@ private function setup_hooks() {
// Early so migrated options are in place before settings registration
// (priority 10) and any admin page render reads them.
add_action( 'admin_init', array( 'ExeLearning_Upgrader', 'maybe_upgrade' ), 5 );
- add_action( 'init', array( $this->components['hooks'], 'register_hooks' ) );
- add_action( 'init', array( $this->components['post_types'], 'register_post_types' ) );
add_action( 'init', array( $this->components['shortcodes'], 'register_shortcodes' ) );
- $this->components['filters']->register_filters();
$this->components['mime_types']->register_mime_types();
$this->components['elp_upload_handler']->register();
}
@@ -106,11 +89,4 @@ private function setup_hooks() {
private function load_i18n() {
add_action( 'init', array( $this->components['i18n'], 'load_textdomain' ) );
}
-
- /**
- * Runs the plugin.
- */
- public function run() {
- // Additional execution code can be added here.
- }
}
diff --git a/includes/class-filters.php b/includes/class-filters.php
deleted file mode 100644
index 3cbb293..0000000
--- a/includes/class-filters.php
+++ /dev/null
@@ -1,67 +0,0 @@
-is_elp_file( $file ) ) {
- // Add custom metadata for .elp files.
- $metadata['exelearning'] = 'elp file metadata';
- }
-
- return $metadata;
- }
-
- /**
- * Checks if a file is an .elp file.
- *
- * @param string $file File path.
- *
- * @return bool True if the file is an .elp file, false otherwise.
- */
- private function is_elp_file( $file ) {
- if ( ! $file || ! is_string( $file ) ) {
- return false;
- }
- $ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
- return 'elpx' === $ext;
- }
-}
diff --git a/includes/class-hooks.php b/includes/class-hooks.php
deleted file mode 100644
index d2d10ad..0000000
--- a/includes/class-hooks.php
+++ /dev/null
@@ -1,36 +0,0 @@
-
admin/vendor
- admin/class-admin-upload.php
includes/class-cli-command.php
diff --git a/tests/unit/AdminUploadTest.php b/tests/unit/AdminUploadTest.php
deleted file mode 100644
index ad0860f..0000000
--- a/tests/unit/AdminUploadTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-upload = new ExeLearning_Admin_Upload();
- }
-
- /**
- * Test constructor registers action.
- */
- public function test_constructor_registers_action() {
- $upload = new ExeLearning_Admin_Upload();
-
- $this->assertGreaterThan(
- 0,
- has_action( 'admin_post_exelearning_upload', array( $upload, 'handle_upload' ) )
- );
- }
-
- /**
- * Test handle_upload method exists.
- */
- public function test_handle_upload_exists() {
- $this->assertTrue( method_exists( $this->upload, 'handle_upload' ) );
- }
-
- /**
- * Test handle_upload is public.
- */
- public function test_handle_upload_is_public() {
- $method = new ReflectionMethod( ExeLearning_Admin_Upload::class, 'handle_upload' );
- $this->assertTrue( $method->isPublic() );
- }
-}
diff --git a/tests/unit/ElpListTableTest.php b/tests/unit/ElpListTableTest.php
deleted file mode 100644
index ce6371f..0000000
--- a/tests/unit/ElpListTableTest.php
+++ /dev/null
@@ -1,139 +0,0 @@
-list_table = new ExeLearning_Elp_List_Table();
- }
-
- /**
- * Test get_columns returns expected columns.
- */
- public function test_get_columns() {
- $columns = $this->list_table->get_columns();
-
- $this->assertIsArray( $columns );
- $this->assertArrayHasKey( 'cb', $columns );
- $this->assertArrayHasKey( 'title', $columns );
- $this->assertArrayHasKey( 'date', $columns );
- $this->assertArrayHasKey( 'status', $columns );
- }
-
- /**
- * Test prepare_items sets items.
- */
- public function test_prepare_items() {
- $this->list_table->prepare_items();
-
- $this->assertNotEmpty( $this->list_table->items );
- $this->assertCount( 2, $this->list_table->items );
- }
-
- /**
- * Test prepare_items sets column headers.
- */
- public function test_prepare_items_sets_headers() {
- $this->list_table->prepare_items();
-
- $headers = $this->list_table->get_column_info();
-
- $this->assertIsArray( $headers );
- $this->assertCount( 4, $headers );
- }
-
- /**
- * Test column_cb renders checkbox.
- */
- public function test_column_cb() {
- $method = new ReflectionMethod( ExeLearning_Elp_List_Table::class, 'column_cb' );
- $method->setAccessible( true );
-
- $item = array( 'ID' => 123 );
- $result = $method->invoke( $this->list_table, $item );
-
- $this->assertStringContainsString( 'assertStringContainsString( 'type="checkbox"', $result );
- $this->assertStringContainsString( 'value="123"', $result );
- }
-
- /**
- * Test column_title renders title with actions.
- */
- public function test_column_title() {
- $method = new ReflectionMethod( ExeLearning_Elp_List_Table::class, 'column_title' );
- $method->setAccessible( true );
-
- $item = array(
- 'ID' => 1,
- 'title' => 'Test File',
- );
- $result = $method->invoke( $this->list_table, $item );
-
- $this->assertStringContainsString( 'Test File', $result );
- $this->assertStringContainsString( '', $result );
- $this->assertStringContainsString( 'row-actions', $result );
- $this->assertStringContainsString( 'edit', $result );
- $this->assertStringContainsString( 'delete', $result );
- }
-
- /**
- * Test column_default returns column value.
- */
- public function test_column_default() {
- $method = new ReflectionMethod( ExeLearning_Elp_List_Table::class, 'column_default' );
- $method->setAccessible( true );
-
- $item = array(
- 'date' => '2025-01-01',
- 'status' => 'Active',
- );
- $result = $method->invoke( $this->list_table, $item, 'date' );
-
- $this->assertEquals( '2025-01-01', $result );
- }
-
- /**
- * Test column_default returns empty for unknown column.
- */
- public function test_column_default_unknown() {
- $method = new ReflectionMethod( ExeLearning_Elp_List_Table::class, 'column_default' );
- $method->setAccessible( true );
-
- $item = array( 'date' => '2025-01-01' );
- $result = $method->invoke( $this->list_table, $item, 'unknown' );
-
- $this->assertEquals( '', $result );
- }
-
- /**
- * Test class extends WP_List_Table.
- */
- public function test_extends_wp_list_table() {
- $this->assertInstanceOf( WP_List_Table::class, $this->list_table );
- }
-}
diff --git a/tests/unit/ExeLearningTest.php b/tests/unit/ExeLearningTest.php
index 656bc69..ebd1921 100644
--- a/tests/unit/ExeLearningTest.php
+++ b/tests/unit/ExeLearningTest.php
@@ -34,13 +34,6 @@ public function test_plugin_instantiation() {
$this->assertInstanceOf( ExeLearning::class, $this->plugin );
}
- /**
- * Test run method exists.
- */
- public function test_run_method_exists() {
- $this->assertTrue( method_exists( $this->plugin, 'run' ) );
- }
-
/**
* Read an instantiated component from the plugin's component registry.
*
@@ -54,20 +47,6 @@ private function get_component( $key ) {
return isset( $components[ $key ] ) ? $components[ $key ] : null;
}
- /**
- * Test hooks component is initialized.
- */
- public function test_hooks_initialized() {
- $this->assertInstanceOf( ExeLearning_Hooks::class, $this->get_component( 'hooks' ) );
- }
-
- /**
- * Test filters component is initialized.
- */
- public function test_filters_initialized() {
- $this->assertInstanceOf( ExeLearning_Filters::class, $this->get_component( 'filters' ) );
- }
-
/**
* Test mime_types component is initialized.
*/
@@ -175,5 +154,4 @@ public function test_admin_styles_component_is_admin_only() {
$this->assertInstanceOf( ExeLearning_Admin_Styles::class, $components['admin_styles'] );
}
-
}
diff --git a/tests/unit/FiltersTest.php b/tests/unit/FiltersTest.php
deleted file mode 100644
index 699e09b..0000000
--- a/tests/unit/FiltersTest.php
+++ /dev/null
@@ -1,204 +0,0 @@
-filters = new ExeLearning_Filters();
- }
-
- /**
- * Test register_filters adds filter.
- */
- public function test_register_filters_adds_filter() {
- $this->filters->register_filters();
-
- $this->assertGreaterThan(
- 0,
- has_filter( 'wp_get_attachment_metadata', array( $this->filters, 'filter_attachment_metadata' ) )
- );
- }
-
- /**
- * Test filter_attachment_metadata returns metadata unchanged for non-elp.
- */
- public function test_filter_attachment_metadata_unchanged_for_non_elp() {
- $attachment_id = $this->factory->attachment->create();
- $metadata = array( 'width' => 100, 'height' => 100 );
-
- $result = $this->filters->filter_attachment_metadata( $metadata, $attachment_id );
-
- $this->assertEquals( $metadata, $result );
- }
-
- /**
- * Test filter_attachment_metadata handles empty attachment_id.
- */
- public function test_filter_attachment_metadata_handles_empty_id() {
- $metadata = array( 'test' => 'value' );
-
- $result = $this->filters->filter_attachment_metadata( $metadata, 0 );
-
- $this->assertEquals( $metadata, $result );
- }
-
- /**
- * Test filter_attachment_metadata handles null attachment_id.
- */
- public function test_filter_attachment_metadata_handles_null_id() {
- $metadata = array( 'test' => 'value' );
-
- $result = $this->filters->filter_attachment_metadata( $metadata, null );
-
- $this->assertEquals( $metadata, $result );
- }
-
- /**
- * Test filter_attachment_metadata handles non-numeric attachment_id.
- */
- public function test_filter_attachment_metadata_handles_non_numeric_id() {
- $metadata = array( 'test' => 'value' );
-
- $result = $this->filters->filter_attachment_metadata( $metadata, 'invalid' );
-
- $this->assertEquals( $metadata, $result );
- }
-
- /**
- * Test is_elp_file method is private.
- */
- public function test_is_elp_file_is_private() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $this->assertTrue( $method->isPrivate() );
- }
-
- /**
- * Test is_elp_file returns true for elpx files.
- */
- public function test_is_elp_file_returns_true_for_elpx() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- $this->assertTrue( $method->invoke( $this->filters, '/path/to/file.elpx' ) );
- }
-
- /**
- * Test is_elp_file returns false for non-elp files.
- */
- public function test_is_elp_file_returns_false_for_other() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- $this->assertFalse( $method->invoke( $this->filters, '/path/to/file.pdf' ) );
- $this->assertFalse( $method->invoke( $this->filters, '/path/to/file.zip' ) );
- }
-
- /**
- * Test is_elp_file handles null input.
- */
- public function test_is_elp_file_handles_null() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- $this->assertFalse( $method->invoke( $this->filters, null ) );
- }
-
- /**
- * Test is_elp_file handles empty string.
- */
- public function test_is_elp_file_handles_empty() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- $this->assertFalse( $method->invoke( $this->filters, '' ) );
- }
-
- /**
- * Test filter_attachment_metadata adds exelearning key for elpx files.
- */
- public function test_filter_attachment_metadata_adds_key_for_elpx() {
- $attachment_id = $this->factory->attachment->create();
-
- // Create a temp elpx file.
- $upload_dir = wp_upload_dir();
- $file_path = $upload_dir['basedir'] . '/test-filter-' . $attachment_id . '.elpx';
- file_put_contents( $file_path, 'test content' );
-
- update_attached_file( $attachment_id, $file_path );
-
- $metadata = array( 'width' => 100 );
- $result = $this->filters->filter_attachment_metadata( $metadata, $attachment_id );
-
- $this->assertArrayHasKey( 'exelearning', $result );
- $this->assertEquals( 'elp file metadata', $result['exelearning'] );
-
- unlink( $file_path );
- }
-
- /**
- * Test filter_attachment_metadata preserves existing metadata.
- */
- public function test_filter_attachment_metadata_preserves_existing() {
- $attachment_id = $this->factory->attachment->create();
-
- $upload_dir = wp_upload_dir();
- $file_path = $upload_dir['basedir'] . '/test-preserve-' . $attachment_id . '.elpx';
- file_put_contents( $file_path, 'test content' );
-
- update_attached_file( $attachment_id, $file_path );
-
- $metadata = array(
- 'width' => 100,
- 'height' => 200,
- );
- $result = $this->filters->filter_attachment_metadata( $metadata, $attachment_id );
-
- $this->assertEquals( 100, $result['width'] );
- $this->assertEquals( 200, $result['height'] );
- $this->assertArrayHasKey( 'exelearning', $result );
-
- unlink( $file_path );
- }
-
- /**
- * Test is_elp_file returns true for elp extension.
- */
- public function test_is_elp_file_returns_false_for_elp() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- // The function only returns true for elpx, not elp.
- $this->assertFalse( $method->invoke( $this->filters, '/path/to/file.elp' ) );
- }
-
- /**
- * Test is_elp_file case insensitive.
- */
- public function test_is_elp_file_case_insensitive() {
- $method = new ReflectionMethod( ExeLearning_Filters::class, 'is_elp_file' );
- $method->setAccessible( true );
-
- $this->assertTrue( $method->invoke( $this->filters, '/path/to/FILE.ELPX' ) );
- $this->assertTrue( $method->invoke( $this->filters, '/path/to/file.Elpx' ) );
- }
-}
diff --git a/tests/unit/HooksTest.php b/tests/unit/HooksTest.php
deleted file mode 100644
index 9fb333d..0000000
--- a/tests/unit/HooksTest.php
+++ /dev/null
@@ -1,74 +0,0 @@
-hooks = new ExeLearning_Hooks();
- }
-
- /**
- * Test register_hooks method exists and is callable.
- */
- public function test_register_hooks_exists() {
- $this->assertTrue( method_exists( $this->hooks, 'register_hooks' ) );
- }
-
- /**
- * Test register_hooks does not register the legacy public CPT.
- *
- * The boilerplate `exelearning` custom post type was removed: the plugin
- * works with attachments only and must not expose a public post type.
- */
- public function test_register_hooks_does_not_register_cpt() {
- if ( post_type_exists( 'exelearning' ) ) {
- unregister_post_type( 'exelearning' );
- }
-
- // register_hooks() must not register any init callback that creates the CPT.
- // (We avoid firing do_action('init') here because that would re-run the
- // whole init chain, including block registration, and trip WP's
- // already-registered incorrect-usage notice.)
- $this->hooks->register_hooks();
-
- $this->assertFalse( post_type_exists( 'exelearning' ) );
- $this->assertFalse( has_action( 'init', array( $this->hooks, 'register_custom_post_type' ) ) );
- }
-
- /**
- * Test register_hooks does not add a the_content filter.
- */
- public function test_register_hooks_adds_no_content_filter() {
- $this->hooks->register_hooks();
-
- $this->assertFalse( has_filter( 'the_content', array( $this->hooks, 'modify_content' ) ) );
- }
-
- /**
- * Test the removed boilerplate methods no longer exist.
- */
- public function test_legacy_methods_removed() {
- $this->assertFalse( method_exists( $this->hooks, 'register_custom_post_type' ) );
- $this->assertFalse( method_exists( $this->hooks, 'modify_content' ) );
- }
-}
diff --git a/tests/unit/PostTypesTest.php b/tests/unit/PostTypesTest.php
deleted file mode 100644
index 7b2681f..0000000
--- a/tests/unit/PostTypesTest.php
+++ /dev/null
@@ -1,55 +0,0 @@
-post_types = new ExeLearning_Post_Types();
- }
-
- /**
- * Test register_post_types method exists.
- */
- public function test_register_post_types_exists() {
- $this->assertTrue( method_exists( $this->post_types, 'register_post_types' ) );
- }
-
- /**
- * The plugin deliberately registers no custom post type: ELP packages are
- * WordPress attachments and their metadata lives in attachment post meta.
- * This guards that decision — registering one here would silently change
- * where content is stored.
- */
- public function test_register_post_types_registers_no_custom_post_type() {
- $before = get_post_types( array(), 'names' );
-
- $this->post_types->register_post_types();
-
- $this->assertSame(
- array(),
- array_values( array_diff( get_post_types( array(), 'names' ), $before ) ),
- 'register_post_types() must not register any post type.'
- );
- $this->assertFalse( post_type_exists( 'exelearning' ) );
- }
-}
diff --git a/tests/unit/RestApiTest.php b/tests/unit/RestApiTest.php
index 2cd3225..6388e85 100644
--- a/tests/unit/RestApiTest.php
+++ b/tests/unit/RestApiTest.php
@@ -1824,149 +1824,6 @@ public function test_validate_elp_file_path_missing() {
$this->assertEquals( 'file_not_found', $result->get_error_code() );
}
- /**
- * Test cleanup_old_extraction with no extraction.
- */
- public function test_cleanup_old_extraction_no_extraction() {
- $attachment_id = $this->factory->attachment->create();
-
- // No extraction metadata set.
- $reflection = new ReflectionMethod( $this->rest_api, 'cleanup_old_extraction' );
- $reflection->setAccessible( true );
-
- // Should not throw any errors.
- $result = $reflection->invoke( $this->rest_api, $attachment_id );
-
- $this->assertNull( $result );
- }
-
- /**
- * Test cleanup_old_extraction with existing folder.
- */
- public function test_cleanup_old_extraction_with_folder() {
- $attachment_id = $this->factory->attachment->create();
-
- $upload_dir = wp_upload_dir();
- $hash = str_repeat( 'c', 40 );
- $folder = trailingslashit( $upload_dir['basedir'] ) . 'exelearning/' . $hash . '/';
-
- wp_mkdir_p( $folder );
- file_put_contents( $folder . 'test.html', '' );
- $this->cleanup_paths[] = $folder;
-
- update_post_meta( $attachment_id, '_exelearning_extracted', $hash );
-
- $this->assertTrue( is_dir( $folder ) );
-
- $reflection = new ReflectionMethod( $this->rest_api, 'cleanup_old_extraction' );
- $reflection->setAccessible( true );
-
- $reflection->invoke( $this->rest_api, $attachment_id );
-
- $this->assertFalse( is_dir( $folder ) );
- }
-
- /**
- * Test cleanup_old_extraction with non-existent folder.
- */
- public function test_cleanup_old_extraction_nonexistent_folder() {
- $attachment_id = $this->factory->attachment->create();
-
- $hash = str_repeat( 'd', 40 );
- update_post_meta( $attachment_id, '_exelearning_extracted', $hash );
-
- $reflection = new ReflectionMethod( $this->rest_api, 'cleanup_old_extraction' );
- $reflection->setAccessible( true );
-
- // Should not throw any errors.
- $result = $reflection->invoke( $this->rest_api, $attachment_id );
-
- $this->assertNull( $result );
- }
-
- /**
- * Test recursive_delete with non-existent path.
- */
- public function test_recursive_delete_nonexistent() {
- $reflection = new ReflectionMethod( $this->rest_api, 'recursive_delete' );
- $reflection->setAccessible( true );
-
- // Should not throw any errors.
- $result = $reflection->invoke( $this->rest_api, '/nonexistent/path/to/delete' );
-
- $this->assertNull( $result );
- }
-
- /**
- * Test recursive_delete with file.
- */
- public function test_recursive_delete_file() {
- $upload_dir = wp_upload_dir();
- $file_path = $upload_dir['basedir'] . '/test-delete-file.txt';
- file_put_contents( $file_path, 'test content' );
-
- $this->assertTrue( file_exists( $file_path ) );
-
- $reflection = new ReflectionMethod( $this->rest_api, 'recursive_delete' );
- $reflection->setAccessible( true );
-
- $reflection->invoke( $this->rest_api, $file_path );
-
- $this->assertFalse( file_exists( $file_path ) );
- }
-
- /**
- * Test recursive_delete with nested directory.
- */
- public function test_recursive_delete_nested_directory() {
- $upload_dir = wp_upload_dir();
- $base_dir = $upload_dir['basedir'] . '/test-nested-delete/';
- $sub_dir = $base_dir . 'subdir/';
-
- wp_mkdir_p( $sub_dir );
- file_put_contents( $base_dir . 'file1.txt', 'content1' );
- file_put_contents( $sub_dir . 'file2.txt', 'content2' );
-
- $this->assertTrue( is_dir( $base_dir ) );
- $this->assertTrue( is_dir( $sub_dir ) );
-
- $reflection = new ReflectionMethod( $this->rest_api, 'recursive_delete' );
- $reflection->setAccessible( true );
-
- $reflection->invoke( $this->rest_api, $base_dir );
-
- $this->assertFalse( is_dir( $base_dir ) );
- }
-
- /**
- * Test recursive_delete with symlink.
- */
- public function test_recursive_delete_symlink() {
- $upload_dir = wp_upload_dir();
- $target_file = $upload_dir['basedir'] . '/symlink-target.txt';
- $symlink = $upload_dir['basedir'] . '/test-symlink';
-
- file_put_contents( $target_file, 'target content' );
-
- // Create symlink if supported.
- if ( @symlink( $target_file, $symlink ) ) {
- $this->assertTrue( is_link( $symlink ) );
-
- $reflection = new ReflectionMethod( $this->rest_api, 'recursive_delete' );
- $reflection->setAccessible( true );
-
- $reflection->invoke( $this->rest_api, $symlink );
-
- $this->assertFalse( is_link( $symlink ) );
- // Target should still exist.
- $this->assertTrue( file_exists( $target_file ) );
- }
-
- if ( file_exists( $target_file ) ) {
- unlink( $target_file );
- }
- }
-
/**
* Test ensure_elpx_extension normalizes any filename to .elpx.
*
diff --git a/tests/unit/UninstallTest.php b/tests/unit/UninstallTest.php
new file mode 100644
index 0000000..f7d5476
--- /dev/null
+++ b/tests/unit/UninstallTest.php
@@ -0,0 +1,41 @@
+assertFalse( get_option( $option ), $option . ' survived uninstall.' );
+ }
+ $this->assertSame( 'Kept', get_option( 'blogname' ) );
+ }
+}
diff --git a/uninstall.php b/uninstall.php
index dfac54a..be39e4c 100644
--- a/uninstall.php
+++ b/uninstall.php
@@ -2,21 +2,8 @@
/**
* Fired when the plugin is uninstalled.
*
- * When populating this file, consider the following flow
- * of control:
- *
- * - This method should be static
- * - Check if the $_REQUEST content actually is the plugin name
- * - Run an admin referrer check to make sure it goes through authentication
- * - Verify the output of $_GET makes sense
- * - Repeat with other user roles. Best directly by using the links/query string parameters.
- * - Repeat things for multisite. Once for a single site in the network, once sitewide.
- *
- * This file may be updated more in future version of the Boilerplate; however, this is the
- * general skeleton and outline for how the file should work.
- *
- * For more information, see the following discussion:
- * https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate/pull/123#issuecomment-28541913
+ * Removes the plugin's settings. Uploaded .elpx attachments, their extracted
+ * content and uploaded style packages are user content and are left in place.
*
* @link https://www3.gobiernodecanarias.org/medusa/ecoescuela/ate/
*
@@ -27,3 +14,35 @@
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
exit;
}
+
+/**
+ * Delete the plugin's options on the current site.
+ */
+function exelearning_uninstall_site() {
+ $options = array(
+ 'exelearning_db_version',
+ 'exelearning_disabled_styles',
+ 'exelearning_proxy_assets',
+ 'exelearning_styles_block_import',
+ 'exelearning_styles_registry',
+ );
+ foreach ( $options as $option ) {
+ delete_option( $option );
+ }
+}
+
+if ( is_multisite() ) {
+ $exelearning_site_ids = get_sites(
+ array(
+ 'fields' => 'ids',
+ 'number' => 0, // WP_Site_Query stops at 100 sites by default.
+ )
+ );
+ foreach ( $exelearning_site_ids as $exelearning_site_id ) {
+ switch_to_blog( $exelearning_site_id );
+ exelearning_uninstall_site();
+ restore_current_blog();
+ }
+} else {
+ exelearning_uninstall_site();
+}