*/ 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; } }