diff --git a/includes/types/basetype.class.php b/includes/types/basetype.class.php index 59148eb3..f4a16b71 100644 --- a/includes/types/basetype.class.php +++ b/includes/types/basetype.class.php @@ -234,15 +234,15 @@ abstract class BaseType // append grouping if ($g = array_column($this->queryOpts, 'g')) - $this->queryBase .= ' GROUP BY '.implode(', ', $g); + $this->queryBase .= ' GROUP BY '.implode(', ', array_filter($g)); // append post filtering if ($h = array_column($this->queryOpts, 'h')) - $this->queryBase .= ' HAVING '.implode(' AND ', $h); + $this->queryBase .= ' HAVING '.implode(' AND ', array_filter($h)); // append ordering if ($o = array_column($this->queryOpts, 'o')) - $this->queryBase .= ' ORDER BY '.implode(', ', $o); + $this->queryBase .= ' ORDER BY '.implode(', ', array_filter($o)); // apply limit if ($limit) @@ -651,9 +651,10 @@ abstract class Filter $this->formData['form'][$w[0]] = $tmp2; - array_walk($tmp2, function(&$v) { $v = intVal($v); }); + array_walk($tmp2, function(&$v) { + $v = intVal($v); + }); $this->fiData['v'][$w[0]] = $tmp2; - } else { @@ -662,10 +663,7 @@ abstract class Filter $this->sanitize($w[1]); if ($w[1] !== '') - { - Util::checkNumeric($w[1]); $this->fiData['v'][$w[0]] = $w[1]; - } else $this->error = true; } diff --git a/includes/types/item.class.php b/includes/types/item.class.php index fba7fb3e..6d05bf22 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -23,7 +23,7 @@ class ItemList extends BaseType protected $queryBase = 'SELECT i.*, i.id AS ARRAY_KEY FROM ?_items i'; protected $queryOpts = array( - 'is' => ['s' => ', 1 as score', 'j' => '?_item_stats AS `is` ON `is`.`id` = `i`.`id`', 'h' => 'score > 0', 'o' => 'score DESC'], + 'is' => ['j' => '?_item_stats AS `is` ON `is`.`id` = `i`.`id`', 'o' => 'score DESC'], 's' => ['j' => ['?_spell AS `s` ON s.effect1CreateItemId = i.id', true], 'g' => 'i.id'], 'i' => ['o' => 'i.quality DESC, i.itemLevel DESC'] ); @@ -1407,7 +1407,8 @@ class ItemList extends BaseType class ItemListFilter extends Filter { private $ubFilter = []; // usable-by - limit weapon/armor selection per CharClass - itemClass => available itemsubclasses - public $extraOpts = null; // score for statWeights + public $extraOpts = []; // score for statWeights + public $wtCnd = []; protected $enums = array( 99 => array( // profession | recycled for 86, 87 null, 171, 164, 185, 333, 202, 129, 755, 165, 186, 197, true, false, 356, 182, 773 @@ -1562,7 +1563,8 @@ class ItemListFilter extends Filter if (!$data['wt'] || !$data['wtv'] || count($data['wt']) != count($data['wtv'])) return null; - $select = $cnd = []; + $this->wtCnd = []; + $select = []; $wtSum = 0; foreach ($data['wt'] as $k => $v) @@ -1578,9 +1580,9 @@ class ItemListFilter extends Filter if ($str == 'mledps') // todo (med): unify rngdps and mledps to dps $str = 'dps'; - $select[] = '(`is`.`'.$str.'` * '.$qty.')'; - $cnd[] = ['is.'.$str, 0, '>']; - $wtSum += $qty; + $select[] = '(`is`.`'.$str.'` * '.$qty.')'; + $this->wtCnd[] = ['is.'.$str, 0, '>']; + $wtSum += $qty; } else // well look at that.. erronous indizes or zero-weights { @@ -1589,15 +1591,20 @@ class ItemListFilter extends Filter } } - if (count($cnd) > 1) - array_unshift($cnd, 'OR'); - else if (count($cnd) == 1) - $cnd = $cnd[0]; + if (count($this->wtCnd) > 1) + array_unshift($this->wtCnd, 'OR'); + else if (count($this->wtCnd) == 1) + $this->wtCnd = $this->wtCnd[0]; if ($select) + { $this->extraOpts['is']['s'][] = ', ('.implode(' + ', $select).') / '.$wtSum.' AS score'; + $this->extraOpts['i']['o'][] = null; // remove default ordering + } + else + $this->extraOpts['is']['s'][] = ', 0 AS score'; // prevent errors - return $cnd; + return $this->wtCnd; } protected function createSQLForCriterium(&$cr) @@ -1898,12 +1905,18 @@ class ItemListFilter extends Filter { // valid item? if (!is_int($_v['upg']) && !is_array($_v['upg'])) + { + unset($this->formData['form']['upg']); unset($_v['upg']); + } else { $_ = DB::Aowow()->selectCol('SELECT id as ARRAY_KEY, slot FROM ?_items WHERE class IN (2, 3, 4) AND id IN (?a)', (array)$_v['upg']); if ($_ === null) + { unset($_v['upg']); + unset($this->formData['form']['upg']); + } else { $this->formData['form']['upg'] = $_; diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 97ca859a..19b225f4 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -165,8 +165,8 @@ $lang = array( 'zone' => "zone", 'zones' => "Zones", - 'honorPoints' => "Honor Points", // tooltip_honorpoints - 'arenaPoints' => "Arena Points", // tooltip_arenapoints + 'honorPoints' => "Honor Points", + 'arenaPoints' => "Arena Points", 'heroClass' => "Hero class", 'resource' => "Resource", 'resources' => "Resources", diff --git a/pages/account.php b/pages/account.php index 8b6c32e6..35e9784e 100644 --- a/pages/account.php +++ b/pages/account.php @@ -216,7 +216,7 @@ function signup() $smarty->assign('signup_error', Lang::$account['nameInUse']); else { - $success = DB::Auth()->query('INSERT INTO aowow_account (user, passHash, displayName, email, joindate, lastIP, locale) VALUES (?, ?, ?, ?, NOW(), ?, ?)', + $success = DB::Aowow()->query('INSERT INTO aowow_account (user, passHash, displayName, email, joindate, lastIP, locale) VALUES (?, ?, ?, ?, NOW(), ?, ?)', $_POST['username'], sha1(strtoupper($_POST['username']).':'.strtoupper($_POST['password'])), Util::ucFirst($_POST['username']), @@ -270,24 +270,24 @@ if (User::$id) $next = !empty($next[1]) ? '?'.$next[1] : '.'; header('Location: '.$next); case 'weightscales': - if (isset($post['save'])) + if (isset($_POST['save']) && User::$id) { - if (!isset($post['id'])) + if (!isset($_POST['id'])) { $res = DB::Aowow()->selectRow('SELECT max(id) as max, count(id) as num FROM ?_account_weightscales WHERE account = ?d', User::$id); if ($res['num'] < 5) // more or less hard-defined in LANG.message_weightscalesaveerror - $post['id'] = ++$res['max']; + $_POST['id'] = ++$res['max']; else die('0'); } - if (DB::Aowow()->query('REPLACE INTO ?_account_weightscales VALUES (?d, ?d, ?, ?)', intVal($post['id']), User::$id, $post['name'], $post['scale'])) - die((string)$post['id']); + if (DB::Aowow()->query('REPLACE INTO ?_account_weightscales VALUES (?d, ?d, ?, ?)', intVal($_POST['id']), User::$id, $_POST['name'], $_POST['scale'])) + die((string)$_POST['id']); else die('0'); } - else if (isset($post['delete']) && isset($post['id'])) - DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE id = ?d AND account = ?d', intVal($post['id']), User::$id); + else if (isset($_POST['delete']) && isset($_POST['id']) && User::$id) + DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE id = ?d AND account = ?d', intVal($_POST['id']), User::$id); else die('0'); diff --git a/pages/items.php b/pages/items.php index 86404ce2..43d75901 100644 --- a/pages/items.php +++ b/pages/items.php @@ -231,21 +231,19 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) { $sharedLvParams['computeDataFunc'] = '$fi_scoreSockets'; - $w = $itemFilter->getForm('setWeights', true); $q = intVal($filter['gm']); $mask = 14; $cnd = [10, ['class', ITEM_CLASS_GEM], ['gemColorMask', &$mask, '&'], ['quality', &$q]]; if (!isset($filter['jc'])) $cnd[] = ['itemLimitCategory', 0]; // Jeweler's Gems - $wData = ['wt' => $w[0], 'wtv' => $w[1]]; - If ($_ = $itemFilter->createConditionsForWeights($wData)) - $cnd[] = $_; + If ($itemFilter->wtCnd) + $cnd[] = $itemFilter->wtCnd; $anyColor = new ItemList($cnd, ['extraOpts' => $itemFilter->extraOpts]); if (!$anyColor->error) { - $anyColor->addGlobalsToJScript($smarty); + $anyColor->addGlobalsToJScript(); $pageData['page']['gemScores'][0] = array_values($anyColor->getListviewData(ITEMINFO_GEM)); } @@ -256,7 +254,7 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $byColor = new ItemList($cnd, ['extraOpts' => $itemFilter->extraOpts]); if (!$byColor->error) { - $byColor->addGlobalsToJScript($smarty); + $byColor->addGlobalsToJScript(); $pageData['page']['gemScores'][$mask] = array_values($byColor->getListviewData(ITEMINFO_GEM)); } } @@ -274,30 +272,31 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) if ($itemFilter->error) $sharedLvParams['_errors'] = '$1'; - if (!empty($filter['upg'])) + if (!empty($filter['upg']) && !empty($filter['fi']['setWeights'])) { - // v poke it to use item_stats - $upgItem = new ItemList(array(['id', $filter['upg']], ['is.id', null, '!']), ['extraOpts' => $itemFilter->extraOpts]); - if (!$upgItem->error) + // v poke it to use item_stats + $upgItems = new ItemList(array(['id', array_keys($filter['upg'])], ['is.id', null, '!']), ['extraOpts' => $itemFilter->extraOpts]); + if (!$upgItems->error) { - $upgItem->addGlobalsToJScript($smarty); - $upgItemData = $upgItem->getListviewData($infoMask)[$filter['upg']]; + $upgItems->addGlobalsToJScript(); + $upgItemData = $upgItems->getListviewData($infoMask); } - - // if (!empty($filter['gb'])) - $sharedLvParams['customFilter'] = '$fi_filterUpgradeListview'; - - $sharedLvParams['_upgradeIds'] = "$[".$filter['upg']."]"; } - /* - * todo (low): this is a long term issue. - * upgradeItems .. Profiler can send them as lists, so multiple lv-tabs would occur - * - */ - /* 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], @@ -306,12 +305,40 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $sourcesGlobalToItem = [1 => 3, 2 => 4, 3 => 5, 4 => 6, 5 => 7, 6 => 8]; $groups = []; $nameSource = []; - $field = ''; + $gbField = ''; + $extraOpts = []; + $singleSlot = true; + $maxResults = CFG_SQL_LIMIT_DEFAULT; + + if ($upgItemData) + { + // check if upItems cover multiple slots + $ref = reset($filter['upg']); + foreach ($filter['upg'] as $slot) + { + if ($slot == $ref) + continue; + + $singleSlot = false; + break; + } + + if ($singleSlot && empty($filter['gb'])) // enforce group by slot + $filter['gb'] = 1; + else if (!$singleSlot) // multiples can only be grouped by slot + { + $filter['gb'] = 1; + $maxResults = 25; + $sharedLvParams['customFilter'] = '$fi_filterUpgradeListview'; + } + } + switch (@$filter['gb']) { // 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: + case 3: // todo(med): source .. well .. no, not at the moment .. the database doesn't event have a field for that, so reroute to slots if (isset($cats[0]) && $cats[0] == ITEM_CLASS_ARMOR) $groups = isset($filter['sl']) ? array_intersect($availableSlots[ITEM_CLASS_ARMOR], (array)$filter['sl']) : $availableSlots[ITEM_CLASS_ARMOR]; else if (isset($cats[0]) && $cats[0] == ITEM_CLASS_WEAPON) @@ -327,13 +354,19 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) { $nameSource = Lang::$item['inventoryType']; $pageData['lv']['isGrouped'] = true; - $field = 'slot'; + $gbField = 'slot'; } break; // itemlevel: first, try to find 10 level steps within range (if given) as tabs case 2: - $levelRef = new ItemList(array_merge($conditions, [10]), ['extraOpts' => ['i' => ['g' => 'itemlevel', 'o' => 'itemlevel DESC']]]); + // ohkayy, maybe i need to rethink this + $filterOpts = $itemFilter->extraOpts; + $filterOpts['is']['o'] = [null]; + $extraOpts = array_merge($filterOpts, ['i' => ['g' => ['itemlevel'], 'o' => ['itemlevel DESC']]]); + + $levelRef = new ItemList(array_merge($conditions, [10]), ['extraOpts' => $extraOpts]); + foreach ($levelRef->iterate() as $_) { $l = $levelRef->getField('itemLevel'); @@ -345,23 +378,22 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) { $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']; $pageData['lv']['isGrouped'] = true; - $field = 'itemlevel'; + $gbField = 'itemlevel'; } break; - // todo(med): source - // .. well .. no, not at the moment .. the databse doesn't event have a field for that - case 3: + case 3: $groups = array_filter(array_keys(Lang::$game['sources'])); + array_walk($groups, function (&$v, $k) { + $v = $v.':'; + }); - if ($groups) - { - $nameSource = Lang::$game['sources']; - $pageData['lv']['isGrouped'] = true; - $field = 'source'; - } + $nameSource = Lang::$game['sources']; + $pageData['lv']['isGrouped'] = true; + $gbField = 'source'; break; // none @@ -371,59 +403,74 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) foreach ($groups as $group) { - $finalCnd = $field ? array_merge($conditions, [[$field, abs($group), $group > 0 ? null : '<'], 25]) : $conditions; + $finalCnd = $gbField ? array_merge($conditions, [[$gbField, abs($group), $group > 0 ? null : '<'], $maxResults]) : $conditions; - $items = new ItemList($finalCnd, ['extraOpts' => $itemFilter->extraOpts]); - $items->addGlobalsToJscript($smarty); + $items = new ItemList($finalCnd, ['extraOpts' => array_merge($extraOpts, $itemFilter->extraOpts)]); + $items->addGlobalsToJscript(); if ($items->error) continue; - $data = $items->getListviewData($infoMask); - - if ($upgItemData) - $data[$filter['upg']] = $upgItemData; - $tab = array( - 'data' => $data, + 'data' => $items->getListviewData($infoMask), 'params' => $sharedLvParams ); - if ($field) + $upg = []; + if ($upgItemData) { - $tab['params']['id'] = $group > 0 ? $field.'-'.$group : 'other'; + if ($gbField == 'slot') // match upgradeItem to slot + { + $upg = array_keys(array_filter($filter['upg'], function ($v) use ($group) { + return $v == $group; + })); + + foreach ($upg as $uId) + $tab['data'][$uId] = $upgItemData[$uId]; + + if ($upg) + $tab['params']['_upgradeIds'] = '$'.json_encode($upg, JSON_NUMERIC_CHECK); + } + else if ($gbField) + { + $upg = array_keys($filter['upg']); + $tab['params']['_upgradeIds'] = '$'.json_encode($upg, JSON_NUMERIC_CHECK); + foreach ($upgItemData as $uId => $data) // using numeric keys => cant use array_merge + $tab['data'][$uId] = $data; + } + } + + if ($gbField) + { + $tab['params']['id'] = $group > 0 ? $gbField.'-'.$group : 'other'; $tab['params']['name'] = $nameSource[$group]; $tab['params']['tabs'] = '$tabsGroups'; } if (!empty($filter['fi']['setWeights'])) - { if ($items->hasSetFields(['armor'])) $visibleCols[] = 'armor'; - } // create note if search limit was exceeded; overwriting 'note' is intentional - if ($items->getMatches() > CFG_SQL_LIMIT_DEFAULT && empty($filter['upg']) && !$field) - { - $tab['params']['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_itemsfound', $items->getMatches(), CFG_SQL_LIMIT_DEFAULT); - $tab['params']['_truncated'] = 1; - } - else if ($field && $items->getMatches() > 25) + if ($items->getMatches() > $maxResults && count($groups) > 1) { $tab['params']['_truncated'] = 1; $addCr = []; - if ($field == 'slot') + if ($gbField == 'slot') { $note = 'lvnote_viewmoreslot'; $override = ['sl' => $group, 'gb' => '']; } - else if ($field == 'itemlevel') + else if ($gbField == 'itemlevel') { $note = 'lvnote_viewmorelevel'; - $override = ['minle' => $group, 'maxle' => $group, 'gb' => '']; + if ($group > 0) + $override = ['minle' => $group, 'maxle' => $group, 'gb' => '']; + else + $override = ['maxle' => abs($group) - 1, 'gb' => '']; } - else if ($field == 'source') + else if ($gbField == 'source') { if ($_ = @$sourcesGlobalToItem[$group]) { @@ -434,12 +481,20 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $override = ['gb' => '']; } + if ($upg) + $override['upg'] = implode(':', $upg); + $cls = isset($cats[0]) ? '='.$cats[0] : ''; $filterUrl = $itemFilter->urlize($override, $addCr); if ($note) $tab['params']['note'] = '$$WH.sprintf(LANG.'.$note.', \''.$cls.'\', \''.$filterUrl.'\')'; } + else if ($items->getMatches() > $maxResults) + { + $tab['params']['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_itemsfound', $items->getMatches(), CFG_SQL_LIMIT_DEFAULT); + $tab['params']['_truncated'] = 1; + } if ($hiddenCols) $tab['params']['hiddenCols'] = '$'.json_encode($hiddenCols); @@ -447,12 +502,15 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) if ($visibleCols) $tab['params']['visibleCols'] = '$'.json_encode($visibleCols); - if ($field) + if ($gbField) $tab['params']['hideCount'] = '$1'; $pageData['lv']['tabs'][] = $tab; } + if (isset($filter['upg'])) + $filter['upg'] = implode(':', array_keys($filter['upg'])); + // whoops, we have no data? create emergency content if (!$pageData['lv']['tabs']) { diff --git a/static/css/global.css b/static/css/global.css index d5b0de7a..dc328fcb 100644 --- a/static/css/global.css +++ b/static/css/global.css @@ -1880,6 +1880,7 @@ Variations: .listview-note { line-height: 16px; + clear: left; } .listview table diff --git a/template/items.tpl b/template/items.tpl index 85b65245..0b8017d8 100644 --- a/template/items.tpl +++ b/template/items.tpl @@ -109,7 +109,7 @@