summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--admin_trees_renumber.php2
-rw-r--r--app/Tree.php77
-rw-r--r--includes/functions/functions.php76
-rw-r--r--includes/functions/functions_import.php2
-rw-r--r--tests/includes/functions/FunctionsTest.php9
5 files changed, 78 insertions, 88 deletions
diff --git a/admin_trees_renumber.php b/admin_trees_renumber.php
index e4fb621fea..6f42ce282d 100644
--- a/admin_trees_renumber.php
+++ b/admin_trees_renumber.php
@@ -83,7 +83,7 @@ if (Filter::get('go')) {
" `##link` WRITE," .
" `##user_gedcom_setting` WRITE"
);
- $new_xref = get_new_xref($type, $WT_TREE);
+ $new_xref = $WT_TREE->getNewXref($type);
switch ($type) {
case 'INDI':
Database::prepare(
diff --git a/app/Tree.php b/app/Tree.php
index 7edbf31a6e..0b4bccda64 100644
--- a/app/Tree.php
+++ b/app/Tree.php
@@ -753,6 +753,81 @@ class Tree {
}
/**
+ * Generate a new XREF, unique across all family trees
+ *
+ * @param string $type
+ *
+ * @return string
+ */
+ function getNewXref($type = 'INDI') {
+ /** @var string[] Which tree preference is used for which record type */
+ static $type_to_preference = array(
+ 'INDI' => 'GEDCOM_ID_PREFIX',
+ 'FAM' => 'FAM_ID_PREFIX',
+ 'OBJE' => 'MEDIA_ID_PREFIX',
+ 'NOTE' => 'NOTE_ID_PREFIX',
+ 'SOUR' => 'SOURCE_ID_PREFIX',
+ 'REPO' => 'REPO_ID_PREFIX',
+ );
+
+ if (array_key_exists($type, $type_to_preference)) {
+ $prefix = $this->getPreference($type_to_preference[$type]);
+ } else {
+ // Use the first non-underscore character
+ $prefix = substr(trim($type, '_'), 0, 1);
+ }
+
+ do {
+ // Use LAST_INSERT_ID(expr) to provide a transaction-safe sequence. See
+ // http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id
+ $statement = Database::prepare(
+ "UPDATE `##next_id` SET next_id = LAST_INSERT_ID(next_id + 1) WHERE record_type = :record_type AND gedcom_id = :tree_id"
+ );
+ $statement->execute(array(
+ 'record_type' => $type,
+ 'tree_id' => $this->getTreeId(),
+ ));
+
+ if ($statement->rowCount() === 0) {
+ // First time we've used this record type.
+ Database::prepare(
+ "INSERT INTO `##next_id` (gedcom_id, record_type, next_id) VALUES(:tree_id, :record_type, 1)"
+ )->execute(array(
+ 'record_type' => $type,
+ 'tree_id' => $this->getTreeId(),
+ ));
+ $num = 1;
+ } else {
+ $num = Database::prepare("SELECT LAST_INSERT_ID()")->fetchOne();
+ }
+
+ // Records may already exist with this sequence number.
+ $already_used = Database::prepare(
+ "SELECT i_id FROM `##individuals` WHERE i_id = :i_id" .
+ " UNION ALL " .
+ "SELECT f_id FROM `##families` WHERE f_id = :f_id" .
+ " UNION ALL " .
+ "SELECT s_id FROM `##sources` WHERE s_id = :s_id" .
+ " UNION ALL " .
+ "SELECT m_id FROM `##media` WHERE m_id = :m_id" .
+ " UNION ALL " .
+ "SELECT o_id FROM `##other` WHERE o_id = :o_id" .
+ " UNION ALL " .
+ "SELECT xref FROM `##change` WHERE xref = :xref"
+ )->execute(array(
+ 'i_id' => $prefix . $num,
+ 'f_id' => $prefix . $num,
+ 's_id' => $prefix . $num,
+ 'm_id' => $prefix . $num,
+ 'o_id' => $prefix . $num,
+ 'xref' => $prefix . $num,
+ ))->fetchOne();
+ } while ($already_used);
+
+ return $prefix . $num;
+ }
+
+ /**
* Create a new record from GEDCOM data.
*
* @param string $gedcom
@@ -774,7 +849,7 @@ class Tree {
// webtrees creates XREFs containing digits. Anything else (e.g. β€œnew”) is just a placeholder.
if (!preg_match('/\d/', $xref)) {
- $xref = get_new_xref($type, $this);
+ $xref = $this->getNewXref($type);
$gedcom = preg_replace('/^0 @(' . WT_REGEX_XREF . ')@/', '0 @' . $xref . '@', $gedcom);
}
diff --git a/includes/functions/functions.php b/includes/functions/functions.php
index 0d0e72397a..58c9b46bdc 100644
--- a/includes/functions/functions.php
+++ b/includes/functions/functions.php
@@ -2305,82 +2305,6 @@ function get_query_url($overwrite = null, $separator = '&') {
}
/**
- * Generate a new XREF, unique across all family trees
- *
- * @param string $type
- * @param Tree $tree
- *
- * @return string
- */
-function get_new_xref($type = 'INDI', $tree) {
- /** @var string[] Which tree preference is used for which record type */
- static $type_to_preference = array(
- 'INDI' => 'GEDCOM_ID_PREFIX',
- 'FAM' => 'FAM_ID_PREFIX',
- 'OBJE' => 'MEDIA_ID_PREFIX',
- 'NOTE' => 'NOTE_ID_PREFIX',
- 'SOUR' => 'SOURCE_ID_PREFIX',
- 'REPO' => 'REPO_ID_PREFIX',
- );
-
- if (array_key_exists($type, $type_to_preference)) {
- $prefix = $tree->getPreference($type_to_preference[$type]);
- } else {
- // Use the first non-underscore character
- $prefix = substr(trim($type, '_'), 0, 1);
- }
-
- do {
- // Use LAST_INSERT_ID(expr) to provide a transaction-safe sequence. See
- // http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id
- $statement = Database::prepare(
- "UPDATE `##next_id` SET next_id = LAST_INSERT_ID(next_id + 1) WHERE record_type = :record_type AND gedcom_id = :tree_id"
- );
- $statement->execute(array(
- 'record_type' => $type,
- 'tree_id' => $tree->getTreeId(),
- ));
-
- if ($statement->rowCount() === 0) {
- // First time we've used this record type.
- Database::prepare(
- "INSERT INTO `##next_id` (gedcom_id, record_type, next_id) VALUES(:tree_id, :record_type, 1)"
- )->execute(array(
- 'record_type' => $type,
- 'tree_id' => $tree->getTreeId(),
- ));
- $num = 1;
- } else {
- $num = Database::prepare("SELECT LAST_INSERT_ID()")->fetchOne();
- }
-
- // Records may already exist with this sequence number.
- $already_used = Database::prepare(
- "SELECT i_id FROM `##individuals` WHERE i_id = :i_id" .
- " UNION ALL " .
- "SELECT f_id FROM `##families` WHERE f_id = :f_id" .
- " UNION ALL " .
- "SELECT s_id FROM `##sources` WHERE s_id = :s_id" .
- " UNION ALL " .
- "SELECT m_id FROM `##media` WHERE m_id = :m_id" .
- " UNION ALL " .
- "SELECT o_id FROM `##other` WHERE o_id = :o_id" .
- " UNION ALL " .
- "SELECT xref FROM `##change` WHERE xref = :xref"
- )->execute(array(
- 'i_id' => $prefix . $num,
- 'f_id' => $prefix . $num,
- 's_id' => $prefix . $num,
- 'm_id' => $prefix . $num,
- 'o_id' => $prefix . $num,
- 'xref' => $prefix . $num,
- ))->fetchOne();
- } while ($already_used);
-
- return $prefix . $num;
-}
-
-/**
* Determines whether the passed in filename is a link to an external source (i.e. contains β€œ://”)
*
* @param string $file
diff --git a/includes/functions/functions_import.php b/includes/functions/functions_import.php
index b001a416c7..d9efbcb066 100644
--- a/includes/functions/functions_import.php
+++ b/includes/functions/functions_import.php
@@ -1008,7 +1008,7 @@ function create_media_object($level, $gedrec, $ged_id) {
$xref = $sql_select_media->execute(array($file, $titl, $ged_id))->fetchOne();
if (!$xref) {
- $xref = get_new_xref("OBJE", Tree::findById($ged_id));
+ $xref = Tree::findById($ged_id)->getNewXref('OBJE');
// renumber the lines
$gedrec = preg_replace_callback('/\n(\d+)/', function($m) use ($level) { return "\n" . ($m[1] - $level); }, $gedrec);
// convert to an object
diff --git a/tests/includes/functions/FunctionsTest.php b/tests/includes/functions/FunctionsTest.php
index eb2b3a4e7f..f8677b641e 100644
--- a/tests/includes/functions/FunctionsTest.php
+++ b/tests/includes/functions/FunctionsTest.php
@@ -166,15 +166,6 @@ class FunctionsTest extends PHPUnit_Framework_TestCase {
}
/**
- * Test that function get_new_xref() exists in the correct namespace.
- *
- * @return void
- */
- public function testFunctionGetNewXrefExists() {
- $this->assertEquals(function_exists(__NAMESPACE__ . '\\get_new_xref'), true);
- }
-
- /**
* Test that function isFileExternal() exists in the correct namespace.
*
* @return void