Passed
Push — master ( 357df8...5617f0 )
by Georges
02:00 queued 12s
created

Driver::encodeDocument()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 11
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 file.
10
 *
11
 * @author Khoa Bui (khoaofgod)  <[email protected]> https://www.phpfastcache.com
12
 * @author Georges.L (Geolim4)  <[email protected]>
13
 *
14
 */
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Drivers\Couchbase;
18
19
use Couchbase\Exception as CouchbaseException;
20
use Couchbase\PasswordAuthenticator;
21
use Couchbase\Bucket as CouchbaseBucket;
22
use Couchbase\Cluster as CouchbaseClient;
23
use DateTime;
24
use Phpfastcache\Cluster\AggregatablePoolInterface;
25
use Phpfastcache\Core\Pool\{DriverBaseTrait, ExtendedCacheItemPoolInterface};
26
use Phpfastcache\Config\ConfigurationOption;
27
use Phpfastcache\Entities\DriverStatistic;
28
use Phpfastcache\Exceptions\{PhpfastcacheDriverCheckException, PhpfastcacheInvalidArgumentException, PhpfastcacheLogicException};
29
use Psr\Cache\CacheItemInterface;
30
31
32
/**
33
 * Class Driver
34
 * @package phpFastCache\Drivers
35
 * @property CouchbaseClient $instance Instance of driver service
36
 * @property Config $config Config object
37
 * @method Config getConfig() Return the config object
38
 */
39
class Driver implements ExtendedCacheItemPoolInterface, AggregatablePoolInterface
40
{
41
    use DriverBaseTrait {
42
        __construct as __baseConstruct;
43
    }
44
45
    /**
46
     * @var CouchbaseBucket[]
47
     */
48
    protected $bucketInstances = [];
49
50
    /**
51
     * @var CouchbaseBucket
52
     */
53
    protected $bucketInstance;
54
55
    /**
56
     * @var string
57
     */
58
    protected $currentBucket = '';
59
60
    public function __construct(ConfigurationOption $config, $instanceId)
61
    {
62
        // @todo Deprecation to enable in v8.1
63
        // \trigger_error('Couchbase driver is now deprecated and will be removed in the V9, use Couchbasev3 instead which will support SDK 3.', \E_USER_DEPRECATED);
64
        $this->__baseConstruct($config, $instanceId);
65
    }
66
67
    /**
68
     * @return bool
69
     */
70
    public function driverCheck(): bool
71
    {
72
        return extension_loaded('couchbase');
73
    }
74
75
    /**
76
     * @return DriverStatistic
77
     */
78
    public function getStats(): DriverStatistic
79
    {
80
        $info = $this->getBucket()->manager()->info();
81
82
        return (new DriverStatistic())
83
            ->setSize($info['basicStats']['diskUsed'])
84
            ->setRawData($info)
85
            ->setData(implode(', ', array_keys($this->itemInstances)))
86
            ->setInfo(
87
                'CouchBase version ' . $info['nodes'][0]['version'] . ', Uptime (in days): ' . round(
88
                    $info['nodes'][0]['uptime'] / 86400,
89
                    1
90
                ) . "\n For more information see RawData."
91
            );
92
    }
93
94
    /**
95
     * @return bool
96
     * @throws PhpfastcacheLogicException
97
     */
98
    protected function driverConnect(): bool
99
    {
100
        if (\class_exists(\Couchbase\ClusterOptions::class)) {
0 ignored issues
show
Bug introduced by
The type Couchbase\ClusterOptions 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...
101
            throw new PhpfastcacheDriverCheckException('You are using the Couchbase PHP SDK 3.x so please use driver Couchbasev3');
102
        }
103
104
        if ($this->instance instanceof CouchbaseClient) {
0 ignored issues
show
introduced by
$this->instance is always a sub-type of Couchbase\Cluster.
Loading history...
105
            throw new PhpfastcacheLogicException('Already connected to Couchbase server');
106
        }
107
108
        $clientConfig = $this->getConfig();
109
110
        $authenticator = new PasswordAuthenticator();
111
        $authenticator->username($clientConfig->getUsername())->password($clientConfig->getPassword());
112
113
        $this->instance = new CouchbaseClient(
114
            'couchbase://' . $clientConfig->getHost() . ($clientConfig->getPort() ? ":{$clientConfig->getPort()}" : '')
115
        );
116
117
        $this->instance->authenticate($authenticator);
118
        $this->setBucket($this->instance->openBucket($clientConfig->getBucketName()));
119
120
        return true;
121
    }
122
123
    /**
124
     * @param CouchbaseBucket $CouchbaseBucket
125
     */
126
    protected function setBucket(CouchbaseBucket $CouchbaseBucket)
127
    {
128
        $this->bucketInstance = $CouchbaseBucket;
129
    }
130
131
    /**
132
     * @param CacheItemInterface $item
133
     * @return null|array
134
     */
135
    protected function driverRead(CacheItemInterface $item)
136
    {
137
        try {
138
            /**
139
             * CouchbaseBucket::get() returns a CouchbaseMetaDoc object
140
             */
141
            return $this->decodeDocument((array) $this->getBucket()->get($item->getEncodedKey())->value);
142
        } catch (CouchbaseException $e) {
143
            return null;
144
        }
145
    }
146
147
    /**
148
     * @return CouchbaseBucket
149
     */
150
    protected function getBucket(): CouchbaseBucket
151
    {
152
        return $this->bucketInstance;
153
    }
154
155
    /**
156
     * @param CacheItemInterface $item
157
     * @return bool
158
     * @throws PhpfastcacheInvalidArgumentException
159
     */
160
    protected function driverWrite(CacheItemInterface $item): bool
161
    {
162
        /**
163
         * Check for Cross-Driver type confusion
164
         */
165
        if ($item instanceof Item) {
166
            try {
167
                return (bool)$this->getBucket()->upsert(
168
                    $item->getEncodedKey(),
169
                    $this->encodeDocument($this->driverPreWrap($item)),
170
                    ['expiry' => $item->getTtl()]
171
                );
172
            } catch (CouchbaseException $e) {
173
                return false;
174
            }
175
        }
176
177
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
178
    }
179
180
    /**
181
     * @param CacheItemInterface $item
182
     * @return bool
183
     * @throws PhpfastcacheInvalidArgumentException
184
     */
185
    protected function driverDelete(CacheItemInterface $item): bool
186
    {
187
        /**
188
         * Check for Cross-Driver type confusion
189
         */
190
        if ($item instanceof Item) {
191
            try {
192
                return (bool)$this->getBucket()->remove($item->getEncodedKey());
193
            } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type Phpfastcache\Drivers\Couchbase\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
194
                return $e->getCode() === COUCHBASE_KEY_ENOENT;
195
            }
196
        }
197
198
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
199
    }
200
201
    /**
202
     * @param array $data
203
     * @return array
204
     */
205
    protected function encodeDocument(array $data): array
206
    {
207
        $data[ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX] = $this->encode($data[ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX]);
208
        $data[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX] = $data[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX]->format(\DateTime::ATOM);
209
210
        if($this->getConfig()->isItemDetailedDate()){
211
            $data[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX] = $data[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX]->format(\DateTime::ATOM);
212
            $data[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX] = $data[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX]->format(\DateTime::ATOM);
213
        }
214
215
        return $data;
216
    }
217
218
    /**
219
     * @param array $data
220
     * @return array
221
     */
222
    protected function decodeDocument(array $data): array
223
    {
224
        $data[ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX] = $this->decode($data[ExtendedCacheItemPoolInterface::DRIVER_DATA_WRAPPER_INDEX]);
225
        $data[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX] = \DateTime::createFromFormat(
226
            \DateTime::ATOM,
227
            $data[ExtendedCacheItemPoolInterface::DRIVER_EDATE_WRAPPER_INDEX]
228
        );
229
230
        if($this->getConfig()->isItemDetailedDate()){
231
            $data[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX] = \DateTime::createFromFormat(
232
                \DateTime::ATOM,
233
                $data[ExtendedCacheItemPoolInterface::DRIVER_CDATE_WRAPPER_INDEX]
234
            );
235
236
            $data[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX] = \DateTime::createFromFormat(
237
                \DateTime::ATOM,
238
                $data[ExtendedCacheItemPoolInterface::DRIVER_MDATE_WRAPPER_INDEX]
239
            );
240
        }
241
242
        return $data;
243
    }
244
    /********************
245
     *
246
     * PSR-6 Extended Methods
247
     *
248
     *******************/
249
250
    /**
251
     * @return bool
252
     */
253
    protected function driverClear(): bool
254
    {
255
        $this->getBucket()->manager()->flush();
256
        return true;
257
    }
258
}
259