Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
NotificationListener
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 3
552
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onAfterInsert
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 1
342
 notifyPostChange
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace Flow\Data\Listener;
4
5use Flow\Exception\InvalidDataException;
6use Flow\Model\AbstractRevision;
7use Flow\Model\PostRevision;
8use Flow\Model\Workflow;
9use Flow\Notifications\Controller;
10
11class NotificationListener extends AbstractListener {
12
13    /**
14     * @var Controller
15     */
16    protected $notificationController;
17
18    public function __construct( Controller $notificationController ) {
19        $this->notificationController = $notificationController;
20    }
21
22    /** @inheritDoc */
23    public function onAfterInsert( $object, array $row, array $metadata ) {
24        if ( !$object instanceof AbstractRevision ) {
25            return;
26        }
27
28        if ( isset( $metadata['imported'] ) && $metadata['imported'] ) {
29            // Don't send any notifications by default for imports
30            return;
31        }
32
33        switch ( $row['rev_change_type'] ) {
34            // Actually new-topic @todo rename
35            case 'new-post':
36                if ( !isset( $metadata['board-workflow'] ) ||
37                    !isset( $metadata['workflow'] ) ||
38                    !isset( $metadata['topic-title'] ) ||
39                    !isset( $metadata['first-post'] )
40                ) {
41                    throw new InvalidDataException( 'Invalid metadata for revision ' .
42                        $object->getRevisionId()->getAlphadecimal(), 'missing-metadata' );
43                }
44
45                $this->notificationController->notifyNewTopic( [
46                    'board-workflow' => $metadata['board-workflow'],
47                    'topic-workflow' => $metadata['workflow'],
48                    'topic-title' => $metadata['topic-title'],
49                    'first-post' => $metadata['first-post'],
50                ] );
51                break;
52
53            case 'edit-title':
54                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
55                $this->notifyPostChange( 'flow-topic-renamed', $object, $metadata );
56                break;
57
58            case 'reply':
59                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
60                $this->notifyPostChange( 'flow-post-reply', $object, $metadata );
61                break;
62
63            case 'edit-post':
64                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
65                $this->notifyPostChange( 'flow-post-edited', $object, $metadata );
66                break;
67
68            case 'lock-topic':
69                $this->notificationController->notifyTopicLocked( 'flow-topic-resolved', [
70                    'revision' => $object,
71                    'topic-workflow' => $metadata['workflow'],
72                    'topic-title' => $metadata['topic-title'],
73                ] );
74                break;
75
76            // "restore" can be a lot of different things
77            // - undo moderation (suppress/delete/hide) things
78            // - undo lock status
79            // we'll need to inspect the previous revision to figure out what is was
80            case 'restore-topic':
81                $post = $object->getCollection();
82                $previousRevision = $post->getPrevRevision( $object );
83                if ( $previousRevision->isLocked() ) {
84                    $this->notificationController->notifyTopicLocked( 'flow-topic-reopened', [
85                        'revision' => $object,
86                        'topic-workflow' => $metadata['workflow'],
87                        'topic-title' => $metadata['topic-title'],
88                    ] );
89                }
90                break;
91
92            case 'edit-header':
93                $this->notificationController->notifyHeaderChange( [
94                    'revision' => $object,
95                    'board-workflow' => $metadata['workflow'],
96                ] );
97                break;
98
99            case 'create-topic-summary':
100            case 'edit-topic-summary':
101                $this->notificationController->notifySummaryChange( [
102                    'revision' => $object,
103                    'topic-workflow' => $metadata['workflow'],
104                    'topic-title' => $metadata['topic-title'],
105                ] );
106                break;
107        }
108    }
109
110    /**
111     * @param string $type
112     * @param PostRevision $object
113     * @param array $metadata
114     * @param array $params
115     * @throws InvalidDataException
116     */
117    protected function notifyPostChange( $type, PostRevision $object, $metadata, array $params = [] ) {
118        if ( !isset( $metadata['workflow'] ) ||
119            !isset( $metadata['topic-title'] )
120        ) {
121            throw new InvalidDataException( 'Invalid metadata for topic|post revision ' .
122                $object->getRevisionId()->getAlphadecimal(), 'missing-metadata' );
123        }
124
125        $workflow = $metadata['workflow'];
126        if ( !$workflow instanceof Workflow ) {
127            throw new InvalidDataException( 'Workflow metadata is not a Workflow', 'missing-metadata' );
128        }
129
130        $this->notificationController->notifyPostChange( $type, $params + [
131            'revision' => $object,
132            'topic-workflow' => $workflow,
133            'topic-title' => $metadata['topic-title'],
134        ] );
135    }
136}