Moodleのリソースで「動画を全て視聴したら完了にする」ようにする

# 「動画を全て視聴したら完了にする」にしたい！

mod_resourceで動画教材を作成すると、__画面を開いた瞬間__に活動完了トラッキング「完了」にしてしまう仕様となっています。この場合、ページを開いただけで完了扱いとなってしまうため、学生が動画を全部視聴したかどうかを確認することが出来ません。

そこでこの記事では、__「動画を全て視聴したら完了にする」__を実現出来るようにします。

<img width="1019.25" alt="2018-05-10_0823_001.png (150.5 kB)" src="https://img.esa.io/uploads/production/attachments/8158/2018/05/10/4181/1c2bdcf5-bdce-4b71-8abd-cb7f7edf83da.png">

# 注意

この記事ではMoodleの標準プラグイン(mod_resource)を改造する内容となっております。他の機能には影響が出ないようにしていますが、Moodleのバージョンアップ時には本記事の改造をもう一度実施する必要があります。
また、今後のMoodleのバージョンによってはこの手法が使えなくなる可能性があります。

また、あくまで自己責任で行って下さい。

# 対応しているMoodleのバージョン

現時点ではMoodle3.4で確認済みです。
(本記事ではMoodle3.4を前提としています)

# 改造の方針
既存のソースコードへの改造は極力避け、可能な限りローカルプラグインで実装します。
また、出来るだけ新しいMoodleのAPIを使用する。

# 改造手順

おおまかな流れとしては、
* mod/resource/lib.php の`resource_view`関数の差し替え
* local_videocompのインストール

となります。local_videocompは私の方で作成したプラグインで、動画再生完了時のコールバックに使用するjavascriptが格納されています。

## 手順1 : mod/resource/lib.php の修正

mod/resource/lib.phpの526行目付近に`resource_view`という関数があります。

``` php:mod/resource/lib.php
function resource_view($resource, $course, $cm, $context) {

    // Trigger course_module_viewed event.
    $params = array(
        'context' => $context,
        'objectid' => $resource->id
    );

    $event = \mod_resource\event\course_module_viewed::create($params);
    $event->add_record_snapshot('course_modules', $cm);
    $event->add_record_snapshot('course', $course);
    $event->add_record_snapshot('resource', $resource);
    $event->trigger();

    // Completion.
    $completion = new completion_info($course);
    $completion->set_module_viewed($cm);
}
```

### 手順1 -1: `resource_view`関数を`_resource_view`に変更

この関数に手を加えていくのですが、後で元に戻せるようにコピーを残しておきます。
`resource_view`関数を`_resource_view`に変更します。

``` php:mod/resource/lib.php
function _resource_view($resource, $course, $cm, $context) {
```

この様な感じにします。

### 手順1-2 :  新しい`resource_view`関数を追加

次に、`_resource_view`関数の後(545行目あたり)に新しい`resource_view`関数を追加します。
次の改造済み`resource_view`関数を追加して下さい。

``` php:mod/resource/lib.php
/**
 * Mark the activity completed (if required) and trigger the course_module_viewed event.
 *
 * @param  stdClass $resource   resource object
 * @param  stdClass $course     course object
 * @param  stdClass $cm         course module object
 * @param  stdClass $context    context object
 * @since Moodle 3.0
 */
function resource_view($resource, $course, $cm, $context) {

    // Trigger course_module_viewed event.
    $params = array(
            'context' => $context,
            'objectid' => $resource->id
    );

    $event = \mod_resource\event\course_module_viewed::create($params);
    $event->add_record_snapshot('course_modules', $cm);
    $event->add_record_snapshot('course', $course);
    $event->add_record_snapshot('resource', $resource);
    $event->trigger();

    // Completion.
    $completion = new completion_info($course);

    // 動画ファイルの場合、ここでは「完了」にはしない。
    $fs = get_file_storage();
    $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder DESC, id ASC', false);
    if (count($files) >= 1) {
        $file = reset($files);
        unset($files);

        if(strpos($file->get_mimetype(), 'video') !== false){
            return;
        }
    }

    $completion->set_module_viewed($cm);
}
```

### 手順3 : localプラグイン(local_videocomp)をインストール

動画プレーヤーで動画を全て再生した時にステータスを「完了」にする[Moodleプラグイン](https://github.com/yuesan/moodle-local_videocomp)を公開しています。
local_videocompにはAJAX通信や活動完了が実装済となっています。

また、Moodle2.9以降で実装された'core/ajax'を使用した実装になっています。(Ajaxエンドポイントを自分で実装しなくてもよくなった)
https://docs.moodle.org/dev/AJAX

#### インストール方法

Moodleサーバ上で、次のコマンドでソースコードをダウンロードします。

```
cd /path/to/moodle
git clone https://github.com/yuesan/moodle-local_videocomp.git local/videocomp
```

次に、Moodleに管理者アカウントでログインし、インストールを行います。


以上の手順を踏むことで、「動画を全て視聴したら完了にする」ことが可能になります。

視聴が完了した所でこんな感じ↓になります。

<img width="917.25" alt="2018-05-10_2248.png (3.4 kB)" src="https://img.esa.io/uploads/production/attachments/8158/2018/05/10/4181/888802df-3ffa-442d-b5e2-b62d15e4ac8b.png">