SqsHelper::listen()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 29
rs 8.439
cc 5
eloc 15
nc 5
nop 1
1
<?php namespace AwsHelper;
2
3
use Aws\Sqs\SqsClient;
4
use Aws\S3\Exception\S3Exception;
5
6
class SqsHelper
7
{
8
9
    protected $sqs;
10
    protected $adapter;
11
    protected $queue_url;
12
    protected $region;
13
14
    public function __construct(AwsHelper $adapter, $queue_url, $region)
15
    {
16
        $this->setQueueUrl($queue_url);
17
        $this->adapter = $adapter;
18
        $this->region = $region;
19
        $this->connect();
20
    }
21
22
    public function connect()
23
    {
24
        $this->sqs = SqsClient::factory($this->adapter->getDefaultOptions() + ['region' => $this->region]);
25
    }
26
27
    public function setQueueUrl($queue_url)
28
    {
29
        $this->queue_url = $queue_url;
30
    }
31
32
    /* For when you want to stop the listener from running */
33
    public function stop()
34
    {
35
        $this->stop = true;
0 ignored issues
show
Bug introduced by
The property stop does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
36
    }
37
38
    /* Begin listening for messages from the SQS queue.
39
    @param $num_msg Dictates how many messages you wish to process at a time
40
    */
41
    public function listen($num_msg = 1)
42
    {
43
        $expirationTime = $this->adapter->getJSON()->Expiration;
44
        $this->stop = false;
45
        while (!$this->stop) {
46
47
            if ($this->adapter->hasAccessExpired($expirationTime))
48
            {
49
                $this->connect();
50
                $expirationTime = $this->adapter->getJSON()->Expiration;
51
            }
52
53
            $messages = $this->sqs->receiveMessage([
54
                'QueueUrl'        => $this->queue_url,
55
56
                // Enables HTTP long polling
57
                'WaitTimeSeconds' => 20,
58
                'MaxNumberOfMessages' => $num_msg,
59
            ]);
60
61
            if (!$messages->hasKey('Messages')) {
62
                continue;
63
            }
64
65
            foreach ($messages->get('Messages') as $msg_data) {
66
                yield new SqsMessage($msg_data);
67
            }
68
        }
69
    }
70
71
    /* Throws a message off the queue. I.E. It's been processed successfully
72
    @params $message Feed it the message object you recieved from the listen method
73
    */
74
    public function remove(SqsMessage $message)
75
    {
76
        $messages = $this->sqs->deleteMessage([
0 ignored issues
show
Unused Code introduced by
$messages is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
77
            'QueueUrl'       => $this->queue_url,
78
            'ReceiptHandle'  => $message->get('ReceiptHandle'),
79
80
        ]);
81
    }
82
83
    /* Pushes something to the SQS service
84
    @params $data The data of your message.
85
    @params $attributes Any optional meta data attributes you wish to feed through
86
    */
87
    public function push($data, $attributes = [])
88
    {
89
        return $this->sqs->sendMessage([
90
            'QueueUrl' => $this->queue_url,
91
            'MessageBody' => $data,
92
            'MessageAttributes' => $attributes,
93
        ]);
94
    }
95
96
    /**
97
     * Get a list of queue attributes
98
     * @param  array $attributes An array of queue attribute names
99
     * @return array             An array of specified queue attributes with keys as attribute names
100
     */
101
    public function getQueueAttributes($attributes)
102
    {
103
        $queueAttributes = $this->sqs->getQueueAttributes([
104
            'QueueUrl' => $this->queue_url,
105
            'AttributeNames' => $attributes,
106
        ]);
107
        if (!$queueAttributes->hasKey('Attributes')) {
108
            return [];
109
        }
110
        return $queueAttributes->get('Attributes');
111
    }
112
113
    /**
114
     * Shorthand function to get a single queue attribute
115
     * @param  string $attribute A Queue attribute
116
     * @return mixed             String data of the specified queue attribute or null
117
     */
118
    public function getQueueAttribute($attribute)
119
    {
120
        $queueAttributes = $this->getQueueAttributes([$attribute]);
121
        return array_key_exists($attribute, $queueAttributes) ? $queueAttributes[$attribute] : null;
122
    }
123
}
124
125
126
class SqsMessage
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
127
{
128
    public function __construct($msg_data)
129
    {
130
        $this->data = $msg_data;
0 ignored issues
show
Bug introduced by
The property data does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
131
    }
132
133
    public function getAll()
134
    {
135
        return $this->data;
136
    }
137
138
    public function get($key)
139
    {
140
        return $this->data[$key];
141
    }
142
143
    public function has($key)
144
    {
145
        return empty($this->data[$key]);
146
    }
147
}
148