mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-07-12 11:24:31 +02:00
Allow to import PartKeepr attachments
This commit is contained in:
parent
ae438f1650
commit
bcaf8e9912
4 changed files with 136 additions and 2 deletions
|
@ -21,6 +21,9 @@
|
|||
namespace App\Services\ImportExportSystem\PartKeeprImporter;
|
||||
|
||||
use App\Doctrine\Purger\ResetAutoIncrementORMPurger;
|
||||
use App\Entity\Attachments\FootprintAttachment;
|
||||
use App\Entity\Attachments\ManufacturerAttachment;
|
||||
use App\Entity\Attachments\StorelocationAttachment;
|
||||
use App\Entity\Base\AbstractDBElement;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
use App\Entity\Contracts\TimeStampableInterface;
|
||||
|
@ -125,6 +128,8 @@ class PKDatastructureImporter
|
|||
|
||||
$this->em->flush();
|
||||
|
||||
$this->importAttachments($data, 'manufacturericlogo', Manufacturer::class, 'manufacturer_id', ManufacturerAttachment::class);
|
||||
|
||||
return count($manufacturer_data);
|
||||
}
|
||||
|
||||
|
@ -249,11 +254,22 @@ class PKDatastructureImporter
|
|||
|
||||
public function importFootprints(array $data): int
|
||||
{
|
||||
return $this->importElementsWithCategory($data, Footprint::class, 'footprint');
|
||||
$count = $this->importElementsWithCategory($data, Footprint::class, 'footprint');
|
||||
|
||||
//Footprints have both attachments and images
|
||||
$this->importAttachments($data, 'footprintattachment', Footprint::class, 'footprint_id', FootprintAttachment::class);
|
||||
$this->importAttachments($data, 'footprintimage', Footprint::class, 'footprint_id', FootprintAttachment::class);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
public function importStorelocations(array $data): int
|
||||
{
|
||||
return $this->importElementsWithCategory($data, Storelocation::class, 'storagelocation');
|
||||
$count = $this->importElementsWithCategory($data, Storelocation::class, 'storagelocation');
|
||||
|
||||
//Footprints have both attachments and images
|
||||
$this->importAttachments($data, 'storagelocationimage', Storelocation::class, 'footprint_id', StorelocationAttachment::class);
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
namespace App\Services\ImportExportSystem\PartKeeprImporter;
|
||||
|
||||
use App\Entity\Attachments\Attachment;
|
||||
use App\Entity\Attachments\AttachmentContainingDBElement;
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Base\AbstractDBElement;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
use App\Entity\Contracts\TimeStampableInterface;
|
||||
|
@ -35,6 +38,114 @@ trait PKImportHelperTrait
|
|||
protected EntityManagerInterface $em;
|
||||
protected PropertyAccessorInterface $propertyAccessor;
|
||||
|
||||
private ?AttachmentType $import_attachment_type = null;
|
||||
|
||||
/**
|
||||
* Converts a PartKeepr attachment/image row to an Attachment entity.
|
||||
* @param array $attachment_row The attachment row from the PartKeepr database
|
||||
* @param string $target_class The target class for the attachment
|
||||
* @param string $type The type of the attachment (attachment or image)
|
||||
* @return Attachment
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function convertAttachmentDataToEntity(array $attachment_row, string $target_class, string $type): Attachment
|
||||
{
|
||||
//By default we use the cached version
|
||||
if (!$this->import_attachment_type) {
|
||||
//Get the import attachment type
|
||||
$this->import_attachment_type = $this->em->getRepository(AttachmentType::class)->findOneBy([
|
||||
'name' => 'PartKeepr Attachment'
|
||||
]);
|
||||
if (!$this->import_attachment_type) { //If not existing in DB create it
|
||||
$this->import_attachment_type = new AttachmentType();
|
||||
$this->import_attachment_type->setName('PartKeepr Attachment');
|
||||
$this->em->persist($this->import_attachment_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($type, ['attachment', 'image'], true)) {
|
||||
throw new \InvalidArgumentException(sprintf('The type %s is not a valid attachment type', $type));
|
||||
}
|
||||
|
||||
if (!is_a($target_class, Attachment::class, true)) {
|
||||
throw new \InvalidArgumentException(sprintf('The target class %s is not a subclass of %s', $target_class, Attachment::class));
|
||||
}
|
||||
|
||||
/** @var Attachment $attachment */
|
||||
$attachment = new $target_class();
|
||||
if (!empty($attachment_row['description'])) {
|
||||
$attachment->setName($attachment_row['description']);
|
||||
} else {
|
||||
$attachment->setName($attachment_row['originalname']);
|
||||
}
|
||||
$attachment->setFilename($attachment_row['originalname']);
|
||||
$attachment->setAttachmentType($this->import_attachment_type);
|
||||
$this->setCreationDate($attachment, $attachment_row['created']);
|
||||
|
||||
//Determine file extension (if the extension is empty, we use the original extension)
|
||||
if (empty($attachment_row['extension'])) {
|
||||
$attachment_row['extension'] = pathinfo($attachment_row['originalname'], PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
//Determine file path
|
||||
//Images are stored in the (public) media folder, attachments in the (private) uploads/ folder
|
||||
$path = $type === 'attachment' ? '%SECURE%' : '%MEDIA%';
|
||||
//The folder is the type of the attachment from the PartKeepr database
|
||||
$path .= '/'.$attachment_row['type'];
|
||||
//Next comes the filename plus extension
|
||||
$path .= '/'.$attachment_row['filename'].'.'.$attachment_row['extension'];
|
||||
|
||||
$attachment->setPath($path);
|
||||
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the attachments from the given data
|
||||
* @param array $data The PartKeepr database
|
||||
* @param string $table_name The table name for the attachments (if it contain "image", it will be treated as an image)
|
||||
* @param string $target_class The target class (e.g. Part)
|
||||
* @param string $target_id_field The field name where the target ID is stored
|
||||
* @param string $attachment_class The attachment class (e.g. PartAttachment)
|
||||
* @return void
|
||||
*/
|
||||
protected function importAttachments(array $data, string $table_name, string $target_class, string $target_id_field, string $attachment_class): void
|
||||
{
|
||||
//Determine if we have an image or an attachment
|
||||
$type = str_contains($table_name, 'image') || str_contains($table_name, 'iclogo') ? 'image' : 'attachment';
|
||||
|
||||
if (!isset($data[$table_name])) {
|
||||
throw new \RuntimeException(sprintf('The table %s does not exist in the PartKeepr database', $table_name));
|
||||
}
|
||||
|
||||
if (!is_a($target_class, AttachmentContainingDBElement::class, true)) {
|
||||
throw new \InvalidArgumentException(sprintf('The target class %s is not a subclass of %s', $target_class, AttachmentContainingDBElement::class));
|
||||
}
|
||||
|
||||
if (!is_a($attachment_class, Attachment::class, true)) {
|
||||
throw new \InvalidArgumentException(sprintf('The attachment class %s is not a subclass of %s', $attachment_class, Attachment::class));
|
||||
}
|
||||
|
||||
//Get the table data
|
||||
$table_data = $data[$table_name];
|
||||
foreach($table_data as $attachment_row) {
|
||||
$attachment = $this->convertAttachmentDataToEntity($attachment_row, $attachment_class, $type);
|
||||
|
||||
//Retrieve the target entity
|
||||
$target_id = (int) $attachment_row[$target_id_field];
|
||||
/** @var AttachmentContainingDBElement $target */
|
||||
$target = $this->em->find($target_class, $target_id);
|
||||
if (!$target) {
|
||||
throw new \RuntimeException(sprintf('Could not find target entity with ID %s', $target_id));
|
||||
}
|
||||
|
||||
$target->addAttachment($attachment);
|
||||
$this->em->persist($attachment);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the parent to the given entity, using the numerical IDs from the imported data.
|
||||
* @param string $class
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace App\Services\ImportExportSystem\PartKeeprImporter;
|
||||
|
||||
use App\Entity\Attachments\ProjectAttachment;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Entity\ProjectSystem\ProjectBOMEntry;
|
||||
|
@ -96,6 +97,8 @@ class PKOptionalImporter
|
|||
}
|
||||
$this->em->flush();
|
||||
|
||||
$this->importAttachments($data, 'projectattachment', Project::class, 'project_id', ProjectAttachment::class);
|
||||
|
||||
return count($projects_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace App\Services\ImportExportSystem\PartKeeprImporter;
|
||||
|
||||
use App\Entity\Attachments\PartAttachment;
|
||||
use App\Entity\Parameters\PartParameter;
|
||||
use App\Entity\Parts\Category;
|
||||
use App\Entity\Parts\Footprint;
|
||||
|
@ -119,6 +120,9 @@ class PKPartImporter
|
|||
$this->importPartParameters($data);
|
||||
$this->importOrderdetails($data);
|
||||
|
||||
//Import attachments
|
||||
$this->importAttachments($data, 'partattachment', Part::class, 'part_id', PartAttachment::class);
|
||||
|
||||
return count($part_data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue