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

Improve imports #15898

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open

Conversation

bryanlopezinc
Copy link
Contributor

PR Summary

  • Validate input options when importing items from the CLI.
  • Validate the import type to prevent errors when an invalid type is provided, applicable to both CLI and API endpoints.
  • Fixed an issue in the import command where a success message was returned even when the import file did not exist.
  • Remove the deprecated method fetchOne

Checklist:

@bryanlopezinc bryanlopezinc requested a review from snipe as a code owner November 28, 2024 10:52
Copy link

what-the-diff bot commented Nov 28, 2024

PR Summary

  • Improved Import Command Functionality

    • The object import command has been refined. We added a mechanism that checks the validity of an import file to make sure it exists and follows the rules we set. This helps in avoiding faulty operations.
    • We've made it easier to create importers and included more detailed error messages if something goes wrong during the import.
  • New Factory Class

    • A new class called 'Factory' has been created. This is responsible for creating appropriate importer objects based on what type of item we're importing. So it's a smart way to keep our import operations flexible and manageable.
  • Constant Class for Mime Types

    • A new class accommodating supported types of import files has been created. It ensures we work with valid file types and helps avoid errors.
  • Defined Type of Importers

    • We have introduced a way to define valid types of importers and a function to obtain these types, making it easier for future command-line operations.
  • Improved Request Validation

    • The rules validating the types of items being imported have been improved. This ensures we only deal with valid items.
  • Upgraded Importer Class

    • Changes were made to the import method making it easier to recognize the header row, improving the efficiency of the import operation.
  • Added Tests

    • New tests were created to make sure our import command works well, which includes a variety of scenarios and checks. This will make it easier for us to catch any potential issues early on.
  • Code Cleanup

    • Some minor changes were made to improve the style of the code and the clarity of the comments.

@snipe snipe changed the title Impprove imports Improve imports Dec 2, 2024
@snipe
Copy link
Owner

snipe commented Dec 19, 2024

Hiya - looks like there's a merge conflict here - can you take a look?

Copy link
Collaborator

@uberbrady uberbrady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for this! Not a lot of people use the command-line importer, but for those that do, it's important that we don't break it - and especially with your new tests, that's going to be a lot less likely in the future. I did have a couple of small issues, mostly about bits of verbiage and naming of things (which, as you probably know, is one of the hardest problems in computer science). But let me know what you think about that feedback and how you want to go, and then we'll start to do some testing on our end so that we can get this merged. This is really lovely code, thank you so much for your contribution!

$importFile = new File(realpath($filepath), false);
$validator = Validator::make(
array_merge($this->options(), ['file' => $importFile]),
$this->rules(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only ever use the rules() function in one place, you could just embed them right here if you wanted. Not a dealbreaker though.

$validator = Validator::make(
array_merge($this->options(), ['file' => $importFile]),
$this->rules(),
$this->messages()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here with the messages, but again, not a dealbreaker.

['user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1],
['update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'],
['send-welcome', null, InputOption::VALUE_NONE, 'Whether to send a welcome email to any new users that are created.'],
['email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are <info>firstname.lastname</info>, <info>firstname</info>, <info>filastname</info>', null],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this <info> thing before in command-line stuff, but I'm sure it must work or you wouldn't have done it :) - but we'll be testing to see how it goes.

$class = ucfirst($import->import_type);
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$importer = Factory::make($filename, $this->input('import-type'));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, but the name Factory here is confusing since that's usually used in the context of testing. Additionally, I feel like, based on how simple the Factory is, it could be just a static method on the Importer class - but we can't call it factory() since that's actually used in testing. Maybe something like Importer::makeImporter()? But that sounds janky. Importer::makeSpecifcImporter? I dunno. But something along those lines should probably work better.

@@ -38,9 +40,8 @@ public function import(Import $import)

$filename = config('app.private_uploads').'/imports/'.$import->file_path;
$import->import_type = $this->input('import-type');
$class = ucfirst($import->import_type);
$classString = "App\\Importer\\{$class}Importer";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have always felt really uncomfortable with the way this works - I really appreciate that you took the time to fix it! Your way is so much better!

@@ -146,7 +146,7 @@ public function __construct($file)
*/
public function import()
{
$headerRow = $this->csv->fetchOne();
$headerRow = $this->csv->nth(0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really hate that the CSV people make us do this - but that's not your fault. I get the same deprecation warning in PHPStorm when I look at this line, so this is probably the right thing to do. Sigh.


namespace App\Importer;

class MimeTypes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another one that is only used once - so we could inline it above if we wanted. But if you have plans or ideas on how to re-use this file elsewhere in the system in the future then I'm fine with it being a separate file. Again, not a dealbreaker for me. (Just, when we're troubleshooting, we often don't like to have to be flipping back and forth between a bunch of files - and we do a LOT of troubleshooting).


namespace App\Importer;

enum Type: string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this being an enum, but I don't like the Type name here - it's just going to be too confusing. Can we rename it to ImportType or something like that? It can continue to live here - that's fine, since it really does only have to do with importing - but if you wanted to put it into App\Enums that would be OK too.

@@ -0,0 +1,167 @@
<?php
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOVE THIS!!!!!!!!!!!!!!!!!!!!!!

@@ -13,4 +14,21 @@ public function testRequiresExistingImport()
$this->importFileResponse(['import' => 9999, 'import-type' => 'accessory'])
->assertStatusMessageIs('import-errors');
}

public function testWillReturnValidationErrorWhenImportTypeIsInvalid()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Love more tests :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants