Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate WordPress block asset files from PHP to JSON format #1656

Merged
merged 45 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8bd1f16
Improve unzipping compat
josephfusco Nov 15, 2023
0b20557
Fix liniting issues
josephfusco Nov 15, 2023
dba8bfb
Fix liniting issues
josephfusco Nov 15, 2023
edaf855
Fix linting issues
josephfusco Nov 15, 2023
8fa6d13
Clean up unused functions & tests
josephfusco Nov 16, 2023
2fccd87
Add test coverage
josephfusco Nov 16, 2023
ff54a08
Match parent class
josephfusco Nov 16, 2023
afc7efc
Fix PSR-4 warning
josephfusco Nov 16, 2023
463d8a3
Improve block tests
josephfusco Nov 16, 2023
1c5fc5f
Attempt to fix failing test config
josephfusco Nov 16, 2023
db48bb9
failing tests
josephfusco Nov 16, 2023
8091a3a
Update tests
josephfusco Nov 16, 2023
c1d73f7
Fix refactoring issues
josephfusco Nov 16, 2023
01a2974
Explicitly require patchwork
josephfusco Nov 16, 2023
dd101ce
Require patchwork before anything else
josephfusco Nov 16, 2023
ff29ebc
Correct path to Patchwork
josephfusco Nov 16, 2023
bb04e39
Attempt to resolve failing E2E tests
josephfusco Nov 16, 2023
9b3371a
Scope requiring patchwork to it’s relevant class
josephfusco Nov 16, 2023
a3c525d
Revert "Scope requiring patchwork to it’s relevant class"
josephfusco Nov 16, 2023
33358a7
Avoid polluting codeception env with Patchwork
josephfusco Nov 16, 2023
d08068e
Conditionally load patchwork package via env
josephfusco Nov 16, 2023
fba8da2
Only update antecedent/patchwork in lockfile
josephfusco Nov 16, 2023
de8b873
Clean up refactor
josephfusco Nov 16, 2023
f20b5f4
Use our own directories method
josephfusco Nov 16, 2023
10c1415
Update tests to reflect function argument changes
josephfusco Nov 16, 2023
7352acc
Clean up
josephfusco Nov 17, 2023
cfd6db9
Revert "Clean up"
josephfusco Nov 17, 2023
653a8fa
Merge branch 'canary' into fix/blockset-issue-1633
josephfusco Nov 28, 2023
01118f5
Prevent .php inclusion as faust handles dependencies
josephfusco Nov 28, 2023
e572b44
Update block-support example deps
josephfusco Nov 28, 2023
efd388b
Ensure --webpack-no-externals is used to remove generated php
josephfusco Nov 28, 2023
cc4bfa0
leave wp deps alone
josephfusco Nov 28, 2023
6e70451
Remove problematic CLI flag
josephfusco Nov 29, 2023
93f9085
Handle PHP block files in the CLI w/ tests
josephfusco Nov 29, 2023
cada1d6
Resolve linting errors
josephfusco Nov 29, 2023
d4a3ba0
Clean up logging
josephfusco Nov 30, 2023
abcf8c9
Resolve phpcs issue
josephfusco Nov 30, 2023
9484a73
Resolve phpcs issue
josephfusco Nov 30, 2023
fbeadba
Fix asset loading
josephfusco Nov 30, 2023
f4e54f2
Merge branch 'canary' into fix/blockset-issue-1633
josephfusco Dec 1, 2023
c9894ab
Sync lockfile
josephfusco Dec 1, 2023
5cd554d
Resolve linting issues
josephfusco Dec 1, 2023
3633917
Merge branch 'canary' into fix/blockset-issue-1633
josephfusco Dec 6, 2023
44a254c
Fix linting warnings
josephfusco Dec 13, 2023
42e0f85
Update lockfile
josephfusco Dec 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/slow-mayflies-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@faustwp/wordpress-plugin': patch
---

Improved plugin's process for handling blockset file uploads by leveraging WordPress' native [unzip_file](https://developer.wordpress.org/reference/functions/unzip_file/) function.
163 changes: 125 additions & 38 deletions plugins/faustwp/includes/blocks/functions.php
Original file line number Diff line number Diff line change
@@ -1,70 +1,157 @@
<?php
/**
* Functions related to block support.
* Block support functions for FaustWP.
*
* @package FaustWP
*/

namespace WPE\FaustWP\Blocks;

use function WPE\FaustWP\Utilities\{
rrmdir,
unzip_to_directory,
};
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}
require_once ABSPATH . 'wp-admin/includes/file.php';

/**
* Handle the uploaded blockset file and unzip it.
* Returns true upon success.
* Handles the uploaded blockset file and unzips it.
*
* @param array $file The uploaded file details.
* @return \WP_Error|bool
* @return WP_Error|bool
*/
function handle_uploaded_blockset( $file ) {
// Ensure ZipArchive class is available.
if ( ! class_exists( 'ZipArchive' ) ) {
return new \WP_Error( 'ziparchive_missing', __( 'The ZipArchive class is not available', 'faustwp' ) );
global $wp_filesystem;
WP_Filesystem();

$error = validate_uploaded_file( $wp_filesystem, $file );
if ( $error ) {
josephfusco marked this conversation as resolved.
Show resolved Hide resolved
return $error;
}

// Check if it's a zip file.
if ( 'application/zip' !== $file['type'] ) {
return new \WP_Error( 'wrong_type', __( 'Not a zip file', 'faustwp' ) );
$dirs = define_directories();
$error = ensure_directories_exist( $wp_filesystem, $dirs );
if ( $error ) {
return $error;
}

// Define directories.
$upload_dir = wp_upload_dir();
$target_dir = trailingslashit( $upload_dir['basedir'] ) . 'faustwp/';
$blocks_dir = $target_dir . 'blocks/';
$tmp_dir = $target_dir . 'tmp_blocks/';
return process_and_replace_blocks( $wp_filesystem, $file, $dirs );
}

// Ensure temporary directory exists.
if ( ! file_exists( $tmp_dir ) && ! wp_mkdir_p( $tmp_dir ) ) {
return new \WP_Error( 'mkdir_error', __( 'Could not create temporary directory', 'faustwp' ) );
/**
* Processes the uploaded blockset file, unzips it, and replaces the old blocks directory.
*
* @param WP_Filesystem_Base $wp_filesystem Filesystem object.
* @param array $file The uploaded file details.
* @param array $dirs Directories array.
* @return WP_Error|bool True on success, WP_Error on failure.
*/
function process_and_replace_blocks( $wp_filesystem, $file, $dirs ) {
$target_file = $dirs['target'] . sanitize_file_name( basename( $file['name'] ) );
josephfusco marked this conversation as resolved.
Show resolved Hide resolved

$move_result = move_uploaded_file( $wp_filesystem, $file, $target_file );
if ( is_wp_error( $move_result ) ) {
return $move_result;
}

// Move the uploaded file.
$target_file = $target_dir . sanitize_file_name( basename( $file['name'] ) );
if ( ! move_uploaded_file( $file['tmp_name'], $target_file ) ) {
return new \WP_Error( 'move_error', __( 'Could not move uploaded file', 'faustwp' ) );
$unzip_result = unzip_uploaded_file( $target_file, $dirs['blocks'] );
if ( is_wp_error( $unzip_result ) ) {
return $unzip_result;
}

// Unzip the file to the temporary directory.
if ( ! unzip_to_directory( $target_file, $tmp_dir ) ) {
rrmdir( $tmp_dir ); // Cleanup the temporary directory in case of unzip failure.
return new \WP_Error( 'unzip_error', __( 'Could not unzip the file', 'faustwp' ) );
cleanup_temp_directory( $wp_filesystem, $dirs['temp'] );

return true;
}

/**
* Validates the uploaded file type and readability.
*
* @param WP_Filesystem_Base $wp_filesystem Filesystem object.
* @param array $file The uploaded file details.
* @return WP_Error|bool
*/
function validate_uploaded_file( $wp_filesystem, $file ) {
if ( 'application/zip' !== $file['type'] ) {
return new WP_Error( 'wrong_type', esc_html__( 'Not a zip file', 'faustwp' ) );
}

if ( ! $wp_filesystem->is_readable( $file['tmp_name'] ) ) {
return new WP_Error( 'file_read_error', esc_html__( 'Uploaded file is not readable', 'faustwp' ) );
}

// Replace the old blocks directory with the new content.
if ( is_dir( $blocks_dir ) ) {
rrmdir( $blocks_dir );
return true;
josephfusco marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Defines and returns necessary directories for file processing.
*
* @return array
*/
function define_directories() {
$upload_dir = wp_upload_dir();
$base_dir = trailingslashit( $upload_dir['basedir'] ) . trailingslashit( FAUSTWP_SLUG );

return array(
'target' => $base_dir . 'blocks',
'temp' => $base_dir . 'tmp_blocks',
);
}

/**
* Ensures that the necessary directories exist.
*
* @param WP_Filesystem_Base $wp_filesystem Filesystem object.
* @param array $dirs Directories array.
* @return WP_Error|true
*/
function ensure_directories_exist( $wp_filesystem, $dirs ) {
foreach ( $dirs as $dir ) {
if ( ! $wp_filesystem->is_dir( $dir ) && ! $wp_filesystem->mkdir( $dir, FS_CHMOD_DIR ) ) {
/* translators: %s: directory path */
return new WP_Error( 'mkdir_error', sprintf( esc_html__( 'Could not create directory: %s', 'faustwp' ), $dir ) );
}
}

if ( ! rename( $tmp_dir, $blocks_dir ) ) {
return new \WP_Error( 'rename_error', __( 'Could not rename the directory', 'faustwp' ) );
return true;
josephfusco marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Moves the uploaded file to the target directory.
*
* @param WP_Filesystem_Base $wp_filesystem Filesystem object.
* @param array $file The uploaded file details.
* @param string $target_file The target file path.
* @return WP_Error|bool True on success, WP_Error on failure.
*/
function move_uploaded_file( WP_Filesystem_Base $wp_filesystem, $file, $target_file ) {
if ( ! $wp_filesystem->move( $file['tmp_name'], $target_file, true ) ) {
return new WP_Error( 'move_error', esc_html__( 'Could not move uploaded file', 'faustwp' ) );
}
return true;
}

/**
* Unzips the uploaded file.
*
* @param string $target_file The target file path.
* @param string $destination The destination directory for unzipping.
* @return WP_Error|bool True on success, WP_Error on failure.
*/
function unzip_uploaded_file( $target_file, $destination ) {
$unzip_result = unzip_file( $target_file, $destination );
if ( is_wp_error( $unzip_result ) ) {
return $unzip_result;
}
return true;
}

/**
* Cleans up temporary files or directories.
*
* @param WP_Filesystem_Base $wp_filesystem Filesystem object.
* @param string $temp_dir The temporary directory path.
* @return void
*/
function cleanup_temp_directory( WP_Filesystem_Base $wp_filesystem, $temp_dir ) {
if ( $wp_filesystem->is_dir( $temp_dir ) ) {
$wp_filesystem->delete( $temp_dir, true );
}
}
46 changes: 0 additions & 46 deletions plugins/faustwp/includes/utilities/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,49 +43,3 @@ function plugin_version() {

return $plugin['Version'];
}

/**
* Unzip a file to a specified directory.
*
* @param string $file_path Path to the zip file.
* @param string $destination Directory to unzip to.
* @return bool True on success, false on failure.
*/
function unzip_to_directory( $file_path, $destination ) {
$zip = new \ZipArchive();
if ( true !== $zip->open( $file_path ) ) {
return false;
}

$zip->extractTo( $destination );
$zip->close();
unlink( $file_path ); // Delete the zip file.

return true;
}

/**
* Recursive function to remove a directory and its contents.
*
* @param string $dir Directory path.
*/
function rrmdir( $dir ) {
if ( ! is_dir( $dir ) ) {
return;
}

$objects = scandir( $dir );
foreach ( $objects as $object ) {
if ( '.' === $object || '..' === $object ) {
continue;
}

$item_path = $dir . '/' . $object;
if ( is_dir( $item_path ) ) {
rrmdir( $item_path );
} else {
unlink( $item_path );
}
}
rmdir( $dir );
}
61 changes: 1 addition & 60 deletions plugins/faustwp/tests/integration/UtilitiesFunctionsTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,18 @@
/**
* Class UtilitiesTest
*/
class UtilitiesTest extends \WP_UnitTestCase {
/**
* Path to the test directory.
*
* @var string
*/
private $testDir;

/**
* Path to the test zip file.
*
* @var string
*/
private $testZip;

class UtilitiesFunctionsTests extends \WP_UnitTestCase {
/**
* Setup runs before every test.
*/
protected function setUp(): void {
parent::setUp();

$this->testDir = sys_get_temp_dir() . '/faustwp_test_directory';
$this->testZip = sys_get_temp_dir() . '/test.zip';
}

/**
* Cleanup runs after every test.
*/
protected function tearDown(): void {
if ( is_dir( $this->testDir ) ) {
Utilities\rrmdir( $this->testDir );
}

if ( file_exists( $this->testZip ) ) {
unlink( $this->testZip );
}

parent::tearDown();
}

Expand All @@ -70,38 +45,4 @@ public function testPluginVersion() {
// This test assumes FAUSTWP_FILE is defined correctly.
$this->assertIsString( Utilities\plugin_version() );
}

/**
* Test the unzip_to_directory function.
*/
public function testUnzipToDirectory() {
// Create a dummy zip file for testing.
$zip = new \ZipArchive();
$zip->open( $this->testZip, \ZipArchive::CREATE );
$zip->addFromString( 'testfile.txt', 'Test content' );
$zip->close();

$this->assertTrue( Utilities\unzip_to_directory( $this->testZip, $this->testDir ) );
$this->assertFileExists( $this->testDir . '/testfile.txt' );
$this->assertFalse( file_exists( $this->testZip ) );

// Test non-existent file.
$this->assertFalse( Utilities\unzip_to_directory( 'nonexistent.zip', $this->testDir ) );
}

/**
* Test the rrmdir function.
*/
public function testRrmdir() {
mkdir( $this->testDir . '/subdir', 0777, true );
touch( $this->testDir . '/file.txt' );
touch( $this->testDir . '/subdir/file2.txt' );

Utilities\rrmdir( $this->testDir );
$this->assertFalse( is_dir( $this->testDir ) );

// Test rrmdir on non-existent directory.
Utilities\rrmdir( $this->testDir );
$this->assertFalse( is_dir( $this->testDir ) );
}
}
Loading
Loading