Skip to content

Commit

Permalink
feat: Model API after Google's Firestore PHP library (free docs!)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: new API
  • Loading branch information
morrislaptop committed Jun 8, 2018
1 parent e10c2b7 commit b6b5b7f
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 737 deletions.
451 changes: 0 additions & 451 deletions src/Collection.php

This file was deleted.

99 changes: 99 additions & 0 deletions src/CollectionReference.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace Morrislaptop\Firestore;

use Psr\Http\Message\UriInterface;
use Kreait\Firebase\Exception\ApiException;
use Kreait\Firebase\Database\Reference\Validator;
use Kreait\Firebase\Exception\OutOfRangeException;
use Kreait\Firebase\Exception\InvalidArgumentException;

/**
* A Reference represents a specific location in your database and can be used
* for reading or writing data to that database location.
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference
*/
class CollectionReference
{
/**
* @var UriInterface
*/
private $uri;

/**
* @var ApiClient
*/
private $apiClient;

/**
* @var Validator
*/
private $validator;

protected $valueMapper;

/**
* Creates a new Reference instance for the given URI which is accessed by
* the given API client and validated by the Validator (obviously).
*
* @param UriInterface $uri
* @param ApiClient $apiClient
* @param Validator|null $validator
*
* @throws InvalidArgumentException if the reference URI is invalid
*/
public function __construct(UriInterface $uri, ApiClient $apiClient, Validator $validator = null, ValueMapper $valueMapper = null)
{
$this->validator = $validator ?? new Validator();
$this->validator->validateUri($uri);

$this->valueMapper = $valueMapper ?? new ValueMapper(null, false);

$this->uri = $uri;
$this->apiClient = $apiClient;
$this->valueMapper = $valueMapper;
}

/**
* Gets a Reference for the location at the specified relative path.
*
* The relative path can either be a simple child name (for example, "ada")
* or a deeper slash-separated path (for example, "ada/name/first").
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#child
*
* @param string $path
*
* @throws InvalidArgumentException if the path is invalid
*
* @return Reference
*/
public function document(string $path): DocumentReference
{
$childPath = sprintf('%s/%s', trim($this->uri->getPath(), '/'), trim($path, '/'));

try {
return new DocumentReference($this->uri->withPath($childPath), $this->apiClient, $this->validator, $this->valueMapper);
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}

/**
* Remove the data at this database location.
*
* Any data at child locations will also be deleted.
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#remove
*
* @throws ApiException if the API reported an error
*
* @return Reference A new instance for the now empty Reference
*/
public function remove(): self
{
throw new \BadMethodCallException('Not implemented');
}

}
248 changes: 3 additions & 245 deletions src/Document.php → src/DocumentReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference
*/
class Document
class DocumentReference
{
/**
* @var UriInterface
Expand Down Expand Up @@ -57,248 +57,6 @@ public function __construct(UriInterface $uri, ApiClient $apiClient, Validator $
$this->apiClient = $apiClient;
}

/**
* The last part of the current path.
*
* For example, "ada" is the key for https://sample-app.firebaseio.com/users/ada.
*
* The key of the root Reference is null.
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#key
*
* @return string|null
*/
public function getKey()
{
$key = basename($this->getPath());

return '' !== $key ? $key : null;
}

/**
* Returns the full path to a reference.
*
* @return string
*/
public function getPath(): string
{
return trim($this->uri->getPath(), '/');
}

/**
* The parent location of a Reference.
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#parent
*
* @throws OutOfRangeException if requested for the root Reference
*
* @return Reference
*/
public function getParent(): self
{
$parentPath = \dirname($this->getPath());

if ('.' === $parentPath) {
throw new OutOfRangeException('Cannot get parent of root reference');
}

/* @noinspection ExceptionsAnnotatingAndHandlingInspection */
return new self($this->uri->withPath($parentPath), $this->apiClient, $this->validator);
}

/**
* The root location of a Reference.
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#root
*
* @return Reference
*/
public function getRoot(): self
{
/* @noinspection ExceptionsAnnotatingAndHandlingInspection */
return new self($this->uri->withPath('/'), $this->apiClient, $this->validator);
}

/**
* Gets a Reference for the location at the specified relative path.
*
* The relative path can either be a simple child name (for example, "ada")
* or a deeper slash-separated path (for example, "ada/name/first").
*
* @see https://firebase.google.com/docs/reference/js/firebase.database.Reference#child
*
* @param string $path
*
* @throws InvalidArgumentException if the path is invalid
*
* @return Reference
*/
public function getChild(string $path): self
{
$childPath = sprintf('%s/%s', trim($this->uri->getPath(), '/'), trim($path, '/'));

try {
return new self($this->uri->withPath($childPath), $this->apiClient, $this->validator);
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}

/**
* Generates a new Query object ordered by the specified child key.
*
* @see Query::orderByChild()
*
* @param string $path
*
* @return Query
*/
public function orderByChild(string $path): Query
{
/* @noinspection ExceptionsAnnotatingAndHandlingInspection */
return $this->query()->orderByChild($path);
}

/**
* Generates a new Query object ordered by key.
*
* @see Query::orderByKey()
*
* @return Query
*/
public function orderByKey(): Query
{
/* @noinspection ExceptionsAnnotatingAndHandlingInspection */
return $this->query()->orderByKey();
}

/**
* Generates a new Query object ordered by child values.
*
* @see Query::orderByValue()
*
* @return Query
*/
public function orderByValue(): Query
{
/* @noinspection ExceptionsAnnotatingAndHandlingInspection */
return $this->query()->orderByValue();
}

/**
* Generates a new Query limited to the first specific number of children.
*
* @see Query::limitToFirst()
*
* @param int $limit
*
* @return Query
*/
public function limitToFirst(int $limit): Query
{
return $this->query()->limitToFirst($limit);
}

/**
* Generates a new Query object limited to the last specific number of children.
*
* @see Query::limitToLast()
*
* @param int $limit
*
* @return Query
*/
public function limitToLast(int $limit): Query
{
return $this->query()->limitToLast($limit);
}

/**
* Creates a Query with the specified starting point.
*
* @see Query::startAt()
*
* @param int|float|string|bool $value $value
*
* @return Query
*/
public function startAt($value): Query
{
return $this->query()->startAt($value);
}

/**
* Creates a Query with the specified ending point.
*
* @see Query::endAt()
*
* @param int|float|string|bool $value
*
* @return Query
*/
public function endAt($value): Query
{
return $this->query()->endAt($value);
}

/**
* Creates a Query which includes children which match the specified value.
*
* @see Query::equalTo()
*
* @param int|float|string|bool $value
*
* @return Query
*/
public function equalTo($value): Query
{
return $this->query()->equalTo($value);
}

/**
* Creates a Query with shallow results.
*
* @see Query::shallow()
*
* @return Query
*/
public function shallow(): Query
{
return $this->query()->shallow();
}

/**
* Returns the keys of a reference's children.
*
* @throws OutOfRangeException if the reference has no children with keys
* @throws ApiException if the API reported an error
*
* @return string[]
*/
public function getChildKeys(): array
{
/** @noinspection ExceptionsAnnotatingAndHandlingInspection */
$snapshot = $this->shallow()->getSnapshot();

if (\is_array($value = $snapshot->getValue())) {
return array_keys($value);
}

throw new OutOfRangeException(sprintf('%s has no children with keys', $this));
}

/**
* Convenience method for {@see getSnapshot()}->getValue().
*
* @throws ApiException if the API reported an error
*
* @return mixed
*/
public function getValue()
{
return $this->getSnapshot()->getValue();
}

/**
* Write data to this database location.
*
Expand Down Expand Up @@ -342,13 +100,13 @@ public function set($value, $merge = false): self
*
* @return Snapshot
*/
public function getSnapshot(): Snapshot
public function snapshot(): DocumentSnapshot
{
$value = $this->apiClient->get($this->uri);

$data = $this->valueMapper->decodeValues($value['fields']);

return new Snapshot($this, [], $data, true);
return new DocumentSnapshot($this, [], $data, true);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Snapshot.php → src/DocumentSnapshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* $bitcoinWalletValue = $snapshot['wallet']['cryptoCurrency']['bitcoin'];
* ```
*/
class Snapshot implements \ArrayAccess
class DocumentSnapshot implements \ArrayAccess
{
/**
* @var DocumentReference
Expand Down Expand Up @@ -75,7 +75,7 @@ class Snapshot implements \ArrayAccess
* @param bool $exists Whether the document exists in the Firestore database.
*/
public function __construct(
Document $reference,
DocumentReference $reference,
array $info,
array $data,
$exists
Expand Down
Loading

0 comments on commit b6b5b7f

Please sign in to comment.