$saved ? 'XML sitemap settings saved' : null,
'fields' => array(
'questions' => array(
'label' => 'Include question pages',
'type' => 'checkbox',
'value' => (int)qa_opt('xml_sitemap_show_questions'),
'tags' => 'name="xml_sitemap_show_questions_field"',
),
),
'buttons' => array(
array(
'label' => 'Save Changes',
'tags' => 'name="xml_sitemap_save_button"',
),
),
);
if (!QA_FINAL_EXTERNAL_USERS) {
$form['fields']['users'] = array(
'label' => 'Include user pages',
'type' => 'checkbox',
'value' => (int)qa_opt('xml_sitemap_show_users'),
'tags' => 'name="xml_sitemap_show_users_field"',
);
}
if (qa_using_tags()) {
$form['fields']['tagqs'] = array(
'label' => 'Include question list for each tag',
'type' => 'checkbox',
'value' => (int)qa_opt('xml_sitemap_show_tag_qs'),
'tags' => 'name="xml_sitemap_show_tag_qs_field"',
);
}
if (qa_using_categories()) {
$form['fields']['categoryqs'] = array(
'label' => 'Include question list for each category',
'type' => 'checkbox',
'value' => (int)qa_opt('xml_sitemap_show_category_qs'),
'tags' => 'name="xml_sitemap_show_category_qs_field"',
);
$form['fields']['categories'] = array(
'label' => 'Include category browser',
'type' => 'checkbox',
'value' => (int)qa_opt('xml_sitemap_show_categories'),
'tags' => 'name="xml_sitemap_show_categories_field"',
);
}
return $form;
}
public function suggest_requests()
{
return array(
array(
'title' => 'XML Sitemap',
'request' => 'sitemap.xml',
'nav' => null, // 'M'=main, 'F'=footer, 'B'=before main, 'O'=opposite main, null=none
),
);
}
public function match_request($request)
{
return ($request == 'sitemap.xml');
}
public function process_request($request)
{
@ini_set('display_errors', 0); // we don't want to show PHP errors inside XML
header('Content-type: text/xml; charset=utf-8');
echo '' . "\n";
echo '' . "\n";
// Question pages
if (qa_opt('xml_sitemap_show_questions')) {
$hotstats = qa_db_read_one_assoc(qa_db_query_sub(
"SELECT MIN(hotness) AS base, MAX(hotness)-MIN(hotness) AS spread FROM ^posts WHERE type='Q'"
));
$nextpostid = 0;
while (1) {
$questions = qa_db_read_all_assoc(qa_db_query_sub(
"SELECT postid, title, hotness FROM ^posts WHERE postid>=# AND type='Q' ORDER BY postid LIMIT 100",
$nextpostid
));
if (!count($questions))
break;
foreach ($questions as $question) {
$this->sitemap_output(qa_q_request($question['postid'], $question['title']),
0.1 + 0.9 * ($question['hotness'] - $hotstats['base']) / (1 + $hotstats['spread']));
$nextpostid = max($nextpostid, $question['postid'] + 1);
}
}
}
// User pages
if (!QA_FINAL_EXTERNAL_USERS && qa_opt('xml_sitemap_show_users')) {
$nextuserid = 0;
while (1) {
$users = qa_db_read_all_assoc(qa_db_query_sub(
"SELECT userid, handle FROM ^users WHERE userid>=# ORDER BY userid LIMIT 100",
$nextuserid
));
if (!count($users))
break;
foreach ($users as $user) {
$this->sitemap_output('user/' . $user['handle'], 0.25);
$nextuserid = max($nextuserid, $user['userid'] + 1);
}
}
}
// Tag pages
if (qa_using_tags() && qa_opt('xml_sitemap_show_tag_qs')) {
$nextwordid = 0;
while (1) {
$tagwords = qa_db_read_all_assoc(qa_db_query_sub(
"SELECT wordid, word, tagcount FROM ^words WHERE wordid>=# AND tagcount>0 ORDER BY wordid LIMIT 100",
$nextwordid
));
if (!count($tagwords))
break;
foreach ($tagwords as $tagword) {
$this->sitemap_output('tag/' . $tagword['word'], 0.5 / (1 + (1 / $tagword['tagcount']))); // priority between 0.25 and 0.5 depending on tag frequency
$nextwordid = max($nextwordid, $tagword['wordid'] + 1);
}
}
}
// Question list for each category
if (qa_using_categories() && qa_opt('xml_sitemap_show_category_qs')) {
$nextcategoryid = 0;
while (1) {
$categories = qa_db_read_all_assoc(qa_db_query_sub(
"SELECT categoryid, backpath FROM ^categories WHERE categoryid>=# AND qcount>0 ORDER BY categoryid LIMIT 2",
$nextcategoryid
));
if (!count($categories))
break;
foreach ($categories as $category) {
$this->sitemap_output('questions/' . implode('/', array_reverse(explode('/', $category['backpath']))), 0.5);
$nextcategoryid = max($nextcategoryid, $category['categoryid'] + 1);
}
}
}
// Pages in category browser
if (qa_using_categories() && qa_opt('xml_sitemap_show_categories')) {
$this->sitemap_output('categories', 0.5);
$nextcategoryid = 0;
while (1) { // only find categories with a child
$categories = qa_db_read_all_assoc(qa_db_query_sub(
"SELECT parent.categoryid, parent.backpath FROM ^categories AS parent " .
"JOIN ^categories AS child ON child.parentid=parent.categoryid WHERE parent.categoryid>=# GROUP BY parent.categoryid LIMIT 100",
$nextcategoryid
));
if (!count($categories))
break;
foreach ($categories as $category) {
$this->sitemap_output('categories/' . implode('/', array_reverse(explode('/', $category['backpath']))), 0.5);
$nextcategoryid = max($nextcategoryid, $category['categoryid'] + 1);
}
}
}
echo "\n";
return null;
}
private function sitemap_output($request, $priority)
{
echo "\t\n" .
"\t\t" . qa_xml(qa_path($request, null, qa_opt('site_url'))) . "\n" .
"\t\t" . max(0, min(1.0, $priority)) . "\n" .
"\t\n";
}
}