summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorGreg Roach <fisharebest@gmail.com>2015-01-29 14:00:09 +0000
committerGreg Roach <fisharebest@gmail.com>2015-01-29 14:00:09 +0000
commit1080c5ec1106dd029ac79b42803454d8d5a652ee (patch)
tree21602c1d546e69d9495fde125df02fbad7bba619 /library
parentcb2af47cc380a07be10e8e1214907e5b13057dd7 (diff)
downloadwebtrees-1080c5ec1106dd029ac79b42803454d8d5a652ee.tar.gz
webtrees-1080c5ec1106dd029ac79b42803454d8d5a652ee.tar.bz2
webtrees-1080c5ec1106dd029ac79b42803454d8d5a652ee.zip
Move tree import code to WT_Tree class
Diffstat (limited to 'library')
-rw-r--r--library/WT/Tree.php69
1 files changed, 60 insertions, 9 deletions
diff --git a/library/WT/Tree.php b/library/WT/Tree.php
index e814baca09..db81cef75d 100644
--- a/library/WT/Tree.php
+++ b/library/WT/Tree.php
@@ -481,15 +481,16 @@ class WT_Tree {
* @param bool $keep_media
*/
public function deleteGenealogyData($keep_media) {
- WT_DB::prepare("DELETE FROM `##individuals` WHERE i_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##families` WHERE f_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##sources` WHERE s_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##other` WHERE o_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##places` WHERE p_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##placelinks` WHERE pl_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##name` WHERE n_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##dates` WHERE d_file =?")->execute(array($this->tree_id));
- WT_DB::prepare("DELETE FROM `##change` WHERE gedcom_id=?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##gedcom_chunk` WHERE gedcom_id = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##individuals` WHERE i_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##families` WHERE f_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##sources` WHERE s_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##other` WHERE o_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##places` WHERE p_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##placelinks` WHERE pl_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##name` WHERE n_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##dates` WHERE d_file = ?")->execute(array($this->tree_id));
+ WT_DB::prepare("DELETE FROM `##change` WHERE gedcom_id = ?")->execute(array($this->tree_id));
if ($keep_media) {
WT_DB::prepare("DELETE FROM `##link` WHERE l_file =? AND l_type<>'OBJE'")->execute(array($this->tree_id));
@@ -571,4 +572,54 @@ class WT_Tree {
return @rename($tmp_file, $gedcom_file);
}
+
+ /**
+ * Import data from a gedcom file into this tree.
+ *
+ * @param string $path The full path to the (possibly temporary) file.
+ * @param string $filename The preferred filename, for export/download.
+ * @param boolean $keep_media Whether to retain any existing media records
+ *
+ * @throws Exception
+ */
+ public function importGedcomFile($path, $filename, $keep_media) {
+ // Read the file in blocks of roughly 64K. Ensure that each block
+ // contains complete gedcom records. This will ensure we don’t split
+ // multi-byte characters, as well as simplifying the code to import
+ // each block.
+
+ $file_data = '';
+ $fp = fopen($path, 'rb');
+
+ // Don’t allow the user to cancel the request. We do not want to be left with an incomplete transaction.
+ ignore_user_abort(true);
+
+ WT_DB::beginTransaction();
+ $this->deleteGenealogyData($keep_media);
+ $this->setPreference('gedcom_filename', $filename);
+ $this->setPreference('imported', '0');
+
+ while (!feof($fp)) {
+ $file_data .= fread($fp, 65536);
+ // There is no strrpos() function that searches for substrings :-(
+ for ($pos = strlen($file_data) - 1; $pos > 0; --$pos) {
+ if ($file_data[$pos] === '0' && ($file_data[$pos - 1] === "\n" || $file_data[$pos - 1] === "\r")) {
+ // We’ve found the last record boundary in this chunk of data
+ break;
+ }
+ }
+ if ($pos) {
+ WT_DB::prepare(
+ "INSERT INTO `##gedcom_chunk` (gedcom_id, chunk_data) VALUES (?, ?)"
+ )->execute(array($this->tree_id, substr($file_data, 0, $pos)));
+ $file_data = substr($file_data, $pos);
+ }
+ }
+ WT_DB::prepare(
+ "INSERT INTO `##gedcom_chunk` (gedcom_id, chunk_data) VALUES (?, ?)"
+ )->execute(array($this->tree_id, $file_data));
+
+ WT_DB::commit();
+ fclose($fp);
+ }
}