Пример #1
0
 protected function generateContent()
 {
     $conditions = [];
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     if ($_ = $this->filterObj->getConditions()) {
         $conditions[] = $_;
     }
     $itemsets = new ItemsetList($conditions);
     $this->extendGlobalData($itemsets->getJSGlobals());
     // recreate form selection
     $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter);
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
     $this->filter['fi'] = $this->filterObj->getForm();
     $this->addJS('?data=weight-presets&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     $lv = array('file' => 'itemset', 'data' => $itemsets->getListviewData(), 'params' => []);
     if (!empty($this->filter['fi']['extraCols'])) {
         $lv['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
     }
     // create note if search limit was exceeded
     if ($itemsets->getMatches() > CFG_SQL_LIMIT_DEFAULT) {
         $lv['params']['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_itemsetsfound', $itemsets->getMatches(), CFG_SQL_LIMIT_DEFAULT);
         $lv['params']['_truncated'] = 1;
     }
     if ($this->filterObj->error) {
         $lv['params']['_errors'] = '$1';
     }
     $this->lvTabs[] = $lv;
     // sort for dropdown-menus
     Lang::sort('itemset', 'notes', SORT_NATURAL);
     Lang::sort('game', 'si');
 }
Пример #2
0
 protected function generateContent()
 {
     $conditions = [];
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     // include child categories if current category is empty
     if ($this->category) {
         $conditions[] = ['category', (int) end($this->category)];
     }
     // recreate form selection
     $this->filter = $this->filterObj->getForm('form');
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : null;
     $this->filter['fi'] = $this->filterObj->getForm();
     if ($fiCnd = $this->filterObj->getConditions()) {
         $conditions[] = $fiCnd;
     }
     $acvList = new AchievementList($conditions);
     if (!$acvList->getMatches()) {
         $curCats = $catList = [!empty($this->category) ? (int) end($this->category) : 0];
         while ($curCats) {
             $curCats = DB::Aowow()->SelectCol('SELECT Id FROM ?_achievementcategory WHERE parentCategory IN (?a)', $curCats);
             $catList = array_merge($catList, $curCats);
         }
         $conditions = [];
         if ($fiCnd) {
             $conditions[] = $fiCnd;
         }
         if ($catList) {
             $conditions[] = ['category', $catList];
         }
         $acvList = new AchievementList($conditions);
     }
     $params = $data = [];
     if (!$acvList->error) {
         $data = $acvList->getListviewData();
         // fill g_items, g_titles, g_achievements
         $this->extendGlobalData($acvList->getJSGlobals());
         // if we are have different cats display field
         if ($acvList->hasDiffFields(['category'])) {
             $params['visibleCols'] = "\$['category']";
         }
         if (!empty($this->filter['fi']['extraCols'])) {
             $params['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
         }
         // create note if search limit was exceeded
         if ($acvList->getMatches() > CFG_SQL_LIMIT_DEFAULT) {
             $params['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_achievementsfound', $acvList->getMatches(), CFG_SQL_LIMIT_DEFAULT);
             $params['_truncated'] = 1;
         }
         if ($this->filterObj->error) {
             $params['_errors'] = '$1';
         }
     }
     $this->lvTabs[] = array('file' => 'achievement', 'data' => $data, 'params' => $params);
     // sort for dropdown-menus in filter
     Lang::sort('game', 'si');
 }
Пример #3
0
 protected function generateContent()
 {
     $this->addJS('?data=weight-presets.realms&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     $tDistrib = $this->getTalentDistribution($this->character['talents']['builds'][$this->character['talents']['active']]['talents']);
     $exampleRow = array('id' => 0, 'name' => $this->character['name'], 'achievementpoints' => $this->character['achievementpoints'], 'guild' => $this->character['guild'], 'guildRank' => -1, 'realm' => $this->character['realm'][0], 'realmname' => $this->character['realm'][1], 'battlegroup' => $this->character['battlegroup'][0], 'battlegroupname' => $this->character['battlegroup'][0], 'region' => $this->character['region'][0], 'level' => $this->character['level'], 'race' => $this->character['race'], 'gender' => $this->character['gender'], 'classs' => $this->character['classs'], 'faction' => $this->character['faction'], 'talenttree1' => $tDistrib[0], 'talenttree2' => $tDistrib[1], 'talenttree3' => $tDistrib[2], 'talentspec' => $this->character['talents']['active']);
     // description:'{$curr.description|escape:"javascript"}',
     // icon:'{$curr.icon|escape:"javascript"}',
     // published:1,
     // pinned:1,
     // deleted:1,
     // dont send ID for real chars unless they have some kind of custom avatar
     // on second thought .. ids are required for resync, but the function that generates the icon is faulty
     $this->lvTabs[] = array('file' => 'profile', 'data' => [$exampleRow], 'params' => ['id' => 'characters', 'name' => '$LANG.tab_characters', 'hideCount' => 1, '_truncated' => 1, 'roster' => 3, 'visibleCols' => "\$['race','classs','level','talents','achievementpoints']", 'note' => '$$WH.sprintf(LANG.lvnote_charactersfound, \'20,592,390\', 200) + LANG.dash + LANG.lvnote_tryfiltering.replace(\'<a>\', \'<a href="javascript:;" onclick="fi_toggle()">\')', 'onBeforeCreate' => '$pr_initRosterListview']);
     $this->filter = ['query' => 1, 'fi' => []];
     Lang::sort('game', 'cl');
     Lang::sort('game', 'ra');
 }
Пример #4
0
 protected function generateContent()
 {
     $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     $conditions = [];
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     if ($this->category) {
         $conditions[] = ['type', $this->category[0]];
         $this->petFamPanel = $this->category[0] == 1;
     } else {
         $this->petFamPanel = false;
     }
     if ($_ = $this->filterObj->getConditions()) {
         $conditions[] = $_;
     }
     // beast subtypes are selected via filter
     $npcs = new CreatureList($conditions, ['extraOpts' => $this->filterObj->extraOpts]);
     // recreate form selection
     $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter);
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
     $this->filter['fi'] = $this->filterObj->getForm();
     $repCols = $this->filterObj->getForm('reputationCols');
     $tabData = array('data' => array_values($npcs->getListviewData($repCols ? NPCINFO_REP : 0x0)));
     if ($repCols) {
         $tabData['extraCols'] = '$fi_getReputationCols(' . Util::toJSON($repCols) . ')';
     } else {
         if (!empty($this->filter['fi']['extraCols'])) {
             $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
         }
     }
     if ($this->category) {
         $tabData['hiddenCols'] = ['type'];
     }
     // create note if search limit was exceeded
     if ($npcs->getMatches() > CFG_SQL_LIMIT_DEFAULT) {
         $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_npcsfound', $npcs->getMatches(), CFG_SQL_LIMIT_DEFAULT);
         $tabData['_truncated'] = 1;
     }
     if ($this->filterObj->error) {
         $tabData['_errors'] = 1;
     }
     $this->lvTabs[] = ['creature', $tabData];
     // sort for dropdown-menus
     Lang::sort('game', 'fa');
 }
Пример #5
0
 protected function generateContent()
 {
     $this->addJS('?data=weight-presets&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     $conditions = [];
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     /*******************/
     /* evaluate filter */
     /*******************/
     // recreate form selection (must be evaluated first via getConditions())
     if ($_ = $this->filterObj->getConditions()) {
         $conditions[] = $_;
     }
     $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter);
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : null;
     $this->filter['fi'] = $this->filterObj->getForm();
     $menu = $this->createExtraMenus();
     foreach ($menu['type'][0] as $k => $str) {
         if ($str && (!$menu['type'][1] || $menu['type'][1] & 1 << $k)) {
             $this->filter['type'][$k] = $str;
         }
     }
     foreach ($menu['slot'][0] as $k => $str) {
         if ($str && (!$menu['slot'][1] || $menu['slot'][1] & 1 << $k)) {
             $this->filter['slot'][$k] = $str;
         }
     }
     if (isset($this->filter['slot'][INVTYPE_SHIELD])) {
         // "Off Hand" => "Shield"
         $this->filter['slot'][INVTYPE_SHIELD] = Lang::item('armorSubClass', 6);
     }
     $xCols = $this->filterObj->getForm('extraCols', true);
     $infoMask = ITEMINFO_JSON;
     if (array_intersect([63, 64, 125], $xCols)) {
         // 63:buyPrice; 64:sellPrice; 125:reqarenartng
         $infoMask |= ITEMINFO_VENDOR;
     }
     if (!empty($this->filter['fi']['extraCols'])) {
         $this->sharedLV['extraCols'] = '$fi_getExtraCols(fi_extraCols, ' . (isset($this->filter['gm']) ? $this->filter['gm'] : 0) . ', ' . (array_intersect([63], $xCols) ? 1 : 0) . ')';
     }
     if ($this->filterObj->error) {
         $this->sharedLV['_errors'] = '$1';
     }
     /******************/
     /* set conditions */
     /******************/
     if (isset($this->category[0])) {
         $conditions[] = ['i.class', $this->category[0]];
     }
     if (isset($this->category[1])) {
         $conditions[] = ['i.subClass', $this->category[1]];
     }
     if (isset($this->category[2])) {
         $conditions[] = ['i.subSubClass', $this->category[2]];
     }
     /***********************/
     /* handle auto-gemming */
     /***********************/
     $this->gemScores = $this->createGemScores();
     /*************************/
     /* handle upgrade search */
     /*************************/
     $upgItemData = [];
     if (!empty($this->filter['upg']) && !empty($this->filter['fi']['setWeights'])) {
         $upgItems = new ItemList(array(['id', array_keys($this->filter['upg'])]), ['extraOpts' => $this->filterObj->extraOpts]);
         if (!$upgItems->error) {
             $this->extendGlobalData($upgItems->getJSGlobals());
             $upgItemData = $upgItems->getListviewData($infoMask);
         }
     }
     if ($upgItemData) {
         $singleSlot = true;
         $ref = reset($this->filter['upg']);
         foreach ($this->filter['upg'] as $slot) {
             if ($slot == $ref) {
                 continue;
             }
             $singleSlot = false;
             break;
         }
         if ($singleSlot && empty($this->filter['gb'])) {
             // enforce group by slot
             $this->filter['gb'] = 1;
         } else {
             if (!$singleSlot) {
                 $this->filter['gb'] = 1;
                 $maxResults = 25;
                 $this->sharedLV['customFilter'] = '$fi_filterUpgradeListview';
             }
         }
     }
     /********************************************************************************************************************************/
     /* group by                                                                                                                     */
     /*                                                                                                                              */
     /* cases that make sense:                                                                                                       */
     /* no upgItems             -> everything goes                                                                                   */
     /*  1 upgItems             OR                                                                                                   */
     /*  N upgItems (same slot) -> gb:none   - disabled                                                                              */
     /*                         -> gb:slot   - limited to slot of the upgItems (in theory weapons create a tab for each weapon type) */
     /*                         -> gb:level  - upgItems is added to all tabs                                                         */
     /*                         -> gb:source - upgItems is added to all tabs                                                         */
     /*  N upgItems (random)    -> gb:none   - disabled                                                                              */
     /*                         -> gb:slot   - only slots existing within the upgItems; match upgItems to slot                       */
     /*                         -> gb:level  - disabled                                                                              */
     /*                         -> gb:source - disabled                                                                              */
     /********************************************************************************************************************************/
     $availableSlots = array(ITEM_CLASS_ARMOR => [INVTYPE_HEAD, INVTYPE_NECK, INVTYPE_SHOULDERS, INVTYPE_CHEST, INVTYPE_WAIST, INVTYPE_LEGS, INVTYPE_FEET, INVTYPE_WRISTS, INVTYPE_HANDS, INVTYPE_FINGER, INVTYPE_TRINKET, INVTYPE_SHIELD, INVTYPE_CLOAK], ITEM_CLASS_WEAPON => [INVTYPE_WEAPON, INVTYPE_RANGED, INVTYPE_2HWEAPON, INVTYPE_WEAPONMAINHAND, INVTYPE_WEAPONOFFHAND, INVTYPE_THROWN, INVTYPE_HOLDABLE]);
     $groups = [];
     $nameSource = [];
     $grouping = isset($this->filter['gb']) ? $this->filter['gb'] : null;
     $extraOpts = [];
     $maxResults = CFG_SQL_LIMIT_DEFAULT;
     switch ($grouping) {
         // slot: (try to limit the lookups by class grouping and intersecting with preselected slots)
         // if intersect yields an empty array no lookups will occur
         case 1:
             if (isset($this->category[0]) && $this->category[0] == ITEM_CLASS_ARMOR) {
                 $groups = $availableSlots[ITEM_CLASS_ARMOR];
             } else {
                 if (isset($this->category[0]) && $this->category[0] == ITEM_CLASS_WEAPON) {
                     $groups = $availableSlots[ITEM_CLASS_WEAPON];
                 } else {
                     $groups = array_merge($availableSlots[ITEM_CLASS_ARMOR], $availableSlots[ITEM_CLASS_WEAPON]);
                 }
             }
             if (isset($this->filter['sl'])) {
                 // skip lookups for unselected slots
                 $groups = array_intersect($groups, (array) $this->filter['sl']);
             }
             if (!empty($this->filter['upg'])) {
                 // skip lookups for slots we dont have items to upgrade for
                 $groups = array_intersect($groups, (array) $this->filter['upg']);
             }
             if ($groups) {
                 $nameSource = Lang::item('inventoryType');
                 $this->forceTabs = true;
             }
             break;
         case 2:
             // itemlevel: first, try to find 10 level steps within range (if given) as tabs
             // ohkayy, maybe i need to rethink $this
             $this->filterOpts = $this->filterObj->extraOpts;
             $this->filterOpts['is']['o'] = [null];
             // remove 'order by' from itemStats
             $extraOpts = array_merge($this->filterOpts, ['i' => ['g' => ['itemlevel'], 'o' => ['itemlevel DESC']]]);
             $levelRef = new ItemList(array_merge($conditions, [10]), ['extraOpts' => $extraOpts]);
             foreach ($levelRef->iterate() as $_) {
                 $l = $levelRef->getField('itemLevel');
                 $groups[] = $l;
                 $nameSource[$l] = Lang::game('level') . ' ' . $l;
             }
             if ($groups) {
                 $l = -end($groups);
                 $groups[] = $l;
                 // push last value as negativ to signal misc group after $this level
                 $extraOpts = ['i' => ['o' => ['itemlevel DESC']]];
                 $nameSource[$l] = Lang::item('tabOther');
                 $this->forceTabs = true;
             }
             break;
         case 3:
             // source
             $groups = [1, 2, 3, 4, 5, 10, 11, 12, 0];
             $nameSource = Lang::game('sources');
             $this->forceTabs = true;
             break;
             // none
         // none
         default:
             $grouping = 0;
             $groups[0] = null;
     }
     /*****************************/
     /* create lv-tabs for groups */
     /*****************************/
     foreach ($groups as $group) {
         switch ($grouping) {
             case 1:
                 $finalCnd = array_merge($conditions, [['slot', $group], $maxResults]);
                 break;
             case 2:
                 $finalCnd = array_merge($conditions, [['itemlevel', abs($group), $group > 0 ? null : '<'], $maxResults]);
                 break;
             case 3:
                 $finalCnd = array_merge($conditions, [$group ? ['src.src' . $group, null, '!'] : ['src.typeId', null], $maxResults]);
                 break;
             default:
                 $finalCnd = $conditions;
         }
         $items = new ItemList($finalCnd, ['extraOpts' => array_merge($extraOpts, $this->filterObj->extraOpts)]);
         if ($items->error) {
             continue;
         }
         $this->extendGlobalData($items->getJSGlobals());
         $tabData = array_merge(['data' => $items->getListviewData($infoMask)], $this->sharedLV);
         $upg = [];
         if ($upgItemData) {
             if ($grouping == 1) {
                 $upg = array_keys(array_filter($this->filter['upg'], function ($v) use($group) {
                     return $v == $group;
                 }));
                 foreach ($upg as $uId) {
                     $tabData['data'][$uId] = $upgItemData[$uId];
                 }
                 if ($upg) {
                     $tabData['_upgradeIds'] = $upg;
                 }
             } else {
                 if ($grouping) {
                     $upg = array_keys($this->filter['upg']);
                     $tabData['_upgradeIds'] = $upg;
                     foreach ($upgItemData as $uId => $data) {
                         // using numeric keys => cant use array_merge
                         $tabData['data'][$uId] = $data;
                     }
                 }
             }
         }
         if ($grouping) {
             switch ($grouping) {
                 case 1:
                     $tabData['id'] = 'slot-' . $group;
                     break;
                 case 2:
                     $tabData['id'] = $group > 0 ? 'level-' . $group : 'other';
                     break;
                 case 3:
                     $tabData['id'] = $group ? 'source-' . $group : 'unknown';
                     break;
             }
             $tabData['name'] = $nameSource[$group];
             $tabData['tabs'] = '$tabsGroups';
         }
         if (!empty($this->filter['fi']['setWeights'])) {
             if ($items->hasSetFields(['armor'])) {
                 $tabData['visibleCols'][] = 'armor';
             }
         }
         // create note if search limit was exceeded; overwriting 'note' is intentional
         if ($items->getMatches() > $maxResults && count($groups) > 1) {
             $tabData['_truncated'] = 1;
             $cls = isset($this->category[0]) ? '=' . $this->category[0] : '';
             $override = ['gb' => ''];
             if ($upg) {
                 $override['upg'] = implode(':', $upg);
             }
             switch ($grouping) {
                 case 1:
                     $override['sl'] = $group;
                     $tabData['note'] = '$$WH.sprintf(LANG.lvnote_viewmoreslot, \'' . $cls . '\', \'' . $this->filterObj->urlize($override) . '\')';
                     break;
                 case 2:
                     if ($group > 0) {
                         $override['minle'] = $group;
                         $override['maxle'] = $group;
                     } else {
                         $override['maxle'] = abs($group) - 1;
                     }
                     $tabData['note'] = '$$WH.sprintf(LANG.lvnote_viewmorelevel, \'' . $cls . '\', \'' . $this->filterObj->urlize($override) . '\')';
                     break;
                 case 3:
                     if ($_ = [null, 3, 4, 5, 6, 7, 9, 10, 11][$group]) {
                         $tabData['note'] = '$$WH.sprintf(LANG.lvnote_viewmoresource, \'' . $cls . '\', \'' . $this->filterObj->urlize($override, ['cr' => 128, 'crs' => $_, 'crv' => 0]) . '\')';
                     }
                     break;
             }
         } else {
             if ($items->getMatches() > $maxResults) {
                 $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_itemsfound', $items->getMatches(), CFG_SQL_LIMIT_DEFAULT);
                 $tabData['_truncated'] = 1;
             }
         }
         foreach ($tabData as $k => $p) {
             if (!$p && $k != 'data') {
                 unset($tabData[$k]);
             }
         }
         if ($grouping) {
             $tabData['hideCount'] = 1;
         }
         $tabData['data'] = array_values($tabData['data']);
         $this->lvTabs[] = ['item', $tabData];
     }
     // reformat for use in template
     if (!empty($this->filter['upg'])) {
         $this->filter['upg'] = implode(':', array_keys($this->filter['upg']));
     }
     // whoops, we have no data? create emergency content
     if (empty($this->lvTabs)) {
         $this->forceTabs = false;
         $this->lvTabs[] = ['item', ['data' => []]];
     }
     // sort for dropdown-menus
     Lang::sort('game', 'ra');
     Lang::sort('game', 'cl');
 }
Пример #6
0
 protected function generateContent()
 {
     $conditions = [];
     $visibleCols = [];
     $hiddenCols = [];
     $tabData = ['data' => []];
     // the next lengthy ~250 lines determine $conditions and lvParams
     if ($this->category) {
         switch ($this->category[0]) {
             case -2:
                 // Character Talents
                 $this->filter['classPanel'] = true;
                 array_push($visibleCols, 'singleclass', 'level', 'schools', 'tier');
                 $conditions[] = ['s.typeCat', -2];
                 // i will NOT redefine those class2skillId ... reusing
                 if (isset($this->category[2])) {
                     $conditions[] = ['s.skillLine1', $this->category[2]];
                 } else {
                     if (isset($this->category[1])) {
                         $conditions[] = ['s.skillLine1', $this->validCats[-2][$this->category[1]]];
                     }
                 }
                 break;
             case -3:
                 // Pet Spells
                 array_push($visibleCols, 'level', 'schools');
                 $conditions[] = ['s.typeCat', -3];
                 if (isset($this->category[1])) {
                     $xCond = null;
                     for ($i = -2; $i < 0; $i++) {
                         foreach (Util::$skillLineMask[$i] as $idx => $pair) {
                             if ($pair[1] == $this->category[1]) {
                                 $xCond = ['AND', ['s.skillLine1', $i], ['s.skillLine2OrMask', 1 << $idx, '&']];
                                 break;
                             }
                         }
                     }
                     $conditions[] = ['OR', $xCond, ['s.skillLine1', $this->category[1]], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]]];
                 } else {
                     $conditions[] = ['OR', ['s.skillLine1', [-1, -2]], ['s.skillLine1', $this->validCats[-3]], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[-3]]]];
                 }
                 break;
             case -4:
                 // Racials
                 array_push($visibleCols, 'classes');
                 $conditions[] = ['s.typeCat', -4];
                 break;
             case -8:
                 // NPC-Spells
             // NPC-Spells
             case -9:
                 // GM Spells
                 array_push($visibleCols, 'level');
             case -5:
                 // Mounts
             // Mounts
             case -6:
                 // Companions
                 $conditions[] = ['s.typeCat', $this->category[0]];
                 break;
             case -7:
                 // Pet Talents
                 array_push($visibleCols, 'level', 'tier');
                 $conditions[] = ['s.typeCat', -7];
                 if (isset($this->category[1])) {
                     switch ($this->category[1]) {
                         case 409:
                             // Tenacity
                             $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE1, '&'];
                             $url = '?pets=1';
                             break;
                         case 410:
                             // Cunning
                             $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE2, '&'];
                             $url = '?pets=2';
                             break;
                         case 411:
                             // Ferocity
                             $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE0, '&'];
                             $url = '?pets=0';
                             break;
                     }
                     $tabData['note'] = '$$WH.sprintf(LANG.lvnote_pettalents, "' . $url . '")';
                 }
                 $tabData['_petTalents'] = 1;
                 // not conviced, this is correct, but .. it works
                 break;
             case -11:
                 // Proficiencies ... the subIds are actually SkillLineCategories
                 if (!isset($this->category[1]) || $this->category[1] != 10) {
                     array_push($visibleCols, 'classes');
                 }
                 $conditions[] = ['s.typeCat', -11];
                 if (isset($this->category[1])) {
                     if ($this->category[1] == 6) {
                         // todo (med): we know Weapon(6) includes spell Shoot(3018), that has a mask; but really, ANY proficiency or petSkill should be in that mask so there is no need to differenciate
                         $conditions[] = ['OR', ['s.skillLine1', SpellList::$skillLines[$this->category[1]]], ['s.skillLine1', -3]];
                     } else {
                         $conditions[] = ['s.skillLine1', SpellList::$skillLines[$this->category[1]]];
                     }
                 }
                 break;
             case -13:
                 // Glyphs
                 $this->filter['classPanel'] = true;
                 $this->filter['glyphPanel'] = true;
                 array_push($visibleCols, 'singleclass', 'glyphtype');
                 $conditions[] = ['s.typeCat', -13];
                 if (isset($this->category[1])) {
                     $conditions[] = ['s.reqClassMask', 1 << $this->category[1] - 1, '&'];
                 }
                 break;
             case 7:
                 // Abilities
                 $this->filter['classPanel'] = true;
                 array_push($visibleCols, 'level', 'singleclass', 'schools');
                 $conditions[] = ['s.typeCat', [7, -2]];
                 $conditions[] = [['s.cuFlags', SPELL_CU_TRIGGERED | SPELL_CU_TALENT, '&'], 0];
                 // Runeforging listed multiple times, exclude from explicit skill-listing
                 // if (isset($this->category[1]) && $this->category[1] == 6 && isset($this->category[2]) && $this->category[2] != 776)
                 // $conditions[] = [['s.attributes0', 0x80, '&'], 0];
                 // else
                 // $conditions[] = [
                 // [['s.attributes0', 0x80, '&'], 0],      // ~SPELL_ATTR0_HIDDEN_CLIENTSIDE
                 // ['s.attributes0', 0x20, '&'],           // SPELL_ATTR0_TRADESPELL (DK: Runeforging)
                 // 'OR'
                 // ];
                 if (isset($this->category[2])) {
                     $conditions[] = ['OR', ['s.skillLine1', $this->category[2]], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[2]]]];
                 } else {
                     if (isset($this->category[1])) {
                         $conditions[] = ['OR', ['s.skillLine1', $this->validCats[7][$this->category[1]]], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[7][$this->category[1]]]]];
                     }
                 }
                 break;
             case 9:
                 // Secondary Skills
                 array_push($visibleCols, 'source');
                 $conditions[] = ['s.typeCat', 9];
                 if (isset($this->category[1])) {
                     $conditions[] = ['OR', ['s.skillLine1', $this->category[1]], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]]];
                     if (!empty($this->shortFilter[$this->category[1]])) {
                         $sf = $this->shortFilter[$this->category[1]];
                         $txt = '';
                         if ($sf[0] && $sf[1]) {
                             $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]) . Lang::spell('relItems', 'link') . sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
                         } else {
                             if ($sf[0]) {
                                 $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]);
                             } else {
                                 if ($sf[1]) {
                                     $txt = sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
                                 }
                             }
                         }
                         $note = Lang::spell('cat', $this->category[0], $this->category[1]);
                         if (is_array($note)) {
                             $note = $note[0];
                         }
                         $tabData['note'] = sprintf(Lang::spell('relItems', 'base'), $txt, $note);
                         $tabData['sort'] = ['skill', 'name'];
                     }
                 }
                 break;
             case 11:
                 // Professions
                 array_push($visibleCols, 'source');
                 $conditions[] = ['s.typeCat', 11];
                 if (isset($this->category[2])) {
                     if ($this->category[2] == 9787) {
                         // general weaponsmithing
                         $conditions[] = ['s.reqSpellId', [9787, 17039, 17040, 17041]];
                     } else {
                         $conditions[] = ['s.reqSpellId', $this->category[2]];
                     }
                 } else {
                     if (isset($this->category[1])) {
                         $conditions[] = ['s.skillLine1', $this->category[1]];
                     }
                 }
                 if (isset($this->category[1])) {
                     $conditions[] = ['s.skillLine1', $this->category[1]];
                     if (!empty($this->shortFilter[$this->category[1]])) {
                         $sf = $this->shortFilter[$this->category[1]];
                         $txt = '';
                         if ($sf[0] && $sf[1]) {
                             $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]) . Lang::spell('relItems', 'link') . sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
                         } else {
                             if ($sf[0]) {
                                 $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]);
                             } else {
                                 if ($sf[1]) {
                                     $txt = sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
                                 }
                             }
                         }
                         $note = Lang::spell('cat', $this->category[0], $this->category[1]);
                         if (is_array($note)) {
                             $note = $note[0];
                         }
                         $tabData['note'] = sprintf(Lang::spell('relItems', 'base'), $txt, $note);
                         $tabData['sort'] = ['skill', 'name'];
                     }
                 }
                 break;
             case 0:
                 // misc. Spells & triggered player abilities
                 array_push($visibleCols, 'level');
                 $conditions[] = ['OR', ['s.typeCat', 0], ['AND', ['s.cuFlags', SPELL_CU_TRIGGERED, '&'], ['s.typeCat', [7, -2]]]];
                 break;
         }
     }
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     if ($_ = $this->filterObj->getConditions()) {
         $conditions[] = $_;
     }
     $spells = new SpellList($conditions);
     $this->extendGlobalData($spells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
     $tabData['data'] = array_values($spells->getListviewData());
     // recreate form selection
     $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter);
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL;
     $this->filter['fi'] = $this->filterObj->getForm();
     if (!empty($this->filter['fi']['extraCols'])) {
         $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
     }
     // create note if search limit was exceeded; overwriting 'note' is intentional
     if ($spells->getMatches() > CFG_SQL_LIMIT_DEFAULT) {
         $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_spellsfound', $spells->getMatches(), CFG_SQL_LIMIT_DEFAULT);
         $tabData['_truncated'] = 1;
     }
     if ($this->filterObj->error) {
         $tabData['_errors'] = 1;
     }
     // add source to cols if explicitly searching for it
     if ($_ = $this->filterObj->getForm('setCriteria', true)) {
         if (in_array(9, $_['cr']) && !in_array('source', $visibleCols)) {
             $visibleCols[] = 'source';
         }
     }
     $mask = $spells->hasSetFields(['reagent1', 'skillLines', 'trainingCost', 'reqClassMask']);
     if ($mask & 0x1) {
         $visibleCols[] = 'reagents';
     }
     if (!($mask & 0x2) && $this->category && !in_array($this->category[0], [9, 11])) {
         $hiddenCols[] = 'skill';
     }
     if ($mask & 0x4) {
         $visibleCols[] = 'trainingcost';
     }
     if ($mask & 0x8 && !in_array('singleclass', $visibleCols)) {
         $visibleCols[] = 'singleclass';
     }
     if ($visibleCols) {
         $tabData['visibleCols'] = $visibleCols;
     }
     if ($hiddenCols) {
         $tabData['hiddenCols'] = $hiddenCols;
     }
     $this->lvTabs[] = ['spell', $tabData];
     // sort for dropdown-menus
     Lang::sort('game', 'ra');
     Lang::sort('game', 'cl');
     Lang::sort('game', 'sc');
     Lang::sort('game', 'me');
 }