diff options
| -rw-r--r-- | admin_trees_renumber.php | 2 | ||||
| -rw-r--r-- | app/Tree.php | 77 | ||||
| -rw-r--r-- | includes/functions/functions.php | 76 | ||||
| -rw-r--r-- | includes/functions/functions_import.php | 2 | ||||
| -rw-r--r-- | tests/includes/functions/FunctionsTest.php | 9 |
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 |
