TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Show Off (http://www.talkphp.com/show-off/)
-   -   World of Warcraft Armory xml Grabber with cURL (http://www.talkphp.com/show-off/3281-world-warcraft-armory-xml-grabber-curl.html)

mortisimus 08-24-2008 09:00 PM

World of Warcraft Armory xml Grabber with cURL
 
Ok, I ran across this a little while ago and since I spent a lot of time looking for this, I thought I would share this with all you guys here that want it.

PHP Code:

class armory {

 const 
BROWSER="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070319 Firefox/2.0.0.3";

 public 
$query;
 public 
$server;
 public 
$guild;
 public 
$guildie;
 public 
$page;

public function 
__construct $query$server$guild$guildie$page ) {
    
$this->query $query;
    
$this->server $server;
    
$this->guild $guild;
    
$this->guildie $guildie;
    
$this->page $page;
 } 
// end of __construct()

public function pull_xml() {

    
// change the first part of the $url to the armory link that you need
    
if( $this->query === 'roster' ){
        
$url 'http://eu.wowarmory.com/guild-info.xml?r=' urlencode($this->server) . '&n=' urlencode($this->guild) . '&p=' $this->page;
        
      }elseif( 
$this->query === 'character' ){
        
$url 'http://eu.wowarmory.com/character-sheet.xml?r=' urlencode($this->server) . '&n=' $this->guildie;
        
        }  

    
$ch curl_init();
    
curl_setopt ($chCURLOPT_URL$url);
    
curl_setopt ($chCURLOPT_RETURNTRANSFER1);
    
curl_setopt ($chCURLOPT_CONNECTTIMEOUT15);
    
curl_setopt ($chCURLOPT_USERAGENT,  self::BROWSER);
    
    
$url_string curl_exec($ch);
    
curl_close($ch);
    return 
simplexml_load_string($url_string);
    
   
 } 
// end of pull_xml()

// end class 

And then to use it:

PHP Code:

Syntax:
$armory = new armory( [character or roster] , realm , [guild name or NULL] , character name , [page number (guilds only) or NULL];

Example:
$armory = new armory(characterhellscreamNULLmortisimusNULL);
$xml $armory->pull_xml(); 

Then you could var_dump($xml) to see all the options you can pull from the armory.

Another example (to get the name):
PHP Code:

$armory = new armory(characterhellscreamNULLmortisimusNULL);
$xml $armory->pull_xml();
echo 
$xml->characterInfo->character['name']; 

Which will get the value of the name in the character tag, contained in the characterInfo tag in the xml file from the armory or in short, the characters name ;-)

All simple stuff but it helped me out.

The World of Warcraft Armory - EU
The World of Warcraft Armory - US

sketchMedia 08-25-2008 02:12 PM

Thanks, I wrote something similar not long ago for a guild website i was developing. In my case I used armory to populate the guild roster in the DB.

One thing i did notice about your code:
PHP Code:

$url_string curl_exec($ch); 
return 
simplexml_load_string($url_string); 
     
curl_close($ch); 

The curl_close is defined after the return, thus it is never fired and resources never freed.

This is the correct code:
PHP Code:

$url_string curl_exec($ch); 
curl_close($ch); 

return 
simplexml_load_string($url_string); 

Also
PHP Code:

curl_setopt ($chCURLOPT_USERAGENT,  armory::BROWSER); 

may aswell be:
PHP Code:

curl_setopt ($chCURLOPT_USERAGENT,  self::BROWSER); 

Just in case you wish to change the name of your class.

mortisimus 08-26-2008 12:03 PM

Thanks, updated it.

Tanax 10-05-2008 04:24 PM

Looks cool :D

ReSpawN 10-10-2008 10:57 AM

Pretty good, but I don't play WoW. ;) Non the less, good share.

Mithadriel 11-08-2008 09:07 PM

Great contribution, really simple to follow and takes a whole lot of headache out of querying the armory!

Managed to get information on characters with no problems but hit a snag when trying to query guild info. Noticed a wee typo on the example above:

PHP Code:

// change the first part of the $url to the armory link that you need
    
if( $this->query === 'roster' ){
        
$url 'http://eu.wowarmory.com.com/guild-info.xml?r=' $this->server '&n=' $this->guild '&p=' $this->page


Remove the spurious .com and everything works as expected :)

p.s excuse the thread necromancy ... figured this was worth it though.

Mithadriel 11-08-2008 09:32 PM

Just also noticed, for guilds or server names with spaces the above code breaks. This very slightly modified version should be fine as it converts the whitespace to '+' which is how blizz formats it.

PHP Code:

public function pull_xml() {

    
// change the first part of the $url to the armory link that you need
    
if( $this->query === 'roster' ){
        
$url 'http://eu.wowarmory.com/guild-info.xml?r=' urlencode($this->server) . '&n=' urlencode($this->guild) . '&p=' $this->page;
        
      }elseif( 
$this->query === 'character' ){
        
$url 'http://eu.wowarmory.com/character-sheet.xml?r=' urlencode($this->server) . '&n=' $this->guildie;
        
        } 


mortisimus 11-09-2008 09:43 AM

Cheers :-)

TheMuffinMan 11-21-2008 08:44 PM

Ok quick question for you PHP folks. :)

I have managed to get this "working" for a guild roster.

I get to this point...
PHP Code:

$armory = new armory('roster''Dawnbringer''Fates Defiance''Bberrymuffin'NULL);
$xml $armory->pull_xml();
echo 
$xml->guildInfo->guild->members->character['name']; 

Now I have the XML, and the "character" tag repeats for every member in the guild.

My question is, how do you look through all of the character elements of the members element to get the information on each character?

My PHP skills aren't the best in the world, sorry if this is a dumb question!

Thanks in advance for any help!

TheMuffinMan 11-21-2008 09:12 PM

Ok I figured it out (should have googled first haha!)

PHP Code:

foreach ($xml->guildInfo->guild->members->character as $char) {
    echo 
$char['name'] . "<br>";



Anyone know how I can go about sorting this array of arrays for the ['name']?

Kalle200000 01-06-2009 11:06 PM

It doesnt work for me.

Quote:

Fatal error: Call to undefined function curl_init() in C:\wamp\www\wow\index.php on line 32

Wildhoney 01-06-2009 11:50 PM

Welcome to the community, Kalle! In order for it to work, you will need to have the cURL module enabled on your server.

To do so, open the following file: C:\wamp\Apache2\bin\php.ini and uncomment the line extension=php_curl.dll (Remove the semi-colon from the start of the line). Don't forget to restart WAMP after doing so.

sketchMedia 01-07-2009 07:16 PM

An alternative to using curl would be:
PHP Code:

/* $ch = curl_init();
 curl_setopt ($ch, CURLOPT_URL, $url);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 15);
 curl_setopt ($ch, CURLOPT_USERAGENT,  self::BROWSER);

 $url_string = curl_exec($ch);
 curl_close($ch);*/
$opts = array(
    
'http'=>array(
        
'method'=>"GET",
        
'header'=>"User-Agent: ".self::BROWSER." \r\n"
    
)
);
$url_string file_get_contents($url,false,stream_context_create($opts));
return 
simplexml_load_string($url_string); 


Dark Severance 01-07-2009 08:22 PM

This is great. I'm slowly working with it to get what I needed but I'm having a problem.

I love the roster and able to pull information from that to create a guild roster. The issue I'm having is I also want to parse in the Profession information. However that is on the separate character pages themselves. How can I grab both roster and all the character pages from that one guild roster so I can then display them how I want.

You can see what I've sort of been experimenting with here:
http://wow.guildregister.com/sortableTable/roster.php

Or even better due to Armory not updating as much. How could I get a .lua file converted over to XML or some format so I can work with it, similar to what you've done with the Armory page. That would work best since that includes officer notes, guild notes, professions, names, etc.

Example of .lua file is here:
http://wow.guildregister.com/sortabl...erProfiler.lua

sketchMedia 01-07-2009 09:12 PM

have a look at this:
http://fin.instinct.org/lua/

Dark Severance 01-08-2009 08:06 PM

Unfortunately that doesn't work for me. So continuing to work with what he has done here I have...

I can then sort the xml data and have it display information in a table format (still work in progress) just by adding this to the code:
Code:

$armory = new armory('roster', 'Drenden', 'Priests of Discord', NULL, NULL);
$xml = $armory->pull_xml();

foreach ($xml->guildInfo->guild->members->character as $char) {
  echo "<tr id=\"".$char['name']."\">";
  echo "<td class=\"rightAlign\">".$char['name']."</td>";
  echo "<td>".$char['level']."</td>";
  echo "<td>".$char['class']."</td>";
  echo "<td>".$char['gender']."</td>";
  echo "<td>".$char['race']."</td>";
  echo "<td>".$char['achPoints']."</td>";
  echo "<td>".$char['url']."</td><br />";
  echo "</tr>";
                        }

I understand that the following:
Code:

$armory = new armory('roster', 'Drenden', 'Priests of Discord', NULL, NULL);
$xml = $armory->pull_xml();

is broken up into variables that let me define where it's pulling the data. There are two different XML pages, one is 'roster' and the other is 'character'. The second field determines what server: 'Drenden'. The third field indicates the guild name: 'Priests of Discord'. The fourth field indicates specific character name: NULL. The last field is page number, when looking at guild information only used during the 'roster' option.

The problem is the 'character' xml page. There is a lot more information in that page. I could access it for a single character like 'Anastasia' by using the following code:
Code:

$armory = new armory('character', 'Drenden', 'Priests of Discord', 'Anastasia', NULL);
$xml = $armory->pull_xml();

I want to be able to temporarily load all the XML data for the 'roster' page as well as each 'character' page for only those members on that 'roster' page. I tried to do something like:

Load Armory Roster Page
Code:

$armory = new armory('roster', 'Drenden', 'Priests of Discord', NULL, NULL);
$xml = $armory->pull_xml();

Then use access the name variable to create a separate query for each by doing:
Code:

foreach ($xml->guildInfo->guild->members->character as $char) {
$armory = new armory('character', 'Drenden', 'Priests of Discord', $char.['name'], NULL);
$xml = $armory->pull_xml();
                }

Unfortunately that does not seem to work. I'm probably trying to load too much variable information or I have the wrong order of how I can use it. I might be over complicating it too. Step by step I can produce each thing individually, now I'm just trying to combine all the single steps so I can display it all on one page.



Full Code:
Code:

<?php

class armory {

 const BROWSER="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070319 Firefox/2.0.0.3";

 public $query;
 public $server;
 public $guild;
 public $guildie;
 public $page;

public function __construct ( $query, $server, $guild, $guildie, $page ) {
        $this->query = $query;
        $this->server = $server;
        $this->guild = $guild;
        $this->guildie = $guildie;
        $this->page = $page;
 } // end of __construct()

public function pull_xml() {

        // change the first part of the $url to the armory link that you need
        if( $this->query === 'roster' ){
                $url = 'http://www.wowarmory.com/guild-info.xml?r=' . urlencode($this->server) . '&n=' . urlencode($this->guild) . '&p=' . $this->page;
               
          }elseif( $this->query === 'character' ){
                $url = 'http://www.wowarmory.com/character-sheet.xml?r=' . urlencode($this->server) . '&n=' . $this->guildie;
               
                } 

        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 15);
        curl_setopt ($ch, CURLOPT_USERAGENT,  self::BROWSER);
       
        $url_string = curl_exec($ch);
        curl_close($ch);
        return simplexml_load_string($url_string);
       
 
 } // end of pull_xml()

} // end class 

$armory = new armory('roster', 'Drenden', 'Priests of Discord', NULL, NULL);
$xml = $armory->pull_xml();

        foreach ($xml->guildInfo->guild->members->character as $char) {
$armory = new armory('character', 'Drenden', 'Priests of Discord', $char['name'], NULL);
$xml = $armory->pull_xml();
                }

foreach ($xml->characterInfo->characterTab->professions->skill as $prof) {
        echo $prof['name'];
}

foreach ($xml->guildInfo->guild->members->character as $char) {
  echo "<tr id=\"".$char['name']."\">";
  echo "<td class=\"rightAlign\">".$char['name']."</td>";
  echo "<td>".$char['level']."</td>";
  echo "<td>".$char['class']."</td>";
  echo "<td>".$char['gender']."</td>";
  echo "<td>".$char['race']."</td>";
  echo "<td>".$char['achPoints']."</td>";
  echo "<td>".$char['url']."</td><br />";
  echo "</tr>";
                        }

?>


yiyang 01-15-2009 07:14 AM

it is work

add

$server = ereg_replace(' ', '+', $server);

SaintIsaiah 01-29-2009 05:45 AM

Hey I'm trying this script and it's working great so far. but what line do I need to write to navigate into and display the values of each primary profession

example:

Profession 1 name
skill#/maxskill#

Profession 2 name
skill#/maxskill#

I see that there is an "@attributes" in several lines of the entire dump but I dont know how to use

PHP Code:

$prof1 $xml->characterInfo->character->professions->skills->0->@attributes["name"

to display even the profession name without there being a massive error.

Any help would be appreciated.

sketchMedia 01-30-2009 08:53 PM

try this:
PHP Code:

$xml $armory->pull_xml();

foreach(
$xml->characterInfo->characterTab->professions->skill as $skill)
{
    
$skill reset($skill);
    echo 
$skill['name'] , ': '$skill['value'],'/',$skill['max'],'<br />';


Seems to work.

SaintIsaiah 01-30-2009 09:05 PM

Ahh I see, didn't think of the foreach function. I also tried it on the equipment. Thanks for the help. Looks nice as well. Haven't skinned it yet but this is what I got so far.

http://hellfireclub.org/testprofile.php?name=Haiasi

Rather than set a predefined character to show, I modified the code to use $_GET to retrieve the name of the character so any character can be viewed.

PHP Code:

$charname $_GET['name'];

$armory = new armory(characterdestromathNULL$charnameNULL); 

so the page in the url should look like
"pagenamehere.php?name=charactername"

Also, you can do the same for the realm to leave it open for anything

PHP Code:

$realmname $_GET['realm'];
$charname $_GET['name'];

$armory = new armory(character$realmnameNULL$charnameNULL); 

Which in turn would make the page in the url look like
"pagenamehere.php?realm=realmname&name=charactername"

I'm a little newbish at php so if I made a mistake, please go easy on me lol.


All times are GMT. The time now is 12:08 PM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0