| Pages: 1 2 3 [4] :: one page |
| Author |
Thread Statistics | Show CCP posts - 0 post(s) |

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.07.19 11:46:00 -
[91]
Originally by: Kanmahr Hello, wondering you can help
After a few retrievals (cached or not) the getSkillTree call throws the following error:
Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: Entity: line 5492: parser error : out of memory error in /php/api/class.api.php on line 273
It's the first thing I call in my file. Anyone else have issues with this?
I think I found that particular one. isCached and retrieveXML both use large variables that hold the entire text that you fetched. PHP does not release memory for these on function exit. So, now I am calling unset() on these. I am running some more tests, and then 0.22 will be released. I'd be grateful if you could test your usecase against 0.22 - let me shoot you an EM, maybe you could even test before release to confirm the bug's been nailed.
|

Lifigaana Becar
ICE is Coming to EVE
|
Posted - 2008.08.15 12:45:00 -
[92]
my contribution :
File class.api.php
public function getAssetsList() { $contents = $this->retrieveXml("/char/AssetList.xml.aspx");
return $contents; }
File class.assetslist.php
<?php /************************************************************************** PHP Api Lib Copyright (C) 2007 Kw4h
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ class AssetsList { static function getAssetsList($contents) { if (!empty($contents)) { $output = array(); $xml = new SimpleXMLElement($contents);
// add all assets items in an array foreach ($xml->result->rowset->row as $row) { $index = count($output); foreach ($row->attributes() as $name => $value) { $output[$index][(string) $name] = (string) $value; } }
return $output; }
return null; } } ?>
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.08.17 15:58:00 -
[93]
Thank you! I actually already have an assetsList contribution, which is waiting with a few other things to be tested before 0.22 can be released. I'll take a look at your code and see whether it improves on what's been contributed.
If you'd like to see where the code is at currently, please feel free to get trunk/ from SVN - that's usually reasonably stable, has a TODO that lists things that aren't fully tested yet, and has the contributions I received.
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.08.20 14:56:00 -
[94]
Version 0.22 has been released. You can grab it from the SourceForge project page. New API functions, new license, fixed some memory bugs and that pesky amp bug.
Here's the CHANGELOG:
- The library has moved to the LGPLv3 instead of the GPLv3. This means you are now free to use the library, and you do not have to GPLv3 the code that uses the library. If you make changes to the library, you do have to release those changes back to the public, even if you do not distribute your copy of the library but only use it to offer services through a web host. I feel that LGPLv3 gives much greater freedom all around to everyone - I get your changes to the library back, which I want; and you are free to use the library in a closed alliance tool if you so desire. - Added getAssetList and getIndustryJobs functions, donated by Dustin Tinklin - Several users have run into issues with http_build_query using '& amp;' as a separator instead of '&' in their environment. Added some code to retrieveXML that will force it to be '&', and then reset it back to what it was. The alternative to use the 5.2 syntax of http_build_query was considered and rejected on the discovery that 5.1 and even 5.0 are still very common "out there" - Removed the $cachethis parameters again, across the board - Lumy is right, that was a bad idea. Please use the api->cache() function to control caching behavior - Changed the default caching behavior. Things will be kept in cache for the period of time that CCP specifies, unless this is overridden with the optional "timeout" parameter on the get* functions. Note that this library does not save you from shooting yourself in the foot - if you set timeout to a lower time than the caching value specified by CCP, the API may return errors on subsequent attempts to fetch data. - With the exception of wallet data, which has a cachedUntil of 15 minutes, but returns API errors because it really only wants to be called every 60. Setting it to 65 to be safe. See also http://oldforums.eveonline.com/?a=topic&threadID=802053. - And added an extra 5 minutes leeway (default) into the cachedUntil and $timeout logic, to give the CCP server and your server a chance to be "off" a little on time. - api->setTimeTolerance() can be used to adjust the above leeway. - Fixed a bug where $params would not be reset correctly if it was not an array - Added manual garbage collection to isCached and retrieveXml as well as parsing functions so that PHP won't run out of memory so quickly
|

Relyen
Caldari Dead Flesh Corp Rigor Mortis Mortalis
|
Posted - 2008.09.24 14:46:00 -
[95]
Was just reviewing this library as a reference to something I am planning to work on and noticed a small code bug. Not a PHP expert, so feel free to correct me. :P
in class.api.php -- lines 229-230
// Presumably, if it's not set to '&', they might have had a reason for that - be a good citizen $sep = ini_get('arg_separator.output');
And then in class.api.php -- lines 238-239
// And set it back to whatever sensical or non-sensical value it was in the 1st place ini_set('arg_separator.output','&');
I'm guessing that line 239 was supposed to be
ini_set('arg_separator.output', $sep);
________________________________
I am own. |

Eldstrom
|
Posted - 2008.09.24 16:44:00 -
[96]
Edited by: Eldstrom on 24/09/2008 16:46:49 looks like you could be right there.
Corrected it in current working branch.
Eld
|

Relyen
Caldari Dead Flesh Corp Rigor Mortis Mortalis
|
Posted - 2008.09.25 18:29:00 -
[97]
Edited by: Relyen on 25/09/2008 18:35:33 As I mentioned before, I was interested in this api and was going to use it as a reference for something I would be working on. So, with that in mind I basically rewrote it to fit a bit more of my style.
I am posting here for a review of it, not really a release, just curious if I'm heading in the right direction or am totally f'd up :P They are of course, not totally done, but they work :)
I reused several chunks of code (didn't feel like reinventing the wheel) but I rearranged them, altered the style a bit, added more documentation and gave it some more core objects.
In the main api file, I removed the Debug and Cache code and moved each to their own objects. Also, I gave the debug object a level's option. Also, I removed the various API specific retrieve functions, instead I am going to move those into the associated classes.
As I don't think the api needs to know how each specific API needs to be called. It should be able to handle any call, but the specifics should be known to the associated objects themselves.
Atm, I am creating the API in the test file, and passing it as a reference to the specifc api class (I only have 1 atm for testing). It doesn't do much, but just tests the retrieval of the corp security logs.
I plan on adding smarty Templates in the future, and then fleshing out the individual API classes more.
Just curious what people think. I tossed in the LGPL from the eveapi v0.22 of this thread (as that is where I got a lot of the code), but I didn't include any copyright notes in any of the files, not even for myself. I was just doing this for my corp and am interested in feedback. I really don't know how all the licenses work, so just stating where I got alot of code chunks from. I may rewrite more as I advance in my progress and find my needs change.
You can check out the files Here
________________________________
I am own. |

Eldstrom
|
Posted - 2008.09.29 10:58:00 -
[98]
So Far .2x has only been bug fixes and increased eveapi support to Kw4h orignal, however I know Yorick Downe has plans for a rewrite for version .50 . It sounds like your thoughts on are along the samelines as his, Might be an idea if you talk to him about it.
Eld
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.10.02 10:43:00 -
[99]
Relyen, Eldstrom's right. The 0.2x effort has been to make what's there now more complete. I agree that the overall structure of the library is convoluted, that it should be able to generic-parse just about anything the API throws at it without knowing the specifics of every call, and that debug levels, exception handling, and such are needed. Also, the api class should be more generic, so that it can be used for TQ, Sisi, China, EvE-Central, etc.
I haven't gotten past the "thinking about it" stages. Thank you for sharing your code. Once the current 0.23 effort is out the door, I'll go take a closer look. If you'd like to be a direct part of the 0.50 rewrite effort, let me know by EM, and we'll get you set up as a dev for this project on SourceForge.
|

Malice Shecktily
|
Posted - 2008.10.11 23:09:00 -
[100]
here's a little addition to get a character's market orders (seems to be missing from this version -and I can't remember now whether I wrote this myself (been ages since I last looked at this) or whether I pciked it up from another post somewhere - so if someone other than me wrote it then please jump up and claim the credit!)):-
file class.api.php:- add... public function getMarketOrders($corp = false) { $params = array();
$content = null; if ($corp == true) { $contents = $this->retrieveXml("/corp/MarketOrders.xml.aspx ", $params); } else { $contents = $this->retrieveXml("/char/MarketOrders.xml.aspx ", $params); }
return $contents; }
file class.mktorders.php:-
<?php /************************************************************************** PHP Api Lib AccountBalance Class Portions Copyright (C) 2007 Kw4h Portions Copyright (c) 2008 Thorsten Behrens
This file is part of PHP Api Lib.
PHP Api Lib is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
PHP Api Lib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with PHP Api Lib. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ class MarketOrders { static function getMarketOrders($contents) { if (!empty($contents)) { $output = array(); $xml = new SimpleXMLElement($contents);
// add all transaction items in an array foreach ($xml->result->rowset->row as $row) { $index = count($output); foreach ($row->attributes() as $name => $value) { $output[$index][(string) $name] = (string) $value; } }
return $output; }
return null; } } ?>
Keep up the good work folks - This is good stuff, I've been devving in php for a while but am just starting with OOP (so scary!) so this is useful learning stuff for me - Thank you all!
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.10.12 14:18:00 -
[101]
Thank you. We actually have every single last API function in CVS right now - yes, including portraits and even eve-central, all thanks to Eldstrom's heroic efforts - but it needs testing. That's my job, and I haven't gotten to it, mainly due to a) work and b) playing Sacred.
We'll get there. There'll be a 0.23, which will be API-complete.
|

Malice Shecktily
|
Posted - 2008.10.28 00:10:00 -
[102]
Originally by: Yorick Downe
We'll get there. There'll be a 0.23, which will be API-complete.
Looking forward to it - doing some stuff of my own - db abs class to handle MySql stuff etc (I'm a data horder and trader in-game ... so needed the market orders asap)
One idea that's occurred to me is that the Api might benefit from a getCacheDateTime function so a decision can me made from the app as to what to do next with either cache or live data (namely update the db or not) - I'm working on that myself but being new to oop it's going uncertainly - am I re-inventing the wheel? at present I'm setting a property in isCached and using a getChacheTime public function within the class to retrieve the value, but , being new to oop I'm not at all sure that would be considered "best practice" - how would others approach this? - I get the feeling there's a few posting here who know a thing or two!
Should be interesting to see what people's final results are from the api work. The eve-central stuff sounds interesting too.
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2008.10.28 01:03:00 -
[103]
Excellent. I'd love to run the 0.5 design by you when (and if :) it materializes. The idea was to return an object that has properties such as "fromCache" and so on, so that one knows whether the returned data is new or old cached stuff.
|

Alesk Remo
Amarr Corpus Prometheus
|
Posted - 2008.12.01 07:32:00 -
[104]
Edited by: Alesk Remo on 01/12/2008 07:33:11 First of all - thanks for a really nice class.
Secondly, I've made some modifications to make the cache MySQL dependent (as a choice). However, all this change does is store the XML data into a database table for easy and fast access.
The database requirements: The database requires a single table, api_cache, which has three columns, CacheID, CacheLocation and CacheValue.
CacheID is an indexed Primary Key field which I use in order to speed up requests to the cache table.
CacheLocation stores a unique path like structure similarly to that which is currently used as the path that is created by the getCacheFile function. In fact it uses the same function except it replaces the "/" slashes with "-" hyphens.
CacheValue stores the XML data in an HTML encoded format (using the htmlentities function) which has been fetched by the API class.
Quote:
CREATE TABLE `api_cache` ( `CacheID` int(11) NOT NULL auto_increment, `CacheLocation` longtext character set latin1, `CacheValue` longtext character set latin1, PRIMARY KEY (`CacheID`), FULLTEXT KEY `CacheLocation` (`CacheLocation`,`CacheValue`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;
The code changes: The only file affected with the changes is the class.api.php file.
The code changes only affect those function which access and write/update the cache. Static variables are also created along with a property function to specify the database parameters.
There is a fair amount of changes to the function which would take about 5 replies. To simplify this I've linked to the modified file so that you can download and have a look at the code.
Linkage
I have no doubt that there are better ways to use a database with this class, however these modification basically just replace the use of the directory store as a cache with a database store. All XML is encoded when stored and then decoded again when accessed.
I would like to hear opinions and feedback on this as well as if anyone has any ideas to improve on this.
Regards,
Alesk Remo
|

Eldstrom
|
Posted - 2008.12.03 11:36:00 -
[105]
I am assuming your alteration is to the 0.22 Version and not the upcoming 0.23 very which covers the whole API that is currently available?
Eld
|

Alezra
Di-Tron Heavy Industries Atlas Alliance
|
Posted - 2008.12.05 03:38:00 -
[106]
I built a framework for a similar API interface and I'm guessing it operates in a similar fashion to Relyen's. The whole thing is broken out into different objects (perhaps even excessively.) The base class is apiConnection. Its only purpose is to connect to the API using the supplied arguments and handle caching data.
The individual data classes are supplied with a reference to an apiConnection object which they use to fetch xml.
An example of my api in action:
$myAccount = new apiConnection($userID, $apiKey); $myData = new apiData();
$myData->char->SkillInTraining->fetch($myAccount, $characterID); $xml = $myData->char->SkillInTraining->getRawXML();
It can generically retrieve the xml for any api call at the moment. The next part of implementation would be to cause the data fetch() method to parse the xml into usable content. I realized that I could literally copy the code out of your parsing functions directly into my data objects. I'm still debating if I want to do that or write my own xml parsing.
The constructor for the apiConnection class looks like this:
public function __construct ($id = 0, $key = 0, $setCaching = TRUE, $dir = "xmlcache/", $rootAddress = "http://api.eve-online.com")
If caching is enabled (which it is, by default) then all data retrieved from the api is stored under
xmlcache/$userID/$characterID/
A call to flushCache() will delete that data, and a fetch command with the flag FLUSH_CACHE will force the apiConnection to query the server again.
|

Kyara
Gallente Tides of Silence KIA Alliance
|
Posted - 2008.12.09 14:28:00 -
[107]
I've been using this API for a private Project of mine, so i might aswell make the code to it public.
Page with Download and Instructions: http://trac.beerta.net/trac/EveTool/ Screenshots: http://files.beerta.net/gallery/EveTool/
Maybe somebody has use for it.
Patches with new stuff welcome!
|

Lumy
Minmatar eXceed Inc. Triumvirate.
|
Posted - 2008.12.09 15:13:00 -
[108]
Originally by: Alezra the long post
Could you provide link to SVN or source code? Maybe I could steal something useful from you. 
Joomla! in EVE - IGB compatible CMS. |

Alezra
Di-Tron Heavy Industries Atlas Alliance
|
Posted - 2008.12.10 03:11:00 -
[109]
Ehrm, well I was planning on releasing it eventually, but to be honest at the moment it isn't terribly impressive. I have about 55 lines of useful code that handle the apiConnection->fetch() and caching and then 600 lines of code that do nothing but build empty data handlers. As an example, for each API call there's a class like this:
class skillTrainingData extends genericData { public function __construct($url) { parent::__construct($url); } }
Eventually I want to add an xml parser and accessors to each of these class definitions, but it's a bit daunting. At the moment the only thing each data object does is construct, fetch and getRawXML (which are all members of genericData.)
My strategy would be to do something like have an abstract function parse() in each data member that's called when fetch() is ran. The parse command for SkillTrainingData runs an xml parser and stores the results in public variables. Then the user can call something like
$myData->char->SkillInTraining->fetch(); $currentSkill = $myData->char->SkillInTraining->typeID; $nextLevel = $myData->char->SkillInTraining->trainingToLevel;
|

Dan Treva
Raptor Services LTD
|
Posted - 2008.12.12 02:51:00 -
[110]
Originally by: Kyara I've been using this API for a private Project of mine, so i might aswell make the code to it public.
Page with Download and Instructions: http://trac.beerta.net/trac/EveTool/ Screenshots: http://files.beerta.net/gallery/EveTool/
Maybe somebody has use for it.
Patches with new stuff welcome!
You should start your own thread for this.
It definitely had some promise.
I gave it a whirl, and there are a few bugs... looks like some is static db calls and a few missing calls.
|

Alesk Remo
Amarr Corpus Prometheus
|
Posted - 2008.12.23 12:27:00 -
[111]
Quote: I am assuming your alteration is to the 0.22 Version and not the upcoming 0.23 very which covers the whole API that is currently available?
Eld
@Eldstrom:
You are correct, my alteration is to the 0.22 version. I was unaware of the 0.23 version at the time of development. I have now moved my code over to the 0.23 version which is available here:
Linkage
This might not be the best way to handle it but I'm open to any suggestions further. I've tried to keep it quite simple.
Any feedback welcome.
Regards,
Alesk Remo
--- ---
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2009.01.05 12:47:00 -
[112]
Edited by: Yorick Downe on 05/01/2009 12:48:29 Hiya, figured I'd pipe up after a long silence. Lumy's been, as he said, reworking the library in a Herculean effort. I've been mostly slacking, but have recently come out of my slumber to do QA on Eldstrom's 0.23 effort. As a result, we now have a 0.23 that works, encompasses all EvE-API calls and EvE-Central calls, and is ready for testing.
I'd like to ask those who wish to use the library to give it a good spanking. Particularly the new functions, such as the Faction code, has only been tested against XML dumps we got from the forums, as we have no characters that are part of a Faction. The EvE-Central output can also use a good looking-at. Check the samples directory to see how this all works while documentation is being updated, please.
The current 0.23 trunk lives here: http://eve-apiphp.svn.sourceforge.net/viewvc/eve-apiphp/trunk/
There are two TODOs on my plate right now - update the documentation, and handle SimpleXML exceptions when EvE-Central goes down (as it does frequently).
Happy New Year!
|

Buzz AU
|
Posted - 2009.01.13 17:22:00 -
[113]
Hey guys,
Nice work on this, I am a little confused with this as I dont use / havnt used XML. I am looking to use this script to check for payments into my player account and want to make use of the following fields from the output of WalletJournal:
Quote: [ownerName2] = $mychar [amount] = '10000000.00' [reason] = 'free monies'
[date] = Output this [ownerName1] = Output this
So what I want to display is the name of the person sending the above "gift" to a set character (me). In the end this information will be stored into a SQL database, which will essentialy add time to a service that I offer upon reciept of the payment.
Any help would be greatly appriciated.
This is the code I have but it just spews out a lot of transactions.
Quote:
<?php
require_once('eveapi/class.api.php'); require_once('eveapi/class.charselect.php'); require_once('eveapi/class.walletjournal.php');
$apiuser = 'XXXXXX'; // User ID $apipass = 'XXXXXX'; // API Key full $mychar = 'My Name'; // Name of the character $apichar = 'XXXXXX'; // The ID of the character
$api = new Api(); $api->debug(true);// enable debugging $api->setCredentials($apiuser,$apipass,$apichar); $apicharsxml = $api->getCharacters(); $apichars = Characters::getCharacters($apicharsxml);
$api->setCredentials($apiuser,$apipass,$apichar); $walletxml = $api->getWalletJournal(); $wallet = WalletJournal::getWalletJournal($walletxml);
print_r($wallet);
?>
|

Johnathan Roark
Caldari Quantum Industries RAZOR Alliance
|
Posted - 2009.01.13 20:00:00 -
[114]
Originally by: Buzz AU Hey guys,
Nice work on this, I am a little confused with this as I dont use / havnt used XML. I am looking to use this script to check for payments into my player account and want to make use of the following fields from the output of WalletJournal:
Quote: [ownerName2] = $mychar [amount] = '10000000.00' [reason] = 'free monies'
[date] = Output this [ownerName1] = Output this
So what I want to display is the name of the person sending the above "gift" to a set character (me). In the end this information will be stored into a SQL database, which will essentialy add time to a service that I offer upon reciept of the payment.
Any help would be greatly appriciated.
This is the code I have but it just spews out a lot of transactions.
Quote:
<?php
require_once('eveapi/class.api.php'); require_once('eveapi/class.charselect.php'); require_once('eveapi/class.walletjournal.php');
$apiuser = 'XXXXXX'; // User ID $apipass = 'XXXXXX'; // API Key full $mychar = 'My Name'; // Name of the character $apichar = 'XXXXXX'; // The ID of the character
$api = new Api(); $api->debug(true);// enable debugging $api->setCredentials($apiuser,$apipass,$apichar); $apicharsxml = $api->getCharacters(); $apichars = Characters::getCharacters($apicharsxml);
$api->setCredentials($apiuser,$apipass,$apichar); $walletxml = $api->getWalletJournal(); $wallet = WalletJournal::getWalletJournal($walletxml);
print_r($wallet);
?>
All this class does is fetch the api data and dumps it into an array. You would have to go through the array probably using a foreach to put it in an a database. You may be better off using YAPEALif you'd like to go direct to database. |

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2009.01.16 01:24:00 -
[115]
Originally by: Buzz AU
I am looking to use this script to check for payments into my player account and want to make use of the following fields from the output of WalletJournal:
[ownerName2] = $mychar [amount] = '10000000.00' [reason] = 'free monies'
[date] = Output this [ownerName1] = Output this
So what I want to display is the name of the person sending the above "gift" to a set character (me). In the end this information will be stored into a SQL database, which will essentialy add time to a service that I offer upon reciept of the payment.
That very same application is actually sample code in the "sample" directory. Look for "WalletJournal" in the code, you'll see a section there that steps through looking for specific "refTypeID"s. Just before that is the code that grabs the right ID for "Player Donation". So what you want to do is adapt that sample code to your situation. I think you are looking for player donations as well, so it should fit into your situation with a minimum amount of tweaking. The sample code fetches corp, not char (that's the second "true" parameter), which is easily enough changed.
MySQL output is something that has been added to the code, see the posts above yours. It's not (yet) an official part of the library - the team is convinced that we need to redesign/refactor the way the library works in order to make it do all the things we want it to do, and that takes -- long.
"yapeal" is an option, it'll dump the entire WalletJournal into a DB, for you to query on refTypeID or any other criteria. Not a bad approach, though it is the "rival" library. 
Yorick
|

Yorick Downe
Caldari Agony Unleashed Agony Empire
|
Posted - 2009.01.24 02:00:00 -
[116]
0.23 has been released. In celebration, the project has been renamed, and has it's own thread.
I'll probably continue monitoring this one just for the heck of it, but you'll get better results over in the new digs.
|

Wraas Mlnir
Arctic Flying Penguins A.X.I.S
|
Posted - 2009.03.19 13:24:00 -
[117]
COuld someone either provide an expanded explanation of the Getting Started notes that talk about inserting rows into the tables: utilRegisteredUser, utilRegisteredCharacter & utilRegisteredCorporation or point me in the direction of some documentation or even a post in this thread that I missed?
I am having problems and it appears as though I am either putting in too much (is it updated with data as part of its first pass at the API) or I am not putting in something important.
Thanks
-Farting on exiting elevators since 2003 |

Dragonaire
Caldari Corax.
|
Posted - 2009.03.19 14:06:00 -
[118]
I'm guessing you looking maybe for the Yapeal thread? I don't think they use any tables like that in this library except if they have made some changes I haven't seen ;)
Yapeal thread is Yapeal PHP API Library -- Finds camping stations from the inside much easier. Designer of Yapeal for Eve API.
|
| |
|
| Pages: 1 2 3 [4] :: one page |
| First page | Previous page | Next page | Last page |