array( 'label' => __( 'LatePoint customer CSV (English headers)', 'abientot' ), 'kind' => 'customers', 'edition' => 'shared', 'extension' => 'csv' ), 'ssa_free_contacts_v1' => array( 'label' => __( 'Simply Schedule Appointments JSON (contacts only)', 'abientot' ), 'kind' => 'customers', 'edition' => 'shared', 'extension' => 'json' ) ); } public static function normalize( string $format, string $bytes, string $delimiter = ',' ): array { if ( $format === 'ssa_free_contacts_v1' ) { return \Abientot\Import\SourceAdapters\SSAFree::normalize( $bytes ); } if ( $format !== 'latepoint_customers_v1' ) { throw new \DomainException( 'import_source_format' ); } $parsed = Csv::parse( $bytes, $delimiter ); if ( $parsed['headers'] !== array( 'ID', 'Name', 'Phone', 'Email', 'Total Appointments', 'Next Appointment', 'Registered On' ) ) { throw new \DomainException( 'import_source_format' ); } $stream = fopen( 'php://temp', 'w+' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- In-memory php://temp stream for fputcsv(); no file is written. if ( ! $stream ) { throw new \RuntimeException( 'import_storage' ); } try { fputcsv( $stream, array( 'source_key', 'display_name', 'email', 'phone' ), ',', '"', '' ); $ids = array(); foreach ( $parsed['rows']as$row ) { $id = Service::integer( $row[0], 1 ); if ( isset( $ids[ $id ] ) ) { throw new \DomainException( 'import_duplicate_source' ); } $ids[ $id ] = true; $phone = $row[2]; if ( preg_match( "/^'\\+[0-9 ().-]{3,80}$/D", $phone ) ) { $phone = substr( $phone, 1 ); } // Only a syntactically international telephone escape is reversible. Do not // strip arbitrary spreadsheet escaping or interpret exported cells as code. $contact = array( 'source_key' => (string) $id, 'display_name' => $row[1], 'email' => $row[3], 'phone' => $phone ); Service::normalize( 'customers', $contact ); fputcsv( $stream, array_values( $contact ), ',', '"', '' ); } rewind( $stream ); $csv = stream_get_contents( $stream ); if ( ! is_string( $csv ) ) { throw new \RuntimeException( 'import_storage' ); } Csv::parse( $csv, ',' ); return array( 'csv' => $csv, 'metadata' => array( 'format' => 'latepoint_customers_v1', 'kind' => 'customers', 'edition' => 'shared', 'scope' => 'contacts_only' ) ); } finally { fclose( $stream ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Closes the in-memory php://temp stream. } } }