Issues (109)

src/EoC/Couch.php (46 issues)

1
<?php
2
3
/**
4
 * @file Couch.php
5
 * @brief This file contains the Couch class.
6
 * @details
7
 * @author Filippo F. Fadda
8
 */
9
10
//! This is the main Elephant on Couch library namespace.
11
namespace EoC;
12
13
14
use Surfer\Surfer;
15
use Surfer\Adapter\IClientAdapter;
16
use Surfer\Message\Request;
17
use Surfer\Message\Response;
18
use Surfer\Hook\IChunkHook;
19
20
use stdClass;
21
22
23
/**
24
 * @brief The CouchDB's client. You need an instance of this class to interact with CouchDB.
25
 * @nosubgrouping
26
 * @todo Add Memcached support. Remember to use Memcached extension, not memcache.
27
 * @todo Check ISO-8859-1 because CouchDB uses it, in particular utf8_encode().
28
 */
29
final class Couch extends Surfer {
30
31
  //! The user agent name.
32
  const USER_AGENT_NAME = "EoC Client";
33
34
  //! Default CouchDB revisions limit number.
35
  const REVS_LIMIT = 1000;
36
37
  /** @name Document Paths */
38
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
39
40
  const STD_DOC_PATH = ""; //!< Path for standard documents.
41
  const LOCAL_DOC_PATH = "_local/";  //!< Path for local documents.
42
  const DESIGN_DOC_PATH = "_design/";  //!< Path for design documents.
43
44
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
45
46
  // A database's name prefix.
47
  private $prefix = '';
48
49
50
  /**
51
   * @brief Creates a Couch class instance.
52
   * @param[in] IClientAdapter $adapter An instance of a class that implements the IClientAdapter interface.
53
   */
54
  public function __construct(IClientAdapter $adapter) {
55
    parent::__construct($adapter);
56
  }
57
58
59
  /**
60
   * @brief Returns a CouchDB wild card.
61
   * @details A standard object is translated to JSON as `{}` same of a JavaScript empty object.
62
   * @return stdClass
63
   */
64
  public static function WildCard() {
65
    return new stdClass();
66
  }
67
68
69
  /**
70
   * @brief Sets the document class and type in case the document hasn't one.
71
   * @param[in] Doc\IDoc $doc A document.
72
   */
73
  private function setDocInfo(Doc\IDoc $doc) {
74
    // Sets the class name.
75
    $class = get_class($doc);
76
    $doc->setClass($class);
77
78
    // Sets the document type.
79
    if (!$doc->hasType()) {
80
      preg_match('/([\w]+$)/', $class, $matches);
81
      $type = strtolower($matches[1]);
82
      $doc->setType($type);
83
    }
84
  }
85
86
87
  /**
88
   * @brief Overrides the rows, adding a new row for every key hasn't been matched.
89
   * @details CouchDB doesn't return rows for the keys a match is not found. To make joins having a row for each key is
90
   * essential. The algorithm below overrides the rows, adding a new row for every key hasn't been matched. The JSON
91
   * encoding is necessary because we might have complex keys. A complex key is no more than an array.
92
   * @param array $keys An array containing the keys.
93
   * @param[out] array $rows An associative array containing the rows.
94
   */
95
  private function addMissingRows(array $keys, &$rows) {
96
97
    if (!empty($keys) && isset($rows)) {
98
99
      // These are the rows for the matched keys.
100
      $matches = [];
101
      foreach ($rows as $row) {
102
        $hash = md5(json_encode($row['key']));
103
        $matches[$hash] = $row;
104
      }
105
106
      $allRows = [];
107
      foreach ($keys as $key) {
108
        $hash = md5(json_encode($key));
109
110
        if (isset($matches[$hash])) // Match found.
111
          $allRows[] = $matches[$hash];
112
        else // No match found.
113
          $allRows[] = ['id' => NULL, 'key' => $key, 'value' => NULL];
114
      }
115
116
      // Overrides the response, replacing rows.
117
      $rows = $allRows;
118
    }
119
120
  }
121
122
123
  /**
124
   * @brief Sets a prefix which is used to compose the database's name.
125
   * @param string $prefix A string prefix.
126
   */
127
  public function setDbPrefix($prefix) {
128
    $this->prefix = $prefix;
129
  }
130
131
132
  /**
133
   * @brief Gets the prefix used to compose the database's name if any.
134
   * @return string
135
   */
136
  public function getDbPrefix() {
137
    return $this->prefix;
138
  }
139
140
141
  /**
142
   * @brief This method is used to send a Request to CouchDB.
143
   * @details If you want call a not supported CouchDB API, you can use this function to send your request.\n
144
   * You can also provide an instance of a class that implements the IChunkHook interface, to deal with a chunked
145
   * response.
146
   * @param Request $request The Request object.
147
   * @param IChunkHook $chunkHook (optional) A class instance that implements the IChunkHook interface.
148
   * @return Response
149
   */
150
  public function send(Request $request, IChunkHook $chunkHook = NULL) {
151
    // Sets user agent information.
152
    $request->setHeaderField(Request::USER_AGENT_HF, self::USER_AGENT_NAME." ".Version::getNumber());
153
154
    // We accept JSON.
155
    $request->setHeaderField(Request::ACCEPT_HF, "application/json");
156
157
    // We close the connection after read the response.
158
    // NOTE: we don't use anymore the connection header field, because we use the same socket until the end of script.
159
    //$request->setHeaderField(Message::CONNECTION_HF, "close");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
160
161
    return parent::send($request, $chunkHook);
162
  }
163
164
165
  /** @name Validation and Encoding Methods */
166
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
167
168
  /**
169
   * @brief This method raise an exception when a user provide an invalid document path.
170
   * @details This method is called by any other methods that interacts with CouchDB. You don't need to call, unless
171
   * you are making a not supported call to CouchDB.
172
   * @param string $path Document path.
173
   * @param bool $excludeLocal Document path.
174
   */
175
  public function validateDocPath($path, $excludeLocal = FALSE) {
176
    if (empty($path)) // STD_DOC_PATH
177
      return;
178
179
    if ($path == self::DESIGN_DOC_PATH)
180
      return;
181
    elseif ($path == self::LOCAL_DOC_PATH && $excludeLocal)
182
      throw new \InvalidArgumentException("Local document doesn't have attachments.");
183
    else
184
      throw new \InvalidArgumentException("Invalid document path.");
185
  }
186
187
188
  /**
189
   * @brief Encodes the document id.
190
   * @details This method is called by any other methods that interacts with CouchDB. You don't need to call, unless
191
   * you are making a not supported call to CouchDB.
192
   * @param string $docId Document id.
193
   */
194
  public function validateAndEncodeDocId(&$docId) {
195
    if (!empty($docId))
196
      $docId = rawurlencode($docId);
197
    else
198
      throw new \InvalidArgumentException("\$docId must be a non-empty string.");
199
  }
200
201
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
202
203
204
  /** @name Miscellaneous Methods */
205
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
206
207
  /**
208
   * @brief Creates the admin user.
209
   * @todo Implement the method.
210
   */
211
  public function createAdminUser() {
212
    throw new \BadMethodCallException("The method `createAdminUser()` is not available.");
213
  }
214
215
216
  /**
217
   * @brief Restarts the server.
218
   * @attention Requires admin privileges.
219
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#restart
220
   * @bug [COUCHDB-947](https://issues.apache.org/jira/browse/COUCHDB-947)
221
   */
222
  public function restartServer() {
223
    $request = new Request(Request::POST_METHOD, "/_restart");
224
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
225
226
    // There is a bug in CouchDB, sometimes it doesn't return the 200 Status Code because it closes the connection
227
    // before the client has received the entire response. To avoid problems, we trap the exception and we go on.
228
    try {
229
      $this->send($request);
230
    }
231
    catch (\Exception $e) {
232
      if ($e->getCode() > 0)
233
        throw $e;
234
    }
235
  }
236
237
238
  /**
239
   * @brief Returns an object that contains MOTD, server and client and PHP versions.
240
   * @details The MOTD can be specified in CouchDB configuration files. This function returns more information
241
   * compared to the CouchDB standard REST call.
242
   * @return Info\ServerInfo
243
   */
244
  public function getServerInfo() {
245
    $response = $this->send(new Request(Request::GET_METHOD, "/"));
246
    $info = $response->getBodyAsArray();
247
    return new Info\ServerInfo($info["couchdb"], $info["version"]);
248
  }
249
250
251
  /**
252
   * @brief Returns information about the Elephant on Couch client.
253
   * @return Info\ClientInfo
254
   */
255
  public function getClientInfo() {
256
    return new Info\ClientInfo();
257
  }
258
259
260
  /**
261
   * @brief Returns the favicon.ico file.
262
   * @details The favicon is a part of the admin interface, but the handler for it is special as CouchDB tries to make
263
   * sure that the favicon is cached for one year. Returns a string that represents the icon.
264
   * @return string
265
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#favicon-ico
266
   */
267
  public function getFavicon() {
268
    $response = $this->send(new Request(Request::GET_METHOD, "/favicon.ico"));
269
270
    if ($response->getHeaderFieldValue(Request::CONTENT_TYPE_HF) == "image/x-icon")
271
      return $response->getBody();
272
    else
273
      throw new \InvalidArgumentException("Content-Type must be image/x-icon.");
274
  }
275
276
277
  /**
278
   * @brief Returns server statistics.
279
   * @return array An associative array
280
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#stats
281
   */
282
  public function getStats() {
283
    return $this->send(new Request(Request::GET_METHOD, "/_stats"))->getBodyAsArray();
284
  }
285
286
287
  /**
288
   * @brief Returns a list of all databases on this server.
289
   * @return array of string
290
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#all-dbs
291
   */
292
  public function getAllDbs() {
293
    return $this->send(new Request(Request::GET_METHOD, "/_all_dbs"))->getBodyAsArray();
294
  }
295
296
297
  /**
298
   * @brief Returns a list of all database events in the CouchDB instance.
299
   * @param Opt\DbUpdatesFeedOpts $opts Additional options.
300
   * @return array An associative array.
301
   * @attention Requires admin privileges.
302
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#db-updates
303
   */
304
  public function getDbUpdates(Opt\DbUpdatesFeedOpts $opts = NULL) {
305
    $request = new Request(Request::GET_METHOD, "/_db_updates");
306
307
    if (isset($opts))
308
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
309
310
    return $this->send($request)->getBodyAsArray();
311
  }
312
313
314
  /**
315
   * @brief Returns a list of running tasks.
316
   * @attention Requires admin privileges.
317
   * @return array An associative array.
318
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#active-tasks
319
   */
320
  public function getActiveTasks() {
321
    return $this->send(new Request(Request::GET_METHOD, "/_active_tasks"))->getBodyAsArray();
322
  }
323
324
325
  /**
326
   * @brief Returns the tail of the server's log file.
327
   * @attention Requires admin privileges.
328
   * @param integer $bytes How many bytes to return from the end of the log file.
329
   * @return string
330
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#log
331
   */
332
  public function getLogTail($bytes = 1000) {
333
    if (is_int($bytes) && ($bytes > 0)) {
334
      $request = new Request(Request::GET_METHOD, "/_log");
335
      $request->setQueryParam("bytes", $bytes);
336
      return $this->send($request)->getBody();
337
    }
338
    else
339
      throw new \InvalidArgumentException("\$bytes must be a positive integer.");
340
  }
341
342
343
  /**
344
   * @brief Returns a list of generated UUIDs.
345
   * @param integer $count Requested UUIDs number.
346
   * @return string|array If `$count == 1` (default) returns a string else returns an array of strings.
347
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#uuids
348
   */
349
  public function getUuids($count = 1) {
350
    if (is_int($count) && ($count > 0)) {
351
      $request = new Request(Request::GET_METHOD, "/_uuids");
352
      $request->setQueryParam("count", $count);
353
354
      $response = $this->send($request);
355
356
      if ($count == 1) // We don't need to use === operator because, just above, we made a type checking.
357
        return $response->getBodyAsArray()['uuids'][0];
358
      else
359
        return $response->getBodyAsArray()['uuids'];
360
    }
361
    else
362
      throw new \InvalidArgumentException("\$count must be a positive integer.");
363
  }
364
365
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
366
367
368
  /** @name Server Configuration Methods */
369
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
370
371
  /**
372
   * @brief Returns the entire server configuration or a single section or a single configuration value of a section.
373
   * @param string $section Requested section.
374
   * @param string $key Requested key.
375
   * @return string|array An array with the configuration keys or a simple string in case of a single key.
376
   * @see http://docs.couchdb.org/en/latest/api/server/configuration.html#get--_config
377
   * @see http://docs.couchdb.org/en/latest/api/server/configuration.html#get--_config-section
378
   * @see http://docs.couchdb.org/en/latest/api/server/configuration.html#config-section-key
379
   */
380
  public function getConfig($section = "", $key = "") {
381
    $path = "/_config";
382
383
    if (!empty($section)) {
384
      $path .= "/".$section;
385
386
      if (!empty($key))
387
        $path .= "/".$key;
388
    }
389
390
    return $this->send(new Request(Request::GET_METHOD, $path))->getBodyAsArray();
391
  }
392
393
394
  /**
395
   * @brief Sets a single configuration value in a given section to server configuration.
396
   * @param string $section The configuration section.
397
   * @param string $key The key.
398
   * @param string $value The value for the key.
399
   * @see http://docs.couchdb.org/en/latest/api/server/configuration.html#put--_config-section-key
400
   */
401
  public function setConfigKey($section, $key, $value) {
402
    if (!is_string($section) || empty($section))
0 ignored issues
show
The condition is_string($section) is always true.
Loading history...
403
      throw new \InvalidArgumentException("\$section must be a not empty string.");
404
405
    if (!is_string($key) || empty($key))
0 ignored issues
show
The condition is_string($key) is always true.
Loading history...
406
      throw new \InvalidArgumentException("\$key must be a not empty string.");
407
408
    if (is_null($value))
0 ignored issues
show
The condition is_null($value) is always false.
Loading history...
409
      throw new \InvalidArgumentException("\$value cannot be null.");
410
411
    $request = new Request(Request::PUT_METHOD, "/_config/".$section."/".$key);
412
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
413
    $request->setBody(json_encode(utf8_encode($value)));
414
    $this->send($request);
415
  }
416
417
418
  /**
419
   * @brief Deletes a single configuration value from a given section in server configuration.
420
   * @param string $section The configuration section.
421
   * @param string $key The key.
422
   * @see http://docs.couchdb.org/en/latest/api/configuration.html#delete-config-section-key
423
   */
424
  public function deleteConfigKey($section, $key) {
425
    if (!is_string($section) || empty($section))
0 ignored issues
show
The condition is_string($section) is always true.
Loading history...
426
      throw new \InvalidArgumentException("\$section must be a not empty string.");
427
428
    if (!is_string($key) || empty($key))
0 ignored issues
show
The condition is_string($key) is always true.
Loading history...
429
      throw new \InvalidArgumentException("\$key must be a not empty string.");
430
431
    $this->send(new Request(Request::DELETE_METHOD, "/_config/".$section."/".$key));
432
  }
433
434
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
435
436
437
  /** @name Cookie Authentication */
438
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
439
440
  /**
441
   * @brief Returns cookie based login user information.
442
   * @return Response
443
   * @see http://docs.couchdb.org/en/latest/api/server/authn.html#get--_session
444
   */
445
  public function getSession() {
446
    return $this->send(new Request(Request::GET_METHOD, "/_session"));
447
  }
448
449
450
  /**
451
   * @brief Makes cookie based user login.
452
   * @return Response
453
   * @see http://docs.couchdb.org/en/latest/api/server/authn.html#post--_session
454
   */
455
  public function setSession($userName, $password) {
456
    if (!is_string($userName) || empty($userName))
457
      throw new \InvalidArgumentException("\$userName must be a not empty string.");
458
459
    if (!is_string($password) || empty($password))
460
      throw new \InvalidArgumentException("\$password must be a not empty string.");
461
462
    $request = new Request(Request::POST_METHOD, "/_session");
463
464
    $request->setHeaderField(Request::X_COUCHDB_WWW_AUTHENTICATE_HF, "Cookie");
465
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/x-www-form-urlencoded");
466
467
    $request->setQueryParam("name", $userName);
468
    $request->setQueryParam("password", $password);
469
470
    return $this->send($request);
471
  }
472
473
474
  /**
475
   * @brief Makes user logout.
476
   * @return Response
477
   * @see http://docs.couchdb.org/en/latest/api/server/authn.html#delete--_session
478
   */
479
  public function deleteSession() {
480
    return $this->send(new Request(Request::DELETE_METHOD, "/_session"));
481
  }
482
483
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
484
485
486
  /** @name OAuth Authentication */
487
  //! @see http://docs.couchdb.org/en/latest/api/server/authn.html#oauth-authentication
488
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
489
490
  /**
491
   * @brief
492
   * @todo To be implemented and documented.
493
   */
494
  public function getAccessToken() {
495
    return $this->send(new Request(Request::GET_METHOD, "/_oauth/access_token"));
496
  }
497
498
499
  /**
500
   * @brief
501
   * @todo To be implemented and documented.
502
   */
503
  public function getAuthorize() {
504
    return $this->send(new Request(Request::GET_METHOD, "/_oauth/authorize"));
505
  }
506
507
508
  /**
509
   * @brief
510
   * @todo To be implemented and documented.
511
   */
512
  public function setAuthorize() {
513
    return $this->send(new Request(Request::POST_METHOD, "/_oauth/authorize"));
514
  }
515
516
517
  /**
518
   * @brief
519
   * @todo To be implemented and documented.
520
   */
521
  public function requestToken() {
522
    return $this->send(new Request(Request::GET_METHOD, "/_oauth/request_token"));
523
  }
524
525
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
526
527
528
  /**
529
   * @brief Creates a new database and selects it.
530
   * @param string $name The database name. A database must be named with all lowercase letters (a-z),
531
   * digits (0-9), or any of the _$()+-/ characters and must end with a slash in the URL. The name has to start with a
532
   * lowercase letter (a-z).
533
   * @see http://docs.couchdb.org/en/latest/api/database/common.html#put--db
534
   */
535
  public function createDb($name) {
536
    # \A[a-z][a-z\d_$()+-/]++\z
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
537
    #
538
    # Assert position at the beginning of the string «\A»
539
    # Match a single character in the range between “a” and “z” «[a-z]»
540
    # Match a single character present in the list below «[a-z\d_$()+-/]++»
541
    #    Between one and unlimited times, as many times as possible, without giving back (possessive) «++»
542
    #    A character in the range between “a” and “z” «a-z»
543
    #    A single digit 0..9 «\d»
544
    #    One of the characters “_$()” «_$()»
545
    #    A character in the range between “+” and “/” «+-/»
546
    # Assert position at the very end of the string «\z»
547
    if (preg_match('%\A[a-z][a-z\d_$()+-/]++\z%', $name) === FALSE)
548
      throw new \InvalidArgumentException("Invalid database name.");
549
550
    $this->send(new Request(Request::PUT_METHOD, "/".rawurlencode($this->prefix.$name)."/"));
551
  }
552
553
554
  /**
555
   * @brief Deletes an existing database.
556
   * @param string $name The database name.
557
   * @see http://docs.couchdb.org/en/latest/api/database/common.html#delete--db
558
   */
559
  public function deleteDb($name) {
560
    $this->send(new Request(Request::DELETE_METHOD, "/".rawurlencode($this->prefix.$name)));
561
  }
562
563
564
  /**
565
   * @brief Returns information about the selected database.
566
   * @param string $name The database name.
567
   * @return Info\Dbinfo
568
   * @see http://docs.couchdb.org/en/latest/api/database/common.html#get--db
569
   */
570
  public function getDbInfo($name) {
571
    return new Info\Dbinfo($this->send(new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$name)."/"))->getBodyAsArray());
572
  }
573
574
575
  /**
576
   * @brief Obtains a list of the changes made to the database. This can be used to monitor for update and modifications
577
   * to the database for post processing or synchronization.
578
   * @param string $name The database name.
579
   * @param Opt\ChangesFeedOpts $opts Additional options.
580
   * @return Response
581
   * @see http://docs.couchdb.org/en/latest/api/database/changes.html
582
   */
583
  public function getDbChanges($name, Opt\ChangesFeedOpts $opts = NULL) {
584
    $request = new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$name)."/_changes");
585
586
    if (isset($opts))
587
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
588
589
    return $this->send($request);
590
  }
591
592
593
  /**
594
   * @brief Starts a compaction for the current selected database.
595
   * @details Writes a new version of the database file, removing any unused sections from the new version during write.
596
   * Because a new file is temporary created for this purpose, you will need twice the current storage space of the
597
   * specified database in order for the compaction routine to complete.\n
598
   * Removes old revisions of documents from the database, up to the per-database limit specified by the `_revs_limit`
599
   * database setting.\n
600
   * Compaction can only be requested on an individual database; you cannot compact all the databases for a CouchDB
601
   * instance.\n
602
   * The compaction process runs as a background process. You can determine if the compaction process is operating on a
603
   * database by obtaining the database meta information, the `compact_running` value of the returned database
604
   * structure will be set to true. You can also obtain a list of running processes to determine whether compaction is
605
   * currently running, using getActiveTasks().
606
   * @param string $name The database name.
607
   * @attention Requires admin privileges.
608
   * @see http://docs.couchdb.org/en/latest/api/database/compact.html
609
   */
610
  public function compactDb($name) {
611
    $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$name)."/_compact");
612
613
    // A POST method requires Content-Type header.
614
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
615
616
    $this->send($request);
617
  }
618
619
620
  /**
621
   * @brief Compacts the specified view.
622
   * @details If you have very large views or are tight on space, you might consider compaction as well. To run compact
623
   * for a particular view on a particular database, use this method.
624
   * @param string $dbName The database name.
625
   * @param string $designDocName Name of the design document where is stored the view.
626
   * @see http://docs.couchdb.org/en/latest/api/database/compact.html#db-compact-design-doc
627
   */
628
  public function compactView($dbName, $designDocName) {
629
    $path = "/".rawurlencode($this->prefix.$dbName)."/_compact/".$designDocName;
630
631
    $request = new Request(Request::POST_METHOD, $path);
632
633
    // A POST method requires Content-Type header.
634
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
635
636
    $this->send($request);
637
  }
638
639
640
  /**
641
   * @brief Removes all outdated view indexes.
642
   * @details Old views files remain on disk until you explicitly run cleanup.
643
   * @param string $dbName The database name.
644
   * @attention Requires admin privileges.
645
   * @see http://docs.couchdb.org/en/latest/api/database/compact.html#db-view-cleanup
646
   */
647
  public function cleanupViews($dbName) {
648
    $request =  new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_view_cleanup");
649
650
    // A POST method requires Content-Type header.
651
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
652
653
    $this->send($request);
654
  }
655
656
657
  /**
658
   * @brief Makes sure all uncommited database changes are written and synchronized to the disk.
659
   * @details Default CouchDB configuration use delayed commit to improve performances. So CouchDB allows operations to
660
   * be run against the disk without an explicit fsync after each operation. Synchronization takes time (the disk may
661
   * have to seek, on some platforms the hard disk cache buffer is flushed, etc.), so requiring an fsync for each update
662
   * deeply limits CouchDB's performance for non-bulk writers.\n
663
   * Delayed commit should be left set to true in the configuration settings. Anyway, you can still tell CouchDB to make
664
   * an fsync, calling the this method.
665
   * @param string $dbName The database name.
666
   * @return string The timestamp of the last time the database file was opened.
667
   * @see http://docs.couchdb.org/en/latest/api/database/compact.html#db-ensure-full-commit
668
   */
669
  public function ensureFullCommit($dbName) {
670
    $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_ensure_full_commit");
671
672
    // A POST method requires Content-Type header.
673
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
674
675
    return $this->send($request)->getBodyAsArray()["instance_start_time"];
676
  }
677
678
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
679
680
681
  /**
682
   * @name Security Methods
683
   * @details The security object consists of two compulsory elements, admins and members, which are used to specify
684
   * the list of users and/or roles that have admin and members rights to the database respectively:
685
   * - members: they can read all types of documents from the DB, and they can write (and edit) documents to the
686
   * database except for design documents.
687
   * - admins: they have all the privileges of members plus the privileges: write (and edit) design documents, add/remove
688
   * database admins and members, set the database revisions limit and execute temporary views against the database.
689
   * They can not create a database nor delete a database.
690
   *
691
   * Both members and admins objects are contains two array-typed fields:
692
   * - users: List of CouchDB user names
693
   * - roles: List of users roles
694
   *
695
   * Any other additional fields in the security object are optional. The entire security object is made available to
696
   * validation and other internal functions so that the database can control and limit functionality.
697
   * If both the names and roles fields of either the admins or members properties are empty arrays, it means the
698
   * database has no admins or members.\n
699
   * Having no admins, only server admins (with the reserved _admin role) are able to update design document and make
700
   * other admin level changes.\n
701
   * Having no members, any user can write regular documents (any non-design document) and read documents from the database.
702
   * If there are any member names or roles defined for a database, then only authenticated users having a matching name
703
   * or role are allowed to read documents from the database.
704
   */
705
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
706
707
  /**
708
   * @brief Returns the special security object for the database.
709
   * @param string $dbName The database name.
710
   * @return array An associative array.
711
   * @see http://docs.couchdb.org/en/latest/api/database/security.html#get--db-_security
712
   */
713
  public function getSecurityObj($dbName) {
714
    return $this->send(new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_security"))->getBodyAsArray();
715
  }
716
717
718
  /**
719
   * @brief Sets the special security object for the database.
720
   * @param string $dbName The database name.
721
   * @see http://docs.couchdb.org/en/latest/api/database/security.html#put--db-_security
722
   */
723
  public function setSecurityObj($dbName) {
724
    return $this->send(new Request(Request::PUT_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_security"));
725
  }
726
727
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
728
729
730
  /**
731
   * @name Database Replication Methods
732
   * @details The replication is an incremental one way process involving two databases (a source and a destination).
733
   * The aim of the replication is that at the end of the process, all active documents on the source database are also
734
   * in the destination database and all documents that were deleted in the source databases are also deleted (if
735
   * exists) on the destination database.\n
736
   * The replication process only copies the last revision of a document, so all previous revisions that were only on
737
   * the source database are not copied to the destination database.\n
738
   * Changes on the master will not automatically replicate to the slaves. To make replication continuous, you must set
739
   * `$continuous = true`. At this time, CouchDB does not remember continuous replications over a server restart.
740
   * Specifying a local source database and a remote target database is called push replication and a remote source and
741
   * local target is called pull replication. As of CouchDB 0.9, pull replication is a lot more efficient and resistant
742
   * to errors, and it is suggested that you use pull replication in most cases, especially if your documents are large
743
   * or you have large attachments.
744
   */
745
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
746
747
  /**
748
   * @brief Starts replication.
749
   @code
750
     startReplication("sourcedbname", "http://example.org/targetdbname", TRUE, TRUE);
751
   @endcode
752
   * @param string $sourceDbUrl Source database URL.
753
   * @param string $targetDbUrl Destination database URL.
754
   * @param string $proxy (optional) Specify the optional proxy used to perform the replication.
755
   * @param bool $createTargetDb (optional) The target database has to exist and is not implicitly created. You
756
   * can force the creation setting `$createTargetDb = true`.
757
   * @param bool $continuous (optional) When `true` CouchDB will not stop after replicating all missing documents
758
   * from the source to the target.\n
759
   * At the time of writing, CouchDB doesn't remember continuous replications over a server restart. For the time being,
760
   * you are required to trigger them again when you restart CouchDB. In the future, CouchDB will allow you to define
761
   * permanent continuous replications that survive a server restart without you having to do anything.
762
   * @param string|array $filter (optional) Name of a filter function that can choose which revisions get replicated.
763
   * You can also provide an array of document identifiers; if given, only these documents will be replicated.
764
   * @param Opt\ViewQueryOpts $opts (optional) Query options to get additional information, grouping results, include
765
   * docs, etc.
766
   * @return Response
767
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#post--_replicate
768
   */
769
  public function startReplication($sourceDbUrl, $targetDbUrl, $proxy = NULL, $createTargetDb = TRUE,
770
                                     $continuous = FALSE, $filter = NULL, Opt\ViewQueryOpts $opts = NULL) {
771
    // Sets source and target databases.
772
    if (is_string($sourceDbUrl) && !empty($sourceDbUrl) &&
773
      is_string($targetDbUrl) && !empty($targetDbUrl)) {
774
      $body["source"] = $sourceDbUrl;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$body was never initialized. Although not strictly required by PHP, it is generally a good practice to add $body = array(); before regardless.
Loading history...
775
      $body["target"] = $targetDbUrl;
776
    }
777
    else
778
      throw new \InvalidArgumentException("\$source_db_url and \$target_db_url must be non-empty strings.");
779
780
    if (!is_bool($continuous))
0 ignored issues
show
The condition is_bool($continuous) is always true.
Loading history...
781
      throw new \InvalidArgumentException("\$continuous must be a bool.");
782
    elseif ($continuous)
783
      $body["continuous"] = $continuous;
784
785
    // Uses the specified proxy if any set.
786
    if (isset($proxy))
787
      $body["proxy"] = $proxy;
788
789
    // create_target option
790
    if (!is_bool($createTargetDb))
0 ignored issues
show
The condition is_bool($createTargetDb) is always true.
Loading history...
791
      throw new \InvalidArgumentException("\$createTargetDb must be a bool.");
792
    elseif ($createTargetDb)
793
      $body["create_target"] = $createTargetDb;
794
795
    if (!empty($filter)) {
796
      if (is_string($filter)) // filter option
797
        $body["filter"] = $filter;
798
      elseif (is_array($filter)) // doc_ids option
0 ignored issues
show
The condition is_array($filter) is always true.
Loading history...
799
        $body["doc_ids"] = array_values($filter);
800
      else
801
        throw new \InvalidArgumentException("\$filter must be a string or an array.");
802
    }
803
804
    // queryParams option
805
    if (!is_null($opts)) {
806
      if ($opts instanceof Opt\ViewQueryOpts)
0 ignored issues
show
$opts is always a sub-type of EoC\Opt\ViewQueryOpts.
Loading history...
807
        $body["query_params"] = get_object_vars($opts);
808
      else
809
        throw new \InvalidArgumentException("\$queryParams must be an instance of ViewQueryOpts class.");
810
    }
811
812
    $request = new Request(Request::POST_METHOD, "/_replicate");
813
    $request->setBody($body);
814
815
    return $this->send($request);
816
  }
817
818
819
  /**
820
   * @brief Cancels replication.
821
   * @param string $replicationId The replication ID.
822
   * @return Response
823
   * @see http://docs.couchdb.org/en/latest/api/server/common.html#canceling-continuous-replication
824
   */
825
  public function stopReplication($replicationId) {
826
    if (is_null($replicationId))
0 ignored issues
show
The condition is_null($replicationId) is always false.
Loading history...
827
      throw new \InvalidArgumentException("You must provide a replication id.");
828
829
    $body["replication_id"] = $replicationId;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$body was never initialized. Although not strictly required by PHP, it is generally a good practice to add $body = array(); before regardless.
Loading history...
830
    $body["cancel"] = TRUE;
831
832
    $request = new Request(Request::POST_METHOD, "/_replicate");
833
    $request->setBody($body);
834
835
    return $this->send($request);
836
  }
837
838
839
  /**
840
   * @brief
841
   * @details
842
   * @see http://wiki.apache.org/couchdb/Replication#Replicator_database
843
   * @see http://docs.couchbase.org/couchdb-release-1.1/index.html#couchb-release-1.1-replicatordb
844
   * @see https://gist.github.com/832610
845
   * @todo To be implemented and documented.
846
   */
847
  public function getReplicator() {
848
    throw new \BadMethodCallException("The method `getReplicator()` is not available.");
849
  }
850
851
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
852
853
854
  /** @name Query Documents Methods
855
   * @details Queries are the primary mechanism for retrieving a result set from a view. The result of a query is an
856
   * instance of `QueryResult`, a class that implements the [IteratorAggregate](http://php.net/manual/en/class.iteratoraggregate.php),
857
   * [Countable](http://php.net/manual/en/class.countable.php) and [ArrayAccess](http://php.net/manual/en/class.arrayaccess.php)
858
   * interfaces, so you can use the result set as an array.
859
   */
860
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
861
862
  /**
863
   * @brief Returns a built-in view of all documents in this database. If keys are specified returns only certain rows.
864
   * @param string $dbName The database name.
865
   * @param array $keys (optional) Used to retrieve just the view rows matching that set of keys. Rows are returned
866
   * in the order of the specified keys. Combining this feature with Opt\ViewQueryOpts.includeDocs() results in the so-called
867
   * multi-document-fetch feature.
868
   * @param Opt\ViewQueryOpts $opts (optional) Query options to get additional information, grouping results, include
869
   * docs, etc.
870
   * @param IChunkHook $chunkHook (optional) A class instance that implements the IChunkHook interface.
871
   * @return Result\QueryResult The result of the query.
872
   * @see http://docs.couchdb.org/en/latest/api/database/bulk-api.html#get--db-_all_docs
873
   * @see http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs
874
   */
875
  public function queryAllDocs($dbName, array $keys = NULL, Opt\ViewQueryOpts $opts = NULL, IChunkHook $chunkHook = NULL) {
876
    if (is_null($keys))
877
      $request = new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_all_docs");
878
    else {
879
      $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_all_docs");
880
      $request->setBody(json_encode(['keys' => $keys]));
881
    }
882
883
    if (isset($opts))
884
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
885
886
    $result = $this->send($request, $chunkHook)->getBodyAsArray();
887
888
    return new Result\QueryResult($result);
889
  }
890
891
892
  /**
893
   * @brief Executes the given view and returns the result.
894
   * @param string $dbName The database name.
895
   * @param string $designDocName The design document's name.
896
   * @param string $viewName The view's name.
897
   * @param array $keys (optional) Used to retrieve just the view rows matching that set of keys. Rows are returned
898
   * in the order of the specified keys. Combining this feature with Opt\ViewQueryOpts.includeDocs() results in the so-called
899
   * multi-document-fetch feature.
900
   * @param Opt\ViewQueryOpts $opts (optional) Query options to get additional information, grouping results, include
901
   * docs, etc.
902
   * @param IChunkHook $chunkHook (optional) A class instance that implements the IChunkHook interface.
903
   * @return Result\QueryResult The result of the query.
904
   * @attention Multiple keys request to a reduce function only supports `group=true` (identical to `group-level=exact`,
905
   * but it doesn't support `group_level` > 0.
906
   * CouchDB raises "Multi-key fetchs for reduce view must include `group=true`" error, in case you use `group_level`.
907
   * @see http://docs.couchdb.org/en/latest/api/ddoc/views.html#get--db-_design-ddoc-_view-view
908
   * @see http://docs.couchdb.org/en/latest/api/ddoc/views.html#post--db-_design-ddoc-_view-view
909
   */
910
  public function queryView($dbName, $designDocName, $viewName, array $keys = NULL, Opt\ViewQueryOpts $opts = NULL, IChunkHook $chunkHook = NULL) {
911
    $this->validateAndEncodeDocId($designDocName);
912
913
    if (empty($viewName))
914
      throw new \InvalidArgumentException("You must provide a valid \$viewName.");
915
916
    if (empty($keys))
917
      $request = new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_design/".$designDocName."/_view/".$viewName);
918
    else {
919
      $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_design/".$designDocName."/_view/".$viewName);
920
      $request->setBody(json_encode(['keys' => $keys]));
921
    }
922
923
    // Required since CouchDB 2.0.
924
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
925
926
    if (isset($opts)) {
927
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
928
      $includeMissingKeys = $opts->issetIncludeMissingKeys();
929
    }
930
    else
931
      $includeMissingKeys = FALSE;
932
933
    $result = $this->send($request, $chunkHook)->getBodyAsArray();
934
935
    if ($includeMissingKeys)
936
      $this->addMissingRows($keys, $result['rows']);
0 ignored issues
show
It seems like $keys can also be of type null; however, parameter $keys of EoC\Couch::addMissingRows() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

936
      $this->addMissingRows(/** @scrutinizer ignore-type */ $keys, $result['rows']);
Loading history...
937
938
    return new Result\QueryResult($result);
939
  }
940
941
942
  /**
943
   * @brief Executes the given view, both map and reduce functions, for all documents and returns the result.
944
   * @details Map and Reduce functions are provided by the programmer.
945
   * @attention Requires admin privileges.
946
   * @param string $dbName The database name.
947
   * @param string $mapFn The map function.
948
   * @param string $reduceFn The reduce function.
949
   * @param array $keys (optional) Used to retrieve just the view rows matching that set of keys. Rows are returned
950
   * in the order of the specified keys. Combining this feature with Opt\ViewQueryOpts.includeDocs() results in the so-called
951
   * multi-document-fetch feature.
952
   * @param Opt\ViewQueryOpts $opts (optional) Query options to get additional information, grouping results, include
953
   * docs, etc.
954
   * @param string $language The language used to implement the map and reduce functions.
955
   * @param IChunkHook $chunkHook (optional) A class instance that implements the IChunkHook interface.
956
   * @return Result\QueryResult The result of the query.
957
   * @see http://docs.couchdb.org/en/latest/api/database/temp-views.html#post--db-_temp_view
958
   */
959
  public function queryTempView($dbName, $mapFn, $reduceFn = "", array $keys = NULL, Opt\ViewQueryOpts $opts = NULL, $language = 'php', IChunkHook $chunkHook = NULL) {
960
    $handler = new Handler\ViewHandler('temp');
961
    $handler->language = $language;
962
    $handler->mapFn = $mapFn;
963
    if (!empty($reduce))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $reduce does not exist. Did you maybe mean $reduceFn?
Loading history...
964
      $handler->reduceFn = $reduceFn;
965
966
    $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_temp_view");
967
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
968
969
    $array = $handler->asArray();
970
971
    if (!empty($keys))
972
      $array['keys'] = $keys;
973
974
    $request->setBody(json_encode($array));
975
976
    if (isset($opts)) {
977
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
978
      $includeMissingKeys = $opts->issetIncludeMissingKeys();
979
    }
980
    else
981
      $includeMissingKeys = FALSE;
982
983
    $result = $this->send($request, $chunkHook)->getBodyAsArray();
984
985
    if ($includeMissingKeys)
986
      $this->addMissingRows($keys, $result['rows']);
0 ignored issues
show
It seems like $keys can also be of type null; however, parameter $keys of EoC\Couch::addMissingRows() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

986
      $this->addMissingRows(/** @scrutinizer ignore-type */ $keys, $result['rows']);
Loading history...
987
988
    return new Result\QueryResult($result);
989
  }
990
991
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
992
993
994
  /** @name Revisions Management Methods */
995
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
996
997
  /**
998
   * @brief Given a list of document revisions, returns the document revisions that do not exist in the database.
999
   * @param string $dbName The database name.
1000
   * @return Response
1001
   * @see http://docs.couchdb.org/en/latest/api/database/misc.html#db-missing-revs
1002
   */
1003
  public function getMissingRevs($dbName) {
1004
    $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_missing_revs");
1005
1006
    return $this->send($request);
1007
  }
1008
1009
1010
  /**
1011
   * @brief Given a list of document revisions, returns differences between the given revisions and ones that are in
1012
   * the database.
1013
   * @param string $dbName The database name.
1014
   * @return Response
1015
   * @see http://docs.couchdb.org/en/latest/api/database/misc.html#db-revs-diff
1016
   */
1017
  public function getRevsDiff($dbName) {
1018
    $request = new Request(Request::POST_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_missing_revs");
1019
1020
    return $this->send($request);
1021
  }
1022
1023
1024
  /**
1025
   * @brief Gets the limit of historical revisions to store for a single document in the database.
1026
   * @param string $dbName The database name.
1027
   * @return integer The maximum number of document revisions that will be tracked by CouchDB.
1028
   * @see http://docs.couchdb.org/en/latest/api/database/misc.html#get--db-_revs_limit
1029
   */
1030
  public function getRevsLimit($dbName) {
1031
    $request = new Request(Request::GET_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_revs_limit");
1032
1033
    return (integer)$this->send($request)->getBody();
1034
  }
1035
1036
1037
  /**
1038
   * @brief Sets the limit of historical revisions for a single document in the database.
1039
   * @param string $dbName The database name.
1040
   * @param integer $revsLimit (optional) Maximum number historical revisions for a single document in the database.
1041
   * Must be a positive integer.
1042
   * @see http://docs.couchdb.org/en/latest/api/database/misc.html#put--db-_revs_limit
1043
   */
1044
  public function setRevsLimit($dbName, $revsLimit = self::REVS_LIMIT) {
1045
    if (!is_int($revsLimit) || ($revsLimit <= 0))
0 ignored issues
show
The condition is_int($revsLimit) is always true.
Loading history...
1046
      throw new \InvalidArgumentException("\$revsLimit must be a positive integer.");
1047
1048
    $request = new Request(Request::PUT_METHOD, "/".rawurlencode($this->prefix.$dbName)."/_revs_limit");
1049
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
1050
    $request->setBody(json_encode($revsLimit));
1051
1052
    $this->send($request);
1053
  }
1054
1055
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1056
1057
1058
  /** @name Documents Management Methods */
1059
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1060
1061
  /**
1062
   * @brief Returns the document's entity tag, that can be used for caching or optimistic concurrency control purposes.
1063
   * The ETag Header is simply the document's revision in quotes.
1064
   * @details This function is not available for special documents. To get information about a design document, use
1065
   * the special function getDesignDocInfo().
1066
   * @param string $dbName The database name.
1067
   * @param string $docId The document's identifier.
1068
   * @return string The document's revision.
1069
   * @see http://docs.couchdb.org/en/latest/api/document/common.html#db-doc
1070
   * @bug CouchDB ETag is
1071
   */
1072
  public function getDocEtag($dbName, $docId) {
1073
    $this->validateAndEncodeDocId($docId);
1074
1075
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$docId;
1076
1077
    $request = new Request(Request::HEAD_METHOD, $path);
1078
1079
    // CouchDB ETag is included between quotation marks.
1080
    return trim($this->send($request)->getHeaderFieldValue(Response::ETAG_HF), '"');
1081
  }
1082
1083
1084
  /**
1085
   * @brief Returns the latest revision of the document.
1086
   * @details Since CouchDB uses different paths to store special documents, you must provide the document type for
1087
   * design and local documents.
1088
   * @param string $dbName The database name.
1089
   * @param string $docId The document's identifier.
1090
   * @param string $path The document's path.
1091
   * @param string $rev (optional) The document's revision.
1092
   * @param Opt\DocOpts $opts Query options to get additional document information, like conflicts, attachments, etc.
1093
   * @return object|Response An instance of Doc, LocalDoc, DesignDoc or any subclass of Doc.
1094
   * @see http://docs.couchdb.org/en/latest/api/document/common.html#get--db-docid
1095
   */
1096
  public function getDoc($dbName, $path, $docId, $rev = NULL, Opt\DocOpts $opts = NULL) {
1097
    $this->validateDocPath($path);
1098
    $this->validateAndEncodeDocId($docId);
1099
1100
    $requestPath = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId;
1101
1102
    $request = new Request(Request::GET_METHOD, $requestPath);
1103
1104
    // Retrieves the specific revision of the document.
1105
    if (!empty($rev))
1106
      $request->setQueryParam("rev", (string)$rev);
1107
1108
    // If there are any options, add them to the request.
1109
    if (isset($opts)) {
1110
      $request->setMultipleQueryParamsAtOnce($opts->asArray());
1111
      $ignoreClass = $opts->issetIgnoreClass();
1112
    }
1113
    else
1114
      $ignoreClass = FALSE;
1115
1116
    $response = $this->send($request);
1117
    $body = $response->getBodyAsArray();
1118
1119
    // We use `class` metadata to store an instance of a specialized document class. We can have Article and Book classes,
1120
    // both derived from Doc, with special properties and methods. Instead to convert them, we store the class name in a
1121
    // special attribute called 'class' within the others metadata. So, once we retrieve the document, the client creates
1122
    // an instance of the class we provided when we saved the document; we never need to convert it.
1123
    if (!$ignoreClass && isset($body['class'])) { // Special document class inherited from Doc or LocalDoc.
1124
      $class = "\\".$body['class'];
1125
      $doc = new $class;
1126
    }
1127
    elseif ($path == self::DESIGN_DOC_PATH)
1128
      $doc = new Doc\DesignDoc;
1129
    else
1130
      $doc = NULL;
1131
1132
    if (is_object($doc)) {
1133
      $doc->assignArray($body);
1134
      return $doc;
1135
    }
1136
    else
1137
      return $response;
1138
  }
1139
1140
1141
  /**
1142
   * @brief Inserts or updates a document into the selected database.
1143
   * @details Whether the `$doc` has an id we use a different HTTP method. Using POST CouchDB generates an id for the doc,
1144
   * using PUT instead we need to specify one. We can still use the function getUuids() to ask CouchDB for some ids.
1145
   * This is an internal detail. You have only to know that CouchDB can generate the document id for you.
1146
   * @param string $dbName The database name.
1147
   * @param Doc\IDoc $doc The document you want insert or update.
1148
   * @param bool $batchMode (optional) You can write documents to the database at a higher rate by using the batch
1149
   * option. This collects document writes together in memory (on a user-by-user basis) before they are committed to
1150
   * disk. This increases the risk of the documents not being stored in the event of a failure, since the documents are
1151
   * not written to disk immediately.
1152
   * @see http://docs.couchdb.org/en/latest/api/document/common.html#put--db-docid
1153
   */
1154
  public function saveDoc($dbName, Doc\IDoc $doc, $batchMode = FALSE) {
1155
    // Whether the document has an id we use a different HTTP method. Using POST CouchDB generates an id for the doc
1156
    // using PUT we need to specify one. We can still use the function getUuids() to ask CouchDB for some ids.
1157
    if (!$doc->issetId())
1158
      $doc->setId(Generator\UUID::generate(Generator\UUID::UUID_RANDOM, Generator\UUID::FMT_STRING));
1159
1160
    $this->setDocInfo($doc);
1161
1162
    // We never use the POST method.
1163
    $method = Request::PUT_METHOD;
1164
1165
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$doc->getPath().$doc->getId();
1166
1167
    $request = new Request($method, $path);
1168
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
1169
    $request->setBody($doc->asJson());
1170
1171
    // Enables batch mode.
1172
    if ($batchMode)
1173
      $request->setQueryParam("batch", "ok");
1174
1175
    $this->send($request);
1176
  }
1177
1178
1179
  /**
1180
   * @brief Deletes the specified document.
1181
   * @details To delete a document you must provide the document identifier and the revision number.
1182
   * @param string $dbName The database name.
1183
   * @param string $docId The document's identifier you want delete.
1184
   * @param string $rev The document's revision number you want delete.
1185
   * @param string $path The document path.
1186
   * @see http://docs.couchdb.org/en/latest/api/document/common.html#delete--db-docid
1187
   */
1188
  public function deleteDoc($dbName, $path, $docId, $rev) {
1189
    $this->validateDocPath($path);
1190
    $this->validateAndEncodeDocId($docId);
1191
1192
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId;
1193
1194
    $request = new Request(Request::DELETE_METHOD, $path);
1195
    $request->setQueryParam("rev", (string)$rev);
1196
1197
    // We could use another technique to send the revision number. Here just for documentation.
1198
    // $request->setHeader(Request::IF_MATCH_HEADER, (string)$rev);
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1199
1200
    $this->send($request);
1201
  }
1202
1203
1204
  /**
1205
   * @brief Makes a duplicate of the specified document. If you want to overwrite an existing document, you need to
1206
   * specify the target document's revision with a `$rev` parameter.
1207
   * @details If you want copy a special document you must specify his type.
1208
   * @param string $dbName The database name.
1209
   * @param string $sourceDocId The source document id.
1210
   * @param string $targetDocId The destination document id.
1211
   * @param string $rev Needed when you want override an existent document.
1212
   * @param string $path The document path.
1213
   * @see http://docs.couchdb.org/en/latest/api/document/common.html#copy--db-docid
1214
   */
1215
  public function copyDoc($dbName, $path, $sourceDocId, $targetDocId, $rev = NULL) {
1216
    $this->validateDocPath($path);
1217
1218
    $this->validateAndEncodeDocId($sourceDocId);
1219
    $this->validateAndEncodeDocId($targetDocId);
1220
1221
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$sourceDocId;
1222
1223
    // This request uses the special method COPY.
1224
    $request = new Request(Request::COPY_METHOD, $path);
1225
1226
    if (empty($rev))
1227
      $request->setHeaderField(Request::DESTINATION_HF, $targetDocId);
1228
    else
1229
      $request->setHeaderField(Request::DESTINATION_HF, $targetDocId."?rev=".(string)$rev);
1230
1231
    $this->send($request);
1232
  }
1233
1234
1235
  /**
1236
   * @brief The purge operation removes the references to the deleted documents from the database.
1237
   * @details A database purge permanently removes the references to deleted documents from the database. Deleting a
1238
   * document within CouchDB does not actually remove the document from the database, instead, the document is marked
1239
   * as deleted (and a new revision is created). This is to ensure that deleted documents are replicated to other
1240
   * databases as having been deleted. This also means that you can check the status of a document and identify that
1241
   * the document has been deleted.\n
1242
   * The purging of old documents is not replicated to other databases. If you are replicating between databases and
1243
   * have deleted a large number of documents you should run purge on each database.\n
1244
   * Purging documents does not remove the space used by them on disk. To reclaim disk space, you should run compactDb().\n
1245
   * @param string $dbName The database name.
1246
   * @param array $refs An array of references used to identify documents and revisions to delete. The array must
1247
   * contains instances of the DocRef class.
1248
   * @return Response
1249
   * @see http://docs.couchdb.org/en/latest/api/database/misc.html#post--db-_purge
1250
   * @see http://wiki.apache.org/couchdb/Purge_Documents
1251
   */
1252
  public function purgeDocs($dbName, array $refs) {
1253
    $path = "/".rawurlencode($this->prefix.$dbName)."/_purge";
1254
1255
    $request = new Request(Request::POST_METHOD, $path);
1256
1257
    $purge = [];
1258
    foreach ($refs as $ref)
1259
      $purge[] = $ref->asArray();
1260
1261
    $request->setBody(json_encode($purge));
1262
1263
    return $this->send($request);
1264
  }
1265
1266
1267
  /**
1268
   * @brief Inserts, updates and deletes documents in a bulk.
1269
   * @details Documents that are updated or deleted must contain the `rev` number. To delete a document, you should
1270
   * call delete() method on your document. When creating new documents the document ID is optional. For updating existing
1271
   * documents, you must provide the document ID and revision.
1272
   * @param string $dbName The database name.
1273
   * @param array $docs An array of documents you want insert, delete or update.
1274
   * @param bool $fullCommit (optional) Makes sure all uncommited database changes are written and synchronized
1275
   * to the disk immediately.
1276
   * @param bool $allOrNothing (optional) In all-or-nothing mode, either all documents are written to the database,
1277
   * or no documents are written to the database, in the event of a system failure during commit.\n
1278
   * You can ask CouchDB to check that all the documents pass your validation functions. If even one fails, none of the
1279
   * documents are written. If all documents pass validation, then all documents will be updated, even if that introduces
1280
   * a conflict for some or all of the documents.
1281
   * @param bool $newEdits (optional) When `false` CouchDB pushes existing revisions instead of creating
1282
   * new ones. The response will not include entries for any of the successful revisions (since their rev IDs are
1283
   * already known to the sender), only for the ones that had errors. Also, the conflict error will never appear,
1284
   * since in this mode conflicts are allowed.
1285
   * @return Response
1286
   * @see http://docs.couchdb.org/en/latest/api/database/bulk-api.html#db-bulk-docs
1287
   * @see http://docs.couchdb.org/en/latest/json-structure.html#bulk-documents
1288
   * @see http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
1289
   */
1290
  public function performBulkOperations($dbName, array $docs, $fullCommit = FALSE, $allOrNothing = FALSE, $newEdits = TRUE) {
1291
    if (count($docs) == 0)
1292
      throw new \InvalidArgumentException("The \$docs array cannot be empty.");
1293
    else
1294
      $operations = [];
1295
1296
    $path = "/".rawurlencode($this->prefix.$dbName)."/_bulk_docs";
1297
1298
    $request = new Request(Request::POST_METHOD, $path);
1299
    $request->setHeaderField(Request::CONTENT_TYPE_HF, "application/json");
1300
1301
    if ($fullCommit)
1302
      $request->setHeaderField(Request::X_COUCHDB_FULL_COMMIT_HF, "full_commit");
1303
    else
1304
      $request->setHeaderField(Request::X_COUCHDB_FULL_COMMIT_HF, "delay_commit");
1305
1306
    if ($allOrNothing)
1307
      $operations['all_or_nothing'] = 'true';
1308
1309
    if (!$newEdits)
1310
      $operations['new_edits'] = 'false';
1311
1312
    foreach ($docs as $doc) {
1313
      $this->setDocInfo($doc);
1314
      $operations['docs'][] = $doc->asArray();
1315
    }
1316
1317
    $request->setBody(json_encode($operations));
1318
1319
    return $this->send($request);
1320
  }
1321
1322
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1323
1324
1325
  /** @name Attachments Management Methods */
1326
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1327
1328
1329
  /**
1330
   * @brief Returns the attachment revision.
1331
   * @param string $dbName The database name.
1332
   * @param string $fileName The attachment's name.
1333
   * @param string $docId The document's identifier.
1334
   * @param string $path The document's path.
1335
   * @param string $rev (optional) The document's revision.
1336
   * @return array An associative array.
1337
   * @see http://docs.couchdb.org/en/latest/api/document/attachments.html#db-doc-attachment
1338
   */
1339
  public function getAttachmentInfo($dbName, $fileName, $path, $docId, $rev = NULL) {
1340
    $this->validateDocPath($path, TRUE);
1341
    $this->validateAndEncodeDocId($docId);
1342
1343
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId."/".$fileName;
1344
1345
    $request = new Request(Request::HEAD_METHOD, $path);
1346
1347
    // In case we want retrieve a specific document revision.
1348
    if (!empty($rev))
1349
      $request->setQueryParam("rev", (string)$rev);
1350
1351
    return $this->send($request)->getHeaderAsArray();
1352
  }
1353
1354
1355
  /**
1356
   * @brief Retrieves the attachment from the specified document.
1357
   * @param string $dbName The database name.
1358
   * @param string $fileName The attachment's name.
1359
   * @param string $docId The document's identifier.
1360
   * @param string $path The document's path.
1361
   * @param string $rev (optional) The document's revision.
1362
   * @see http://docs.couchdb.org/en/latest/api/document/attachments.html#get--db-docid-attname
1363
   * @see http://docs.couchdb.org/en/latest/api/document/attachments.html#http-range-requests
1364
   * @todo Add support for Range request, using header "Range: bytes=0-12".
1365
   */
1366
  public function getAttachment($dbName, $fileName, $path, $docId, $rev = NULL) {
1367
    $this->validateDocPath($path, TRUE);
1368
    $this->validateAndEncodeDocId($docId);
1369
1370
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId."/".$fileName;
1371
1372
    $request = new Request(Request::GET_METHOD, $path);
1373
1374
    // In case we want retrieve a specific document revision.
1375
    if (!empty($rev))
1376
      $request->setQueryParam("rev", (string)$rev);
1377
1378
    return $this->send($request)->getBody();
1379
  }
1380
1381
1382
  /**
1383
   * @brief Inserts or updates an attachment to the specified document.
1384
   * @param string $dbName The database name.
1385
   * @param string $fileName The attachment's name.
1386
   * @param string $docId The document's identifier.
1387
   * @param string $path The document's path.
1388
   * @param string $rev (optional) The document's revision.
1389
   * @see http://docs.couchdb.org/en/latest/api/document/attachments.html#put--db-docid-attname
1390
   */
1391
  public function putAttachment($dbName, $fileName, $path, $docId, $rev = NULL) {
1392
    $this->validateDocPath($path, TRUE);
1393
    $this->validateAndEncodeDocId($docId);
1394
1395
    $attachment = Doc\Attachment\Attachment::fromFile($fileName);
1396
1397
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId."/".rawurlencode($attachment->getName());
1398
1399
    $request = new Request(Request::PUT_METHOD, $path);
1400
    $request->setHeaderField(Request::CONTENT_LENGTH_HF, $attachment->getContentLength());
1401
    $request->setHeaderField(Request::CONTENT_TYPE_HF, $attachment->getContentType());
1402
    $request->setBody(base64_encode($attachment->getData()));
1403
1404
    // In case of adding or updating an existence document.
1405
    if (!empty($rev))
1406
      $request->setQueryParam("rev", (string)$rev);
1407
1408
    return $this->send($request);
1409
  }
1410
1411
1412
  /**
1413
   * @brief Deletes an attachment from the document.
1414
   * @param string $dbName The database name.
1415
   * @param string $fileName The attachment's name.
1416
   * @param string $docId The document's identifier.
1417
   * @param string $path The document's path.
1418
   * @param string $rev The document's revision.
1419
   * @see http://docs.couchdb.org/en/latest/api/document/attachments.html#delete--db-docid-attname
1420
   */
1421
  public function deleteAttachment($dbName, $fileName, $path, $docId, $rev) {
1422
    $this->validateDocPath($path, TRUE);
1423
    $this->validateAndEncodeDocId($docId);
1424
1425
    $path = "/".rawurlencode($this->prefix.$dbName)."/".$path.$docId."/".rawurlencode($fileName);
1426
1427
    $request = new Request(Request::DELETE_METHOD, $path);
1428
    $request->setQueryParam("rev", (string)$rev);
1429
1430
    return $this->send($request);
1431
  }
1432
1433
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1434
1435
1436
  /** @name Special Design Documents Management Methods */
1437
  //!@{
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1438
1439
1440
  /**
1441
   * @brief Returns basic information about the design document and his views.
1442
   * @param string $dbName The database name.
1443
   * @param string $docName The design document's name.
1444
   * @return array An associative array
1445
   * @see http://docs.couchdb.org/en/latest/api/ddoc/common.html#get--db-_design-ddoc-_info
1446
   */
1447
  public function getDesignDocInfo($dbName, $docName) {
1448
    $this->validateAndEncodeDocId($docName);
1449
1450
    $path = "/".rawurlencode($this->prefix.$dbName)."/".self::DESIGN_DOC_PATH.$docName."/_info";
1451
1452
    $request = new Request(Request::GET_METHOD, $path);
1453
1454
    return $this->send($request)->getBodyAsArray();
1455
  }
1456
1457
  //!@}
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1458
1459
}