Beispiel #1
0
function search_indis_soundex($soundex, $lastname, $firstname, $place, $geds)
{
    $sql = "SELECT DISTINCT i_id AS xref, i_file AS gedcom_id, i_gedcom AS gedcom FROM `##individuals`";
    if ($place) {
        $sql .= " JOIN `##placelinks` ON (pl_file=i_file AND pl_gid=i_id)";
        $sql .= " JOIN `##places` ON (p_file=pl_file AND pl_p_id=p_id)";
    }
    if ($firstname || $lastname) {
        $sql .= " JOIN `##name` ON (i_file=n_file AND i_id=n_id)";
    }
    $sql .= ' WHERE i_file IN (' . implode(',', $geds) . ')';
    switch ($soundex) {
        case 'Russell':
            $givn_sdx = WT_Soundex::soundex_std($firstname);
            $surn_sdx = WT_Soundex::soundex_std($lastname);
            $plac_sdx = WT_Soundex::soundex_std($place);
            $field = 'std';
            break;
        default:
        case 'DaitchM':
            $givn_sdx = WT_Soundex::soundex_dm($firstname);
            $surn_sdx = WT_Soundex::soundex_dm($lastname);
            $plac_sdx = WT_Soundex::soundex_dm($place);
            $field = 'dm';
            break;
    }
    // Nothing to search for?  Return nothing.
    if (!$givn_sdx && !$surn_sdx && !$plac_sdx) {
        return array();
    }
    $sql_args = array();
    if ($firstname && $givn_sdx) {
        $givn_sdx = explode(':', $givn_sdx);
        foreach ($givn_sdx as $k => $v) {
            $givn_sdx[$k] = "n_soundex_givn_{$field} LIKE CONCAT('%', ?, '%')";
            $sql_args[] = $v;
        }
        $sql .= ' AND (' . implode(' OR ', $givn_sdx) . ')';
    }
    if ($lastname && $surn_sdx) {
        $surn_sdx = explode(':', $surn_sdx);
        foreach ($surn_sdx as $k => $v) {
            $surn_sdx[$k] = "n_soundex_surn_{$field} LIKE CONCAT('%', ?, '%')";
            $sql_args[] = $v;
        }
        $sql .= ' AND (' . implode(' OR ', $surn_sdx) . ')';
    }
    if ($place && $plac_sdx) {
        $plac_sdx = explode(':', $plac_sdx);
        foreach ($plac_sdx as $k => $v) {
            $plac_sdx[$k] = "p_{$field}_soundex LIKE CONCAT('%', ?, '%')";
            $sql_args[] = $v;
        }
        $sql .= ' AND (' . implode(' OR ', $plac_sdx) . ')';
    }
    // Group results by gedcom, to minimise switching between privacy files
    $sql .= ' ORDER BY gedcom_id';
    $list = array();
    $rows = WT_DB::prepare($sql)->execute($sql_args)->fetchAll();
    $GED_ID = WT_GED_ID;
    foreach ($rows as $row) {
        // Switch privacy file if necessary
        if ($row->gedcom_id != $GED_ID) {
            $GEDCOM = get_gedcom_from_id($row->gedcom_id);
            load_gedcom_settings($row->gedcom_id);
            $GED_ID = $row->gedcom_id;
        }
        $indi = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
        if ($indi->canShowName()) {
            $list[] = $indi;
        }
    }
    // Switch privacy file if necessary
    if ($GED_ID != WT_GED_ID) {
        $GEDCOM = WT_GEDCOM;
        load_gedcom_settings(WT_GED_ID);
    }
    return $list;
}
Beispiel #2
0
 private function getDescendantsHtml(WT_Individual $individual, WT_Family $parents = null)
 {
     // A person has many names.  Select the one that matches the searched surname
     $person_name = '';
     foreach ($individual->getAllNames() as $name) {
         list($surn1) = explode(",", $name['sort']);
         if (stripos($surn1, $this->surname) !== false || stripos($this->surname, $surn1) !== false || $this->soundex_std && WT_Soundex::compare(WT_Soundex::soundex_std($surn1), WT_Soundex::soundex_std($this->surname)) || $this->soundex_dm && WT_Soundex::compare(WT_Soundex::soundex_dm($surn1), WT_Soundex::soundex_dm($this->surname))) {
             $person_name = $name['full'];
             break;
         }
     }
     // No matching name?  Typically children with a different surname.  The tree stops here.
     if (!$person_name) {
         return '<li title="' . strip_tags($individual->getFullName()) . '">' . $individual->getSexImage() . '…</li>';
     }
     // Is this individual one of our ancestors?
     $sosa = array_search($individual, $this->ancestors, true);
     if ($sosa) {
         $sosa_class = 'search_hit';
         $sosa_html = ' <a class="details1 ' . $individual->getBoxStyle() . '" title="' . WT_I18N::translate('Sosa') . '" href="relationship.php?pid2=' . WT_USER_ROOT_ID . '&amp;pid1=' . $individual->getXref() . '">' . $sosa . '</a>' . self::sosaGeneration($sosa);
     } else {
         $sosa_class = '';
         $sosa_html = '';
     }
     // Generate HTML for this individual, and all their descendants
     $indi_html = $individual->getSexImage() . '<a class="' . $sosa_class . '" href="' . $individual->getHtmlUrl() . '">' . $person_name . '</a> ' . $individual->getLifeSpan() . $sosa_html;
     // If this is not a birth pedigree (e.g. an adoption), highlight it
     if ($parents) {
         $pedi = '';
         foreach ($individual->getFacts('FAMC') as $fact) {
             if ($fact->getTarget() === $parents) {
                 $pedi = $fact->getAttribute('PEDI');
                 break;
             }
         }
         if ($pedi && $pedi != 'birth') {
             $indi_html = '<span class="red">' . WT_Gedcom_Code_Pedi::getValue($pedi, $individual) . '</span> ' . $indi_html;
         }
     }
     // spouses and children
     $spouse_families = $individual->getSpouseFamilies();
     if ($spouse_families) {
         usort($spouse_families, array('WT_Family', 'compareMarrDate'));
         $fam_html = '';
         foreach ($spouse_families as $family) {
             $fam_html .= $indi_html;
             // Repeat the individual details for each spouse.
             $spouse = $family->getSpouse($individual);
             if ($spouse) {
                 $sosa = array_search($spouse, $this->ancestors, true);
                 if ($sosa) {
                     $sosa_class = 'search_hit';
                     $sosa_html = ' <a class="details1 ' . $spouse->getBoxStyle() . '" title="' . WT_I18N::translate('Sosa') . '" href="relationship.php?pid2=' . WT_USER_ROOT_ID . '&amp;pid1=' . $spouse->getXref() . '"> ' . $sosa . ' </a>' . self::sosaGeneration($sosa);
                 } else {
                     $sosa_class = '';
                     $sosa_html = '';
                 }
                 $marriage_year = $family->getMarriageYear();
                 if ($marriage_year) {
                     $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . strip_tags($family->getMarriageDate()->Display()) . '"><i class="icon-rings"></i>' . $marriage_year . '</a>';
                 } elseif ($family->getFirstFact('MARR')) {
                     $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . WT_Gedcom_Tag::getLabel('MARR') . '"><i class="icon-rings"></i></a>';
                 } elseif ($family->getFirstFact('_NMR')) {
                     $fam_html .= ' <a href="' . $family->getHtmlUrl() . '" title="' . WT_Gedcom_Tag::getLabel('_NMR') . '"><i class="icon-rings"></i></a>';
                 }
                 $fam_html .= ' ' . $spouse->getSexImage() . '<a class="' . $sosa_class . '" href="' . $spouse->getHtmlUrl() . '">' . $spouse->getFullName() . '</a> ' . $spouse->getLifeSpan() . ' ' . $sosa_html;
             }
             $fam_html .= '<ol>';
             foreach ($family->getChildren() as $child) {
                 $fam_html .= $this->getDescendantsHtml($child, $family);
             }
             $fam_html .= '</ol>';
         }
         return '<li>' . $fam_html . '</li>';
     } else {
         // No spouses - just show the individual
         return '<li>' . $indi_html . '</li>';
     }
 }
Beispiel #3
0
 function advancedSearch($justSql = false, $table = "individuals", $prefix = "i")
 {
     $this->myindilist = array();
     $fct = count($this->fields);
     if ($fct == 0) {
         return;
     }
     // Dynamic SQL query, plus bind variables
     $sql = "SELECT DISTINCT ind.i_id AS xref, ind.i_file AS gedcom_id, ind.i_gedcom AS gedcom FROM `##individuals` ind";
     $bind = array();
     // Join the following tables
     $father_name = false;
     $mother_name = false;
     $spouse_family = false;
     $indi_name = false;
     $indi_date = false;
     $fam_date = false;
     $indi_plac = false;
     $fam_plac = false;
     foreach ($this->fields as $n => $field) {
         if ($this->values[$n]) {
             if (substr($field, 0, 14) == 'FAMC:HUSB:NAME') {
                 $father_name = true;
             } elseif (substr($field, 0, 14) == 'FAMC:WIFE:NAME') {
                 $mother_name = true;
             } elseif (substr($field, 0, 4) == 'NAME') {
                 $indi_name = true;
             } elseif (strpos($field, ':DATE') !== false) {
                 if (substr($field, 0, 4) == 'FAMS') {
                     $fam_date = true;
                     $spouse_family = true;
                 } else {
                     $indi_date = true;
                 }
             } elseif (strpos($field, ':PLAC') !== false) {
                 if (substr($field, 0, 4) == 'FAMS') {
                     $fam_plac = true;
                     $spouse_family = true;
                 } else {
                     $indi_plac = true;
                 }
             }
         }
     }
     if ($father_name || $mother_name) {
         $sql .= " JOIN `##link`   l_1 ON (l_1.l_file=ind.i_file AND l_1.l_from=ind.i_id AND l_1.l_type='FAMC')";
     }
     if ($father_name) {
         $sql .= " JOIN `##link`   l_2 ON (l_2.l_file=ind.i_file AND l_2.l_from=l_1.l_to AND l_2.l_type='HUSB')";
         $sql .= " JOIN `##name`   f_n ON (f_n.n_file=ind.i_file AND f_n.n_id  =l_2.l_to)";
     }
     if ($mother_name) {
         $sql .= " JOIN `##link`   l_3 ON (l_3.l_file=ind.i_file AND l_3.l_from=l_1.l_to AND l_3.l_type='WIFE')";
         $sql .= " JOIN `##name`   m_n ON (m_n.n_file=ind.i_file AND m_n.n_id  =l_3.l_to)";
     }
     if ($spouse_family) {
         $sql .= " JOIN `##link`     l_4 ON (l_4.l_file=ind.i_file AND l_4.l_from=ind.i_id AND l_4.l_type='FAMS')";
         $sql .= " JOIN `##families` fam ON (fam.f_file=ind.i_file AND fam.f_id  =l_4.l_to)";
     }
     if ($indi_name) {
         $sql .= " JOIN `##name`   i_n ON (i_n.n_file=ind.i_file AND i_n.n_id=ind.i_id)";
     }
     if ($indi_date) {
         $sql .= " JOIN `##dates`  i_d ON (i_d.d_file=ind.i_file AND i_d.d_gid=ind.i_id)";
     }
     if ($fam_date) {
         $sql .= " JOIN `##dates`  f_d ON (f_d.d_file=ind.i_file AND f_d.d_gid=fam.f_id)";
     }
     if ($indi_plac) {
         $sql .= " JOIN `##placelinks`   i_pl ON (i_pl.pl_file=ind.i_file AND i_pl.pl_gid =ind.i_id)";
         $sql .= " JOIN (" . "SELECT CONCAT_WS(', ', p1.p_place, p2.p_place, p3.p_place, p4.p_place, p5.p_place, p6.p_place, p7.p_place, p8.p_place, p9.p_place) AS place, p1.p_id AS id, p1.p_file AS file" . " FROM      `##places` AS p1" . " LEFT JOIN `##places` AS p2 ON (p1.p_parent_id=p2.p_id)" . " LEFT JOIN `##places` AS p3 ON (p2.p_parent_id=p3.p_id)" . " LEFT JOIN `##places` AS p4 ON (p3.p_parent_id=p4.p_id)" . " LEFT JOIN `##places` AS p5 ON (p4.p_parent_id=p5.p_id)" . " LEFT JOIN `##places` AS p6 ON (p5.p_parent_id=p6.p_id)" . " LEFT JOIN `##places` AS p7 ON (p6.p_parent_id=p7.p_id)" . " LEFT JOIN `##places` AS p8 ON (p7.p_parent_id=p8.p_id)" . " LEFT JOIN `##places` AS p9 ON (p8.p_parent_id=p9.p_id)" . ") AS i_p ON (i_p.file  =ind.i_file AND i_pl.pl_p_id= i_p.id)";
     }
     if ($fam_plac) {
         $sql .= " JOIN `##placelinks`   f_pl ON (f_pl.pl_file=ind.i_file AND f_pl.pl_gid =fam.f_id)";
         $sql .= " JOIN (" . "SELECT CONCAT_WS(', ', p1.p_place, p2.p_place, p3.p_place, p4.p_place, p5.p_place, p6.p_place, p7.p_place, p8.p_place, p9.p_place) AS place, p1.p_id AS id, p1.p_file AS file" . " FROM      `##places` AS p1" . " LEFT JOIN `##places` AS p2 ON (p1.p_parent_id=p2.p_id)" . " LEFT JOIN `##places` AS p3 ON (p2.p_parent_id=p3.p_id)" . " LEFT JOIN `##places` AS p4 ON (p3.p_parent_id=p4.p_id)" . " LEFT JOIN `##places` AS p5 ON (p4.p_parent_id=p5.p_id)" . " LEFT JOIN `##places` AS p6 ON (p5.p_parent_id=p6.p_id)" . " LEFT JOIN `##places` AS p7 ON (p6.p_parent_id=p7.p_id)" . " LEFT JOIN `##places` AS p8 ON (p7.p_parent_id=p8.p_id)" . " LEFT JOIN `##places` AS p9 ON (p8.p_parent_id=p9.p_id)" . ") AS f_p ON (f_p.file  =ind.i_file AND f_pl.pl_p_id= f_p.id)";
     }
     // Add the where clause
     $sql .= " WHERE ind.i_file=?";
     $bind[] = WT_GED_ID;
     for ($i = 0; $i < $fct; $i++) {
         $field = $this->fields[$i];
         $value = $this->values[$i];
         if ($value === '') {
             continue;
         }
         $parts = preg_split("/:/", $field . '::::');
         if ($parts[0] == 'NAME') {
             // NAME:*
             switch ($parts[1]) {
                 case 'GIVN':
                     switch ($parts[2]) {
                         case 'EXACT':
                             $sql .= " AND i_n.n_givn=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND i_n.n_givn LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_givn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_givn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_givn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                     }
                     break;
                 case 'SURN':
                     switch ($parts[2]) {
                         case 'EXACT':
                             $sql .= " AND i_n.n_surname=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND i_n.n_surname LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND i_n.n_surname LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_surn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= " AND (" . implode(' OR ', $sdx) . ")";
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_surn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "i_n.n_soundex_surn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= " AND (" . implode(' OR ', $sdx) . ")";
                                 break;
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND i_n.n_surn LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                     }
                     break;
                 case 'NICK':
                 case '_MARNM':
                 case '_HEB':
                 case '_AKA':
                     $sql .= " AND i_n.n_type=? AND i_n.n_full LIKE CONCAT('%', ?, '%')";
                     $bind[] = $parts[1];
                     $bind[] = $value;
                     break;
             }
         } elseif ($parts[1] == 'DATE') {
             // *:DATE
             $date = new WT_Date($value);
             if ($date->isOK()) {
                 $jd1 = $date->date1->minJD;
                 if ($date->date2) {
                     $jd2 = $date->date2->maxJD;
                 } else {
                     $jd2 = $date->date1->maxJD;
                 }
                 if (!empty($this->plusminus[$i])) {
                     $adjd = $this->plusminus[$i] * 365;
                     //echo $jd1.":".$jd2.":".$adjd;
                     $jd1 = $jd1 - $adjd;
                     $jd2 = $jd2 + $adjd;
                 }
                 $sql .= " AND i_d.d_fact=? AND i_d.d_julianday1>=? AND i_d.d_julianday2<=?";
                 $bind[] = $parts[0];
                 $bind[] = $jd1;
                 $bind[] = $jd2;
             }
         } elseif ($parts[0] == 'FAMS' && $parts[2] == 'DATE') {
             // FAMS:*:DATE
             $date = new WT_Date($value);
             if ($date->isOK()) {
                 $jd1 = $date->date1->minJD;
                 if ($date->date2) {
                     $jd2 = $date->date2->maxJD;
                 } else {
                     $jd2 = $date->date1->maxJD;
                 }
                 if (!empty($this->plusminus[$i])) {
                     $adjd = $this->plusminus[$i] * 365;
                     //echo $jd1.":".$jd2.":".$adjd;
                     $jd1 = $jd1 - $adjd;
                     $jd2 = $jd2 + $adjd;
                 }
                 $sql .= " AND f_d.d_fact=? AND f_d.d_julianday1>=? AND f_d.d_julianday2<=?";
                 $bind[] = $parts[1];
                 $bind[] = $jd1;
                 $bind[] = $jd2;
             }
         } elseif ($parts[1] == 'PLAC') {
             // *:PLAC
             // SQL can only link a place to a person/family, not to an event.
             $sql .= " AND i_p.place LIKE CONCAT('%', ?, '%')";
             //$sql.=" AND i_p.p_place=?";
             $bind[] = $value;
         } elseif ($parts[0] == 'FAMS' && $parts[2] == 'PLAC') {
             // FAMS:*:PLAC
             // SQL can only link a place to a person/family, not to an event.
             $sql .= " AND f_p.place LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         } elseif ($parts[0] == 'FAMC' && $parts[2] == 'NAME') {
             $table = $parts[1] == 'HUSB' ? 'f_n' : 'm_n';
             // NAME:*
             switch ($parts[3]) {
                 case 'GIVN':
                     switch ($parts[4]) {
                         case 'EXACT':
                             $sql .= " AND {$table}.n_givn=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND {$table}.n_givn LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND {$table}.n_givn LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_givn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_givn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_givn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                                 break;
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_givn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                     }
                     break;
                 case 'SURN':
                     switch ($parts[4]) {
                         case 'EXACT':
                             $sql .= " AND {$table}.n_surname=?";
                             $bind[] = $value;
                             break;
                         case 'BEGINS':
                             $sql .= " AND {$table}.n_surname LIKE CONCAT(?, '%')";
                             $bind[] = $value;
                             break;
                         case 'CONTAINS':
                             $sql .= " AND {$table}.n_surname LIKE CONCAT('%', ?, '%')";
                             $bind[] = $value;
                             break;
                         case 'SDX_STD':
                             $sdx = WT_Soundex::soundex_std($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_surn_std LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_surn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                         case 'SDX':
                             // SDX uses DM by default.
                         // SDX uses DM by default.
                         case 'SDX_DM':
                             $sdx = WT_Soundex::soundex_dm($value);
                             if ($sdx) {
                                 $sdx = explode(':', $sdx);
                                 foreach ($sdx as $k => $v) {
                                     $sdx[$k] = "{$table}.n_soundex_surn_dm LIKE CONCAT('%', ?, '%')";
                                     $bind[] = $v;
                                 }
                                 $sql .= ' AND (' . implode(' OR ', $sdx) . ')';
                             } else {
                                 // No phonetic content?  Use a substring match
                                 $sql .= " AND {$table}.n_surn = LIKE CONCAT('%', ?, '%')";
                                 $bind[] = $value;
                             }
                             break;
                     }
                     break;
             }
         } elseif ($parts[0] == 'FAMS') {
             $sql .= " AND fam.f_gedcom LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         } else {
             $sql .= " AND ind.i_gedcom LIKE CONCAT('%', ?, '%')";
             $bind[] = $value;
         }
     }
     $rows = WT_DB::prepare($sql)->execute($bind)->fetchAll();
     foreach ($rows as $row) {
         $person = WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
         // Check for XXXX:PLAC fields, which were only partially matched by SQL
         foreach ($this->fields as $n => $field) {
             if ($this->values[$n] && preg_match('/^(' . WT_REGEX_TAG . '):PLAC$/', $field, $match)) {
                 if (!preg_match('/\\n1 ' . $match[1] . '(\\n[2-9].*)*\\n2 PLAC .*' . preg_quote($this->values[$n], '/') . '/i', $person->getGedcom())) {
                     continue 2;
                 }
             }
         }
         $this->myindilist[] = $person;
     }
 }
function update_names($xref, $ged_id, $record)
{
    static $sql_insert_name_indi = null;
    static $sql_insert_name_other = null;
    if (!$sql_insert_name_indi) {
        $sql_insert_name_indi = WT_DB::prepare("INSERT INTO `##name` (n_file,n_id,n_num,n_type,n_sort,n_full,n_surname,n_surn,n_givn,n_soundex_givn_std,n_soundex_surn_std,n_soundex_givn_dm,n_soundex_surn_dm) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
        $sql_insert_name_other = WT_DB::prepare("INSERT INTO `##name` (n_file,n_id,n_num,n_type,n_sort,n_full) VALUES (?,?,?,?,?,?)");
    }
    foreach ($record->getAllNames() as $n => $name) {
        if ($record instanceof WT_Individual) {
            if ($name['givn'] == '@P.N.') {
                $soundex_givn_std = null;
                $soundex_givn_dm = null;
            } else {
                $soundex_givn_std = WT_Soundex::soundex_std($name['givn']);
                $soundex_givn_dm = WT_Soundex::soundex_dm($name['givn']);
            }
            if ($name['surn'] == '@N.N.') {
                $soundex_surn_std = null;
                $soundex_surn_dm = null;
            } else {
                $soundex_surn_std = WT_Soundex::soundex_std($name['surname']);
                $soundex_surn_dm = WT_Soundex::soundex_dm($name['surname']);
            }
            $sql_insert_name_indi->execute(array($ged_id, $xref, $n, $name['type'], $name['sort'], $name['fullNN'], $name['surname'], $name['surn'], $name['givn'], $soundex_givn_std, $soundex_surn_std, $soundex_givn_dm, $soundex_surn_dm));
        } else {
            $sql_insert_name_other->execute(array($ged_id, $xref, $n, $name['type'], $name['sort'], $name['fullNN']));
        }
    }
}