setHeaders(); doSpecialViewXML( $query ); } } function getCategoriesList() { global $wgContLang, $dtgContLang; $dt_props = $dtgContLang->getPropertyLabels(); $exclusion_cat_name = str_replace( ' ', '_', $dt_props[DT_SP_IS_EXCLUDED_FROM_XML] ); $exclusion_cat_full_name = $wgContLang->getNSText( NS_CATEGORY ) . ':' . $exclusion_cat_name; $dbr = wfGetDB( DB_SLAVE ); $categorylinks = $dbr->tableName( 'categorylinks' ); $res = $dbr->query( "SELECT DISTINCT cl_to FROM $categorylinks" ); $categories = array(); while ( $row = $dbr->fetchRow( $res ) ) { $cat_name = $row[0]; // add this category to the list, if it's not the // "Excluded from XML" category, and it's not a child of that // category if ( $cat_name != $exclusion_cat_name ) { $title = Title::newFromText( $cat_name, NS_CATEGORY ); $parent_categories = $title->getParentCategoryTree( array() ); if ( ! treeContainsElement( $parent_categories, $exclusion_cat_full_name ) ) $categories[] = $cat_name; } } $dbr->freeResult( $res ); sort( $categories ); return $categories; } function getNamespacesList() { $dbr = wfGetDB( DB_SLAVE ); $page = $dbr->tableName( 'page' ); $res = $dbr->query( "SELECT DISTINCT page_namespace FROM $page" ); $namespaces = array(); while ( $row = $dbr->fetchRow( $res ) ) { $namespaces[] = $row[0]; } $dbr->freeResult( $res ); return $namespaces; } function getGroupings() { global $dtgContLang; global $smwgIP; if ( ! isset( $smwgIP ) ) { return array(); } else { $groupings = array(); $store = smwfGetStore(); $grouping_prop = SMWPropertyValue::makeProperty( '_DT_XG' ); $grouped_props = $store->getAllPropertySubjects( $grouping_prop ); foreach ( $grouped_props as $grouped_prop ) { $res = $store->getPropertyValues( $grouped_prop, $grouping_prop ); $num = count( $res ); if ( $num > 0 ) { $grouping_label = $res[0]->getShortWikiText(); $groupings[] = array( $grouped_prop, $grouping_label ); } } return $groupings; } } function getSubpagesForPageGrouping( $page_name, $relation_name ) { $dbr = wfGetDB( DB_SLAVE ); $smw_relations = $dbr->tableName( 'smw_relations' ); $smw_attributes = $dbr->tableName( 'smw_attributes' ); $res = $dbr->query( "SELECT subject_title FROM $smw_relations WHERE object_title = '$page_name' AND relation_title = '$relation_name'" ); $subpages = array(); while ( $row = $dbr->fetchRow( $res ) ) { $subpage_name = $row[0]; $query_subpage_name = str_replace( "'", "\'", $subpage_name ); // get the display order $res2 = $dbr->query( "SELECT value_num FROM $smw_attributes WHERE subject_title = '$query_subpage_name' AND attribute_title = 'Display_order'" ); if ( $row2 = $dbr->fetchRow( $res2 ) ) { $display_order = $row2[0]; } else { $display_order = - 1; } $dbr->freeResult( $res2 ); // HACK - page name is the key, display order is the value $subpages[$subpage_name] = $display_order; } $dbr->freeResult( $res ); uasort( $subpages, "cmp" ); return array_keys( $subpages ); } /* * Get all the pages that belong to a category and all its subcategories, * down a certain number of levels - heavily based on SMW's * SMWInlineQuery::includeSubcategories() */ function getPagesForCategory( $top_category, $num_levels ) { if ( 0 == $num_levels ) return $top_category; $db = wfGetDB( DB_SLAVE ); $fname = "getPagesForCategory"; $categories = array( $top_category ); $checkcategories = array( $top_category ); $titles = array(); for ( $level = $num_levels; $level > 0; $level-- ) { $newcategories = array(); foreach ( $checkcategories as $category ) { $res = $db->select( // make the query array( 'categorylinks', 'page' ), array( 'page_id', 'page_title', 'page_namespace' ), array( 'cl_from = page_id', 'cl_to = ' . $db->addQuotes( $category ) ), $fname ); if ( $res ) { while ( $res && $row = $db->fetchRow( $res ) ) { if ( array_key_exists( 'page_title', $row ) ) { $page_namespace = $row['page_namespace']; if ( $page_namespace == NS_CATEGORY ) { $new_category = $row[ 'page_title' ]; if ( !in_array( $new_category, $categories ) ) { $newcategories[] = $new_category; } } else { $titles[] = Title::newFromID( $row['page_id'] ); } } } $db->freeResult( $res ); } } if ( count( $newcategories ) == 0 ) { return $titles; } else { $categories = array_merge( $categories, $newcategories ); } $checkcategories = array_diff( $newcategories, array() ); } return $titles; } /* function getPagesForCategory($category) { $dbr = wfGetDB( DB_SLAVE ); $categorylinks = $dbr->tableName( 'categorylinks' ); $res = $dbr->query("SELECT cl_from FROM $categorylinks WHERE cl_to = '$category'"); $titles = array(); while ($row = $dbr->fetchRow($res)) { $titles[] = Title::newFromID($row[0]); } $dbr->freeResult($res); return $titles; } */ function getPagesForNamespace( $namespace ) { $dbr = wfGetDB( DB_SLAVE ); $page = $dbr->tableName( 'page' ); $res = $dbr->query( "SELECT page_id FROM $page WHERE page_namespace = '$namespace'" ); $titles = array(); while ( $row = $dbr->fetchRow( $res ) ) { $titles[] = Title::newFromID( $row[0] ); } $dbr->freeResult( $res ); return $titles; } /** * Helper function for getXMLForPage() */ function treeContainsElement( $tree, $element ) { // escape out if there's no tree (i.e., category) if ( $tree == null ) return false; foreach ( $tree as $node => $child_tree ) { if ( $node === $element ) { return true; } elseif ( count( $child_tree ) > 0 ) { if ( treeContainsElement( $child_tree, $element ) ) { return true; } } } // no match found return false; } function getXMLForPage( $title, $simplified_format, $groupings, $depth = 0 ) { if ( $depth > 5 ) { return ""; } global $wgContLang, $dtgContLang; $namespace_labels = $wgContLang->getNamespaces(); $template_label = $namespace_labels[NS_TEMPLATE]; $namespace_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_namespace' ) ); $page_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_page' ) ); $field_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_field' ) ); $name_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_name' ) ); $title_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_title' ) ); $id_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_id' ) ); $free_text_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_freetext' ) ); // if this page belongs to the exclusion category, exit $parent_categories = $title->getParentCategoryTree( array() ); $dt_props = $dtgContLang->getPropertyLabels(); // $exclusion_category = $title->newFromText($dt_props[DT_SP_IS_EXCLUDED_FROM_XML], NS_CATEGORY); $exclusion_category = $wgContLang->getNSText( NS_CATEGORY ) . ':' . str_replace( ' ', '_', $dt_props[DT_SP_IS_EXCLUDED_FROM_XML] ); if ( treeContainsElement( $parent_categories, $exclusion_category ) ) return ""; $article = new Article( $title ); $page_title = str_replace( '"', '"', $title->getText() ); $page_title = str_replace( '&', '&', $page_title ); if ( $simplified_format ) $text = "<$page_str><$id_str>{$article->getID()}<$title_str>$page_title\n"; else $text = "<$page_str $id_str=\"" . $article->getID() . "\" $title_str=\"" . $page_title . '" >'; // traverse the page contents, one character at a time $uncompleted_curly_brackets = 0; $page_contents = $article->getContent(); // escape out variables like "{{PAGENAME}}" $page_contents = str_replace( '{{PAGENAME}}', '{{PAGENAME}}', $page_contents ); // escape out parser functions $page_contents = preg_replace( '/{{(#.+)}}/', '{{$1}}', $page_contents ); // escape out transclusions $page_contents = preg_replace( '/{{(:.+)}}/', '{{$1}}', $page_contents ); // escape out variable names $page_contents = str_replace( '{{{', '{{{', $page_contents ); $page_contents = str_replace( '}}}', '}}}', $page_contents ); // escape out tables $page_contents = str_replace( '{|', '{|', $page_contents ); $page_contents = str_replace( '|}', '|}', $page_contents ); $free_text = ""; $free_text_id = 1; $template_name = ""; $field_name = ""; $field_value = ""; $field_has_name = false; for ( $i = 0; $i < strlen( $page_contents ); $i++ ) { $c = $page_contents[$i]; if ( $uncompleted_curly_brackets == 0 ) { if ( $c == "{" || $i == strlen( $page_contents ) - 1 ) { if ( $i == strlen( $page_contents ) - 1 ) $free_text .= $c; $uncompleted_curly_brackets++; $free_text = trim( $free_text ); $free_text = str_replace( '&', '&', $free_text ); $free_text = str_replace( '[', '[', $free_text ); $free_text = str_replace( ']', ']', $free_text ); $free_text = str_replace( '<', '<', $free_text ); $free_text = str_replace( '>', '>', $free_text ); if ( $free_text != "" ) { $text .= "<$free_text_str id=\"$free_text_id\">$free_text"; $free_text = ""; $free_text_id++; } } elseif ( $c == "{" ) { // do nothing } else { $free_text .= $c; } } elseif ( $uncompleted_curly_brackets == 1 ) { if ( $c == "{" ) { $uncompleted_curly_brackets++; $creating_template_name = true; } elseif ( $c == "}" ) { $uncompleted_curly_brackets--; // is this needed? // if ($field_name != "") { // $field_name = ""; // } if ( $page_contents[$i - 1] == '}' ) { if ( $simplified_format ) $text .= ""; else $text .= ""; } $template_name = ""; } } else { // 2 or greater - probably 2 if ( $c == "}" ) { $uncompleted_curly_brackets--; } if ( $c == "{" ) { $uncompleted_curly_brackets++; } else { if ( $creating_template_name ) { if ( $c == "|" || $c == "}" ) { $template_name = str_replace( ' ', '_', trim( $template_name ) ); $template_name = str_replace( '&', '&', $template_name ); if ( $simplified_format ) { $text .= "<" . $template_name . ">"; } else $text .= "<$template_label $name_str=\"$template_name\">"; $creating_template_name = false; $creating_field_name = true; $field_id = 1; } else { $template_name .= $c; } } else { if ( $c == "|" || $c == "}" ) { if ( $field_has_name ) { $field_value = str_replace( '&', '&', $field_value ); if ( $simplified_format ) { $field_name = str_replace( ' ', '_', trim( $field_name ) ); $text .= "<" . $field_name . ">"; $text .= trim( $field_value ); $text .= ""; } else { $text .= "<$field_str $name_str=\"" . trim( $field_name ) . "\">"; $text .= trim( $field_value ); $text .= ""; } $field_value = ""; $field_has_name = false; } else { // "field_name" is actually the value if ( $simplified_format ) { $field_name = str_replace( ' ', '_', $field_name ); // add "Field" to the beginning of the file name, since // XML tags that are simply numbers aren't allowed $text .= "<" . $field_str . '_' . $field_id . ">"; $text .= trim( $field_name ); $text .= ""; } else { $text .= "<$field_str $name_str=\"$field_id\">"; $text .= trim( $field_name ); $text .= ""; } $field_id++; } $creating_field_name = true; $field_name = ""; } elseif ( $c == "=" ) { // handle case of = in value if ( ! $creating_field_name ) { $field_value .= $c; } else { $creating_field_name = false; $field_has_name = true; } } elseif ( $creating_field_name ) { $field_name .= $c; } else { $field_value .= $c; } } } } } // handle groupings, if any apply here; first check if SMW is installed global $smwgIP; if ( isset( $smwgIP ) ) { $store = smwfGetStore(); foreach ( $groupings as $pair ) { list( $property_page, $grouping_label ) = $pair; $wiki_page = SMWDataValueFactory::newTypeIDValue( '_wpg', $page_title ); $options = new SMWRequestOptions(); $options->sort = "subject_title"; // get actual property from the wiki-page of the property $property = SMWPropertyValue::makeProperty( $property_page->getTitle()->getText() ); $res = $store->getPropertySubjects( $property, $wiki_page, $options ); $num = count( $res ); if ( $num > 0 ) { $grouping_label = str_replace( ' ', '_', $grouping_label ); $text .= "<$grouping_label>\n"; foreach ( $res as $subject ) { $subject_title = $subject->getTitle(); $text .= getXMLForPage( $subject_title, $simplified_format, $groupings, $depth + 1 ); } $text .= "\n"; } } } $text .= "\n"; // escape back the curly brackets that were escaped out at the beginning $text = str_replace( '&#123;', '{', $text ); $text = str_replace( '&#125;', '}', $text ); return $text; } function doSpecialViewXML() { global $wgOut, $wgRequest, $wgUser, $wgContLang; $skin = $wgUser->getSkin(); $namespace_labels = $wgContLang->getNamespaces(); $category_label = $namespace_labels[NS_CATEGORY]; $template_label = $namespace_labels[NS_TEMPLATE]; $name_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_name' ) ); $namespace_str = str_replace( ' ', '_', wfMsg( 'dt_xml_namespace' ) ); $pages_str = str_replace( ' ', '_', wfMsgForContent( 'dt_xml_pages' ) ); $form_submitted = false; $page_titles = array(); $cats = $wgRequest->getArray( 'categories' ); $nses = $wgRequest->getArray( 'namespaces' ); if ( count( $cats ) > 0 || count( $nses ) > 0 ) { $form_submitted = true; } if ( $form_submitted ) { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header( "Content-type: application/xml; charset=utf-8" ); $groupings = getGroupings(); $simplified_format = $wgRequest->getVal( 'simplified_format' ); $text = "<$pages_str>"; if ( $cats ) { foreach ( $cats as $cat => $val ) { if ( $simplified_format ) $text .= '<' . str_replace( ' ', '_', $cat ) . ">\n"; else $text .= "<$category_label $name_str=\"$cat\">\n"; $titles = getPagesForCategory( $cat, 10 ); foreach ( $titles as $title ) { $text .= getXMLForPage( $title, $simplified_format, $groupings ); } if ( $simplified_format ) $text .= '\n"; else $text .= "\n"; } } if ( $nses ) { foreach ( $nses as $ns => $val ) { if ( $ns == 0 ) { $ns_name = "Main"; } else { $ns_name = MWNamespace::getCanonicalName( $ns ); } if ( $simplified_format ) $text .= '<' . str_replace( ' ', '_', $ns_name ) . ">\n"; else $text .= "<$namespace_str $name_str=\"$ns_name\">\n"; $titles = getPagesForNamespace( $ns ); foreach ( $titles as $title ) { $text .= getXMLForPage( $title, $simplified_format, $groupings ); } if ( $simplified_format ) $text .= '\n"; else $text .= "\n"; } } $text .= ""; print $text; } else { // set 'title' as hidden field, in case there's no URL niceness global $wgContLang; $mw_namespace_labels = $wgContLang->getNamespaces(); $special_namespace = $mw_namespace_labels[NS_SPECIAL]; $text = << END; $text .= "

" . wfMsg( 'dt_viewxml_docu' ) . "

\n"; $text .= "

" . wfMsg( 'dt_viewxml_categories' ) . "

\n"; $categories = getCategoriesList(); foreach ( $categories as $category ) { $title = Title::makeTitle( NS_CATEGORY, $category ); $link = $skin->makeLinkObj( $title, $title->getText() ); $text .= " $link
\n"; } $text .= "

" . wfMsg( 'dt_viewxml_namespaces' ) . "

\n"; $namespaces = getNamespacesList(); foreach ( $namespaces as $namespace ) { if ( $namespace == 0 ) { $ns_name = wfMsgHtml( 'blanknamespace' ); } else { $ns_name = htmlspecialchars( $wgContLang->getFormattedNsText( $namespace ) ); } $ns_name = str_replace( '_', ' ', $ns_name ); $text .= " $ns_name
\n"; } $text .= "

" . wfMsg( 'dt_viewxml_simplifiedformat' ) . "

\n"; $text .= "\n"; $text .= "\n"; $wgOut->addHTML( $text ); } }