-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2704bb1
commit af2bd43
Showing
3 changed files
with
73 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
namespace MagicSunday\Webtrees\PedigreeChart\Processor; | ||
|
||
use DOMDocument; | ||
use DOMNode; | ||
use DOMXPath; | ||
use Fisharebest\Webtrees\Individual; | ||
|
||
|
@@ -20,7 +21,7 @@ | |
* | ||
* @author Rico Sonntag <[email protected]> | ||
* @license https://opensource.org/licenses/GPL-3.0 GNU General Public License v3.0 | ||
* @link https://github.com/magicsunday/webtrees-module-base/ | ||
* @link https://github.com/magicsunday/webtrees-pedigree-chart/ | ||
*/ | ||
class NameProcessor | ||
{ | ||
|
@@ -34,6 +35,17 @@ class NameProcessor | |
*/ | ||
private const FULL_NAME = 'full'; | ||
|
||
/** | ||
* The XPath identifier to extract the first name parts (including the prefix). | ||
*/ | ||
private const XPATH_FIRST_NAMES | ||
= './/text()[count(.|(//span[@class="SURN"]/text() | //span[@class="SURN"]/following::text()))!=count((//span[@class="SURN"]/text() | //span[@class="SURN"]/following::text()))]'; | ||
|
||
/** | ||
* The XPath identifier to extract the last name parts (surname + surname suffix). | ||
*/ | ||
private const XPATH_LAST_NAMES = '//span[@class="NAME"]//span[@class="SURN"]/text()|//span[@class="SURN"]/following::text()'; | ||
|
||
/** | ||
* The XPath identifier to extract the starred name part. | ||
*/ | ||
|
@@ -97,7 +109,7 @@ private function getDomXPathInstance(string $input): DOMXPath | |
/** | ||
* Extracts the primary name from the individual. | ||
* | ||
* @param Individual|null $spouse | ||
* @param null|Individual $spouse | ||
* @param bool $useMarriedName TRUE to return the married name instead of the primary one | ||
* | ||
* @return array<string, string> | ||
|
@@ -164,36 +176,65 @@ private function replacePlaceholders(string $value): string | |
); | ||
} | ||
|
||
/** | ||
* Returns the full name of the individual without formatting of the individual parts of the name. | ||
* All placeholders were removed as we do not need them in this module. | ||
* | ||
* @return string | ||
*/ | ||
public function getFullName(): string | ||
{ | ||
// The name of the person without formatting of the individual parts of the name. | ||
// Remove placeholders as we do not need them in this module | ||
return $this->replacePlaceholders($this->primaryName[self::FULL_NAME_WITH_PLACEHOLDERS]); | ||
} | ||
|
||
/** | ||
* Splits a name into an array, removing all name placeholders. | ||
* | ||
* @param string $name | ||
* @param string[] $names | ||
* | ||
* @return string[] | ||
*/ | ||
private function splitAndCleanName(string $name): array | ||
private function splitAndCleanName(array $names): array | ||
{ | ||
$values = [[]]; | ||
|
||
foreach ($names as $name) { | ||
$values[] = explode(' ', $name); | ||
} | ||
|
||
// Remove empty values and reindex array | ||
return array_values( | ||
array_filter( | ||
explode( | ||
' ', | ||
$this->replacePlaceholders($name) | ||
) | ||
array_merge(...$values) | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Returns the full name of the individual without formatting of the individual parts of the name. | ||
* All placeholders were removed as we do not need them in this module. | ||
* Returns all name parts by given identifier. | ||
* | ||
* @return string | ||
* @param string $expression The XPath expression to execute | ||
* | ||
* @return string[] | ||
*/ | ||
public function getFullName(): string | ||
private function getNamesByIdentifier(string $expression): array | ||
{ | ||
// The name of the person without formatting of the individual parts of the name. | ||
// Remove placeholders as we do not need them in this module | ||
return $this->replacePlaceholders($this->primaryName[self::FULL_NAME_WITH_PLACEHOLDERS]); | ||
$nodeList = $this->xPath->query($expression); | ||
$names = []; | ||
|
||
if ($nodeList !== false) { | ||
/** @var DOMNode $node */ | ||
foreach ($nodeList as $node) { | ||
$names[] = $node->nodeValue ?? ''; | ||
} | ||
} | ||
|
||
// Remove all leading/trailing whitespace characters | ||
$names = array_map('trim', $names); | ||
|
||
return $this->splitAndCleanName($names); | ||
} | ||
|
||
/** | ||
|
@@ -203,7 +244,7 @@ public function getFullName(): string | |
*/ | ||
public function getFirstNames(): array | ||
{ | ||
return $this->splitAndCleanName($this->primaryName['givn']); | ||
return $this->getNamesByIdentifier(self::XPATH_FIRST_NAMES); | ||
} | ||
|
||
/** | ||
|
@@ -213,7 +254,7 @@ public function getFirstNames(): array | |
*/ | ||
public function getLastNames(): array | ||
{ | ||
return $this->splitAndCleanName($this->primaryName['surn']); | ||
return $this->getNamesByIdentifier(self::XPATH_LAST_NAMES); | ||
} | ||
|
||
/** | ||
|
@@ -247,7 +288,7 @@ public function getAlternateName(Individual $individual): string | |
$individual->canShowName() | ||
&& ($individual->getPrimaryName() !== $individual->getSecondaryName()) | ||
) { | ||
$allNames = $individual->getAllNames(); | ||
$allNames = $individual->getAllNames(); | ||
$alternativeName = $allNames[$individual->getSecondaryName()][self::FULL_NAME_WITH_PLACEHOLDERS]; | ||
|
||
return $this->replacePlaceholders($alternativeName); | ||
|