diff --git a/src/Model/Repository.php b/src/Model/Repository.php index 6129aab..a82ebb8 100644 --- a/src/Model/Repository.php +++ b/src/Model/Repository.php @@ -4,8 +4,18 @@ namespace Gitea\Model; use GuzzleHttp\Psr7\{Uri}; use Psr\Http\Message\{UriInterface}; +use Gitea\Collections\ApiItemCollection; +use Gitea\Model\Owner; +use Gitea\Api\Repositories; +use Gitea\Api\Branches; +use Gitea\Api\Tags; + +use \InvalidArgumentException; + +use Gitea\Model\Abstracts\AbstractApiModel; + /** Represents a repository. */ -class Repository implements \JsonSerializable { +class Repository extends AbstractApiModel { /** @var UriInterface|null The HTTP-based URL for cloning this repository. */ private $cloneUrl; @@ -78,12 +88,31 @@ class Repository implements \JsonSerializable { /** * Creates a new repository. + * @param object $giteaClient The Gitea client that originally made the request for this object's data + * @param object $apiRequester The Api requester that created this object * @param int $id The repository identifier. * @param string $fullName The full name of the repository. */ - function __construct(int $id, string $fullName, object $giteaClient = null) { - $this->id = $id; - $this->setFullName($fullName); + function __construct(object $giteaClient, object $apiRequester, ...$args) { + $this->setGiteaClient($giteaClient); + $this->setApiRequester($apiRequester); + if (count($args) >= 2) { + $id = $args[0]; + $fullName = $args[1]; + if (!is_int($id)) { + $argumentType = gettype($id); + throw new InvalidArgumentException("The \"construct()\" function requires the 3rd parameter to be of the integer type, but a \"$argumentType\" was passed in"); + } + if (!is_string($fullName)) { + $argumentType = gettype($fullName); + throw new InvalidArgumentException("The \"construct()\" function requires the 4th parameter to be of the string type, but a \"$argumentType\" was passed in"); + } + $this->id = $id; + $this->setFullName($fullName); + } else { + $numArgs = func_num_args(); + throw new InvalidArgumentException("The \"construct()\" function requires 4 parameters but only $numArgs were passed in"); + } } /** @@ -91,29 +120,36 @@ class Repository implements \JsonSerializable { * @param object $map A JSON map representing a repository. * @return static The instance corresponding to the specified JSON map. */ - static function fromJson(object $map): self { - return (new static(isset($map->id) && is_int($map->id) ? $map->id : -1, isset($map->full_name) && is_string($map->full_name) ? $map->full_name : '')) - ->setCloneUrl(isset($map->clone_url) && is_string($map->clone_url) ? new Uri($map->clone_url) : null) - ->setCreatedAt(isset($map->created_at) && is_string($map->created_at) ? new \DateTime($map->created_at) : null) - ->setDefaultBranch(isset($map->default_branch) && is_string($map->default_branch) ? $map->default_branch : '') - ->setDescription(isset($map->description) && is_string($map->description) ? $map->description : '') - ->setEmpty(isset($map->empty) && is_bool($map->empty) ? $map->empty : true) - ->setFork(isset($map->fork) && is_bool($map->fork) ? $map->fork : false) - ->setForksCount(isset($map->forks_count) && is_int($map->forks_count) ? $map->forks_count : 0) - ->setHtmlUrl(isset($map->html_url) && is_string($map->html_url) ? new Uri($map->html_url) : null) - ->setMirror(isset($map->mirror) && is_bool($map->mirror) ? $map->mirror : false) - ->setName(isset($map->name) && is_string($map->name) ? $map->name : '') - ->setOpenIssuesCount(isset($map->open_issues_count) && is_int($map->open_issues_count) ? $map->open_issues_count : 0) - ->setOwner(isset($map->owner) && is_object($map->owner) ? User::fromJson($map->owner) : null) - ->setParent(isset($map->parent) && is_object($map->parent) ? Repository::fromJson($map->parent) : null) - ->setPermissions(isset($map->permissions) && is_object($map->permissions) ? Permission::fromJson($map->permissions) : null) - ->setPrivate(isset($map->private) && is_bool($map->private) ? $map->private : false) - ->setSize(isset($map->size) && is_int($map->size) ? $map->size : 0) - ->setSshUrl(isset($map->ssh_url) && is_string($map->ssh_url) ? new Uri($map->ssh_url) : null) - ->setStarsCount(isset($map->stars_count) && is_int($map->stars_count) ? $map->stars_count : 0) - ->setUpdatedAt(isset($map->updated_at) && is_string($map->updated_at) ? new \DateTime($map->updated_at) : null) - ->setWatchersCount(isset($map->watchers_count) && is_int($map->watchers_count) ? $map->watchers_count : 0) - ->setWebsite(isset($map->website) && is_string($map->website) ? new Uri($map->website) : null); + static function fromJson(object $giteaClient, object $apiRequester, object $map): self { + return ( + new static( + $giteaClient, + $apiRequester, + isset($map->id) && is_int($map->id) ? $map->id : -1, + isset($map->full_name) && is_string($map->full_name) ? $map->full_name : '' + ) + ) + ->setCloneUrl(isset($map->clone_url) && is_string($map->clone_url) ? new Uri($map->clone_url) : null) + ->setCreatedAt(isset($map->created_at) && is_string($map->created_at) ? new \DateTime($map->created_at) : null) + ->setDefaultBranch(isset($map->default_branch) && is_string($map->default_branch) ? $map->default_branch : '') + ->setDescription(isset($map->description) && is_string($map->description) ? $map->description : '') + ->setEmpty(isset($map->empty) && is_bool($map->empty) ? $map->empty : true) + ->setFork(isset($map->fork) && is_bool($map->fork) ? $map->fork : false) + ->setForksCount(isset($map->forks_count) && is_int($map->forks_count) ? $map->forks_count : 0) + ->setHtmlUrl(isset($map->html_url) && is_string($map->html_url) ? new Uri($map->html_url) : null) + ->setMirror(isset($map->mirror) && is_bool($map->mirror) ? $map->mirror : false) + ->setName(isset($map->name) && is_string($map->name) ? $map->name : '') + ->setOpenIssuesCount(isset($map->open_issues_count) && is_int($map->open_issues_count) ? $map->open_issues_count : 0) + ->setOwner(isset($map->owner) && is_object($map->owner) ? Owner::fromJson($giteaClient, $apiRequester, $map->owner) : null) + ->setParent(isset($map->parent) && is_object($map->parent) ? Repository::fromJson($giteaClient, $apiRequester, $map->parent) : null) + ->setPermissions(isset($map->permissions) && is_object($map->permissions) ? Permission::fromJson($giteaClient, $apiRequester, $map->permissions) : null) + ->setPrivate(isset($map->private) && is_bool($map->private) ? $map->private : false) + ->setSize(isset($map->size) && is_int($map->size) ? $map->size : 0) + ->setSshUrl(isset($map->ssh_url) && is_string($map->ssh_url) ? new Uri($map->ssh_url) : null) + ->setStarsCount(isset($map->stars_count) && is_int($map->stars_count) ? $map->stars_count : 0) + ->setUpdatedAt(isset($map->updated_at) && is_string($map->updated_at) ? new \DateTime($map->updated_at) : null) + ->setWatchersCount(isset($map->watchers_count) && is_int($map->watchers_count) ? $map->watchers_count : 0) + ->setWebsite(isset($map->website) && is_string($map->website) ? new Uri($map->website) : null); } /** @@ -201,7 +237,7 @@ class Repository implements \JsonSerializable { * Gets the repository owner. * @return User|null The repository owner. */ - function getOwner(): ?User { + function getOwner(): ?Owner { return $this->owner; } @@ -320,7 +356,7 @@ class Repository implements \JsonSerializable { 'mirror' => $this->isMirror(), 'name' => $this->getName(), 'open_issues_count' => $this->getOpenIssuesCount(), - 'owner' => ($user = $this->getOwner()) ? $user->jsonSerialize() : null, + 'owner' => ($owner = $this->getOwner()) ? $owner->jsonSerialize() : null, 'parent' => ($repository = $this->getParent()) ? $repository->jsonSerialize() : null, 'permissions' => ($perms = $this->getPermissions()) ? $perms->jsonSerialize() : null, 'private' => $this->isPrivate(), @@ -458,7 +494,7 @@ class Repository implements \JsonSerializable { * @param User|null $value The new owner. * @return $this This instance. */ - function setOwner(?User $value): self { + function setOwner(?Owner $value): self { $this->owner = $value; return $this; } @@ -553,4 +589,57 @@ class Repository implements \JsonSerializable { return $this; } + /** + * Download the archive for the repository + * + * @author Benjamin Blake (sitelease.ca) + * + * @param string $gitRef The branch, tag, or commit SHA for the archive + * @param string $format The format of the downloaded archive (".zip", or ".tar.gz") + * @return string A string that can be written to a file + */ + public function archive(string $gitRef, string $format = ".tar.gz") + { + $owner = $this->getOwner(); + if ($owner) { + $client = $this->getGiteaClient(); + $repositoriesApi = new Repositories($client, $client->getAuthToken()); + return $repositoriesApi->downloadArchive($owner->getUsername(), $this->getName(), $gitRef, $format); + } + } + + /** + * Get all branches for this repository + * + * @author Benjamin Blake (sitelease.ca) + * + * @return ApiItemCollection + */ + public function branches() + { + $owner = $this->getOwner(); + if ($owner) { + $client = $this->getGiteaClient(); + $branchesApi = new Branches($client, $client->getAuthToken()); + return $branchesApi->fromRepository($owner->getUsername(), $this->getName()); + } + } + + /** + * Get all tags for this repository + * + * @author Benjamin Blake (sitelease.ca) + * + * @return ApiItemCollection + */ + public function tags() + { + $owner = $this->getOwner(); + if ($owner) { + $client = $this->getGiteaClient(); + $tagsApi = new Tags($client, $client->getAuthToken()); + return $tagsApi->fromRepository($owner->getUsername(), $this->getName()); + } + } + }