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    public function onAfterInsert( $object, array $row, array $metadata ) {
23        if ( !$object instanceof AbstractRevision ) {
24            return;
25        }
26
27        if ( isset( $metadata['imported'] ) && $metadata['imported'] ) {
28            // Don't send any notifications by default for imports
29            return;
30        }
31
32        switch ( $row['rev_change_type'] ) {
33            // Actually new-topic @todo rename
34            case 'new-post':
35                if ( !isset( $metadata['board-workflow'] ) ||
36                    !isset( $metadata['workflow'] ) ||
37                    !isset( $metadata['topic-title'] ) ||
38                    !isset( $metadata['first-post'] )
39                ) {
40                    throw new InvalidDataException( 'Invalid metadata for revision ' .
41                        $object->getRevisionId()->getAlphadecimal(), 'missing-metadata' );
42                }
43
44                $this->notificationController->notifyNewTopic( [
45                    'board-workflow' => $metadata['board-workflow'],
46                    'topic-workflow' => $metadata['workflow'],
47                    'topic-title' => $metadata['topic-title'],
48                    'first-post' => $metadata['first-post'],
49                ] );
50                break;
51
52            case 'edit-title':
53                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
54                $this->notifyPostChange( 'flow-topic-renamed', $object, $metadata );
55                break;
56
57            case 'reply':
58                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
59                $this->notifyPostChange( 'flow-post-reply', $object, $metadata );
60                break;
61
62            case 'edit-post':
63                // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
64                $this->notifyPostChange( 'flow-post-edited', $object, $metadata );
65                break;
66
67            case 'lock-topic':
68                $this->notificationController->notifyTopicLocked( 'flow-topic-resolved', [
69                    'revision' => $object,
70                    'topic-workflow' => $metadata['workflow'],
71                    'topic-title' => $metadata['topic-title'],
72                ] );
73                break;
74
75            // "restore" can be a lot of different things
76            // - undo moderation (suppress/delete/hide) things
77            // - undo lock status
78            // we'll need to inspect the previous revision to figure out what is was
79            case 'restore-topic':
80                $post = $object->getCollection();
81                $previousRevision = $post->getPrevRevision( $object );
82                if ( $previousRevision->isLocked() ) {
83                    $this->notificationController->notifyTopicLocked( 'flow-topic-reopened', [
84                        'revision' => $object,
85                        'topic-workflow' => $metadata['workflow'],
86                        'topic-title' => $metadata['topic-title'],
87                    ] );
88                }
89                break;
90
91            case 'edit-header':
92                $this->notificationController->notifyHeaderChange( [
93                    'revision' => $object,
94                    'board-workflow' => $metadata['workflow'],
95                ] );
96                break;
97
98            case 'create-topic-summary':
99            case 'edit-topic-summary':
100                $this->notificationController->notifySummaryChange( [
101                    'revision' => $object,
102                    'topic-workflow' => $metadata['workflow'],
103                    'topic-title' => $metadata['topic-title'],
104                ] );
105                break;
106        }
107    }
108
109    /**
110     * @param string $type
111     * @param PostRevision $object
112     * @param array $metadata
113     * @param array $params
114     * @throws InvalidDataException
115     */
116    protected function notifyPostChange( $type, PostRevision $object, $metadata, array $params = [] ) {
117        if ( !isset( $metadata['workflow'] ) ||
118            !isset( $metadata['topic-title'] )
119        ) {
120            throw new InvalidDataException( 'Invalid metadata for topic|post revision ' .
121                $object->getRevisionId()->getAlphadecimal(), 'missing-metadata' );
122        }
123
124        $workflow = $metadata['workflow'];
125        if ( !$workflow instanceof Workflow ) {
126            throw new InvalidDataException( 'Workflow metadata is not a Workflow', 'missing-metadata' );
127        }
128
129        $this->notificationController->notifyPostChange( $type, $params + [
130            'revision' => $object,
131            'topic-workflow' => $workflow,
132            'topic-title' => $metadata['topic-title'],
133        ] );
134    }
135}