Skip to content

Commit

Permalink
Merge branch 'MDL-58835_master' of git://github.com/dmonllao/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
danpoltawski committed Sep 12, 2017
2 parents 776ca02 + 2e151c3 commit 8e085aa
Show file tree
Hide file tree
Showing 20 changed files with 724 additions and 48 deletions.
28 changes: 26 additions & 2 deletions analytics/classes/local/target/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,42 @@ public static function based_on_assumptions() {
* @return \core_analytics\prediction_action[]
*/
public function prediction_actions(\core_analytics\prediction $prediction, $includedetailsaction = false) {
global $PAGE;

$predictionid = $prediction->get_prediction_data()->id;

$PAGE->requires->js_call_amd('report_insights/actions', 'init', array($predictionid));

$actions = array();

if ($includedetailsaction) {

$predictionurl = new \moodle_url('/report/insights/prediction.php',
array('id' => $prediction->get_prediction_data()->id));
array('id' => $predictionid));

$actions['predictiondetails'] = new \core_analytics\prediction_action('predictiondetails', $prediction,
$actions[] = new \core_analytics\prediction_action(\core_analytics\prediction::ACTION_PREDICTION_DETAILS, $prediction,
$predictionurl, new \pix_icon('t/preview', get_string('viewprediction', 'analytics')),
get_string('viewprediction', 'analytics'));
}

// Flag as fixed / solved.
$fixedattrs = array(
'data-prediction-id' => $predictionid,
'data-prediction-methodname' => 'report_insights_set_fixed_prediction'
);
$actions[] = new \core_analytics\prediction_action(\core_analytics\prediction::ACTION_FIXED,
$prediction, new \moodle_url(''), new \pix_icon('t/check', get_string('fixedack', 'analytics')),
get_string('fixedack', 'analytics'), false, $fixedattrs);

// Flag as not useful.
$notusefulattrs = array(
'data-prediction-id' => $predictionid,
'data-prediction-methodname' => 'report_insights_set_notuseful_prediction'
);
$actions[] = new \core_analytics\prediction_action(\core_analytics\prediction::ACTION_NOT_USEFUL,
$prediction, new \moodle_url(''), new \pix_icon('t/delete', get_string('notuseful', 'analytics')),
get_string('notuseful', 'analytics'), false, $notusefulattrs);

return $actions;
}

Expand Down
48 changes: 39 additions & 9 deletions analytics/classes/model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1041,15 +1041,29 @@ public function mark_as_trained() {
/**
* Get the contexts with predictions.
*
* @param bool $skiphidden Skip hidden predictions
* @return \stdClass[]
*/
public function get_predictions_contexts() {
global $DB;
public function get_predictions_contexts($skiphidden = true) {
global $DB, $USER;

$sql = "SELECT DISTINCT ap.contextid FROM {analytics_predictions} ap
JOIN {context} ctx ON ctx.id = ap.contextid
WHERE ap.modelid = ?";
return $DB->get_records_sql($sql, array($this->model->id));
WHERE ap.modelid = :modelid";
$params = array('modelid' => $this->model->id);

if ($skiphidden) {
$sql .= " AND NOT EXISTS (
SELECT 1
FROM {analytics_prediction_actions} apa
WHERE apa.predictionid = ap.id AND apa.userid = :userid AND (apa.actionname = :fixed OR apa.actionname = :notuseful)
)";
$params['userid'] = $USER->id;
$params['fixed'] = \core_analytics\prediction::ACTION_FIXED;
$params['notuseful'] = \core_analytics\prediction::ACTION_NOT_USEFUL;
}

return $DB->get_records_sql($sql, $params);
}

/**
Expand Down Expand Up @@ -1096,12 +1110,13 @@ public function predictions_exist(\context $context) {
* Gets the predictions for this context.
*
* @param \context $context
* @param bool $skiphidden Skip hidden predictions
* @param int $page The page of results to fetch. False for all results.
* @param int $perpage The max number of results to fetch. Ignored if $page is false.
* @return array($total, \core_analytics\prediction[])
*/
public function get_predictions(\context $context, $page = false, $perpage = 100) {
global $DB;
public function get_predictions(\context $context, $skiphidden = true, $page = false, $perpage = 100) {
global $DB, $USER;

\core_analytics\manager::check_can_list_insights($context);

Expand All @@ -1111,12 +1126,27 @@ public function get_predictions(\context $context, $page = false, $perpage = 100
JOIN (
SELECT sampleid, max(rangeindex) AS rangeindex
FROM {analytics_predictions}
WHERE modelid = ? and contextid = ?
WHERE modelid = :modelidsubap and contextid = :contextidsubap
GROUP BY sampleid
) apsub
ON ap.sampleid = apsub.sampleid AND ap.rangeindex = apsub.rangeindex
WHERE ap.modelid = ? and ap.contextid = ?";
$params = array($this->model->id, $context->id, $this->model->id, $context->id);
WHERE ap.modelid = :modelid and ap.contextid = :contextid";

$params = array('modelid' => $this->model->id, 'contextid' => $context->id,
'modelidsubap' => $this->model->id, 'contextidsubap' => $context->id);

if ($skiphidden) {
$sql .= " AND NOT EXISTS (
SELECT 1
FROM {analytics_prediction_actions} apa
WHERE apa.predictionid = ap.id AND apa.userid = :userid AND (apa.actionname = :fixed OR apa.actionname = :notuseful)
)";
$params['userid'] = $USER->id;
$params['fixed'] = \core_analytics\prediction::ACTION_FIXED;
$params['notuseful'] = \core_analytics\prediction::ACTION_NOT_USEFUL;
}

$sql .= " ORDER BY ap.timecreated DESC";
if (!$predictions = $DB->get_records_sql($sql, $params)) {
return array();
}
Expand Down
60 changes: 60 additions & 0 deletions analytics/classes/prediction.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@
*/
class prediction {

/**
* Prediction details (one of the default prediction actions)
*/
const ACTION_PREDICTION_DETAILS = 'predictiondetails';

/**
* Prediction not useful (one of the default prediction actions)
*/
const ACTION_NOT_USEFUL = 'notuseful';

/**
* Prediction already fixed (one of the default prediction actions)
*/
const ACTION_FIXED = 'fixed';

/**
* @var \stdClass
*/
Expand Down Expand Up @@ -97,6 +112,51 @@ public function get_calculations() {
return $this->calculations;
}

/**
* Stores the executed action.
* Prediction instances should be retrieved using \core_analytics\manager::get_prediction,
* It is the caller responsability to check that the user can see the prediction.
*
* @param string $actionname
* @param \core_analytics\local\target\base $target
*/
public function action_executed($actionname, \core_analytics\local\target\base $target) {
global $USER, $DB;

$context = \context::instance_by_id($this->get_prediction_data()->contextid, IGNORE_MISSING);
if (!$context) {
throw new \moodle_exception('errorpredictioncontextnotavailable', 'analytics');
}

// Check that the provided action exists.
$actions = $target->prediction_actions($this, true);
foreach ($actions as $action) {
if ($action->get_action_name() === $actionname) {
$found = true;
}
}
if (empty($found)) {
throw new \moodle_exception('errorunknownaction', 'analytics');
}

$predictionid = $this->get_prediction_data()->id;

$action = new \stdClass();
$action->predictionid = $predictionid;
$action->userid = $USER->id;
$action->actionname = $actionname;
$action->timecreated = time();
$DB->insert_record('analytics_prediction_actions', $action);

$eventdata = array (
'context' => $context,
'objectid' => $predictionid,
'other' => array('actionname' => $actionname)
);
\core\event\prediction_action_started::create($eventdata)->trigger();
}

/**
* format_calculations
*
Expand Down
36 changes: 27 additions & 9 deletions analytics/classes/prediction_action.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,54 @@
*/
class prediction_action {

/**
* @var string
*/
protected $actionname = null;

/**
* @var \action_menu_link
*/
protected $actionlink = null;

/**
* __construct
* Prediction action constructor.
*
* @param string $actionname
* @param string $actionname They should match a-zA-Z_0-9-, as we apply a PARAM_ALPHANUMEXT filter
* @param \core_analytics\prediction $prediction
* @param \moodle_url $actionurl
* @param \pix_icon $icon
* @param string $text
* @param bool $primary
* @param \pix_icon $icon Link icon
* @param string $text Link text
* @param bool $primary Primary button or secondary.
* @param array $attributes Link attributes
* @return void
*/
public function __construct($actionname, \core_analytics\prediction $prediction, \moodle_url $actionurl, \pix_icon $icon, $text, $primary = false) {
public function __construct($actionname, \core_analytics\prediction $prediction, \moodle_url $actionurl, \pix_icon $icon,
$text, $primary = false, $attributes = array()) {

$this->actionname = $actionname;

// We want to track how effective are our suggested actions, we pass users through a script that will log these actions.
$params = array('action' => $actionname, 'predictionid' => $prediction->get_prediction_data()->id,
$params = array('action' => $this->actionname, 'predictionid' => $prediction->get_prediction_data()->id,
'forwardurl' => $actionurl->out(false));
$url = new \moodle_url('/report/insights/action.php', $params);

if ($primary === false) {
$this->actionlink = new \action_menu_link_secondary($url, $icon, $text);
$this->actionlink = new \action_menu_link_secondary($url, $icon, $text, $attributes);
} else {
$this->actionlink = new \action_menu_link_primary($url, $icon, $text);
$this->actionlink = new \action_menu_link_primary($url, $icon, $text, $attributes);
}
}

/**
* Returns the action name.
*
* @return string
*/
public function get_action_name() {
return $this->actionname;
}

/**
* Returns the link to the action.
*
Expand Down
Loading

0 comments on commit 8e085aa

Please sign in to comment.