<?php
/**
*
* Simple rapidshare file checker class.
* Usage:
* $files = RSFile::getInstance($id1, $name1);
* $files = RSFile::getInstance($id2, $name2);
* $files->processFiles();
* if ($files->getStatus() === RSFile::STATUS_FILE_OK) {
* echo $files->getSize(RSFile::SIZE_MB);
* echo $files->getDownloadMirror();
* }
*
* @version v1.0
* @author Alex
*/
class RSFile implements Iterator {
/**
* The file was not found on the rapidshare servers.
* @var integer
*/
const STATUS_FILE_NOT_FOUND = 0;
/**
* File was found and everything is OK.
* @var integer
*/
const STATUS_FILE_OK = 1;
/**
* The rapidshare server is down.
* @var integer
*/
const STATUS_SERVER_DOWN = 3;
/**
* The file was marked as illegal.
* @var integer
*/
const STATUS_ILLEGAL_FILE = 4;
/**
* Format file size to bytes (by default).
* @var string
*/
const SIZE_B = 'b';
/**
* Format file size to kilobytes
* @var string
*/
const SIZE_KB = 'kb';
/**
* Format file size to megabytes
* @var string
*/
const SIZE_MB = 'mb';
/**
* Format file size to gigabytes
* @var string
*/
const SIZE_GB = 'gb';
/**
* The maximum number of calls to the rapidshare servers.
* @var integer
*/
const MAX_SERVER_CALLS = 3;
/**
* Stores the latest error (if any)
* @var string
*/
private $_error = null;
/**
* Stores the latest error number (if any)
* @var string
*/
private $_errno = null;
/**
* Stores the current file id
* @var string
*/
private $_id;
/**
* Stores the current file name
* @var string
*/
private $_name;
/**
* Stores the current file size in bytes
* @var integer
*/
private $_size;
/**
* Stores the server id for the current file
* @var integer
*/
private $_serverId;
/**
* Stores the status for the current file
* @var integer
*/
private $_status;
/**
* Stores the short host for the current file
* @var string
*/
private $_shortHost;
/**
* Stores the md5sum of the current file
* @var string
*/
private $_md5sum;
/**
* We use this simple variable to know if more than MAX_SERVER_CALLS calls
* are made to the rapidshare server, you should never make more than one
* call to processFiles() function that connects to the rapidshare servers.
* @var integer
*/
private static $calls = 0;
/**
* The list of instances of this class
* @var object
*/
private static $instances = array();
/**
* Private constructor
*/
private function __construct($id, $name) {
$this->_id = $id;
$this->_name = $name;
}
/**
* Returns only one instance of this class per id/name
*
* @param string $id File id on rapidshare servers
* @param string $name File name on rapidshare servers
*
* @return object
*/
public static function getInstance($id, $name) {
$instance = (string) $id.$name;
if (!empty($instance)) {
if (!isset(self::$instances[$instance]) || !self::$instances[$instance] instanceof self)
self::$instances[$instance] = new self($id, $name);
return self::$instances[$instance];
}
trigger_error("Empty instance id!", E_USER_ERROR);
}
/**
* Removes the instance.
* @param string $id
*/
public function unsetInstance($id, $name) {
$instance = (string) $id.$name;
if (!empty($instance)) {
if (isset(self::$instances[$instance]))
unset(self::$instances[$instance]);
return true;
}
trigger_error("Empty instance id!", E_USER_ERROR);
}
/**
* Returns the id for the current file
* @return string
*/
public function getFileId() {
return $this->_id;
}
/**
* Returns the name of the current file
* @return string
*/
public function getFileName() {
return $this->_name;
}
/**
* Returns the size of the current file
* @param string $format Use one of the defined SIZE_* constants
* @param int $precision Precision for round function
*
* @return float The file size changed in the desired format.
*/
public function getFileSize($format = self::SIZE_B, $precision = 2) {
if (!is_int($precision))
$precision = (int) $precision;
switch ($format) {
case self::SIZE_GB:
return round($this->_size / (1024 * 1024 * 1024), $precision);
case self::SIZE_MB:
return round($this->_size / (1024 * 1024), $precision);
case self::SIZE_KB:
return round($this->_size / 1024, $precision);
default:
case self::SIZE_B:
return $this->_size;
}
}
/**
* Returns the server id where the file is hosted.
* @return integer
*/
public function getServerId() {
return $this->_serverId;
}
/**
* Returns the status of the current file
* @returns integer.
*/
public function getFileStatus() {
return $this->_status;
}
/**
* Returns the short host for the current file, is used to get the best
* download mirror.
* @return string.
*/
public function getShortHost() {
return $this->_shortHost;
}
/**
* Returns the best download mirror for the current file or null if the
* file status is not equal to 1
*
* @return mixed
*/
public function getDownloadMirror() {
// The status of the file MUST be ok or there is no file.
if ($this->getFileStatus() !== self::STATUS_FILE_OK)
return null;
// http://rs$serverid$shorthost.rapidshare.com/files/$fileid/$filename
$url = 'http://rs';
$url .= $this->getServerId();
$url .= $this->getShortHost();
$url .= '.rapidshare.com/files/';
$url .= $this->getFileId();
$url .= '/';
$url .= $this->getFileName();
return $url;
}
/**
* Returns the md5sum of the current file
* @return string
*/
public function getMd5sum() {
return $this->_md5sum;
}
/**
* Simple implode function but works with multiton objects.
*
* @param string $glue String separator
* @param object $objs Instance of class implementing Iterator interface
* @param string $callback Object method used to get the string for
* concatenation
*/
public function implodeObjs($glue, $objs, $callback) {
$returns = '';
foreach ($objs as $obj) {
$returns .= $obj->$callback();
$returns .= $glue;
}
/*
* If the separator is not an empty string then remove it from the end
* of the final string.
*/
if (isset($glue[0]))
$returns = substr($returns, 0, (count($glue) * -1));
return $returns;
}
/**
* This function must be called only after every file is already created.
* e.g. $files = RSFile::getInstance(id1, name1)->getInstance(id2, name2)...
* $files->processFiles();
* foreach($files as $file)
* $file->getFileSize() ...
*
* @return boolean true on success and false otherwise.
*/
public function processFiles() {
// Make sure we dont call to many times the rapidshare api.
if (self::$calls >= self::MAX_SERVER_CALLS) {
$this->_error = 'You can NOT call this method more than
MAX_SERVER_CALLS times!';
$this->_errno = '0001';
return false;
}
// Get file ids separated by comma
$files = $this->implodeObjs(',', $this, 'getFileId');
// Get file names separated by comma
$filenames = $this->implodeObjs(',', $this, 'getFileName');
// Some checking before getting any error from the server.
if (count($files) > 3000 || count($filenames) > 30000) {
$this->_error = 'There is a server based limitation. Files are limited
to 3000 characters and filenames to 30.000';
$this->_errno = '0002';
return false;
}
// Create all POST fields
$chPostFields = 'sub=checkfiles';
$chPostFields .= '&files=';
$chPostFields .= $files;
$chPostFields .= '&filenames=';
$chPostFields .= $filenames;
// Initiate cURL
$ch = curl_init('http://api.rapidshare.com/cgi-bin/rsapi.cgi');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $chPostFields);
// Get all files from the response
$data = curl_exec($ch);
if ($data === false) {
// There was an error. Take note of that...
$this->_error = curl_error($ch);
$this->_errno = curl_errno($ch);
// Close the connection
@curl_close($ch);
// Return false so we know ther is an error.
return false;
}
// Explode the results
$files = explode("\n", $data);
// Remove the last item
array_pop($files);
foreach ($files as $file) {
list($id, $name, $size, $serverId, $status, $shortHost, $md5sum)
= explode(',', $file);
// Set all fields.
self::$instances[$id.$name]->_size = (int) $size;
self::$instances[$id.$name]->_serverId = (int) $serverId;
self::$instances[$id.$name]->_status = (int) $status;
self::$instances[$id.$name]->_shortHost = $shortHost;
self::$instances[$id.$name]->_md5sum = $md5sum;
}
curl_close($ch);
self::$calls++;
return true;
}
/**
* Returns the last error description.
* @return string
*/
public function error() {
return $this->_error;
}
/**
* Returns the last error number.
* @return string
*/
public function errno() {
return $this->_errno;
}
/**
* No serialization allowed
*/
public function __sleep() {
trigger_error("No serialization allowed!", E_USER_ERROR);
}
/**
* No cloning allowed
*/
public function __clone() {
trigger_error("No cloning allowed!", E_USER_ERROR);
}
/**
* Implementing Iterator
*/
public function current() {
return current(self::$instances);
}
public function key() {
return key(self::$instances);
}
public function next() {
return next(self::$instances);
}
public function rewind() {
reset(self::$instances);
}
public function valid() {
return current(self::$instances) !== false;
}
}
|