Completed
Pull Request — master (#9)
by Joas
02:30
created

PageController::add()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 9
Bugs 1 Features 3
Metric Value
c 9
b 1
f 3
dl 0
loc 25
ccs 15
cts 15
cp 1
rs 8.8571
cc 3
eloc 16
nc 3
nop 3
crap 3
1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2016, Joas Schilling <[email protected]>
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OCA\AnnouncementCenter\Controller;
23
24
use OCA\AnnouncementCenter\Manager;
25
use OCP\AppFramework\Http;
26
use OCP\AppFramework\Http\JSONResponse;
27
use OCP\AppFramework\Http\TemplateResponse;
28
use OCP\AppFramework\Http\Response;
29
use OCP\AppFramework\Controller;
30
use OCP\BackgroundJob\IJobList;
31
use OCP\IDBConnection;
32
use OCP\IGroupManager;
33
use OCP\IL10N;
34
use OCP\IRequest;
35
use OCP\IUser;
36
use OCP\IUserManager;
37
use OCP\IUserSession;
38
use OCP\Notification\IManager as INotificationManager;
39
40
class PageController extends Controller {
41
	/** @var int */
42
	const PAGE_LIMIT = 5;
43
44
	/** @var INotificationManager */
45
	protected $notificationManager;
46
47
	/** @var IJobList */
48
	protected $jobList;
49
50
	/** @var IDBConnection */
51
	protected $connection;
52
53
	/** @var IGroupManager */
54
	protected $groupManager;
55
56
	/** @var IUserManager */
57
	protected $userManager;
58
59
	/** @var IL10N */
60
	protected $l;
61
62
	/** @var Manager */
63
	protected $manager;
64
65
	/** @var IUserSession */
66
	protected $userSession;
67
68
	/**
69
	 * @param string $AppName
70
	 * @param IRequest $request
71
	 * @param IDBConnection $connection
72
	 * @param IGroupManager $groupManager
73
	 * @param IUserManager $userManager
74
	 * @param IJobList $jobList
75
	 * @param INotificationManager $notificationManager
76
	 * @param IL10N $l
77
	 * @param Manager $manager
78
	 * @param IUserSession $userSession
79
	 */
80 19
	public function __construct($AppName, IRequest $request, IDBConnection $connection, IGroupManager $groupManager, IUserManager $userManager, IJobList $jobList, INotificationManager $notificationManager, IL10N $l, Manager $manager, IUserSession $userSession) {
81 19
		parent::__construct($AppName, $request);
82
83 19
		$this->connection = $connection;
84 19
		$this->groupManager = $groupManager;
85 19
		$this->userManager = $userManager;
86 19
		$this->jobList = $jobList;
87 19
		$this->notificationManager = $notificationManager;
88 19
		$this->l = $l;
89 19
		$this->manager = $manager;
90 19
		$this->userSession = $userSession;
91 19
	}
92
93
	/**
94
	 * @NoAdminRequired
95
	 * @NoCSRFRequired
96
	 *
97
	 * @param int $offset
98
	 * @return JSONResponse
99
	 */
100 6
	public function get($offset = 0) {
101 6
		$rows = $this->manager->getAnnouncements(self::PAGE_LIMIT, $offset);
102
103 6
		$announcements = [];
104 6
		foreach ($rows as $row) {
105 3
			$displayName = $row['author'];
106 3
			$user = $this->userManager->get($displayName);
107 3
			if ($user instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
108 1
				$displayName = $user->getDisplayName();
109 1
			}
110
111 3
			$announcements[] = [
112 3
				'id'		=> $row['id'],
113 3
				'author'	=> $displayName,
114 3
				'author_id'	=> $row['author'],
115 3
				'time'		=> $row['time'],
116 3
				'subject'	=> $row['subject'],
117 3
				'message'	=> $row['message'],
118 3
				'groups'	=> $row['groups'],
119
			];
120 6
		}
121
122 6
		return new JSONResponse($announcements);
123
	}
124
125
	/**
126
	 * @NoAdminRequired
127
	 *
128
	 * @param string $subject
129
	 * @param string $message
130
	 * @param string[] $groups
131
	 * @return JSONResponse
132
	 */
133 5
	public function add($subject, $message, array $groups) {
134 5
		if (!$this->manager->checkIsAdmin()) {
135 1
			return new JSONResponse(
136 1
				['message' => 'Logged in user must be an admin'],
137
				Http::STATUS_FORBIDDEN
138 1
			);
139
		}
140
141 4
		$timeStamp = time();
142
		try {
143 4
			$announcement = $this->manager->announce($subject, $message, $this->userSession->getUser()->getUID(), $timeStamp, $groups);
144 4
		} catch (\InvalidArgumentException $e) {
145 2
			return new JSONResponse(
146 2
				['error' => (string)$this->l->t('The subject is too long or empty')],
147
				Http::STATUS_BAD_REQUEST
148 2
			);
149
		}
150
151 2
		$this->jobList->add('OCA\AnnouncementCenter\BackgroundJob', ['id' => $announcement['id']]);
152
153 2
		$announcement['author_id'] = $announcement['author'];
154 2
		$announcement['author'] = $this->userManager->get($announcement['author_id'])->getDisplayName();
155
156 2
		return new JSONResponse($announcement);
157
	}
158
159
	/**
160
	 * @NoAdminRequired
161
	 *
162
	 * @param int $id
163
	 * @return Response
164
	 */
165 2
	public function delete($id) {
166 2
		if (!$this->manager->checkIsAdmin()) {
167 1
			return new JSONResponse(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \OCP\AppFrame...ttp::STATUS_FORBIDDEN); (OCP\AppFramework\Http\JSONResponse) is incompatible with the return type documented by OCA\AnnouncementCenter\C...\PageController::delete of type OCP\AppFramework\Http\Response.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
168 1
				['message' => 'Logged in user must be an admin'],
169
				Http::STATUS_FORBIDDEN
170 1
			);
171
		}
172
173 1
		$this->manager->delete($id);
174
175 1
		$notification = $this->notificationManager->createNotification();
176 1
		$notification->setApp('announcementcenter')
177 1
			->setObject('announcement', $id);
178 1
		$this->notificationManager->markProcessed($notification);
179
180 1
		return new Response();
181
	}
182
183
	/**
184
	 * @NoAdminRequired
185
	 * @NoCSRFRequired
186
	 *
187
	 * @return TemplateResponse
188
	 */
189 2
	public function index() {
190 2
		return new TemplateResponse('announcementcenter', 'main', [
191 2
			'is_admin'	=> $this->manager->checkIsAdmin(),
192 2
		]);
193
	}
194
195
	/**
196
	 * @NoAdminRequired
197
	 *
198
	 * @param string $pattern
199
	 * @return JSONResponse
200
	 */
201 3
	public function searchGroups($pattern) {
202 3
		if (!$this->manager->checkIsAdmin()) {
203 1
			return new JSONResponse(
204 1
				['message' => 'Logged in user must be an admin'],
205
				Http::STATUS_FORBIDDEN
206 1
			);
207
		}
208
209 2
		$groups = $this->groupManager->search($pattern, 10);
210 2
		$gids = [];
211 2
		foreach ($groups as $group) {
212 1
			$gids[] = $group->getGID();
213 2
		}
214
215 2
		return new JSONResponse($gids);
216
	}
217
}
218