Return the details for a person

@param Individual  $individual
@param Family|null $family

@return string
348035
private function getPersonDetails(Individual $individual, Family $family = null): string
    {
        $chart_url = route('module', [
            'module' => 'tree',
            'action' => 'Chart',
            'xref'   => $individual->xref(),
            'ged'    => $individual->tree()->name(),
        ]);

        $hmtl = $this->getThumbnail($individual);
        $hmtl .= '<a class="tv_link" href="' . e($individual->url()) . '">' . $individual->fullName() . '</a> <a href="' . e($chart_url) . '" title="' . I18N::translate('Interactive tree of %s', strip_tags($individual->fullName())) . '" class="wt-icon-individual tv_link tv_treelink"></a>';
        foreach ($individual->facts(Gedcom::BIRTH_EVENTS, true) as $fact) {
            $hmtl .= $fact->summary();
        }
        if ($family) {
            foreach ($family->facts(Gedcom::MARRIAGE_EVENTS, true) as $fact) {
                $hmtl .= $fact->summary();
            }
        }
        foreach ($individual->facts(Gedcom::DEATH_EVENTS, true) as $fact) {
            $hmtl .= $fact->summary();
        }

        return '<div class="tv' . $individual->sex() . ' tv_person_expanded">' . $hmtl . '</div>';
    }
419361
public function generate(Individual $individual, Individual $head): string
    {
        foreach ($individual->spouseFamilies() as $family) {
            foreach ($family->facts(['MARR']) as $fact) {
                $marriage_jd = $fact->date()->julianDay();
                $census_jd   = $this->date()->julianDay();
                if ($marriage_jd <= $census_jd && $marriage_jd >= $census_jd - 365) {
                    // Use the GEDCOM month, as we need this in English - for the US census
                    return ucfirst(strtolower($fact->date()->minimumDate()->format('%O')));
                }
            }
        }

        return '';
    }
132400
protected function chartCompact(Individual $individual, ChartService $chart_service): ResponseInterface
    {
        $ancestors = $chart_service->sosaStradonitzAncestors($individual, 5);

        $html = view('modules/compact-chart/chart', [
            'ancestors' => $ancestors,
            'module'    => $this,
        ]);

        return response($html);
    }
238011
public function generate(Individual $individual, Individual $head): string
    {
        foreach ($individual->getAllNames() as $name) {
            $given = $name['givn'];
            $space_pos = strpos($given, ' ');

            if ($space_pos === false) {
                return $given;
            }

            return substr($given, 0, $space_pos + 2);
        }

        return '';
    }
226126
public function generate(Individual $individual, Individual $head): string
    {
        $birth_place  = (string) $individual->getBirthPlace()->lastParts(1)->first();
        $census_place = $this->place();

        if ($birth_place === 'Wales') {
            $birth_place = 'England';
        }

        if ($census_place === 'Wales') {
            $census_place = 'England';
        }

        if ($birth_place === $census_place || $birth_place === '') {
            return '';
        }

        if ($birth_place === 'England' || $birth_place === 'Scotland' || $birth_place === 'Ireland') {
            return substr($birth_place, 0, 1);
        }

        return 'F';
    }
922438
public function generate(Individual $individual, Individual $head): string
    {
        foreach ($individual->getAllNames() as $name) {
            return $name['givn'];
        }

        return '';
    }
509876
public function getPerson($personId, $fields = ['*'])
    {
        $apiUrl = $this->getEndpoint('people');
        $apiUrl .= $personId;

        $params = array(
            'fields' => implode(',', $fields)
        );

        $apiData = $this->apiGet($apiUrl, $params);

        return $this->decodeSingle($apiData);
    }
609580
public function historicEventsForIndividual(Individual $individual): Collection
    {
        $min_date = $individual->getEstimatedBirthDate();
        $max_date = $individual->getEstimatedDeathDate();

        return (new Collection($this->historicEventsAll()))
            ->map(static function (string $gedcom) use ($individual): Fact {
                return new Fact($gedcom, $individual, 'histo');
            })
            ->filter(static function (Fact $fact) use ($min_date, $max_date): bool {
                return Date::compare($fact->date(), $min_date) >= 0 && Date::compare($fact->date(), $max_date) <= 0;
            });
    }
671076
private function individualOptions(Individual $individual): array
    {
        $name = strip_tags($individual->fullName());

        if ($individual->sex() === 'F') {
            return [
                'self'              => $name,
                'parents'           => I18N::translate('%s, her parents and siblings', $name),
                'spouses'           => I18N::translate('%s, her spouses and children', $name),
                'ancestors'         => I18N::translate('%s and her ancestors', $name),
                'ancestor_families' => I18N::translate('%s, her ancestors and their families', $name),
                'descendants'       => I18N::translate('%s, her spouses and descendants', $name),
            ];
        }

        return [
            'self'              => $name,
            'parents'           => I18N::translate('%s, his parents and siblings', $name),
            'spouses'           => I18N::translate('%s, his spouses and children', $name),
            'ancestors'         => I18N::translate('%s and his ancestors', $name),
            'ancestor_families' => I18N::translate('%s, his ancestors and their families', $name),
            'descendants'       => I18N::translate('%s, his spouses and descendants', $name),
        ];
    }
969202
public function generate(Individual $individual, Individual $head): string
    {
        $family = $this->spouseFamily($individual);
        $sex    = $individual->sex();

        if ($family === null || $family->facts(['MARR'])->isEmpty()) {
            if ($this->isChild($individual)) {
                return $this->conditionChild($sex);
            }

            return $this->conditionSingle($sex);
        }

        if ($family->facts(['DIV'])->isNotEmpty()) {
            return $this->conditionDivorced($sex);
        }

        $spouse = $family->spouse($individual);
        if ($spouse instanceof Individual && $this->isDead($spouse)) {
            return $this->conditionWidowed($sex);
        }

        return $this->conditionMarried($sex);
    }
307193
private function addAncestorsToCart(Individual $individual): void
    {
        $this->addRecordToCart($individual);

        foreach ($individual->childFamilies() as $family) {
            foreach ($family->spouses() as $parent) {
                $this->addAncestorsToCart($parent);
            }
        }
    }
55956
protected final Person getMother(final Family family) {
        final FamilyNavigator navigator = new FamilyNavigator(family);
        return navigator.getMother();
    }
447361
private function summaryData(Individual $individual, Fact $fact): array
    {
        $record = $fact->record();
        $name   = '';
        $url    = '';
        $tag    = $fact->label();

        if ($record instanceof Family) {
            // Marriage
            $spouse = $record->spouse($individual);
            if ($spouse instanceof Individual) {
                $url  = $spouse->url();
                $name = $spouse->fullName();
            }
        } elseif ($record !== $individual) {
            // Birth of a child
            $url  = $record->url();
            $name = $record->fullName();
            $tag  = GedcomTag::getLabel('_BIRT_CHIL', $record);
        }

        return [
            'tag'    => $tag,
            'url'    => $url,
            'name'   => $name,
            'value'  => $fact->value(),
            'date'   => $fact->date()->display(true),
            'place'  => $fact->place(),
            'addtag' => false,
        ];
    }
684840
public function getChildFamilyLabel(Family $family): string
    {
        if (preg_match('/\n1 FAMC @' . $family->xref() . '@(?:\n[2-9].*)*\n2 PEDI (.+)/', $this->gedcom(), $match)) {
            // A specified pedigree
            return GedcomCodePedi::getChildFamilyLabel($match[1]);
        }

        // Default (birth) pedigree
        return GedcomCodePedi::getChildFamilyLabel('');
    }
880517
public function father(Individual $individual): ?Individual
    {
        $family = $individual->primaryChildFamily();

        if ($family) {
            return $family->husband();
        }

        return null;
    }
1238476
private function associateFacts(Individual $person): array
    {
        $facts = [];

        /** @var Individual[] $associates */
        $associates = array_merge(
            $person->linkedIndividuals('ASSO'),
            $person->linkedIndividuals('_ASSO'),
            $person->linkedFamilies('ASSO'),
            $person->linkedFamilies('_ASSO')
        );
        foreach ($associates as $associate) {
            foreach ($associate->facts() as $fact) {
                $arec = $fact->attribute('_ASSO');
                if (!$arec) {
                    $arec = $fact->attribute('ASSO');
                }
                if ($arec && trim($arec, '@') === $person->xref()) {
                    // Extract the important details from the fact
                    $factrec = '1 ' . $fact->getTag();
                    if (preg_match('/\n2 DATE .*/', $fact->gedcom(), $match)) {
                        $factrec .= $match[0];
                    }
                    if (preg_match('/\n2 PLAC .*/', $fact->gedcom(), $match)) {
                        $factrec .= $match[0];
                    }
                    if ($associate instanceof Family) {
                        foreach ($associate->spouses() as $spouse) {
                            $factrec .= "\n2 _ASSO @" . $spouse->xref() . '@';
                        }
                    } else {
                        $factrec .= "\n2 _ASSO @" . $associate->xref() . '@';
                    }
                    $facts[] = new Fact($factrec, $associate, 'asso');
                }
            }
        }

        return $facts;
    }
1324099
public function significantIndividual(UserInterface $user): Individual
    {
        $individual = null;

        if ($this->getUserPreference($user, 'rootid') !== '') {
            $individual = Individual::getInstance($this->getUserPreference($user, 'rootid'), $this);
        }

        if ($individual === null && $this->getUserPreference($user, 'gedcomid') !== '') {
            $individual = Individual::getInstance($this->getUserPreference($user, 'gedcomid'), $this);
        }

        if ($individual === null && $this->getPreference('PEDIGREE_ROOT_ID') !== '') {
            $individual = Individual::getInstance($this->getPreference('PEDIGREE_ROOT_ID'), $this);
        }
        if ($individual === null) {
            $xref = (string) DB::table('individuals')
                ->where('i_file', '=', $this->id())
                ->min('i_id');

            $individual = Individual::getInstance($xref, $this);
        }
        if ($individual === null) {
            // always return a record
            $individual = new Individual('I', '0 @I@ INDI', null, $this);
        }

        return $individual;
    }