Passed
Push — master ( 4006b8...c871f9 )
by Georges
02:32 queued 21s
created

Driver::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 *
5
 * This file is part of Phpfastcache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files.
10
 *
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 * @author Contributors  https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Drivers\Firestore;
18
19
use Google\Cloud\Core\Blob as GoogleBlob;
0 ignored issues
show
Bug introduced by
The type Google\Cloud\Core\Blob was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Google\Cloud\Core\Timestamp as GoogleTimestamp;
0 ignored issues
show
Bug introduced by
The type Google\Cloud\Core\Timestamp was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Google\Cloud\Firestore\FirestoreClient as GoogleFirestoreClient;
0 ignored issues
show
Bug introduced by
The type Google\Cloud\Firestore\FirestoreClient was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Phpfastcache\Cluster\AggregatablePoolInterface;
23
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
24
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
25
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait;
26
use Phpfastcache\Entities\DriverStatistic;
27
use Phpfastcache\Exceptions\PhpfastcacheDriverConnectException;
28
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
29
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
30
31
/**
32
 * Class Driver
33
 * @method Config getConfig()
34
 * @property GoogleFirestoreClient $instance
35
 */
36
class Driver implements ExtendedCacheItemPoolInterface, AggregatablePoolInterface
37
{
38
    use TaggableCacheItemPoolTrait;
39
40
    /**
41
     * @return bool
42
     */
43
    public function driverCheck(): bool
44
    {
45
        return \class_exists(GoogleFirestoreClient::class) && \extension_loaded('grpc');
46
    }
47
48
    /**
49
     * @return bool
50
     * @throws PhpfastcacheDriverConnectException
51
     * @throws PhpfastcacheInvalidArgumentException
52
     * @throws PhpfastcacheLogicException
53
     */
54
    protected function driverConnect(): bool
55
    {
56
        $gcpId = $this->getConfig()->getSuperGlobalAccessor()('SERVER', 'GOOGLE_CLOUD_PROJECT');
57
        $gacPath = $this->getConfig()->getSuperGlobalAccessor()('SERVER', 'GOOGLE_APPLICATION_CREDENTIALS');
58
59
        if (empty($gcpId)) {
60
            throw new PhpfastcacheDriverConnectException('The environment configuration GOOGLE_CLOUD_PROJECT must be set');
61
        }
62
63
        if (empty($gacPath) || !\is_readable($gacPath)) {
64
            throw new PhpfastcacheDriverConnectException('The environment configuration GOOGLE_APPLICATION_CREDENTIALS must be set and the JSON file must be readable.');
65
        }
66
67
        $this->instance = new GoogleFirestoreClient();
68
69
        return true;
70
    }
71
72
    /**
73
     * @param ExtendedCacheItemInterface $item
74
     * @return bool
75
     */
76
    protected function driverWrite(ExtendedCacheItemInterface $item): bool
77
    {
78
        $this->instance->collection($this->getConfig()->getCollection())
79
            ->document($item->getKey())
80
            ->set(
81
                $this->driverPreWrap($item),
82
                ['merge' => true]
83
            );
84
85
        return true;
86
    }
87
88
    /**
89
     * @param ExtendedCacheItemInterface $item
90
     * @return null|array
91
     * @throws \Exception
92
     */
93
    protected function driverRead(ExtendedCacheItemInterface $item): ?array
94
    {
95
        $doc = $this->instance->collection($this->getConfig()->getCollection())
96
            ->document($item->getKey());
97
98
        $snapshotData = $doc->snapshot()->data();
99
100
        if (\is_array($snapshotData)) {
101
            return $this->decodeFirestoreDocument($snapshotData);
102
        }
103
104
        return null;
105
    }
106
107
    /**
108
     * @param ExtendedCacheItemInterface $item
109
     * @return bool
110
     */
111
    protected function driverDelete(ExtendedCacheItemInterface $item): bool
112
    {
113
        $this->instance->collection($this->getConfig()->getCollection())
114
            ->document($item->getKey())
115
            ->delete();
116
117
        return true;
118
    }
119
120
    /**
121
     * @return bool
122
     */
123
    protected function driverClear(): bool
124
    {
125
        $batchSize = 100;
126
        $collection = $this->instance->collection($this->getConfig()->getCollection());
127
        $documents = $collection->limit($batchSize)->documents();
128
        while (!$documents->isEmpty()) {
129
            foreach ($documents as $document) {
130
                $document->reference()->delete();
131
            }
132
            $documents = $collection->limit($batchSize)->documents();
133
        }
134
135
        return true;
136
    }
137
138
    protected function decodeFirestoreDocument(array $snapshotData): array
139
    {
140
        return \array_map(static function ($datum) {
141
            if ($datum instanceof GoogleTimestamp) {
142
                $date = $datum->get();
143
                if ($date instanceof \DateTimeImmutable) {
144
                    return \DateTime::createFromImmutable($date);
145
                }
146
                return $date;
147
            }
148
149
            if ($datum instanceof GoogleBlob) {
150
                return (string) $datum;
151
            }
152
153
            return $datum;
154
        }, $snapshotData);
155
    }
156
157
    public function getStats(): DriverStatistic
158
    {
159
        return (new DriverStatistic())
160
            ->setData(implode(', ', array_keys($this->itemInstances)))
161
            ->setInfo('No info provided by Google Firestore')
162
            ->setRawData([])
163
            ->setSize(0);
164
    }
165
}
166