commit 1ad55edfc40ae376daf56a929f34a2834c8138af
Author: jfederico <jesus@123it.ca>
Date:   Fri Nov 26 17:21:55 2021 +0000

    CONTRIB-8777: restored synchrony of recordngs in Moodle and BBB

diff --git a/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php b/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php
index 507529eac48..4ae1fab9f9e 100644
--- a/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php
+++ b/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php
@@ -165,9 +165,10 @@ class recording_proxy extends proxy_base {
      *
      * @param array $keyids list of meetingids or recordingids
      * @param string $key the param name used for the BBB request (<recordID>|meetingID)
+     * @param int $cachettl the ttl used for expiring cached recordings, deault 0 for no cache
      * @return array (associative) with recordings indexed by recordID, each recording is a non sequential array
      */
-    public static function fetch_recordings(array $keyids = [], string $key = 'recordID'): array {
+    public static function fetch_recordings(array $keyids = [], string $key = 'recordID', int $cachettl = 0): array {
         $recordings = [];
 
         // If $ids is empty return array() to prevent a getRecordings with meetingID and recordID set to ''.
@@ -177,7 +178,14 @@ class recording_proxy extends proxy_base {
 
         $cache = cache::make('mod_bigbluebuttonbn', 'recordings');
         $currentfetchcache = cache::make('mod_bigbluebuttonbn', 'currentfetch');
-        $recordings = array_filter($cache->get_many($keyids));
+        $recordings = array_filter(array_map(function($recording) use ($cachettl) {
+            if (!isset($recording['fetchedAt']) || $recording['fetchedAt'] + $cachettl <= time()) {
+                // Invalidate cached recording.
+                self::invalidate_cache_for_recording($recording['recordID']);
+                return false;
+            }
+            return $recording;
+        }, array_filter($cache->get_many($keyids))));
         $missingkeys = array_diff(array_values($keyids), array_keys($recordings));
 
         $pagesize = 25;
@@ -188,7 +196,6 @@ class recording_proxy extends proxy_base {
 
             $recordings += $fetchrecordings;
         }
-
         // Sort recordings.
         return self::sort_recordings($recordings);
     }
@@ -202,7 +209,7 @@ class recording_proxy extends proxy_base {
      */
     private static function fetch_recordings_page(array $ids, $key = 'recordID'): array {
         // The getRecordings call is executed using a method GET (supported by all versions of BBB).
-        $xml = self::fetch_endpoint_xml('getRecordings', [$key => implode(',', $ids)]);
+        $xml = self::fetch_endpoint_xml('getRecordings', [$key => implode(',', $ids), 'state' => 'any']);
 
         if (!$xml) {
             return [];
@@ -220,6 +227,7 @@ class recording_proxy extends proxy_base {
         // If there were meetings already created.
         foreach ($xml->recordings->recording as $recordingxml) {
             $recording = self::parse_recording($recordingxml);
+            $recording['fetchedAt'] = (string)time();
             $recordings[$recording['recordID']] = $recording;
 
             // Check if there is childs.
@@ -293,9 +301,13 @@ class recording_proxy extends proxy_base {
             self::parse_recording_meta(get_object_vars($recording->metadata));
         $recordingarray = [
             'recordID' => (string) $recording->recordID,
-            'meetingID' => (string) $recording->meetingID, 'meetingName' => (string) $recording->name,
-            'published' => (string) $recording->published, 'startTime' => (string) $recording->startTime,
-            'endTime' => (string) $recording->endTime, 'playbacks' => $playbackarray
+            'meetingID' => (string) $recording->meetingID,
+            'meetingName' => (string) $recording->name,
+            'published' => (string) $recording->published,
+            'state' => (string) $recording->state,
+            'startTime' => (string) $recording->startTime,
+            'endTime' => (string) $recording->endTime,
+            'playbacks' => $playbackarray
         ];
         if (isset($recording->protected)) {
             $recordingarray['protected'] = (string) $recording->protected;
diff --git a/mod/bigbluebuttonbn/classes/recording.php b/mod/bigbluebuttonbn/classes/recording.php
index a10a836d752..0543be0cad6 100644
--- a/mod/bigbluebuttonbn/classes/recording.php
+++ b/mod/bigbluebuttonbn/classes/recording.php
@@ -63,6 +63,9 @@ class recording extends persistent {
     /** @var int A meeting set to be recorded was processed and set back to an awaiting state */
     public const RECORDING_STATUS_RESET = 4;
 
+    /** @var int A meeting set to be recorded was deleted from bigbluebutton */
+    public const RECORDING_STATUS_DELETED = 5;
+
     /** @var bool Whether metadata been changed so the remote information needs to be updated ? */
     protected $metadatachanged = false;
 
@@ -683,27 +686,44 @@ class recording extends persistent {
     protected static function fetch_records(array $selects, array $params): array {
         global $DB;
 
+        $withindays = time() - (30 * DAYSECS);
+
         // Fetch the local data. Arbitrary sort by id, so we get the same result on different db engines.
         $recordings = $DB->get_records_select(static::TABLE, implode(" AND ", $selects), $params,
             self::DEFAULT_RECORDING_SORT);
 
         // Grab the recording IDs.
-        $recordingids = array_filter(array_map(function($recording) {
+        $recordingids = array_values(array_map(function($recording) {
             return $recording->recordingid;
         }, $recordings));
 
         // Fetch all metadata for these recordings.
-        $metadatas = recording_proxy::fetch_recordings($recordingids);
+        $cfg = \mod_bigbluebuttonbn\local\config::get_options();
+        $metadatas = recording_proxy::fetch_recordings($recordingids, 'recordID', $cfg['recording_refresh_period']);
 
         // Return the instances.
-        return array_map(function($recording) use ($metadatas) {
-            $metadata = null;
-            if (array_key_exists($recording->recordingid, $metadatas)) {
-                $metadata = $metadatas[$recording->recordingid];
+        return array_filter(array_map(function($recording) use ($metadatas, $withindays) {
+            // Do not include it if no metadata was fetched.
+            if (!array_key_exists($recording->recordingid, $metadatas)) {
+                // Mark it as dismissed if it is older than 30 days.
+                if ($withindays > $recording->timecreated) {
+                    $recording = new self(0, $recording, null);
+                    $recording->raw_set('status', self::RECORDING_STATUS_DISMISSED);
+                    $recording->update();
+                }
+                return false;
             }
-
+            $metadata = $metadatas[$recording->recordingid];
+            // Do not include it and mark it as deleted if it was deleted in BBB.
+            if ($metadata['state'] == 'deleted') {
+                $recording = new self(0, $recording, null);
+                $recording->raw_set('status', self::RECORDING_STATUS_DELETED);
+                $recording->update();
+                return false;
+            }
+            // Include it otherwise.
             return new self(0, $recording, $metadata);
-        }, $recordings);
+        }, $recordings));
     }
 
     /**
@@ -770,7 +790,8 @@ class recording extends persistent {
 
         // Fetch all metadata for these recordings.
         mtrace("=> Fetching recording metadata from server");
-        $metadatas = recording_proxy::fetch_recordings($recordingids);
+        $cfg = \mod_bigbluebuttonbn\local\config::get_options();
+        $metadatas = recording_proxy::fetch_recordings($recordingids, 'recordID', $cfg['recording_refresh_period']);
 
         $foundcount = 0;
         foreach ($metadatas as $recordingid => $metadata) {
