Howto implement data caching?

Maniaplanet public API, ManiaConnect system and the open source PHP SDK.

Moderator: NADEO

Post Reply
User avatar
Electron
Posts: 797
Joined: 15 Jun 2010, 18:02
Contact:

Howto implement data caching?

Post by Electron »

A clan mate ask for a maniaplanet compatible signature banner with server statistics, ladder points and rankings.
Because all members with PHP skills are currently in deep winter sleep, I tried to port our forum banner to support Maniaplanet/TrackMania² (you can see the result below).
But my PHP kowledge is very basic. I started to learn PHP just some weeks ago.

Our TMF banner used the TMFDataFetcher class by oorf|fuckfish (Our clan has access to the TrackMania stats server).
So I searched for a TMFDataFetcher script that was ported to Maniaplanet/Trackmania Canyon. But it looks like, no one has done it so far.
Then I tried to use the Maniaplanet Web Services to access the statistics on my own. It was very easy. You need only three lines of code.
But for a fast and efficient access you need to cache the requested data. But I found not sample code.

The TMFDataFetcher class use a MySQL database to cache all the rankings.
Because I only need the ladder points, the world and nation rank, and our our forum has a limited number of visitors, I decided to use a simple file based cache.
It seems to work, but if some one had allready written a better solution, please let me know.

I experienced one problem. If someone delete the cache file, it will be created anew. But without write access. file_put_contents() failed with a permission denied error.
I have no experience with Linux and its file system. Why was the file created wihout write access? And how to change my code to solve this problem?

Code: Select all

$login = $_GET['login'];

// cache file
$filename = __DIR__.'/signature.cache';

// get ladder points, world rank, nation rank
try
{
    $worldrank = 0;
    $nationrank = 0;
    $ladderpoints = 0;

    // very basic file based data caching
    $refreshStats = true;
    $timeNow = time();

    // cache file existing?
    if (file_exists($filename))
    {
        // read cached stats from file
        $data = unserialize(file_get_contents($filename));
        if (array_key_exists($login, $data))
        { // player found in stats
            if (($timeNow - $data[$login]['cachetime']) < 43200) // 12 hours
            {
                // use cached player data
                $ladderpoints = $data[$login]['ladderpoints'];
                $worldrank    = $data[$login]['worldrank'];
                $nationrank   = $data[$login]['nationrank'];
                $refreshStats = false;
            }
        }
    }

    if ($refreshStats)
    {
        // get latest stats via Maniaplanet Web Services
        $multiplayerCanyon = new \Maniaplanet\WebServices\Canyon\MultiplayerRankings($apiuser, $apipass);
        $player = $multiplayerCanyon->getPlayer($login);

        $ladderpoints = $player->points;
        $count = count($player->ranks);
        if ($count > 0)
            $worldrank = $player->ranks[0]->rank;
        if ($count > 1)
            $nationrank = $player->ranks[1]->rank;

        $data[$login]['ladderpoints'] = $ladderpoints;
        $data[$login]['worldrank']    = $worldrank;
        $data[$login]['nationrank']   = $nationrank;
        $data[$login]['cachetime']    = $timeNow;

        // write stats to cache file
        // ToDo: check write permissions if the file must be rebuilt
        file_put_contents($filename, serialize($data));
    }

    // draw stats
	// ...
}
catch(\Maniaplanet\WebServices\Exception $e) {}
Image
User avatar
gouxim
Nadeo
Nadeo
Posts: 1186
Joined: 14 Jun 2010, 17:20

Re: Howto implement data caching?

Post by gouxim »

There's no difference between creating/writing to an existing file in term of Linux access rights: both require the process that executes it (ie. Apache process if you're running that Web server) to have the W (write) right on the directory (for creation) or the file (for edition).

When you executes file_put_contents, it creates a file with the default rights which depend on your system's configuration.

You'll want to check the rights (ie. file owner and access rights for read/write/execute) at each steps (most of the time you can do that with your ftp, or with ssh if you have such access):

* What are the rights of the directory where you create your file?
* What are the rights of the file just after it was created?

Here's a possible fix:

If the file is created by file_put_content, it should mean you have write rights on that dir. You may want to force the rights of the file just after it was created to allow further edition:

Code: Select all

file_put_contents($filename, serialize($data));
chmod($filename, '0700');
Please do not PM for support. Instead, create a thread so that everyone can contribute or benefit from the answer! 8-)
User avatar
gouxim
Nadeo
Nadeo
Posts: 1186
Joined: 14 Jun 2010, 17:20

Re: Howto implement data caching?

Post by gouxim »

Side note:

In ManiaLib (our open source framework) there's a simple cache interface that works with several technologies (it can either work with Memcached, APC or MySQL - though for the last one you'll obviously need to create a table).

It's very simple to use, and the installation is the same as MPWSSDK's: you just need to download a package and to put one directory (ManiaLib) next to your "Maniaplanet" directory (in your libraries folder).

If you're intersted in using that, I can make a quick tutorial.
Please do not PM for support. Instead, create a thread so that everyone can contribute or benefit from the answer! 8-)
User avatar
Electron
Posts: 797
Joined: 15 Jun 2010, 18:02
Contact:

Re: Howto implement data caching?

Post by Electron »

Electron wrote:I experienced one problem. If someone delete the cache file, it will be created anew. But without write access. file_put_contents() failed with a permission denied error.
I was wrong. The file was not created. It will be created only if the directory had "0777" permissions.
Therefore I created a separate subdirectory with full access only for the cache file. Now I am happy with my code.
gouxim wrote:In ManiaLib (our open source framework) there's a simple cache interface that works with several technologies (it can either work with Memcached, APC or MySQL - though for the last one you'll obviously need to create a table). [...] If you're intersted in using that, I can make a quick tutorial.
You do not need to do it it for me (for my usage of the api my solution is sufficient). But other users need caching too and may interested. Lets wait for corresponding replies.

But I still will take a look inside the ManiaLib framework. But I am confused. The featured version "ManiaLib 1.0 beta" is marked for 'TRACKMANIA FOREVER only' and both ManiaLib 2.0 previews are marked as 'deprecated'.
User avatar
gouxim
Nadeo
Nadeo
Posts: 1186
Joined: 14 Jun 2010, 17:20

Re: Howto implement data caching?

Post by gouxim »

Electron wrote:
Electron wrote:But I still will take a look inside the ManiaLib framework. But I am confused. The featured version "ManiaLib 1.0 beta" is marked for 'TRACKMANIA FOREVER only' and both ManiaLib 2.0 previews are marked as 'deprecated'.
I've been doing lot of clean in ManiaLib lately. The 2.0 preview is really outdate and was for TMF anyway. I'm preparing the release of ManiaLib for Maniaplanet and it should come in the forthcoming weeks !
Please do not PM for support. Instead, create a thread so that everyone can contribute or benefit from the answer! 8-)
User avatar
gouxim
Nadeo
Nadeo
Posts: 1186
Joined: 14 Jun 2010, 17:20

Re: Howto implement data caching?

Post by gouxim »

Please do not PM for support. Instead, create a thread so that everyone can contribute or benefit from the answer! 8-)
Post Reply

Return to “Maniaplanet Web Services”

Who is online

Users browsing this forum: No registered users and 1 guest