fetchOne(); $alphas[$letter]=WT_I18N::number($count); } // Now fetch initial letters that are not in our alphabet, // including "@" (for "@N.N.") and "" for no surname. $sql= "SELECT SQL_CACHE UPPER(LEFT(n_surn, 1)), COUNT(n_id)". " FROM `##name` ". ($fams ? " JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). " WHERE n_file={$ged_id} AND n_surn<>''". ($marnm ? "" : " AND n_type!='_MARNM'"); foreach (self::_getAlphabet() as $n=>$letter) { $sql.=" AND n_surn NOT LIKE '".$letter."%' COLLATE ".WT_I18N::$collation; } $sql.=" GROUP BY LEFT(n_surn, 1) ORDER BY LEFT(n_surn, 1)='', LEFT(n_surn, 1)='@', LEFT(n_surn, 1)"; foreach (WT_DB::prepare($sql)->fetchAssoc() as $alpha=>$count) { $alphas[$alpha]=WT_I18N::number($count); } // Names with no surname $sql= "SELECT SQL_CACHE COUNT(n_id)". " FROM `##name` ". ($fams ? " JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). " WHERE n_file={$ged_id} AND n_surn=''". ($marnm ? "" : " AND n_type!='_MARNM'"); $num_none=WT_DB::prepare($sql)->fetchOne(); if ($num_none) { // Special code to indicate "no surname" $alphas[',']=$num_none; } return $alphas; } // Get a list of initial given name letters for indilist.php and famlist.php // $surn - if set, only consider people with this surname // $salpha - if set, only consider surnames starting with this letter // $marnm - if set, include married names // $fams - if set, only consider individuals with FAMS records // $ged_id - only consider individuals from this gedcom static public function givenAlpha($surn, $salpha, $marnm, $fams, $ged_id) { $alphas=array(); $sql= "SELECT SQL_CACHE COUNT(DISTINCT n_id)". " FROM `##name`". ($fams ? " JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). " WHERE n_file={$ged_id} ". ($marnm ? "" : " AND n_type!='_MARNM'"); if ($surn) { $sql.=" AND n_surn=".WT_DB::quote($surn)." COLLATE '".WT_I18N::$collation."'"; } elseif ($salpha==',') { $sql.=" AND n_surn=''"; } elseif ($salpha=='@') { $sql.=" AND n_surn='@N.N.'"; } elseif ($salpha) { $sql.=" AND ".self::_getInitialSql('n_surn', $salpha); } else { // All surnames $sql.=" AND n_surn NOT IN ('', '@N.N.')"; } // Fetch all the letters in our alphabet, whether or not there // are any names beginning with that letter. It looks better to // show the full alphabet, rather than omitting rare letters such as X foreach (self::_getAlphabet() as $letter) { $count=WT_DB::prepare($sql." AND ".self::_getInitialSql('n_givn', $letter))->fetchOne(); $alphas[$letter]=WT_I18N::number($count); } // Now fetch initial letters that are not in our alphabet, // including "@" (for "@N.N.") and "" for no surname $sql= "SELECT SQL_CACHE UPPER(LEFT(n_givn, 1)), COUNT(DISTINCT n_id)". " FROM `##name` ". ($fams ? " JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). " WHERE n_file={$ged_id} ". ($marnm ? "" : " AND n_type!='_MARNM'"); if ($surn) { $sql.=" AND n_surn=".WT_DB::quote($surn)." COLLATE '".WT_I18N::$collation."'"; } elseif ($salpha==',') { $sql.=" AND n_surn=''"; } elseif ($salpha=='@') { $sql.=" AND n_surn='@N.N.'"; } elseif ($salpha) { $sql.=" AND ".self::_getInitialSql('n_surn', $salpha); } else { // All surnames $sql.=" AND n_surn NOT IN ('', '@N.N.')"; } foreach (self::_getAlphabet() as $n=>$letter) { $sql.=" AND n_givn NOT LIKE '".$letter."%' COLLATE ".WT_I18N::$collation; } $sql.=" GROUP BY LEFT(n_givn, 1) ORDER BY LEFT(n_givn, 1)='@', LEFT(n_givn, 1)='', LEFT(n_givn, 1)"; foreach (WT_DB::prepare($sql)->fetchAssoc() as $alpha=>$count) { $alphas[$alpha]=WT_I18N::number($count); } return $alphas; } //////////////////////////////////////////////////////////////////////////////// // Get a list of actual surnames and variants, based on a "root" surname. // $surn - if set, only fetch people with this surname // $salpha - if set, only consider surnames starting with this letter // $marnm - if set, include married names // $fams - if set, only consider individuals with FAMS records // $ged_id - only consider individuals from this gedcom //////////////////////////////////////////////////////////////////////////////// public static function surnames($surn, $salpha, $marnm, $fams, $ged_id) { $sql= "SELECT SQL_CACHE n2.n_surn, n1.n_surname, n1.n_id". " FROM `##name` n1 ". ($fams ? " JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). " JOIN (SELECT n_surn, n_file FROM `##name`". " WHERE n_file={$ged_id}". ($marnm ? "" : " AND n_type!='_MARNM'"); if ($surn) { $sql.=" AND n_surn COLLATE '".WT_I18N::$collation."' =".WT_DB::quote($surn); } elseif ($salpha==',') { $sql.=" AND n_surn=''"; } elseif ($salpha=='@') { $sql.=" AND n_surn='@N.N.'"; } elseif ($salpha) { $sql.=" AND ".self::_getInitialSql('n_surn', $salpha); } else { // All surnames $sql.=" AND n_surn NOT IN ('', '@N.N.')"; } $sql.=" GROUP BY n_surn COLLATE '".WT_I18N::$collation."', n_file) n2 ON (n1.n_surn=n2.n_surn COLLATE '".WT_I18N::$collation."' AND n1.n_file=n2.n_file)"; if (!$marnm) { $sql.=" AND n_type!='_MARNM'"; } $list=array(); foreach (WT_DB::prepare($sql)->fetchAll() as $row) { $list[utf8_strtoupper($row->n_surn)][$row->n_surname][$row->n_id]=true; } return $list; } // $surn - if set, only fetch people with this surname // $salpha - if set, only fetch surnames starting with this letter // $galpha - if set, only fetch given names starting with this letter // $marnm - if set, include married names // $fams - if set, only fetch individuals with FAMS records // $ged_id - if set, only fetch individuals from this gedcom // // All parameters must be in upper case. We search against a database column // that contains uppercase values. This will allow non utf8-aware database // to match diacritics. // // To search for unknown names, use $surn="@N.N.", $salpha="@" or $galpha="@" // To search for names with no surnames, use $salpha="," public static function individuals($surn, $salpha, $galpha, $marnm, $fams, $ged_id) { $sql= "SELECT i_id AS xref, i_file AS gedcom_id, i_gedcom AS gedcom, n_full ". "FROM `##individuals` ". "JOIN `##name` ON (n_id=i_id AND n_file=i_file) ". ($fams ? "JOIN `##link` ON (n_id=l_from AND n_file=l_file AND l_type='FAMS') " : ""). "WHERE n_file={$ged_id} ". ($marnm ? "" : "AND n_type!='_MARNM'"); if ($surn) { $sql.=" AND n_surn COLLATE '".WT_I18N::$collation."'=".WT_DB::quote($surn); } elseif ($salpha==',') { $sql.=" AND n_surn=''"; } elseif ($salpha=='@') { $sql.=" AND n_surn='@N.N.'"; } elseif ($salpha) { $sql.=" AND ".self::_getInitialSql('n_surn', $salpha); } else { // All surnames $sql.=" AND n_surn NOT IN ('', '@N.N.')"; } if ($galpha) { $sql.=" AND ".self::_getInitialSql('n_givn', $galpha); } $sql.=" ORDER BY CASE n_surn WHEN '@N.N.' THEN 1 ELSE 0 END, n_surn COLLATE '".WT_I18N::$collation."', CASE n_givn WHEN '@P.N.' THEN 1 ELSE 0 END, n_givn COLLATE '".WT_I18N::$collation."'"; $list=array(); $rows=WT_DB::prepare($sql)->fetchAll(); foreach ($rows as $row) { $person=WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom); // The name from the database may be private - check the filtered list... foreach ($person->getAllNames() as $n=>$name) { if ($name['fullNN']==$row->n_full) { $person->setPrimaryName($n); // We need to clone $person, as we may have multiple references to the // same person in this list, and the "primary name" would otherwise // be shared amongst all of them. $list[]=clone $person; break; } } } return $list; } // Get a list of families for famlist.php // $surn - if set, only fetch people with this surname // $salpha - if set, only fetch surnames starting with this letter // $galpha - if set, only fetch given names starting with this letter // $marnm - if set, include married names // $ged_id - if set, only fetch individuals from this gedcom // // All parameters must be in upper case. We search against a database column // that contains uppercase values. This will allow non utf8-aware database // to match diacritics. // // To search for unknown names, use $surn="@N.N.", $salpha="@" or $galpha="@" // To search for names with no surnames, use $salpha="," public static function families($surn, $salpha, $galpha, $marnm, $ged_id) { $list=array(); foreach (self::individuals($surn, $salpha, $galpha, $marnm, true, $ged_id) as $indi) { foreach ($indi->getSpouseFamilies() as $family) { $list[$family->getXref()]=$family; } } usort($list, array('WT_GedcomRecord', 'Compare')); return $list; } }