/**
  * @param $token - encoded token object
  * @result - SQL token
  */
 private static function getSqlToken(stdClass $token)
 {
     switch ($token->type) {
         case 'comparsion':
             $matches = array();
             preg_match_all(CB_ENCODED_TOKEN_MATCH, $token->value, $matches, PREG_SET_ORDER);
             if (count($matches) == 1 && isset($matches[0]) && count($matches[0]) == 4) {
                 // decode comparsion op
                 return self::$sql_fields[$matches[0][2]] . ' ' . self::$sql_cmps[$matches[0][1]] . ' ' . (int) $matches[0][3];
             }
             break;
         case 'logical':
             if (in_array($token->value, self::$valid_logical_ops)) {
                 // decode logical op
                 // we store logical ops uppercase for the "prettiness"
                 return strtoupper($token->value);
             }
             break;
         case 'bracket':
             if (($opcode = array_search($token->value, self::$valid_bracket_ops)) !== false) {
                 // decode bracket op
                 return self::$valid_bracket_ops[$opcode];
             }
     }
     throw new MWException('Invalid operation type=' . CB_Setup::specialchars($token->type) . ' value=' . CB_Setup::specialchars($token->value) . ' in ' . __METHOD__);
 }
 /**
  * called via AJAX to get list of (subcategories,pages,files) for specitied parent category id, offset, limit
  * @param $args[0] : type of pager ('subcats','pages','files')
  * @param $args[1] : parent category name
  * @param $args[2] : offset (optional)
  * @param $args[3] : limit (optional)
  */
 static function getSubOffsetHtml()
 {
     $pager_types = array('subcats' => array('js_nav_func' => "subCatsNav", 'select_fields' => "cl_sortkey, cat_id, cat_title, cat_subcats, " . CB_AbstractPager::$cat_pages_only . ", cat_files", 'ns_cond' => "page_namespace = " . NS_CATEGORY, 'default_limit' => CB_Setup::$categoriesLimit), 'pages' => array('js_nav_func' => "pagesNav", 'select_fields' => "page_title, page_namespace, page_len, page_is_redirect", 'ns_cond' => "NOT page_namespace IN (" . NS_FILE . "," . NS_CATEGORY . ")", 'default_limit' => CB_Setup::$pagesLimit), 'files' => array('js_nav_func' => "filesNav", 'select_fields' => "page_title, page_namespace, page_len, page_is_redirect", 'ns_cond' => "page_namespace = " . NS_FILE, 'default_limit' => CB_Setup::$filesLimit), 'parents' => array('default_limit' => CB_Setup::$parentsLimit));
     $args = func_get_args();
     if (count($args) < 2) {
         return 'Too few parameters in ' . __METHOD__;
     }
     $pager_type = $args[0];
     if (!isset($pager_types[$pager_type])) {
         return 'Unknown pager type=' . CB_Setup::specialchars($pager_type) . ' in ' . __METHOD__;
     }
     $pager_setup =& $pager_types[$pager_type];
     $limit = count($args) > 3 ? abs(intval($args[3])) : $pager_setup['default_limit'];
     $offset = count($args) > 2 ? abs(intval($args[2])) : 0;
     $parentCatName = $args[1];
     $cb = new CategoryBrowser();
     if ($pager_type == 'parents') {
         $pager = new CB_ParentPager($parentCatName, $offset, $limit);
     } else {
         $pager = new CB_SubPager($parentCatName, $offset, $limit, $pager_setup['js_nav_func'], $pager_setup['select_fields'], $pager_setup['ns_cond']);
     }
     $pager->getCurrentRows();
     switch ($pager_type) {
         case 'subcats':
         case 'parents':
             $view = new CB_CategoriesView($pager);
             break;
         case 'pages':
             $view = new CB_PagesView($pager);
             break;
         case 'files':
             # respect extension & core settings
             global $wgOut, $wgCategoryMagicGallery;
             // unstub $wgOut, otherwise $wgOut->mNoGallery may be unavailable
             // strange, but calling wfDebug() instead does not unstub $wgOut successfully
             $wgOut->getHeadItems();
             if (CB_Setup::$imageGalleryPerRow < 1 || !$wgCategoryMagicGallery || $wgOut->mNoGallery) {
                 $view = new CB_PagesView($pager);
             } else {
                 $view = new CB_FilesView($pager);
             }
             break;
         default:
             return 'Unknown list type in ' . __METHOD__;
     }
     $list = $view->generateList();
     return CB_XML::toText($list);
 }