Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow widgets to save their current play state so a play can be resumed later. #1238

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions fuel/app/classes/controller/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,15 @@ protected function _play_widget($inst_id = false, $demo=false, $is_embedded=fals

// create the play
$play_id = \Materia\Api::session_play_create($inst_id, $context_id);
$play_state = \Materia\Session_Play::get_play_state($play_id) ?: '';

if ($play_id instanceof \Materia\Msg)
{
\Log::warning('session_play_create failed!');
throw new HttpServerErrorException;
}

$this->display_widget($inst, $play_id, $is_embedded);
$this->display_widget($inst, $play_id, $is_embedded, $play_state);
}

/**
Expand Down Expand Up @@ -456,7 +457,7 @@ protected function build_widget_login_messages($inst)
return [$summary, $desc, $status['open']];
}

protected function display_widget(\Materia\Widget_Instance $inst, $play_id=false, $is_embedded=false)
protected function display_widget(\Materia\Widget_Instance $inst, $play_id=false, $is_embedded=false, $play_state=null)
{
Css::push_group(['core', 'widget_play']);
Js::push_group(['angular', 'materia', 'student']);
Expand All @@ -467,6 +468,7 @@ protected function display_widget(\Materia\Widget_Instance $inst, $play_id=false
}

Js::push_inline('var PLAY_ID = "'.$play_id.'";');
Js::push_inline("var PLAY_STATE = '".$play_state."';");
$this->add_s3_config_to_response();
$this->theme->get_template()
->set('title', $inst->name.' '.$inst->widget->name)
Expand Down
15 changes: 15 additions & 0 deletions fuel/app/classes/materia/api/v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ static public function play_activity_get($start = 0, $range = 6)
// but we don't want to include that in the results
$play = new Session_Play();
$plays = $play->get_plays_by_user_id(\Model_User::find_current_id(), $start, $range + 1);
trace($plays);
$count = count($plays);
if ($count > $range) $plays = array_slice($plays, 0, $range);
return [
Expand All @@ -393,6 +394,20 @@ static public function play_activity_get($start = 0, $range = 6)
];
}

static public function play_state_save($play_id, $state)
{
$inst = self::_get_instance_for_play_id($play_id);
if ( ! $inst->playable_by_current_user()) return Msg::no_login();
if ($inst->guest_access) return;

$encoded_state = base64_encode(json_encode($state));

\DB::update('log_play')
->value('last_state', $encoded_state)
->where('id', $play_id)
->execute();
}

static public function play_logs_save($play_id, $logs, $preview_inst_id = null)
{
if ( ! $preview_inst_id)
Expand Down
34 changes: 32 additions & 2 deletions fuel/app/classes/materia/session/play.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class Session_Play
public $referrer_url;
public $score;
public $user_id;
public $last_state;

/**
* NEEDS DOCUMENTAION
Expand Down Expand Up @@ -60,6 +61,7 @@ public function start($user_id=0, $inst_id=0, $context_id=false, $is_preview=fal
'ip_address' => \Input::ip(),
'referrer' => \Input::referrer(),
];
$this->last_state = $this->unfinished_play_state() ?: '';

// @TODO: This is a hack - assuming 'lti_message_type' in POST or 'token' in GET implies an LTI.
// Essentially true but fragile.
Expand Down Expand Up @@ -104,6 +106,32 @@ protected static function set_user_is_playing()
\Session::set('user_is_playing', true);
}

public static function get_play_state($play_id)
{
$last_state = \DB::select('last_state')
->from('log_play')
->where('id', $play_id)
->execute();
if ( ! empty($last_state[0])) return base64_decode($last_state[0]['last_state']);
return false;
}

//used to grab the most recent saved state from an unfinished play of this instance by this user
protected function unfinished_play_state()
{
$last_state = \DB::select('last_state')
->from('log_play')
->where('inst_id', $this->inst_id)
->where('user_id', $this->user_id)
->where('is_complete', '0')
->where('last_state', '!=', '')
->order_by('created_at', 'desc')
->limit(1)
->execute();
if ( ! empty($last_state[0])) return $last_state[0]['last_state'];
return false;
}

protected static function start_preview($inst_id)
{
$previews = \Session::get('widgetPreviews', [0 => '']);
Expand Down Expand Up @@ -154,7 +182,8 @@ protected function insert_play($hash)
'auth' => $this->auth,
'referrer_url' => $this->referrer_url,
'context_id' => $this->context_id,
'semester' => $this->semester
'semester' => $this->semester,
'last_state' => $this->last_state
])
->execute();

Expand Down Expand Up @@ -427,7 +456,8 @@ public function get_plays_by_user_id($user_id, $start, $range)
'p.is_complete',
'p.inst_id',
['w.name', 'widget_name'],
['i.name', 'inst_name']
['i.name', 'inst_name'],
'p.last_state'
)
->from( ['log_play', 'p'])
->join( ['widget_instance', 'i'], 'LEFT')
Expand Down
21 changes: 21 additions & 0 deletions fuel/app/migrations/040_add_play_state_to_log_play.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Fuel\Migrations;

class Add_Play_State_To_Log_Play
{
public function up()
{
\DBUtil::add_fields(
'log_play',
[
'last_state' => ['type' => 'longblob'],
]
);
}

public function down()
{
\DBUtil::drop_fields('log_play', ['last_state']);
}
}