admin();
break;
case 'generate':
Zend_Session::writeClose();
$this->generate(WT_Filter::get('file'));
break;
default:
header('HTTP/1.0 404 Not Found');
}
}
private function generate($file) {
if ($file=='sitemap.xml') {
$this->generate_index();
} elseif (preg_match('/^sitemap-(\d+)-([isrmn])-(\d+).xml$/', $file, $match)) {
$this->generate_file($match[1], $match[2], $match[3]);
} else {
header('HTTP/1.0 404 Not Found');
}
}
// The index file contains references to all the other files.
// These files are the same for visitors/users/admins.
private function generate_index() {
// Check the cache
$timestamp = $this->getSetting( 'sitemap.timestamp');
if ($timestamp > WT_TIMESTAMP - self::CACHE_LIFE) {
$data = $this->getSetting('sitemap.xml');
} else {
$data='';
$lastmod=''.date('Y-m-d').'';
foreach (WT_Tree::getAll() as $tree) {
if ($tree->getPreference('include_in_sitemap')) {
$n=WT_DB::prepare("SELECT COUNT(*) FROM `##individuals` WHERE i_file=?")->execute(array($tree->tree_id))->fetchOne();
for ($i=0; $i<=$n/self::RECORDS_PER_VOLUME; ++$i) {
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap-'.$tree->tree_id.'-i-'.$i.'.xml'.$lastmod.''.PHP_EOL;
}
$n=WT_DB::prepare("SELECT COUNT(*) FROM `##sources` WHERE s_file=?")->execute(array($tree->tree_id))->fetchOne();
if ($n) {
for ($i=0; $i<=$n/self::RECORDS_PER_VOLUME; ++$i) {
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap-'.$tree->tree_id.'-s-'.$i.'.xml'.$lastmod.''.PHP_EOL;
}
}
$n=WT_DB::prepare("SELECT COUNT(*) FROM `##other` WHERE o_file=? AND o_type='REPO'")->execute(array($tree->tree_id))->fetchOne();
if ($n) {
for ($i=0; $i<=$n/self::RECORDS_PER_VOLUME; ++$i) {
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap-'.$tree->tree_id.'-r-'.$i.'.xml'.$lastmod.''.PHP_EOL;
}
}
$n=WT_DB::prepare("SELECT COUNT(*) FROM `##other` WHERE o_file=? AND o_type='NOTE'")->execute(array($tree->tree_id))->fetchOne();
if ($n) {
for ($i=0; $i<=$n/self::RECORDS_PER_VOLUME; ++$i) {
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap-'.$tree->tree_id.'-n-'.$i.'.xml'.$lastmod.''.PHP_EOL;
}
}
$n=WT_DB::prepare("SELECT COUNT(*) FROM `##media` WHERE m_file=?")->execute(array($tree->tree_id))->fetchOne();
if ($n) {
for ($i=0; $i<=$n/self::RECORDS_PER_VOLUME; ++$i) {
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap-'.$tree->tree_id.'-m-'.$i.'.xml'.$lastmod.''.PHP_EOL;
}
}
}
}
$data = '<'.'?xml version="1.0" encoding="UTF-8" ?'.'>' . PHP_EOL . '' . PHP_EOL . $data . '' . PHP_EOL;
// Cache this data.
$this->setSetting('sitemap.xml', $data);
$this->setSetting('sitemap.timestamp', WT_TIMESTAMP);
}
header('Content-Type: application/xml');
header('Content-Length: ' . strlen($data));
echo $data;
}
// A separate file for each family tree and each record type.
// These files depend on access levels, so only cache for visitors.
private function generate_file($ged_id, $rec_type, $volume) {
// Check the cache
$timestamp = $this->getSetting('sitemap-' . $ged_id . '-' . $rec_type . '-' . $volume . '.timestamp');
if ($timestamp > WT_TIMESTAMP - self::CACHE_LIFE && !WT_USER_ID) {
$data = $this->getSetting('sitemap-' . $ged_id . '-' . $rec_type . '-' . $volume . '.xml');
} else {
$tree=WT_Tree::get($ged_id);
$data=''.WT_SERVER_NAME.WT_SCRIPT_PATH.'index.php?ctype=gedcom&ged='.$tree->tree_name_url.''.PHP_EOL;
$records=array();
switch ($rec_type) {
case 'i':
$rows=WT_DB::prepare(
"SELECT i_id AS xref, i_file AS gedcom_id, i_gedcom AS gedcom".
" FROM `##individuals`".
" WHERE i_file=?".
" ORDER BY i_id".
" LIMIT ".self::RECORDS_PER_VOLUME." OFFSET ".($volume*self::RECORDS_PER_VOLUME)
)->execute(array($ged_id))->fetchAll();
foreach ($rows as $row) {
$records[]=WT_Individual::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
}
break;
case 's':
$rows=WT_DB::prepare(
"SELECT s_id AS xref, s_file AS gedcom_id, s_gedcom AS gedcom".
" FROM `##sources`".
" WHERE s_file=?".
" ORDER BY s_id".
" LIMIT ".self::RECORDS_PER_VOLUME." OFFSET ".($volume*self::RECORDS_PER_VOLUME)
)->execute(array($ged_id))->fetchAll();
foreach ($rows as $row) {
$records[]=WT_Source::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
}
break;
case 'r':
$rows=WT_DB::prepare(
"SELECT o_id AS xref, o_file AS gedcom_id, o_gedcom AS gedcom".
" FROM `##other`".
" WHERE o_file=? AND o_type='REPO'".
" ORDER BY o_id".
" LIMIT ".self::RECORDS_PER_VOLUME." OFFSET ".($volume*self::RECORDS_PER_VOLUME)
)->execute(array($ged_id))->fetchAll();
foreach ($rows as $row) {
$records[]=WT_Repository::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
}
break;
case 'n':
$rows=WT_DB::prepare(
"SELECT o_id AS xref, o_file AS gedcom_id, o_gedcom AS gedcom".
" FROM `##other`".
" WHERE o_file=? AND o_type='NOTE'".
" ORDER BY o_id".
" LIMIT ".self::RECORDS_PER_VOLUME." OFFSET ".($volume*self::RECORDS_PER_VOLUME)
)->execute(array($ged_id))->fetchAll();
foreach ($rows as $row) {
$records[]=WT_Note::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
}
break;
case 'm':
$rows=WT_DB::prepare(
"SELECT m_id AS xref, m_file AS gedcom_id, m_gedcom AS gedcom".
" FROM `##media`".
" WHERE m_file=?".
" ORDER BY m_id".
" LIMIT ".self::RECORDS_PER_VOLUME." OFFSET ".($volume*self::RECORDS_PER_VOLUME)
)->execute(array($ged_id))->fetchAll();
foreach ($rows as $row) {
$records[]=WT_Media::getInstance($row->xref, $row->gedcom_id, $row->gedcom);
}
break;
}
foreach ($records as $record) {
if ($record->canShowName()) {
$data.='';
$data.=''.WT_SERVER_NAME.WT_SCRIPT_PATH.$record->getHtmlUrl().'';
$chan=$record->getFirstFact('CHAN');
if ($chan) {
$date=$chan->getDate();
if ($date->isOK()) {
$data.=''.$date->minDate()->Format('%Y-%m-%d').'';
}
}
$data.=''.PHP_EOL;
}
}
$data='<'.'?xml version="1.0" encoding="UTF-8" ?'.'>'.PHP_EOL.''.PHP_EOL.$data.''.PHP_EOL;
// Cache this data - but only for visitors, as we don’t want
// visitors to see data created by logged-in users.
if (!WT_USER_ID) {
$this->setSetting('sitemap-' . $ged_id . '-' . $rec_type . '-' . $volume . '.xml', $data);
$this->setSetting('sitemap-' . $ged_id . '-' . $rec_type . '-' . $volume . '.timestamp', WT_TIMESTAMP);
}
}
header('Content-Type: application/xml');
header('Content-Length: '.strlen($data));
echo $data;
}
private function admin() {
$controller=new WT_Controller_Page();
$controller
->restrictAccess(Auth::isAdmin())
->setPageTitle($this->getTitle())
->pageHeader();
// Save the updated preferences
if (WT_Filter::post('action')=='save') {
foreach (WT_Tree::getAll() as $tree) {
$tree->setPreference('include_in_sitemap', WT_Filter::postBool('include'.$tree->tree_id));
}
// Clear cache and force files to be regenerated
WT_DB::prepare(
"DELETE FROM `##module_setting` WHERE setting_name LIKE 'sitemap%'"
)->execute();
}
$include_any=false;
echo
'
', $this->getTitle(), '
',
'',
/* I18N: The www.sitemaps.org site is translated into many languages (e.g. http://www.sitemaps.org/fr/) - choose an appropriate URL. */
WT_I18N::translate('Sitemaps are a way for webmasters to tell search engines about the pages on a website that are available for crawling. All major search engines support sitemaps. For more information, see www.sitemaps.org.').
'
',
'', WT_I18N::translate('Which family trees should be included in the sitemaps?'), '
',
'',
'
';
if ($include_any) {
$site_map_url1=WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap.xml';
$site_map_url2=rawurlencode(WT_SERVER_NAME.WT_SCRIPT_PATH.'module.php?mod='.$this->getName().'&mod_action=generate&file=sitemap.xml');
echo '', WT_I18N::translate('To tell search engines that sitemaps are available, you should add the following line to your robots.txt file.'), '
';
echo
'Sitemap: ', $site_map_url1, '
',
'
',
'', WT_I18N::translate('To tell search engines that sitemaps are available, you can use the following links.'), '
',
'',
// This list comes from http://en.wikipedia.org/wiki/Sitemaps
'- Bing
',
'- Google
',
'
';
}
}
// Implement WT_Module_Config
public function getConfigLink() {
return 'module.php?mod='.$this->getName().'&mod_action=admin';
}
}