• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

How to cache "attributes" from items.xml to PHP (Znote)

grilo13

RAWR
Joined
Jun 17, 2011
Messages
254
Solutions
4
Reaction score
57
Location
HUEland
GitHub
mTsGrilo
I'm using spells.php from @Znote as my base, and trying to do a "items.php", where players will be able to see eq. items in server, but I just import the items' ID, Name and Prefix. (Example from the cache generated)

Code:
{"id":"2472","name":"magic plate armor","article":"a"},{"id":"2474","name":"winged helmet","article":"a"},{"id":"2475","name":"warrior helmet","article":"a"}

I'd like to know how to also add all the "attribute" values (as weight, armor, slotType).

My code in this moment:
PHP:
<?php require_once 'engine/init.php'; include 'layout/overall/header.php';

// Loading item list
$itemsCache = new Cache('engine/cache/items');
if (user_logged_in() && is_admin($user_data)) {
    if (isset($_GET['update'])) {
        echo "<p><strong>Logged in as admin, loading engine/XML/items.xml file and updating cache.</strong></p>";
        // SPELLS XML TO PHP ARRAY
        $itemsXML = simplexml_load_file("engine/XML/items.xml");
        if ($itemsXML !== false) {
            $types = array();
            $type_attr = array();
            $groups = array();

            // This empty array will eventually contain all items grouped by type and indexed by item type
            $items = array();

            // Loop through each XML spell object
            foreach ($itemsXML as $type => $item) {
                // Get item types
                if (!in_array($type, $types)) {
                    $types[] = $type;
                    $type_attr[$type] = array();
                }
                // Get spell attributes
                $attributes = array();
                // Extract attribute values from the XML object and store it in a more manage friendly way $attributes
                foreach ($item->attributes() as $aName => $aValue)
                    $attributes["$aName"] = "$aValue";
                // Remove unececsary attributes
                if (isset($attributes['plural'])) unset($attributes['plural']);
                if (isset($attributes['fromid'])) unset($attributes['fromid']);
                if (isset($attributes['toid'])) unset($attributes['toid']);
                if (isset($attributes['editorsuffix'])) unset($attributes['editorsuffix']);
                //if (isset($attributes['itemid'])) unset($attributes['itemid']);
                //if (isset($attributes['id'])) unset($attributes['id']);
                //if (isset($attributes['conjureId'])) unset($attributes['conjureId']);
                //if (isset($attributes['function'])) unset($attributes['function']);
                // Populate type attributes
                foreach (array_keys($attributes) as $attr) {
                    if (!in_array($attr, $type_attr[$type]))
                        $type_attr[$type][] = $attr;
                }
           
                // I have no idea what I did below here

                // Exclude monster spells (Monster spells looks like this on the ORTS data pack)
                $slotType = (isset($attributes['slotType'])) ? $attributes['slotType'] : false;
                // Also exclude "house spells" such as aleta sio.
                $name = (isset($attributes['name'])) ? $attributes['name'] : false;
                if (substr($slotType, 0, 3) == NULL ) {
                    // Populate spell array with potential relevant attributes for the spell type
                    foreach ($type_attr[$type] as $att)
                        $items[$type][$name][$att] = (isset($attributes[$att])) ? $attributes[$att] : false;
                }
            }
            // Will sort the items later
            // Sort the spell list properly
            foreach (array_keys($items) as $type) {
                usort($items[$type], function ($a, $b) {
                    if (isset($a['lvl']))
                        return $a['lvl'] - $b['lvl'];
                    if (isset($a['maglv']))
                        return $a['maglv'] - $b['maglv'];
                    return -1;
                });
            }
            $itemsCache->setContent($items);
            $itemsCache->save();
        } else {
            echo "<p><strong>Failed to load engine/XML/items.xml file.</strong></p>";
        }
    } else {
        $items = $itemsCache->load();
        ?>
        <form action="">
            <input type="submit" name="update" value="Generate new cache">
        </form>
        <?php
    }
    // END SPELLS XML TO PHP ARRAY
} else {
    $items = $itemsCache->load();
}
// End loading spell list

if ($items) {
    // Preparing data
    $configVoc = $config['vocations'];
    $types = array_keys($items);
    $itemServer = 'http://'.$config['shop']['imageServer'].'/';

    // Filter spells by vocation
    $getVoc = (isset($_GET['vocation'])) ? getValue($_GET['vocation']) : 'all';
    if ($getVoc !== 'all') {
        $getVoc = (int)$getVoc;
        foreach ($types as $type)
            foreach ($items[$type] as $name => $item)
                if (!empty($item['vocations']))
                    if (!in_array($getVoc, $item['vocations']))
                        unset($items[$type][$name]);
    }

    // Render HTML
    ?>

    HTML Not done yet
    <?php
}

include 'layout/overall/footer.php'; ?>

And I'll also add a Pull Request when I finish it. :p
 
Lets have a look at itms.xml structure:
XML:
<items>
    <item id="2472" article="a" name="magic plate armor">
        <attribute key="weight" value="8500" />
        <attribute key="armor" value="17" />
        <attribute key="slotType" value="body" />
    </item>
    <item id="2473" article="a" name="viking helmet">
        <attribute key="weight" value="3900" />
        <attribute key="armor" value="4" />
        <attribute key="slotType" value="head" />
    </item>
    <item id="2474" article="a" name="winged helmet">
        <attribute key="description" value="It's the Helmet of Hermes." />
        <attribute key="weight" value="1200" />
        <attribute key="armor" value="10" />
        <attribute key="slotType" value="head" />
    </item>
</items>

PHP:
// Loop through <items> and load every <item> object
foreach ($itemsXML as $type => $item) {
    // Get spell attributes
    $attributes = array();
    // Fetch all attributes on the <item> object
    // Extract attribute values from the XML object and store it in a more manage friendly way $attributes
    foreach ($item->attributes() as $aName => $aValue)
        $attributes["$aName"] = "$aValue";
    // Remove unececsary attributes
}

You also need to do a foreach loop to loop through every <attribute> xml object inside the <item> object, and then loop through all attributes on the <attribute> object.

Something along the lines of:
PHP:
// Loop through <items> and load every <item> object
foreach ($itemsXML as $type => $item) {
    // Get spell attributes
    $item_attributes = array();
    // Fetch all attributes on the <item> object
    // Extract attribute values from the XML object and store it in a more manage friendly way $item_attributes
    foreach ($item->attributes() as $aName => $aValue)
        $item_attributes["$aName"] = "$aValue";
    // Remove unececsary attributes

    $attribute_attributes = array();
    // Loop through every <attribute> object inside the <item> object
    foreach ($item as $attribute) {
        // Fetch all attributes on the <attribute> xml object
        foreach ($attribute->attributes() as $aName => $aValue)
            $attribute_attributes["$aName"] = "$aValue";
    }
}

You probably wanna build this type of cache format:
JSON:
{
    "id":"2472",
    "name":"magic plate armor",
    "article":"a",
    "attributes":[
        {"key":"description", "value":"It's the Helmet of Hermes."},
        {"key":"weight", "value":1200},
        {"key":"armor", "value":10},
        {"key":"slotType", "value":"head"}
    ]
}
 
Last edited:
Ok, it worked this way:

PHP:
<?php require_once 'engine/init.php'; include 'layout/overall/header.php';

// Loading spell list
$spellsCache = new Cache('engine/cache/spells');
if (user_logged_in() && is_admin($user_data)) {
   if (isset($_GET['update'])) {
       echo "<p><strong>Logged in as admin, loading engine/XML/spells.xml file and updating cache.</strong></p>";
       // SPELLS XML TO PHP ARRAY
       $spellsXML = simplexml_load_file("engine/XML/spells.xml");
       if ($spellsXML !== false) {
           $types = array();
           $type_attr = array();
           $groups = array();

           // This empty array will eventually contain all spells grouped by type and indexed by spell name
           $spells = array();

           // Loop through each XML spell object
           foreach ($spellsXML as $type => $spell) {
               // Get spell types
               if (!in_array($type, $types)) {
                   $types[] = $type;
                   $type_attr[$type] = array();
               }
               // Get spell attributes
               $attributes = array();
               // Extract attribute values from the XML object and store it in a more manage friendly way $attributes
               foreach ($spell->attributes() as $aName => $aValue)
                   $attributes["$aName"] = "$aValue";
               // Remove unececsary attributes
               if (isset($attributes['script'])) unset($attributes['script']);
               if (isset($attributes['spellid'])) unset($attributes['spellid']);
               //if (isset($attributes['id'])) unset($attributes['id']);
               //if (isset($attributes['conjureId'])) unset($attributes['conjureId']);
               if (isset($attributes['function'])) unset($attributes['function']);
               // Populate type attributes
               foreach (array_keys($attributes) as $attr) {
                   if (!in_array($attr, $type_attr[$type]))
                       $type_attr[$type][] = $attr;
               }
               // Get spell groups
               if (isset($attributes['group'])) {
                   if (!in_array($attributes['group'], $groups))
                       $groups[] = $attributes['group'];
               }
               // Get spell vocations
               $vocations = array();
               foreach ($spell->vocation as $vocation) {
                   foreach ($vocation->attributes() as $attributeName => $attributeValue) {
                       if ("$attributeName" == "name") {
                           $vocId = vocation_name_to_id("$attributeValue");
                           $vocations[] = ($vocId !== false) ? $vocId : "$attributeValue";
                       }
                   }
               }
               // Exclude monster spells (Monster spells looks like this on the ORTS data pack)
               $words = (isset($attributes['words'])) ? $attributes['words'] : false;
               // Also exclude "house spells" such as aleta sio.
               $name = (isset($attributes['name'])) ? $attributes['name'] : false;
               if (substr($words, 0, 3) !== '###' && substr($name, 0, 5) !== 'House') {
                   // Build full spell list where the spell name is the key to the spell array.
                   $spells[$type][$name] = array('vocations' => $vocations);
                   // Populate spell array with potential relevant attributes for the spell type
                   foreach ($type_attr[$type] as $att)
                       $spells[$type][$name][$att] = (isset($attributes[$att])) ? $attributes[$att] : false;
               }
           }
           // Sort the spell list properly
           foreach (array_keys($spells) as $type) {
               usort($spells[$type], function ($a, $b) {
                   if (isset($a['lvl']))
                       return $a['lvl'] - $b['lvl'];
                   if (isset($a['maglv']))
                       return $a['maglv'] - $b['maglv'];
                   return -1;
               });
           }
           $spellsCache->setContent($spells);
           $spellsCache->save();
       } else {
           echo "<p><strong>Failed to load engine/XML/spells.xml file.</strong></p>";
       }
   } else {
       $spells = $spellsCache->load();
       ?>
       <form action="">
           <input type="submit" name="update" value="Generate new cache">
       </form>
       <?php
   }
   // END SPELLS XML TO PHP ARRAY
} else {
   $spells = $spellsCache->load();
}
// End loading spell list

if ($spells) {
   // Preparing data
   $configVoc = $config['vocations'];
   $types = array_keys($spells);
   $itemServer = 'http://'.$config['shop']['imageServer'].'/';

   // Filter spells by vocation
   $getVoc = (isset($_GET['vocation'])) ? getValue($_GET['vocation']) : 'all';
   if ($getVoc !== 'all') {
       $getVoc = (int)$getVoc;
       foreach ($types as $type)
           foreach ($spells[$type] as $name => $spell)
               if (!empty($spell['vocations']))
                   if (!in_array($getVoc, $spell['vocations']))
                       unset($spells[$type][$name]);
   }

   // Render HTML
   ?>
                       <div id="contentBody" class="col-sm-12">
                       <div id="messages"></div>   
       <div class="panel panel-default">
   <div class="panel-heading">
       Spells <?php if ($getVoc !== 'all') echo '('.$configVoc[$getVoc]['name'].')'; else echo '(All vocations)'; ?>
   </div>
   <div class="panel-body">
       

       <div>
           <table class="table table-striped table-hover table-fixed">
               <tr>
               <form action="#spells" class="filter_spells">
                   <td>Filter vocation:</td>
                   <td>       <select id="vocation" name="vocation">
           <option value="all">All</option>
           <?php foreach ($config['vocations'] as $id => $vocation): ?>
               <option value="<?php echo $id; ?>" <?php if ($getVoc === $id) echo "selected"; ?>><?php echo $vocation['name']; ?></option>
           <?php endforeach; ?>
       </select></td>
                   <td>       <input type="submit" value="Filter " class="btn btn-info"></td>
               </form>
               </tr>
           
           </table>
           
                       <table class="table table-striped table-hover table-fixed">
                           <div id="Tabs" class="panel-body">
                             <ul class="nav nav-tabs nav-justified">
                               <li class="active"><a data-toggle="tab" href="#Instant">Instant</a></li>
                               <li><a data-toggle="tab" href="#Rune">Rune</a></li>
                               <li><a data-toggle="tab" href="#Conjure">Conjure</a></li>
                             </ul>
                                   <div class="tab-content">
                                   <div class="tab-pane active" id="Instant">
                                                               <div class="row">
                                                                       <table class="table tbl-hover">
                                                                               <tr class="yellow">
                                                                                   <td>Name</td>
                                                                                   <td>Words</td>
                                                                                   <td>Level</td>
                                                                                   <td>Mana</td>
                                                                                   <td>Vocations</td>
                                                                               </tr>
                                                                               <?php foreach ($spells['instant'] as $spell): ?>
                                                                               <tr>
                                                                                   <td><?php echo $spell['name']; ?></td>
                                                                                   <td><?php echo $spell['words']; ?></td>
                                                                                   <td><?php echo $spell['lvl']; ?></td>
                                                                                   <td><?php echo $spell['mana']; ?></td>
                                                                                   <td><?php
                                                                                   if (!empty($spell['vocations'])) {
                                                                                       $names = array();
                                                                                       foreach ($spell['vocations'] as $id) {
                                                                                           if (isset($configVoc[$id]))
                                                                                               $names[] = $configVoc[$id]['name'];
                                                                                       }
                                                                                       echo implode(',<br>', $names);
                                                                                   }
                                                                                   ?></td>
                                                                               </tr>
                                                                               <?php endforeach; ?>
                                                                           </tbody>
                                                                       </table>

                                                               </div>
                                   </div>
                                   
                                   <div class="tab-pane" id="Rune">
                                   Rune
                                   </div>

                                   <div class="tab-pane" id="Conjure">
                                   Conjure
                                   </div>
                                   </div>
                           </div>
                       </table>
                       
                       
                       
                       </table>
       </div>
   </div>
   </div>
   </div>

   <h2 id="spell_instant">Instant Spells</h2>
   <a href="#spells">Jump to top</a>
   <table class="table tbl-hover">
       <tbody>
           <tr class="yellow">
               <td>Name</td>
               <td>Words</td>
               <td>Level</td>
               <td>Mana</td>
               <td>Vocations</td>
           </tr>
           <?php foreach ($spells['instant'] as $spell): ?>
           <tr>
               <td><?php echo $spell['name']; ?></td>
               <td><?php echo $spell['words']; ?></td>
               <td><?php echo $spell['lvl']; ?></td>
               <td><?php echo $spell['mana']; ?></td>
               <td><?php
               if (!empty($spell['vocations'])) {
                   $names = array();
                   foreach ($spell['vocations'] as $id) {
                       if (isset($configVoc[$id]))
                           $names[] = $configVoc[$id]['name'];
                   }
                   echo implode(',<br>', $names);
               }
               ?></td>
           </tr>
           <?php endforeach; ?>
       </tbody>
   </table>

   <h2 id="spell_rune">Magical Runes</h2>
   <a href="#spells">Jump to top</a>
   <table class="table tbl-hover">
       <tbody>
           <tr class="yellow">
               <td>Name</td>
               <td>Level</td>
               <td>Magic Level</td>
               <td>Image</td>
               <td>Vocations</td>
           </tr>
           <?php foreach ($spells['rune'] as $spell): ?>
           <tr>
               <td><?php echo $spell['name']; ?></td>
               <td><?php echo $spell['lvl']; ?></td>
               <td><?php echo $spell['maglv']; ?></td>
               <td><img src="<?php echo $itemServer.$spell['id'].'.gif'; ?>" alt="Rune image"></td>
               <td><?php
               if (!empty($spell['vocations'])) {
                   $names = array();
                   foreach ($spell['vocations'] as $id) {
                       if (isset($configVoc[$id]))
                           $names[] = $configVoc[$id]['name'];
                   }
                   echo implode(',<br>', $names);
               }
               ?></td>
           </tr>
           <?php endforeach; ?>
       </tbody>
   </table>

   <h2 id="spell_conjure">Conjure Spells</h2>
   <a href="#spells">Jump to top</a>
   <table class="table tbl-hover">
       <tbody>
           <tr class="yellow">
               <td>Name</td>
               <td>Words</td>
               <td>Level</td>
               <td>Mana</td>
               <td>Soul</td>
               <td>Charges</td>
               <td>Image</td>
               <td>Vocations</td>
           </tr>
           <?php foreach ($spells['conjure'] as $spell): ?>
           <tr>
               <td><?php echo $spell['name']; ?></td>
               <td><?php echo $spell['words']; ?></td>
               <td><?php echo $spell['lvl']; ?></td>
               <td><?php echo $spell['mana']; ?></td>
               <td><?php echo $spell['soul']; ?></td>
               <td><?php echo $spell['conjureCount']; ?></td>
               <td><img src="<?php echo $itemServer.$spell['conjureId'].'.gif'; ?>" alt="Rune image"></td>
               <td><?php
               if (!empty($spell['vocations'])) {
                   $names = array();
                   foreach ($spell['vocations'] as $id) {
                       if (isset($configVoc[$id]))
                           $names[] = $configVoc[$id]['name'];
                   }
                   echo implode(',<br>', $names);
               }
               ?></td>
           </tr>
           <?php endforeach; ?>
       </tbody>
   </table>
   <a href="#spells">Jump to top</a>
   <?php
} else {
   ?>
   <h1>Spells</h1>
   <p>Spells have currently not been loaded into the website by the server admin.</p>
   <?php
}

/* Debug tests
foreach ($spells as $type => $spells) {
   data_dump($spells, false, "Type: $type");
}

// All spell attributes?
'group', 'words', 'lvl', 'maglv', 'charges', 'allowfaruse', 'blocktype', 'mana', 'soul', 'prem', 'aggressive', 'range', 'selftarget', 'needtarget', 'blockwalls', 'needweapon', 'exhaustion', 'groupcooldown', 'needlearn', 'casterTargetOrDirection', 'direction', 'params', 'playernameparam', 'conjureId', 'reagentId', 'conjureCount', 'vocations'
*/
include 'layout/overall/footer.php'; ?>

But the "attributes" are before the other stuffs, whatever, it's working :v
 
Last edited:
Back
Top