/**
  * check stack for inheritance consistency, repair the stack internally -- 
  * that is, set $this->array to the top to at least the errorous position
  **/
 function clean()
 {
     // trivial case.
     if (empty($this->array)) {
         // add a root
         $this->array[] = MsCategoryFactory::get_root_category();
         return;
     }
     // check root
     if ($this->array[0]->id != self::$root_category_name) {
         // the root was bad.
         array_unshift($this->array[0], MsCategoryFactory::get_root_category());
     }
     // walk down stack from the TOP until almost-root
     for ($x = count($this->array) - 1; $x >= 1; $x--) {
         // if the top element is not a child from the one below...
         if (!$this->array[$x - 1]->has_sub_category($this->array[$x])) {
             // ... then kill it.
             array_pop($this->array);
         }
     }
     // stack is clean.
 }
 function category_tree($leaf = false, $level = 1)
 {
     if (!$leaf) {
         $leaf = MsCategoryFactory::get_root_category();
     }
     $indent = str_repeat('#', $level);
     $name = $leaf->get('name');
     if (!$name) {
         $name = "''no name set!''";
     }
     $id = $leaf->id;
     $r = "{$indent} '''[[MediaWiki:ms-{$id}-category|{$id}]]''' " . ($leaf->exists() ? '' : "'''DOES NOT EXIST'''") . "\n";
     $r .= "{$indent}* ''MSGS'': [[MediaWiki:ms-{$id}-record|record]], [[MediaWiki:ms-{$id}-category-input|input]], [[MediaWiki:ms-{$id}-presearch-box|presearch]], [[MediaWiki:ms-{$id}-postsearch-box|postsearch]]\n";
     $r .= "{$indent}* ''DATABASES'': ";
     foreach ($leaf->get_databases() as $db) {
         $r .= "[[MediaWiki:ms-{$db}-database|{$db}]], ";
         $msg = MsDatabase::get_conf_msg_name($db);
         if (wfMsgExists($msg)) {
             $this->list_of_msgs[] = $msg;
         }
     }
     $r .= "\n";
     foreach ($leaf->get_conf_array() as $k => $v) {
         $r .= "{$indent}* ''{$k}'': {$v}\n";
     }
     #if(wfMsgExists($msg)) $this->list_of_msgs += $msg;
     $this->list_of_msgs = array_merge($this->list_of_msgs, $leaf->get_messages());
     $this->list_of_dbs = array_merge($this->list_of_dbs, $leaf->get_databases());
     foreach ($leaf->get_sub_categories(MsCategory::AS_OBJECTS) as $subcat) {
         $r .= $this->category_tree($subcat, $level + 1);
     }
     return $r;
 }
    function print_out()
    {
        global $wgOut, $msConfiguration;
        # clean the category stack
        $this->cat_stack = MsCategoryFactory::clean_category_stack($this->cat_stack);
        # get the topmost category of the stack
        $current_cat = $this->get_top_cat();
        $prepost = $this->get_status() . 'search';
        $action = $this->controller->view->special_page->getTitle()->escapeLocalURL();
        // <form> action.
        $wgOut->addHTML('<div class="ms-formbox ms-' . $prepost . '">');
        $wgOut->addHTML('<form method="get" action="' . $action . '" name="ms">');
        if ($current_cat->has_input_text()) {
            $wgOut->addHTML('<div class="ms-right">');
            $wgOut->addHTML('<div class="ms-assistant-box">');
        } else {
            $wgOut->addHTML('<div class="ms-assistant-box">');
        }
        // Contents of assistant box
        $box = $current_cat->get_box($this->get_status() . 'search');
        $wgOut->addWikiText($box);
        $wgOut->addHTML('</div><!--assistant box-->');
        if (!$current_cat->has_input_text()) {
            $wgOut->addHTML('<div class="ms-right">');
        }
        $wgOut->addHTML('<div class="mc-bc">');
        $wgOut->addWikiText(wfMsg($this->get_assistant_msg()));
        $wgOut->addHTML('</div>');
        $wgOut->addHTML('</div><!--ms-right-->');
        $wgOut->addHTML('<div class="ms-left">');
        if ($current_cat->has_input_text()) {
            $wgOut->addHTML('<div class="ms-inputtext">');
            $current_cat->add_input_text($this->query);
            $wgOut->addHTML('</div>');
        }
        $wgOut->addHTML('<div class="ms-class-selector">');
        $str = '';
        // out string buffer.
        for ($x = 0; $x < count($this->cat_stack); $x++) {
            $sub_cats = $this->cat_stack[$x]->get_sub_categories(true);
            if (empty($sub_cats)) {
                // Endkategorie erreicht!
                break;
            }
            if ($x != 0) {
                $str .= '<img src="http://upload.wikimedia.org/wikipedia/commons/0/0e/Forward.png" class="arrow">';
            }
            $str .= '<select class="cat-' . $x . '" name="ms_cat[]" size="6" onchange="try{document.ms.ms_search.value=\'\';}catch(e){}; document.ms.submit();">';
            foreach ($sub_cats as $sub_cat) {
                $str .= '<option value="' . $sub_cat->id . '" ';
                // Anwaehlen aktueller Datenbanken
                if ($x + 1 < count($this->cat_stack) && $this->cat_stack[$x + 1]->id == $sub_cat->id) {
                    $str .= 'selected="selected"';
                }
                // ausgrauen noch nicht gemachter Datenbanken
                if ($sub_cat->get('input') == 'notyet') {
                    $str .= 'style="color:#aaa;"';
                }
                $str .= '>';
                $str .= $sub_cat->get('name');
                #$this->get_category_name($sub_cat);
                $str .= '</option>';
            }
            $str .= '</select>';
        }
        $str .= <<<BLU
\t\t\t</div>
\t\t</div><!--left-->
\t</form>
</div><!--formbox-->
BLU;
        $wgOut->addHTML($str);
    }