MailQueue::push()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace yiicod\mailqueue;
4
5
use Exception;
6
use Yii;
7
use yii\base\BootstrapInterface;
8
use yii\base\Component;
9
use yii\base\Event;
10
use yii\console\Application;
11
use yii\db\Command;
12
use yii\helpers\ArrayHelper;
13
use yiicod\base\helpers\LoggerMessage;
14
use yiicod\mailqueue\components\MailHandlerInterface;
15
use yiicod\mailqueue\events\DeliveredEvent;
16
use yiicod\mailqueue\events\DeliveredItemEvent;
17
use yiicod\mailqueue\events\DeliveryEvent;
18
use yiicod\mailqueue\events\DeliveryItemEvent;
19
use yiicod\mailqueue\models\MailRepositoryInterface;
20
21
/**
22
 * Comments extension settings
23
 *
24
 * @author Orlov Alexey <[email protected]>
25
 */
26
class MailQueue extends Component implements BootstrapInterface
27
{
28
    const EVENT_BEFORE_DELIVERY = 'before_delivery';
29
30
    const EVENT_AFTER_DELIVERY = 'after_delivery';
31
32
    const EVENT_BEFORE_DELIVERY_ITEM = 'before_delivery_item';
33
34
    const EVENT_AFTER_DELIVERY_ITEM = 'after_delivery_item';
35
36
    /**
37
     * @var array Table settings
38
     */
39
    public $modelMap = [];
40
41
    /**
42
     * @var array
43
     */
44
    public $commandMap = [];
45
46
    public function bootstrap($app)
47
    {
48
        // Merge main extension config with local extension config
49
        $config = include(dirname(__FILE__) . '/config/main.php');
50
        foreach ($config as $key => $value) {
51
            if (is_array($value)) {
52
                $this->{$key} = ArrayHelper::merge($value, $this->{$key});
53
            } elseif (null === $this->{$key}) {
54
                $this->{$key} = $value;
55
            }
56
        }
57
58
        if (Yii::$app instanceof Application) {
59
            //Merge commands map
60
            Yii::$app->controllerMap = ArrayHelper::merge($this->commandMap, Yii::$app->controllerMap);
61
        }
62
63
        Yii::setAlias('@yiicod', realpath(dirname(__FILE__) . '/..'));
64
    }
65
66
    /**
67
     * Push mass
68
     *
69
     * @todo Think change this to Array<MailQueueInterface>. Add method getData():array to MailQueueInterface.
70
     *
71
     * array(
72
     *    array(
73
     *      'field name to' => '',
74
     *      'field name subject' => '',
75
     *      'field name body' => '',
76
     *      'field name priority' => '',
77
     *      'field name from' => '',
78
     *      'field name attaches' => '',
79
     *    )
80
     * )
81
     *
82
     * @param array $data
83
     * @param Command $db
84
     *
85
     * @return int Return int
86
     */
87
    public static function batch($data, $partSize = 100, $db = null)
88
    {
89
        $table = Yii::$app->mailqueue->modelMap['mailQueue']['class'];
90
91
        $db = (null === $db ? Yii::$app->db : $db);
92
        $columns = array_keys(reset($data));
93
        $items = array_chunk($data, $partSize);
94
        foreach ($items as $chunk) {
95
            $rows = array_map(function ($item) {
96
                return $item->getData();
97
            }, $chunk);
98
            //Reconnect for big duration
99
            $db->close();
100
            $db->open();
101
            $db->createCommand()
102
                ->batchInsert($table::tableName(), $columns, $rows)
103
                ->execute();
104
        }
105
        //Reconnect for stable db works
106
        $db->close();
107
        $db->open();
108
    }
109
110
    /**
111
     * Add mail to queue
112
     *
113
     * @param MailRepositoryInterface $mail
114
     *
115
     * @return bool
116
     */
117
    public static function push(MailRepositoryInterface $mail)
118
    {
119
        return $mail->push();
120
    }
121
122
    /**
123
     * Send mail from queue
124
     *
125
     * @param MailHandlerInterface $mailHandler
126
     */
127
    public static function delivery(MailHandlerInterface $mailHandler)
128
    {
129
        $successIds = [];
130
        $failedIds = [];
131
132
        $models = $mailHandler->findAll();
133
134
        Event::trigger(static::class, static::EVENT_BEFORE_DELIVERY, new DeliveryEvent($models));
135
136
        foreach ($models as $item) {
137
            try {
138
                Event::trigger(static::class, static::EVENT_BEFORE_DELIVERY_ITEM, new DeliveryItemEvent($item));
139
                //$mailer = Yii::$app->mailer;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
140
                if ($isSuccess = $mailHandler->send($item)) {
141
                    Yii::info(LoggerMessage::trace('MailQueue send success to - {to}, subject - {subject}', ['{to}' => $item->to, '{subject}' => $item->subject]), 'system.mailqueue');
142
                    $successIds[] = $item->id;
143
                } else {
144
                    Yii::info(LoggerMessage::trace('MailQueue send failed to - {to}, subject - {subject}', ['{to}' => $item->to, '{subject}' => $item->subject]), 'system.mailqueue');
145
                    $failedIds[] = $item->id;
146
                }
147
                Event::trigger(static::class, static::EVENT_AFTER_DELIVERY_ITEM, new DeliveredItemEvent($isSuccess, $item));
148
            } catch (Exception $e) {
149
                $failedIds[] = $item->id;
150
151
                Yii::error(LoggerMessage::log($e));
0 ignored issues
show
Documentation introduced by
$e is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
152
            }
153
        }
154
155
        Event::trigger(static::class, static::EVENT_AFTER_DELIVERY, new DeliveredEvent($successIds, $failedIds));
156
        if (count($successIds)) {
157
            $mailHandler->success($successIds);
158
        }
159
        if (count($failedIds)) {
160
            $mailHandler->failed($failedIds);
161
        }
162
    }
163
}
164