3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php namespace TorrentPHP; /** * Interface ClientAdaptor * * If you want to add support for your own torrent client of choice, you need to create an ClientAdaptor that sends * commands to your client. For transmission and vuze, these are RPC calls over the HTTP protocol, but your client may * require command-line calls, for example. * * @package TorrentPHP */ interface ClientAdaptor { /** * Add a torrent to the client * * Each client may have different requirements to add a torrent, so an array of arguments with the key being the * argument name and the value being the argument value is required. It is therefore the specific implementation's * responsibility to provide validation throughout it's usage. * * @param array $arguments A single dimensional array of key value pairs * * @throws ClientException When the client does not return expected output to say that this action succeeded * * @return Torrent The newly added torrent object */ public function addTorrent(array $arguments); /** * Start a torrent * * @param Torrent $torrent * * @throws ClientException When the client does not return expected output to say that this action succeeded * * @return Torrent The newly started torrent object */ public function startTorrent(Torrent $torrent); /** * Pause a torrent * * @param Torrent $torrent * * @throws ClientException When the client does not return expected output to say that this action succeeded * * @return Torrent The newly paused torrent object */ public function pauseTorrent(Torrent $torrent); /** * Delete a torrent - be aware this relates to deleting the torrent file and all files associated with it * * @param Torrent $torrent * * @throws ClientException When the client does not return expected output to say that this action succeeded * * @return void */ public function deleteTorrent(Torrent $torrent); } /** * Class Torrent * * Represents the final torrent object provided by TorrentPHP * * @package TorrentPHP */ class Torrent { /** * Default status */ const STATUS_UNKNOWN = -1; /** * A torrent client error has occurred */ const STATUS_ERROR = 0; /** * Torrent is downloading */ const STATUS_DOWNLOADING = 1; /** * Torrent is paused */ const STATUS_PAUSED = 2; /** * Torrent is seeding */ const STATUS_SEEDING = 3; /** * Torrent has completed both downloading and seeding */ const STATUS_COMPLETE = 4; /** * @var array An array of status matching the status constants for validation */ private $statuses = array( self::STATUS_UNKNOWN => 'unknown', self::STATUS_ERROR => 'error', self::STATUS_DOWNLOADING => 'downloading', self::STATUS_PAUSED => 'paused', self::STATUS_SEEDING => 'seeding', self::STATUS_COMPLETE => 'complete' ); /** * @var int The torrent id (used by the torrent client, and may change on each reboot) */ private $id; /** * @var string The torrent hashString which can be used to uniquely identify this torrent */ private $hashString = ''; /** * @var string The torrent name */ private $name = ''; /** * @var int Size of the torrent in bytes */ private $size = 0; /** * @var int Torrent status must be in the $statuses array */ private $status = self::STATUS_UNKNOWN; /** * @var string A string containing an error message */ private $errorString = ''; /** * @var int Download speed in bytes */ private $downloadSpeed = 0; /** * @var int Upload speed in bytes */ private $uploadSpeed = 0; /** * @var float Percentage download completion */ private $percentDone = 0.0; /** * @var int Number of bytes downloaded */ private $bytesDownloaded = 0; /** * @var int Number of bytes uploaded */ private $bytesUploaded = 0; /** * @var float Seeding ratio */ private $seedRatio = 0.0; /** * @var File[] A list of files within the torrent */ private $files = array(); /** * @constructor * * @param int $id The id used by the torrent client (may change on each reboot) * @param string $hashString Uniquely identifiable hash string (remains constant) */ public function __construct($id, $hashString) { $this->id = $id; $this->hashString = $hashString; } /** * Set the torrent name * * @param string $name The name of the torrent */ public function setName($name) { $this->name = $name; } /** * Get torrent name * * @return string The torrent name */ public function getName() { return $this->name; } /** * Set the torrent size in bytes * * @param int $bytes The size of the torrent * * @throws \InvalidArgumentException When an invalid size given */ public function setSize($bytes) { if (is_int($bytes) && $bytes > -1) { $this->size = $bytes; } else { throw new \InvalidArgumentException( 'Invalid torrent size provided. Size should be bigger than "-1" but "%s" given', $bytes ); } } /** * Get torrent size * * @return int The torrent size in bytes */ public function getSize() { return $this->size; } /** * Set the torrent status according to a status within the $statuses array * * @param int $status The status integer (constant representing an integer) * * @throws \InvalidArgumentException When an invalid status integer given */ public function setStatus($status) { if (is_int($status) && isset($this->statuses[$status])) { $this->status = $status; } else { throw new \InvalidArgumentException(sprintf( 'Invalid torrent status provided. Status should be one of "%s", "%s" given.', print_r($this->statuses, true), $status )); } } /** * Get the status integer value * * @return int */ public function getStatus() { return $this->status; } /** * Get the status string * * @return string */ public function getStatusString() { return $this->statuses[$this->status]; } /** * Set error string * * @param string $errorString */ public function setErrorString($errorString) { $this->errorString = $errorString; } /** * Get error string * * @return string */ public function getErrorString() { return $this->errorString; } /** * Set download speed in bytes per second * * @param int $bytesPerSecond * * @throws \InvalidArgumentException When an integer is not provided as the parameter */ public function setDownloadSpeed($bytesPerSecond) { if (is_int($bytesPerSecond) && $bytesPerSecond > -1) { $this->downloadSpeed = $bytesPerSecond; } else { throw new \InvalidArgumentException(sprintf( 'Invalid torrent download speed provided. Download speed should be non-negative integer, "%s" given.', $bytesPerSecond )); } } /** * Get download speed in bytes per second * * @return int */ public function getDownloadSpeed() { return $this->downloadSpeed; } /** * Set upload speed in bytes per second * * @param int $bytesPerSecond * * @throws \InvalidArgumentException When an integer is not provided as the parameter */ public function setUploadSpeed($bytesPerSecond) { if (is_int($bytesPerSecond) && $bytesPerSecond > -1) { $this->uploadSpeed = $bytesPerSecond; } else { throw new \InvalidArgumentException(sprintf( 'Invalid torrent upload speed provided. Upload speed should be non-negative integer, "%s" given.', $bytesPerSecond )); } } /** * Get download speed in bytes per second * * @return int */ public function getUploadSpeed() { return $this->uploadSpeed; } /** * Set number of bytes downloaded * * @param int $numBytes * * @throws \InvalidArgumentException When an integer is not provided as the parameter * * @note Also sets the completion percentage and status to complete if 100% */ public function setBytesDownloaded($numBytes) { if (is_int($numBytes) && $numBytes > -1) { $this->bytesDownloaded = $numBytes; $size = $this->size; $percentDone = function() use ($size, $numBytes) { $size = ($size === 0) ? 1 : $size; $numBytes = ($size > $numBytes) ? $numBytes : 0; if ($size === 0 && $numBytes === 0) { return (float)0; } return (float)number_format(($numBytes / $size) * 100, 2, '.', ''); }; $this->percentDone = $percentDone(); if ($this->percentDone === 100 || $numBytes === $this->size) { $this->status = self::STATUS_COMPLETE; } } else { throw new \InvalidArgumentException(sprintf( 'Invalid torrent bytes downloaded provided. Amount should be non-negative integer, "%s" given.', $numBytes )); } } /** * Get number of bytes downloaded * * @return int */ public function getBytesDownloaded() { return $this->bytesDownloaded; } /** * Set number of bytes uploaded * * @param int $numBytes * * @throws \InvalidArgumentException * * @note Also sets the seed ratio percentage */ public function setBytesUploaded($numBytes) { if (is_int($numBytes) && $numBytes > -1) { $this->bytesUploaded = $numBytes; $downloaded = $this->bytesDownloaded; $seedRatio = function() use ($downloaded, $numBytes) { $downloaded = ($downloaded === 0) ? 1 : $downloaded; $numBytes = ($downloaded > $numBytes) ? $numBytes : 0; if ($downloaded === 0 && $numBytes === 0) { return (float)0; } return (float)number_format(($numBytes / $downloaded) * 100, 2, '.', ''); }; $this->seedRatio = $seedRatio(); } else { throw new \InvalidArgumentException(sprintf( 'Invalid torrent bytes uploaded provided. Amount should be non-negative integer, "%s" given.', $numBytes )); } } /** * Get number of bytes uploaded * * @return int */ public function getBytesUploaded() { return $this->bytesUploaded; } /** * Add a file to the torrent * * @param File $file */ public function addFile(File $file) { if (!in_array($file, $this->files)) { $this->files[] = $file; } } /** * Get the files list * * @return File[] */ public function getFiles() { return $this->files; } /** * Get a specific File by name * * @param string $name * * @throws FileNotFoundException When the file does not exist with the given name * * @return File The found file */ public function getFile($name) { $files = array_values(array_filter($this->files, function($file) use ($name) { /** @var File $file */ return strtolower($file->getName()) === strtolower($name); })); if (!empty($files)) { return $files[0]; } else { throw new FileNotFoundException(sprintf( 'File with name: "%s" not found for torrent: "%s"', $name, $this->name )); } } /** * Get whether or not the torrent has completed both downloading and seeding * * @return bool */ public function isComplete() { return ($this->status === self::STATUS_COMPLETE); } }
Output for 5.3.0 - 5.6.28, hhvm-3.10.0 - 3.12.0, 7.0.0 - 7.1.0