Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
35.71% covered (danger)
35.71%
10 / 28
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
FileExtractor
35.71% covered (danger)
35.71%
10 / 28
0.00% covered (danger)
0.00%
0 / 4
84.01
0.00% covered (danger)
0.00%
0 / 1
 extract
72.73% covered (warning)
72.73%
8 / 11
0.00% covered (danger)
0.00%
0 / 1
9.30
 extract_zip
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 extract_tar
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 ensure_dir_exists
50.00% covered (danger)
50.00%
2 / 4
0.00% covered (danger)
0.00%
0 / 1
4.12
1<?php
2/**
3 * FileExtractor file.
4 *
5 * @package wpcomsh
6 */
7
8namespace Imports\Utils;
9
10use WP_Error;
11/**
12 * Class FileExtractor
13 *
14 * This class is responsible for extracting files from a ZIP or TAR archive.
15 */
16class FileExtractor {
17    /**
18     * Extract the contents of a file to a destination directory.
19     *
20     * @param string $file The path to the file to extract.
21     * @param string $destination The path to the directory where the file should be extracted.
22     * @return bool|WP_Error True on success, or a WP_Error on failure.
23     */
24    public static function extract( $file, $destination ) {
25        $extension = pathinfo( $file, PATHINFO_EXTENSION );
26
27        // Check if the file exists.
28        if ( ! is_file( $file ) || ! is_readable( $file ) ) {
29            return new WP_Error( 'file_not_exists', __( 'File not exists', 'wpcomsh' ) );
30        }
31
32        if ( ! self::ensure_dir_exists( $destination ) ) {
33            return new WP_Error( 'dest_dir_not_created', __( 'Could not create folder', 'wpcomsh' ) );
34        }
35
36        switch ( $extension ) {
37            case 'zip':
38                return self::extract_zip( $file, $destination );
39            case 'tar':
40            case 'gz':
41                return self::extract_tar( $file, $destination );
42            default:
43                return new WP_Error( 'file_type_not_supported', __( 'File type is not supported', 'wpcomsh' ) );
44        }
45    }
46
47    /**
48     * Extract the contents of a ZIP file to a destination directory.
49     *
50     * @param string $file The path to the ZIP file to extract.
51     * @param string $destination The path to the directory where the ZIP file should be extracted.
52     * @return bool|WP_Error True on success, or a WP_Error on failure.
53     */
54    private static function extract_zip( string $file, string $destination ) {
55        $zip = new \ZipArchive();
56        if ( $zip->open( $file ) !== true ) {
57            return new WP_Error( 'zipfile_open_failure', __( 'The ZIP file could not be opened.', 'wpcomsh' ) );
58        }
59
60        $extracted = $zip->extractTo( $destination );
61        $zip->close();
62
63        if ( ! $extracted ) {
64            return new WP_Error( 'zipfile_extract_failure', __( 'The ZIP file could not be extracted.', 'wpcomsh' ) );
65        }
66        return true;
67    }
68
69    /**
70     * Extract the contents of a tar file to a destination directory.
71     *
72     * @param string $file The path to the tar file to extract.
73     * @param string $destination The path to the directory where the tar file should be extracted.
74     * @return bool|WP_Error True on success, or a WP_Error on failure.
75     */
76    private static function extract_tar( string $file, string $destination ) {
77        // For .tar and .tar.gz files, we'll use the PharData class
78        try {
79            $phar = new \PharData( $file );
80            $phar->extractTo( $destination );
81        } catch ( \Exception $e ) {
82            return new WP_Error( 'phar_extract_failure', __( 'The TAR file could not be extracted.', 'wpcomsh' ) );
83        }
84        return true;
85    }
86
87    /**
88     * Ensure directory exists.
89     *
90     * @param string $dir Directory to ensure the existence of.
91     * @return bool Whether the existence could be asserted.
92     */
93    private static function ensure_dir_exists( $dir ) {
94        if ( ! is_dir( $dir ) ) {
95            if ( ! wp_mkdir_p( $dir ) ) {
96                return false;
97            }
98        }
99        return true;
100    }
101}