RedisPubSubFeedEngine::send()   B
last analyzed

Complexity

Conditions 6
Paths 32

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 32
nop 2
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License along
15
 * with this program; if not, write to the Free Software Foundation, Inc.,
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
 * http://www.gnu.org/copyleft/gpl.html
18
 *
19
 * @file
20
 */
21
22
/**
23
 * Emit a recent change notification via Redis Pub/Sub
24
 *
25
 * If the feed URI contains a path component, it will be used to generate a
26
 * channel name by stripping the leading slash and replacing any remaining
27
 * slashes with '.'. If no path component is present, the channel is set to
28
 * 'rc'. If the URI contains a query string, its parameters will be parsed
29
 * as RedisConnectionPool options.
30
 *
31
 * @example
32
 * $wgRCFeeds['redis'] = array(
33
 *      'formatter' => 'JSONRCFeedFormatter',
34
 *      'uri'       => "redis://127.0.0.1:6379/rc.$wgDBname",
35
 * );
36
 *
37
 * @since 1.22
38
 */
39
class RedisPubSubFeedEngine implements RCFeedEngine {
40
41
	/**
42
	 * @see RCFeedEngine::send
43
	 */
44
	public function send( array $feed, $line ) {
45
		$parsed = wfParseUrl( $feed['uri'] );
46
		$server = $parsed['host'];
47
		$options = [ 'serializer' => 'none' ];
48
		$channel = 'rc';
49
50
		if ( isset( $parsed['port'] ) ) {
51
			$server .= ":{$parsed['port']}";
52
		}
53
		if ( isset( $parsed['query'] ) ) {
54
			parse_str( $parsed['query'], $options );
55
		}
56
		if ( isset( $parsed['pass'] ) ) {
57
			$options['password'] = $parsed['pass'];
58
		}
59
		if ( isset( $parsed['path'] ) ) {
60
			$channel = str_replace( '/', '.', ltrim( $parsed['path'], '/' ) );
61
		}
62
		$pool = RedisConnectionPool::singleton( $options );
0 ignored issues
show
Bug introduced by
It seems like $options can also be of type null; however, RedisConnectionPool::singleton() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
63
		$conn = $pool->getConnection( $server );
64
		if ( $conn !== false ) {
65
			$conn->publish( $channel, $line );
0 ignored issues
show
Documentation Bug introduced by
The method publish does not exist on object<RedisConnRef>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
66
			return true;
67
		} else {
68
			return false;
69
		}
70
	}
71
}
72