diff options
45 files changed, 187 insertions, 224 deletions
diff --git a/app/Census/CensusColumnBirthPlace.php b/app/Census/CensusColumnBirthPlace.php index b184454071..3d148afb38 100644 --- a/app/Census/CensusColumnBirthPlace.php +++ b/app/Census/CensusColumnBirthPlace.php @@ -34,7 +34,7 @@ class CensusColumnBirthPlace extends AbstractCensusColumn implements CensusColum */ public function generate(Individual $individual, Individual $head): string { - $birth_place = $individual->getBirthPlace()->getGedcomName(); + $birth_place = $individual->getBirthPlace()->gedcomName(); $census_place = $this->place(); // Ignore the census country diff --git a/app/Census/CensusColumnBornForeignParts.php b/app/Census/CensusColumnBornForeignParts.php index feaac61022..269dd77516 100644 --- a/app/Census/CensusColumnBornForeignParts.php +++ b/app/Census/CensusColumnBornForeignParts.php @@ -34,7 +34,7 @@ class CensusColumnBornForeignParts extends AbstractCensusColumn implements Censu */ public function generate(Individual $individual, Individual $head): string { - $birth_place = $individual->getBirthPlace()->lastPart(); + $birth_place = (string) $individual->getBirthPlace()->lastParts(1)->first(); $census_place = $this->place(); if ($birth_place === 'Wales') { diff --git a/app/Census/CensusColumnFatherBirthPlace.php b/app/Census/CensusColumnFatherBirthPlace.php index b5432f2c70..e4cbc272d6 100644 --- a/app/Census/CensusColumnFatherBirthPlace.php +++ b/app/Census/CensusColumnFatherBirthPlace.php @@ -37,7 +37,7 @@ class CensusColumnFatherBirthPlace extends AbstractCensusColumn implements Censu $father = $this->father($individual); if ($father) { - return $this->notCountry($father->getBirthPlace()->getGedcomName()); + return $this->notCountry($father->getBirthPlace()->gedcomName()); } return ''; diff --git a/app/Census/CensusColumnFatherForeign.php b/app/Census/CensusColumnFatherForeign.php index 5e860261d1..950d9be654 100644 --- a/app/Census/CensusColumnFatherForeign.php +++ b/app/Census/CensusColumnFatherForeign.php @@ -36,7 +36,7 @@ class CensusColumnFatherForeign extends AbstractCensusColumn implements CensusCo { $father = $this->father($individual); - if ($father && $this->lastPartOfPlace($father->getBirthPlace()->getGedcomName()) !== $this->place()) { + if ($father && $this->lastPartOfPlace($father->getBirthPlace()->gedcomName()) !== $this->place()) { return 'Y'; } diff --git a/app/Census/CensusColumnMotherBirthPlace.php b/app/Census/CensusColumnMotherBirthPlace.php index d222bada2f..9625c24599 100644 --- a/app/Census/CensusColumnMotherBirthPlace.php +++ b/app/Census/CensusColumnMotherBirthPlace.php @@ -37,7 +37,7 @@ class CensusColumnMotherBirthPlace extends AbstractCensusColumn implements Censu $mother = $this->mother($individual); if ($mother) { - return $this->notCountry($mother->getBirthPlace()->getGedcomName()); + return $this->notCountry($mother->getBirthPlace()->gedcomName()); } return ''; diff --git a/app/Census/CensusColumnMotherForeign.php b/app/Census/CensusColumnMotherForeign.php index b3b31a1be5..cf474def77 100644 --- a/app/Census/CensusColumnMotherForeign.php +++ b/app/Census/CensusColumnMotherForeign.php @@ -36,7 +36,7 @@ class CensusColumnMotherForeign extends AbstractCensusColumn implements CensusCo { $mother = $this->mother($individual); - if ($mother && $this->lastPartOfPlace($mother->getBirthPlace()->getGedcomName()) !== $this->place()) { + if ($mother && $this->lastPartOfPlace($mother->getBirthPlace()->gedcomName()) !== $this->place()) { return 'Y'; } diff --git a/app/Census/CensusColumnNationality.php b/app/Census/CensusColumnNationality.php index 46539bd635..f61b7bd495 100644 --- a/app/Census/CensusColumnNationality.php +++ b/app/Census/CensusColumnNationality.php @@ -44,7 +44,7 @@ class CensusColumnNationality extends AbstractCensusColumn implements CensusColu */ public function generate(Individual $individual, Individual $head): string { - $place = $individual->getBirthPlace()->getGedcomName(); + $place = $individual->getBirthPlace()->gedcomName(); // No birthplace? Assume born in the same country. if ($place === '') { @@ -54,7 +54,7 @@ class CensusColumnNationality extends AbstractCensusColumn implements CensusColu // Did we emigrate or naturalise? foreach ($individual->facts(['IMMI' ,'EMIG', 'NATU'], true) as $fact) { if (Date::compare($fact->date(), $this->date()) <= 0) { - $place = $fact->place()->getGedcomName(); + $place = $fact->place()->gedcomName(); } } diff --git a/app/Fact.php b/app/Fact.php index 537c8b7e22..7bb5eba9e5 100644 --- a/app/Fact.php +++ b/app/Fact.php @@ -526,8 +526,8 @@ class Fact } } // Fact place - if (!$this->place()->isEmpty()) { - $attributes[] = $this->place()->getShortName(); + if ($this->place()->gedcomName() <> '') { + $attributes[] = $this->place()->shortName(); } } diff --git a/app/FactLocation.php b/app/FactLocation.php index fb7e045d80..bfc7dbf83d 100644 --- a/app/FactLocation.php +++ b/app/FactLocation.php @@ -42,7 +42,7 @@ class FactLocation extends Location $this->individual = $individual; $this->fact = $fact; - parent::__construct($fact->place()->getGedcomName()); + parent::__construct($fact->place()->gedcomName()); $coords = $this->getCoordsFromGedcom(); if ($coords !== null) { @@ -158,7 +158,7 @@ class FactLocation extends Location */ public function toolTip() { - return $this->fact->place()->getGedcomName(); + return $this->fact->place()->gedcomName(); } /** @@ -169,7 +169,7 @@ class FactLocation extends Location private function getCoordsFromGedcom() { $coords = null; - if (!$this->fact->place()->isEmpty()) { + if ($this->fact->place()->gedcomName() <> '') { $gedcom = $this->fact->gedcom(); $f1 = preg_match("/\d LATI (.*)/", $gedcom, $match1); $f2 = preg_match("/\d LONG (.*)/", $gedcom, $match2); diff --git a/app/Functions/FunctionsImport.php b/app/Functions/FunctionsImport.php index 63778b2306..645831d6fd 100644 --- a/app/Functions/FunctionsImport.php +++ b/app/Functions/FunctionsImport.php @@ -26,6 +26,7 @@ use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Log; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Note; +use Fisharebest\Webtrees\Place; use Fisharebest\Webtrees\Repository; use Fisharebest\Webtrees\Soundex; use Fisharebest\Webtrees\Source; @@ -815,81 +816,24 @@ class FunctionsImport $places = array_unique($matches[1]); - foreach ($places as $place) { - // Find (or create) the place ID. - $place_id = self::importPlace($place, $tree); + foreach ($places as $place_name) { + $place = new Place($place_name, $tree); + // Calling Place::id() will create the entry in the database, if it doesn't already exist. // Link the place to the record try { DB::table('placelinks')->insert([ - 'pl_p_id' => $place_id, + 'pl_p_id' => $place->id(), 'pl_gid' => $xref, 'pl_file' => $tree->id(), ]); } catch (PDOException $ex) { - // Collation differences (Quebec and Québec) can cause the same place name to be found twice. - // @TODO - what if there is some other DB error? + // Already linked this place? } } } /** - * Find (or create) the place ID for a place name. - * - * @param string $place - * @param Tree $tree - * - * @return int - */ - private static function importPlace(string $place, Tree $tree): int - { - /** @var int[] $cache */ - static $cache; - - // The global, top-level, place has an ID of zero. - if ($place === '') { - return 0; - } - - // Already imported? - $cache_key = $tree->id() . '/' . $place; - if (isset($cache[$cache_key])) { - return $cache[$cache_key]; - } - - // Find the parent place ID first - if (preg_match('/([^,]*), (.+)/', $place, $match)) { - $place = $match[1]; - $parent_id = self::importPlace($match[2], $tree); - } else { - $parent_id = 0; - } - - // Does the place already exist? - $place_id = (int) DB::table('places') - ->where('p_file', '=', $tree->id()) - ->where('p_parent_id', '=', $parent_id) - ->where('p_place', '=', mb_substr($place, 0, 150)) - ->value('p_id'); - - if ($place_id === 0) { - DB::table('places')->insert([ - 'p_place' => mb_substr($place, 0, 150), - 'p_parent_id' => $parent_id, - 'p_file' => $tree->id(), - 'p_std_soundex' => Soundex::russell($place), - 'p_dm_soundex' => Soundex::daitchMokotoff($place), - ]); - - $place_id = (int) DB::connection()->getPdo()->lastInsertId(); - } - - $cache[$cache_key] = $place_id; - - return $place_id; - } - - /** * Extract all the dates from the given record and insert them into the database. * * @param string $xref diff --git a/app/Functions/FunctionsPrint.php b/app/Functions/FunctionsPrint.php index 5d4ec0855d..78a5074a59 100644 --- a/app/Functions/FunctionsPrint.php +++ b/app/Functions/FunctionsPrint.php @@ -353,10 +353,10 @@ class FunctionsPrint if ($anchor) { // Show the full place name, for facts/events tab - $html = '<a href="' . e($event->place()->url()) . '">' . $event->place()->getFullName() . '</a>'; + $html = $event->place()->fullName(true); } else { // Abbreviate the place name, for chart boxes - return $event->place()->getShortName(); + return $event->place()->shortName(); } if ($sub_records) { @@ -365,7 +365,7 @@ class FunctionsPrint if (preg_match_all('/\n3 (?:_HEB|ROMN) (.+)/', $placerec, $matches)) { foreach ($matches[1] as $match) { $wt_place = new Place($match, $tree); - $html .= ' - ' . $wt_place->getFullName(); + $html .= ' - ' . $wt_place->fullName(); } } $map_lati = ''; diff --git a/app/Gedcom.php b/app/Gedcom.php index 1010ac936c..7fc217a1e0 100644 --- a/app/Gedcom.php +++ b/app/Gedcom.php @@ -51,4 +51,7 @@ class Gedcom // Separates parts of a place name. public const PLACE_SEPARATOR = ', '; + + // Regex to match a (badly formed) GEDCOM place separator. + public const PLACE_SEPARATOR_REGEX = ' *, *'; } diff --git a/app/GedcomRecord.php b/app/GedcomRecord.php index afe5798a90..56f42a008b 100644 --- a/app/GedcomRecord.php +++ b/app/GedcomRecord.php @@ -820,12 +820,12 @@ class GedcomRecord { foreach ($this->facts($facts, true) as $event) { // Only display if it has a date or place (or both) - if ($event->date()->isOK() && !$event->place()->isEmpty()) { + if ($event->date()->isOK() && $event->place()->gedcomName() <> '') { $joiner = ' — '; } else { $joiner = ''; } - if ($event->date()->isOK() || !$event->place()->isEmpty()) { + if ($event->date()->isOK() || $event->place()->gedcomName() <> '') { switch ($style) { case 1: return '<br><em>' . $event->label() . ' ' . FunctionsPrint::formatFactDate($event, $this, false, false) . $joiner . FunctionsPrint::formatFactPlace($event) . '</em>'; diff --git a/app/Http/Controllers/AutocompleteController.php b/app/Http/Controllers/AutocompleteController.php index c1f350ec65..34c80c3161 100644 --- a/app/Http/Controllers/AutocompleteController.php +++ b/app/Http/Controllers/AutocompleteController.php @@ -178,7 +178,7 @@ class AutocompleteController extends AbstractBaseController $data = []; foreach ($this->search_service->searchPlaces($tree, $query) as $place) { - $data[] = ['value' => $place->getGedcomName()]; + $data[] = ['value' => $place->gedcomName()]; } if (empty($data) && $tree->getPreference('GEONAMES_ACCOUNT')) { @@ -392,7 +392,7 @@ class AutocompleteController extends AbstractBaseController $found = false; foreach ($this->search_service->searchPlaces($tree, $query) as $place) { - $place_name = $place->getGedcomName(); + $place_name = $place->gedcomName(); if ($place_name === $query) { $found = true; } diff --git a/app/Http/Controllers/PlaceHierarchyController.php b/app/Http/Controllers/PlaceHierarchyController.php index 467df990b5..3b633a4b5f 100644 --- a/app/Http/Controllers/PlaceHierarchyController.php +++ b/app/Http/Controllers/PlaceHierarchyController.php @@ -102,7 +102,7 @@ class PlaceHierarchyController extends AbstractBaseController 'parent' => $parent, 'place' => $fqpn, 'content' => $content, - 'showeventslink' => null !== $data && !$place->isEmpty() && $action !== 'hierarchy-e', + 'showeventslink' => null !== $data && $place->gedcomName() !== '' && $action !== 'hierarchy-e', 'nextaction' => $nextaction, ] ); @@ -118,7 +118,7 @@ class PlaceHierarchyController extends AbstractBaseController { $places = $search_service->searchPlaces($tree, '') ->sort(function (Place $x, Place $y): int { - return $x->getGedcomName() <=> $y->getGedcomName(); + return $x->gedcomName() <=> $y->gedcomName(); }) ->all(); @@ -182,7 +182,7 @@ class PlaceHierarchyController extends AbstractBaseController ->on('pl_gid', '=', 'i_id'); }) ->where('i_file', '=', $tree->id()) - ->where('pl_p_id', '=', $place->getPlaceId()) + ->where('pl_p_id', '=', $place->id()) ->select(['individuals.*']) ->distinct() ->get() @@ -197,7 +197,7 @@ class PlaceHierarchyController extends AbstractBaseController ->on('pl_gid', '=', 'f_id'); }) ->where('f_file', '=', $tree->id()) - ->where('pl_p_id', '=', $place->getPlaceId()) + ->where('pl_p_id', '=', $place->id()) ->select(['families.*']) ->distinct() ->get() @@ -219,12 +219,12 @@ class PlaceHierarchyController extends AbstractBaseController private function breadcrumbs($place): array { $breadcrumbs = []; - if (!$place->isEmpty()) { + if ($place->gedcomName() <> '') { $breadcrumbs[] = $place; - $parent_place = $place->getParentPlace(); - while (!$parent_place->isEmpty()) { + $parent_place = $place->parent(); + while ($parent_place->gedcomName() !== '') { $breadcrumbs[] = $parent_place; - $parent_place = $parent_place->getParentPlace(); + $parent_place = $parent_place->parent(); } $breadcrumbs = array_reverse($breadcrumbs); $current = array_pop($breadcrumbs); @@ -257,11 +257,11 @@ class PlaceHierarchyController extends AbstractBaseController $showlink = false; } foreach ($places as $id => $place) { - $location = new Location($place->getGedcomName()); + $location = new Location($place->gedcomName()); //Stats $placeStats = []; foreach (['INDI', 'FAM'] as $type) { - $tmp = $stats->statsPlaces($type, '', $place->getPlaceId()); + $tmp = $stats->statsPlaces($type, '', $place->id()); $placeStats[$type] = empty($tmp) ? 0 : $tmp[0]->tot; } //Flag @@ -283,7 +283,7 @@ class PlaceHierarchyController extends AbstractBaseController 'name' => 'globe', 'color' => '#1e90ff', ], - 'tooltip' => $place->getGedcomName(), + 'tooltip' => $place->gedcomName(), 'summary' => view('place-sidebar', [ 'showlink' => $showlink, 'flag' => $flag, diff --git a/app/Individual.php b/app/Individual.php index 2db05374e0..39a3281419 100644 --- a/app/Individual.php +++ b/app/Individual.php @@ -554,8 +554,8 @@ class Individual extends GedcomRecord public function getLifeSpan(): string { // Just the first part of the place name - $birth_place = strip_tags($this->getBirthPlace()->getShortName()); - $death_place = strip_tags($this->getDeathPlace()->getShortName()); + $birth_place = strip_tags($this->getBirthPlace()->shortName()); + $death_place = strip_tags($this->getDeathPlace()->shortName()); // Remove markup from dates $birth_date = strip_tags($this->getBirthDate()->display()); $death_date = strip_tags($this->getDeathDate()->display()); diff --git a/app/Module/LifespansChartModule.php b/app/Module/LifespansChartModule.php index 56603c97b9..9f45b7c1c5 100644 --- a/app/Module/LifespansChartModule.php +++ b/app/Module/LifespansChartModule.php @@ -373,7 +373,7 @@ class LifespansChartModule extends AbstractModule implements ModuleChartInterfac ->on('pl_gid', '=', 'i_id'); }) ->where('i_file', '=', $tree->id()) - ->where('pl_p_id', '=', $place->getPlaceId()) + ->where('pl_p_id', '=', $place->id()) ->pluck('i_id') ->all(); } diff --git a/app/Module/PedigreeMapModule.php b/app/Module/PedigreeMapModule.php index 7e0e969a54..0592e568e0 100644 --- a/app/Module/PedigreeMapModule.php +++ b/app/Module/PedigreeMapModule.php @@ -225,7 +225,7 @@ class PedigreeMapModule extends AbstractModule implements ModuleChartInterface foreach ($ancestors as $sosa => $person) { if ($person->canShow()) { $birth = $person->getFirstFact('BIRT'); - if ($birth instanceof Fact && !$birth->place()->isEmpty()) { + if ($birth instanceof Fact && $birth->place()->gedcomName() !== '') { $facts[$sosa] = $birth; } } diff --git a/app/Module/PlacesModule.php b/app/Module/PlacesModule.php index 2885ec429e..6ca77eac44 100644 --- a/app/Module/PlacesModule.php +++ b/app/Module/PlacesModule.php @@ -153,7 +153,7 @@ class PlacesModule extends AbstractModule implements ModuleTabInterface // Add birth of children from this family to the facts array foreach ($family->getChildren() as $child) { $childsBirth = $child->getFirstFact('BIRT'); - if ($childsBirth && !$childsBirth->place()->isEmpty()) { + if ($childsBirth && $childsBirth->place()->gedcomName() !== '') { $facts[] = $childsBirth; } } diff --git a/app/Place.php b/app/Place.php index de97ebc3dd..02e1219625 100644 --- a/app/Place.php +++ b/app/Place.php @@ -18,14 +18,18 @@ declare(strict_types=1); namespace Fisharebest\Webtrees; use Illuminate\Database\Capsule\Manager as DB; +use Illuminate\Support\Collection; /** * A GEDCOM place (PLAC) object. */ class Place { - /** @var string[] e.g. array('Westminster', 'London', 'England') */ - private $gedcom_place; + /** @var string e.g. "Westminster, London, England" */ + private $place_name; + + /** @var Collection|string[] The parts of a place name, e.g. ["Westminster", "London", "England"] */ + private $parts; /** @var Tree We may have the same place name in different trees. */ private $tree; @@ -33,57 +37,93 @@ class Place /** * Create a place. * - * @param string $gedcom_place + * @param string $place_name * @param Tree $tree */ - public function __construct($gedcom_place, Tree $tree) + public function __construct(string $place_name, Tree $tree) { - if ($gedcom_place === '') { - $this->gedcom_place = []; - } else { - $this->gedcom_place = explode(Gedcom::PLACE_SEPARATOR, $gedcom_place); - } + // Ignore any empty parts in place names such as "Village, , , Country". + $this->parts = (new Collection(preg_split(Gedcom::PLACE_SEPARATOR_REGEX, $place_name))) + ->filter(); + + // Rebuild the placename in the correct format. + $this->place_name = $this->parts->implode(Gedcom::PLACE_SEPARATOR); + $this->tree = $tree; } /** - * Extract the country (last part) of a place name. + * Get the higher level place. * - * @return string - e.g. "England" + * @return Place */ - public function lastPart(): string + public function parent(): Place { - return $this->gedcom_place[count($this->gedcom_place) - 1] ?? ''; + return new static($this->parts->slice(1)->implode(Gedcom::PLACE_SEPARATOR), $this->tree); } /** - * Get the identifier for a place. + * The database row that contains this place. + * Note that due to database collation, both "Quebec" and "Québec" will share the same row. * * @return int */ - public function getPlaceId(): int + public function id(): int { - $place_id = 0; + return app()->make('cache.array')->rememberForever('place:' . $this->place_name, function () { + // The "top-level" place won't exist in the database. + if ($this->parts->isEmpty()) { + return 0; + } + + $parent_place = $this->parent(); - foreach (array_reverse($this->gedcom_place) as $place) { $place_id = (int) DB::table('places') ->where('p_file', '=', $this->tree->id()) - ->where('p_place', '=', $place) - ->where('p_parent_id', '=', $place_id) + ->where('p_place', '=', $this->parts->first()) + ->where('p_parent_id', '=', $parent_place->id()) ->value('p_id'); - } - return $place_id; + if ($place_id === 0) { + $place = $this->parts->first(); + + DB::table('places')->insert([ + 'p_file' => $this->tree->id(), + 'p_place' => $place, + 'p_parent_id' => $parent_place->id(), + 'p_std_soundex' => Soundex::russell($place), + 'p_dm_soundex' => Soundex::daitchMokotoff($place), + ]); + + $place_id = (int) DB::connection()->getPdo()->lastInsertId(); + } + + return $place_id; + }); } /** - * Get the higher level place. + * Extract the locality (first parts) of a place name. * - * @return Place + * @param int $n + * + * @return Collection */ - public function getParentPlace(): Place + public function firstParts(int $n): Collection { - return new self(implode(Gedcom::PLACE_SEPARATOR, array_slice($this->gedcom_place, 1)), $this->tree); + return $this->parts->slice(0, $n); + } + + /** + * Extract the country (last parts) of a place name. + * + * @param int $n + * + * @return Collection + */ + public function lastParts(int $n): Collection + { + return $this->parts->slice(-$n); } /** @@ -93,15 +133,15 @@ class Place */ public function getChildPlaces(): array { - if ($this->getPlaceId()) { - $parent_text = Gedcom::PLACE_SEPARATOR . $this->getGedcomName(); + if ($this->place_name !== '') { + $parent_text = Gedcom::PLACE_SEPARATOR . $this->place_name; } else { $parent_text = ''; } return DB::table('places') ->where('p_file', '=', $this->tree->id()) - ->where('p_parent_id', '=', $this->getPlaceId()) + ->where('p_parent_id', '=', $this->id()) ->orderBy(DB::raw('p_place /*! COLLATE ' . I18N::collation() . ' */')) ->pluck('p_place') ->map(function (string $place) use ($parent_text): Place { @@ -118,19 +158,19 @@ class Place public function url(): string { return route('place-hierarchy', [ - 'parent' => array_reverse($this->gedcom_place), + 'parent' => $this->parts->reverse()->all(), 'ged' => $this->tree->name(), ]); } /** - * Format this name for GEDCOM data. + * Format this place for GEDCOM data. * * @return string */ - public function getGedcomName(): string + public function gedcomName(): string { - return implode(Gedcom::PLACE_SEPARATOR, $this->gedcom_place); + return $this->place_name; } /** @@ -138,85 +178,62 @@ class Place * * @return string */ - public function getPlaceName(): string + public function placeName(): string { - if (empty($this->gedcom_place)) { - return I18N::translate('unknown'); - } + $place_name = $this->parts->first() ?? I18N::translate('unknown'); - return '<span dir="auto">' . e($this->gedcom_place[0]) . '</span>'; - } - - /** - * Is this a null/empty/missing/invalid place? - * - * @return bool - */ - public function isEmpty(): bool - { - return empty($this->gedcom_place); + return '<span dir="auto">' . e($place_name) . '</span>'; } /** * Generate the place name for display, including the full hierarchy. * + * @param bool $link + * * @return string */ - public function getFullName() + public function fullName(bool $link = false) { - if (true) { - // If a place hierarchy is a single entity - return '<span dir="auto">' . e(implode(I18N::$list_separator, $this->gedcom_place)) . '</span>'; + if ($this->parts->isEmpty()) { + return ''; } - // If a place hierarchy is a list of distinct items - $tmp = []; - foreach ($this->gedcom_place as $place) { - $tmp[] = '<span dir="auto">' . e($place) . '</span>'; + $full_name = $this->parts->implode(I18N::$list_separator); + + if ($link) { + return '<a dir="auto" href="' . e($this->url()) . '">' . e($full_name) . '</a>'; } - return implode(I18N::$list_separator, $tmp); + return '<span dir="auto">' . e($full_name) . '</span>'; } /** * For lists and charts, where the full name won’t fit. * + * @param bool $link + * * @return string */ - public function getShortName() + public function shortName(bool $link = false) { $SHOW_PEDIGREE_PLACES = (int) $this->tree->getPreference('SHOW_PEDIGREE_PLACES'); - if ($SHOW_PEDIGREE_PLACES >= count($this->gedcom_place)) { - // A short place name - no need to abbreviate - return $this->getFullName(); - } - // Abbreviate the place name, for lists if ($this->tree->getPreference('SHOW_PEDIGREE_PLACES_SUFFIX')) { - // The *last* $SHOW_PEDIGREE_PLACES components - $short_name = implode(Gedcom::PLACE_SEPARATOR, array_slice($this->gedcom_place, -$SHOW_PEDIGREE_PLACES)); + $parts = $this->lastParts($SHOW_PEDIGREE_PLACES); } else { - // The *first* $SHOW_PEDIGREE_PLACES components - $short_name = implode(Gedcom::PLACE_SEPARATOR, array_slice($this->gedcom_place, 0, $SHOW_PEDIGREE_PLACES)); + $parts = $this->firstParts($SHOW_PEDIGREE_PLACES); } + $short_name = $parts->implode(I18N::$list_separator); + // Add a tool-tip showing the full name - return '<span title="' . e($this->getGedcomName()) . '" dir="auto">' . e($short_name) . '</span>'; - } + $title = strip_tags($this->fullName()); - /** - * For the Place hierarchy "list all" option - * - * @return string - */ - public function getReverseName(): string - { - $tmp = []; - foreach (array_reverse($this->gedcom_place) as $place) { - $tmp[] = '<span dir="auto">' . e($place) . '</span>'; + if ($link) { + return '<a dir="auto" href="' . e($this->url()) . '" title="' . $title . '"">' . e($short_name) . '</a>'; } - return implode(I18N::$list_separator, $tmp); + return '<span dir="auto">' . e($short_name) . '</span>'; } } diff --git a/app/Report/ReportParserGenerate.php b/app/Report/ReportParserGenerate.php index 8efe16f0fe..d02a24de03 100644 --- a/app/Report/ReportParserGenerate.php +++ b/app/Report/ReportParserGenerate.php @@ -1021,7 +1021,7 @@ class ReportParserGenerate extends ReportParserBase break; case 'PLAC': $tmp = new Place($value, $this->tree); - $value = $tmp->getShortName(); + $value = $tmp->shortName(); break; } if ($useBreak === '1') { diff --git a/app/Services/SearchService.php b/app/Services/SearchService.php index d7f73ad025..f9ed013b64 100644 --- a/app/Services/SearchService.php +++ b/app/Services/SearchService.php @@ -715,7 +715,7 @@ class SearchService if ($parts[1] === 'PLAC') { // *:PLAC foreach ($individual->facts([$parts[0]]) as $fact) { - if (preg_match($regex, $fact->place()->getGedcomName())) { + if (preg_match($regex, $fact->place()->gedcomName())) { return true; } } @@ -723,7 +723,7 @@ class SearchService // FAMS:*:PLAC foreach ($individual->getSpouseFamilies() as $family) { foreach ($family->facts([$parts[1]]) as $fact) { - if (preg_match($regex, $fact->place()->getGedcomName())) { + if (preg_match($regex, $fact->place()->gedcomName())) { return true; } } diff --git a/app/Stats.php b/app/Stats.php index aa986a3fe7..4066aa5c99 100644 --- a/app/Stats.php +++ b/app/Stats.php @@ -1877,7 +1877,7 @@ class Stats arsort($places); foreach ($places as $place => $count) { $tmp = new Place($place, $this->tree); - $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->getFullName() . '</a>'; + $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->fullName() . '</a>'; $top10[] = '<li>' . $place . ' - ' . I18N::number($count) . '</li>'; if ($i++ == 10) { break; @@ -1901,7 +1901,7 @@ class Stats arsort($places); foreach ($places as $place => $count) { $tmp = new Place($place, $this->tree); - $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->getFullName() . '</a>'; + $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->fullName() . '</a>'; $top10[] = '<li>' . $place . ' - ' . I18N::number($count) . '</li>'; if ($i++ == 10) { break; @@ -1925,7 +1925,7 @@ class Stats arsort($places); foreach ($places as $place => $count) { $tmp = new Place($place, $this->tree); - $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->getFullName() . '</a>'; + $place = '<a href="' . e($tmp->url()) . '" class="list_item">' . $tmp->fullName() . '</a>'; $top10[] = '<li>' . $place . ' - ' . I18N::number($count) . '</li>'; if ($i++ == 10) { break; diff --git a/resources/views/edit/paste-fact-row.phtml b/resources/views/edit/paste-fact-row.phtml index 8baa4434cd..759f144d7f 100644 --- a/resources/views/edit/paste-fact-row.phtml +++ b/resources/views/edit/paste-fact-row.phtml @@ -21,7 +21,7 @@ – <?= $fact->date()->minimumDate()->format('%Y') ?> <?php endif ?> <?php if (!$fact->place()->isEmpty()) : ?> - – <?= $fact->place()->getShortName() ?> + – <?= $fact->place()->shortName() ?> <?php endif ?> </option> <?php endforeach ?> diff --git a/resources/views/lists/families-table.phtml b/resources/views/lists/families-table.phtml index b0a54deb9a..361c4790d2 100644 --- a/resources/views/lists/families-table.phtml +++ b/resources/views/lists/families-table.phtml @@ -321,9 +321,7 @@ for ($year = 1550; $year < 2030; $year += 10) { <!-- Marriage place --> <td> <?php foreach ($family->getAllMarriagePlaces() as $n => $marriage_place) : ?> - <a href="<?= e($marriage_place->url()) ?>" title="<?= strip_tags($marriage_place->getFullName()) ?>"> - <?= $marriage_place->getShortName() ?> - </a> + <?= $marriage_place->shortName(true) ?> <br> <?php endforeach ?> </td> diff --git a/resources/views/lists/individuals-table.phtml b/resources/views/lists/individuals-table.phtml index f878aa4bf1..588710f130 100644 --- a/resources/views/lists/individuals-table.phtml +++ b/resources/views/lists/individuals-table.phtml @@ -159,7 +159,7 @@ for ($year = 1550; $year < 2030; $year += 10) { data-filter-value="Y100" title="<?= I18N::translate('Show individuals who died within the last 100 years.') ?>" > - <?= I18N::translate('Death') ?><<=100 + <?= I18N::translate('Death') ?><=100 </button> </div> <div class="btn-group" data-toggle="buttons"> @@ -295,9 +295,7 @@ for ($year = 1550; $year < 2030; $year += 10) { <!-- Birth place --> <td> <?php foreach ($individual->getAllBirthPlaces() as $n => $birth_place) : ?> - <a href="<?= e($birth_place->url()) ?>" title="<?= strip_tags($birth_place->getFullName()) ?>"> - <?= $birth_place->getShortName() ?> - </a> + <?= $birth_place->shortName(true) ?> <br> <?php endforeach ?> </td> @@ -342,9 +340,7 @@ for ($year = 1550; $year < 2030; $year += 10) { <!-- Death place --> <td> <?php foreach ($individual->getAllDeathPlaces() as $n => $death_place) : ?> - <a href="<?= e($death_place->url()) ?>" title="<?= e(strip_tags($death_place->getFullName())) ?>"> - <?= $death_place->getShortName() ?> - </a> + <?= $death_place->shortName(true) ?> <br> <?php endforeach ?> </td> diff --git a/resources/views/modules/pedigree-map/events.phtml b/resources/views/modules/pedigree-map/events.phtml index df2f431386..ae60f14c00 100644 --- a/resources/views/modules/pedigree-map/events.phtml +++ b/resources/views/modules/pedigree-map/events.phtml @@ -22,10 +22,10 @@ <?= $date ?> </div> -<?php if (!$place->isEmpty()) : ?> +<?php if ($place->gedcomName() !== '') : ?> <div> <a href="<?= e($place->url()) ?>"> - <?= $place->getFullName() ?> + <?= $place->fullName() ?> </a> </div> <?php endif ?> diff --git a/resources/views/modules/relatives/family.phtml b/resources/views/modules/relatives/family.phtml index a7dab7cada..72e119089d 100644 --- a/resources/views/modules/relatives/family.phtml +++ b/resources/views/modules/relatives/family.phtml @@ -107,7 +107,7 @@ <th scope="row"> </th> <td> - <?= GedcomTag::getLabelValue($fact->getTag(), $fact->date()->display() . ' — ' . $fact->place()->getFullName()) ?> + <?= GedcomTag::getLabelValue($fact->getTag(), $fact->date()->display() . ' — ' . $fact->place()->fullName()) ?> </td> </tr> diff --git a/resources/views/modules/timeline-chart/chart.phtml b/resources/views/modules/timeline-chart/chart.phtml index 3cc349edeb..629c01191a 100644 --- a/resources/views/modules/timeline-chart/chart.phtml +++ b/resources/views/modules/timeline-chart/chart.phtml @@ -356,7 +356,7 @@ } echo ' ' . e($desc); if (!$event->place()->isEmpty()) { - echo ' — ' . $event->place()->getShortName(); + echo ' — ' . $event->place()->shortName(); } // Print spouses names for family events if ($event->record() instanceof Family) { diff --git a/resources/views/modules/todays_events/list.phtml b/resources/views/modules/todays_events/list.phtml index a3796f2450..2926991a3e 100644 --- a/resources/views/modules/todays_events/list.phtml +++ b/resources/views/modules/todays_events/list.phtml @@ -13,7 +13,7 @@ <?= $fact->label() . ' — ' . $fact->date()->display(true); ?> <?= ' (' . I18N::timeAgo($fact->anniv * 365 * 24 * 60 * 60) . ')'; ?> <?php if (!$fact->place()->isEmpty()) : ?> - <?= ' — <a href="' . e($fact->place()->url()) . '">' . $fact->place()->getFullName() . '</a>'; ?> + <?= ' — <a href="' . e($fact->place()->url()) . '">' . $fact->place()->fullName() . '</a>'; ?> <?php endif ?> </div> <?php endforeach ?> diff --git a/resources/views/modules/upcoming_events/list.phtml b/resources/views/modules/upcoming_events/list.phtml index a3796f2450..c708ad8bab 100644 --- a/resources/views/modules/upcoming_events/list.phtml +++ b/resources/views/modules/upcoming_events/list.phtml @@ -12,8 +12,8 @@ <div class="indent"> <?= $fact->label() . ' — ' . $fact->date()->display(true); ?> <?= ' (' . I18N::timeAgo($fact->anniv * 365 * 24 * 60 * 60) . ')'; ?> - <?php if (!$fact->place()->isEmpty()) : ?> - <?= ' — <a href="' . e($fact->place()->url()) . '">' . $fact->place()->getFullName() . '</a>'; ?> + <?php if ($fact->place()->gedcomName() !== '') : ?> + — <?=$fact->place()->fullName(true); ?> <?php endif ?> </div> <?php endforeach ?> diff --git a/resources/views/place-hierarchy.phtml b/resources/views/place-hierarchy.phtml index d31579517f..453f729f67 100644 --- a/resources/views/place-hierarchy.phtml +++ b/resources/views/place-hierarchy.phtml @@ -12,7 +12,7 @@ <ul class="col list_value_wrap mr-1"> <?php foreach ($column as $item) : ?> <li> - <a href="<?= e($item->url()) ?>"><?= $item->getPlaceName() ?></a> + <a href="<?= e($item->url()) ?>"><?= $item->placeName() ?></a> </li> <?php endforeach ?> </ul> diff --git a/resources/views/place-list.phtml b/resources/views/place-list.phtml index 1b3b867a6e..693589a7ff 100644 --- a/resources/views/place-list.phtml +++ b/resources/views/place-list.phtml @@ -11,7 +11,7 @@ <ul class="col list_value_wrap mr-1"> <?php foreach ($column as $item) : ?> <li> - <a href="<?= e($item->url()) ?>"><?= $item->getFullName() ?></a> + <a href="<?= e($item->url()) ?>"><?= $item->fullName() ?></a> </li> <?php endforeach ?> </ul> diff --git a/resources/views/place-sidebar.phtml b/resources/views/place-sidebar.phtml index 3f19222247..daa487f1a8 100644 --- a/resources/views/place-sidebar.phtml +++ b/resources/views/place-sidebar.phtml @@ -5,10 +5,10 @@ <div class="d-table-cell label"> <?php if ($showlink) : ?> <a href="<?= e($place->url()) ?>"> - <?= $place->getPlaceName() ?> + <?= $place->placeName() ?> </a> <?php else : ?> - <?= $place->getPlaceName() ?> + <?= $place->placeName() ?> <?php endif ?> </div> <div class="d-table-cell text-right"> diff --git a/resources/views/places-page.phtml b/resources/views/places-page.phtml index 95c6d4b8bf..647c96ec37 100644 --- a/resources/views/places-page.phtml +++ b/resources/views/places-page.phtml @@ -14,11 +14,11 @@ <?php foreach ($breadcrumbs as $item) : ?> - - <a href="<?= e($item->url()) ?>" dir="auto"><?= $item->getPlaceName() ?></a> + <a href="<?= e($item->url()) ?>" dir="auto"><?= $item->placeName() ?></a> <?php endforeach ?> <?php if ($current) : ?> - - <?= $current->getPlaceName() ?> + - <?= $current->placeName() ?> <?php endif ?> </h5> <?php if ($note) : ?> diff --git a/tests/app/Census/CensusColumnBirthPlaceSimpleTest.php b/tests/app/Census/CensusColumnBirthPlaceSimpleTest.php index 65199c411b..17f872fd1a 100644 --- a/tests/app/Census/CensusColumnBirthPlaceSimpleTest.php +++ b/tests/app/Census/CensusColumnBirthPlaceSimpleTest.php @@ -46,7 +46,7 @@ class CensusColumnBirthPlaceSimpleTest extends \Fisharebest\Webtrees\TestCase private function getPlaceMock($place): Place { $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); + $placeMock->shouldReceive('gedcomName')->andReturn($place); return $placeMock; } diff --git a/tests/app/Census/CensusColumnBirthPlaceTest.php b/tests/app/Census/CensusColumnBirthPlaceTest.php index e6a4e3179f..8e7d39b795 100644 --- a/tests/app/Census/CensusColumnBirthPlaceTest.php +++ b/tests/app/Census/CensusColumnBirthPlaceTest.php @@ -46,7 +46,7 @@ class CensusColumnBirthPlaceTest extends \Fisharebest\Webtrees\TestCase private function getPlaceMock($place): Place { $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); + $placeMock->shouldReceive('gedcomName')->andReturn($place); return $placeMock; } diff --git a/tests/app/Census/CensusColumnBornForeignPartsTest.php b/tests/app/Census/CensusColumnBornForeignPartsTest.php index bcd69218b7..84aa45c588 100644 --- a/tests/app/Census/CensusColumnBornForeignPartsTest.php +++ b/tests/app/Census/CensusColumnBornForeignPartsTest.php @@ -19,6 +19,7 @@ namespace Fisharebest\Webtrees\Census; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Place; +use Illuminate\Support\Collection; use Mockery; /** @@ -48,8 +49,8 @@ class CensusColumnBornForeignPartsTest extends \Fisharebest\Webtrees\TestCase $placeParts = explode(', ', $place); $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); - $placeMock->shouldReceive('lastPart')->andReturn(end($placeParts)); + $placeMock->shouldReceive('gedcomName')->andReturn($place); + $placeMock->shouldReceive('lastParts')->andReturn((new Collection($placeParts))->slice(-1)); return $placeMock; } diff --git a/tests/app/Census/CensusColumnFatherBirthPlaceSimpleTest.php b/tests/app/Census/CensusColumnFatherBirthPlaceSimpleTest.php index 24bcd10d91..96b89eb584 100644 --- a/tests/app/Census/CensusColumnFatherBirthPlaceSimpleTest.php +++ b/tests/app/Census/CensusColumnFatherBirthPlaceSimpleTest.php @@ -20,6 +20,7 @@ namespace Fisharebest\Webtrees\Census; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Place; +use Illuminate\Support\Collection; use Mockery; /** @@ -49,8 +50,8 @@ class CensusColumnFatherBirthPlaceSimpleTest extends \Fisharebest\Webtrees\TestC $placeParts = explode(', ', $place); $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); - $placeMock->shouldReceive('lastPart')->andReturn(end($placeParts)); + $placeMock->shouldReceive('gedcomName')->andReturn($place); + $placeMock->shouldReceive('lastParts')->andReturn(new Collection($placeParts)); return $placeMock; } diff --git a/tests/app/Census/CensusColumnFatherBirthPlaceTest.php b/tests/app/Census/CensusColumnFatherBirthPlaceTest.php index 9d29208fac..537cc910e6 100644 --- a/tests/app/Census/CensusColumnFatherBirthPlaceTest.php +++ b/tests/app/Census/CensusColumnFatherBirthPlaceTest.php @@ -20,6 +20,7 @@ namespace Fisharebest\Webtrees\Census; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Place; +use Illuminate\Support\Collection; use Mockery; /** @@ -49,8 +50,8 @@ class CensusColumnFatherBirthPlaceTest extends \Fisharebest\Webtrees\TestCase $placeParts = explode(', ', $place); $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); - $placeMock->shouldReceive('lastPart')->andReturn(end($placeParts)); + $placeMock->shouldReceive('gedcomName')->andReturn($place); + $placeMock->shouldReceive('lastParts')->andReturn(new Collection($placeParts)); return $placeMock; } diff --git a/tests/app/Census/CensusColumnFatherForeignTest.php b/tests/app/Census/CensusColumnFatherForeignTest.php index cf01affb5a..ef93ada4ed 100644 --- a/tests/app/Census/CensusColumnFatherForeignTest.php +++ b/tests/app/Census/CensusColumnFatherForeignTest.php @@ -47,7 +47,7 @@ class CensusColumnFatherForeignTest extends \Fisharebest\Webtrees\TestCase private function getPlaceMock($place): Place { $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); + $placeMock->shouldReceive('gedcomName')->andReturn($place); return $placeMock; } diff --git a/tests/app/Census/CensusColumnMotherBirthPlaceSimpleTest.php b/tests/app/Census/CensusColumnMotherBirthPlaceSimpleTest.php index f470c16dd2..19e0a0fb53 100644 --- a/tests/app/Census/CensusColumnMotherBirthPlaceSimpleTest.php +++ b/tests/app/Census/CensusColumnMotherBirthPlaceSimpleTest.php @@ -20,6 +20,7 @@ namespace Fisharebest\Webtrees\Census; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Place; +use Illuminate\Support\Collection; use Mockery; /** @@ -49,8 +50,8 @@ class CensusColumnMotherBirthPlaceSimpleTest extends \Fisharebest\Webtrees\TestC $placeParts = explode(', ', $place); $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); - $placeMock->shouldReceive('lastPart')->andReturn(end($placeParts)); + $placeMock->shouldReceive('gedcomName')->andReturn($place); + $placeMock->shouldReceive('lastParts')->andReturn(new Collection($placeParts)); return $placeMock; } diff --git a/tests/app/Census/CensusColumnMotherBirthPlaceTest.php b/tests/app/Census/CensusColumnMotherBirthPlaceTest.php index 71dcae85f1..7d604dcccd 100644 --- a/tests/app/Census/CensusColumnMotherBirthPlaceTest.php +++ b/tests/app/Census/CensusColumnMotherBirthPlaceTest.php @@ -20,6 +20,7 @@ namespace Fisharebest\Webtrees\Census; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Place; +use Illuminate\Support\Collection; use Mockery; /** @@ -49,8 +50,8 @@ class CensusColumnMotherBirthPlaceTest extends \Fisharebest\Webtrees\TestCase $placeParts = explode(', ', $place); $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); - $placeMock->shouldReceive('lastPart')->andReturn(end($placeParts)); + $placeMock->shouldReceive('gedcomName')->andReturn($place); + $placeMock->shouldReceive('lastParts')->andReturn(new Collection($placeParts)); return $placeMock; } diff --git a/tests/app/Census/CensusColumnMotherForeignTest.php b/tests/app/Census/CensusColumnMotherForeignTest.php index a8384b6386..fe29f4dce7 100644 --- a/tests/app/Census/CensusColumnMotherForeignTest.php +++ b/tests/app/Census/CensusColumnMotherForeignTest.php @@ -47,7 +47,7 @@ class CensusColumnMotherForeignTest extends \Fisharebest\Webtrees\TestCase private function getPlaceMock($place): Place { $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); + $placeMock->shouldReceive('gedcomName')->andReturn($place); return $placeMock; } diff --git a/tests/app/Census/CensusColumnNationalityTest.php b/tests/app/Census/CensusColumnNationalityTest.php index fe6332e156..132b2b15f8 100644 --- a/tests/app/Census/CensusColumnNationalityTest.php +++ b/tests/app/Census/CensusColumnNationalityTest.php @@ -48,7 +48,7 @@ class CensusColumnNationalityTest extends \Fisharebest\Webtrees\TestCase private function getPlaceMock($place): Place { $placeMock = Mockery::mock(Place::class); - $placeMock->shouldReceive('getGedcomName')->andReturn($place); + $placeMock->shouldReceive('gedcomName')->andReturn($place); return $placeMock; } @@ -122,14 +122,14 @@ class CensusColumnNationalityTest extends \Fisharebest\Webtrees\TestCase public function testEmigrated(): void { $place1 = Mockery::mock('Fisharebest\Webtrees\Place'); - $place1->shouldReceive('getGedcomName')->andReturn('United States'); + $place1->shouldReceive('gedcomName')->andReturn('United States'); $fact1 = Mockery::mock(Fact::class); $fact1->shouldReceive('place')->andReturn($place1); $fact1->shouldReceive('date')->andReturn(new Date('1855')); $place2 = Mockery::mock('Fisharebest\Webtrees\Place'); - $place2->shouldReceive('getGedcomName')->andReturn('Australia'); + $place2->shouldReceive('gedcomName')->andReturn('Australia'); $fact2 = Mockery::mock(Fact::class); $fact2->shouldReceive('place')->andReturn($place2); |
