Skip to content

Commit

Permalink
revision history
Browse files Browse the repository at this point in the history
* adds comment field when editing an event (closes #107)
* supports viewing an event at an old revision (closes #5)
* view revision history for an event (closes #6)
  • Loading branch information
aaronpk committed Jul 6, 2020
1 parent c09b2de commit 893811e
Show file tree
Hide file tree
Showing 16 changed files with 686 additions and 51 deletions.
13 changes: 13 additions & 0 deletions app/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ class Event extends Model
'cancelled' => 'Cancelled',
];

public static $EDITABLE_PROPERTIES = [
'name', 'start_date', 'end_date', 'start_time', 'end_time',
'location_name', 'location_address', 'location_locality', 'location_region', 'location_country',
'latitude', 'longitude', 'timezone', 'status',
'website', 'tickets_url', 'code_of_conduct_url', 'meeting_url',
'description', 'cover_image',
];

public static function slug_from_name($name) {
return preg_replace('/--+/', '-', mb_ereg_replace('[^a-z0-9à-öø-ÿāăąćĉċčŏœ]+', '-', mb_strtolower($name)));
}
Expand Down Expand Up @@ -59,6 +67,11 @@ public function num_pending_responses() {
->count();
}

public function revisions() {
return $this->hasMany('\App\EventRevision', 'key', 'key')
->orderBy('created_at', 'desc');
}

public function photos() {
return $this->hasManyThrough('\App\ResponsePhoto', '\App\Response')
->where('approved', true)
Expand Down
20 changes: 16 additions & 4 deletions app/EventRevision.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,23 @@

use Illuminate\Database\Eloquent\Model;

class EventRevision extends Model
class EventRevision extends Event
{

protected $casts = [
'photo_order' => 'array',
];
public function num_changed_fields(Event $previous) {
return count($this->changed_fields($previous));
}

public function changed_fields(Event $previous) {
$editable = self::$EDITABLE_PROPERTIES;
$editable[] = 'tags';

$changes = [];
foreach($editable as $p) {
if($this->{$p} != $previous->{$p})
$changes[] = $p;
}
return $changes;
}

}
1 change: 1 addition & 0 deletions app/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ public function event($year, $month, $key_or_slug, $key2=false) {
'month' => $month,
'key' => $key,
'slug' => $slug,
'mode' => 'event',
]);
}

Expand Down
93 changes: 71 additions & 22 deletions app/Http/Controllers/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Illuminate\Support\Str;
use Auth, Storage, Gate, Log;
use Image;
use DateTime;
use App\Services\Zoom, App\Services\EventParser;


Expand Down Expand Up @@ -152,54 +153,102 @@ public function save_event(Request $request, Event $event) {
'status' => 'in:'.implode(',', array_keys(Event::$STATUSES)),
]);

$properties = [
'name', 'start_date', 'end_date', 'start_time', 'end_time',
'location_name', 'location_address', 'location_locality', 'location_region', 'location_country',
'latitude', 'longitude', 'timezone', 'status',
'website', 'tickets_url', 'code_of_conduct_url', 'meeting_url',
'description', 'cover_image',
];

// Save a snapshot of the previous state
$revision = new EventRevision;
$fixed_properties = ['key','slug','created_by','last_modified_by'];
foreach(array_merge($properties, $fixed_properties) as $p) {
$revision->{$p} = $event->{$p} ?: null;
}
$revision->save();

// Update the properties on the event
foreach($properties as $p) {
$event->{$p} = request($p) ?: null;
foreach(Event::$EDITABLE_PROPERTIES as $p) {
$event->{$p} = $revision->{$p} = (request($p) ?: null);
}

$event->sort_date = $event->sort_date();
$event->sort_date = $revision->sort_date = $event->sort_date();

// Generate a new slug
$event->slug = Event::slug_from_name($event->name);
$event->slug = $revision->slug = Event::slug_from_name($event->name);

// Schedule a zoom meeting if requested
if(Setting::value('zoom_api_key') && request('create_zoom_meeting')) {
$event->meeting_url = Zoom::schedule_meeting($event);
$event->meeting_url = $revision->meeting_url = Zoom::schedule_meeting($event);
if(!$event->meeting_url) {
return back()->withInput()->withErrors(['Failed to create the Zoom meeting. The changes were not saved.']);
}
}

$event->last_modified_by = Auth::user()->id;
$event->last_modified_by = $revision->last_modified_by = Auth::user()->id;
$event->save();

$revision->created_by = $event->created_by;

// Capture the tags serialized as JSON
$rawtags = request('tags') ? explode(' ', request('tags')) : [];
$tags = [];
$tags_string = [];
foreach($rawtags as $t) {
if(trim($t)) {
$tag = Tag::get($t);
$tags[] = $tag;
$tags_string[] = $tag->tag;
}
}

$revision->key = $event->key;
$revision->tags = json_encode($tags_string);
$revision->edit_summary = request('edit_summary');
$revision->save();

// Delete related tags
$event->tags()->detach();
// Add all the tags back
foreach(explode(' ', request('tags')) as $t) {
if(trim($t))
$event->tags()->attach(Tag::get($t));
foreach($tags as $tag) {
$event->tags()->attach($tag);
}

return redirect($event->permalink());
}

public function revision_history(Event $event) {
Gate::authorize('manage-event', $event);

$revisions = $event->revisions;

return view('revision-history', [
'event' => $event,
'revisions' => $revisions,
]);
}

public function view_revision(Event $event, EventRevision $revision) {
Gate::authorize('manage-event', $revision);

$date = new DateTime($revision->start_date);

return view('event', [
'event' => $revision,
'year' => $date->format('Y'),
'month' => $date->format('m'),
'key' => $revision->key,
'slug' => $revision->slug,
'mode' => 'archive',
'event_id' => $event->id,
]);
}

public function view_revision_diff(Event $event, EventRevision $revision) {
Gate::authorize('manage-event', $revision);

$previous = EventRevision::where('key', $revision->key)
->where('id', '!=', $revision->id)
->where('created_at', '<', $revision->created_at)
->orderBy('created_at', 'desc')
->first();

return view('diff', [
'current' => $revision,
'previous' => $previous,
'event_id' => $event->id,
]);
}

public function upload_event_cover_image(Event $event) {
Gate::authorize('manage-event', $event);

Expand Down
4 changes: 4 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class User extends Authenticatable
protected $casts = [
];

public function display_name() {
return $this->name ?: \p3k\url\display_url($this->url);
}

public function downloadProfilePhoto($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"guzzlehttp/guzzle": "^6.5",
"indieweb/date-formatter": "^0.3.1",
"intervention/image": "^2.5",
"jfcherng/php-diff": "^6.7",
"laravel/framework": "^6.13",
"laravel/tinker": "^1.0",
"lcobucci/jwt": "^3.3",
Expand Down
Loading

0 comments on commit 893811e

Please sign in to comment.