Passed
Push — v9 ( 473b89...c87345 )
by Georges
02:33
created

Driver::driverClear()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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