# easy-invoice/2.4.1/includes/Controllers/ImportController.php

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.4.1. 190 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.4.1/code/includes/Controllers/ImportController.php
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.4.1/raw/includes/Controllers/ImportController.php
- Modified: 2026-09-15T12:31:20+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.4.1/code/includes/Controllers/ImportController.php#L10-L20`.

```php
<?php
/**
 * Import screen.
 *
 * @package Easy_Invoice
 * @subpackage Controllers
 */

namespace EasyInvoice\Controllers;

use EasyInvoice\Import\CsvImporter;
use EasyInvoice\Import\SlicedImporter;
use EasyInvoice\Import\SproutImporter;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * One screen: what is on this site that could be imported, a dry-run count
 * for each source, and a button that does it. CSV uploads go through the
 * same screen with template files to download.
 */
class ImportController {

    const PAGE_SLUG  = 'easy-invoice-import';
    const ACTION_RUN = 'easy_invoice_import_run';
    const ACTION_TPL = 'easy_invoice_import_template';

    public static function init(): void {
        add_action( 'admin_menu', [ __CLASS__, 'registerPage' ], 99 );
        add_action( 'easy_invoice_admin_main_content', [ __CLASS__, 'maybeRenderPage' ], 11 );
        add_action( 'admin_post_' . self::ACTION_RUN, [ __CLASS__, 'handleRun' ] );
        add_action( 'admin_post_' . self::ACTION_TPL, [ __CLASS__, 'handleTemplate' ] );
        add_filter( 'easy_invoice_self_rendering_pages', [ __CLASS__, 'claimPage' ] );
    }

    public static function claimPage( $slugs ): array {
        $slugs   = is_array( $slugs ) ? $slugs : [];
        $slugs[] = self::PAGE_SLUG;
        return $slugs;
    }

    public static function registerPage(): void {
        add_submenu_page( 'easy-invoice-hidden', __( 'Import', 'easy-invoice' ), __( 'Import', 'easy-invoice' ), 'manage_options', self::PAGE_SLUG, [ __CLASS__, 'renderShell' ] );
    }

    public static function renderShell(): void {
        include EASY_INVOICE_PLUGIN_DIR . 'templates/main-template.php';
    }

    /**
     * The importers that could run here, keyed by source.
     *
     * @return array<string,\EasyInvoice\Import\Importer>
     */
    public static function sources(): array {
        $sources = [
            'sliced' => new SlicedImporter(),
            'sprout' => new SproutImporter(),
        ];
        /**
         * Filter the available import sources.
         *
         * @param array $sources Importer instances keyed by source name.
         */
        return (array) apply_filters( 'easy_invoice_import_sources', $sources );
    }

    public static function maybeRenderPage( $page ): void {
        if ( self::PAGE_SLUG !== $page || ! current_user_can( 'manage_options' ) ) {
            return;
        }
        $sources  = self::sources();
        $previews = [];
        foreach ( $sources as $key => $importer ) {
            if ( $importer->available() ) {
                $previews[ $key ] = $importer->preview();
            }
        }
        $result = get_transient( 'easy_invoice_import_result_' . get_current_user_id() );
        delete_transient( 'easy_invoice_import_result_' . get_current_user_id() );

        include EASY_INVOICE_PLUGIN_DIR . 'templates/admin/import-page.php';
    }

    /**
     * Run an import.
     *
     * @return void
     */
    public static function handleRun(): void {
        check_admin_referer( self::ACTION_RUN );
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'You do not have permission to import.', 'easy-invoice' ), '', [ 'response' => 403 ] );
        }

        $source = isset( $_POST['source'] ) ? sanitize_key( $_POST['source'] ) : '';

        // Imports of any size take a while; never let the request die halfway.
        if ( function_exists( 'set_time_limit' ) ) {
            @set_time_limit( 0 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
        }
        wp_raise_memory_limit( 'admin' );

        if ( 'csv' === $source ) {
            $importer = new CsvImporter( self::uploaded( 'clients_csv' ), self::uploaded( 'invoices_csv' ) );
            if ( ! $importer->preview()['clients'] && ! $importer->preview()['invoices'] ) {
                self::finish( [ 'error' => __( 'Choose at least one CSV file with a header row.', 'easy-invoice' ) ] );
            }
        } else {
            $sources = self::sources();
            if ( ! isset( $sources[ $source ] ) ) {
                self::finish( [ 'error' => __( 'Unknown import source.', 'easy-invoice' ) ] );
            }
            $importer = $sources[ $source ];
        }

        $report = $importer->run();
        $report['label'] = $importer->label();

        /**
         * Fires after an import has run.
         *
         * @param string $source Source key.
         * @param array  $report Counts and notes.
         */
        do_action( 'easy_invoice_import_finished', $source, $report );

        self::finish( $report );
    }

    /**
     * Serve a CSV template.
     *
     * @return void
     */
    public static function handleTemplate(): void {
        check_admin_referer( self::ACTION_TPL );
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( '', '', [ 'response' => 403 ] );
        }
        $which = ( isset( $_GET['which'] ) && 'clients' === $_GET['which'] ) ? 'clients' : 'invoices';
        nocache_headers();
        header( 'Content-Type: text/csv; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename="easy-invoice-' . $which . '-template.csv"' );
        echo CsvImporter::template( $which ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV download.
        exit;
    }

    /**
     * Path of an uploaded CSV, moved into the uploads dir; '' when none.
     *
     * @param string $field Form field.
     * @return string
     */
    private static function uploaded( string $field ): string {
        if ( empty( $_FILES[ $field ]['tmp_name'] ) || UPLOAD_ERR_OK !== (int) ( $_FILES[ $field ]['error'] ?? 1 ) ) {
            return '';
        }
        if ( ! function_exists( 'wp_handle_upload' ) ) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
        }
        $moved = wp_handle_upload( $_FILES[ $field ], [ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- validated by wp_handle_upload.
            'test_form' => false,
            'mimes'     => [ 'csv' => 'text/csv', 'txt' => 'text/plain' ],
        ] );
        if ( ! is_array( $moved ) || ! empty( $moved['error'] ) || empty( $moved['file'] ) ) {
            return '';
        }
        // Delete after the request: the file has no reason to stay in the media folder.
        register_shutdown_function( static function () use ( $moved ) {
            wp_delete_file( $moved['file'] );
        } );
        return (string) $moved['file'];
    }

    /**
     * Stash the result and go back to the screen.
     *
     * @param array $report Report or ['error' => msg].
     * @return void
     */
    private static function finish( array $report ): void {
        set_transient( 'easy_invoice_import_result_' . get_current_user_id(), $report, 5 * MINUTE_IN_SECONDS );
        wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_SLUG ) );
        exit;
    }
}

```
