From 15b26b8b2af028ea30dc34f78ed5c6f3fcb0d547 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Mon, 5 Sep 2016 23:43:35 +0200 Subject: Suggest new verbs --- app/Http/Controllers/VerbController.php | 92 ++++++++++++++++++++-- app/PointChange.php | 35 ++++++++ app/Verb.php | 14 +++- ...016_09_04_081811_create_point_changes_table.php | 37 +++++++++ public/css/hebrewparsetrainer.css | 4 + public/js/alerts.js | 11 +++ public/js/moderators.js | 39 ++++++++- resources/views/layouts/master.blade.php | 1 + resources/views/suggest.blade.php | 30 ++++--- resources/views/suggestions.blade.php | 10 +-- 10 files changed, 248 insertions(+), 25 deletions(-) create mode 100644 app/PointChange.php create mode 100644 database/migrations/2016_09_04_081811_create_point_changes_table.php create mode 100644 public/js/alerts.js diff --git a/app/Http/Controllers/VerbController.php b/app/Http/Controllers/VerbController.php index 98b0579..18cdd2f 100644 --- a/app/Http/Controllers/VerbController.php +++ b/app/Http/Controllers/VerbController.php @@ -18,12 +18,17 @@ */ namespace App\Http\Controllers; +use HebrewParseTrainer\PointChange; +use HebrewParseTrainer\Stem; +use HebrewParseTrainer\Tense; use HebrewParseTrainer\Verb; use HebrewParseTrainer\VerbAction; use HebrewParseTrainer\RandomLog; + use Illuminate\Http\Request; -use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Input; +use Illuminate\Support\Facades\Validator; use Laravel\Lumen\Routing\Controller as BaseController; class VerbController extends BaseController { @@ -48,6 +53,82 @@ class VerbController extends BaseController { return response()->json($obj); } + public function suggest(Request $request) { + $_tenses = Tense::all(); + $tenses = []; + foreach ($_tenses as $tense) + $tenses[] = $tense->name; + + $_stems = Stem::all(); + $stems = []; + foreach ($_stems as $stem) + $stems[] = $stem->name; + + $validator = Validator::make($request->input(), [ + 'verb' => 'required', + 'root' => 'required', + 'stem' => 'in:' . implode(',', $stems), + 'tense' => 'in:' . implode(',', $tenses), + 'person' => 'in:,1,2,3', + 'gender' => 'in:,m,f', + 'number' => 'in:,s,p', + ]); + + if ($validator->fails()) { + return [ + 'success' => false, + 'message' => $validator->errors()->first() + ]; + } + + $verb = new Verb; + $verb->verb = $request->input('verb'); + $verb->root = $request->input('root'); + $verb->stem = $request->input('stem'); + $verb->tense = $request->input('tense'); + $verb->person = $request->input('person') ? $request->input('person') : null; + $verb->gender = $request->input('gender') ? $request->input('gender') : null; + $verb->number = $request->input('number') ? $request->input('number') : null; + $verb->active = 0; + $verb->save(); + + $action = new VerbAction; + $action->kind = VerbAction::KIND_SUGGEST; + $action->user_id = Auth::user()->id; + $action->verb_id = $verb->id; + $action->save(); + + $this->vote(1, $verb->id); + + return [ + 'success' => true, + 'id' => $verb->id, + 'accepted' => $verb->active != 0 + ]; + } + + protected function checkAccept($verb) { + if ($verb->voteCount() < Verb::ACCEPTED_VOTE_COUNT) + return false; + + $verb->active = 1; + $verb->save(); + + if (!is_null($user = $verb->suggestedBy())) { + $ptchange = new PointChange; + $ptchange->kind = PointChange::KIND_SUGGESTION_ACCEPTED; + $ptchange->change = PointChange::POINTS_SUGGESTION_ACCEPTED; + $ptchange->user_id = $user->id; + $ptchange->verb_id = $verb->id; + $ptchange->save(); + + $user->points += PointChange::POINTS_SUGGESTION_ACCEPTED; + $user->save(); + } + + return true; + } + public function vote($choice, $verb_id) { $verb = Verb::findOrFail($verb_id); $user = Auth::user(); @@ -68,17 +149,12 @@ class VerbController extends BaseController { $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(); - } + $accepted = $this->checkAccept($verb); return [ 'success' => true, 'vote_weight' => $user->voteWeight(), - 'accepted' => (bool) $verb->active, + 'accepted' => $accepted, 'new_vote_count' => $verb->voteCount() ]; } diff --git a/app/PointChange.php b/app/PointChange.php new file mode 100644 index 0000000..c157b36 --- /dev/null +++ b/app/PointChange.php @@ -0,0 +1,35 @@ + + * + * 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 . + */ +namespace HebrewParseTrainer; + +use Illuminate\Database\Eloquent\Model; + +class PointChange extends Model { + + protected $table = 'point_changes'; + public $timestamps = false; + protected $dates = ['date']; + protected $fillable = ['kind', 'change']; + + const KIND_SUGGESTION_ACCEPTED = 1; + const KIND_MANUAL = 3; + + const POINTS_SUGGESTION_ACCEPTED = 2; + +} diff --git a/app/Verb.php b/app/Verb.php index aa0db26..3ff79fc 100644 --- a/app/Verb.php +++ b/app/Verb.php @@ -26,7 +26,7 @@ class Verb extends Model { public $timestamps = false; protected $fillable = ['verb', 'root', 'stem', 'tense', 'person', 'gender', 'number']; - const ACCEPTED_VOTE_COUNT = 1; + const ACCEPTED_VOTE_COUNT = 5; public function actions() { return $this->hasMany('HebrewParseTrainer\VerbAction'); @@ -56,4 +56,16 @@ class Verb extends Model { return 0; } + public function suggestedBy() { + $suggs = $this->actions() + ->where('kind', VerbAction::KIND_SUGGEST) + ->get(); + + foreach ($suggs as $sugg) { + return $sugg->user; + } + + return null; + } + } diff --git a/database/migrations/2016_09_04_081811_create_point_changes_table.php b/database/migrations/2016_09_04_081811_create_point_changes_table.php new file mode 100644 index 0000000..4ade816 --- /dev/null +++ b/database/migrations/2016_09_04_081811_create_point_changes_table.php @@ -0,0 +1,37 @@ +increments('id'); + $table->integer('user_id')->unsigned(); + $table->integer('verb_id')->unsigned()->nullable(); + $table->tinyInteger('kind')->unsigned(); + $table->integer('change'); + $table->timestamp('date')->default(DB::raw('CURRENT_TIMESTAMP')); + + $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('verb_id')->references('id')->on('verbs'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('point_changes'); + } +} diff --git a/public/css/hebrewparsetrainer.css b/public/css/hebrewparsetrainer.css index 30ef258..6e35fe8 100644 --- a/public/css/hebrewparsetrainer.css +++ b/public/css/hebrewparsetrainer.css @@ -37,6 +37,10 @@ body { vertical-align: middle !important; } +.suggestions td.vote-cell { + width: 30px; +} + #trainer-404 { display: none; padding: 15px; diff --git a/public/js/alerts.js b/public/js/alerts.js new file mode 100644 index 0000000..c1763ed --- /dev/null +++ b/public/js/alerts.js @@ -0,0 +1,11 @@ +$.fn.addAlert = function (kind, message) { + var box = ''; + + $(this).find('.alerts').append($(box)); +} + +$.fn.clearAlerts = function () { + $(this).find('.alerts').html(''); +} diff --git a/public/js/moderators.js b/public/js/moderators.js index 2b192f8..1a61075 100644 --- a/public/js/moderators.js +++ b/public/js/moderators.js @@ -20,10 +20,17 @@ $(document).ready(function(){ var vote = parseInt($(this).data('vote')); var verbId = $(this).data('verb'); - var container = $(this).parent(); + var container = $(this).closest('tr'); + + var fail = function(msg) { + alert('Voting failed with the message: "' + msg + '". Please try again.'); + } $.ajax({ url: app_url + 'verb/' + verbId + '/vote/' + vote, + error: function(jqxhr, stat, error) { + fail(stat); + }, success: function(data) { if (!data.success) { fail(data.message); @@ -54,4 +61,34 @@ $(document).ready(function(){ return true; }); + + $('form#suggest').submit(function(){ + var data = $(this).serialize(); + var form = $(this); + + form.clearAlerts(); + + $.ajax({ + url: app_url + 'verb/suggest', + method: 'post', + data: data, + error: function(jqxhr, stat, error) { + form.addAlert('danger', stat); + }, + success: function(data) { + if (!data.success) { + form.addAlert('danger', data.message); + return; + } + + if (data.accepted) { + form.addAlert('success', 'The new verb has been accepted immediately.'); + } else { + form.addAlert('success', 'The new verb has been proposed for peer review.'); + } + } + }); + + return false; + }); }); diff --git a/resources/views/layouts/master.blade.php b/resources/views/layouts/master.blade.php index 199db2d..ad8056d 100644 --- a/resources/views/layouts/master.blade.php +++ b/resources/views/layouts/master.blade.php @@ -60,6 +60,7 @@ if (Auth::check()) { + @if(Auth::check()) diff --git a/resources/views/suggest.blade.php b/resources/views/suggest.blade.php index 6a1ebe8..1bc50f7 100644 --- a/resources/views/suggest.blade.php +++ b/resources/views/suggest.blade.php @@ -1,5 +1,6 @@ @@ -8,19 +9,30 @@ use HebrewParseTrainer\Verb;

Suggest a new verb

-
+ +
- +
- @foreach(Root::all() as $root) - + + @endforeach + +
+
+
+ +
+
@@ -28,9 +40,9 @@ use HebrewParseTrainer\Verb;
- @foreach(Tense::all() as $tense) - + @endforeach
@@ -38,7 +50,7 @@ use HebrewParseTrainer\Verb;
- @@ -49,7 +61,7 @@ use HebrewParseTrainer\Verb;
- @@ -59,7 +71,7 @@ use HebrewParseTrainer\Verb;
- diff --git a/resources/views/suggestions.blade.php b/resources/views/suggestions.blade.php index dcec56a..e9b8efb 100644 --- a/resources/views/suggestions.blade.php +++ b/resources/views/suggestions.blade.php @@ -11,18 +11,16 @@ use HebrewParseTrainer\Verb; Verb Root Parsing - Votes + Votes @forelse(Verb::where('active', 0)->orderBy('verb')->get() as $verb) {{ $verb->verb }} {{ $verb->root }} {{ $verb->stem }} {{ $verb->tense }} {{ $verb->person }}{{ $verb->gender }}{{ $verb->number }} - - - {{ $verb->voteCount() }} - - + + {{ $verb->voteCount() }} + @empty There are no active suggestions. Why not add a verb yourself? -- cgit v1.2.3