Redis Object Cache - Version 1.0.2

Version Description

  • Added "Flush Cache" button
    • Added support for UNIX domain sockets
    • Improved cache object retrieval performance significantly
    • Updated bundled Predis library to version 1.0.1
Download this release

Release Info

Developer tillkruess
Plugin Icon 128x128 Redis Object Cache
Version 1.0.2
Comparing to
See all releases

Code changes from version 1.0.1 to 1.0.2

includes/admin-page.php CHANGED
@@ -10,7 +10,7 @@
10
  <table class="form-table">
11
 
12
  <tr valign="top">
13
- <th scope="row"><?php _e( 'Object Cache Status', 'redis-cache' ); ?></th>
14
  <td><code><?php echo $this->get_redis_status(); ?></code></td>
15
  </tr>
16
 
@@ -18,13 +18,24 @@
18
  <th scope="row"><?php _e( 'Connection Parameters', 'redis-cache' ); ?></th>
19
  <td>
20
  <p>
 
21
  <?php _e( 'Protocol:', 'redis-cache' ); ?> <code><?php echo strtoupper( esc_html( $this->get_redis_scheme() ) ); ?></code><br />
22
- <?php _e( 'Host:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_host() ); ?></code><br />
23
- <?php _e( 'Port:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_port() ); ?></code><br />
 
 
 
 
 
 
 
 
24
  <?php _e( 'Database:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_database() ); ?></code><br />
 
25
  <?php if ( ! is_null( $this->get_redis_password() ) ) : ?>
26
  <?php _e( 'Password:', 'redis-cache' ); ?> <code><?php echo str_repeat( '*', strlen( $this->get_redis_password() ) ); ?></code>
27
  <?php endif; ?>
 
28
  </p>
29
  </td>
30
  </tr>
@@ -32,11 +43,18 @@
32
  </table>
33
 
34
  <p class="submit">
 
 
 
 
 
 
35
  <?php if ( ! $this->object_cache_dropin_exists() ) : ?>
36
  <a href="<?php echo wp_nonce_url( admin_url( add_query_arg( 'action', 'enable-cache', $this->admin_page ) ), 'enable-cache' ); ?>" class="button button-primary button-large"><?php _e( 'Enable Object Cache', 'redis-cache' ); ?></a>
37
  <?php elseif ( $this->validate_object_cache_dropin() ) : ?>
38
  <a href="<?php echo wp_nonce_url( admin_url( add_query_arg( 'action', 'disable-cache', $this->admin_page ) ), 'disable-cache' ); ?>" class="button button-secondary button-large delete"><?php _e( 'Disable Object Cache', 'redis-cache' ); ?></a>
39
  <?php endif; ?>
 
40
  </p>
41
 
42
  </div>
10
  <table class="form-table">
11
 
12
  <tr valign="top">
13
+ <th scope="row"><?php _e( 'Redis Status', 'redis-cache' ); ?></th>
14
  <td><code><?php echo $this->get_redis_status(); ?></code></td>
15
  </tr>
16
 
18
  <th scope="row"><?php _e( 'Connection Parameters', 'redis-cache' ); ?></th>
19
  <td>
20
  <p>
21
+
22
  <?php _e( 'Protocol:', 'redis-cache' ); ?> <code><?php echo strtoupper( esc_html( $this->get_redis_scheme() ) ); ?></code><br />
23
+
24
+ <?php if ( strcasecmp( 'tcp', $this->get_redis_scheme() ) === 0 ) : ?>
25
+ <?php _e( 'Host:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_host() ); ?></code><br />
26
+ <?php _e( 'Port:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_port() ); ?></code><br />
27
+ <?php endif; ?>
28
+
29
+ <?php if ( strcasecmp( 'unix', $this->get_redis_scheme() ) === 0 ) : ?>
30
+ <?php _e( 'Path:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_path() ); ?></code><br />
31
+ <?php endif; ?>
32
+
33
  <?php _e( 'Database:', 'redis-cache' ); ?> <code><?php echo esc_html( $this->get_redis_database() ); ?></code><br />
34
+
35
  <?php if ( ! is_null( $this->get_redis_password() ) ) : ?>
36
  <?php _e( 'Password:', 'redis-cache' ); ?> <code><?php echo str_repeat( '*', strlen( $this->get_redis_password() ) ); ?></code>
37
  <?php endif; ?>
38
+
39
  </p>
40
  </td>
41
  </tr>
43
  </table>
44
 
45
  <p class="submit">
46
+
47
+ <?php if ( strcasecmp( 'connected', $this->get_redis_status() ) === 0 ) : ?>
48
+ <a href="<?php echo wp_nonce_url( admin_url( add_query_arg( 'action', 'flush-cache', $this->admin_page ) ), 'flush-cache' ); ?>" class="button button-primary button-large"><?php _e( 'Flush Cache', 'redis-cache' ); ?></a>
49
+ &nbsp;
50
+ <?php endif; ?>
51
+
52
  <?php if ( ! $this->object_cache_dropin_exists() ) : ?>
53
  <a href="<?php echo wp_nonce_url( admin_url( add_query_arg( 'action', 'enable-cache', $this->admin_page ) ), 'enable-cache' ); ?>" class="button button-primary button-large"><?php _e( 'Enable Object Cache', 'redis-cache' ); ?></a>
54
  <?php elseif ( $this->validate_object_cache_dropin() ) : ?>
55
  <a href="<?php echo wp_nonce_url( admin_url( add_query_arg( 'action', 'disable-cache', $this->admin_page ) ), 'disable-cache' ); ?>" class="button button-secondary button-large delete"><?php _e( 'Disable Object Cache', 'redis-cache' ); ?></a>
56
  <?php endif; ?>
57
+
58
  </p>
59
 
60
  </div>
includes/object-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
- Version: 1.0
7
  Author: Till Krüss
8
  Author URI: http://till.kruss.me/
9
  License: GPLv3
@@ -335,6 +335,10 @@ class WP_Object_Cache {
335
  $redis[ 'port' ] = WP_REDIS_PORT;
336
  }
337
 
 
 
 
 
338
  if ( defined( 'WP_REDIS_PASSWORD' ) ) {
339
  $redis[ 'password' ] = WP_REDIS_PASSWORD;
340
  }
@@ -537,22 +541,21 @@ class WP_Object_Cache {
537
  public function get( $key, $group = 'default' ) {
538
  $derived_key = $this->build_key( $key, $group );
539
 
540
- if ( in_array( $group, $this->no_redis_groups ) || ! $this->redis_status() ) {
541
- if ( isset( $this->cache[ $derived_key ] ) ) {
542
- $this->cache_hits++;
543
- return is_object( $this->cache[ $derived_key ] ) ? clone $this->cache[ $derived_key ] : $this->cache[ $derived_key ];
544
- } else {
545
- $this->cache_misses++;
546
- return false;
547
- }
548
  }
549
 
550
- if ( $this->redis->exists( $derived_key ) ) {
551
- $this->cache_hits++;
552
- $value = maybe_unserialize( $this->redis->get( $derived_key ) );
553
- } else {
554
- $this->cache_misses;
555
  return false;
 
 
 
556
  }
557
 
558
  $this->add_to_internal_cache( $derived_key, $value );
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
+ Version: 1.0.2
7
  Author: Till Krüss
8
  Author URI: http://till.kruss.me/
9
  License: GPLv3
335
  $redis[ 'port' ] = WP_REDIS_PORT;
336
  }
337
 
338
+ if ( defined( 'WP_REDIS_PATH' ) ) {
339
+ $redis[ 'path' ] = WP_REDIS_PATH;
340
+ }
341
+
342
  if ( defined( 'WP_REDIS_PASSWORD' ) ) {
343
  $redis[ 'password' ] = WP_REDIS_PASSWORD;
344
  }
541
  public function get( $key, $group = 'default' ) {
542
  $derived_key = $this->build_key( $key, $group );
543
 
544
+ if ( isset( $this->cache[ $derived_key ] ) ) {
545
+ $this->cache_hits++;
546
+ return is_object( $this->cache[ $derived_key ] ) ? clone $this->cache[ $derived_key ] : $this->cache[ $derived_key ];
547
+ } elseif ( in_array( $group, $this->no_redis_groups ) || ! $this->redis_status() ) {
548
+ $this->cache_misses++;
549
+ return false;
 
 
550
  }
551
 
552
+ $result = $this->redis->get( $derived_key );
553
+ if ($result == NULL) {
554
+ $this->cache_misses++;
 
 
555
  return false;
556
+ } else {
557
+ $this->cache_hits++;
558
+ $value = maybe_unserialize($result);
559
  }
560
 
561
  $this->add_to_internal_cache( $derived_key, $value );
includes/predis.php CHANGED
@@ -291,6 +291,33 @@ class ZSetRange extends Command
291
  }
292
  }
293
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  /**
295
  * @link http://redis.io/commands/sinter
296
  * @author Daniele Alessandri <suppakilla@gmail.com>
@@ -340,44 +367,47 @@ class ServerEval extends Command
340
  }
341
 
342
  /**
343
- * @link http://redis.io/commands/sinterstore
344
  * @author Daniele Alessandri <suppakilla@gmail.com>
345
  */
346
- class SetIntersectionStore extends Command
347
  {
348
  /**
349
  * {@inheritdoc}
350
  */
351
  public function getId()
352
  {
353
- return 'SINTERSTORE';
354
  }
 
355
 
 
 
 
 
 
 
356
  /**
357
  * {@inheritdoc}
358
  */
359
- protected function filterArguments(array $arguments)
360
  {
361
- if (count($arguments) === 2 && is_array($arguments[1])) {
362
- return array_merge(array($arguments[0]), $arguments[1]);
363
- }
364
-
365
- return $arguments;
366
  }
367
  }
368
 
369
  /**
370
- * @link http://redis.io/commands/rpush
371
  * @author Daniele Alessandri <suppakilla@gmail.com>
372
  */
373
- class ListPushTail extends Command
374
  {
375
  /**
376
  * {@inheritdoc}
377
  */
378
  public function getId()
379
  {
380
- return 'RPUSH';
381
  }
382
 
383
  /**
@@ -385,22 +415,19 @@ class ListPushTail extends Command
385
  */
386
  protected function filterArguments(array $arguments)
387
  {
388
- return self::normalizeVariadic($arguments);
389
- }
390
- }
391
 
392
- /**
393
- * @link http://redis.io/commands/ttl
394
- * @author Daniele Alessandri <suppakilla@gmail.com>
395
- */
396
- class KeyTimeToLive extends Command
397
- {
398
- /**
399
- * {@inheritdoc}
400
- */
401
- public function getId()
402
- {
403
- return 'TTL';
404
  }
405
  }
406
 
@@ -428,32 +455,17 @@ class KeyExpireAt extends Command
428
  }
429
 
430
  /**
431
- * @link http://redis.io/commands/rename
432
- * @author Daniele Alessandri <suppakilla@gmail.com>
433
- */
434
- class KeyRename extends Command
435
- {
436
- /**
437
- * {@inheritdoc}
438
- */
439
- public function getId()
440
- {
441
- return 'RENAME';
442
- }
443
- }
444
-
445
- /**
446
- * @link http://redis.io/commands/subscribe
447
  * @author Daniele Alessandri <suppakilla@gmail.com>
448
  */
449
- class PubSubSubscribe extends Command
450
  {
451
  /**
452
  * {@inheritdoc}
453
  */
454
  public function getId()
455
  {
456
- return 'SUBSCRIBE';
457
  }
458
 
459
  /**
@@ -461,22 +473,27 @@ class PubSubSubscribe extends Command
461
  */
462
  protected function filterArguments(array $arguments)
463
  {
464
- return self::normalizeArguments($arguments);
 
 
 
 
 
465
  }
466
  }
467
 
468
  /**
469
- * @link http://redis.io/commands/blpop
470
  * @author Daniele Alessandri <suppakilla@gmail.com>
471
  */
472
- class ListPopFirstBlocking extends Command
473
  {
474
  /**
475
  * {@inheritdoc}
476
  */
477
  public function getId()
478
  {
479
- return 'BLPOP';
480
  }
481
 
482
  /**
@@ -484,12 +501,7 @@ class ListPopFirstBlocking extends Command
484
  */
485
  protected function filterArguments(array $arguments)
486
  {
487
- if (count($arguments) === 2 && is_array($arguments[0])) {
488
- list($arguments, $timeout) = $arguments;
489
- array_push($arguments, $timeout);
490
- }
491
-
492
- return $arguments;
493
  }
494
  }
495
 
@@ -592,57 +604,111 @@ class ServerInfo extends Command
592
  }
593
 
594
  /**
595
- * @link http://redis.io/commands/zrangebyscore
596
  * @author Daniele Alessandri <suppakilla@gmail.com>
597
  */
598
- class ZSetRangeByScore extends ZSetRange
599
  {
600
  /**
601
  * {@inheritdoc}
602
  */
603
  public function getId()
604
  {
605
- return 'ZRANGEBYSCORE';
606
  }
607
 
608
  /**
609
- * {@inheritdoc}
 
 
610
  */
611
- protected function prepareOptions($options)
612
  {
613
- $opts = array_change_key_case($options, CASE_UPPER);
614
- $finalizedOpts = array();
 
615
 
616
- if (isset($opts['LIMIT']) && is_array($opts['LIMIT'])) {
617
- $limit = array_change_key_case($opts['LIMIT'], CASE_UPPER);
 
 
 
 
 
 
 
 
 
 
 
618
 
619
- $finalizedOpts[] = 'LIMIT';
620
- $finalizedOpts[] = isset($limit['OFFSET']) ? $limit['OFFSET'] : $limit[0];
621
- $finalizedOpts[] = isset($limit['COUNT']) ? $limit['COUNT'] : $limit[1];
622
- }
 
 
 
 
623
 
624
- return array_merge($finalizedOpts, parent::prepareOptions($options));
 
 
 
 
 
 
 
 
 
 
 
625
  }
626
 
627
  /**
628
  * {@inheritdoc}
629
  */
630
- protected function withScores()
631
  {
632
- $arguments = $this->getArguments();
 
 
633
 
634
- for ($i = 3; $i < count($arguments); $i++) {
635
- switch (strtoupper($arguments[$i])) {
636
- case 'WITHSCORES':
637
- return true;
 
 
 
 
 
 
 
 
 
638
 
639
- case 'LIMIT':
640
- $i += 2;
641
- break;
642
- }
643
- }
 
 
 
644
 
645
- return false;
 
 
 
 
 
 
 
 
 
 
 
646
  }
647
  }
648
 
@@ -712,67 +778,102 @@ class ZSetUnionStore extends Command
712
  }
713
 
714
  /**
715
- * @link http://redis.io/commands/mset
716
  * @author Daniele Alessandri <suppakilla@gmail.com>
717
  */
718
- class StringSetMultiple extends Command
719
  {
720
  /**
721
  * {@inheritdoc}
722
  */
723
  public function getId()
724
  {
725
- return 'MSET';
726
  }
727
 
728
  /**
729
  * {@inheritdoc}
730
  */
731
- protected function filterArguments(array $arguments)
732
  {
733
- if (count($arguments) === 1 && is_array($arguments[0])) {
734
- $flattenedKVs = array();
735
- $args = $arguments[0];
736
 
737
- foreach ($args as $k => $v) {
738
- $flattenedKVs[] = $k;
739
- $flattenedKVs[] = $v;
740
- }
741
 
742
- return $flattenedKVs;
 
 
743
  }
744
 
745
- return $arguments;
746
  }
747
- }
748
 
749
- /**
750
- * @link http://redis.io/commands/setex
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
751
  * @author Daniele Alessandri <suppakilla@gmail.com>
752
  */
753
- class StringSetExpire extends Command
754
  {
755
  /**
756
  * {@inheritdoc}
757
  */
758
  public function getId()
759
  {
760
- return 'SETEX';
761
  }
762
  }
763
 
764
  /**
765
- * @link http://redis.io/commands/expire
766
  * @author Daniele Alessandri <suppakilla@gmail.com>
767
  */
768
- class KeyExpire extends Command
769
  {
770
  /**
771
  * {@inheritdoc}
772
  */
773
  public function getId()
774
  {
775
- return 'EXPIRE';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
776
  }
777
 
778
  /**
@@ -785,95 +886,138 @@ class KeyExpire extends Command
785
  }
786
 
787
  /**
788
- * @link http://redis.io/commands/unsubscribe
789
  * @author Daniele Alessandri <suppakilla@gmail.com>
790
  */
791
- class PubSubUnsubscribe extends Command
792
  {
793
  /**
794
  * {@inheritdoc}
795
  */
796
  public function getId()
797
  {
798
- return 'UNSUBSCRIBE';
799
  }
800
 
801
  /**
802
  * {@inheritdoc}
803
  */
804
- protected function filterArguments(array $arguments)
805
  {
806
- return self::normalizeArguments($arguments);
807
  }
808
  }
809
 
810
  /**
811
- * @link http://redis.io/commands/evalsha
812
  * @author Daniele Alessandri <suppakilla@gmail.com>
813
  */
814
- class ServerEvalSHA extends ServerEval
815
  {
816
  /**
817
  * {@inheritdoc}
818
  */
819
  public function getId()
820
  {
821
- return 'EVALSHA';
822
  }
 
823
 
 
 
 
 
 
 
824
  /**
825
- * Returns the SHA1 hash of the body of the script.
826
- *
827
- * @return string SHA1 hash.
828
  */
829
- public function getScriptHash()
830
  {
831
- return $this->getArgument(0);
832
  }
833
  }
834
 
835
  /**
836
- * @link http://redis.io/commands/decr
837
  * @author Daniele Alessandri <suppakilla@gmail.com>
838
  */
839
- class StringDecrement extends Command
840
  {
841
  /**
842
  * {@inheritdoc}
843
  */
844
  public function getId()
845
  {
846
- return 'DECR';
847
  }
848
  }
849
 
850
  /**
851
- * @link http://redis.io/commands/decrby
852
  * @author Daniele Alessandri <suppakilla@gmail.com>
853
  */
854
- class StringDecrementBy extends Command
855
  {
856
  /**
857
  * {@inheritdoc}
858
  */
859
  public function getId()
860
  {
861
- return 'DECRBY';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
  }
863
  }
864
 
865
  /**
866
- * @link http://redis.io/commands/get
867
  * @author Daniele Alessandri <suppakilla@gmail.com>
868
  */
869
- class StringGet extends Command
870
  {
871
  /**
872
  * {@inheritdoc}
873
  */
874
  public function getId()
875
  {
876
- return 'GET';
877
  }
878
  }
879
 
@@ -922,62 +1066,62 @@ class StringBitCount extends Command
922
  }
923
 
924
  /**
925
- * @link http://redis.io/commands/sunionstore
926
  * @author Daniele Alessandri <suppakilla@gmail.com>
927
  */
928
- class SetUnionStore extends SetIntersectionStore
929
  {
930
  /**
931
  * {@inheritdoc}
932
  */
933
  public function getId()
934
  {
935
- return 'SUNIONSTORE';
936
  }
937
  }
938
 
939
  /**
940
- * @link http://redis.io/commands/append
941
  * @author Daniele Alessandri <suppakilla@gmail.com>
942
  */
943
- class StringAppend extends Command
944
  {
945
  /**
946
  * {@inheritdoc}
947
  */
948
  public function getId()
949
  {
950
- return 'APPEND';
951
  }
952
  }
953
 
954
  /**
955
- * @link http://redis.io/commands/getbit
956
  * @author Daniele Alessandri <suppakilla@gmail.com>
957
  */
958
- class StringGetBit extends Command
959
  {
960
  /**
961
  * {@inheritdoc}
962
  */
963
  public function getId()
964
  {
965
- return 'GETBIT';
966
  }
967
  }
968
 
969
  /**
970
- * @link http://redis.io/commands/mget
971
  * @author Daniele Alessandri <suppakilla@gmail.com>
972
  */
973
- class StringGetMultiple extends Command
974
  {
975
  /**
976
  * {@inheritdoc}
977
  */
978
  public function getId()
979
  {
980
- return 'MGET';
981
  }
982
 
983
  /**
@@ -985,140 +1129,213 @@ class StringGetMultiple extends Command
985
  */
986
  protected function filterArguments(array $arguments)
987
  {
988
- return self::normalizeArguments($arguments);
989
  }
990
  }
991
 
992
  /**
993
- * @link http://redis.io/commands/incrbyfloat
994
  * @author Daniele Alessandri <suppakilla@gmail.com>
995
  */
996
- class StringIncrementByFloat extends Command
997
  {
998
  /**
999
  * {@inheritdoc}
1000
  */
1001
  public function getId()
1002
  {
1003
- return 'INCRBYFLOAT';
1004
  }
1005
  }
1006
 
1007
  /**
1008
- * @link http://redis.io/commands/psetex
1009
  * @author Daniele Alessandri <suppakilla@gmail.com>
1010
  */
1011
- class StringPreciseSetExpire extends StringSetExpire
1012
  {
1013
  /**
1014
  * {@inheritdoc}
1015
  */
1016
  public function getId()
1017
  {
1018
- return 'PSETEX';
1019
  }
1020
- }
1021
 
1022
- /**
1023
- * @link http://redis.io/commands/incrby
1024
- * @author Daniele Alessandri <suppakilla@gmail.com>
1025
- */
1026
- class StringIncrementBy extends Command
1027
- {
1028
  /**
1029
  * {@inheritdoc}
1030
  */
1031
- public function getId()
1032
  {
1033
- return 'INCRBY';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1034
  }
1035
  }
1036
 
1037
  /**
1038
- * @link http://redis.io/commands/incr
1039
  * @author Daniele Alessandri <suppakilla@gmail.com>
1040
  */
1041
- class StringIncrement extends Command
1042
  {
1043
  /**
1044
  * {@inheritdoc}
1045
  */
1046
  public function getId()
1047
  {
1048
- return 'INCR';
1049
  }
1050
  }
1051
 
1052
  /**
1053
- * @link http://redis.io/commands/getrange
1054
  * @author Daniele Alessandri <suppakilla@gmail.com>
1055
  */
1056
- class StringGetRange extends Command
1057
  {
1058
  /**
1059
  * {@inheritdoc}
1060
  */
1061
  public function getId()
1062
  {
1063
- return 'GETRANGE';
 
 
 
 
 
 
 
 
 
 
 
 
1064
  }
1065
  }
1066
 
1067
  /**
1068
- * @link http://redis.io/commands/getset
1069
  * @author Daniele Alessandri <suppakilla@gmail.com>
1070
  */
1071
- class StringGetSet extends Command
1072
  {
1073
  /**
1074
  * {@inheritdoc}
1075
  */
1076
  public function getId()
1077
  {
1078
- return 'GETSET';
1079
  }
1080
  }
1081
 
1082
  /**
1083
- * @link http://redis.io/commands/sunion
1084
  * @author Daniele Alessandri <suppakilla@gmail.com>
1085
  */
1086
- class SetUnion extends SetIntersection
1087
  {
1088
  /**
1089
  * {@inheritdoc}
1090
  */
1091
  public function getId()
1092
  {
1093
- return 'SUNION';
1094
  }
1095
  }
1096
 
1097
  /**
1098
- * @link http://redis.io/commands/sscan
1099
  * @author Daniele Alessandri <suppakilla@gmail.com>
1100
  */
1101
- class SetScan extends Command
1102
  {
1103
  /**
1104
  * {@inheritdoc}
1105
  */
1106
  public function getId()
1107
  {
1108
- return 'SSCAN';
1109
  }
1110
 
1111
  /**
1112
  * {@inheritdoc}
1113
  */
1114
- protected function filterArguments(array $arguments)
1115
  {
1116
- if (count($arguments) === 3 && is_array($arguments[2])) {
1117
- $options = $this->prepareOptions(array_pop($arguments));
1118
- $arguments = array_merge($arguments, $options);
1119
- }
1120
 
1121
- return $arguments;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1122
  }
1123
 
1124
  /**
@@ -1145,73 +1362,99 @@ class SetScan extends Command
1145
 
1146
  return $normalized;
1147
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1148
  }
1149
 
1150
  /**
1151
- * @link http://redis.io/commands/scard
1152
  * @author Daniele Alessandri <suppakilla@gmail.com>
1153
  */
1154
- class SetCardinality extends Command
1155
  {
1156
  /**
1157
  * {@inheritdoc}
1158
  */
1159
  public function getId()
1160
  {
1161
- return 'SCARD';
1162
  }
1163
  }
1164
 
1165
  /**
1166
- * @link http://redis.io/commands/sdiff
1167
  * @author Daniele Alessandri <suppakilla@gmail.com>
1168
  */
1169
- class SetDifference extends SetIntersection
1170
  {
1171
  /**
1172
  * {@inheritdoc}
1173
  */
1174
  public function getId()
1175
  {
1176
- return 'SDIFF';
1177
  }
1178
  }
1179
 
1180
  /**
1181
- * @link http://redis.io/commands/sdiffstore
1182
  * @author Daniele Alessandri <suppakilla@gmail.com>
1183
  */
1184
- class SetDifferenceStore extends SetIntersectionStore
1185
  {
1186
  /**
1187
  * {@inheritdoc}
1188
  */
1189
  public function getId()
1190
  {
1191
- return 'SDIFFSTORE';
1192
  }
1193
  }
1194
 
1195
  /**
1196
- * @link http://redis.io/commands/sadd
1197
  * @author Daniele Alessandri <suppakilla@gmail.com>
1198
  */
1199
- class SetAdd extends Command
1200
  {
1201
  /**
1202
  * {@inheritdoc}
1203
  */
1204
  public function getId()
1205
  {
1206
- return 'SADD';
1207
  }
 
1208
 
 
 
 
 
 
 
1209
  /**
1210
  * {@inheritdoc}
1211
  */
1212
- protected function filterArguments(array $arguments)
1213
  {
1214
- return self::normalizeVariadic($arguments);
1215
  }
1216
  }
1217
 
@@ -1231,17 +1474,17 @@ class ServerTime extends Command
1231
  }
1232
 
1233
  /**
1234
- * @link http://redis.io/commands/slaveof
1235
  * @author Daniele Alessandri <suppakilla@gmail.com>
1236
  */
1237
- class ServerSlaveOf extends Command
1238
  {
1239
  /**
1240
  * {@inheritdoc}
1241
  */
1242
  public function getId()
1243
  {
1244
- return 'SLAVEOF';
1245
  }
1246
 
1247
  /**
@@ -1249,163 +1492,127 @@ class ServerSlaveOf extends Command
1249
  */
1250
  protected function filterArguments(array $arguments)
1251
  {
1252
- if (count($arguments) === 0 || $arguments[0] === 'NO ONE') {
1253
- return array('NO', 'ONE');
1254
- }
1255
-
1256
- return $arguments;
1257
  }
1258
  }
1259
 
1260
  /**
1261
- * @link http://redis.io/commands/slowlog
1262
  * @author Daniele Alessandri <suppakilla@gmail.com>
1263
  */
1264
- class ServerSlowlog extends Command
1265
  {
1266
  /**
1267
  * {@inheritdoc}
1268
  */
1269
  public function getId()
1270
  {
1271
- return 'SLOWLOG';
1272
- }
1273
-
1274
- /**
1275
- * {@inheritdoc}
1276
- */
1277
- public function parseResponse($data)
1278
- {
1279
- if (is_array($data)) {
1280
- $log = array();
1281
-
1282
- foreach ($data as $index => $entry) {
1283
- $log[$index] = array(
1284
- 'id' => $entry[0],
1285
- 'timestamp' => $entry[1],
1286
- 'duration' => $entry[2],
1287
- 'command' => $entry[3],
1288
- );
1289
- }
1290
-
1291
- return $log;
1292
- }
1293
-
1294
- return $data;
1295
  }
1296
  }
1297
 
1298
  /**
1299
- * @link http://redis.io/commands/hexists
1300
  * @author Daniele Alessandri <suppakilla@gmail.com>
1301
  */
1302
- class HashExists extends Command
1303
  {
1304
  /**
1305
  * {@inheritdoc}
1306
  */
1307
  public function getId()
1308
  {
1309
- return 'HEXISTS';
1310
- }
1311
-
1312
- /**
1313
- * {@inheritdoc}
1314
- */
1315
- public function parseResponse($data)
1316
- {
1317
- return (bool) $data;
1318
  }
1319
  }
1320
 
1321
  /**
1322
- * @link http://redis.io/commands/hdel
1323
  * @author Daniele Alessandri <suppakilla@gmail.com>
1324
  */
1325
- class HashDelete extends Command
1326
  {
1327
  /**
1328
  * {@inheritdoc}
1329
  */
1330
  public function getId()
1331
  {
1332
- return 'HDEL';
1333
- }
1334
-
1335
- /**
1336
- * {@inheritdoc}
1337
- */
1338
- protected function filterArguments(array $arguments)
1339
- {
1340
- return self::normalizeVariadic($arguments);
1341
  }
1342
  }
1343
 
1344
  /**
1345
- * @link http://redis.io/commands/srandmember
1346
  * @author Daniele Alessandri <suppakilla@gmail.com>
1347
  */
1348
- class SetRandomMember extends Command
1349
  {
1350
  /**
1351
  * {@inheritdoc}
1352
  */
1353
  public function getId()
1354
  {
1355
- return 'SRANDMEMBER';
1356
  }
1357
  }
1358
 
1359
  /**
1360
- * @link http://redis.io/commands/srem
1361
  * @author Daniele Alessandri <suppakilla@gmail.com>
1362
  */
1363
- class SetRemove extends Command
1364
  {
1365
  /**
1366
  * {@inheritdoc}
1367
  */
1368
  public function getId()
1369
  {
1370
- return 'SREM';
1371
  }
 
1372
 
 
 
 
 
 
 
1373
  /**
1374
  * {@inheritdoc}
1375
  */
1376
- protected function filterArguments(array $arguments)
1377
  {
1378
- return self::normalizeVariadic($arguments);
1379
  }
1380
  }
1381
 
1382
  /**
1383
- * @link http://redis.io/commands/spop
1384
  * @author Daniele Alessandri <suppakilla@gmail.com>
1385
  */
1386
- class SetPop extends Command
1387
  {
1388
  /**
1389
  * {@inheritdoc}
1390
  */
1391
  public function getId()
1392
  {
1393
- return 'SPOP';
1394
  }
1395
  }
1396
 
1397
  /**
1398
- * @link http://redis.io/commands/smove
1399
  * @author Daniele Alessandri <suppakilla@gmail.com>
1400
  */
1401
- class SetMove extends Command
1402
  {
1403
  /**
1404
  * {@inheritdoc}
1405
  */
1406
  public function getId()
1407
  {
1408
- return 'SMOVE';
1409
  }
1410
 
1411
  /**
@@ -1418,17 +1625,17 @@ class SetMove extends Command
1418
  }
1419
 
1420
  /**
1421
- * @link http://redis.io/commands/sismember
1422
  * @author Daniele Alessandri <suppakilla@gmail.com>
1423
  */
1424
- class SetIsMember extends Command
1425
  {
1426
  /**
1427
  * {@inheritdoc}
1428
  */
1429
  public function getId()
1430
  {
1431
- return 'SISMEMBER';
1432
  }
1433
 
1434
  /**
@@ -1441,77 +1648,77 @@ class SetIsMember extends Command
1441
  }
1442
 
1443
  /**
1444
- * @link http://redis.io/commands/smembers
1445
  * @author Daniele Alessandri <suppakilla@gmail.com>
1446
  */
1447
- class SetMembers extends Command
1448
  {
1449
  /**
1450
  * {@inheritdoc}
1451
  */
1452
  public function getId()
1453
  {
1454
- return 'SMEMBERS';
1455
  }
1456
  }
1457
 
1458
  /**
1459
- * @link http://redis.io/commands/set
1460
  * @author Daniele Alessandri <suppakilla@gmail.com>
1461
  */
1462
- class StringSet extends Command
1463
  {
1464
  /**
1465
  * {@inheritdoc}
1466
  */
1467
  public function getId()
1468
  {
1469
- return 'SET';
1470
  }
1471
  }
1472
 
1473
  /**
1474
- * @link http://redis.io/commands/setbit
1475
  * @author Daniele Alessandri <suppakilla@gmail.com>
1476
  */
1477
- class StringSetBit extends Command
1478
  {
1479
  /**
1480
  * {@inheritdoc}
1481
  */
1482
  public function getId()
1483
  {
1484
- return 'SETBIT';
1485
  }
1486
  }
1487
 
1488
  /**
1489
- * @link http://redis.io/commands/zrank
1490
  * @author Daniele Alessandri <suppakilla@gmail.com>
1491
  */
1492
- class ZSetRank extends Command
1493
  {
1494
  /**
1495
  * {@inheritdoc}
1496
  */
1497
  public function getId()
1498
  {
1499
- return 'ZRANK';
1500
  }
1501
  }
1502
 
1503
  /**
1504
- * @link http://redis.io/commands/zrem
1505
  * @author Daniele Alessandri <suppakilla@gmail.com>
1506
  */
1507
- class ZSetRemove extends Command
1508
  {
1509
  /**
1510
  * {@inheritdoc}
1511
  */
1512
  public function getId()
1513
  {
1514
- return 'ZREM';
1515
  }
1516
 
1517
  /**
@@ -1519,37 +1726,75 @@ class ZSetRemove extends Command
1519
  */
1520
  protected function filterArguments(array $arguments)
1521
  {
1522
- return self::normalizeVariadic($arguments);
 
 
 
 
 
 
 
 
 
 
 
1523
  }
1524
  }
1525
 
1526
  /**
1527
- * @link http://redis.io/commands/zremrangebylex
1528
  * @author Daniele Alessandri <suppakilla@gmail.com>
1529
  */
1530
- class ZSetRemoveRangeByLex extends Command
1531
  {
1532
  /**
1533
  * {@inheritdoc}
1534
  */
1535
  public function getId()
1536
  {
1537
- return 'ZREMRANGEBYLEX';
 
 
 
 
 
 
 
 
 
 
 
 
1538
  }
1539
  }
1540
 
1541
  /**
1542
- * @link http://redis.io/commands/echo
1543
  * @author Daniele Alessandri <suppakilla@gmail.com>
1544
  */
1545
- class ConnectionEcho extends Command
1546
  {
1547
  /**
1548
  * {@inheritdoc}
1549
  */
1550
  public function getId()
1551
  {
1552
- return 'ECHO';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1553
  }
1554
  }
1555
 
@@ -1596,469 +1841,410 @@ class ZSetRangeByLex extends ZSetRange
1596
  }
1597
 
1598
  /**
1599
- * @link http://redis.io/commands/zlexcount
1600
  * @author Daniele Alessandri <suppakilla@gmail.com>
1601
  */
1602
- class ZSetLexCount extends Command
1603
  {
1604
  /**
1605
  * {@inheritdoc}
1606
  */
1607
  public function getId()
1608
  {
1609
- return 'ZLEXCOUNT';
1610
  }
1611
  }
1612
 
1613
  /**
1614
- * @link http://redis.io/commands/ping
1615
  * @author Daniele Alessandri <suppakilla@gmail.com>
1616
  */
1617
- class ConnectionPing extends Command
1618
  {
1619
  /**
1620
  * {@inheritdoc}
1621
  */
1622
  public function getId()
1623
  {
1624
- return 'PING';
1625
  }
1626
- }
1627
 
1628
- /**
1629
- * @link http://redis.io/commands/zremrangebyrank
1630
- * @author Daniele Alessandri <suppakilla@gmail.com>
1631
- */
1632
- class ZSetRemoveRangeByRank extends Command
1633
- {
1634
  /**
1635
  * {@inheritdoc}
1636
  */
1637
- public function getId()
1638
  {
1639
- return 'ZREMRANGEBYRANK';
1640
  }
1641
  }
1642
 
1643
  /**
1644
- * @link http://redis.io/commands/zremrangebyscore
1645
  * @author Daniele Alessandri <suppakilla@gmail.com>
1646
  */
1647
- class ZSetRemoveRangeByScore extends Command
1648
  {
1649
  /**
1650
  * {@inheritdoc}
1651
  */
1652
  public function getId()
1653
  {
1654
- return 'ZREMRANGEBYSCORE';
1655
  }
1656
  }
1657
 
1658
  /**
1659
- * @link http://redis.io/commands/zscore
1660
  * @author Daniele Alessandri <suppakilla@gmail.com>
1661
  */
1662
- class ZSetScore extends Command
1663
  {
1664
  /**
1665
  * {@inheritdoc}
1666
  */
1667
  public function getId()
1668
  {
1669
- return 'ZSCORE';
1670
  }
1671
- }
1672
 
1673
- /**
1674
- * @link http://redis.io/commands/auth
1675
- * @author Daniele Alessandri <suppakilla@gmail.com>
1676
- */
1677
- class ConnectionAuth extends Command
1678
- {
1679
  /**
1680
  * {@inheritdoc}
1681
  */
1682
- public function getId()
1683
  {
1684
- return 'AUTH';
1685
  }
1686
  }
1687
 
1688
  /**
1689
- * @link http://redis.io/commands/zscan
1690
  * @author Daniele Alessandri <suppakilla@gmail.com>
1691
  */
1692
- class ZSetScan extends Command
1693
  {
1694
  /**
1695
  * {@inheritdoc}
1696
  */
1697
  public function getId()
1698
  {
1699
- return 'ZSCAN';
1700
  }
 
1701
 
 
 
 
 
 
 
1702
  /**
1703
  * {@inheritdoc}
1704
  */
1705
- protected function filterArguments(array $arguments)
1706
- {
1707
- if (count($arguments) === 3 && is_array($arguments[2])) {
1708
- $options = $this->prepareOptions(array_pop($arguments));
1709
- $arguments = array_merge($arguments, $options);
1710
- }
1711
-
1712
- return $arguments;
1713
- }
1714
-
1715
- /**
1716
- * Returns a list of options and modifiers compatible with Redis.
1717
- *
1718
- * @param array $options List of options.
1719
- *
1720
- * @return array
1721
- */
1722
- protected function prepareOptions($options)
1723
  {
1724
- $options = array_change_key_case($options, CASE_UPPER);
1725
- $normalized = array();
1726
-
1727
- if (!empty($options['MATCH'])) {
1728
- $normalized[] = 'MATCH';
1729
- $normalized[] = $options['MATCH'];
1730
- }
1731
-
1732
- if (!empty($options['COUNT'])) {
1733
- $normalized[] = 'COUNT';
1734
- $normalized[] = $options['COUNT'];
1735
- }
1736
-
1737
- return $normalized;
1738
  }
 
1739
 
 
 
 
 
 
 
1740
  /**
1741
  * {@inheritdoc}
1742
  */
1743
- public function parseResponse($data)
1744
  {
1745
- if (is_array($data)) {
1746
- $members = $data[1];
1747
- $result = array();
1748
-
1749
- for ($i = 0; $i < count($members); $i++) {
1750
- $result[$members[$i]] = (float) $members[++$i];
1751
- }
1752
-
1753
- $data[1] = $result;
1754
- }
1755
-
1756
- return $data;
1757
  }
1758
  }
1759
 
1760
  /**
1761
- * @link http://redis.io/commands/zrevrank
1762
  * @author Daniele Alessandri <suppakilla@gmail.com>
1763
  */
1764
- class ZSetReverseRank extends Command
1765
  {
1766
  /**
1767
  * {@inheritdoc}
1768
  */
1769
  public function getId()
1770
  {
1771
- return 'ZREVRANK';
1772
  }
1773
  }
1774
 
1775
  /**
1776
- * @link http://redis.io/commands/zrevrange
1777
  * @author Daniele Alessandri <suppakilla@gmail.com>
1778
  */
1779
- class ZSetReverseRange extends ZSetRange
1780
  {
1781
  /**
1782
  * {@inheritdoc}
1783
  */
1784
  public function getId()
1785
  {
1786
- return 'ZREVRANGE';
1787
  }
1788
  }
1789
 
1790
  /**
1791
- * @link http://redis.io/commands/zrevrangebyscore
1792
  * @author Daniele Alessandri <suppakilla@gmail.com>
1793
  */
1794
- class ZSetReverseRangeByScore extends ZSetRangeByScore
1795
  {
1796
  /**
1797
  * {@inheritdoc}
1798
  */
1799
  public function getId()
1800
  {
1801
- return 'ZREVRANGEBYSCORE';
1802
  }
1803
  }
1804
 
1805
  /**
1806
- * @link http://redis.io/commands/zinterstore
1807
  * @author Daniele Alessandri <suppakilla@gmail.com>
1808
  */
1809
- class ZSetIntersectionStore extends ZSetUnionStore
1810
  {
1811
  /**
1812
  * {@inheritdoc}
1813
  */
1814
  public function getId()
1815
  {
1816
- return 'ZINTERSTORE';
1817
  }
1818
  }
1819
 
1820
  /**
1821
- * @link http://redis.io/commands/zincrby
1822
  * @author Daniele Alessandri <suppakilla@gmail.com>
1823
  */
1824
- class ZSetIncrementBy extends Command
1825
  {
1826
  /**
1827
  * {@inheritdoc}
1828
  */
1829
  public function getId()
1830
  {
1831
- return 'ZINCRBY';
1832
  }
1833
  }
1834
 
1835
  /**
1836
- * @link http://redis.io/commands/setrange
1837
  * @author Daniele Alessandri <suppakilla@gmail.com>
1838
  */
1839
- class StringSetRange extends Command
1840
  {
1841
  /**
1842
  * {@inheritdoc}
1843
  */
1844
  public function getId()
1845
  {
1846
- return 'SETRANGE';
1847
  }
1848
  }
1849
 
1850
  /**
1851
- * @link http://redis.io/commands/strlen
1852
  * @author Daniele Alessandri <suppakilla@gmail.com>
1853
  */
1854
- class StringStrlen extends Command
1855
  {
1856
  /**
1857
  * {@inheritdoc}
1858
  */
1859
  public function getId()
1860
  {
1861
- return 'STRLEN';
1862
  }
1863
  }
1864
 
1865
  /**
1866
- * @link http://redis.io/commands/substr
1867
  * @author Daniele Alessandri <suppakilla@gmail.com>
1868
  */
1869
- class StringSubstr extends Command
1870
  {
1871
  /**
1872
  * {@inheritdoc}
1873
  */
1874
  public function getId()
1875
  {
1876
- return 'SUBSTR';
1877
  }
1878
  }
1879
 
1880
  /**
1881
- * @link http://redis.io/commands/setnx
1882
  * @author Daniele Alessandri <suppakilla@gmail.com>
1883
  */
1884
- class StringSetPreserve extends Command
1885
  {
1886
  /**
1887
  * {@inheritdoc}
1888
  */
1889
  public function getId()
1890
  {
1891
- return 'SETNX';
1892
  }
 
1893
 
 
 
 
 
 
 
1894
  /**
1895
  * {@inheritdoc}
1896
  */
1897
- public function parseResponse($data)
1898
  {
1899
- return (bool) $data;
1900
  }
1901
  }
1902
 
1903
  /**
1904
- * @link http://redis.io/commands/msetnx
1905
  * @author Daniele Alessandri <suppakilla@gmail.com>
1906
  */
1907
- class StringSetMultiplePreserve extends StringSetMultiple
1908
  {
1909
  /**
1910
  * {@inheritdoc}
1911
  */
1912
  public function getId()
1913
  {
1914
- return 'MSETNX';
1915
  }
1916
 
1917
  /**
1918
  * {@inheritdoc}
1919
  */
1920
- public function parseResponse($data)
1921
  {
1922
- return (bool) $data;
1923
  }
1924
  }
1925
 
1926
  /**
1927
- * @link http://redis.io/commands/select
1928
  * @author Daniele Alessandri <suppakilla@gmail.com>
1929
  */
1930
- class ConnectionSelect extends Command
1931
  {
1932
  /**
1933
  * {@inheritdoc}
1934
  */
1935
  public function getId()
1936
  {
1937
- return 'SELECT';
1938
  }
1939
  }
1940
 
1941
  /**
1942
- * @link http://redis.io/commands/quit
1943
  * @author Daniele Alessandri <suppakilla@gmail.com>
1944
  */
1945
- class ConnectionQuit extends Command
1946
  {
1947
  /**
1948
  * {@inheritdoc}
1949
  */
1950
  public function getId()
1951
  {
1952
- return 'QUIT';
1953
  }
1954
- }
1955
 
1956
- /**
1957
- * @link http://redis.io/commands/discard
1958
- * @author Daniele Alessandri <suppakilla@gmail.com>
1959
- */
1960
- class TransactionDiscard extends Command
1961
- {
1962
  /**
1963
  * {@inheritdoc}
1964
  */
1965
- public function getId()
1966
  {
1967
- return 'DISCARD';
1968
  }
1969
  }
1970
 
1971
  /**
1972
- * @link http://redis.io/commands/exec
1973
  * @author Daniele Alessandri <suppakilla@gmail.com>
1974
  */
1975
- class TransactionExec extends Command
1976
  {
1977
  /**
1978
  * {@inheritdoc}
1979
  */
1980
  public function getId()
1981
  {
1982
- return 'EXEC';
1983
  }
1984
- }
1985
 
1986
- /**
1987
- * @link http://redis.io/commands/zcard
1988
- * @author Daniele Alessandri <suppakilla@gmail.com>
1989
- */
1990
- class ZSetCardinality extends Command
1991
- {
1992
  /**
1993
  * {@inheritdoc}
1994
  */
1995
- public function getId()
1996
  {
1997
- return 'ZCARD';
1998
  }
1999
  }
2000
 
2001
  /**
2002
- * @link http://redis.io/commands/zcount
2003
  * @author Daniele Alessandri <suppakilla@gmail.com>
2004
  */
2005
- class ZSetCount extends Command
2006
  {
2007
  /**
2008
  * {@inheritdoc}
2009
  */
2010
  public function getId()
2011
  {
2012
- return 'ZCOUNT';
2013
  }
2014
- }
2015
 
2016
- /**
2017
- * @link http://redis.io/commands/zadd
2018
- * @author Daniele Alessandri <suppakilla@gmail.com>
2019
- */
2020
- class ZSetAdd extends Command
2021
- {
2022
  /**
2023
  * {@inheritdoc}
2024
  */
2025
- public function getId()
2026
  {
2027
- return 'ZADD';
2028
  }
 
2029
 
 
 
 
 
 
 
2030
  /**
2031
  * {@inheritdoc}
2032
  */
2033
- protected function filterArguments(array $arguments)
2034
  {
2035
- if (count($arguments) === 2 && is_array($arguments[1])) {
2036
- $flattened = array($arguments[0]);
2037
-
2038
- foreach ($arguments[1] as $member => $score) {
2039
- $flattened[] = $score;
2040
- $flattened[] = $member;
2041
- }
2042
-
2043
- return $flattened;
2044
- }
2045
-
2046
- return $arguments;
2047
  }
2048
  }
2049
 
2050
  /**
2051
- * @link http://redis.io/commands/watch
2052
  * @author Daniele Alessandri <suppakilla@gmail.com>
2053
  */
2054
- class TransactionWatch extends Command
2055
  {
2056
  /**
2057
  * {@inheritdoc}
2058
  */
2059
  public function getId()
2060
  {
2061
- return 'WATCH';
2062
  }
2063
 
2064
  /**
@@ -2066,71 +2252,68 @@ class TransactionWatch extends Command
2066
  */
2067
  protected function filterArguments(array $arguments)
2068
  {
2069
- if (isset($arguments[0]) && is_array($arguments[0])) {
2070
- return $arguments[0];
2071
- }
2072
 
2073
- return $arguments;
 
 
 
 
 
2074
  }
2075
  }
2076
 
2077
  /**
2078
- * @link http://redis.io/commands/multi
2079
  * @author Daniele Alessandri <suppakilla@gmail.com>
2080
  */
2081
- class TransactionMulti extends Command
2082
  {
2083
  /**
2084
  * {@inheritdoc}
2085
  */
2086
  public function getId()
2087
  {
2088
- return 'MULTI';
2089
  }
2090
  }
2091
 
2092
  /**
2093
- * @link http://redis.io/commands/unwatch
2094
  * @author Daniele Alessandri <suppakilla@gmail.com>
2095
  */
2096
- class TransactionUnwatch extends Command
2097
  {
2098
  /**
2099
  * {@inheritdoc}
2100
  */
2101
  public function getId()
2102
  {
2103
- return 'UNWATCH';
2104
  }
2105
- }
2106
 
2107
- /**
2108
- * @link http://redis.io/commands/shutdown
2109
- * @author Daniele Alessandri <suppakilla@gmail.com>
2110
- */
2111
- class ServerShutdown extends Command
2112
- {
2113
  /**
2114
  * {@inheritdoc}
2115
  */
2116
- public function getId()
2117
  {
2118
- return 'SHUTDOWN';
2119
  }
2120
  }
2121
 
2122
  /**
2123
- * @link http://redis.io/topics/sentinel
2124
  * @author Daniele Alessandri <suppakilla@gmail.com>
2125
  */
2126
- class ServerSentinel extends Command
2127
  {
2128
  /**
2129
  * {@inheritdoc}
2130
  */
2131
  public function getId()
2132
  {
2133
- return 'SENTINEL';
2134
  }
2135
 
2136
  /**
@@ -2138,135 +2321,128 @@ class ServerSentinel extends Command
2138
  */
2139
  public function parseResponse($data)
2140
  {
2141
- switch (strtolower($this->getArgument(0))) {
2142
- case 'masters':
2143
- case 'slaves':
2144
- return self::processMastersOrSlaves($data);
2145
-
2146
- default:
2147
- return $data;
2148
- }
2149
  }
 
2150
 
 
 
 
 
 
 
2151
  /**
2152
- * Returns a processed response to SENTINEL MASTERS or SENTINEL SLAVES.
2153
- *
2154
- * @param array $servers List of Redis servers.
2155
- *
2156
- * @return array
2157
  */
2158
- protected static function processMastersOrSlaves(array $servers)
2159
  {
2160
- foreach ($servers as $idx => $node) {
2161
- $processed = array();
2162
- $count = count($node);
2163
-
2164
- for ($i = 0; $i < $count; $i++) {
2165
- $processed[$node[$i]] = $node[++$i];
2166
- }
2167
-
2168
- $servers[$idx] = $processed;
2169
- }
2170
 
2171
- return $servers;
 
 
 
 
 
2172
  }
2173
  }
2174
 
2175
  /**
2176
- * @link http://redis.io/commands/type
2177
  * @author Daniele Alessandri <suppakilla@gmail.com>
2178
  */
2179
- class KeyType extends Command
2180
  {
2181
  /**
2182
  * {@inheritdoc}
2183
  */
2184
  public function getId()
2185
  {
2186
- return 'TYPE';
2187
  }
2188
  }
2189
 
2190
  /**
2191
- * @link http://redis.io/commands/lindex
2192
  * @author Daniele Alessandri <suppakilla@gmail.com>
2193
  */
2194
- class ListIndex extends Command
2195
  {
2196
  /**
2197
  * {@inheritdoc}
2198
  */
2199
  public function getId()
2200
  {
2201
- return 'LINDEX';
2202
  }
2203
  }
2204
 
2205
  /**
2206
- * @link http://redis.io/commands/linsert
2207
  * @author Daniele Alessandri <suppakilla@gmail.com>
2208
  */
2209
- class ListInsert extends Command
2210
  {
2211
  /**
2212
  * {@inheritdoc}
2213
  */
2214
  public function getId()
2215
  {
2216
- return 'LINSERT';
2217
  }
2218
  }
2219
 
2220
  /**
2221
- * @link http://redis.io/commands/hscan
2222
  * @author Daniele Alessandri <suppakilla@gmail.com>
2223
  */
2224
- class HashScan extends Command
2225
  {
2226
  /**
2227
  * {@inheritdoc}
2228
  */
2229
  public function getId()
2230
  {
2231
- return 'HSCAN';
2232
  }
2233
 
2234
  /**
2235
  * {@inheritdoc}
2236
  */
2237
- protected function filterArguments(array $arguments)
2238
  {
2239
- if (count($arguments) === 3 && is_array($arguments[2])) {
2240
- $options = $this->prepareOptions(array_pop($arguments));
2241
- $arguments = array_merge($arguments, $options);
2242
- }
2243
-
2244
- return $arguments;
2245
  }
 
2246
 
 
 
 
 
 
 
2247
  /**
2248
- * Returns a list of options and modifiers compatible with Redis.
2249
- *
2250
- * @param array $options List of options.
2251
- *
2252
- * @return array
2253
  */
2254
- protected function prepareOptions($options)
2255
  {
2256
- $options = array_change_key_case($options, CASE_UPPER);
2257
- $normalized = array();
2258
-
2259
- if (!empty($options['MATCH'])) {
2260
- $normalized[] = 'MATCH';
2261
- $normalized[] = $options['MATCH'];
2262
- }
2263
-
2264
- if (!empty($options['COUNT'])) {
2265
- $normalized[] = 'COUNT';
2266
- $normalized[] = $options['COUNT'];
2267
- }
2268
 
2269
- return $normalized;
 
 
 
 
 
 
 
 
 
 
 
2270
  }
2271
 
2272
  /**
@@ -2274,33 +2450,22 @@ class HashScan extends Command
2274
  */
2275
  public function parseResponse($data)
2276
  {
2277
- if (is_array($data)) {
2278
- $fields = $data[1];
2279
- $result = array();
2280
-
2281
- for ($i = 0; $i < count($fields); $i++) {
2282
- $result[$fields[$i]] = $fields[++$i];
2283
- }
2284
-
2285
- $data[1] = $result;
2286
- }
2287
-
2288
- return $data;
2289
  }
2290
  }
2291
 
2292
  /**
2293
- * @link http://redis.io/commands/sort
2294
  * @author Daniele Alessandri <suppakilla@gmail.com>
2295
  */
2296
- class KeySort extends Command
2297
  {
2298
  /**
2299
  * {@inheritdoc}
2300
  */
2301
  public function getId()
2302
  {
2303
- return 'SORT';
2304
  }
2305
 
2306
  /**
@@ -2308,85 +2473,49 @@ class KeySort extends Command
2308
  */
2309
  protected function filterArguments(array $arguments)
2310
  {
2311
- if (count($arguments) === 1) {
2312
- return $arguments;
2313
- }
2314
 
2315
- $query = array($arguments[0]);
2316
- $sortParams = array_change_key_case($arguments[1], CASE_UPPER);
 
 
2317
 
2318
- if (isset($sortParams['BY'])) {
2319
- $query[] = 'BY';
2320
- $query[] = $sortParams['BY'];
2321
  }
2322
 
2323
- if (isset($sortParams['GET'])) {
2324
- $getargs = $sortParams['GET'];
2325
-
2326
- if (is_array($getargs)) {
2327
- foreach ($getargs as $getarg) {
2328
- $query[] = 'GET';
2329
- $query[] = $getarg;
2330
- }
2331
- } else {
2332
- $query[] = 'GET';
2333
- $query[] = $getargs;
2334
- }
2335
- }
2336
-
2337
- if (isset($sortParams['LIMIT']) &&
2338
- is_array($sortParams['LIMIT']) &&
2339
- count($sortParams['LIMIT']) == 2) {
2340
-
2341
- $query[] = 'LIMIT';
2342
- $query[] = $sortParams['LIMIT'][0];
2343
- $query[] = $sortParams['LIMIT'][1];
2344
- }
2345
-
2346
- if (isset($sortParams['SORT'])) {
2347
- $query[] = strtoupper($sortParams['SORT']);
2348
- }
2349
-
2350
- if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
2351
- $query[] = 'ALPHA';
2352
- }
2353
-
2354
- if (isset($sortParams['STORE'])) {
2355
- $query[] = 'STORE';
2356
- $query[] = $sortParams['STORE'];
2357
- }
2358
-
2359
- return $query;
2360
  }
2361
  }
2362
 
2363
  /**
2364
- * @link http://redis.io/commands/restore
2365
  * @author Daniele Alessandri <suppakilla@gmail.com>
2366
  */
2367
- class KeyRestore extends Command
2368
  {
2369
  /**
2370
  * {@inheritdoc}
2371
  */
2372
  public function getId()
2373
  {
2374
- return 'RESTORE';
2375
  }
2376
  }
2377
 
2378
  /**
2379
- * @link http://redis.io/commands/scan
2380
  * @author Daniele Alessandri <suppakilla@gmail.com>
2381
  */
2382
- class KeyScan extends Command
2383
  {
2384
  /**
2385
  * {@inheritdoc}
2386
  */
2387
  public function getId()
2388
  {
2389
- return 'SCAN';
2390
  }
2391
 
2392
  /**
@@ -2394,127 +2523,134 @@ class KeyScan extends Command
2394
  */
2395
  protected function filterArguments(array $arguments)
2396
  {
2397
- if (count($arguments) === 2 && is_array($arguments[1])) {
2398
- $options = $this->prepareOptions(array_pop($arguments));
2399
- $arguments = array_merge($arguments, $options);
2400
- }
2401
-
2402
- return $arguments;
2403
  }
 
2404
 
 
 
 
 
 
 
2405
  /**
2406
- * Returns a list of options and modifiers compatible with Redis.
2407
- *
2408
- * @param array $options List of options.
2409
- *
2410
- * @return array
2411
  */
2412
- protected function prepareOptions($options)
2413
  {
2414
- $options = array_change_key_case($options, CASE_UPPER);
2415
- $normalized = array();
2416
-
2417
- if (!empty($options['MATCH'])) {
2418
- $normalized[] = 'MATCH';
2419
- $normalized[] = $options['MATCH'];
2420
- }
2421
-
2422
- if (!empty($options['COUNT'])) {
2423
- $normalized[] = 'COUNT';
2424
- $normalized[] = $options['COUNT'];
2425
- }
2426
 
2427
- return $normalized;
 
 
 
 
 
2428
  }
2429
  }
2430
 
2431
  /**
2432
- * @link http://redis.io/commands/llen
2433
  * @author Daniele Alessandri <suppakilla@gmail.com>
2434
  */
2435
- class ListLength extends Command
2436
  {
2437
  /**
2438
  * {@inheritdoc}
2439
  */
2440
  public function getId()
2441
  {
2442
- return 'LLEN';
2443
  }
2444
  }
2445
 
2446
  /**
2447
- * @link http://redis.io/commands/lpop
2448
  * @author Daniele Alessandri <suppakilla@gmail.com>
2449
  */
2450
- class ListPopFirst extends Command
2451
  {
2452
  /**
2453
  * {@inheritdoc}
2454
  */
2455
  public function getId()
2456
  {
2457
- return 'LPOP';
2458
  }
2459
  }
2460
 
2461
  /**
2462
- * @link http://redis.io/commands/brpoplpush
2463
  * @author Daniele Alessandri <suppakilla@gmail.com>
2464
  */
2465
- class ListPopLastPushHeadBlocking extends Command
2466
  {
2467
  /**
2468
  * {@inheritdoc}
2469
  */
2470
  public function getId()
2471
  {
2472
- return 'BRPOPLPUSH';
2473
  }
2474
  }
2475
 
2476
  /**
2477
- * @link http://redis.io/commands/lpush
2478
  * @author Daniele Alessandri <suppakilla@gmail.com>
2479
  */
2480
- class ListPushHead extends ListPushTail
2481
  {
2482
  /**
2483
  * {@inheritdoc}
2484
  */
2485
  public function getId()
2486
  {
2487
- return 'LPUSH';
2488
  }
2489
  }
2490
 
2491
  /**
2492
- * @link http://redis.io/commands/rpoplpush
2493
  * @author Daniele Alessandri <suppakilla@gmail.com>
2494
  */
2495
- class ListPopLastPushHead extends Command
2496
  {
2497
  /**
2498
  * {@inheritdoc}
2499
  */
2500
  public function getId()
2501
  {
2502
- return 'RPOPLPUSH';
2503
  }
2504
  }
2505
 
2506
  /**
2507
- * @link http://redis.io/commands/brpop
2508
  * @author Daniele Alessandri <suppakilla@gmail.com>
2509
  */
2510
- class ListPopLastBlocking extends ListPopFirstBlocking
2511
  {
2512
  /**
2513
  * {@inheritdoc}
2514
  */
2515
  public function getId()
2516
  {
2517
- return 'BRPOP';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2518
  }
2519
  }
2520
 
@@ -2534,32 +2670,55 @@ class HashLength extends Command
2534
  }
2535
 
2536
  /**
2537
- * @link http://redis.io/commands/rpop
2538
  * @author Daniele Alessandri <suppakilla@gmail.com>
2539
  */
2540
- class ListPopLast extends Command
2541
  {
2542
  /**
2543
  * {@inheritdoc}
2544
  */
2545
  public function getId()
2546
  {
2547
- return 'RPOP';
2548
  }
2549
- }
2550
 
2551
- /**
2552
- * @link http://redis.io/commands/renamenx
2553
- * @author Daniele Alessandri <suppakilla@gmail.com>
2554
- */
2555
- class KeyRenamePreserve extends KeyRename
2556
- {
2557
  /**
2558
  * {@inheritdoc}
2559
  */
2560
- public function getId()
2561
  {
2562
- return 'RENAMENX';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2563
  }
2564
 
2565
  /**
@@ -2567,7 +2726,18 @@ class KeyRenamePreserve extends KeyRename
2567
  */
2568
  public function parseResponse($data)
2569
  {
2570
- return (bool) $data;
 
 
 
 
 
 
 
 
 
 
 
2571
  }
2572
  }
2573
 
@@ -2595,101 +2765,85 @@ class HashSet extends Command
2595
  }
2596
 
2597
  /**
2598
- * @link http://redis.io/commands/dump
2599
  * @author Daniele Alessandri <suppakilla@gmail.com>
2600
  */
2601
- class KeyDump extends Command
2602
  {
2603
  /**
2604
  * {@inheritdoc}
2605
  */
2606
  public function getId()
2607
  {
2608
- return 'DUMP';
2609
  }
2610
  }
2611
 
2612
  /**
2613
- * @link http://redis.io/commands/exists
2614
  * @author Daniele Alessandri <suppakilla@gmail.com>
2615
  */
2616
- class KeyExists extends Command
2617
  {
2618
  /**
2619
  * {@inheritdoc}
2620
  */
2621
  public function getId()
2622
  {
2623
- return 'EXISTS';
2624
- }
2625
-
2626
- /**
2627
- * {@inheritdoc}
2628
- */
2629
- public function parseResponse($data)
2630
- {
2631
- return (bool) $data;
2632
  }
2633
  }
2634
 
2635
  /**
2636
- * @link http://redis.io/commands/hsetnx
2637
  * @author Daniele Alessandri <suppakilla@gmail.com>
2638
  */
2639
- class HashSetPreserve extends Command
2640
  {
2641
  /**
2642
  * {@inheritdoc}
2643
  */
2644
  public function getId()
2645
  {
2646
- return 'HSETNX';
2647
  }
2648
 
2649
  /**
2650
  * {@inheritdoc}
2651
  */
2652
- public function parseResponse($data)
2653
  {
2654
- return (bool) $data;
2655
  }
2656
  }
2657
 
2658
  /**
2659
- * @link http://redis.io/commands/del
2660
  * @author Daniele Alessandri <suppakilla@gmail.com>
2661
  */
2662
- class KeyDelete extends Command
2663
  {
2664
  /**
2665
  * {@inheritdoc}
2666
  */
2667
  public function getId()
2668
  {
2669
- return 'DEL';
2670
- }
2671
-
2672
- /**
2673
- * {@inheritdoc}
2674
- */
2675
- protected function filterArguments(array $arguments)
2676
- {
2677
- return self::normalizeArguments($arguments);
2678
  }
2679
  }
2680
 
2681
  /**
2682
- * @link http://redis.io/commands/pfmerge
2683
  * @author Daniele Alessandri <suppakilla@gmail.com>
2684
  */
2685
- class HyperLogLogMerge extends Command
2686
  {
2687
  /**
2688
  * {@inheritdoc}
2689
  */
2690
  public function getId()
2691
  {
2692
- return 'PFMERGE';
2693
  }
2694
 
2695
  /**
@@ -2697,76 +2851,52 @@ class HyperLogLogMerge extends Command
2697
  */
2698
  protected function filterArguments(array $arguments)
2699
  {
2700
- return self::normalizeArguments($arguments);
2701
- }
2702
- }
 
2703
 
2704
- /**
2705
- * @link http://redis.io/commands/pfadd
2706
- * @author Daniele Alessandri <suppakilla@gmail.com>
2707
- */
2708
- class HyperLogLogAdd extends Command
2709
- {
2710
- /**
2711
- * {@inheritdoc}
2712
- */
2713
- public function getId()
2714
- {
2715
- return 'PFADD';
2716
  }
2717
 
2718
  /**
2719
- * {@inheritdoc}
 
 
 
 
2720
  */
2721
- protected function filterArguments(array $arguments)
2722
  {
2723
- return self::normalizeVariadic($arguments);
2724
- }
2725
 
2726
- /**
2727
- * {@inheritdoc}
2728
- */
2729
- public function parseResponse($data)
2730
- {
2731
- return (bool) $data;
2732
- }
2733
- }
2734
 
2735
- /**
2736
- * @link http://redis.io/commands/pfcount
2737
- * @author Daniele Alessandri <suppakilla@gmail.com>
2738
- */
2739
- class HyperLogLogCount extends Command
2740
- {
2741
- /**
2742
- * {@inheritdoc}
2743
- */
2744
- public function getId()
2745
- {
2746
- return 'PFCOUNT';
2747
- }
2748
 
2749
- /**
2750
- * {@inheritdoc}
2751
- */
2752
- protected function filterArguments(array $arguments)
2753
- {
2754
- return self::normalizeArguments($arguments);
2755
  }
2756
  }
2757
 
2758
  /**
2759
- * @link http://redis.io/commands/hmset
2760
  * @author Daniele Alessandri <suppakilla@gmail.com>
2761
  */
2762
- class HashSetMultiple extends Command
2763
  {
2764
  /**
2765
  * {@inheritdoc}
2766
  */
2767
  public function getId()
2768
  {
2769
- return 'HMSET';
2770
  }
2771
 
2772
  /**
@@ -2774,278 +2904,166 @@ class HashSetMultiple extends Command
2774
  */
2775
  protected function filterArguments(array $arguments)
2776
  {
2777
- if (count($arguments) === 2 && is_array($arguments[1])) {
2778
- $flattenedKVs = array($arguments[0]);
2779
- $args = $arguments[1];
2780
 
2781
- foreach ($args as $k => $v) {
2782
- $flattenedKVs[] = $k;
2783
- $flattenedKVs[] = $v;
2784
- }
2785
 
2786
- return $flattenedKVs;
 
 
2787
  }
2788
 
2789
- return $arguments;
2790
- }
2791
- }
2792
 
2793
- /**
2794
- * @link http://redis.io/commands/keys
2795
- * @author Daniele Alessandri <suppakilla@gmail.com>
2796
- */
2797
- class KeyKeys extends Command
2798
- {
2799
- /**
2800
- * {@inheritdoc}
2801
- */
2802
- public function getId()
2803
- {
2804
- return 'KEYS';
2805
- }
2806
- }
2807
 
2808
- /**
2809
- * @link http://redis.io/commands/pttl
2810
- * @author Daniele Alessandri <suppakilla@gmail.com>
2811
- */
2812
- class KeyPreciseTimeToLive extends KeyTimeToLive
2813
- {
2814
- /**
2815
- * {@inheritdoc}
2816
- */
2817
- public function getId()
2818
- {
2819
- return 'PTTL';
2820
- }
2821
- }
2822
 
2823
- /**
2824
- * @link http://redis.io/commands/randomkey
2825
- * @author Daniele Alessandri <suppakilla@gmail.com>
2826
- */
2827
- class KeyRandom extends Command
2828
- {
2829
- /**
2830
- * {@inheritdoc}
2831
- */
2832
- public function getId()
2833
- {
2834
- return 'RANDOMKEY';
2835
- }
2836
 
2837
- /**
2838
- * {@inheritdoc}
2839
- */
2840
- public function parseResponse($data)
2841
- {
2842
- return $data !== '' ? $data : null;
2843
- }
2844
- }
2845
 
2846
- /**
2847
- * @link http://redis.io/commands/pexpireat
2848
- * @author Daniele Alessandri <suppakilla@gmail.com>
2849
- */
2850
- class KeyPreciseExpireAt extends KeyExpireAt
2851
- {
2852
- /**
2853
- * {@inheritdoc}
2854
- */
2855
- public function getId()
2856
- {
2857
- return 'PEXPIREAT';
2858
- }
2859
- }
2860
 
2861
- /**
2862
- * @link http://redis.io/commands/pexpire
2863
- * @author Daniele Alessandri <suppakilla@gmail.com>
2864
- */
2865
- class KeyPreciseExpire extends KeyExpire
2866
- {
2867
- /**
2868
- * {@inheritdoc}
2869
- */
2870
- public function getId()
2871
- {
2872
- return 'PEXPIRE';
2873
  }
2874
  }
2875
 
2876
  /**
2877
- * @link http://redis.io/commands/move
 
 
 
 
 
 
2878
  * @author Daniele Alessandri <suppakilla@gmail.com>
2879
  */
2880
- class KeyMove extends Command
2881
  {
2882
- /**
2883
- * {@inheritdoc}
2884
- */
2885
- public function getId()
2886
- {
2887
- return 'MOVE';
2888
- }
2889
 
2890
  /**
2891
- * {@inheritdoc}
 
 
2892
  */
2893
- public function parseResponse($data)
2894
  {
2895
- return (bool) $data;
2896
- }
2897
- }
 
 
2898
 
2899
- /**
2900
- * @link http://redis.io/commands/persist
2901
- * @author Daniele Alessandri <suppakilla@gmail.com>
2902
- */
2903
- class KeyPersist extends Command
2904
- {
2905
- /**
2906
- * {@inheritdoc}
2907
- */
2908
- public function getId()
2909
- {
2910
- return 'PERSIST';
2911
  }
2912
 
2913
  /**
2914
- * {@inheritdoc}
 
 
 
 
 
2915
  */
2916
- public function parseResponse($data)
2917
  {
2918
- return (bool) $data;
2919
- }
2920
- }
2921
 
2922
- /**
2923
- * @link http://redis.io/commands/lpushx
2924
- * @author Daniele Alessandri <suppakilla@gmail.com>
2925
- */
2926
- class ListPushHeadX extends Command
2927
- {
2928
- /**
2929
- * {@inheritdoc}
2930
- */
2931
- public function getId()
2932
- {
2933
- return 'LPUSHX';
2934
  }
2935
- }
2936
 
2937
- /**
2938
- * @link http://redis.io/commands/hkeys
2939
- * @author Daniele Alessandri <suppakilla@gmail.com>
2940
- */
2941
- class HashKeys extends Command
2942
- {
2943
  /**
2944
  * {@inheritdoc}
2945
  */
2946
  public function getId()
2947
  {
2948
- return 'HKEYS';
2949
  }
2950
- }
2951
 
2952
- /**
2953
- * @link http://redis.io/commands/hmget
2954
- * @author Daniele Alessandri <suppakilla@gmail.com>
2955
- */
2956
- class HashGetMultiple extends Command
2957
- {
2958
  /**
2959
  * {@inheritdoc}
2960
  */
2961
- public function getId()
2962
  {
2963
- return 'HMGET';
 
2964
  }
2965
 
2966
  /**
2967
  * {@inheritdoc}
2968
  */
2969
- protected function filterArguments(array $arguments)
2970
  {
2971
- return self::normalizeVariadic($arguments);
2972
  }
2973
- }
2974
 
2975
- /**
2976
- * @link http://redis.io/commands/hgetall
2977
- * @author Daniele Alessandri <suppakilla@gmail.com>
2978
- */
2979
- class HashGetAll extends Command
2980
- {
2981
  /**
2982
  * {@inheritdoc}
2983
  */
2984
- public function getId()
2985
  {
2986
- return 'HGETALL';
2987
  }
2988
 
2989
  /**
2990
  * {@inheritdoc}
2991
  */
2992
- public function parseResponse($data)
2993
  {
2994
- $result = array();
2995
-
2996
- for ($i = 0; $i < count($data); $i++) {
2997
- $result[$data[$i]] = $data[++$i];
2998
  }
2999
-
3000
- return $result;
3001
- }
3002
- }
3003
-
3004
- /**
3005
- * @link http://redis.io/commands/flushall
3006
- * @author Daniele Alessandri <suppakilla@gmail.com>
3007
- */
3008
- class ServerFlushAll extends Command
3009
- {
3010
- /**
3011
- * {@inheritdoc}
3012
- */
3013
- public function getId()
3014
- {
3015
- return 'FLUSHALL';
3016
  }
3017
- }
3018
 
3019
- /**
3020
- * @link http://redis.io/commands/dbsize
3021
- * @author Daniele Alessandri <suppakilla@gmail.com>
3022
- */
3023
- class ServerDatabaseSize extends Command
3024
- {
3025
  /**
3026
  * {@inheritdoc}
3027
  */
3028
- public function getId()
3029
  {
3030
- return 'DBSIZE';
3031
  }
3032
- }
3033
 
3034
- /**
3035
- * @link http://redis.io/commands/config-set
3036
- * @link http://redis.io/commands/config-get
3037
- * @link http://redis.io/commands/config-resetstat
3038
- * @link http://redis.io/commands/config-rewrite
3039
- * @author Daniele Alessandri <suppakilla@gmail.com>
3040
- */
3041
- class ServerConfig extends Command
3042
- {
3043
  /**
3044
  * {@inheritdoc}
3045
  */
3046
- public function getId()
3047
  {
3048
- return 'CONFIG';
 
 
3049
  }
3050
 
3051
  /**
@@ -3053,236 +3071,187 @@ class ServerConfig extends Command
3053
  */
3054
  public function parseResponse($data)
3055
  {
3056
- if (is_array($data)) {
3057
- $result = array();
3058
-
3059
- for ($i = 0; $i < count($data); $i++) {
3060
- $result[$data[$i]] = $data[++$i];
3061
- }
3062
-
3063
- return $result;
3064
- }
3065
-
3066
  return $data;
3067
  }
3068
  }
3069
 
3070
  /**
3071
- * @link http://redis.io/commands/client-list
3072
- * @link http://redis.io/commands/client-kill
3073
- * @link http://redis.io/commands/client-getname
3074
- * @link http://redis.io/commands/client-setname
3075
  * @author Daniele Alessandri <suppakilla@gmail.com>
3076
  */
3077
- class ServerClient extends Command
3078
  {
3079
  /**
3080
- * {@inheritdoc}
 
 
3081
  */
3082
- public function getId()
3083
- {
3084
- return 'CLIENT';
3085
- }
3086
 
3087
  /**
3088
- * {@inheritdoc}
 
 
 
 
 
 
3089
  */
3090
- public function parseResponse($data)
3091
  {
3092
- $args = array_change_key_case($this->getArguments(), CASE_UPPER);
3093
-
3094
- switch (strtoupper($args[0])) {
3095
- case 'LIST':
3096
- return $this->parseClientList($data);
3097
- case 'KILL':
3098
- case 'GETNAME':
3099
- case 'SETNAME':
3100
- default:
3101
- return $data;
3102
- }
3103
  }
3104
 
3105
  /**
3106
- * Parses the response to CLIENT LIST and returns a structured list.
3107
- *
3108
- * @param string $data Response buffer.
3109
  *
3110
  * @return array
3111
  */
3112
- protected function parseClientList($data)
3113
  {
3114
- $clients = array();
3115
-
3116
- foreach (explode("\n", $data, -1) as $clientData) {
3117
- $client = array();
3118
-
3119
- foreach (explode(' ', $clientData) as $kv) {
3120
- @list($k, $v) = explode('=', $kv);
3121
- $client[$k] = $v;
3122
- }
3123
 
3124
- $clients[] = $client;
 
 
 
 
 
 
3125
  }
3126
 
3127
- return $clients;
3128
  }
3129
- }
3130
 
3131
- /**
3132
- * @link http://redis.io/commands/command
3133
- * @author Daniele Alessandri <suppakilla@gmail.com>
3134
- */
3135
- class ServerCommand extends Command
3136
- {
3137
  /**
3138
- * {@inheritdoc}
3139
  */
3140
- public function getId()
3141
  {
3142
- return 'COMMAND';
 
 
 
3143
  }
3144
  }
3145
 
3146
  /**
3147
- * @link http://redis.io/commands/flushdb
3148
  * @author Daniele Alessandri <suppakilla@gmail.com>
3149
  */
3150
- class ServerFlushDatabase extends Command
3151
  {
3152
  /**
3153
  * {@inheritdoc}
3154
  */
3155
  public function getId()
3156
  {
3157
- return 'FLUSHDB';
3158
  }
3159
- }
3160
 
3161
- /**
3162
- * @link http://redis.io/commands/hget
3163
- * @author Daniele Alessandri <suppakilla@gmail.com>
3164
- */
3165
- class HashGet extends Command
3166
- {
3167
  /**
3168
  * {@inheritdoc}
3169
  */
3170
- public function getId()
3171
  {
3172
- return 'HGET';
3173
  }
3174
  }
3175
 
3176
  /**
3177
- * @link http://redis.io/commands/save
3178
  * @author Daniele Alessandri <suppakilla@gmail.com>
3179
  */
3180
- class ServerSave extends Command
3181
  {
3182
  /**
3183
  * {@inheritdoc}
3184
  */
3185
  public function getId()
3186
  {
3187
- return 'SAVE';
3188
  }
3189
  }
3190
 
3191
  /**
3192
- * @link http://redis.io/commands/script
3193
  * @author Daniele Alessandri <suppakilla@gmail.com>
3194
  */
3195
- class ServerScript extends Command
3196
  {
3197
  /**
3198
  * {@inheritdoc}
3199
  */
3200
  public function getId()
3201
  {
3202
- return 'SCRIPT';
3203
  }
3204
  }
3205
 
3206
  /**
3207
- * @link http://redis.io/commands/object
3208
  * @author Daniele Alessandri <suppakilla@gmail.com>
3209
  */
3210
- class ServerObject extends Command
3211
  {
3212
  /**
3213
  * {@inheritdoc}
3214
  */
3215
  public function getId()
3216
  {
3217
- return 'OBJECT';
3218
  }
3219
  }
3220
 
3221
  /**
3222
- * @link http://redis.io/commands/monitor
3223
  * @author Daniele Alessandri <suppakilla@gmail.com>
3224
  */
3225
- class ServerMonitor extends Command
3226
  {
3227
  /**
3228
  * {@inheritdoc}
3229
  */
3230
  public function getId()
3231
  {
3232
- return 'MONITOR';
3233
  }
3234
- }
3235
 
3236
- /**
3237
- * @link http://redis.io/commands/info
3238
- * @author Daniele Alessandri <suppakilla@gmail.com>
3239
- */
3240
- class ServerInfoV26x extends ServerInfo
3241
- {
3242
  /**
3243
  * {@inheritdoc}
3244
  */
3245
  public function parseResponse($data)
3246
  {
3247
- $info = array();
3248
- $current = null;
3249
- $infoLines = preg_split('/\r?\n/', $data);
3250
-
3251
- if (isset($infoLines[0]) && $infoLines[0][0] !== '#') {
3252
- return parent::parseResponse($data);
3253
- }
3254
-
3255
- foreach ($infoLines as $row) {
3256
- if ($row === '') {
3257
- continue;
3258
- }
3259
-
3260
- if (preg_match('/^# (\w+)$/', $row, $matches)) {
3261
- $info[$matches[1]] = array();
3262
- $current = &$info[$matches[1]];
3263
- continue;
3264
- }
3265
 
3266
- list($k, $v) = $this->parseRow($row);
3267
- $current[$k] = $v;
3268
  }
3269
-
3270
- return $info;
3271
  }
3272
- }
3273
 
3274
- /**
3275
- * @link http://redis.io/commands/lastsave
3276
- * @author Daniele Alessandri <suppakilla@gmail.com>
3277
- */
3278
- class ServerLastSave extends Command
3279
- {
3280
  /**
3281
- * {@inheritdoc}
 
 
 
 
3282
  */
3283
- public function getId()
3284
  {
3285
- return 'LASTSAVE';
 
 
 
 
 
 
 
3286
  }
3287
  }
3288
 
@@ -3310,17 +3279,20 @@ class ServerBackgroundSave extends Command
3310
  }
3311
 
3312
  /**
3313
- * @link http://redis.io/commands/bgrewriteaof
 
 
 
3314
  * @author Daniele Alessandri <suppakilla@gmail.com>
3315
  */
3316
- class ServerBackgroundRewriteAOF extends Command
3317
  {
3318
  /**
3319
  * {@inheritdoc}
3320
  */
3321
  public function getId()
3322
  {
3323
- return 'BGREWRITEAOF';
3324
  }
3325
 
3326
  /**
@@ -3328,127 +3300,178 @@ class ServerBackgroundRewriteAOF extends Command
3328
  */
3329
  public function parseResponse($data)
3330
  {
3331
- return $data == 'Background append only file rewriting started';
 
 
 
 
 
 
 
 
 
 
3332
  }
3333
- }
3334
 
3335
- /**
3336
- * @link http://redis.io/commands/ltrim
3337
- * @author Daniele Alessandri <suppakilla@gmail.com>
3338
- */
3339
- class ListTrim extends Command
3340
- {
3341
  /**
3342
- * {@inheritdoc}
 
 
 
 
3343
  */
3344
- public function getId()
3345
  {
3346
- return 'LTRIM';
 
 
 
 
 
 
 
 
 
 
 
 
 
3347
  }
3348
  }
3349
 
3350
  /**
3351
- * Defines a command whose keys can be prefixed.
3352
- *
3353
  * @author Daniele Alessandri <suppakilla@gmail.com>
3354
  */
3355
- interface PrefixableCommandInterface extends CommandInterface
3356
  {
3357
  /**
3358
- * Prefixes all the keys found in the arguments of the command.
3359
- *
3360
- * @param string $prefix String used to prefix the keys.
3361
  */
3362
- public function prefixKeys($prefix);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3363
  }
3364
 
3365
  /**
3366
- * @link http://redis.io/commands/lset
3367
  * @author Daniele Alessandri <suppakilla@gmail.com>
3368
  */
3369
- class ListSet extends Command
3370
  {
3371
  /**
3372
  * {@inheritdoc}
3373
  */
3374
  public function getId()
3375
  {
3376
- return 'LSET';
3377
  }
3378
  }
3379
 
3380
  /**
3381
- * @link http://redis.io/commands/lrem
3382
  * @author Daniele Alessandri <suppakilla@gmail.com>
3383
  */
3384
- class ListRemove extends Command
3385
  {
3386
  /**
3387
  * {@inheritdoc}
3388
  */
3389
  public function getId()
3390
  {
3391
- return 'LREM';
3392
  }
3393
  }
3394
 
3395
  /**
3396
- * @link http://redis.io/commands/rpushx
3397
  * @author Daniele Alessandri <suppakilla@gmail.com>
3398
  */
3399
- class ListPushTailX extends Command
3400
  {
3401
  /**
3402
  * {@inheritdoc}
3403
  */
3404
  public function getId()
3405
  {
3406
- return 'RPUSHX';
3407
  }
3408
  }
3409
 
3410
  /**
3411
- * @link http://redis.io/commands/lrange
3412
  * @author Daniele Alessandri <suppakilla@gmail.com>
3413
  */
3414
- class ListRange extends Command
3415
  {
3416
  /**
3417
  * {@inheritdoc}
3418
  */
3419
  public function getId()
3420
  {
3421
- return 'LRANGE';
3422
  }
3423
  }
3424
 
3425
  /**
3426
- * @link http://redis.io/commands/publish
3427
  * @author Daniele Alessandri <suppakilla@gmail.com>
3428
  */
3429
- class PubSubPublish extends Command
3430
  {
3431
  /**
3432
  * {@inheritdoc}
3433
  */
3434
  public function getId()
3435
  {
3436
- return 'PUBLISH';
3437
  }
3438
  }
3439
 
3440
  /**
3441
- * @link http://redis.io/commands/pubsub
 
 
 
3442
  * @author Daniele Alessandri <suppakilla@gmail.com>
3443
  */
3444
- class PubSubPubsub extends Command
3445
  {
3446
  /**
3447
  * {@inheritdoc}
3448
  */
3449
  public function getId()
3450
  {
3451
- return 'PUBSUB';
3452
  }
3453
 
3454
  /**
@@ -3456,288 +3479,287 @@ class PubSubPubsub extends Command
3456
  */
3457
  public function parseResponse($data)
3458
  {
3459
- switch (strtolower($this->getArgument(0))) {
3460
- case 'numsub':
3461
- return self::processNumsub($data);
3462
-
3463
- default:
3464
- return $data;
3465
- }
3466
- }
3467
-
3468
- /**
3469
- * Returns the processed response to PUBSUB NUMSUB.
3470
- *
3471
- * @param array $channels List of channels
3472
- *
3473
- * @return array
3474
- */
3475
- protected static function processNumsub(array $channels)
3476
- {
3477
- $processed = array();
3478
- $count = count($channels);
3479
-
3480
- for ($i = 0; $i < $count; $i++) {
3481
- $processed[$channels[$i]] = $channels[++$i];
3482
- }
3483
-
3484
- return $processed;
3485
- }
3486
- }
3487
 
3488
- /**
3489
- * Class for generic "anonymous" Redis commands.
3490
- *
3491
- * This command class does not filter input arguments or parse responses, but
3492
- * can be used to leverage the standard Predis API to execute any command simply
3493
- * by providing the needed arguments following the command signature as defined
3494
- * by Redis in its documentation.
3495
- *
3496
- * @author Daniele Alessandri <suppakilla@gmail.com>
3497
- */
3498
- class RawCommand implements CommandInterface
3499
- {
3500
- private $slot;
3501
- private $commandID;
3502
- private $arguments;
3503
 
3504
- /**
3505
- * @param array $arguments Command ID and its arguments.
3506
- */
3507
- public function __construct(array $arguments)
3508
- {
3509
- if (!$arguments) {
3510
- throw new InvalidArgumentException(
3511
- 'The arguments array must contain at least the command ID.'
3512
- );
3513
  }
3514
 
3515
- $this->commandID = strtoupper(array_shift($arguments));
3516
- $this->arguments = $arguments;
3517
  }
 
3518
 
 
 
 
 
 
 
 
3519
  /**
3520
- * Creates a new raw command using a variadic method.
3521
- *
3522
- * @param string $commandID Redis command ID.
3523
- * @param string ... Arguments list for the command.
3524
  *
3525
- * @return CommandInterface
3526
  */
3527
- public static function create($commandID /* [ $arg, ... */)
3528
- {
3529
- $arguments = func_get_args();
3530
- $command = new self($arguments);
3531
-
3532
- return $command;
3533
- }
3534
 
 
 
 
 
 
 
3535
  /**
3536
  * {@inheritdoc}
3537
  */
3538
  public function getId()
3539
  {
3540
- return $this->commandID;
3541
  }
 
3542
 
 
 
 
 
 
 
3543
  /**
3544
  * {@inheritdoc}
3545
  */
3546
- public function setArguments(array $arguments)
3547
  {
3548
- $this->arguments = $arguments;
3549
- unset($this->slot);
3550
  }
 
3551
 
 
 
 
 
 
 
3552
  /**
3553
  * {@inheritdoc}
3554
  */
3555
- public function setRawArguments(array $arguments)
3556
  {
3557
- $this->setArguments($arguments);
3558
  }
 
3559
 
 
 
 
 
 
 
3560
  /**
3561
  * {@inheritdoc}
3562
  */
3563
- public function getArguments()
3564
  {
3565
- return $this->arguments;
3566
  }
 
3567
 
 
 
 
 
 
 
3568
  /**
3569
  * {@inheritdoc}
3570
  */
3571
- public function getArgument($index)
3572
  {
3573
- if (isset($this->arguments[$index])) {
3574
- return $this->arguments[$index];
3575
- }
3576
  }
 
3577
 
 
 
 
 
 
 
3578
  /**
3579
  * {@inheritdoc}
3580
  */
3581
- public function setSlot($slot)
3582
  {
3583
- $this->slot = $slot;
3584
  }
 
3585
 
 
 
 
 
 
 
3586
  /**
3587
  * {@inheritdoc}
3588
  */
3589
- public function getSlot()
3590
  {
3591
- if (isset($this->slot)) {
3592
- return $this->slot;
3593
- }
3594
  }
 
3595
 
 
 
 
 
 
 
3596
  /**
3597
  * {@inheritdoc}
3598
  */
3599
- public function parseResponse($data)
3600
  {
3601
- return $data;
3602
  }
3603
  }
3604
 
3605
  /**
3606
- * Base class used to implement an higher level abstraction for commands based
3607
- * on Lua scripting with EVAL and EVALSHA.
3608
- *
3609
- * @link http://redis.io/commands/eval
3610
  * @author Daniele Alessandri <suppakilla@gmail.com>
3611
  */
3612
- abstract class ScriptCommand extends ServerEvalSHA
3613
  {
3614
  /**
3615
- * Gets the body of a Lua script.
3616
- *
3617
- * @return string
3618
- */
3619
- abstract public function getScript();
3620
-
3621
- /**
3622
- * Specifies the number of arguments that should be considered as keys.
3623
- *
3624
- * The default behaviour for the base class is to return 0 to indicate that
3625
- * all the elements of the arguments array should be considered as keys, but
3626
- * subclasses can enforce a static number of keys.
3627
- *
3628
- * @return int
3629
  */
3630
- protected function getKeysCount()
3631
  {
3632
- return 0;
3633
  }
 
3634
 
 
 
 
 
 
 
3635
  /**
3636
- * Returns the elements from the arguments that are identified as keys.
3637
- *
3638
- * @return array
3639
  */
3640
- public function getKeys()
3641
  {
3642
- return array_slice($this->getArguments(), 2, $this->getKeysCount());
3643
  }
 
3644
 
 
 
 
 
 
 
3645
  /**
3646
  * {@inheritdoc}
3647
  */
3648
- protected function filterArguments(array $arguments)
3649
  {
3650
- if (($numkeys = $this->getKeysCount()) && $numkeys < 0) {
3651
- $numkeys = count($arguments) + $numkeys;
3652
- }
3653
-
3654
- return array_merge(array(sha1($this->getScript()), (int) $numkeys), $arguments);
3655
  }
 
3656
 
 
 
 
 
 
 
3657
  /**
3658
- * @return array
3659
  */
3660
- public function getEvalArguments()
3661
  {
3662
- $arguments = $this->getArguments();
3663
- $arguments[0] = $this->getScript();
3664
-
3665
- return $arguments;
3666
  }
3667
  }
3668
 
3669
  /**
3670
- * @link http://redis.io/commands/punsubscribe
3671
  * @author Daniele Alessandri <suppakilla@gmail.com>
3672
  */
3673
- class PubSubUnsubscribeByPattern extends PubSubUnsubscribe
3674
  {
3675
  /**
3676
  * {@inheritdoc}
3677
  */
3678
  public function getId()
3679
  {
3680
- return 'PUNSUBSCRIBE';
3681
  }
3682
  }
3683
 
3684
  /**
3685
- * @link http://redis.io/commands/hincrby
3686
  * @author Daniele Alessandri <suppakilla@gmail.com>
3687
  */
3688
- class HashIncrementBy extends Command
3689
  {
3690
  /**
3691
  * {@inheritdoc}
3692
  */
3693
  public function getId()
3694
  {
3695
- return 'HINCRBY';
3696
  }
3697
  }
3698
 
3699
  /**
3700
- * @link http://redis.io/commands/hincrbyfloat
3701
  * @author Daniele Alessandri <suppakilla@gmail.com>
3702
  */
3703
- class HashIncrementByFloat extends Command
3704
  {
3705
  /**
3706
  * {@inheritdoc}
3707
  */
3708
  public function getId()
3709
  {
3710
- return 'HINCRBYFLOAT';
3711
  }
3712
  }
3713
 
3714
  /**
3715
- * @link http://redis.io/commands/psubscribe
3716
  * @author Daniele Alessandri <suppakilla@gmail.com>
3717
  */
3718
- class PubSubSubscribeByPattern extends PubSubSubscribe
3719
  {
3720
  /**
3721
  * {@inheritdoc}
3722
  */
3723
  public function getId()
3724
  {
3725
- return 'PSUBSCRIBE';
3726
  }
3727
  }
3728
 
3729
  /**
3730
- * @link http://redis.io/commands/hvals
3731
  * @author Daniele Alessandri <suppakilla@gmail.com>
3732
  */
3733
- class HashValues extends Command
3734
  {
3735
  /**
3736
  * {@inheritdoc}
3737
  */
3738
  public function getId()
3739
  {
3740
- return 'HVALS';
3741
  }
3742
  }
3743
 
@@ -3934,6 +3956,8 @@ abstract class AbstractConnection implements NodeConnectionInterface
3934
  * @param ParametersInterface $parameters Initialization parameters for the connection.
3935
  *
3936
  * @return ParametersInterface
 
 
3937
  */
3938
  protected function assertParameters(ParametersInterface $parameters)
3939
  {
@@ -4207,6 +4231,14 @@ class StreamConnection extends AbstractConnection
4207
  $this->onConnectionError(trim($errstr), $errno);
4208
  }
4209
 
 
 
 
 
 
 
 
 
4210
  return $resource;
4211
  }
4212
 
@@ -4721,6 +4753,8 @@ class WebdisConnection implements NodeConnectionInterface
4721
 
4722
  /**
4723
  * @param ParametersInterface $parameters Initialization parameters for the connection.
 
 
4724
  */
4725
  public function __construct(ParametersInterface $parameters)
4726
  {
@@ -5568,6 +5602,8 @@ class Parameters implements ParametersInterface
5568
  * @param string $uri URI string.
5569
  *
5570
  * @return array
 
 
5571
  */
5572
  public static function parse($uri)
5573
  {
@@ -5658,6 +5694,8 @@ class Factory implements FactoryInterface
5658
  * @param mixed $initializer FQN of a connection class or a callable for lazy initialization.
5659
  *
5660
  * @return mixed
 
 
5661
  */
5662
  protected function checkInitializer($initializer)
5663
  {
@@ -5916,6 +5954,8 @@ abstract class RedisProfile implements ProfileInterface
5916
  *
5917
  * @param string $commandID Command ID.
5918
  * @param string $class Fully-qualified name of a Predis\Command\CommandInterface.
 
 
5919
  */
5920
  public function defineCommand($commandID, $class)
5921
  {
@@ -6179,6 +6219,9 @@ class RedisVersion300 extends RedisProfile
6179
  /* commands operating on the key space */
6180
  'SCAN' => 'Predis\Command\KeyScan',
6181
 
 
 
 
6182
  /* commands operating on sets */
6183
  'SSCAN' => 'Predis\Command\SetScan',
6184
 
@@ -6654,6 +6697,9 @@ class RedisVersion280 extends RedisProfile
6654
  /* commands operating on the key space */
6655
  'SCAN' => 'Predis\Command\KeyScan',
6656
 
 
 
 
6657
  /* commands operating on sets */
6658
  'SSCAN' => 'Predis\Command\SetScan',
6659
 
@@ -7111,6 +7157,8 @@ final class Factory
7111
  *
7112
  * @param string $alias Profile version or alias.
7113
  * @param string $class FQN of a class implementing Predis\Profile\ProfileInterface.
 
 
7114
  */
7115
  public static function define($alias, $class)
7116
  {
@@ -7461,6 +7509,7 @@ abstract class PredisException extends Exception
7461
  * @method $this zadd($key, array $membersAndScoresDictionary)
7462
  * @method $this zcard($key)
7463
  * @method $this zcount($key, $min, $max)
 
7464
  * @method $this zinterstore($destination, array $keys, array $options = null)
7465
  * @method $this zrange($key, $start, $stop, array $options = null)
7466
  * @method $this zrangebyscore($key, $min, $max, array $options = null)
@@ -7707,6 +7756,7 @@ abstract class CommunicationException extends PredisException
7707
  * @method int zadd($key, array $membersAndScoresDictionary)
7708
  * @method int zcard($key)
7709
  * @method string zcount($key, $min, $max)
 
7710
  * @method int zinterstore($destination, array $keys, array $options = null)
7711
  * @method array zrange($key, $start, $stop, array $options = null)
7712
  * @method array zrangebyscore($key, $min, $max, array $options = null)
@@ -7853,7 +7903,7 @@ class ClientException extends PredisException
7853
  */
7854
  class Client implements ClientInterface
7855
  {
7856
- const VERSION = '1.0.0';
7857
 
7858
  protected $connection;
7859
  protected $options;
@@ -7878,6 +7928,8 @@ class Client implements ClientInterface
7878
  * @param mixed $options Client options.
7879
  *
7880
  * @return OptionsInterface
 
 
7881
  */
7882
  protected function createOptions($options)
7883
  {
@@ -7908,6 +7960,8 @@ class Client implements ClientInterface
7908
  * @param mixed $parameters Connection parameters or connection instance.
7909
  *
7910
  * @return ConnectionInterface
 
 
7911
  */
7912
  protected function createConnection($parameters)
7913
  {
@@ -7999,6 +8053,8 @@ class Client implements ClientInterface
7999
  * @param string $connectionID Identifier of a connection.
8000
  *
8001
  * @return Client
 
 
8002
  */
8003
  public function getClientFor($connectionID)
8004
  {
@@ -9455,8 +9511,12 @@ class SortedSetKey extends CursorBasedIterator
9455
  */
9456
  protected function extractNext()
9457
  {
9458
- $this->position = key($this->elements);
9459
- $this->current = array_shift($this->elements);
 
 
 
 
9460
  }
9461
  }
9462
 
@@ -9590,6 +9650,8 @@ class ListKey implements Iterator
9590
  * @param ClientInterface $client Client connected to Redis.
9591
  * @param string $key Redis list key.
9592
  * @param int $count Number of items retrieved on each fetch operation.
 
 
9593
  */
9594
  public function __construct(ClientInterface $client, $key, $count = 10)
9595
  {
@@ -9942,6 +10004,8 @@ abstract class ClusterStrategy implements StrategyInterface
9942
  *
9943
  * @param string $commandID Command ID.
9944
  * @param mixed $callback A valid callable object, or NULL to unset the handler.
 
 
9945
  */
9946
  public function setCommandHandler($commandID, $callback = null)
9947
  {
@@ -10101,11 +10165,6 @@ abstract class ClusterStrategy implements StrategyInterface
10101
  return $slot;
10102
  }
10103
 
10104
- /**
10105
- * {@inheritdoc}
10106
- */
10107
- abstract public function getSlotByKey($key);
10108
-
10109
  /**
10110
  * Checks if the specified array of keys will generate the same hash.
10111
  *
@@ -10152,11 +10211,6 @@ abstract class ClusterStrategy implements StrategyInterface
10152
 
10153
  return $key;
10154
  }
10155
-
10156
- /**
10157
- * {@inheritdoc}
10158
- */
10159
- abstract public function getDistributor();
10160
  }
10161
 
10162
  /**
@@ -10616,6 +10670,8 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10616
  * @param int $first Initial slot of the range.
10617
  * @param int $last Last slot of the range.
10618
  * @param NodeConnectionInterface|string $connection ID or connection instance.
 
 
10619
  */
10620
  public function setSlots($first, $last, $connection)
10621
  {
@@ -10705,6 +10761,8 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable
10705
  * @param int $slot Slot index.
10706
  *
10707
  * @return NodeConnectionInterface
 
 
10708
  */
10709
  public function getConnectionBySlot($slot)
10710
  {
@@ -12476,6 +12534,9 @@ class MultiBulkTuple extends MultiBulk implements OuterIterator
12476
  * Checks for valid preconditions.
12477
  *
12478
  * @param MultiBulk $iterator Inner multibulk response iterator.
 
 
 
12479
  */
12480
  protected function checkPreconditions(MultiBulk $iterator)
12481
  {
@@ -12932,6 +12993,8 @@ class KeyPrefixProcessor implements ProcessorInterface
12932
  *
12933
  * @param string $commandID The ID of the command to be handled.
12934
  * @param mixed $callback A valid callable object or NULL.
 
 
12935
  */
12936
  public function setCommandHandler($commandID, $callback = null)
12937
  {
@@ -13701,6 +13764,8 @@ class DispatcherLoop
13701
  * Checks if the passed argument is a valid callback.
13702
  *
13703
  * @param mixed $callable A callback.
 
 
13704
  */
13705
  protected function assertCallback($callable)
13706
  {
291
  }
292
  }
293
 
294
+ /**
295
+ * @link http://redis.io/commands/sinterstore
296
+ * @author Daniele Alessandri <suppakilla@gmail.com>
297
+ */
298
+ class SetIntersectionStore extends Command
299
+ {
300
+ /**
301
+ * {@inheritdoc}
302
+ */
303
+ public function getId()
304
+ {
305
+ return 'SINTERSTORE';
306
+ }
307
+
308
+ /**
309
+ * {@inheritdoc}
310
+ */
311
+ protected function filterArguments(array $arguments)
312
+ {
313
+ if (count($arguments) === 2 && is_array($arguments[1])) {
314
+ return array_merge(array($arguments[0]), $arguments[1]);
315
+ }
316
+
317
+ return $arguments;
318
+ }
319
+ }
320
+
321
  /**
322
  * @link http://redis.io/commands/sinter
323
  * @author Daniele Alessandri <suppakilla@gmail.com>
367
  }
368
 
369
  /**
370
+ * @link http://redis.io/commands/rename
371
  * @author Daniele Alessandri <suppakilla@gmail.com>
372
  */
373
+ class KeyRename extends Command
374
  {
375
  /**
376
  * {@inheritdoc}
377
  */
378
  public function getId()
379
  {
380
+ return 'RENAME';
381
  }
382
+ }
383
 
384
+ /**
385
+ * @link http://redis.io/commands/setex
386
+ * @author Daniele Alessandri <suppakilla@gmail.com>
387
+ */
388
+ class StringSetExpire extends Command
389
+ {
390
  /**
391
  * {@inheritdoc}
392
  */
393
+ public function getId()
394
  {
395
+ return 'SETEX';
 
 
 
 
396
  }
397
  }
398
 
399
  /**
400
+ * @link http://redis.io/commands/mset
401
  * @author Daniele Alessandri <suppakilla@gmail.com>
402
  */
403
+ class StringSetMultiple extends Command
404
  {
405
  /**
406
  * {@inheritdoc}
407
  */
408
  public function getId()
409
  {
410
+ return 'MSET';
411
  }
412
 
413
  /**
415
  */
416
  protected function filterArguments(array $arguments)
417
  {
418
+ if (count($arguments) === 1 && is_array($arguments[0])) {
419
+ $flattenedKVs = array();
420
+ $args = $arguments[0];
421
 
422
+ foreach ($args as $k => $v) {
423
+ $flattenedKVs[] = $k;
424
+ $flattenedKVs[] = $v;
425
+ }
426
+
427
+ return $flattenedKVs;
428
+ }
429
+
430
+ return $arguments;
 
 
 
431
  }
432
  }
433
 
455
  }
456
 
457
  /**
458
+ * @link http://redis.io/commands/blpop
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  * @author Daniele Alessandri <suppakilla@gmail.com>
460
  */
461
+ class ListPopFirstBlocking extends Command
462
  {
463
  /**
464
  * {@inheritdoc}
465
  */
466
  public function getId()
467
  {
468
+ return 'BLPOP';
469
  }
470
 
471
  /**
473
  */
474
  protected function filterArguments(array $arguments)
475
  {
476
+ if (count($arguments) === 2 && is_array($arguments[0])) {
477
+ list($arguments, $timeout) = $arguments;
478
+ array_push($arguments, $timeout);
479
+ }
480
+
481
+ return $arguments;
482
  }
483
  }
484
 
485
  /**
486
+ * @link http://redis.io/commands/unsubscribe
487
  * @author Daniele Alessandri <suppakilla@gmail.com>
488
  */
489
+ class PubSubUnsubscribe extends Command
490
  {
491
  /**
492
  * {@inheritdoc}
493
  */
494
  public function getId()
495
  {
496
+ return 'UNSUBSCRIBE';
497
  }
498
 
499
  /**
501
  */
502
  protected function filterArguments(array $arguments)
503
  {
504
+ return self::normalizeArguments($arguments);
 
 
 
 
 
505
  }
506
  }
507
 
604
  }
605
 
606
  /**
607
+ * @link http://redis.io/commands/evalsha
608
  * @author Daniele Alessandri <suppakilla@gmail.com>
609
  */
610
+ class ServerEvalSHA extends ServerEval
611
  {
612
  /**
613
  * {@inheritdoc}
614
  */
615
  public function getId()
616
  {
617
+ return 'EVALSHA';
618
  }
619
 
620
  /**
621
+ * Returns the SHA1 hash of the body of the script.
622
+ *
623
+ * @return string SHA1 hash.
624
  */
625
+ public function getScriptHash()
626
  {
627
+ return $this->getArgument(0);
628
+ }
629
+ }
630
 
631
+ /**
632
+ * @link http://redis.io/commands/expire
633
+ * @author Daniele Alessandri <suppakilla@gmail.com>
634
+ */
635
+ class KeyExpire extends Command
636
+ {
637
+ /**
638
+ * {@inheritdoc}
639
+ */
640
+ public function getId()
641
+ {
642
+ return 'EXPIRE';
643
+ }
644
 
645
+ /**
646
+ * {@inheritdoc}
647
+ */
648
+ public function parseResponse($data)
649
+ {
650
+ return (bool) $data;
651
+ }
652
+ }
653
 
654
+ /**
655
+ * @link http://redis.io/commands/subscribe
656
+ * @author Daniele Alessandri <suppakilla@gmail.com>
657
+ */
658
+ class PubSubSubscribe extends Command
659
+ {
660
+ /**
661
+ * {@inheritdoc}
662
+ */
663
+ public function getId()
664
+ {
665
+ return 'SUBSCRIBE';
666
  }
667
 
668
  /**
669
  * {@inheritdoc}
670
  */
671
+ protected function filterArguments(array $arguments)
672
  {
673
+ return self::normalizeArguments($arguments);
674
+ }
675
+ }
676
 
677
+ /**
678
+ * @link http://redis.io/commands/rpush
679
+ * @author Daniele Alessandri <suppakilla@gmail.com>
680
+ */
681
+ class ListPushTail extends Command
682
+ {
683
+ /**
684
+ * {@inheritdoc}
685
+ */
686
+ public function getId()
687
+ {
688
+ return 'RPUSH';
689
+ }
690
 
691
+ /**
692
+ * {@inheritdoc}
693
+ */
694
+ protected function filterArguments(array $arguments)
695
+ {
696
+ return self::normalizeVariadic($arguments);
697
+ }
698
+ }
699
 
700
+ /**
701
+ * @link http://redis.io/commands/ttl
702
+ * @author Daniele Alessandri <suppakilla@gmail.com>
703
+ */
704
+ class KeyTimeToLive extends Command
705
+ {
706
+ /**
707
+ * {@inheritdoc}
708
+ */
709
+ public function getId()
710
+ {
711
+ return 'TTL';
712
  }
713
  }
714
 
778
  }
779
 
780
  /**
781
+ * @link http://redis.io/commands/zrangebyscore
782
  * @author Daniele Alessandri <suppakilla@gmail.com>
783
  */
784
+ class ZSetRangeByScore extends ZSetRange
785
  {
786
  /**
787
  * {@inheritdoc}
788
  */
789
  public function getId()
790
  {
791
+ return 'ZRANGEBYSCORE';
792
  }
793
 
794
  /**
795
  * {@inheritdoc}
796
  */
797
+ protected function prepareOptions($options)
798
  {
799
+ $opts = array_change_key_case($options, CASE_UPPER);
800
+ $finalizedOpts = array();
 
801
 
802
+ if (isset($opts['LIMIT']) && is_array($opts['LIMIT'])) {
803
+ $limit = array_change_key_case($opts['LIMIT'], CASE_UPPER);
 
 
804
 
805
+ $finalizedOpts[] = 'LIMIT';
806
+ $finalizedOpts[] = isset($limit['OFFSET']) ? $limit['OFFSET'] : $limit[0];
807
+ $finalizedOpts[] = isset($limit['COUNT']) ? $limit['COUNT'] : $limit[1];
808
  }
809
 
810
+ return array_merge($finalizedOpts, parent::prepareOptions($options));
811
  }
 
812
 
813
+ /**
814
+ * {@inheritdoc}
815
+ */
816
+ protected function withScores()
817
+ {
818
+ $arguments = $this->getArguments();
819
+
820
+ for ($i = 3; $i < count($arguments); $i++) {
821
+ switch (strtoupper($arguments[$i])) {
822
+ case 'WITHSCORES':
823
+ return true;
824
+
825
+ case 'LIMIT':
826
+ $i += 2;
827
+ break;
828
+ }
829
+ }
830
+
831
+ return false;
832
+ }
833
+ }
834
+
835
+ /**
836
+ * @link http://redis.io/commands/zremrangebyrank
837
  * @author Daniele Alessandri <suppakilla@gmail.com>
838
  */
839
+ class ZSetRemoveRangeByRank extends Command
840
  {
841
  /**
842
  * {@inheritdoc}
843
  */
844
  public function getId()
845
  {
846
+ return 'ZREMRANGEBYRANK';
847
  }
848
  }
849
 
850
  /**
851
+ * @link http://redis.io/commands/spop
852
  * @author Daniele Alessandri <suppakilla@gmail.com>
853
  */
854
+ class SetPop extends Command
855
  {
856
  /**
857
  * {@inheritdoc}
858
  */
859
  public function getId()
860
  {
861
+ return 'SPOP';
862
+ }
863
+ }
864
+
865
+ /**
866
+ * @link http://redis.io/commands/smove
867
+ * @author Daniele Alessandri <suppakilla@gmail.com>
868
+ */
869
+ class SetMove extends Command
870
+ {
871
+ /**
872
+ * {@inheritdoc}
873
+ */
874
+ public function getId()
875
+ {
876
+ return 'SMOVE';
877
  }
878
 
879
  /**
886
  }
887
 
888
  /**
889
+ * @link http://redis.io/commands/sismember
890
  * @author Daniele Alessandri <suppakilla@gmail.com>
891
  */
892
+ class SetIsMember extends Command
893
  {
894
  /**
895
  * {@inheritdoc}
896
  */
897
  public function getId()
898
  {
899
+ return 'SISMEMBER';
900
  }
901
 
902
  /**
903
  * {@inheritdoc}
904
  */
905
+ public function parseResponse($data)
906
  {
907
+ return (bool) $data;
908
  }
909
  }
910
 
911
  /**
912
+ * @link http://redis.io/commands/smembers
913
  * @author Daniele Alessandri <suppakilla@gmail.com>
914
  */
915
+ class SetMembers extends Command
916
  {
917
  /**
918
  * {@inheritdoc}
919
  */
920
  public function getId()
921
  {
922
+ return 'SMEMBERS';
923
  }
924
+ }
925
 
926
+ /**
927
+ * @link http://redis.io/commands/zremrangebyscore
928
+ * @author Daniele Alessandri <suppakilla@gmail.com>
929
+ */
930
+ class ZSetRemoveRangeByScore extends Command
931
+ {
932
  /**
933
+ * {@inheritdoc}
 
 
934
  */
935
+ public function getId()
936
  {
937
+ return 'ZREMRANGEBYSCORE';
938
  }
939
  }
940
 
941
  /**
942
+ * @link http://redis.io/commands/srandmember
943
  * @author Daniele Alessandri <suppakilla@gmail.com>
944
  */
945
+ class SetRandomMember extends Command
946
  {
947
  /**
948
  * {@inheritdoc}
949
  */
950
  public function getId()
951
  {
952
+ return 'SRANDMEMBER';
953
  }
954
  }
955
 
956
  /**
957
+ * @link http://redis.io/commands/sscan
958
  * @author Daniele Alessandri <suppakilla@gmail.com>
959
  */
960
+ class SetScan extends Command
961
  {
962
  /**
963
  * {@inheritdoc}
964
  */
965
  public function getId()
966
  {
967
+ return 'SSCAN';
968
+ }
969
+
970
+ /**
971
+ * {@inheritdoc}
972
+ */
973
+ protected function filterArguments(array $arguments)
974
+ {
975
+ if (count($arguments) === 3 && is_array($arguments[2])) {
976
+ $options = $this->prepareOptions(array_pop($arguments));
977
+ $arguments = array_merge($arguments, $options);
978
+ }
979
+
980
+ return $arguments;
981
+ }
982
+
983
+ /**
984
+ * Returns a list of options and modifiers compatible with Redis.
985
+ *
986
+ * @param array $options List of options.
987
+ *
988
+ * @return array
989
+ */
990
+ protected function prepareOptions($options)
991
+ {
992
+ $options = array_change_key_case($options, CASE_UPPER);
993
+ $normalized = array();
994
+
995
+ if (!empty($options['MATCH'])) {
996
+ $normalized[] = 'MATCH';
997
+ $normalized[] = $options['MATCH'];
998
+ }
999
+
1000
+ if (!empty($options['COUNT'])) {
1001
+ $normalized[] = 'COUNT';
1002
+ $normalized[] = $options['COUNT'];
1003
+ }
1004
+
1005
+ return $normalized;
1006
  }
1007
  }
1008
 
1009
  /**
1010
+ * @link http://redis.io/commands/zremrangebylex
1011
  * @author Daniele Alessandri <suppakilla@gmail.com>
1012
  */
1013
+ class ZSetRemoveRangeByLex extends Command
1014
  {
1015
  /**
1016
  * {@inheritdoc}
1017
  */
1018
  public function getId()
1019
  {
1020
+ return 'ZREMRANGEBYLEX';
1021
  }
1022
  }
1023
 
1066
  }
1067
 
1068
  /**
1069
+ * @link http://redis.io/commands/append
1070
  * @author Daniele Alessandri <suppakilla@gmail.com>
1071
  */
1072
+ class StringAppend extends Command
1073
  {
1074
  /**
1075
  * {@inheritdoc}
1076
  */
1077
  public function getId()
1078
  {
1079
+ return 'APPEND';
1080
  }
1081
  }
1082
 
1083
  /**
1084
+ * @link http://redis.io/commands/sunion
1085
  * @author Daniele Alessandri <suppakilla@gmail.com>
1086
  */
1087
+ class SetUnion extends SetIntersection
1088
  {
1089
  /**
1090
  * {@inheritdoc}
1091
  */
1092
  public function getId()
1093
  {
1094
+ return 'SUNION';
1095
  }
1096
  }
1097
 
1098
  /**
1099
+ * @link http://redis.io/commands/sunionstore
1100
  * @author Daniele Alessandri <suppakilla@gmail.com>
1101
  */
1102
+ class SetUnionStore extends SetIntersectionStore
1103
  {
1104
  /**
1105
  * {@inheritdoc}
1106
  */
1107
  public function getId()
1108
  {
1109
+ return 'SUNIONSTORE';
1110
  }
1111
  }
1112
 
1113
  /**
1114
+ * @link http://redis.io/commands/srem
1115
  * @author Daniele Alessandri <suppakilla@gmail.com>
1116
  */
1117
+ class SetRemove extends Command
1118
  {
1119
  /**
1120
  * {@inheritdoc}
1121
  */
1122
  public function getId()
1123
  {
1124
+ return 'SREM';
1125
  }
1126
 
1127
  /**
1129
  */
1130
  protected function filterArguments(array $arguments)
1131
  {
1132
+ return self::normalizeVariadic($arguments);
1133
  }
1134
  }
1135
 
1136
  /**
1137
+ * @link http://redis.io/commands/zrevrange
1138
  * @author Daniele Alessandri <suppakilla@gmail.com>
1139
  */
1140
+ class ZSetReverseRange extends ZSetRange
1141
  {
1142
  /**
1143
  * {@inheritdoc}
1144
  */
1145
  public function getId()
1146
  {
1147
+ return 'ZREVRANGE';
1148
  }
1149
  }
1150
 
1151
  /**
1152
+ * @link http://redis.io/commands/slowlog
1153
  * @author Daniele Alessandri <suppakilla@gmail.com>
1154
  */
1155
+ class ServerSlowlog extends Command
1156
  {
1157
  /**
1158
  * {@inheritdoc}
1159
  */
1160
  public function getId()
1161
  {
1162
+ return 'SLOWLOG';
1163
  }
 
1164
 
 
 
 
 
 
 
1165
  /**
1166
  * {@inheritdoc}
1167
  */
1168
+ public function parseResponse($data)
1169
  {
1170
+ if (is_array($data)) {
1171
+ $log = array();
1172
+
1173
+ foreach ($data as $index => $entry) {
1174
+ $log[$index] = array(
1175
+ 'id' => $entry[0],
1176
+ 'timestamp' => $entry[1],
1177
+ 'duration' => $entry[2],
1178
+ 'command' => $entry[3],
1179
+ );
1180
+ }
1181
+
1182
+ return $log;
1183
+ }
1184
+
1185
+ return $data;
1186
  }
1187
  }
1188
 
1189
  /**
1190
+ * @link http://redis.io/commands/zscore
1191
  * @author Daniele Alessandri <suppakilla@gmail.com>
1192
  */
1193
+ class ZSetScore extends Command
1194
  {
1195
  /**
1196
  * {@inheritdoc}
1197
  */
1198
  public function getId()
1199
  {
1200
+ return 'ZSCORE';
1201
  }
1202
  }
1203
 
1204
  /**
1205
+ * @link http://redis.io/commands/slaveof
1206
  * @author Daniele Alessandri <suppakilla@gmail.com>
1207
  */
1208
+ class ServerSlaveOf extends Command
1209
  {
1210
  /**
1211
  * {@inheritdoc}
1212
  */
1213
  public function getId()
1214
  {
1215
+ return 'SLAVEOF';
1216
+ }
1217
+
1218
+ /**
1219
+ * {@inheritdoc}
1220
+ */
1221
+ protected function filterArguments(array $arguments)
1222
+ {
1223
+ if (count($arguments) === 0 || $arguments[0] === 'NO ONE') {
1224
+ return array('NO', 'ONE');
1225
+ }
1226
+
1227
+ return $arguments;
1228
  }
1229
  }
1230
 
1231
  /**
1232
+ * @link http://redis.io/commands/shutdown
1233
  * @author Daniele Alessandri <suppakilla@gmail.com>
1234
  */
1235
+ class ServerShutdown extends Command
1236
  {
1237
  /**
1238
  * {@inheritdoc}
1239
  */
1240
  public function getId()
1241
  {
1242
+ return 'SHUTDOWN';
1243
  }
1244
  }
1245
 
1246
  /**
1247
+ * @link http://redis.io/commands/script
1248
  * @author Daniele Alessandri <suppakilla@gmail.com>
1249
  */
1250
+ class ServerScript extends Command
1251
  {
1252
  /**
1253
  * {@inheritdoc}
1254
  */
1255
  public function getId()
1256
  {
1257
+ return 'SCRIPT';
1258
  }
1259
  }
1260
 
1261
  /**
1262
+ * @link http://redis.io/topics/sentinel
1263
  * @author Daniele Alessandri <suppakilla@gmail.com>
1264
  */
1265
+ class ServerSentinel extends Command
1266
  {
1267
  /**
1268
  * {@inheritdoc}
1269
  */
1270
  public function getId()
1271
  {
1272
+ return 'SENTINEL';
1273
  }
1274
 
1275
  /**
1276
  * {@inheritdoc}
1277
  */
1278
+ public function parseResponse($data)
1279
  {
1280
+ switch (strtolower($this->getArgument(0))) {
1281
+ case 'masters':
1282
+ case 'slaves':
1283
+ return self::processMastersOrSlaves($data);
1284
 
1285
+ default:
1286
+ return $data;
1287
+ }
1288
+ }
1289
+
1290
+ /**
1291
+ * Returns a processed response to SENTINEL MASTERS or SENTINEL SLAVES.
1292
+ *
1293
+ * @param array $servers List of Redis servers.
1294
+ *
1295
+ * @return array
1296
+ */
1297
+ protected static function processMastersOrSlaves(array $servers)
1298
+ {
1299
+ foreach ($servers as $idx => $node) {
1300
+ $processed = array();
1301
+ $count = count($node);
1302
+
1303
+ for ($i = 0; $i < $count; $i++) {
1304
+ $processed[$node[$i]] = $node[++$i];
1305
+ }
1306
+
1307
+ $servers[$idx] = $processed;
1308
+ }
1309
+
1310
+ return $servers;
1311
+ }
1312
+ }
1313
+
1314
+ /**
1315
+ * @link http://redis.io/commands/zscan
1316
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1317
+ */
1318
+ class ZSetScan extends Command
1319
+ {
1320
+ /**
1321
+ * {@inheritdoc}
1322
+ */
1323
+ public function getId()
1324
+ {
1325
+ return 'ZSCAN';
1326
+ }
1327
+
1328
+ /**
1329
+ * {@inheritdoc}
1330
+ */
1331
+ protected function filterArguments(array $arguments)
1332
+ {
1333
+ if (count($arguments) === 3 && is_array($arguments[2])) {
1334
+ $options = $this->prepareOptions(array_pop($arguments));
1335
+ $arguments = array_merge($arguments, $options);
1336
+ }
1337
+
1338
+ return $arguments;
1339
  }
1340
 
1341
  /**
1362
 
1363
  return $normalized;
1364
  }
1365
+
1366
+ /**
1367
+ * {@inheritdoc}
1368
+ */
1369
+ public function parseResponse($data)
1370
+ {
1371
+ if (is_array($data)) {
1372
+ $members = $data[1];
1373
+ $result = array();
1374
+
1375
+ for ($i = 0; $i < count($members); $i++) {
1376
+ $result[$members[$i]] = (float) $members[++$i];
1377
+ }
1378
+
1379
+ $data[1] = $result;
1380
+ }
1381
+
1382
+ return $data;
1383
+ }
1384
  }
1385
 
1386
  /**
1387
+ * @link http://redis.io/commands/zrevrank
1388
  * @author Daniele Alessandri <suppakilla@gmail.com>
1389
  */
1390
+ class ZSetReverseRank extends Command
1391
  {
1392
  /**
1393
  * {@inheritdoc}
1394
  */
1395
  public function getId()
1396
  {
1397
+ return 'ZREVRANK';
1398
  }
1399
  }
1400
 
1401
  /**
1402
+ * @link http://redis.io/commands/sdiffstore
1403
  * @author Daniele Alessandri <suppakilla@gmail.com>
1404
  */
1405
+ class SetDifferenceStore extends SetIntersectionStore
1406
  {
1407
  /**
1408
  * {@inheritdoc}
1409
  */
1410
  public function getId()
1411
  {
1412
+ return 'SDIFFSTORE';
1413
  }
1414
  }
1415
 
1416
  /**
1417
+ * @link http://redis.io/commands/zrevrangebyscore
1418
  * @author Daniele Alessandri <suppakilla@gmail.com>
1419
  */
1420
+ class ZSetReverseRangeByScore extends ZSetRangeByScore
1421
  {
1422
  /**
1423
  * {@inheritdoc}
1424
  */
1425
  public function getId()
1426
  {
1427
+ return 'ZREVRANGEBYSCORE';
1428
  }
1429
  }
1430
 
1431
  /**
1432
+ * @link http://redis.io/commands/sdiff
1433
  * @author Daniele Alessandri <suppakilla@gmail.com>
1434
  */
1435
+ class SetDifference extends SetIntersection
1436
  {
1437
  /**
1438
  * {@inheritdoc}
1439
  */
1440
  public function getId()
1441
  {
1442
+ return 'SDIFF';
1443
  }
1444
+ }
1445
 
1446
+ /**
1447
+ * @link http://redis.io/commands/scard
1448
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1449
+ */
1450
+ class SetCardinality extends Command
1451
+ {
1452
  /**
1453
  * {@inheritdoc}
1454
  */
1455
+ public function getId()
1456
  {
1457
+ return 'SCARD';
1458
  }
1459
  }
1460
 
1474
  }
1475
 
1476
  /**
1477
+ * @link http://redis.io/commands/sadd
1478
  * @author Daniele Alessandri <suppakilla@gmail.com>
1479
  */
1480
+ class SetAdd extends Command
1481
  {
1482
  /**
1483
  * {@inheritdoc}
1484
  */
1485
  public function getId()
1486
  {
1487
+ return 'SADD';
1488
  }
1489
 
1490
  /**
1492
  */
1493
  protected function filterArguments(array $arguments)
1494
  {
1495
+ return self::normalizeVariadic($arguments);
 
 
 
 
1496
  }
1497
  }
1498
 
1499
  /**
1500
+ * @link http://redis.io/commands/bitpos
1501
  * @author Daniele Alessandri <suppakilla@gmail.com>
1502
  */
1503
+ class StringBitPos extends Command
1504
  {
1505
  /**
1506
  * {@inheritdoc}
1507
  */
1508
  public function getId()
1509
  {
1510
+ return 'BITPOS';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1511
  }
1512
  }
1513
 
1514
  /**
1515
+ * @link http://redis.io/commands/decrby
1516
  * @author Daniele Alessandri <suppakilla@gmail.com>
1517
  */
1518
+ class StringDecrementBy extends Command
1519
  {
1520
  /**
1521
  * {@inheritdoc}
1522
  */
1523
  public function getId()
1524
  {
1525
+ return 'DECRBY';
 
 
 
 
 
 
 
 
1526
  }
1527
  }
1528
 
1529
  /**
1530
+ * @link http://redis.io/commands/substr
1531
  * @author Daniele Alessandri <suppakilla@gmail.com>
1532
  */
1533
+ class StringSubstr extends Command
1534
  {
1535
  /**
1536
  * {@inheritdoc}
1537
  */
1538
  public function getId()
1539
  {
1540
+ return 'SUBSTR';
 
 
 
 
 
 
 
 
1541
  }
1542
  }
1543
 
1544
  /**
1545
+ * @link http://redis.io/commands/zlexcount
1546
  * @author Daniele Alessandri <suppakilla@gmail.com>
1547
  */
1548
+ class ZSetLexCount extends Command
1549
  {
1550
  /**
1551
  * {@inheritdoc}
1552
  */
1553
  public function getId()
1554
  {
1555
+ return 'ZLEXCOUNT';
1556
  }
1557
  }
1558
 
1559
  /**
1560
+ * @link http://redis.io/commands/zinterstore
1561
  * @author Daniele Alessandri <suppakilla@gmail.com>
1562
  */
1563
+ class ZSetIntersectionStore extends ZSetUnionStore
1564
  {
1565
  /**
1566
  * {@inheritdoc}
1567
  */
1568
  public function getId()
1569
  {
1570
+ return 'ZINTERSTORE';
1571
  }
1572
+ }
1573
 
1574
+ /**
1575
+ * @link http://redis.io/commands/strlen
1576
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1577
+ */
1578
+ class StringStrlen extends Command
1579
+ {
1580
  /**
1581
  * {@inheritdoc}
1582
  */
1583
+ public function getId()
1584
  {
1585
+ return 'STRLEN';
1586
  }
1587
  }
1588
 
1589
  /**
1590
+ * @link http://redis.io/commands/setrange
1591
  * @author Daniele Alessandri <suppakilla@gmail.com>
1592
  */
1593
+ class StringSetRange extends Command
1594
  {
1595
  /**
1596
  * {@inheritdoc}
1597
  */
1598
  public function getId()
1599
  {
1600
+ return 'SETRANGE';
1601
  }
1602
  }
1603
 
1604
  /**
1605
+ * @link http://redis.io/commands/msetnx
1606
  * @author Daniele Alessandri <suppakilla@gmail.com>
1607
  */
1608
+ class StringSetMultiplePreserve extends StringSetMultiple
1609
  {
1610
  /**
1611
  * {@inheritdoc}
1612
  */
1613
  public function getId()
1614
  {
1615
+ return 'MSETNX';
1616
  }
1617
 
1618
  /**
1625
  }
1626
 
1627
  /**
1628
+ * @link http://redis.io/commands/setnx
1629
  * @author Daniele Alessandri <suppakilla@gmail.com>
1630
  */
1631
+ class StringSetPreserve extends Command
1632
  {
1633
  /**
1634
  * {@inheritdoc}
1635
  */
1636
  public function getId()
1637
  {
1638
+ return 'SETNX';
1639
  }
1640
 
1641
  /**
1648
  }
1649
 
1650
  /**
1651
+ * @link http://redis.io/commands/discard
1652
  * @author Daniele Alessandri <suppakilla@gmail.com>
1653
  */
1654
+ class TransactionDiscard extends Command
1655
  {
1656
  /**
1657
  * {@inheritdoc}
1658
  */
1659
  public function getId()
1660
  {
1661
+ return 'DISCARD';
1662
  }
1663
  }
1664
 
1665
  /**
1666
+ * @link http://redis.io/commands/exec
1667
  * @author Daniele Alessandri <suppakilla@gmail.com>
1668
  */
1669
+ class TransactionExec extends Command
1670
  {
1671
  /**
1672
  * {@inheritdoc}
1673
  */
1674
  public function getId()
1675
  {
1676
+ return 'EXEC';
1677
  }
1678
  }
1679
 
1680
  /**
1681
+ * @link http://redis.io/commands/zcard
1682
  * @author Daniele Alessandri <suppakilla@gmail.com>
1683
  */
1684
+ class ZSetCardinality extends Command
1685
  {
1686
  /**
1687
  * {@inheritdoc}
1688
  */
1689
  public function getId()
1690
  {
1691
+ return 'ZCARD';
1692
  }
1693
  }
1694
 
1695
  /**
1696
+ * @link http://redis.io/commands/zcount
1697
  * @author Daniele Alessandri <suppakilla@gmail.com>
1698
  */
1699
+ class ZSetCount extends Command
1700
  {
1701
  /**
1702
  * {@inheritdoc}
1703
  */
1704
  public function getId()
1705
  {
1706
+ return 'ZCOUNT';
1707
  }
1708
  }
1709
 
1710
  /**
1711
+ * @link http://redis.io/commands/zadd
1712
  * @author Daniele Alessandri <suppakilla@gmail.com>
1713
  */
1714
+ class ZSetAdd extends Command
1715
  {
1716
  /**
1717
  * {@inheritdoc}
1718
  */
1719
  public function getId()
1720
  {
1721
+ return 'ZADD';
1722
  }
1723
 
1724
  /**
1726
  */
1727
  protected function filterArguments(array $arguments)
1728
  {
1729
+ if (count($arguments) === 2 && is_array($arguments[1])) {
1730
+ $flattened = array($arguments[0]);
1731
+
1732
+ foreach ($arguments[1] as $member => $score) {
1733
+ $flattened[] = $score;
1734
+ $flattened[] = $member;
1735
+ }
1736
+
1737
+ return $flattened;
1738
+ }
1739
+
1740
+ return $arguments;
1741
  }
1742
  }
1743
 
1744
  /**
1745
+ * @link http://redis.io/commands/watch
1746
  * @author Daniele Alessandri <suppakilla@gmail.com>
1747
  */
1748
+ class TransactionWatch extends Command
1749
  {
1750
  /**
1751
  * {@inheritdoc}
1752
  */
1753
  public function getId()
1754
  {
1755
+ return 'WATCH';
1756
+ }
1757
+
1758
+ /**
1759
+ * {@inheritdoc}
1760
+ */
1761
+ protected function filterArguments(array $arguments)
1762
+ {
1763
+ if (isset($arguments[0]) && is_array($arguments[0])) {
1764
+ return $arguments[0];
1765
+ }
1766
+
1767
+ return $arguments;
1768
  }
1769
  }
1770
 
1771
  /**
1772
+ * @link http://redis.io/commands/multi
1773
  * @author Daniele Alessandri <suppakilla@gmail.com>
1774
  */
1775
+ class TransactionMulti extends Command
1776
  {
1777
  /**
1778
  * {@inheritdoc}
1779
  */
1780
  public function getId()
1781
  {
1782
+ return 'MULTI';
1783
+ }
1784
+ }
1785
+
1786
+ /**
1787
+ * @link http://redis.io/commands/unwatch
1788
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1789
+ */
1790
+ class TransactionUnwatch extends Command
1791
+ {
1792
+ /**
1793
+ * {@inheritdoc}
1794
+ */
1795
+ public function getId()
1796
+ {
1797
+ return 'UNWATCH';
1798
  }
1799
  }
1800
 
1841
  }
1842
 
1843
  /**
1844
+ * @link http://redis.io/commands/zrank
1845
  * @author Daniele Alessandri <suppakilla@gmail.com>
1846
  */
1847
+ class ZSetRank extends Command
1848
  {
1849
  /**
1850
  * {@inheritdoc}
1851
  */
1852
  public function getId()
1853
  {
1854
+ return 'ZRANK';
1855
  }
1856
  }
1857
 
1858
  /**
1859
+ * @link http://redis.io/commands/mget
1860
  * @author Daniele Alessandri <suppakilla@gmail.com>
1861
  */
1862
+ class StringGetMultiple extends Command
1863
  {
1864
  /**
1865
  * {@inheritdoc}
1866
  */
1867
  public function getId()
1868
  {
1869
+ return 'MGET';
1870
  }
 
1871
 
 
 
 
 
 
 
1872
  /**
1873
  * {@inheritdoc}
1874
  */
1875
+ protected function filterArguments(array $arguments)
1876
  {
1877
+ return self::normalizeArguments($arguments);
1878
  }
1879
  }
1880
 
1881
  /**
1882
+ * @link http://redis.io/commands/getrange
1883
  * @author Daniele Alessandri <suppakilla@gmail.com>
1884
  */
1885
+ class StringGetRange extends Command
1886
  {
1887
  /**
1888
  * {@inheritdoc}
1889
  */
1890
  public function getId()
1891
  {
1892
+ return 'GETRANGE';
1893
  }
1894
  }
1895
 
1896
  /**
1897
+ * @link http://redis.io/commands/zrem
1898
  * @author Daniele Alessandri <suppakilla@gmail.com>
1899
  */
1900
+ class ZSetRemove extends Command
1901
  {
1902
  /**
1903
  * {@inheritdoc}
1904
  */
1905
  public function getId()
1906
  {
1907
+ return 'ZREM';
1908
  }
 
1909
 
 
 
 
 
 
 
1910
  /**
1911
  * {@inheritdoc}
1912
  */
1913
+ protected function filterArguments(array $arguments)
1914
  {
1915
+ return self::normalizeVariadic($arguments);
1916
  }
1917
  }
1918
 
1919
  /**
1920
+ * @link http://redis.io/commands/getbit
1921
  * @author Daniele Alessandri <suppakilla@gmail.com>
1922
  */
1923
+ class StringGetBit extends Command
1924
  {
1925
  /**
1926
  * {@inheritdoc}
1927
  */
1928
  public function getId()
1929
  {
1930
+ return 'GETBIT';
1931
  }
1932
+ }
1933
 
1934
+ /**
1935
+ * @link http://redis.io/commands/zincrby
1936
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1937
+ */
1938
+ class ZSetIncrementBy extends Command
1939
+ {
1940
  /**
1941
  * {@inheritdoc}
1942
  */
1943
+ public function getId()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1944
  {
1945
+ return 'ZINCRBY';
 
 
 
 
 
 
 
 
 
 
 
 
 
1946
  }
1947
+ }
1948
 
1949
+ /**
1950
+ * @link http://redis.io/commands/get
1951
+ * @author Daniele Alessandri <suppakilla@gmail.com>
1952
+ */
1953
+ class StringGet extends Command
1954
+ {
1955
  /**
1956
  * {@inheritdoc}
1957
  */
1958
+ public function getId()
1959
  {
1960
+ return 'GET';
 
 
 
 
 
 
 
 
 
 
 
1961
  }
1962
  }
1963
 
1964
  /**
1965
+ * @link http://redis.io/commands/getset
1966
  * @author Daniele Alessandri <suppakilla@gmail.com>
1967
  */
1968
+ class StringGetSet extends Command
1969
  {
1970
  /**
1971
  * {@inheritdoc}
1972
  */
1973
  public function getId()
1974
  {
1975
+ return 'GETSET';
1976
  }
1977
  }
1978
 
1979
  /**
1980
+ * @link http://redis.io/commands/incr
1981
  * @author Daniele Alessandri <suppakilla@gmail.com>
1982
  */
1983
+ class StringIncrement extends Command
1984
  {
1985
  /**
1986
  * {@inheritdoc}
1987
  */
1988
  public function getId()
1989
  {
1990
+ return 'INCR';
1991
  }
1992
  }
1993
 
1994
  /**
1995
+ * @link http://redis.io/commands/set
1996
  * @author Daniele Alessandri <suppakilla@gmail.com>
1997
  */
1998
+ class StringSet extends Command
1999
  {
2000
  /**
2001
  * {@inheritdoc}
2002
  */
2003
  public function getId()
2004
  {
2005
+ return 'SET';
2006
  }
2007
  }
2008
 
2009
  /**
2010
+ * @link http://redis.io/commands/setbit
2011
  * @author Daniele Alessandri <suppakilla@gmail.com>
2012
  */
2013
+ class StringSetBit extends Command
2014
  {
2015
  /**
2016
  * {@inheritdoc}
2017
  */
2018
  public function getId()
2019
  {
2020
+ return 'SETBIT';
2021
  }
2022
  }
2023
 
2024
  /**
2025
+ * @link http://redis.io/commands/psetex
2026
  * @author Daniele Alessandri <suppakilla@gmail.com>
2027
  */
2028
+ class StringPreciseSetExpire extends StringSetExpire
2029
  {
2030
  /**
2031
  * {@inheritdoc}
2032
  */
2033
  public function getId()
2034
  {
2035
+ return 'PSETEX';
2036
  }
2037
  }
2038
 
2039
  /**
2040
+ * @link http://redis.io/commands/incrbyfloat
2041
  * @author Daniele Alessandri <suppakilla@gmail.com>
2042
  */
2043
+ class StringIncrementByFloat extends Command
2044
  {
2045
  /**
2046
  * {@inheritdoc}
2047
  */
2048
  public function getId()
2049
  {
2050
+ return 'INCRBYFLOAT';
2051
  }
2052
  }
2053
 
2054
  /**
2055
+ * @link http://redis.io/commands/incrby
2056
  * @author Daniele Alessandri <suppakilla@gmail.com>
2057
  */
2058
+ class StringIncrementBy extends Command
2059
  {
2060
  /**
2061
  * {@inheritdoc}
2062
  */
2063
  public function getId()
2064
  {
2065
+ return 'INCRBY';
2066
  }
2067
  }
2068
 
2069
  /**
2070
+ * @link http://redis.io/commands/save
2071
  * @author Daniele Alessandri <suppakilla@gmail.com>
2072
  */
2073
+ class ServerSave extends Command
2074
  {
2075
  /**
2076
  * {@inheritdoc}
2077
  */
2078
  public function getId()
2079
  {
2080
+ return 'SAVE';
2081
  }
2082
  }
2083
 
2084
  /**
2085
+ * @link http://redis.io/commands/decr
2086
  * @author Daniele Alessandri <suppakilla@gmail.com>
2087
  */
2088
+ class StringDecrement extends Command
2089
  {
2090
  /**
2091
  * {@inheritdoc}
2092
  */
2093
  public function getId()
2094
  {
2095
+ return 'DECR';
2096
  }
2097
+ }
2098
 
2099
+ /**
2100
+ * @link http://redis.io/commands/flushall
2101
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2102
+ */
2103
+ class ServerFlushAll extends Command
2104
+ {
2105
  /**
2106
  * {@inheritdoc}
2107
  */
2108
+ public function getId()
2109
  {
2110
+ return 'FLUSHALL';
2111
  }
2112
  }
2113
 
2114
  /**
2115
+ * @link http://redis.io/commands/del
2116
  * @author Daniele Alessandri <suppakilla@gmail.com>
2117
  */
2118
+ class KeyDelete extends Command
2119
  {
2120
  /**
2121
  * {@inheritdoc}
2122
  */
2123
  public function getId()
2124
  {
2125
+ return 'DEL';
2126
  }
2127
 
2128
  /**
2129
  * {@inheritdoc}
2130
  */
2131
+ protected function filterArguments(array $arguments)
2132
  {
2133
+ return self::normalizeArguments($arguments);
2134
  }
2135
  }
2136
 
2137
  /**
2138
+ * @link http://redis.io/commands/dump
2139
  * @author Daniele Alessandri <suppakilla@gmail.com>
2140
  */
2141
+ class KeyDump extends Command
2142
  {
2143
  /**
2144
  * {@inheritdoc}
2145
  */
2146
  public function getId()
2147
  {
2148
+ return 'DUMP';
2149
  }
2150
  }
2151
 
2152
  /**
2153
+ * @link http://redis.io/commands/exists
2154
  * @author Daniele Alessandri <suppakilla@gmail.com>
2155
  */
2156
+ class KeyExists extends Command
2157
  {
2158
  /**
2159
  * {@inheritdoc}
2160
  */
2161
  public function getId()
2162
  {
2163
+ return 'EXISTS';
2164
  }
 
2165
 
 
 
 
 
 
 
2166
  /**
2167
  * {@inheritdoc}
2168
  */
2169
+ public function parseResponse($data)
2170
  {
2171
+ return (bool) $data;
2172
  }
2173
  }
2174
 
2175
  /**
2176
+ * @link http://redis.io/commands/pfmerge
2177
  * @author Daniele Alessandri <suppakilla@gmail.com>
2178
  */
2179
+ class HyperLogLogMerge extends Command
2180
  {
2181
  /**
2182
  * {@inheritdoc}
2183
  */
2184
  public function getId()
2185
  {
2186
+ return 'PFMERGE';
2187
  }
 
2188
 
 
 
 
 
 
 
2189
  /**
2190
  * {@inheritdoc}
2191
  */
2192
+ protected function filterArguments(array $arguments)
2193
  {
2194
+ return self::normalizeArguments($arguments);
2195
  }
2196
  }
2197
 
2198
  /**
2199
+ * @link http://redis.io/commands/pfcount
2200
  * @author Daniele Alessandri <suppakilla@gmail.com>
2201
  */
2202
+ class HyperLogLogCount extends Command
2203
  {
2204
  /**
2205
  * {@inheritdoc}
2206
  */
2207
  public function getId()
2208
  {
2209
+ return 'PFCOUNT';
2210
  }
 
2211
 
 
 
 
 
 
 
2212
  /**
2213
  * {@inheritdoc}
2214
  */
2215
+ protected function filterArguments(array $arguments)
2216
  {
2217
+ return self::normalizeArguments($arguments);
2218
  }
2219
+ }
2220
 
2221
+ /**
2222
+ * @link http://redis.io/commands/hvals
2223
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2224
+ */
2225
+ class HashValues extends Command
2226
+ {
2227
  /**
2228
  * {@inheritdoc}
2229
  */
2230
+ public function getId()
2231
  {
2232
+ return 'HVALS';
 
 
 
 
 
 
 
 
 
 
 
2233
  }
2234
  }
2235
 
2236
  /**
2237
+ * @link http://redis.io/commands/pfadd
2238
  * @author Daniele Alessandri <suppakilla@gmail.com>
2239
  */
2240
+ class HyperLogLogAdd extends Command
2241
  {
2242
  /**
2243
  * {@inheritdoc}
2244
  */
2245
  public function getId()
2246
  {
2247
+ return 'PFADD';
2248
  }
2249
 
2250
  /**
2252
  */
2253
  protected function filterArguments(array $arguments)
2254
  {
2255
+ return self::normalizeVariadic($arguments);
2256
+ }
 
2257
 
2258
+ /**
2259
+ * {@inheritdoc}
2260
+ */
2261
+ public function parseResponse($data)
2262
+ {
2263
+ return (bool) $data;
2264
  }
2265
  }
2266
 
2267
  /**
2268
+ * @link http://redis.io/commands/keys
2269
  * @author Daniele Alessandri <suppakilla@gmail.com>
2270
  */
2271
+ class KeyKeys extends Command
2272
  {
2273
  /**
2274
  * {@inheritdoc}
2275
  */
2276
  public function getId()
2277
  {
2278
+ return 'KEYS';
2279
  }
2280
  }
2281
 
2282
  /**
2283
+ * @link http://redis.io/commands/move
2284
  * @author Daniele Alessandri <suppakilla@gmail.com>
2285
  */
2286
+ class KeyMove extends Command
2287
  {
2288
  /**
2289
  * {@inheritdoc}
2290
  */
2291
  public function getId()
2292
  {
2293
+ return 'MOVE';
2294
  }
 
2295
 
 
 
 
 
 
 
2296
  /**
2297
  * {@inheritdoc}
2298
  */
2299
+ public function parseResponse($data)
2300
  {
2301
+ return (bool) $data;
2302
  }
2303
  }
2304
 
2305
  /**
2306
+ * @link http://redis.io/commands/randomkey
2307
  * @author Daniele Alessandri <suppakilla@gmail.com>
2308
  */
2309
+ class KeyRandom extends Command
2310
  {
2311
  /**
2312
  * {@inheritdoc}
2313
  */
2314
  public function getId()
2315
  {
2316
+ return 'RANDOMKEY';
2317
  }
2318
 
2319
  /**
2321
  */
2322
  public function parseResponse($data)
2323
  {
2324
+ return $data !== '' ? $data : null;
 
 
 
 
 
 
 
2325
  }
2326
+ }
2327
 
2328
+ /**
2329
+ * @link http://redis.io/commands/renamenx
2330
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2331
+ */
2332
+ class KeyRenamePreserve extends KeyRename
2333
+ {
2334
  /**
2335
+ * {@inheritdoc}
 
 
 
 
2336
  */
2337
+ public function getId()
2338
  {
2339
+ return 'RENAMENX';
2340
+ }
 
 
 
 
 
 
 
 
2341
 
2342
+ /**
2343
+ * {@inheritdoc}
2344
+ */
2345
+ public function parseResponse($data)
2346
+ {
2347
+ return (bool) $data;
2348
  }
2349
  }
2350
 
2351
  /**
2352
+ * @link http://redis.io/commands/restore
2353
  * @author Daniele Alessandri <suppakilla@gmail.com>
2354
  */
2355
+ class KeyRestore extends Command
2356
  {
2357
  /**
2358
  * {@inheritdoc}
2359
  */
2360
  public function getId()
2361
  {
2362
+ return 'RESTORE';
2363
  }
2364
  }
2365
 
2366
  /**
2367
+ * @link http://redis.io/commands/pttl
2368
  * @author Daniele Alessandri <suppakilla@gmail.com>
2369
  */
2370
+ class KeyPreciseTimeToLive extends KeyTimeToLive
2371
  {
2372
  /**
2373
  * {@inheritdoc}
2374
  */
2375
  public function getId()
2376
  {
2377
+ return 'PTTL';
2378
  }
2379
  }
2380
 
2381
  /**
2382
+ * @link http://redis.io/commands/pexpireat
2383
  * @author Daniele Alessandri <suppakilla@gmail.com>
2384
  */
2385
+ class KeyPreciseExpireAt extends KeyExpireAt
2386
  {
2387
  /**
2388
  * {@inheritdoc}
2389
  */
2390
  public function getId()
2391
  {
2392
+ return 'PEXPIREAT';
2393
  }
2394
  }
2395
 
2396
  /**
2397
+ * @link http://redis.io/commands/persist
2398
  * @author Daniele Alessandri <suppakilla@gmail.com>
2399
  */
2400
+ class KeyPersist extends Command
2401
  {
2402
  /**
2403
  * {@inheritdoc}
2404
  */
2405
  public function getId()
2406
  {
2407
+ return 'PERSIST';
2408
  }
2409
 
2410
  /**
2411
  * {@inheritdoc}
2412
  */
2413
+ public function parseResponse($data)
2414
  {
2415
+ return (bool) $data;
 
 
 
 
 
2416
  }
2417
+ }
2418
 
2419
+ /**
2420
+ * @link http://redis.io/commands/pexpire
2421
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2422
+ */
2423
+ class KeyPreciseExpire extends KeyExpire
2424
+ {
2425
  /**
2426
+ * {@inheritdoc}
 
 
 
 
2427
  */
2428
+ public function getId()
2429
  {
2430
+ return 'PEXPIRE';
2431
+ }
2432
+ }
 
 
 
 
 
 
 
 
 
2433
 
2434
+ /**
2435
+ * @link http://redis.io/commands/hsetnx
2436
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2437
+ */
2438
+ class HashSetPreserve extends Command
2439
+ {
2440
+ /**
2441
+ * {@inheritdoc}
2442
+ */
2443
+ public function getId()
2444
+ {
2445
+ return 'HSETNX';
2446
  }
2447
 
2448
  /**
2450
  */
2451
  public function parseResponse($data)
2452
  {
2453
+ return (bool) $data;
 
 
 
 
 
 
 
 
 
 
 
2454
  }
2455
  }
2456
 
2457
  /**
2458
+ * @link http://redis.io/commands/hmset
2459
  * @author Daniele Alessandri <suppakilla@gmail.com>
2460
  */
2461
+ class HashSetMultiple extends Command
2462
  {
2463
  /**
2464
  * {@inheritdoc}
2465
  */
2466
  public function getId()
2467
  {
2468
+ return 'HMSET';
2469
  }
2470
 
2471
  /**
2473
  */
2474
  protected function filterArguments(array $arguments)
2475
  {
2476
+ if (count($arguments) === 2 && is_array($arguments[1])) {
2477
+ $flattenedKVs = array($arguments[0]);
2478
+ $args = $arguments[1];
2479
 
2480
+ foreach ($args as $k => $v) {
2481
+ $flattenedKVs[] = $k;
2482
+ $flattenedKVs[] = $v;
2483
+ }
2484
 
2485
+ return $flattenedKVs;
 
 
2486
  }
2487
 
2488
+ return $arguments;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2489
  }
2490
  }
2491
 
2492
  /**
2493
+ * @link http://redis.io/commands/select
2494
  * @author Daniele Alessandri <suppakilla@gmail.com>
2495
  */
2496
+ class ConnectionSelect extends Command
2497
  {
2498
  /**
2499
  * {@inheritdoc}
2500
  */
2501
  public function getId()
2502
  {
2503
+ return 'SELECT';
2504
  }
2505
  }
2506
 
2507
  /**
2508
+ * @link http://redis.io/commands/hdel
2509
  * @author Daniele Alessandri <suppakilla@gmail.com>
2510
  */
2511
+ class HashDelete extends Command
2512
  {
2513
  /**
2514
  * {@inheritdoc}
2515
  */
2516
  public function getId()
2517
  {
2518
+ return 'HDEL';
2519
  }
2520
 
2521
  /**
2523
  */
2524
  protected function filterArguments(array $arguments)
2525
  {
2526
+ return self::normalizeVariadic($arguments);
 
 
 
 
 
2527
  }
2528
+ }
2529
 
2530
+ /**
2531
+ * @link http://redis.io/commands/hexists
2532
+ * @author Daniele Alessandri <suppakilla@gmail.com>
2533
+ */
2534
+ class HashExists extends Command
2535
+ {
2536
  /**
2537
+ * {@inheritdoc}
 
 
 
 
2538
  */
2539
+ public function getId()
2540
  {
2541
+ return 'HEXISTS';
2542
+ }
 
 
 
 
 
 
 
 
 
 
2543
 
2544
+ /**
2545
+ * {@inheritdoc}
2546
+ */
2547
+ public function parseResponse($data)
2548
+ {
2549
+ return (bool) $data;
2550
  }
2551
  }
2552
 
2553
  /**
2554
+ * @link http://redis.io/commands/quit
2555
  * @author Daniele Alessandri <suppakilla@gmail.com>
2556
  */
2557
+ class ConnectionQuit extends Command
2558
  {
2559
  /**
2560
  * {@inheritdoc}
2561
  */
2562
  public function getId()
2563
  {
2564
+ return 'QUIT';
2565
  }
2566
  }
2567
 
2568
  /**
2569
+ * @link http://redis.io/commands/ping
2570
  * @author Daniele Alessandri <suppakilla@gmail.com>
2571
  */
2572
+ class ConnectionPing extends Command
2573
  {
2574
  /**
2575
  * {@inheritdoc}
2576
  */
2577
  public function getId()
2578
  {
2579
+ return 'PING';
2580
  }
2581
  }
2582
 
2583
  /**
2584
+ * @link http://redis.io/commands/auth
2585
  * @author Daniele Alessandri <suppakilla@gmail.com>
2586
  */
2587
+ class ConnectionAuth extends Command
2588
  {
2589
  /**
2590
  * {@inheritdoc}
2591
  */
2592
  public function getId()
2593
  {
2594
+ return 'AUTH';
2595
  }
2596
  }
2597
 
2598
  /**
2599
+ * @link http://redis.io/commands/echo
2600
  * @author Daniele Alessandri <suppakilla@gmail.com>
2601
  */
2602
+ class ConnectionEcho extends Command
2603
  {
2604
  /**
2605
  * {@inheritdoc}
2606
  */
2607
  public function getId()
2608
  {
2609
+ return 'ECHO';
2610
  }
2611
  }
2612
 
2613
  /**
2614
+ * @link http://redis.io/commands/hget
2615
  * @author Daniele Alessandri <suppakilla@gmail.com>
2616
  */
2617
+ class HashGet extends Command
2618
  {
2619
  /**
2620
  * {@inheritdoc}
2621
  */
2622
  public function getId()
2623
  {
2624
+ return 'HGET';
2625
  }
2626
  }
2627
 
2628
  /**
2629
+ * @link http://redis.io/commands/hgetall
2630
  * @author Daniele Alessandri <suppakilla@gmail.com>
2631
  */
2632
+ class HashGetAll extends Command
2633
  {
2634
  /**
2635
  * {@inheritdoc}
2636
  */
2637
  public function getId()
2638
  {
2639
+ return 'HGETALL';
2640
+ }
2641
+
2642
+ /**
2643
+ * {@inheritdoc}
2644
+ */
2645
+ public function parseResponse($data)
2646
+ {
2647
+ $result = array();
2648
+
2649
+ for ($i = 0; $i < count($data); $i++) {
2650
+ $result[$data[$i]] = $data[++$i];
2651
+ }
2652
+
2653
+ return $result;
2654
  }
2655
  }
2656
 
2670
  }
2671
 
2672
  /**
2673
+ * @link http://redis.io/commands/hscan
2674
  * @author Daniele Alessandri <suppakilla@gmail.com>
2675
  */
2676
+ class HashScan extends Command
2677
  {
2678
  /**
2679
  * {@inheritdoc}
2680
  */
2681
  public function getId()
2682
  {
2683
+ return 'HSCAN';
2684
  }
 
2685
 
 
 
 
 
 
 
2686
  /**
2687
  * {@inheritdoc}
2688
  */
2689
+ protected function filterArguments(array $arguments)
2690
  {
2691
+ if (count($arguments) === 3 && is_array($arguments[2])) {
2692
+ $options = $this->prepareOptions(array_pop($arguments));
2693
+ $arguments = array_merge($arguments, $options);
2694
+ }
2695
+
2696
+ return $arguments;
2697
+ }
2698
+
2699
+ /**
2700
+ * Returns a list of options and modifiers compatible with Redis.
2701
+ *
2702
+ * @param array $options List of options.
2703
+ *
2704
+ * @return array
2705
+ */
2706
+ protected function prepareOptions($options)
2707
+ {
2708
+ $options = array_change_key_case($options, CASE_UPPER);
2709
+ $normalized = array();
2710
+
2711
+ if (!empty($options['MATCH'])) {
2712
+ $normalized[] = 'MATCH';
2713
+ $normalized[] = $options['MATCH'];
2714
+ }
2715
+
2716
+ if (!empty($options['COUNT'])) {
2717
+ $normalized[] = 'COUNT';
2718
+ $normalized[] = $options['COUNT'];
2719
+ }
2720
+
2721
+ return $normalized;
2722
  }
2723
 
2724
  /**
2726
  */
2727
  public function parseResponse($data)
2728
  {
2729
+ if (is_array($data)) {
2730
+ $fields = $data[1];
2731
+ $result = array();
2732
+
2733
+ for ($i = 0; $i < count($fields); $i++) {
2734
+ $result[$fields[$i]] = $fields[++$i];
2735
+ }
2736
+
2737
+ $data[1] = $result;
2738
+ }
2739
+
2740
+ return $data;
2741
  }
2742
  }
2743
 
2765
  }
2766
 
2767
  /**
2768
+ * @link http://redis.io/commands/hkeys
2769
  * @author Daniele Alessandri <suppakilla@gmail.com>
2770
  */
2771
+ class HashKeys extends Command
2772
  {
2773
  /**
2774
  * {@inheritdoc}
2775
  */
2776
  public function getId()
2777
  {
2778
+ return 'HKEYS';
2779
  }
2780
  }
2781
 
2782
  /**
2783
+ * @link http://redis.io/commands/hincrbyfloat
2784
  * @author Daniele Alessandri <suppakilla@gmail.com>
2785
  */
2786
+ class HashIncrementByFloat extends Command
2787
  {
2788
  /**
2789
  * {@inheritdoc}
2790
  */
2791
  public function getId()
2792
  {
2793
+ return 'HINCRBYFLOAT';
 
 
 
 
 
 
 
 
2794
  }
2795
  }
2796
 
2797
  /**
2798
+ * @link http://redis.io/commands/hmget
2799
  * @author Daniele Alessandri <suppakilla@gmail.com>
2800
  */
2801
+ class HashGetMultiple extends Command
2802
  {
2803
  /**
2804
  * {@inheritdoc}
2805
  */
2806
  public function getId()
2807
  {
2808
+ return 'HMGET';
2809
  }
2810
 
2811
  /**
2812
  * {@inheritdoc}
2813
  */
2814
+ protected function filterArguments(array $arguments)
2815
  {
2816
+ return self::normalizeVariadic($arguments);
2817
  }
2818
  }
2819
 
2820
  /**
2821
+ * @link http://redis.io/commands/hincrby
2822
  * @author Daniele Alessandri <suppakilla@gmail.com>
2823
  */
2824
+ class HashIncrementBy extends Command
2825
  {
2826
  /**
2827
  * {@inheritdoc}
2828
  */
2829
  public function getId()
2830
  {
2831
+ return 'HINCRBY';
 
 
 
 
 
 
 
 
2832
  }
2833
  }
2834
 
2835
  /**
2836
+ * @link http://redis.io/commands/scan
2837
  * @author Daniele Alessandri <suppakilla@gmail.com>
2838
  */
2839
+ class KeyScan extends Command
2840
  {
2841
  /**
2842
  * {@inheritdoc}
2843
  */
2844
  public function getId()
2845
  {
2846
+ return 'SCAN';
2847
  }
2848
 
2849
  /**
2851
  */
2852
  protected function filterArguments(array $arguments)
2853
  {
2854
+ if (count($arguments) === 2 && is_array($arguments[1])) {
2855
+ $options = $this->prepareOptions(array_pop($arguments));
2856
+ $arguments = array_merge($arguments, $options);
2857
+ }
2858
 
2859
+ return $arguments;
 
 
 
 
 
 
 
 
 
 
 
2860
  }
2861
 
2862
  /**
2863
+ * Returns a list of options and modifiers compatible with Redis.
2864
+ *
2865
+ * @param array $options List of options.
2866
+ *
2867
+ * @return array
2868
  */
2869
+ protected function prepareOptions($options)
2870
  {
2871
+ $options = array_change_key_case($options, CASE_UPPER);
2872
+ $normalized = array();
2873
 
2874
+ if (!empty($options['MATCH'])) {
2875
+ $normalized[] = 'MATCH';
2876
+ $normalized[] = $options['MATCH'];
2877
+ }
 
 
 
 
2878
 
2879
+ if (!empty($options['COUNT'])) {
2880
+ $normalized[] = 'COUNT';
2881
+ $normalized[] = $options['COUNT'];
2882
+ }
 
 
 
 
 
 
 
 
 
2883
 
2884
+ return $normalized;
 
 
 
 
 
2885
  }
2886
  }
2887
 
2888
  /**
2889
+ * @link http://redis.io/commands/sort
2890
  * @author Daniele Alessandri <suppakilla@gmail.com>
2891
  */
2892
+ class KeySort extends Command
2893
  {
2894
  /**
2895
  * {@inheritdoc}
2896
  */
2897
  public function getId()
2898
  {
2899
+ return 'SORT';
2900
  }
2901
 
2902
  /**
2904
  */
2905
  protected function filterArguments(array $arguments)
2906
  {
2907
+ if (count($arguments) === 1) {
2908
+ return $arguments;
2909
+ }
2910
 
2911
+ $query = array($arguments[0]);
2912
+ $sortParams = array_change_key_case($arguments[1], CASE_UPPER);
 
 
2913
 
2914
+ if (isset($sortParams['BY'])) {
2915
+ $query[] = 'BY';
2916
+ $query[] = $sortParams['BY'];
2917
  }
2918
 
2919
+ if (isset($sortParams['GET'])) {
2920
+ $getargs = $sortParams['GET'];
 
2921
 
2922
+ if (is_array($getargs)) {
2923
+ foreach ($getargs as $getarg) {
2924
+ $query[] = 'GET';
2925
+ $query[] = $getarg;
2926
+ }
2927
+ } else {
2928
+ $query[] = 'GET';
2929
+ $query[] = $getargs;
2930
+ }
2931
+ }
 
 
 
 
2932
 
2933
+ if (isset($sortParams['LIMIT']) &&
2934
+ is_array($sortParams['LIMIT']) &&
2935
+ count($sortParams['LIMIT']) == 2) {
 
 
 
 
 
 
 
 
 
 
 
2936
 
2937
+ $query[] = 'LIMIT';
2938
+ $query[] = $sortParams['LIMIT'][0];
2939
+ $query[] = $sortParams['LIMIT'][1];
2940
+ }
 
 
 
 
 
 
 
 
 
2941
 
2942
+ if (isset($sortParams['SORT'])) {
2943
+ $query[] = strtoupper($sortParams['SORT']);
2944
+ }
 
 
 
 
 
2945
 
2946
+ if (isset($sortParams['ALPHA']) && $sortParams['ALPHA'] == true) {
2947
+ $query[] = 'ALPHA';
2948
+ }
 
 
 
 
 
 
 
 
 
 
 
2949
 
2950
+ if (isset($sortParams['STORE'])) {
2951
+ $query[] = 'STORE';
2952
+ $query[] = $sortParams['STORE'];
2953
+ }
2954
+
2955
+ return $query;
 
 
 
 
 
 
2956
  }
2957
  }
2958
 
2959
  /**
2960
+ * Class for generic "anonymous" Redis commands.
2961
+ *
2962
+ * This command class does not filter input arguments or parse responses, but
2963
+ * can be used to leverage the standard Predis API to execute any command simply
2964
+ * by providing the needed arguments following the command signature as defined
2965
+ * by Redis in its documentation.
2966
+ *
2967
  * @author Daniele Alessandri <suppakilla@gmail.com>
2968
  */
2969
+ class RawCommand implements CommandInterface
2970
  {
2971
+ private $slot;
2972
+ private $commandID;
2973
+ private $arguments;
 
 
 
 
2974
 
2975
  /**
2976
+ * @param array $arguments Command ID and its arguments.
2977
+ *
2978
+ * @throws \InvalidArgumentException
2979
  */
2980
+ public function __construct(array $arguments)
2981
  {
2982
+ if (!$arguments) {
2983
+ throw new InvalidArgumentException(
2984
+ 'The arguments array must contain at least the command ID.'
2985
+ );
2986
+ }
2987
 
2988
+ $this->commandID = strtoupper(array_shift($arguments));
2989
+ $this->arguments = $arguments;
 
 
 
 
 
 
 
 
 
 
2990
  }
2991
 
2992
  /**
2993
+ * Creates a new raw command using a variadic method.
2994
+ *
2995
+ * @param string $commandID Redis command ID.
2996
+ * @param string ... Arguments list for the command.
2997
+ *
2998
+ * @return CommandInterface
2999
  */
3000
+ public static function create($commandID /* [ $arg, ... */)
3001
  {
3002
+ $arguments = func_get_args();
3003
+ $command = new self($arguments);
 
3004
 
3005
+ return $command;
 
 
 
 
 
 
 
 
 
 
 
3006
  }
 
3007
 
 
 
 
 
 
 
3008
  /**
3009
  * {@inheritdoc}
3010
  */
3011
  public function getId()
3012
  {
3013
+ return $this->commandID;
3014
  }
 
3015
 
 
 
 
 
 
 
3016
  /**
3017
  * {@inheritdoc}
3018
  */
3019
+ public function setArguments(array $arguments)
3020
  {
3021
+ $this->arguments = $arguments;
3022
+ unset($this->slot);
3023
  }
3024
 
3025
  /**
3026
  * {@inheritdoc}
3027
  */
3028
+ public function setRawArguments(array $arguments)
3029
  {
3030
+ $this->setArguments($arguments);
3031
  }
 
3032
 
 
 
 
 
 
 
3033
  /**
3034
  * {@inheritdoc}
3035
  */
3036
+ public function getArguments()
3037
  {
3038
+ return $this->arguments;
3039
  }
3040
 
3041
  /**
3042
  * {@inheritdoc}
3043
  */
3044
+ public function getArgument($index)
3045
  {
3046
+ if (isset($this->arguments[$index])) {
3047
+ return $this->arguments[$index];
 
 
3048
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3049
  }
 
3050
 
 
 
 
 
 
 
3051
  /**
3052
  * {@inheritdoc}
3053
  */
3054
+ public function setSlot($slot)
3055
  {
3056
+ $this->slot = $slot;
3057
  }
 
3058
 
 
 
 
 
 
 
 
 
 
3059
  /**
3060
  * {@inheritdoc}
3061
  */
3062
+ public function getSlot()
3063
  {
3064
+ if (isset($this->slot)) {
3065
+ return $this->slot;
3066
+ }
3067
  }
3068
 
3069
  /**
3071
  */
3072
  public function parseResponse($data)
3073
  {
 
 
 
 
 
 
 
 
 
 
3074
  return $data;
3075
  }
3076
  }
3077
 
3078
  /**
3079
+ * Base class used to implement an higher level abstraction for commands based
3080
+ * on Lua scripting with EVAL and EVALSHA.
3081
+ *
3082
+ * @link http://redis.io/commands/eval
3083
  * @author Daniele Alessandri <suppakilla@gmail.com>
3084
  */
3085
+ abstract class ScriptCommand extends ServerEvalSHA
3086
  {
3087
  /**
3088
+ * Gets the body of a Lua script.
3089
+ *
3090
+ * @return string
3091
  */
3092
+ abstract public function getScript();
 
 
 
3093
 
3094
  /**
3095
+ * Specifies the number of arguments that should be considered as keys.
3096
+ *
3097
+ * The default behaviour for the base class is to return 0 to indicate that
3098
+ * all the elements of the arguments array should be considered as keys, but
3099
+ * subclasses can enforce a static number of keys.
3100
+ *
3101
+ * @return int
3102
  */
3103
+ protected function getKeysCount()
3104
  {
3105
+ return 0;
 
 
 
 
 
 
 
 
 
 
3106
  }
3107
 
3108
  /**
3109
+ * Returns the elements from the arguments that are identified as keys.
 
 
3110
  *
3111
  * @return array
3112
  */
3113
+ public function getKeys()
3114
  {
3115
+ return array_slice($this->getArguments(), 2, $this->getKeysCount());
3116
+ }
 
 
 
 
 
 
 
3117
 
3118
+ /**
3119
+ * {@inheritdoc}
3120
+ */
3121
+ protected function filterArguments(array $arguments)
3122
+ {
3123
+ if (($numkeys = $this->getKeysCount()) && $numkeys < 0) {
3124
+ $numkeys = count($arguments) + $numkeys;
3125
  }
3126
 
3127
+ return array_merge(array(sha1($this->getScript()), (int) $numkeys), $arguments);
3128
  }
 
3129
 
 
 
 
 
 
 
3130
  /**
3131
+ * @return array
3132
  */
3133
+ public function getEvalArguments()
3134
  {
3135
+ $arguments = $this->getArguments();
3136
+ $arguments[0] = $this->getScript();
3137
+
3138
+ return $arguments;
3139
  }
3140
  }
3141
 
3142
  /**
3143
+ * @link http://redis.io/commands/bgrewriteaof
3144
  * @author Daniele Alessandri <suppakilla@gmail.com>
3145
  */
3146
+ class ServerBackgroundRewriteAOF extends Command
3147
  {
3148
  /**
3149
  * {@inheritdoc}
3150
  */
3151
  public function getId()
3152
  {
3153
+ return 'BGREWRITEAOF';
3154
  }
 
3155
 
 
 
 
 
 
 
3156
  /**
3157
  * {@inheritdoc}
3158
  */
3159
+ public function parseResponse($data)
3160
  {
3161
+ return $data == 'Background append only file rewriting started';
3162
  }
3163
  }
3164
 
3165
  /**
3166
+ * @link http://redis.io/commands/punsubscribe
3167
  * @author Daniele Alessandri <suppakilla@gmail.com>
3168
  */
3169
+ class PubSubUnsubscribeByPattern extends PubSubUnsubscribe
3170
  {
3171
  /**
3172
  * {@inheritdoc}
3173
  */
3174
  public function getId()
3175
  {
3176
+ return 'PUNSUBSCRIBE';
3177
  }
3178
  }
3179
 
3180
  /**
3181
+ * @link http://redis.io/commands/psubscribe
3182
  * @author Daniele Alessandri <suppakilla@gmail.com>
3183
  */
3184
+ class PubSubSubscribeByPattern extends PubSubSubscribe
3185
  {
3186
  /**
3187
  * {@inheritdoc}
3188
  */
3189
  public function getId()
3190
  {
3191
+ return 'PSUBSCRIBE';
3192
  }
3193
  }
3194
 
3195
  /**
3196
+ * @link http://redis.io/commands/publish
3197
  * @author Daniele Alessandri <suppakilla@gmail.com>
3198
  */
3199
+ class PubSubPublish extends Command
3200
  {
3201
  /**
3202
  * {@inheritdoc}
3203
  */
3204
  public function getId()
3205
  {
3206
+ return 'PUBLISH';
3207
  }
3208
  }
3209
 
3210
  /**
3211
+ * @link http://redis.io/commands/pubsub
3212
  * @author Daniele Alessandri <suppakilla@gmail.com>
3213
  */
3214
+ class PubSubPubsub extends Command
3215
  {
3216
  /**
3217
  * {@inheritdoc}
3218
  */
3219
  public function getId()
3220
  {
3221
+ return 'PUBSUB';
3222
  }
 
3223
 
 
 
 
 
 
 
3224
  /**
3225
  * {@inheritdoc}
3226
  */
3227
  public function parseResponse($data)
3228
  {
3229
+ switch (strtolower($this->getArgument(0))) {
3230
+ case 'numsub':
3231
+ return self::processNumsub($data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3232
 
3233
+ default:
3234
+ return $data;
3235
  }
 
 
3236
  }
 
3237
 
 
 
 
 
 
 
3238
  /**
3239
+ * Returns the processed response to PUBSUB NUMSUB.
3240
+ *
3241
+ * @param array $channels List of channels
3242
+ *
3243
+ * @return array
3244
  */
3245
+ protected static function processNumsub(array $channels)
3246
  {
3247
+ $processed = array();
3248
+ $count = count($channels);
3249
+
3250
+ for ($i = 0; $i < $count; $i++) {
3251
+ $processed[$channels[$i]] = $channels[++$i];
3252
+ }
3253
+
3254
+ return $processed;
3255
  }
3256
  }
3257
 
3279
  }
3280
 
3281
  /**
3282
+ * @link http://redis.io/commands/client-list
3283
+ * @link http://redis.io/commands/client-kill
3284
+ * @link http://redis.io/commands/client-getname
3285
+ * @link http://redis.io/commands/client-setname
3286
  * @author Daniele Alessandri <suppakilla@gmail.com>
3287
  */
3288
+ class ServerClient extends Command
3289
  {
3290
  /**
3291
  * {@inheritdoc}
3292
  */
3293
  public function getId()
3294
  {
3295
+ return 'CLIENT';
3296
  }
3297
 
3298
  /**
3300
  */
3301
  public function parseResponse($data)
3302
  {
3303
+ $args = array_change_key_case($this->getArguments(), CASE_UPPER);
3304
+
3305
+ switch (strtoupper($args[0])) {
3306
+ case 'LIST':
3307
+ return $this->parseClientList($data);
3308
+ case 'KILL':
3309
+ case 'GETNAME':
3310
+ case 'SETNAME':
3311
+ default:
3312
+ return $data;
3313
+ }
3314
  }
 
3315
 
 
 
 
 
 
 
3316
  /**
3317
+ * Parses the response to CLIENT LIST and returns a structured list.
3318
+ *
3319
+ * @param string $data Response buffer.
3320
+ *
3321
+ * @return array
3322
  */
3323
+ protected function parseClientList($data)
3324
  {
3325
+ $clients = array();
3326
+
3327
+ foreach (explode("\n", $data, -1) as $clientData) {
3328
+ $client = array();
3329
+
3330
+ foreach (explode(' ', $clientData) as $kv) {
3331
+ @list($k, $v) = explode('=', $kv);
3332
+ $client[$k] = $v;
3333
+ }
3334
+
3335
+ $clients[] = $client;
3336
+ }
3337
+
3338
+ return $clients;
3339
  }
3340
  }
3341
 
3342
  /**
3343
+ * @link http://redis.io/commands/info
 
3344
  * @author Daniele Alessandri <suppakilla@gmail.com>
3345
  */
3346
+ class ServerInfoV26x extends ServerInfo
3347
  {
3348
  /**
3349
+ * {@inheritdoc}
 
 
3350
  */
3351
+ public function parseResponse($data)
3352
+ {
3353
+ if ($data === '') {
3354
+ return array();
3355
+ }
3356
+
3357
+ $info = array();
3358
+
3359
+ $current = null;
3360
+ $infoLines = preg_split('/\r?\n/', $data);
3361
+
3362
+ if (isset($infoLines[0]) && $infoLines[0][0] !== '#') {
3363
+ return parent::parseResponse($data);
3364
+ }
3365
+
3366
+ foreach ($infoLines as $row) {
3367
+ if ($row === '') {
3368
+ continue;
3369
+ }
3370
+
3371
+ if (preg_match('/^# (\w+)$/', $row, $matches)) {
3372
+ $info[$matches[1]] = array();
3373
+ $current = &$info[$matches[1]];
3374
+ continue;
3375
+ }
3376
+
3377
+ list($k, $v) = $this->parseRow($row);
3378
+ $current[$k] = $v;
3379
+ }
3380
+
3381
+ return $info;
3382
+ }
3383
  }
3384
 
3385
  /**
3386
+ * @link http://redis.io/commands/lastsave
3387
  * @author Daniele Alessandri <suppakilla@gmail.com>
3388
  */
3389
+ class ServerLastSave extends Command
3390
  {
3391
  /**
3392
  * {@inheritdoc}
3393
  */
3394
  public function getId()
3395
  {
3396
+ return 'LASTSAVE';
3397
  }
3398
  }
3399
 
3400
  /**
3401
+ * @link http://redis.io/commands/monitor
3402
  * @author Daniele Alessandri <suppakilla@gmail.com>
3403
  */
3404
+ class ServerMonitor extends Command
3405
  {
3406
  /**
3407
  * {@inheritdoc}
3408
  */
3409
  public function getId()
3410
  {
3411
+ return 'MONITOR';
3412
  }
3413
  }
3414
 
3415
  /**
3416
+ * @link http://redis.io/commands/flushdb
3417
  * @author Daniele Alessandri <suppakilla@gmail.com>
3418
  */
3419
+ class ServerFlushDatabase extends Command
3420
  {
3421
  /**
3422
  * {@inheritdoc}
3423
  */
3424
  public function getId()
3425
  {
3426
+ return 'FLUSHDB';
3427
  }
3428
  }
3429
 
3430
  /**
3431
+ * @link http://redis.io/commands/dbsize
3432
  * @author Daniele Alessandri <suppakilla@gmail.com>
3433
  */
3434
+ class ServerDatabaseSize extends Command
3435
  {
3436
  /**
3437
  * {@inheritdoc}
3438
  */
3439
  public function getId()
3440
  {
3441
+ return 'DBSIZE';
3442
  }
3443
  }
3444
 
3445
  /**
3446
+ * @link http://redis.io/commands/command
3447
  * @author Daniele Alessandri <suppakilla@gmail.com>
3448
  */
3449
+ class ServerCommand extends Command
3450
  {
3451
  /**
3452
  * {@inheritdoc}
3453
  */
3454
  public function getId()
3455
  {
3456
+ return 'COMMAND';
3457
  }
3458
  }
3459
 
3460
  /**
3461
+ * @link http://redis.io/commands/config-set
3462
+ * @link http://redis.io/commands/config-get
3463
+ * @link http://redis.io/commands/config-resetstat
3464
+ * @link http://redis.io/commands/config-rewrite
3465
  * @author Daniele Alessandri <suppakilla@gmail.com>
3466
  */
3467
+ class ServerConfig extends Command
3468
  {
3469
  /**
3470
  * {@inheritdoc}
3471
  */
3472
  public function getId()
3473
  {
3474
+ return 'CONFIG';
3475
  }
3476
 
3477
  /**
3479
  */
3480
  public function parseResponse($data)
3481
  {
3482
+ if (is_array($data)) {
3483
+ $result = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3484
 
3485
+ for ($i = 0; $i < count($data); $i++) {
3486
+ $result[$data[$i]] = $data[++$i];
3487
+ }
 
 
 
 
 
 
 
 
 
 
 
 
3488
 
3489
+ return $result;
 
 
 
 
 
 
 
 
3490
  }
3491
 
3492
+ return $data;
 
3493
  }
3494
+ }
3495
 
3496
+ /**
3497
+ * Defines a command whose keys can be prefixed.
3498
+ *
3499
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3500
+ */
3501
+ interface PrefixableCommandInterface extends CommandInterface
3502
+ {
3503
  /**
3504
+ * Prefixes all the keys found in the arguments of the command.
 
 
 
3505
  *
3506
+ * @param string $prefix String used to prefix the keys.
3507
  */
3508
+ public function prefixKeys($prefix);
3509
+ }
 
 
 
 
 
3510
 
3511
+ /**
3512
+ * @link http://redis.io/commands/ltrim
3513
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3514
+ */
3515
+ class ListTrim extends Command
3516
+ {
3517
  /**
3518
  * {@inheritdoc}
3519
  */
3520
  public function getId()
3521
  {
3522
+ return 'LTRIM';
3523
  }
3524
+ }
3525
 
3526
+ /**
3527
+ * @link http://redis.io/commands/lpop
3528
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3529
+ */
3530
+ class ListPopFirst extends Command
3531
+ {
3532
  /**
3533
  * {@inheritdoc}
3534
  */
3535
+ public function getId()
3536
  {
3537
+ return 'LPOP';
 
3538
  }
3539
+ }
3540
 
3541
+ /**
3542
+ * @link http://redis.io/commands/rpop
3543
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3544
+ */
3545
+ class ListPopLast extends Command
3546
+ {
3547
  /**
3548
  * {@inheritdoc}
3549
  */
3550
+ public function getId()
3551
  {
3552
+ return 'RPOP';
3553
  }
3554
+ }
3555
 
3556
+ /**
3557
+ * @link http://redis.io/commands/brpop
3558
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3559
+ */
3560
+ class ListPopLastBlocking extends ListPopFirstBlocking
3561
+ {
3562
  /**
3563
  * {@inheritdoc}
3564
  */
3565
+ public function getId()
3566
  {
3567
+ return 'BRPOP';
3568
  }
3569
+ }
3570
 
3571
+ /**
3572
+ * @link http://redis.io/commands/llen
3573
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3574
+ */
3575
+ class ListLength extends Command
3576
+ {
3577
  /**
3578
  * {@inheritdoc}
3579
  */
3580
+ public function getId()
3581
  {
3582
+ return 'LLEN';
 
 
3583
  }
3584
+ }
3585
 
3586
+ /**
3587
+ * @link http://redis.io/commands/linsert
3588
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3589
+ */
3590
+ class ListInsert extends Command
3591
+ {
3592
  /**
3593
  * {@inheritdoc}
3594
  */
3595
+ public function getId()
3596
  {
3597
+ return 'LINSERT';
3598
  }
3599
+ }
3600
 
3601
+ /**
3602
+ * @link http://redis.io/commands/type
3603
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3604
+ */
3605
+ class KeyType extends Command
3606
+ {
3607
  /**
3608
  * {@inheritdoc}
3609
  */
3610
+ public function getId()
3611
  {
3612
+ return 'TYPE';
 
 
3613
  }
3614
+ }
3615
 
3616
+ /**
3617
+ * @link http://redis.io/commands/lindex
3618
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3619
+ */
3620
+ class ListIndex extends Command
3621
+ {
3622
  /**
3623
  * {@inheritdoc}
3624
  */
3625
+ public function getId()
3626
  {
3627
+ return 'LINDEX';
3628
  }
3629
  }
3630
 
3631
  /**
3632
+ * @link http://redis.io/commands/rpoplpush
 
 
 
3633
  * @author Daniele Alessandri <suppakilla@gmail.com>
3634
  */
3635
+ class ListPopLastPushHead extends Command
3636
  {
3637
  /**
3638
+ * {@inheritdoc}
 
 
 
 
 
 
 
 
 
 
 
 
 
3639
  */
3640
+ public function getId()
3641
  {
3642
+ return 'RPOPLPUSH';
3643
  }
3644
+ }
3645
 
3646
+ /**
3647
+ * @link http://redis.io/commands/brpoplpush
3648
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3649
+ */
3650
+ class ListPopLastPushHeadBlocking extends Command
3651
+ {
3652
  /**
3653
+ * {@inheritdoc}
 
 
3654
  */
3655
+ public function getId()
3656
  {
3657
+ return 'BRPOPLPUSH';
3658
  }
3659
+ }
3660
 
3661
+ /**
3662
+ * @link http://redis.io/commands/lrem
3663
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3664
+ */
3665
+ class ListRemove extends Command
3666
+ {
3667
  /**
3668
  * {@inheritdoc}
3669
  */
3670
+ public function getId()
3671
  {
3672
+ return 'LREM';
 
 
 
 
3673
  }
3674
+ }
3675
 
3676
+ /**
3677
+ * @link http://redis.io/commands/lset
3678
+ * @author Daniele Alessandri <suppakilla@gmail.com>
3679
+ */
3680
+ class ListSet extends Command
3681
+ {
3682
  /**
3683
+ * {@inheritdoc}
3684
  */
3685
+ public function getId()
3686
  {
3687
+ return 'LSET';
 
 
 
3688
  }
3689
  }
3690
 
3691
  /**
3692
+ * @link http://redis.io/commands/lrange
3693
  * @author Daniele Alessandri <suppakilla@gmail.com>
3694
  */
3695
+ class ListRange extends Command
3696
  {
3697
  /**
3698
  * {@inheritdoc}
3699
  */
3700
  public function getId()
3701
  {
3702
+ return 'LRANGE';
3703
  }
3704
  }
3705
 
3706
  /**
3707
+ * @link http://redis.io/commands/rpushx
3708
  * @author Daniele Alessandri <suppakilla@gmail.com>
3709
  */
3710
+ class ListPushTailX extends Command
3711
  {
3712
  /**
3713
  * {@inheritdoc}
3714
  */
3715
  public function getId()
3716
  {
3717
+ return 'RPUSHX';
3718
  }
3719
  }
3720
 
3721
  /**
3722
+ * @link http://redis.io/commands/lpush
3723
  * @author Daniele Alessandri <suppakilla@gmail.com>
3724
  */
3725
+ class ListPushHead extends ListPushTail
3726
  {
3727
  /**
3728
  * {@inheritdoc}
3729
  */
3730
  public function getId()
3731
  {
3732
+ return 'LPUSH';
3733
  }
3734
  }
3735
 
3736
  /**
3737
+ * @link http://redis.io/commands/lpushx
3738
  * @author Daniele Alessandri <suppakilla@gmail.com>
3739
  */
3740
+ class ListPushHeadX extends Command
3741
  {
3742
  /**
3743
  * {@inheritdoc}
3744
  */
3745
  public function getId()
3746
  {
3747
+ return 'LPUSHX';
3748
  }
3749
  }
3750
 
3751
  /**
3752
+ * @link http://redis.io/commands/object
3753
  * @author Daniele Alessandri <suppakilla@gmail.com>
3754
  */
3755
+ class ServerObject extends Command
3756
  {
3757
  /**
3758
  * {@inheritdoc}
3759
  */
3760
  public function getId()
3761
  {
3762
+ return 'OBJECT';
3763
  }
3764
  }
3765
 
3956
  * @param ParametersInterface $parameters Initialization parameters for the connection.
3957
  *
3958
  * @return ParametersInterface
3959
+ *
3960
+ * @throws \InvalidArgumentException
3961
  */
3962
  protected function assertParameters(ParametersInterface $parameters)
3963
  {
4231
  $this->onConnectionError(trim($errstr), $errno);
4232
  }
4233
 
4234
+ if (isset($parameters->read_write_timeout)) {
4235
+ $rwtimeout = (float) $parameters->read_write_timeout;
4236
+ $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
4237
+ $timeoutSeconds = floor($rwtimeout);
4238
+ $timeoutUSeconds = ($rwtimeout - $timeoutSeconds) * 1000000;
4239
+ stream_set_timeout($resource, $timeoutSeconds, $timeoutUSeconds);
4240
+ }
4241
+
4242
  return $resource;
4243
  }
4244
 
4753
 
4754
  /**
4755
  * @param ParametersInterface $parameters Initialization parameters for the connection.
4756
+ *
4757
+ * @throws \InvalidArgumentException
4758
  */
4759
  public function __construct(ParametersInterface $parameters)
4760
  {
5602
  * @param string $uri URI string.
5603
  *
5604
  * @return array
5605
+ *
5606
+ * @throws \InvalidArgumentException
5607
  */
5608
  public static function parse($uri)
5609
  {
5694
  * @param mixed $initializer FQN of a connection class or a callable for lazy initialization.
5695
  *
5696
  * @return mixed
5697
+ *
5698
+ * @throws \InvalidArgumentException
5699
  */
5700
  protected function checkInitializer($initializer)
5701
  {
5954
  *
5955
  * @param string $commandID Command ID.
5956
  * @param string $class Fully-qualified name of a Predis\Command\CommandInterface.
5957
+ *
5958
+ * @throws \InvalidArgumentException
5959
  */
5960
  public function defineCommand($commandID, $class)
5961
  {
6219
  /* commands operating on the key space */
6220
  'SCAN' => 'Predis\Command\KeyScan',
6221
 
6222
+ /* commands operating on string values */
6223
+ 'BITPOS' => 'Predis\Command\StringBitPos',
6224
+
6225
  /* commands operating on sets */
6226
  'SSCAN' => 'Predis\Command\SetScan',
6227
 
6697
  /* commands operating on the key space */
6698
  'SCAN' => 'Predis\Command\KeyScan',
6699
 
6700
+ /* commands operating on string values */
6701
+ 'BITPOS' => 'Predis\Command\StringBitPos',
6702
+
6703
  /* commands operating on sets */
6704
  'SSCAN' => 'Predis\Command\SetScan',
6705
 
7157
  *
7158
  * @param string $alias Profile version or alias.
7159
  * @param string $class FQN of a class implementing Predis\Profile\ProfileInterface.
7160
+ *
7161
+ * @throws \InvalidArgumentException
7162
  */
7163
  public static function define($alias, $class)
7164
  {
7509
  * @method $this zadd($key, array $membersAndScoresDictionary)
7510
  * @method $this zcard($key)
7511
  * @method $this zcount($key, $min, $max)
7512
+ * @method $this zincrby($key, $increment, $member)
7513
  * @method $this zinterstore($destination, array $keys, array $options = null)
7514
  * @method $this zrange($key, $start, $stop, array $options = null)
7515
  * @method $this zrangebyscore($key, $min, $max, array $options = null)
7756
  * @method int zadd($key, array $membersAndScoresDictionary)
7757
  * @method int zcard($key)
7758
  * @method string zcount($key, $min, $max)
7759
+ * @method string zincrby($key, $increment, $member)
7760
  * @method int zinterstore($destination, array $keys, array $options = null)
7761
  * @method array zrange($key, $start, $stop, array $options = null)
7762
  * @method array zrangebyscore($key, $min, $max, array $options = null)
7903
  */
7904
  class Client implements ClientInterface
7905
  {
7906
+ const VERSION = '1.0.1';
7907
 
7908
  protected $connection;
7909
  protected $options;
7928
  * @param mixed $options Client options.
7929
  *
7930
  * @return OptionsInterface
7931
+ *
7932
+ * @throws \InvalidArgumentException
7933
  */
7934
  protected function createOptions($options)
7935
  {
7960
  * @param mixed $parameters Connection parameters or connection instance.
7961
  *
7962
  * @return ConnectionInterface
7963
+ *
7964
+ * @throws \InvalidArgumentException
7965
  */
7966
  protected function createConnection($parameters)
7967
  {
8053
  * @param string $connectionID Identifier of a connection.
8054
  *
8055
  * @return Client
8056
+ *
8057
+ * @throws \InvalidArgumentException
8058
  */
8059
  public function getClientFor($connectionID)
8060
  {
9511
  */
9512
  protected function extractNext()
9513
  {
9514
+ if ($kv = each($this->elements)) {
9515
+ $this->position = $kv[0];
9516
+ $this->current = $kv[1];
9517
+
9518
+ unset($this->elements[$this->position]);
9519
+ }
9520
  }
9521
  }
9522
 
9650
  * @param ClientInterface $client Client connected to Redis.
9651
  * @param string $key Redis list key.
9652
  * @param int $count Number of items retrieved on each fetch operation.
9653
+ *
9654
+ * @throws \InvalidArgumentException
9655
  */
9656
  public function __construct(ClientInterface $client, $key, $count = 10)
9657
  {
10004
  *
10005
  * @param string $commandID Command ID.
10006
  * @param mixed $callback A valid callable object, or NULL to unset the handler.
10007
+ *
10008
+ * @throws \InvalidArgumentException
10009
  */
10010
  public function setCommandHandler($commandID, $callback = null)
10011
  {
10165
  return $slot;
10166
  }
10167
 
 
 
 
 
 
10168
  /**
10169
  * Checks if the specified array of keys will generate the same hash.
10170
  *
10211
 
10212
  return $key;
10213
  }
 
 
 
 
 
10214
  }
10215
 
10216
  /**
10670
  * @param int $first Initial slot of the range.
10671
  * @param int $last Last slot of the range.
10672
  * @param NodeConnectionInterface|string $connection ID or connection instance.
10673
+ *
10674
+ * @throws \OutOfBoundsException
10675
  */
10676
  public function setSlots($first, $last, $connection)
10677
  {
10761
  * @param int $slot Slot index.
10762
  *
10763
  * @return NodeConnectionInterface
10764
+ *
10765
+ * @throws \OutOfBoundsException
10766
  */
10767
  public function getConnectionBySlot($slot)
10768
  {
12534
  * Checks for valid preconditions.
12535
  *
12536
  * @param MultiBulk $iterator Inner multibulk response iterator.
12537
+ *
12538
+ * @throws \InvalidArgumentException
12539
+ * @throws \UnexpectedValueException
12540
  */
12541
  protected function checkPreconditions(MultiBulk $iterator)
12542
  {
12993
  *
12994
  * @param string $commandID The ID of the command to be handled.
12995
  * @param mixed $callback A valid callable object or NULL.
12996
+ *
12997
+ * @throws \InvalidArgumentException
12998
  */
12999
  public function setCommandHandler($commandID, $callback = null)
13000
  {
13764
  * Checks if the passed argument is a valid callback.
13765
  *
13766
  * @param mixed $callable A callback.
13767
+ *
13768
+ * @throws \InvalidArgumentException
13769
  */
13770
  protected function assertCallback($callable)
13771
  {
languages/redis-cache.pot CHANGED
@@ -1,56 +1,64 @@
1
- # Copyright (C) 2014 Redis Object Cache
2
  # This file is distributed under the same license as the Redis Object Cache package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Redis Object Cache 1.0.1\n"
6
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/redis-cache\n"
7
- "POT-Creation-Date: 2014-11-19 12:27:42+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #. #-#-#-#-# plugin.pot (Redis Object Cache 1.0.1) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: includes/admin-page.php:6 redis-cache.php:42
18
  msgid "Redis Object Cache"
19
  msgstr ""
20
 
21
  #: includes/admin-page.php:13
22
- msgid "Object Cache Status"
23
  msgstr ""
24
 
25
  #: includes/admin-page.php:18
26
  msgid "Connection Parameters"
27
  msgstr ""
28
 
29
- #: includes/admin-page.php:21
30
  msgid "Protocol:"
31
  msgstr ""
32
 
33
- #: includes/admin-page.php:22
34
  msgid "Host:"
35
  msgstr ""
36
 
37
- #: includes/admin-page.php:23
38
  msgid "Port:"
39
  msgstr ""
40
 
41
- #: includes/admin-page.php:24
 
 
 
 
42
  msgid "Database:"
43
  msgstr ""
44
 
45
- #: includes/admin-page.php:26
46
  msgid "Password:"
47
  msgstr ""
48
 
49
- #: includes/admin-page.php:36
 
 
 
 
50
  msgid "Enable Object Cache"
51
  msgstr ""
52
 
53
- #: includes/admin-page.php:38
54
  msgid "Disable Object Cache"
55
  msgstr ""
56
 
@@ -58,58 +66,66 @@ msgstr ""
58
  msgid "Redis"
59
  msgstr ""
60
 
61
- #: redis-cache.php:132
62
  msgid "No drop-in found"
63
  msgstr ""
64
 
65
- #: redis-cache.php:136
66
  msgid "Connected"
67
  msgstr ""
68
 
69
- #: redis-cache.php:136
70
  msgid "Not connected"
71
  msgstr ""
72
 
73
- #: redis-cache.php:139
74
  msgid "Unknown"
75
  msgstr ""
76
 
77
- #: redis-cache.php:161
78
  msgid ""
79
  "The Redis object cache drop-in is outdated. <a href=\"%s\">Update it now</a>."
80
  msgstr ""
81
 
82
- #: redis-cache.php:167
83
  msgid ""
84
  "Another object cache drop-in is already active. To use Redis, <a href=\"%s"
85
  "\">please replace it now</a>."
86
  msgstr ""
87
 
88
- #: redis-cache.php:183
89
  msgid "This plugin requires PHP 5.4 or greater."
90
  msgstr ""
91
 
92
- #: redis-cache.php:192
93
  msgid "Object Cache enabled."
94
  msgstr ""
95
 
96
- #: redis-cache.php:195
97
  msgid "Object Cache could not be enabled."
98
  msgstr ""
99
 
100
- #: redis-cache.php:198
101
  msgid "Object Cache disabled."
102
  msgstr ""
103
 
104
- #: redis-cache.php:201
105
  msgid "Object Cache could not be disabled."
106
  msgstr ""
107
 
108
- #: redis-cache.php:204
 
 
 
 
 
 
 
 
109
  msgid "Drop-in updated."
110
  msgstr ""
111
 
112
- #: redis-cache.php:207
113
  msgid "Drop-in could not be updated."
114
  msgstr ""
115
 
1
+ # Copyright (C) 2015 Redis Object Cache
2
  # This file is distributed under the same license as the Redis Object Cache package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Redis Object Cache 1.0.2\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/redis-cache\n"
7
+ "POT-Creation-Date: 2015-02-06 08:01:26+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #. #-#-#-#-# plugin.pot (Redis Object Cache 1.0.2) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: includes/admin-page.php:6 redis-cache.php:42
18
  msgid "Redis Object Cache"
19
  msgstr ""
20
 
21
  #: includes/admin-page.php:13
22
+ msgid "Redis Status"
23
  msgstr ""
24
 
25
  #: includes/admin-page.php:18
26
  msgid "Connection Parameters"
27
  msgstr ""
28
 
29
+ #: includes/admin-page.php:22
30
  msgid "Protocol:"
31
  msgstr ""
32
 
33
+ #: includes/admin-page.php:25
34
  msgid "Host:"
35
  msgstr ""
36
 
37
+ #: includes/admin-page.php:26
38
  msgid "Port:"
39
  msgstr ""
40
 
41
+ #: includes/admin-page.php:30
42
+ msgid "Path:"
43
+ msgstr ""
44
+
45
+ #: includes/admin-page.php:33
46
  msgid "Database:"
47
  msgstr ""
48
 
49
+ #: includes/admin-page.php:36
50
  msgid "Password:"
51
  msgstr ""
52
 
53
+ #: includes/admin-page.php:48
54
+ msgid "Flush Cache"
55
+ msgstr ""
56
+
57
+ #: includes/admin-page.php:53
58
  msgid "Enable Object Cache"
59
  msgstr ""
60
 
61
+ #: includes/admin-page.php:55
62
  msgid "Disable Object Cache"
63
  msgstr ""
64
 
66
  msgid "Redis"
67
  msgstr ""
68
 
69
+ #: redis-cache.php:136
70
  msgid "No drop-in found"
71
  msgstr ""
72
 
73
+ #: redis-cache.php:140
74
  msgid "Connected"
75
  msgstr ""
76
 
77
+ #: redis-cache.php:140
78
  msgid "Not connected"
79
  msgstr ""
80
 
81
+ #: redis-cache.php:143
82
  msgid "Unknown"
83
  msgstr ""
84
 
85
+ #: redis-cache.php:165
86
  msgid ""
87
  "The Redis object cache drop-in is outdated. <a href=\"%s\">Update it now</a>."
88
  msgstr ""
89
 
90
+ #: redis-cache.php:171
91
  msgid ""
92
  "Another object cache drop-in is already active. To use Redis, <a href=\"%s"
93
  "\">please replace it now</a>."
94
  msgstr ""
95
 
96
+ #: redis-cache.php:187
97
  msgid "This plugin requires PHP 5.4 or greater."
98
  msgstr ""
99
 
100
+ #: redis-cache.php:196
101
  msgid "Object Cache enabled."
102
  msgstr ""
103
 
104
+ #: redis-cache.php:199
105
  msgid "Object Cache could not be enabled."
106
  msgstr ""
107
 
108
+ #: redis-cache.php:202
109
  msgid "Object Cache disabled."
110
  msgstr ""
111
 
112
+ #: redis-cache.php:205
113
  msgid "Object Cache could not be disabled."
114
  msgstr ""
115
 
116
+ #: redis-cache.php:208
117
+ msgid "Object Cache flushed."
118
+ msgstr ""
119
+
120
+ #: redis-cache.php:211
121
+ msgid "Object Cache could not be flushed."
122
+ msgstr ""
123
+
124
+ #: redis-cache.php:214
125
  msgid "Drop-in updated."
126
  msgstr ""
127
 
128
+ #: redis-cache.php:217
129
  msgid "Drop-in could not be updated."
130
  msgstr ""
131
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: tillkruess
3
  Donate link: http://till.kruss.me/donations/
4
  Tags: redis, predis, caching, cache, object cache, wp object cache, server, performance, optimize, speed, load
5
  Requires at least: 3.3
6
- Tested up to: 4.1
7
- Stable tag: 1.0.1
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -13,11 +13,9 @@ A persistent object cache backend powered by Redis and the Predis library for PH
13
 
14
  == Description ==
15
 
16
- A persistent object cache backend powered by [Redis](http://redis.io/) and the [Predis](https://github.com/nrk/predis/) library for PHP.
17
 
18
- The Predis library requires PHP 5.4 or greater.
19
-
20
- To adjust the connection parameters or prefixing cache keys, see ["Other Notes"](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
21
 
22
  Forked from Eric Mann's and Erick Hitter's [Redis Object Cache](https://github.com/ericmann/Redis-Object-Cache), which requires the Redis PECL extension.
23
 
@@ -50,7 +48,11 @@ To adjust the connection parameters, define the following constants in your `wp-
50
 
51
  TCP/IP port of the target server. This is ignored when connecting to Redis using UNIX domain sockets.
52
 
53
- * `WP_REDIS_DATABASE` [default: not set]
 
 
 
 
54
 
55
  Accepts a numeric value that is used by Predis to automatically select a logical database with the `SELECT` command.
56
 
@@ -73,6 +75,13 @@ Users with setups where multiple installs share a common `wp-config.php` or `$ta
73
 
74
  == Changelog ==
75
 
 
 
 
 
 
 
 
76
  = 1.0.1 =
77
 
78
  * Load plugin translations
@@ -88,6 +97,10 @@ Users with setups where multiple installs share a common `wp-config.php` or `$ta
88
 
89
  == Upgrade Notice ==
90
 
 
 
 
 
91
  = 1.0.1 =
92
 
93
  This update includes several security, user interface and general code improvements.
3
  Donate link: http://till.kruss.me/donations/
4
  Tags: redis, predis, caching, cache, object cache, wp object cache, server, performance, optimize, speed, load
5
  Requires at least: 3.3
6
+ Tested up to: 4.2
7
+ Stable tag: 1.0.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
13
 
14
  == Description ==
15
 
16
+ A persistent object cache backend powered by [Redis](http://redis.io/) and the [Predis](https://github.com/nrk/predis/) library for PHP. The Predis library requires PHP 5.4 or greater.
17
 
18
+ To adjust the connection parameters or prefixing cache keys, see [Other Notes](http://wordpress.org/extend/plugins/redis-cache/other_notes/).
 
 
19
 
20
  Forked from Eric Mann's and Erick Hitter's [Redis Object Cache](https://github.com/ericmann/Redis-Object-Cache), which requires the Redis PECL extension.
21
 
48
 
49
  TCP/IP port of the target server. This is ignored when connecting to Redis using UNIX domain sockets.
50
 
51
+ * `WP_REDIS_PATH` [default: not set]
52
+
53
+ Path of the UNIX domain socket file used when connecting to Redis using UNIX domain sockets.
54
+
55
+ * `WP_REDIS_DATABASE` [default: `0`]
56
 
57
  Accepts a numeric value that is used by Predis to automatically select a logical database with the `SELECT` command.
58
 
75
 
76
  == Changelog ==
77
 
78
+ = 1.0.2 =
79
+
80
+ * Added "Flush Cache" button
81
+ * Added support for UNIX domain sockets
82
+ * Improved cache object retrieval performance significantly
83
+ * Updated bundled Predis library to version `1.0.1`
84
+
85
  = 1.0.1 =
86
 
87
  * Load plugin translations
97
 
98
  == Upgrade Notice ==
99
 
100
+ = 1.0.2 =
101
+
102
+ This update includes significant speed improvements and support for UNIX domain sockets.
103
+
104
  = 1.0.1 =
105
 
106
  This update includes several security, user interface and general code improvements.
redis-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
- Version: 1.0.1
7
  Text Domain: redis-cache
8
  Domain Path: /languages
9
  Author: Till Krüss
@@ -19,7 +19,7 @@ class RedisObjectCache {
19
  private $screen = 'tools_page_redis-cache';
20
  private $capability = 'manage_options';
21
  private $admin_page = 'tools.php?page=redis-cache';
22
- private $admin_actions = array( 'enable-cache', 'disable-cache', 'update-dropin' );
23
 
24
  public function __construct() {
25
 
@@ -105,7 +105,7 @@ class RedisObjectCache {
105
  }
106
 
107
  public function get_redis_scheme() {
108
- return defined( 'WP_REDIS_SCHEME' ) ? WP_REDIS_SCHEME : 'TCP';
109
  }
110
 
111
  public function get_redis_host() {
@@ -113,11 +113,15 @@ class RedisObjectCache {
113
  }
114
 
115
  public function get_redis_port() {
116
- return defined( 'WP_REDIS_PORT' ) ? WP_REDIS_PORT : '6379';
 
 
 
 
117
  }
118
 
119
  public function get_redis_database() {
120
- return defined( 'WP_REDIS_DATABASE' ) ? WP_REDIS_DATABASE : '0';
121
  }
122
 
123
  public function get_redis_password() {
@@ -200,6 +204,12 @@ class RedisObjectCache {
200
  case 'disable-cache-failed':
201
  $error = __( 'Object Cache could not be disabled.', 'redis-cache' );
202
  break;
 
 
 
 
 
 
203
  case 'dropin-updated':
204
  $message = __( 'Drop-in updated.', 'redis-cache' );
205
  break;
@@ -234,6 +244,10 @@ class RedisObjectCache {
234
 
235
  $url = wp_nonce_url( admin_url( add_query_arg( 'action', $action, $this->admin_page ) ), $action );
236
 
 
 
 
 
237
  // do we have filesystem credentials?
238
  if ( $this->initialize_filesystem( $url, true ) ) {
239
 
@@ -256,9 +270,12 @@ class RedisObjectCache {
256
 
257
  }
258
 
 
 
 
 
259
  wp_safe_redirect( admin_url( add_query_arg( 'message', $message, $this->admin_page ) ) );
260
  exit;
261
-
262
  }
263
 
264
  }
3
  Plugin Name: Redis Object Cache
4
  Plugin URI: http://wordpress.org/plugins/redis-cache/
5
  Description: A Redis backend for the WordPress Object Cache based on the Predis client library for PHP.
6
+ Version: 1.0.2
7
  Text Domain: redis-cache
8
  Domain Path: /languages
9
  Author: Till Krüss
19
  private $screen = 'tools_page_redis-cache';
20
  private $capability = 'manage_options';
21
  private $admin_page = 'tools.php?page=redis-cache';
22
+ private $admin_actions = array( 'enable-cache', 'disable-cache', 'flush-cache', 'update-dropin' );
23
 
24
  public function __construct() {
25
 
105
  }
106
 
107
  public function get_redis_scheme() {
108
+ return defined( 'WP_REDIS_SCHEME' ) ? WP_REDIS_SCHEME : 'tcp';
109
  }
110
 
111
  public function get_redis_host() {
113
  }
114
 
115
  public function get_redis_port() {
116
+ return defined( 'WP_REDIS_PORT' ) ? WP_REDIS_PORT : 6379;
117
+ }
118
+
119
+ public function get_redis_path() {
120
+ return defined( 'WP_REDIS_PATH' ) ? WP_REDIS_PATH : null;
121
  }
122
 
123
  public function get_redis_database() {
124
+ return defined( 'WP_REDIS_DATABASE' ) ? WP_REDIS_DATABASE : 0;
125
  }
126
 
127
  public function get_redis_password() {
204
  case 'disable-cache-failed':
205
  $error = __( 'Object Cache could not be disabled.', 'redis-cache' );
206
  break;
207
+ case 'cache-flushed':
208
+ $message = __( 'Object Cache flushed.', 'redis-cache' );
209
+ break;
210
+ case 'flush-cache-failed':
211
+ $error = __( 'Object Cache could not be flushed.', 'redis-cache' );
212
+ break;
213
  case 'dropin-updated':
214
  $message = __( 'Drop-in updated.', 'redis-cache' );
215
  break;
244
 
245
  $url = wp_nonce_url( admin_url( add_query_arg( 'action', $action, $this->admin_page ) ), $action );
246
 
247
+ if ( $action === 'flush-cache' ) {
248
+ $message = wp_cache_flush() ? 'cache-flushed' : 'flush-cache-failed';
249
+ }
250
+
251
  // do we have filesystem credentials?
252
  if ( $this->initialize_filesystem( $url, true ) ) {
253
 
270
 
271
  }
272
 
273
+ }
274
+
275
+ // redirect if status `$message` was set
276
+ if ( isset( $message ) ) {
277
  wp_safe_redirect( admin_url( add_query_arg( 'message', $message, $this->admin_page ) ) );
278
  exit;
 
279
  }
280
 
281
  }