LeagueAdminController::removeAdmin()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 12
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 1
crap 12
1
<?php
2
3
/**
4
 * League admin controller
5
 *
6
 * Class LeagueAdminController
7
 */
8
class LeagueAdminController extends PageController {
0 ignored issues
show
Coding Style introduced by
The property $league_settings_rules is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $team_valiation_rules is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
9
10
	/**
11
	 * League settings validation rules
12
	 *
13
	 * @var array
14
	 */
15
	public $league_settings_rules = [
16
		'name'        => ['required', 'max:255'],
17
		'description' => ['required'],
18
		'url'         => ['url'],
19
		'private'     => ['boolean'],
20
21
		'money'       => ['required', 'integer'],
22
		'units'       => ['required', 'max:16'],
23
		'extra_weeks' => ['required', 'integer', 'between:1,12'],
24
	];
25
26
	/**
27
	 * League settings page
28
	 *
29
	 * @param League $league
30
	 */
31
	public function settings(League $league) {
32
		$league->load('admins');
33
34
		$this->layout->content = View::make('league.admin.settings', compact('league'));
35
		$this->layout->content->validation_rules = $this->league_settings_rules;
36
	}
37
38
	/**
39
	 * Updating league settings page
40
	 *
41
	 * @param League $league
42
	 *
43
	 * @return $this|\Illuminate\Http\RedirectResponse
44
	 */
45
	public function storeSettings(League $league) {
46
		$validator = Validator::make(Input::all(), $this->league_settings_rules);
47
48
		if ($validator->fails()) {
49
			Notification::error('Duder, check your input');
50
51
			return Redirect::back()->withInput()->withErrors($validator);
52
		}
53
54
		// Overwrites
55
		$league->fill(Input::only([
56
			'name', 'description', 'url', 'money', 'units', 'extra_weeks'
57
		]));
58
		$league->private = Input::get('private') ? true : false;
59
60
		if ($league->save()) {
61
			// TODO: End date checking
62
63
			Notification::success('Changes saved!');
64
65
			return Redirect::route('league.admin.settings', ['league' => $league->slug]);
66
		} else {
67
			Notification::error('Database error, try again later!');
68
69
			return Redirect::back()->withInput();
70
		}
71
	}
72
73
	/**
74
	 * List league's movies
75
	 *
76
	 * @param League $league
77
	 */
78
	public function movies(League $league) {
79
		$league->load(['movies' => function ($query) {
80
			/** @var \Illuminate\Database\Eloquent\Builder|Movie $query */
81
			$query->ordered();
82
		}, 'movies.movie']);
83
84
		$this->layout->content = View::make('league.admin.movies', compact('league'));
85
	}
86
87
	/**
88
	 * List movies that can be added to the league
89
	 *
90
	 * @param League $league
91
	 */
92
	public function addableMovies(League $league) {
93
		$show_past = (bool)Input::get('show_past',false);
94
		list($date_range, $movies) = $this->getAddableMovies($league,array(),$show_past);
95
96
		$this->layout->content = View::make('league.admin.addmovies', compact('league', 'movies', 'date_range','show_past'));
97
	}
98
99
100
	/**
101
	 * Add movies to a league
102
	 *
103
	 * @param League $league
104
	 *
105
	 * @return \Illuminate\Http\RedirectResponse
106
	 */
107
	public function addMovies(League $league) {
108
		$movie_ids = Input::get('movie');
109
		$show_past = Input::get('show_past',false);
110
		if (count($movie_ids) == 0) {
111
			Notification::error('Please choose movies to add');
112
113
			return Redirect::back();
114
		}
115
116
		list($date_range, $movies) = $this->getAddableMovies($league, $movie_ids,$show_past);
0 ignored issues
show
Unused Code introduced by
The assignment to $date_range is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
117
118
		/** @type Movie $movie */
119
		foreach ($movies as $movie) {
120
			$league->movies()->create(['movie_id' => $movie->id, 'latest_earnings_id' => $movie->latest_earnings_id]);
121
		}
122
123
		$league->updateLeagueDates();
124
		$league->save();
125
126
		Notification::success(count($movies) . ' movie(s) have been added!');
127
128
		return Redirect::route('league.admin.movies', ['league' => $league->slug]);
129
	}
130
131
132
	/**
133
	 * Removes a LeagueMovie from the league
134
	 *
135
	 * @param League $league
136
	 *
137
	 * @return \Illuminate\Http\RedirectResponse
138
	 */
139
	public function removeMovie(League $league) {
140
141
		$movie_id = intval(Input::get('movie'));
142
143
		/** @var LeagueMovie $movie */
144
		if (! $movie_id || ! ($movie = $league->movies()->find($movie_id))) {
145
			Notification::error('Movie not found');
146
147
			return Redirect::back();
148
		}
149
150
		$movie->delete();
151
		$league->updateLeagueDates();
152
		$league->save();
153
154
		Notification::success('Movie removed from the league');
155
156
		return Redirect::back();
157
	}
158
159
	/**
160
	 * Get moves that can be added by the league, optionally filtered by ID's
161
	 *
162
	 * @param League $league
163
	 * @param array  $ids
0 ignored issues
show
Bug introduced by
There is no parameter named $ids. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
164
	 *
165
	 * @return array
166
	 */
167
	protected function getAddableMovies(League $league, $movie_ids = [],$show_past = false) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $movie_ids is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Naming introduced by
The parameter $show_past is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
168
169
		$query = Movie::query();
170
		if ($show_past)
171
		{
172
			$date_range = [Carbon::now()->subYear(),Carbon::now()];
173
			$query->orderBy('release', 'desc');		
174
		}
175
		else
176
		{
177
			$date_range = [Carbon::now(), $league->maxLastMovieDate()];
178
		}
179
180
		if (count($movie_ids)) {
181
			$query->whereIn('id', $movie_ids);
182
		}
183
		// Remove movies already added
184
		if ($league->movies->count()) {
185
			$query->whereNotIn('id', $league->movies->fetch('movie_id')->toArray());
186
		} else {
187
			// If no movies set start date to a more saner value
188
			$date_range[1] = Carbon::now()->addWeeks(Config::get('draft.maximum_weeks'));
189
		}
190
		$query->whereBetween('release', $date_range);
191
		$query->whereNotNull(Config::get('draft.source') . '_id');
192
		$query->orderBy('release', 'asc');
193
194
		$movies = $query->get();
195
196
		return [$date_range, $movies];
197
	}
198
199
	public $team_valiation_rules = [
200
		'username'  => ['required', 'exists:users,username'],
201
		'team_name' => ['required', 'between:1,64'],
202
	];
203
204
	/**
205
	 * Show user's teams
206
	 *
207
	 * @param League $league
208
	 */
209
	public function teams(League $league) {
210
		$validation_rules = $this->team_valiation_rules;
211
212
		$league->load('teams', 'teams.users');
213
214
		$this->layout->content = View::make('league.admin.teams', compact('league', 'validation_rules'));
215
	}
216
217
218
	/**
219
	 * Add a team to the league
220
	 *
221
	 * @param League $league
222
	 *
223
	 * @return $this|\Illuminate\Http\RedirectResponse
224
	 */
225
	public function addTeam(League $league) {
226
		$validation = Validator::make(Input::all(), $this->team_valiation_rules);
227
		if ($validation->fails()) {
228
			Notification::error('Please check your input and try again');
229
230
			return Redirect::back()->withInput()->withErrors($validation);
231
		}
232
233
		$user = User::whereUsername(Input::get('username'))->first();
0 ignored issues
show
Bug introduced by
The method first does only exist in Illuminate\Database\Query\Builder, but not in User.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
234
235
		// Check if user is already in a team
236
		$check = DB::table('league_teams')
237
		           ->where('league_teams.league_id', $league->id)
238
		           ->join('league_team_user', 'league_teams.id', '=', 'league_team_user.league_team_id')
239
		           ->where('league_team_user.user_id', $user->id)->count();
240
241
		if ($check) {
242
			Notification::error('This user is already in a team in this league');
243
244
			return Redirect::back()->withInput();
245
		}
246
247
		// All good
248
		DB::beginTransaction();
249
250
		/** @type LeagueTeam $team */
251
		$team = $league->teams()->create(['name' => Input::get('team_name')]);
252
		$team->users()->attach($user->id);
253
254
		DB::commit();
255
256
		Notification::success('Team has been added to your league!');
257
258
		return Redirect::back();
259
	}
260
261
	/**
262
	 * Removing a team from the league.
263
	 *
264
	 * @param League $league
265
	 *
266
	 * @return \Illuminate\Http\RedirectResponse
267
	 * @throws Exception
268
	 */
269
	public function removeTeam(League $league) {
270
		/** @type LeagueTeam $team */
271
		$team = $league->teams()->where('id', Input::get('team'))->first();
272
273
		if (! $team) {
274
			Notification::error('Team not found');
275
276
			return Redirect::back();
277
		}
278
279
		$team->delete();
280
281
		Notification::success('Team has been removed');
282
283
		return Redirect::back();
284
	}
285
286
287
	/**
288
	 * Get league drafting page
289
	 *
290
	 * @param League $league
291
	 *
292
	 * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
293
	 */
294
	public function draft(League $league) {
295
		$league->load(['movies' => function($query) {
296
			$query->ordered();
297
		}, 'movies.movie', 'movies.teams', 'teams']);
298
299
		if ($league->movies->count() == 0) {
300
			Notification::error('You need to add more movies before being able to draft');
301
302
			return Redirect::route('league.admin.movies', ['league' => $league->slug]);
303
		}
304
		if ($league->teams->count() == 0) {
305
			Notification::error('You need to add more teams before being able to draft');
306
307
			return Redirect::route('league.admin.teams', ['league' => $league->slug]);
308
		}
309
310
		// Prepend a no team element
311
		$teams = [0 => '(No team)'] + ['Teams' => $league->teams->lists('name', 'id')];
312
313
		// Create a movies array that has the team which owns it ID
314
		$movies = $league->movies->reduce(function ($data, LeagueMovie $movie) {
315
			$data[$movie->id] = [
316
				'movie'   => $movie->movie,
317
				'price'   => $movie->price,
318
				'team_id' => $movie->teams->first() ? $movie->teams->first()->id : null
319
			];
320
321
			return $data;
322
		}, []);
323
324
		$this->layout->content = View::make('league.admin.draft', compact('league', 'movies', 'teams'));
325
326
		return $this->layout;
327
	}
328
329
	/**
330
	 * Save league drafting changes
331
	 *
332
	 * @param League $league
333
	 *
334
	 * @return \Illuminate\Http\RedirectResponse
335
	 */
336
	public function storeDraft(League $league) {
337
		$league->load('movies', 'movies.movie', 'movies.teams', 'teams');
338
339
		$movies = $league->movies;
340
		$teams = $league->teams;
341
342
		$input = Input::get('movie');
343
		if(!is_array($input)) {
344
			App::error(403);
345
		}
346
		$changes = 0;
347
348
		foreach ($input as $movie_id => $post_data) {
0 ignored issues
show
Bug introduced by
The expression $input of type object|integer|double|string|null|boolean|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
349
			/** @type LeagueMovie $movie */
350
			$movie = $movies->find($movie_id);
351
			if (! $movie) continue;
352
353
			// Price
354
			$movie->price = $post_data['price'];
355
			if ($movie->isDirty()) {
356
				$changes++;
357
				$movie->save();
358
			}
359
360
			// Team
361
			$current_team = (! $movie->teams->isEmpty()) ? $movie->teams->first()->id : 0;
362
363
			// If there's a change detected and the new team is valid
364
			if ($post_data['team_id'] != $current_team && (
365
					$post_data['team_id'] == 0 || ($new_team = $teams->find($post_data['team_id']))
366
				)
367
			) {
368
				/** @type LeagueTeam $new_team */
369
				DB::beginTransaction();
370
371
				// Remove old team
372
				if(! $movie->teams->isEmpty()) {
373
					$movie->teams()->detach($current_team);
374
				}
375
				// Add new team
376
				if(isset($new_team)) {
377
					$movie->teams()->attach($new_team);
378
				}
379
380
				$changes++;
381
				DB::commit();
382
			}
383
384
		}
385
386
		Notification::success("{$changes} changes have been saved!");
387
388
		// Active league check
389
		$active_check = DB::table('league_team_movies')->whereIn('league_team_id', $teams->modelKeys())->count();
390
391
		$league->active = $active_check ? 1 : 0;
392
		if($league->isDirty('active')) {
393
			$league->save();
394
395
			if($league->active) {
396
				Notification::success('Your league is now considered active! Happy Drafting!');
397
			} else {
398
				Notification::warning('Your league is no longer considered active.');
399
			}
400
		}
401
402
		return Redirect::back();
403
	}
404
405
	/**
406
	 * Display admins for the league
407
	 *
408
	 * @param League $league
409
	 */
410
	public function admins(League $league) {
411
		$this->layout->content = View::make('league.admin.admins', compact('league'));
412
	}
413
414
	/**
415
	 * Add admins to the league
416
	 *
417
	 * @param League $league
418
	 *
419
	 * @return \Illuminate\Http\RedirectResponse
420
	 */
421
	public function addAdmin(League $league) {
422
		$user = User::whereUsername(Input::get('username'))->first();
0 ignored issues
show
Bug introduced by
The method first does only exist in Illuminate\Database\Query\Builder, but not in User.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
423
424
		if (! $user) {
425
			Notification::error('User not found');
426
427
			return Redirect::back()->withInput();
428
		}
429
		if (! $league->admins()->where('users.id', $user->id)->count()) {
430
			$league->admins()->attach($user);
431
432
			Notification::success('Admin added');
433
		} else {
434
			Notification::warning('User is already an admin');
435
		}
436
437
		return Redirect::back();
438
	}
439
440
	/**
441
	 * Remove an admin from the league
442
	 *
443
	 * @param League $league
444
	 *
445
	 * @return \Illuminate\Http\RedirectResponse
446
	 */
447
	public function removeAdmin(League $league) {
448
		$user = $league->admins()->where('users.id', Input::get('user'))->first();
449
450
		if (! $user) {
451
			Notification::warning('User isn\'t an admin');
452
		} elseif ($user->id == Auth::user()->id) {
453
			Notification::error('You can\'t remove yourself');
454
		} else {
455
			$league->admins()->detach($user->id);
456
			Notification::success('User removed from admins');
457
		}
458
459
		return Redirect::back();
460
	}
461
462
463
}