Burning Crusade Progress Page Part 2
This entry builds off my previous entry for building a Burning Crusade Progress Page. The first entry covered how to pull the data, this entry will cover the display.
Once the guild import page is created and scheduled to run on some frequency, you can move on to building your display page. The basic idea behind the progress page is that certain levels of reputation with specific factions should give you keys to unlock heroic dungeons and even Karazhan.
Again, we will start out with some variables that can be easily changed to control what is displayed later on.
<cfset guildRealm = "Stonemaul" />
<cfset heroicFactions = "Cenarion Expedition,Honor Hold,Keepers of Time,Lower City,The Sha'tar" />
The heroicFactions variable will be an important part of the code below and with it in a list, it should be easy enough to add to or convert to other languages if needed. There is an additional table needed to accomplish this page. It is a lookup table to provide class names. Here is the schema and data.
CREATE TABLE `wow_roster_classes` ( `classID` tinyint(3) unsigned NOT NULL default '0', `className` varchar(20) NOT NULL default '', KEY `classID` (`classID`) );
INSERT INTO `wow_roster_classes` (`classID`, `className`) VALUES (1, 'Warrior'), (2, 'Paladin'), (3, 'Hunter'), (4, 'Rogue'), (5, 'Priest'), (7, 'Shaman'), (8, 'Mage'), (9, 'Warlock'), (11, 'Druid');
Next up are the two queries that will be used to show the heroic dungeon progress and Karazhan progress. There is also a support function that will be used to format the reputation.
SELECT g.characterID, g.name, g.level, g.url, c.className, rep.faction, rep.reputation
FROM wow_roster_guild g
INNER JOIN wow_roster_classes c
ON g.classID = c.classID
INNER JOIN wow_roster_reputation rep
ON g.characterID = rep.characterID
WHERE g.server = <cfqueryparam cfsqltype="cf_sql_varchar" value="#guildRealm#" />
AND g.guild = <cfqueryparam cfsqltype="cf_sql_varchar" value="#guildName#" />
AND g.active = 1
AND rep.faction IN (<cfqueryparam cfsqltype="cf_sql_varchar" list="yes" separator="," value="#heroicFactions#" />)
AND rep.reputation >= 21000
ORDER BY rep.faction, g.name
</cfquery>
<cfquery name="queryTheVioletEye" datasource="#Datasource#" username="#User#" password="#Password#">
SELECT g.characterID, g.name, g.level, g.url, c.className, rep.faction, rep.reputation
FROM wow_roster_guild g
INNER JOIN wow_roster_classes c
ON g.classID = c.classID
INNER JOIN wow_roster_reputation rep
ON g.characterID = rep.characterID
WHERE g.server = <cfqueryparam cfsqltype="cf_sql_varchar" value="#guildRealm#" />
AND g.guild = <cfqueryparam cfsqltype="cf_sql_varchar" value="#guildName#" />
AND g.active = 1
AND rep.faction = "The Violet Eye"
AND rep.reputation >= 1850
ORDER BY rep.faction, g.name
</cfquery>
<cffunction name="FormatReputation" returntype="string">
<cfargument name="reputation" required="yes" type="numeric" />
<cfif ARGUMENTS.reputation lt 3000>
<cfreturn "Neutral (#ARGUMENTS.reputation#/3000)" />
<cfelseif ARGUMENTS.reputation lt 9000>
<cfreturn "Friendly (#ARGUMENTS.reputation-3000#/6000)" />
<cfelseif ARGUMENTS.reputation lt 21000>
<cfreturn "Honored (#ARGUMENTS.reputation-9000#/6000)" />
<cfelseif ARGUMENTS.reputation lt 33000>
<cfreturn "Revered (#ARGUMENTS.reputation-21000#/12000)" />
<cfelse>
<cfreturn "Exalted (#ARGUMENTS.reputation-33000#/21000)" />
</cfif>
</cffunction>
The key to the heroic query is the faction being one of the factions defined in heroicFactions and having a reputation greater then 21000. When reputation is greater then 21000, the character is Revered with the faction which opens up the option to buy the heroic dungeon key from the faction's quartermaster. This is the best method as the armory data does not list inventory so there is no way to just find out who has the key in their inventory. For the Karazhan query, the focus is on The Violet Eye reputation and the reputation being greater then 1850 which is how much reputation should be gained by time the key fragment quest has been completed. Now that we have our data sets, lets get to the display.
<cfloop index="faction" list="#heroicFactions#" delimiters=",">
<p>
<cfquery dbtype="query" name="queryFactionCharacters">
SELECT *
FROM queryCharacters
WHERE faction = <cfqueryparam cfsqltype="cf_sql_varchar" value="#faction#" />
ORDER BY name
</cfquery>
<strong><cfoutput>#faction# (#queryFactionCharacters.RecordCount#)</cfoutput></strong><br />
<cfoutput query="queryFactionCharacters">
<a href="http://armory.worldofwarcraft.com/character-sheet.xml?#queryFactionCharacters.url#" target="CharacterSheet" title="#queryFactionCharacters.className# #queryFactionCharacters.level# #FormatReputation(queryFactionCharacters.reputation)#">#queryFactionCharacters.name#</a><cfif queryFactionCharacters.RecordCount gt queryFactionCharacters.CurrentRow>, </cfif>
</cfoutput>
</p>
</cfloop>
<h3>Karazhan Keyed (<cfoutput>#queryTheVioletEye.RecordCount#</cfoutput>)</h3>
<p>
<strong>Over 1850 reputation with The Violet Eye</strong><br />
<cfoutput query="queryTheVioletEye">
<a href="http://armory.worldofwarcraft.com/character-sheet.xml?#queryTheVioletEye.url#" target="CharacterSheet" title="#queryTheVioletEye.className# #queryTheVioletEye.level# #FormatReputation(queryTheVioletEye.reputation)#">#queryTheVioletEye.name#</a><cfif queryTheVioletEye.RecordCount gt queryTheVioletEye.CurrentRow>, </cfif>
</cfoutput>
</p>
The heroic keyable characters uses a Query of Queries in the loop to pull a specific faction one by one and display the characters. I used some simple display tags but it could always be spruced up with an ordered list or table. The Karazhan Keyed characters just uses the queryTheVioletEye created earlier for the display. Notice the use of the FormatReputation function for displaying the reputation in a more user friendly format.
With that, you now have a Burning Crusade progress page that can be used to find guild mates to attempt the heroic dungeons and for raid leaders to find out who is keyed and ready to start Karazhan. Have fun.

<cffunction name="formatReputation" returntype="string">
<cfargument name="reputation" required="yes" type="numeric" />
<cfif ARGUMENTS.reputation lt -12000>
<cfreturn "Hated (#abs(ARGUMENTS.reputation+42000)#/36000)" />
<cfelseif ARGUMENTS.reputation lt -3000>
<cfreturn "Hostile (#abs(ARGUMENTS.reputation+6000)#/3000)" />
<cfelseif ARGUMENTS.reputation lt 0>
<cfreturn "Unfriendly (#abs(ARGUMENTS.reputation+3000)#/3000)" />
<cfelseif ARGUMENTS.reputation lt 3000>
<cfreturn "Neutral (#ARGUMENTS.reputation#/3000)" />
<cfelseif ARGUMENTS.reputation lt 9000>
<cfreturn "Friendly (#ARGUMENTS.reputation-3000#/6000)" />
<cfelseif ARGUMENTS.reputation lt 21000>
<cfreturn "Honored (#ARGUMENTS.reputation-9000#/9000)" />
<cfelseif ARGUMENTS.reputation lt 33000>
<cfreturn "Revered (#ARGUMENTS.reputation-21000#/21000)" />
<cfelse>
<cfreturn "Exalted (#ARGUMENTS.reputation-42000#/1000)" />
</cfif>
</cffunction>
<cffunction name="formatReputation" returntype="string">
<cfargument name="reputation" required="yes" type="numeric" />
<cfif ARGUMENTS.reputation lt -6000>
<cfreturn "Hated (#abs(ARGUMENTS.reputation+6000)#/36000)" />
<cfelseif ARGUMENTS.reputation lt -3000>
<cfreturn "Hostile (#abs(ARGUMENTS.reputation+3000)#/3000)" />
<cfelseif ARGUMENTS.reputation lt 0>
<cfreturn "Unfriendly (#abs(ARGUMENTS.reputation)#/3000)" />
<cfelseif ARGUMENTS.reputation lt 3000>
<cfreturn "Neutral (#ARGUMENTS.reputation#/3000)" />
<cfelseif ARGUMENTS.reputation lt 9000>
<cfreturn "Friendly (#ARGUMENTS.reputation-3000#/3000)" />
<cfelseif ARGUMENTS.reputation lt 21000>
<cfreturn "Honored (#ARGUMENTS.reputation-9000#/9000)" />
<cfelseif ARGUMENTS.reputation lt 42000>
<cfreturn "Revered (#ARGUMENTS.reputation-21000#/21000)" />
<cfelse>
<cfreturn "Exalted (#ARGUMENTS.reputation-42000#/1000)" />
</cfif>
</cffunction>