app/Individual.php
private static function isRelated(Individual $target, $distance): bool
    {
        static $cache = null;

        $user_individual = self::getInstance($target->tree->getUserPreference(Auth::user(), 'gedcomid'), $target->tree);
        if ($user_individual) {
            if (!$cache) {
                $cache = [
                    0 => [$user_individual],
                    1 => [],
                ];
                foreach ($user_individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                    $family = $fact->target();
                    if ($family instanceof Family) {
                        $cache[1][] = $family;
                    }
                }
            }
        } else {
            // No individual linked to this account? Cannot use relationship privacy.
            return true;
        }

        // Double the distance, as we count the INDI-FAM and FAM-INDI links separately
        $distance *= 2;

        // Consider each path length in turn
        for ($n = 0; $n <= $distance; ++$n) {
            if (array_key_exists($n, $cache)) {
                // We have already calculated all records with this length
                if ($n % 2 === 0 && in_array($target, $cache[$n], true)) {
                    return true;
                }
            } else {
                // Need to calculate these paths
                $cache[$n] = [];
                if ($n % 2 === 0) {
                    // Add FAM->INDI links
                    foreach ($cache[$n - 1] as $family) {
                        foreach ($family->facts(['HUSB', 'WIFE', 'CHIL'], false, Auth::PRIV_HIDE) as $fact) {
                            $individual = $fact->target();
                            // Don’t backtrack
                            if ($individual instanceof self && !in_array($individual, $cache[$n - 2], true)) {
                                $cache[$n][] = $individual;
                            }
                        }
                    }
                    if (in_array($target, $cache[$n], true)) {
                        return true;
                    }
                } else {
                    // Add INDI->FAM links
                    foreach ($cache[$n - 1] as $individual) {
                        foreach ($individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                            $family = $fact->target();
                            // Don’t backtrack
                            if ($family instanceof Family && !in_array($family, $cache[$n - 2], true)) {
                                $cache[$n][] = $family;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }
private static function isRelated(Individual $target, $distance): bool
    {
        static $cache = null;

        $user_individual = self::getInstance($target->tree->getUserPreference(Auth::user(), 'gedcomid'), $target->tree);
        if ($user_individual) {
            if (!$cache) {
                $cache = [
                    0 => [$user_individual],
                    1 => [],
                ];
                foreach ($user_individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                    $family = $fact->target();
                    if ($family instanceof Family) {
                        $cache[1][] = $family;
                    }
                }
            }
        } else {
            // No individual linked to this account? Cannot use relationship privacy.
            return true;
        }

        // Double the distance, as we count the INDI-FAM and FAM-INDI links separately
        $distance *= 2;

        // Consider each path length in turn
        for ($n = 0; $n <= $distance; ++$n) {
            if (array_key_exists($n, $cache)) {
                // We have already calculated all records with this length
                if ($n % 2 === 0 && in_array($target, $cache[$n], true)) {
                    return true;
                }
            } else {
                // Need to calculate these paths
                $cache[$n] = [];
                if ($n % 2 === 0) {
                    // Add FAM->INDI links
                    foreach ($cache[$n - 1] as $family) {
                        foreach ($family->facts(['HUSB', 'WIFE', 'CHIL'], false, Auth::PRIV_HIDE) as $fact) {
                            $individual = $fact->target();
                            // Don’t backtrack
                            if ($individual instanceof self && !in_array($individual, $cache[$n - 2], true)) {
                                $cache[$n][] = $individual;
                            }
                        }
                    }
                    if (in_array($target, $cache[$n], true)) {
                        return true;
                    }
                } else {
                    // Add INDI->FAM links
                    foreach ($cache[$n - 1] as $individual) {
                        foreach ($individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                            $family = $fact->target();
                            // Don’t backtrack
                            if ($family instanceof Family && !in_array($family, $cache[$n - 2], true)) {
                                $cache[$n][] = $family;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }
private static function isRelated ( Individual $ target , $ distance ) : bool { static $ cache = null ; $ user_individual = self :: getInstance ( $ target -> tree -> getUserPreference ( Auth :: user ( ) , 'gedcomid' ) , $ target -> tree ) ; if ( $ user_individual ) { if ( ! $ cache ) { $ cache = [ 0 => [ $ user_individual ] , 1 => [ ] , ] ; foreach ( $ user_individual -> facts ( [ 'FAMC' , 'FAMS' ] , false , Auth :: PRIV_HIDE ) as $ fact ) { $ family = $ fact -> target ( ) ; if ( $ family instanceof Family ) { $ cache [ 1 ] [ ] = $ family ; } } } } else { // No individual linked to this account? Cannot use relationship privacy. return true ; } // Double the distance, as we count the INDI-FAM and FAM-INDI links separately $ distance *= 2 ; // Consider each path length in turn for ( $ n = 0 ; $ n <= $ distance ; ++ $ n ) { if ( array_key_exists ( $ n , $ cache ) ) { // We have already calculated all records with this length if ( $ n % 2 === 0 && in_array ( $ target , $ cache [ $ n ] , true ) ) { return true ; } } else { // Need to calculate these paths $ cache [ $ n ] = [ ] ; if ( $ n % 2 === 0 ) { // Add FAM->INDI links foreach ( $ cache [ $ n - 1 ] as $ family ) { foreach ( $ family -> facts ( [ 'HUSB' , 'WIFE' , 'CHIL' ] , false , Auth :: PRIV_HIDE ) as $ fact ) { $ individual = $ fact -> target ( ) ; // Don’t backtrack if ( $ individual instanceof self && ! in_array ( $ individual , $ cache [ $ n - 2 ] , true ) ) { $ cache [ $ n ] [ ] = $ individual ; } } } if ( in_array ( $ target , $ cache [ $ n ] , true ) ) { return true ; } } else { // Add INDI->FAM links foreach ( $ cache [ $ n - 1 ] as $ individual ) { foreach ( $ individual -> facts ( [ 'FAMC' , 'FAMS' ] , false , Auth :: PRIV_HIDE ) as $ fact ) { $ family = $ fact -> target ( ) ; // Don’t backtrack if ( $ family instanceof Family && ! in_array ( $ family , $ cache [ $ n - 2 ] , true ) ) { $ cache [ $ n ] [ ] = $ family ; } } } } } } return false ; }
For relationship privacy calculations - is this individual a close relative?

@param Individual $target
@param int        $distance

@return bool
For relationship privacy calculations - is this individual a close relative?