diff --git a/config/config.php.in b/config/config.php.in
index c6c5db49..a17368e3 100644
--- a/config/config.php.in
+++ b/config/config.php.in
@@ -47,8 +47,10 @@ $AoWoWconf['characters'][0] = array(
// $AoWoWconf['characters'][1] = array();
// -- Site Configuration --
-$AoWoWconf['page']['name'] = 'Aowow Database Viewer (ADV)'; // Title of the website
$AoWoWconf['page']['cacheTimer'] = 60*60*24*7; // Time to keep cache in seconds (Default: 1 week)
+$AoWoWconf['page']['name'] = 'Aowow Database Viewer (ADV)'; // Title of the website
+$AoWoWconf['page']['shortName'] = 'Aowow'; // used in Feeds
+$AoWoWconf['ttl'] = 60; // time to live for RSS
$AoWowConf['cookieTimeout'] = 5*60*1000; // cookie times out in time() + X
$AoWoWconf['register'] = true; // Allow account creating
// $AoWoWconf['loginFailCount'] = 5; // how often invalid passwords are tollerated
diff --git a/includes/class.achievement.php b/includes/class.achievement.php
index dac90240..c10a1a4b 100644
--- a/includes/class.achievement.php
+++ b/includes/class.achievement.php
@@ -14,7 +14,7 @@ class AchievementList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_achievement WHERE [filter] [cond] GROUP BY Id ORDER BY `orderInGroup` ASC';
- public function __construct($conditions, $applyFilter = false)
+ public function __construct($conditions = [], $applyFilter = false)
{
parent::__construct($conditions, $applyFilter);
diff --git a/includes/class.charclass.php b/includes/class.charclass.php
index a9cc8f2f..921a3c77 100644
--- a/includes/class.charclass.php
+++ b/includes/class.charclass.php
@@ -9,6 +9,15 @@ class CharClassList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_classes WHERE [cond] ORDER BY Id ASC';
+ public function __construct($conditions = [])
+ {
+ parent::__construct($conditions);
+
+ foreach ($this->iterate() as $k => &$_curTpl)
+ if ($k == 6) // todo (low): grr, move to db
+ $_curTpl['hero'] = 1;
+ }
+
public function getListviewData()
{
$data = [];
@@ -25,9 +34,6 @@ class CharClassList extends BaseType
'power' => $this->curTpl['powerType'],
);
- if ($this->curTpl['expansion'] == 2) // todo (low): grr, move to db
- $data[$this->id]['hero'] = 1;
-
if ($this->curTpl['expansion'])
$data[$this->id]['expansion'] = $this->curTpl['expansion'];
}
diff --git a/includes/class.item.php b/includes/class.item.php
index 7a719418..798fc938 100644
--- a/includes/class.item.php
+++ b/includes/class.item.php
@@ -21,7 +21,7 @@ class ItemList extends BaseType
protected $setupQuery = 'SELECT *, i.entry AS ARRAY_KEY FROM item_template i LEFT JOIN ?_item_template_addon iX ON i.entry = iX.id LEFT JOIN locales_item l ON i.entry = l.entry WHERE [filter] [cond] ORDER BY i.Quality DESC';
- public function __construct($conditions, $miscData = null)
+ public function __construct($conditions = [], $miscData = null)
{
// search by statweight
if ($miscData && isset($miscData['wt']) && isset($miscData['wtv']) && count($miscData['wt']) == count($miscData['wtv']))
@@ -281,7 +281,7 @@ class ItemList extends BaseType
// conjured
if ($this->curTpl['Flags'] & ITEM_FLAG_CONJURED)
- $x .= ' '.Lang::$game['conjured'];
+ $x .= ' '.Lang::$item['conjured'];
// bonding
if (($this->curTpl['Flags'] & ITEM_FLAG_ACCOUNTBOUND) && $this->curTpl['Quality'] == ITEM_QUALITY_HEIRLOOM)
diff --git a/includes/class.itemset.php b/includes/class.itemset.php
index c2c160c0..b772627a 100644
--- a/includes/class.itemset.php
+++ b/includes/class.itemset.php
@@ -14,9 +14,9 @@ class ItemsetList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_itemset WHERE [filter] [cond] ORDER BY maxlevel DESC';
- public function __construct($data, $applyFilter = false)
+ public function __construct($conditions = [], $applyFilter = false)
{
- parent::__construct($data, $applyFilter);
+ parent::__construct($conditions, $applyFilter);
// post processing
foreach ($this->iterate() as &$_curTpl)
diff --git a/includes/class.quest.php b/includes/class.quest.php
index 99e14c6d..9e67657a 100644
--- a/includes/class.quest.php
+++ b/includes/class.quest.php
@@ -9,7 +9,7 @@ class QuestList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM quest_template qt LEFT JOIN locales_quest lq ON qt.Id = lq.entry WHERE [filter] [cond] ORDER BY Id ASC';
- public function __construct($conditions)
+ public function __construct($conditions = [])
{
parent::__construct($conditions);
diff --git a/includes/class.skill.php b/includes/class.skill.php
index 16bdd54a..1b302cc2 100644
--- a/includes/class.skill.php
+++ b/includes/class.skill.php
@@ -10,9 +10,9 @@ class SkillList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_skillLine sl WHERE [cond] ORDER BY id ASC';
- public function __construct($data)
+ public function __construct($conditions = [])
{
- parent::__construct($data);
+ parent::__construct($conditions);
// post processing
foreach ($this->iterate() as &$_curTpl)
diff --git a/includes/class.spell.php b/includes/class.spell.php
index 1836e952..b6fa3541 100644
--- a/includes/class.spell.php
+++ b/includes/class.spell.php
@@ -36,7 +36,7 @@ class SpellList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_spell s WHERE [filter] [cond]';
- public function __construct($conditions, $applyFilter = false)
+ public function __construct($conditions = [], $applyFilter = false)
{
parent::__construct($conditions, $applyFilter);
@@ -1023,6 +1023,9 @@ class SpellList extends BaseType
$eq(a, b) - a == b
$floor(a) - floor()
$gt(a, b) - a > b
+ $gte(a, b) - a >= b
+ $min(a, b) - min()
+ $max(a, b) - max()
*/
$this->interactive = $interactive;
diff --git a/includes/class.title.php b/includes/class.title.php
index 4a141b3b..cdcf0bba 100644
--- a/includes/class.title.php
+++ b/includes/class.title.php
@@ -13,9 +13,9 @@ class TitleList extends BaseType
protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM ?_titles WHERE [cond] ORDER BY Id ASC';
- public function __construct($data)
+ public function __construct($conditions = [])
{
- parent::__construct($data);
+ parent::__construct($conditions);
// post processing
foreach ($this->iterate() as $__)
diff --git a/includes/class.worldevent.php b/includes/class.worldevent.php
index 6974427c..d2aa9b48 100644
--- a/includes/class.worldevent.php
+++ b/includes/class.worldevent.php
@@ -9,9 +9,9 @@ class WorldEventList extends BaseType
protected $setupQuery = 'SELECT *, -e.id AS ARRAY_KEY, -e.id as id FROM ?_events e LEFT JOIN ?_holidays h ON e.holidayId = h.id WHERE [cond] ORDER BY -e.id ASC';
- public function __construct($data)
+ public function __construct($conditions = [])
{
- parent::__construct($data);
+ parent::__construct($conditions);
// unseting elements while we iterate over the array will cause the pointer to reset
$replace = [];
diff --git a/includes/utilities.php b/includes/utilities.php
index 7fe5a542..03ab4cfe 100644
--- a/includes/utilities.php
+++ b/includes/utilities.php
@@ -55,7 +55,7 @@ abstract class BaseType
$limit = ' LIMIT '.$AoWoWconf['sqlLimit'];
$className = get_class($this);
- if (!$this->setupQuery)
+ if (!$this->setupQuery || $conditions === null)
return;
// may be called without filtering
@@ -213,6 +213,15 @@ abstract class BaseType
return is_numeric($value) ? floatVal($value) : $value;
}
+ public function getRandomId()
+ {
+ $pattern = '/SELECT .* (-?[\w_]*\.?(id|entry)) AS ARRAY_KEY,?.* FROM (.*) WHERE .*/i';
+ $replace = 'SELECT $1 FROM $3 ORDER BY RAND() ASC LIMIT 1';
+ $query = preg_replace($pattern, $replace, $this->setupQuery);
+
+ return DB::Aowow()->selectCell($query);
+ }
+
public function getFoundIDs()
{
return array_keys($this->templates);
@@ -441,10 +450,10 @@ class Lang
$tmp = [];
if ($flags & CUSTOM_DISABLED)
- $tmp[] = ''.self::$main['disabled'].'';
+ $tmp[] = ''.self::$main['disabled'].'';
if ($flags & CUSTOM_SERVERSIDE)
- $tmp[] = ''.self::$main['serverside'].'';
+ $tmp[] = ''.self::$main['serverside'].'';
return $tmp;
}
@@ -679,28 +688,40 @@ class SmartyAoWoW extends Smarty
public function display($tpl)
{
$tv = &$this->_tpl_vars;
- $_ = [];
+ // fetch article & static infobox
if ($tv['page']['type'] && $tv['page']['typeId'])
{
- if ($article = DB::Aowow()->selectRow('SELECT id, article, quickInfo FROM ?_articles WHERE type = ?d AND typeId = ?d AND locale = ?d', $tv['page']['type'], $tv['page']['typeId'], User::$localeId))
+ $article = DB::Aowow()->selectRow(
+ 'SELECT SQL_CALC_FOUND_ROWS article, quickInfo, locale FROM ?_articles WHERE type = ?d AND typeId = ?d AND locale = ?d UNION ALL '.
+ 'SELECT article, quickInfo, locale FROM ?_articles WHERE type = ?d AND typeId = ?d AND locale = 0 AND FOUND_ROWS() = 0',
+ $tv['page']['type'], $tv['page']['typeId'], User::$localeId,
+ $tv['page']['type'], $tv['page']['typeId']
+ );
+
+ if ($article)
{
- $globals = DB::Aowow()->select('SELECT type, typeId FROM ?_article_items WHERE id = ?d', $article['id']);
+ $tv['article'] = ['text' => $article['article']];
+ if (empty($tv['infobox']) && !empty($article['quickInfo']))
+ $tv['infobox'] = $article['quickInfo'];
- $tv['article'] = $article['article'];
- @$tv['infoBox'] .= $article['quickInfo'];
+ if ($article['locale'] != User::$localeId)
+ $tv['article']['params'] = ['prepend' => Util::jsEscape('
{/if}
diff --git a/pages/miscTools.php b/pages/miscTools.php
new file mode 100644
index 00000000..aee65089
--- /dev/null
+++ b/pages/miscTools.php
@@ -0,0 +1,165 @@
+getRandomId(); break;
+ case TYPE_OBJECT: $id = (new GameobjectList(null))->getRandomId(); break;
+ case TYPE_ITEM: $id = (new ItemList(null))->getRandomId(); break;
+ case TYPE_ITEMSET: $id = (new ItemsetList(null))->getRandomId(); break;
+ case TYPE_QUEST: $id = (new QuestList(null))->getRandomId(); break;
+ case TYPE_SPELL: $id = (new SpellList(null))->getRandomId(); break;
+ case TYPE_ZONE: $id = (new ZoneList(null))->getRandomId(); break;
+ case TYPE_FACTION: $id = (new FactionList(null))->getRandomId(); break;
+ case TYPE_PET: $id = (new PetList(null))->getRandomId(); break;
+ case TYPE_ACHIEVEMENT: $id = (new AchievementList(null))->getRandomId(); break;
+ case TYPE_TITLE: $id = (new TitleList(null))->getRandomId(); break;
+ case TYPE_WORLDEVENT: $id = (new WorldEventList(null))->getRandomId(); break;
+ case TYPE_CLASS: $id = (new CharClassList(null))->getRandomId(); break;
+ case TYPE_RACE: $id = (new CharRaceList(null))->getRandomId(); break;
+ case TYPE_SKILL: $id = (new SkillList(null))->getRandomId(); break;
+ case TYPE_CURRENCY: $id = (new CurrencyList(null))->getRandomId(); break;
+ }
+
+ header('Location: ?'.$page.'='.$id);
+ die();
+ case 'latest-comments':
+ $menu = 2;
+ $lv = array(
+ array(
+ 'file' => 'commentpreview',
+ 'data' => [],
+ 'params' => []
+ )
+ );
+ break;
+ case 'latest-screenshots':
+ $menu = 3;
+ $lv = array(
+ array(
+ 'file' => 'screenshot',
+ 'data' => [],
+ 'params' => []
+ )
+ );
+ break;
+ case 'latest-videos':
+ $menu = 11;
+ $lv = array(
+ array(
+ 'file' => 'video',
+ 'data' => [],
+ 'params' => []
+ )
+ );
+ break;
+ case 'latest-articles':
+ $menu = 1;
+ $lv = [];
+ break;
+ case 'latest-additions':
+ $menu = 0;
+ $lv = [];
+ break;
+ case 'unrated-comments':
+ $menu = 5;
+ $lv = [];
+ break;
+ case 'missing-screenshots':
+ $menu = 13;
+ $lv = [];
+ break;
+ case 'most-comments':
+ if ($pageParam && !in_array($pageParam, [1, 7, 30]))
+ header('Location: ?most-comments=1'.($_rss ? '&rss' : null));
+
+ if (in_array($pageParam, [7, 30]))
+ {
+ $subMenu = $pageParam;
+ $_title = sprintf(Lang::$main['mostComments'][1], $pageParam);
+ }
+ else
+ {
+ $subMenu = 1;
+ $_title = Lang::$main['mostComments'][0];
+ }
+
+ $menu = 12;
+ $lv = [];
+ break;
+ default:
+ $smarty->notFound();
+}
+
+if (strstr($pageCall, 'latest') || $pageCall == 'most-comments')
+{
+ if ($_rss)
+ {
+ header("Content-Type: application/rss+xml; charset=ISO-8859-1");
+
+ $xml = "\n".
+ "\n\t\n".
+ "\t\t".$AoWoWconf['page']['shortName'].' - '.Lang::$main['utilities'][$menu] . ($_title ? Lang::$colon . $_title : null)."\n".
+ "\t\t".STATIC_URL.'?'.$pageCall . ($pageParam ? '='.$pageParam : null)."\n".
+ "\t\t".$AoWoWconf['page']['name']."\n".
+ "\t\t".implode('-', str_split(User::$localeString, 2))."\n".
+ "\t\t".$AoWoWconf['ttl']."\n".
+ // Sat, 31 Aug 2013 15:33:16 -0500
+ "\t\n";
+
+ /*
+ generate 's here
+ */
+
+ $xml .= '';
+
+ die($xml);
+ }
+ else
+ $h1Links = ''.Lang::$main['subscribe'].'';
+}
+
+$pageData = array(
+ 'listviews' => $lv,
+ 'page' => array(
+ 'name' => Lang::$main['utilities'][$menu] . ($_title ? Lang::$colon . $_title : null),
+ 'h1Links' => $h1Links,
+ )
+);
+
+array_push($_path, $menu);
+if ($subMenu)
+ array_push($_path, $subMenu);
+
+
+// menuId 8: Utilities g_initPath()
+// tabId 1: Tools g_initHeader()
+$smarty->updatePageVars(array(
+ 'title' => Lang::$main['utilities'][$menu] . ($_title ? ' - ' . $_title : null),
+ 'path' => json_encode($_path, JSON_NUMERIC_CHECK),
+ 'tab' => 1
+));
+$smarty->assign('lang', Lang::$main);
+$smarty->assign('lvData', $pageData);
+
+// load the page
+$smarty->display('generic-no-filter.tpl');
+
+?>
diff --git a/pages/pets.php b/pages/pets.php
index db484689..b5b7feee 100644
--- a/pages/pets.php
+++ b/pages/pets.php
@@ -23,6 +23,10 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$pets = new PetList(isset($cat) ? array(['type', (int)$cat]) : []);
$pageData = array(
+ 'listviews' => []
+ );
+
+ $lvPet = array(
'file' => 'pet',
'data' => $pets->getListviewData(),
'params' => array(
@@ -31,7 +35,9 @@ if (!$smarty->loadCache($cacheKey, $pageData))
);
if (($mask = $pets->hasDiffFields(['type'])) == 0x0)
- $pageData['params']['hiddenCols'] = "$['type']";
+ $lvPet['params']['hiddenCols'] = "$['type']";
+
+ $pageData['listviews'][] = $lvPet;
$pets->addGlobalsToJscript($smarty, GLOBALINFO_RELATED);
diff --git a/pages/races.php b/pages/races.php
index 3c79bc7f..2e9746f7 100644
--- a/pages/races.php
+++ b/pages/races.php
@@ -11,9 +11,13 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$races = new CharRaceList(array(['side', 0, '!'])); // only playable
$pageData = array(
- 'file' => 'race',
- 'data' => $races->getListviewData(),
- 'params' => []
+ 'listviews' => array(
+ array(
+ 'file' => 'race',
+ 'data' => $races->getListviewData(),
+ 'params' => []
+ )
+ )
);
$smarty->saveCache($cacheKey, $pageData);
diff --git a/pages/skills.php b/pages/skills.php
index 120a6271..7a8bc10c 100644
--- a/pages/skills.php
+++ b/pages/skills.php
@@ -26,9 +26,13 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$skills = new SkillList($conditions);
$pageData = array(
- 'file' => 'skill',
- 'data' => $skills->getListviewData(),
- 'params' => []
+ 'listviews' => array(
+ array(
+ 'file' => 'skill',
+ 'data' => $skills->getListviewData(),
+ 'params' => []
+ )
+ )
);
$smarty->saveCache($cacheKey, $pageData);
diff --git a/pages/titles.php b/pages/titles.php
index 59b0415d..9fbd09aa 100644
--- a/pages/titles.php
+++ b/pages/titles.php
@@ -23,16 +23,22 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$titles = new TitleList(isset($cat) ? array(['category', (int)$cat]) : []);
$pageData = array(
+ 'listviews' => []
+ );
+
+ $lvTitles = array(
'file' => 'title',
'data' => $titles->getListviewData(),
'params' => []
);
if ($titles->hasDiffFields(['category']))
- $pageData['params']['visibleCols'] = "$['category']";
+ $lvTitles['params']['visibleCols'] = "$['category']";
if (!$titles->hasAnySource())
- $pageData['params']['hiddenCols'] = "$['source']";
+ $lvTitles['params']['hiddenCols'] = "$['source']";
+
+ $pageData['listviews'][] = $lvTitles;
$smarty->saveCache($cacheKey, $pageData);
}
diff --git a/pages/zones.php b/pages/zones.php
index 460b232e..ac743ba4 100644
--- a/pages/zones.php
+++ b/pages/zones.php
@@ -58,11 +58,15 @@ if (!$smarty->loadCache($cacheKey, $pageData))
$zones = new ZoneList($conditions);
$pageData = array(
- 'file' => 'zone',
- 'data' => $zones->getListviewData(),
- 'som' => '',
- 'map' => [],
- 'params' => []
+ 'som' => '',
+ 'map' => [],
+ 'listviews' => array(
+ array(
+ 'file' => 'zone',
+ 'data' => $zones->getListviewData(),
+ 'params' => []
+ )
+ )
);
if ($mapFile)
diff --git a/setup/aowow_articles_u1.sql b/setup/aowow_articles_u1.sql
new file mode 100644
index 00000000..b3aa02b4
--- /dev/null
+++ b/setup/aowow_articles_u1.sql
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS `aowow_article_items`;
+REPLACE INTO `aowow_articles` VALUES
+ (1300001,13,1,0,'[b][color=c1]Warriors[/color][/b] are a very powerful class, with the ability to tank or deal significant melee damage. The warrior\'s Protection tree contains many talents to improve their survivability and generate threat versus monsters. Protection warriors are one of the main tanking classes of the game.\\n\\nThey also have two damage-oriented talent trees - [icon name=ability_rogue_eviscerate][url=spells=7.1.26]Arms[/url][/icon] and [icon name=ability_warrior_innerrage][url=spells=7.1.256]Fury[/url][/icon], the latter of which includes the talent [spell=46917], which allows the warrior to wield two two-handed weapons at the same time! They are capable of strong melee AoE damage with spells such as [spell=845], [spell=1680], [spell=46924]. A warrior fights while in a specific [i]stance[/i], which grants him bonuses and access to different sets of abilities. He will use [spell=71] for tanking, and [spell=2457] or [spell=2458] for melee DPS.\\n\\n[ul]\\n[li]All warriors can buff their raid or group by using a [i]shout[/i], [spell=6673] or [spell=469], and Fury warriors can provide the passive buff [spell=29801] which significantly increases the melee and ranged critical strike chance of his allies.[/li]\\n[li]Warriors start out with only [spell=2457] at first, but learn [spell=71] at level 10 and [spell=2458] at level 30.[/li]\\n[li]Warriors have numerous useful methods of getting to their target in a hurry! All warriors can use [spell=100] or [spell=20252] to reach an enemy and Protection warriors have [spell=3411], which allows them to intercept a friendly target and protect them from an attack.[/li]\\n[/ul]',NULL),
+ (1300002,13,2,0,'[b][color=c2]Paladins[/color][/b] bolster their allies with holy auras and blessing to protect their friends from harm and enhance their powers. Wearing heavy armor, they can withstand terrible blows in the thickest battles while healing their wounded allies and resurrecting the slain. In combat, they can wield massive two-handed weapons, stun their foes, destroy undead and demons, and judge their enemies with holy vengeance. Paladins are a defensive class, primarily designed to outlast their opponents.\\n\\nThe paladin is a mix of a melee fighter and a secondary spell caster. The paladin has a great deal of group utility due to the paladin\'s healing, blessings, and other abilities. Paladins can have one active aura per paladin on each party member and use specific blessings for specific players. Paladins are pretty hard to kill, thanks to their assortment of defensive abilities. They also make excellent tanks using their [spell=25780] ability.\\n\\n[ul]\\n[li]Can effectively heal, tank, and deal damage in melee.[/li]\\n[li]Has a wide selection of [url=spells=7.2&filter=na=blessing]Blessings[/url], [url=spells=7.2&filter=na=aura]Auras[/url], and other buffs.[/li]\\n[li]Is the only class with access to a true invulnerability spell: [spell=642][/li]\\n[/ul]',NULL),
+ (1300003,13,3,0,'[b][color=c3]Hunters[/color][/b] are a very unique class in World of Warcraft. They are the sole non-magical ranged damage-dealers, fighting with bows and guns. Hunters have a number of different kinds of shots and stings, which can be used to debuff an enemy, and are capable of laying traps to deal damage or otherwise slow/incapacitate their enemy.\\n\\nA hunter will also tame his very own [url=pets]pet[/url] to aid them in combat. While they are not the only class which can use pet minions, the hunter\'s pet is unique in that each species has a particular type of talent tree, which the hunter can use to distribute points into various skills and passive abilities.\\n\\nIn addition, each species has a unique special ability. Hunters can seek out the most desirable pets based on their appearances or abilities, and if they spec deep enough into the [icon name=ability_hunter_beasttaming][url=spells=7.3.50]Beast Mastery[/url][/icon] tree they gain access to special, \\\"exotic\\\" beasts such as [pet=46] or [pet=39]!\\n\\n[ul]\\n[li]Hunters have access to 23 (32 if [icon name=ability_hunter_beasttaming][url=spells=7.3.50]Beast Mastery[/url][/icon]) different [url=pets]species of pets[/url], featuring over 150 different appearances![/li]\\n[li]Hunters have a number of survival-oriented skills which they can use to escape or avoid potential danger, such as [spell=5384] and [spell=781].[/li]\\n[li][icon name=ability_hunter_swiftstrike][url=spells=7.3.51]Survival[/url][/icon] hunters can spec down the tree into [spell=53292], which allows them to provide the [spell=57669] buff to their party and raid members.[/li]\\n[/ul]',NULL),
+ (1300004,13,4,0,'[b][color=c4]Rogues[/color][/b] are a leather-clad melee class capable of dealing large amounts of damage to their enemies with very fast attacks. They are masters of stealth and assassination, passing by enemies unseen and striking from the shadows, then escaping from combat in the blink of an eye.\\n\\nThey are capable of using poisons to cripple their opponents, massively weakening them in battle. Rogues have a powerful arsenal of skills, many of which are strengthened by their ability to stealth and to incapacitate their victims.\\n[ul]\\n[li]Rogues can use a wide variety of melee weapons, such as daggers, fist weapons, one-handed maces, one-handed swords and one-handed axes.[/li]\\n[li]By coating their weapons with [url=items=0.-3&filter=na=poison;ub=4]poison[/url] rogues can severely cripple or weaken their enemies.[/li]\\n[li]When using [spell=1784] rogues will be unseen except by the most perceptive enemies.[/li]\\n[/ul]','[ul][li]Resource: [span]Energy[/span][/li][li]Role: Melee DPS[/li][li]Specs: [ul][li][icon name=Ability_Rogue_Eviscerate][url=spells=7.4.253]Assassination[/url][/icon][/li][li][icon name=Ability_BackStab][url=spells=7.4.38]Combat[/url][/icon][/li][li][icon name=Ability_Stealth][url=spells=7.4.39]Subtlety[/url][/icon][/li][/ul][/li][/ul]'),
+ (1300005,13,5,0,'[b][color=c5]Priests[/color][/b] are commonly considered one of the standard healing classes in World of Warcraft, as they have two talent specs that can be used to heal quite effectively.\\n\\nTheir [icon name=spell_holy_holybolt][url=spells=7.5.56]Holy[/url][/icon] tree includes talents which strongly boost the healing done to their allies, including spells that can be used to heal multiple players at once, such as [spell=48089]. The [icon name=spell_holy_wordfortitude][url=spells=7.5.613]Discipline[/url][/icon] tree, while still capable of significant raw healing output, focuses primarily on damage absorption and mitigation through use of [spell=48066] and procced shielding effects. Priests are also capable of very powerful ranged damage with their unique [icon name=spell_shadow_shadowwordpain][url=spells=7.5.78]Shadow[/url][/icon] abilities, and upon entering [spell=15473] will see a significant increase in their shadow damage while losing the ability to cast any Holy spells.\\n\\n[ul]\\n[li]While the [icon name=spell_holy_wordfortitude][url=spells=7.5.613]Discipline[/url][/icon] talent tree is commonly used for healing, it also contains some powerful talents that can boost the priest\'s Holy damage, though [icon name=spell_shadow_shadowwordpain][url=spells=7.5.78]Shadow[/url][/icon] spells and abilities should be used primarily for DPS.[/li]\\n[li]Priests provide of the most appreciated buffs in the game - [spell=48161], which grants an indispensable stamina buff to everyone in the raid. They can also buff both [spell=48073] and [spell=48169]![/li]\\n[li]Shadow priests are an excellent utility class for any raid, providing the much-loved [spell=57669] buff to boost mana regeneration and can even heal their own party with [spell=15286]![/li]\\n[/ul]',NULL),
+ (1300006,13,6,0,'Introduced in the Wrath of the Lich King expansion, [b][color=c6]Death Knights[/color][/b] are World of Warcraft\'s first hero class. Death knights start at level 55 in a special, instanced zone unreachable by any other class: Acherus, the Ebon Hold, located in [zone=4298]. Here they will earn their talent points as quest rewards and even get a special summoned mount, the [spell=48778]!\\n\\nDeath knights have multiple very strong damage dealing options, as each of their talent trees can be specced to perform exceptionally well with a variety of melee abilities, spells and damage-over-time dealing diseases. They are also very capable tank classes, with both their Blood and Frost trees providing unique options - [icon name=spell_deathknight_bloodboil][url=spells=7.6.770]Blood[/url][/icon] dealing more with self-healing abilities and [icon name=spell_frost_frostnova][url=spells=7.6.771]Frost[/url][/icon] providing significant damage mitigation and strong AoE damage.\\n\\nDeath knights fight with a special buff active called a [i]presence[/i] (similar to a warrior\'s stances) which provides special bonuses to their roles. Death knights utilize a unique power system, with most spells costing either Runes, which are replenished throughout battle, or Runic Power, which can be generated by various abilities.\\n\\n[ul]\\n[li][icon name=spell_deathknight_armyofthedead][url=spells=7.6.772]Unholy[/url][/icon] death knights can spec into [spell=52143], which makes their summoned Ghoul minion a permanent pet to aid in battle![/li]\\n[li]The death knight class has its own special weapon enchanting ability called [spell=53428], which replaces the need for conventional weapon enchants.[/li]\\n[li]Death knights are a very unique damage-dealing class in that their damage is dealt by both melee abilities [i]and[/i] spells![/li]\\n[/ul]',NULL),
+ (1300007,13,7,0,'[b][color=c7]Shamans[/color][/b] master elemental and nature magics and bring the most potential buffs to any group in the form of totems. A shaman can summon one totem of each element - earth, fire, air, and water - which appears at the shaman\'s feet and provides a buff to anyone in the shaman\'s party or raid within range of it. Some shaman totems, notably the fire ones, also do damage to opponents. The trick to playing any type of shaman is knowing which totems to cast under which circumstances to maximize the group\'s damage output and survivability.\\n\\nShamans are primarily spellcasters, although an [icon name=spell_nature_lightningshield][url=spells=7.7.373]Enhancement[/url][/icon] shaman likes to get close and personal and do damage within melee range. An enhancement shaman learns to [spell=30798] weapons and can use [spell=51533] to summon a pair of Spirit Wolves to aid in battle. Despite being primarily melee, [icon name=spell_nature_lightningshield][url=spells=7.7.373]Enhancement[/url][/icon] shamans can still gain some benefit from spellpower and can cast instant [spell=403] or heals with [spell=51530]. \\n\\n[icon name=spell_nature_lightning][url=spells=7.7.375]Elemental[/url][/icon] shamans stand back and cast fire and lightning spells to deal great amounts of damage. They can push back enemies with [spell=51490] and root all enemies in an area with[spell=51486]. They also bring [icon name=spell_fire_totemofwrath][url=spell=57722]Totem of Wrath[/url][/icon] and [spell=51470] as amazing spellcaster raid buffs. A shaman that choses [icon name=spell_nature_magicimmunity][url=spells=7.7.374]Restoration[/url][/icon] gains improved healing spells and can be a great raid or tank healer. Resto shamans are known for their powerful [spell=1064] ability and for providing a [spell=16190] to help their party\'s mana restoration. They also gain a powerful [spell=974], can use [spell=51886] to remove curses, and have an instant-cast direct heal plus heal over time effect called [spell=61295].\\n\\n[ul]\\n[li]There are over twenty different totems a shaman can learn![/li]\\n[li]Shamans can cast [spell=2825] (or [spell=32182]) to boost the entire group\'s damage and healing. This buff is unique and oft sought after for a raid group.[/li]\\n[li]A shaman can turn into a [spell=2645] at level 16 and can even make it instant cast with [spell=16287]. This spell can be used in combat, but not indoors.[/li]\\n[li]Shamans can only have one elemental shield - [spell=324] or [spell=52127] - on at a time. [spell=974], if the shaman knows it, can be cast on another player.[/li]\\n[/ul]',NULL),
+ (1300008,13,8,0,'[b][color=c8]Mages[/color][/b] wield the elements of fire, frost, and arcane to destroy or neutralize their enemies. They are a robed class that excels at dealing massive damage from afar, casting elemental bolts at a single target, or raining destruction down upon their enemies in a wide area of effect. Mages can also augment their allies\' spell-casting powers, summon food or drink to restore their friends, and even travel across the world in an instant by opening arcane portals to distant lands.\\n\\nWhen seeking someone to introduce monsters to a world of pain, the Mage is a good choice. With their elemental and arcane attacks, it\'s a safe bet something they can do won\'t be resisted by your chosen enemy. Damage is the name of the Mage game, and they do it well. Their arsenal includes some powerful buffs, debuffs, stuns, and snares, enabling them to dictate the terms of any fight.\\n\\n[ul]\\n[li]Can [spell=42956] to restore their allies\' health and mana.[/li]\\n[li]Are the only class that can create portals to transport other players. They cannot, however, summon players [i]from[/i] a distant location - that\'s a [icon name=class_warlock][color=c9]Warlock\'s[/color][/icon] job![/li]\\n[li]Mages who use [item=50045] can have a permanent water elemental pet![/li]\\n[/ul]',NULL),
+ (1300009,13,9,0,'[b][color=c9]Warlocks[/color][/b] are masters of the demonic arts. Clothed in demonic styled cloth, they excel in using curses, firing bolts of fire or shadow, and summoning demons to help them in combat. Warlocks, while being excellent spell casters, also excel in supporting fellow allies by summoning other players or using ritual magics to conjure stones imbued with the power to heal.\\n\\nA warlock has very powerful abilities that, if used correctly, make them a very formidable opponent. Using their curses in combination with direct damage spells, Warlocks wreak havoc and destruction.\\n\\n[ul][li]Can use a [spell=698] to summon another player to the portals location.[/li]\\n[li]Are able to conjure [icon name=inv_stone_04][url=item=5509]Healthstones[/url][/icon] that have the ability to heal the user.[/li]\\n[li]Can use curses on enemies to [url=spell=47865]weaken[/url] them or [url=spell=47864]damage[/url] them.[/li][/ul]',NULL),
+ (1300011,13,11,0,'[b][color=c11]Druids[/color][/b] are World of Warcraft\'s \\\"jack of all trades\\\" class -- that is, capable of performing in a variety of different roles and as such have one of the most varied playstyles. A druid can act as a healer, melee DPS, ranged DPS or a tank, utilizing a variety of [i]shapeshifting[/i] forms. As a druid levels up, he is able to learn new, powerful forms which he can cast to change into different creatures to suit their roles.\\n\\nAt lower levels, a druid will heal or ranged DPS in his caster form, but at later levels players who spec into the specialized trees will gain access to two special shapeshift forms for each different role.\\n\\nHealing druids will learn [spell=33891], which reduces the mana cost of their healing spells and grants a passive healing aura to their allies. Their ranged damage-dealing counterparts will learn [spell=24858], increasing their armor and granting a spell critical aura to their allies. There are also two feral form druid forms -- the mighty [spell=5487] (and at later level, [spell=9634]), a tanking-oriented form which provides additional armor and health and grants access to an arsenal of threat-building and damage mitigation abilities, and the rogue-like [spell=768] which is capable of significant melee DPS.\\n\\n[ul]\\n[li]Druids learn their different forms through questing or training. Some shapeshifts are only learned via talents.[/li]\\n[li]There are some shapeshifts that all druids can learn. [spell=5487] is obtained at level 10, [spell=1066] and [spell=783] at level 16, [spell=768] at level 20 and [spell=9634] at level 40.[/li]\\n[li]Druids even have their own flying travel form! [spell=33943] can be trained at level 60, and [spell=40120] at level 71 provided the player has already trained [spell=34091].[/li]\\n[li]Some druid shapeshifts are obtained via talents only - [spell=24858] can be obtained at level 40 when a player specs deep into the [icon name=spell_nature_starfall][url=spells=7.11.574]Balance[/url][/icon] tree, and [spell=33891] at level 50 after speccing deep into [icon name=spell_nature_healingtouch][url=spells=7.11.573]Restoration[/url][/icon].[/li]\\n[li]Druids have their own, class-specific teleport ability that allows them to travel to and from [zone=493], which is handy when needing to train![/li]\\n[li]Because feral druids do not actually swing weapons while in shapeshift forms, they instead gain a special statistic from any melee weapon they equip called \\\"feral attack power.\\\" This stat is a conversion of a weapon\'s DPS (damage per second) into an attack power-granting statistic which affects the cat or bear\'s damage output.[/li]\\n[/ul]',NULL);
diff --git a/template/achievement.tpl b/template/achievement.tpl
index fdf59c29..458a53e7 100644
--- a/template/achievement.tpl
+++ b/template/achievement.tpl
@@ -16,13 +16,13 @@
g_initPath({$page.path});
//]]>
-{* include file='bricks/infobox.tpl' *}
+{* include file='bricks/infobox.tpl' info=$lvData.infobox *}