1515
1616/**
1717 * Main GEDCOM Import orchestrator class
18+ * Supports both .ged files and .zip files with media
1819 */
1920final class Import implements CreatesTeams
2021{
@@ -30,6 +31,8 @@ final class Import implements CreatesTeams
3031
3132 private CoupleCreator $ coupleCreator ;
3233
34+ private ?MediaImportHandler $ mediaHandler = null ;
35+
3336 /**
3437 * Initialize with user and create a new team
3538 */
@@ -48,55 +51,167 @@ public function __construct(?string $teamName, ?string $teamDescription)
4851 }
4952
5053 /**
51- * Import GEDCOM file content
54+ * Import GEDCOM file content (text only)
55+ *
56+ * @param string $gedcomContent Raw GEDCOM text content
57+ * @return array Import results
5258 */
5359 public function import (string $ gedcomContent ): array
5460 {
55- // At the start of your import method, increase time and memory limits
61+ return $ this ->processImport ($ gedcomContent , []);
62+ }
63+
64+ /**
65+ * Import GEDCOM from ZIP file (with media)
66+ *
67+ * @param string $zipPath Path to ZIP file
68+ * @return array Import results
69+ */
70+ public function importFromZip (string $ zipPath ): array
71+ {
72+ $ zipImporter = new ZipImporter ();
73+
74+ try {
75+ // Extract ZIP file
76+ Log::info ('Extracting ZIP file ' , ['path ' => $ zipPath ]);
77+ $ zipImporter ->extract ($ zipPath );
78+
79+ $ gedcomContent = $ zipImporter ->getGedcomContent ();
80+ $ mediaFiles = $ zipImporter ->getMediaFiles ();
81+
82+ Log::info ('ZIP extracted successfully ' , [
83+ 'media_files ' => count ($ mediaFiles ),
84+ 'gedcom_size ' => mb_strlen ($ gedcomContent ),
85+ ]);
86+
87+ // Process import with media files
88+ return $ this ->processImport ($ gedcomContent , $ mediaFiles );
89+ } catch (Exception $ e ) {
90+ Log::error ('ZIP import failed ' , [
91+ 'error ' => $ e ->getMessage (),
92+ 'trace ' => $ e ->getTraceAsString (),
93+ ]);
94+
95+ return [
96+ 'success ' => false ,
97+ 'error ' => 'ZIP extraction failed: ' . $ e ->getMessage (),
98+ ];
99+ } finally {
100+ $ zipImporter ->cleanup ();
101+ }
102+ }
103+
104+ /**
105+ * Get import statistics
106+ */
107+ public function getStatistics (): array
108+ {
109+ $ parsedData = $ this ->parser ->getParsedData ();
110+
111+ $ stats = [
112+ 'individuals_parsed ' => $ parsedData ? count ($ parsedData ->getIndividuals ()) : 0 ,
113+ 'families_parsed ' => $ parsedData ? count ($ parsedData ->getFamilies ()) : 0 ,
114+ 'individuals_imported ' => count ($ this ->individualImporter ->getPersonMap ()),
115+ 'families_imported ' => count ($ this ->familyImporter ->getFamilyMap ()),
116+ ];
117+
118+ if ($ this ->mediaHandler ) {
119+ $ stats ['media_references ' ] = count ($ this ->mediaHandler ->getPersonMediaMap ());
120+ }
121+
122+ return $ stats ;
123+ }
124+
125+ /**
126+ * Core import processing logic
127+ *
128+ * @param string $gedcomContent GEDCOM text content
129+ * @param array $mediaFiles Array of basename => filepath for media
130+ * @return array Import results
131+ */
132+ private function processImport (string $ gedcomContent , array $ mediaFiles ): array
133+ {
134+ // Increase limits for large imports
56135 ini_set ('max_execution_time ' , 300 ); // 5 minutes
57136 ini_set ('memory_limit ' , '512M ' );
58137
59138 try {
60139 DB ::beginTransaction ();
61140
141+ // Initialize media handler if we have media files
142+ if (! empty ($ mediaFiles )) {
143+ $ this ->mediaHandler = new MediaImportHandler ($ mediaFiles );
144+
145+ // Parse media objects from GEDCOM content BEFORE parsing individuals
146+ $ this ->mediaHandler ->parseMediaObjects ($ gedcomContent );
147+
148+ Log::info ('Media handler initialized ' , [
149+ 'files_count ' => count ($ mediaFiles ),
150+ 'media_objects_count ' => count ($ this ->mediaHandler ->getMediaObjects ()),
151+ ]);
152+ }
153+
62154 // Parse GEDCOM content
63155 $ parsedData = $ this ->parser ->parse ($ gedcomContent );
64156
65- Log::info ('GEDCOM IMPORT: parseGedcom ' , ['gedcomData ' => $ parsedData ->getGedcomData ()]);
157+ Log::info ('GEDCOM parsed ' , [
158+ 'individuals ' => count ($ parsedData ->getIndividuals ()),
159+ 'families ' => count ($ parsedData ->getFamilies ()),
160+ ]);
66161
67162 // Import individuals first
68- $ personMap = $ this ->individualImporter ->import ($ parsedData ->getIndividuals ());
163+ $ personMap = $ this ->individualImporter ->import (
164+ $ parsedData ->getIndividuals (),
165+ $ this ->mediaHandler
166+ );
69167
70- Log::info ('GEDCOM IMPORT: importIndividuals ' , [
71- 'individuals ' => $ parsedData ->getIndividuals (),
72- 'personMap ' => $ personMap ,
168+ Log::info ('Individuals imported ' , [
169+ 'count ' => count ($ personMap ),
73170 ]);
74171
75172 // Import families and relationships
76- $ familyMap = $ this ->familyImporter ->import ($ parsedData ->getFamilies (), $ personMap );
173+ $ familyMap = $ this ->familyImporter ->import (
174+ $ parsedData ->getFamilies (),
175+ $ personMap
176+ );
77177
78- Log::info ('GEDCOM IMPORT: importFamilies ' , [
79- 'families ' => $ parsedData ->getFamilies (),
80- 'familyMap ' => $ familyMap ,
178+ Log::info ('Families imported ' , [
179+ 'count ' => count ($ familyMap ),
81180 ]);
82181
83182 // Create couples from families
84183 $ this ->coupleCreator ->create ($ familyMap , $ personMap );
85184
86- Log::info ('GEDCOM IMPORT: createCouples ' , ['data ' => '???? ' ]);
185+ Log::info ('Couples created ' );
186+
187+ // Import media files if available
188+ $ mediaStats = null ;
189+ if ($ this ->mediaHandler ) {
190+ Log::info ('Starting media import ' );
191+ $ mediaStats = $ this ->mediaHandler ->importMediaToPersons ($ personMap );
192+ Log::info ('Media import complete ' , $ mediaStats );
193+ }
87194
88195 DB ::commit ();
89196
90- return [
197+ $ result = [
91198 'success ' => true ,
92199 'team ' => $ this ->team ->name ,
93200 'individuals_imported ' => count ($ personMap ),
94201 'families_imported ' => count ($ familyMap ),
95202 'message ' => 'GEDCOM file imported successfully ' ,
96203 ];
204+
205+ if ($ mediaStats ) {
206+ $ result ['media_stats ' ] = $ mediaStats ;
207+ }
208+
209+ return $ result ;
97210 } catch (Exception $ e ) {
98211 DB ::rollBack ();
99- Log::error ('GEDCOM Import Error: ' . $ e ->getMessage (), ['trace ' => $ e ->getTraceAsString ()]);
212+ Log::error ('GEDCOM Import Error: ' . $ e ->getMessage (), [
213+ 'trace ' => $ e ->getTraceAsString (),
214+ ]);
100215
101216 return [
102217 'success ' => false ,
@@ -105,22 +220,6 @@ public function import(string $gedcomContent): array
105220 }
106221 }
107222
108- /**
109- * Get import statistics
110- */
111- public function getStatistics (): array
112- {
113- // Only get parsed data if parsing has been done
114- $ parsedData = $ this ->parser ->getParsedData ();
115-
116- return [
117- 'individuals_parsed ' => $ parsedData ? count ($ parsedData ->getIndividuals ()) : 0 ,
118- 'families_parsed ' => $ parsedData ? count ($ parsedData ->getFamilies ()) : 0 ,
119- 'individuals_imported ' => count ($ this ->individualImporter ->getPersonMap ()),
120- 'families_imported ' => count ($ this ->familyImporter ->getFamilyMap ()),
121- ];
122- }
123-
124223 /**
125224 * Create a new team for the import
126225 */
@@ -134,13 +233,10 @@ private function createTeam(string $name, ?string $description): Team
134233 'personal_team ' => false ,
135234 ]));
136235
137- // -----------------------------------------------------------------------
138- // create team photo folder
139- // -----------------------------------------------------------------------
236+ // Create team photo folder
140237 if (! Storage::disk ('photos ' )->exists ($ team ->id )) {
141238 Storage::disk ('photos ' )->makeDirectory ($ team ->id );
142239 }
143- // -----------------------------------------------------------------------
144240
145241 return $ team ;
146242 }
0 commit comments