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?'), '

', '
', ''; foreach (WT_Tree::getAll() as $tree) { echo '

getPreference('include_in_sitemap')) { echo ' checked="checked"'; $include_any=true; } echo '>', $tree->tree_title_html, '

'; } echo '', '
', '
'; 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.'), '

', ''; } } // Implement WT_Module_Config public function getConfigLink() { return 'module.php?mod='.$this->getName().'&mod_action=admin'; } }