aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorCamil Staps2016-09-05 22:30:47 +0200
committerCamil Staps2016-09-05 22:30:47 +0200
commitfc5cef0efddbb1141b0a371108a23fc7f6e8d860 (patch)
tree8b3e62b50e5f856c57af477a78a51567d6e859f2 /app
parentUser creation and authentication (diff)
Vote on verb suggestions
Diffstat (limited to 'app')
-rw-r--r--app/Http/Controllers/VerbController.php86
-rw-r--r--app/Http/Middleware/Login.php34
-rw-r--r--app/Http/routes.php30
-rw-r--r--app/User.php9
-rw-r--r--app/Verb.php42
-rw-r--r--app/VerbAction.php41
6 files changed, 227 insertions, 15 deletions
diff --git a/app/Http/Controllers/VerbController.php b/app/Http/Controllers/VerbController.php
new file mode 100644
index 0000000..98b0579
--- /dev/null
+++ b/app/Http/Controllers/VerbController.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * HebrewParseTrainer - practice Hebrew verbs
+ * Copyright (C) 2015 Camil Staps <info@camilstaps.nl>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+namespace App\Http\Controllers;
+
+use HebrewParseTrainer\Verb;
+use HebrewParseTrainer\VerbAction;
+use HebrewParseTrainer\RandomLog;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Input;
+use Illuminate\Support\Facades\Auth;
+use Laravel\Lumen\Routing\Controller as BaseController;
+
+class VerbController extends BaseController {
+
+ public function random() {
+ $verbs = Verb::where('active', 1)->get();
+ foreach (Input::get() as $col => $val) {
+ $val = explode(',', $val);
+ $verbs = $verbs->filter(function(Verb $item) use ($col, $val) {
+ return in_array($item->getAttribute($col), $val);
+ });
+ }
+ $verb = $verbs->random();
+
+ $log = new RandomLog();
+ $log->request = json_encode(Input::get());
+ $log->response = $verb->id;
+ $log->ip = $_SERVER['REMOTE_ADDR'];
+ $log->save();
+
+ $obj = ['verb' => $verb, 'answers' => $verb->otherParsings()];
+ return response()->json($obj);
+ }
+
+ public function vote($choice, $verb_id) {
+ $verb = Verb::findOrFail($verb_id);
+ $user = Auth::user();
+
+ if ($verb->active)
+ return ['success' => false, 'message' => 'This verb has been accepted already.'];
+
+ foreach ($verb->actions()->where('kind', VerbAction::KIND_VOTE)->get() as $vote) {
+ if ($vote->user->id == $user->id) {
+ $vote->delete();
+ }
+ }
+
+ $vote = new VerbAction;
+ $vote->user_id = $user->id;
+ $vote->verb_id = $verb_id;
+ $vote->kind = VerbAction::KIND_VOTE;
+ $vote->vote_weight = ($choice == 1 ? 1 : -1) * $user->voteWeight();
+ $vote->save();
+
+ $message = 'You have voted.';
+
+ if ($verb->voteCount() >= Verb::ACCEPTED_VOTE_COUNT) {
+ $verb->active = 1;
+ $verb->save();
+ }
+
+ return [
+ 'success' => true,
+ 'vote_weight' => $user->voteWeight(),
+ 'accepted' => (bool) $verb->active,
+ 'new_vote_count' => $verb->voteCount()
+ ];
+ }
+
+}
diff --git a/app/Http/Middleware/Login.php b/app/Http/Middleware/Login.php
new file mode 100644
index 0000000..8a71104
--- /dev/null
+++ b/app/Http/Middleware/Login.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class Login {
+ /**
+ * Create a new middleware instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Factory $auth
+ * @return void
+ */
+ public function __construct() {
+ }
+
+ /**
+ * Handle an incoming request.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ * @param string|null $guard
+ * @return mixed
+ */
+ public function handle($request, Closure $next, $guard = null) {
+ if ($request->has('login') && !Auth::check()) {
+ return response('Unauthorized.', 401)
+ ->header('WWW-Authenticate', 'Basic realm="Please enter your email and password"');
+ }
+
+ return $next($request);
+ }
+}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 9cf12b4..8313029 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -29,7 +29,10 @@
*/
$app->group(
- ['prefix' => parse_url(env('APP_URL'), PHP_URL_PATH)],
+ [
+ 'prefix' => parse_url(env('APP_URL'), PHP_URL_PATH),
+ 'middleware' => 'login'
+ ],
function ($app) {
$app->get('/', function () use ($app) {
@@ -44,15 +47,24 @@ $app->group(
return \HebrewParseTrainer\Tense::all();
});
+ $app->get('/verb/random',
+ 'App\Http\Controllers\VerbController@random');
+
$app->get('/logout', function () use ($app) {
- return response('Unauthorized.', 401)
- ->header('WWW-Authenticate', 'Basic realm="Please click OK, then Cancel to logout."');
+ return response('You have been logged out.', 401)
+ ->header(
+ 'WWW-Authenticate',
+ 'Basic realm="Please click OK, then Cancel to logout."');
});
- $app->get('/verb/random', 'App\Http\Controllers\RandomVerbController@show');
+ $app->get('/contribute', function () use ($app) {
+ return view('contribute');
+ });
- $app->get('/user/create', 'App\Http\Controllers\UserController@createForm');
- $app->post('/user/create', 'App\Http\Controllers\UserController@createForm');
+ $app->get('/user/create',
+ 'App\Http\Controllers\UserController@createForm');
+ $app->post('/user/create',
+ 'App\Http\Controllers\UserController@createForm');
$app->group(
['middleware' => 'auth:basic-http'],
@@ -62,6 +74,12 @@ $app->group(
return view('stats');
});
+ $app->get('/verb/{id}/vote/{choice}',
+ 'App\Http\Controllers\VerbController@vote');
+
+ $app->post('/verb/suggest',
+ 'App\Http\Controllers\VerbController@suggest');
+
});
});
diff --git a/app/User.php b/app/User.php
index 3c1799d..dda14ca 100644
--- a/app/User.php
+++ b/app/User.php
@@ -28,6 +28,8 @@ class User extends Model implements Authenticatable {
public $timestamps = false;
protected $fillable = ['email', 'name'];
+ const VOTE_WEIGHT_BASE = 5;
+
public function changePoints($kind, $change, $verb = null) {
$change = new PointChange;
$change->user = $this->id;
@@ -40,6 +42,13 @@ class User extends Model implements Authenticatable {
$this->save();
}
+ public function voteWeight() {
+ if ($this->points <= 0)
+ return 0;
+
+ return floor(log($this->points, self::VOTE_WEIGHT_BASE));
+ }
+
public function setPasswordAttribute($pass) {
$this->attributes['password'] = Hash::make($pass);
}
diff --git a/app/Verb.php b/app/Verb.php
index 28e22ea..aa0db26 100644
--- a/app/Verb.php
+++ b/app/Verb.php
@@ -22,14 +22,38 @@ use Illuminate\Database\Eloquent\Model;
class Verb extends Model {
- protected $table = 'verbs';
- public $timestamps = false;
- protected $fillable = ['verb', 'root', 'stem', 'tense', 'person', 'gender', 'number'];
+ protected $table = 'verbs';
+ public $timestamps = false;
+ protected $fillable = ['verb', 'root', 'stem', 'tense', 'person', 'gender', 'number'];
- public function otherParsings()
- {
- return self::where('verb', $this->verb)->get()
- ->filter(function($v){return $v->verb === $this->verb;});
- }
+ const ACCEPTED_VOTE_COUNT = 1;
-} \ No newline at end of file
+ public function actions() {
+ return $this->hasMany('HebrewParseTrainer\VerbAction');
+ }
+
+ public function otherParsings() {
+ return self::where('verb', $this->verb)->get()
+ ->filter(function($v){return $v->verb === $this->verb;});
+ }
+
+ public function voteCount() {
+ $votes = $this->actions()->where('kind', VerbAction::KIND_VOTE)->get();
+ $total = 0;
+ foreach ($votes as $vote)
+ $total += $vote->vote_weight;
+ return $total;
+ }
+
+ public function userVote(User $user) {
+ $votes = $this->actions()
+ ->where('kind', VerbAction::KIND_VOTE)
+ ->where('user_id', $user->id)
+ ->get();
+ foreach ($votes as $vote) {
+ return $vote->vote_weight;
+ }
+ return 0;
+ }
+
+}
diff --git a/app/VerbAction.php b/app/VerbAction.php
new file mode 100644
index 0000000..79c8cd0
--- /dev/null
+++ b/app/VerbAction.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * HebrewParseTrainer - practice Hebrew verbs
+ * Copyright (C) 2015 Camil Staps <info@camilstaps.nl>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+namespace HebrewParseTrainer;
+
+use Illuminate\Database\Eloquent\Model;
+
+class VerbAction extends Model {
+
+ protected $table = 'verb_actions';
+ public $timestamps = false;
+ protected $dates = ['date'];
+ protected $fillable = ['user_id', 'verb_id', 'kind', 'vote_weight', 'comment_text'];
+
+ const KIND_SUGGEST = 1;
+ const KIND_VOTE = 2;
+
+ public function verb() {
+ return $this->belongsTo('HebrewParseTrainer\Verb');
+ }
+
+ public function user() {
+ return $this->belongsTo('HebrewParseTrainer\User');
+ }
+
+}