@@ -180,7 +180,11 @@ public function updateCourseContent(Course $course, User $user, $force = false):
180180 $ apiToken = $ this ->getApiToken ($ user );
181181
182182 $ canvasApi = new CanvasApi ($ apiDomain , $ apiToken );
183+ $ tempPages = [];
184+ $ pageUrls = [];
185+ $ asyncFetch = true ;
183186
187+ $ start_time = microtime (true );
184188 foreach ($ urls as $ contentType => $ url ) {
185189 $ response = $ canvasApi ->apiGet ($ url );
186190
@@ -197,9 +201,13 @@ public function updateCourseContent(Course $course, User $user, $force = false):
197201 }
198202
199203 foreach ($ contentList as $ content ) {
200- if (('file ' === $ contentType ) && (in_array ($ content ['mime_class ' ], $ this ->util ->getUnscannableFileMimeClasses ()))) {
201- $ this ->updateFileItem ($ course , $ content );
202- continue ;
204+
205+ if ('file ' === $ contentType ) {
206+ $ output ->writeln ('Found ' . $ content ['mime_class ' ] . ' file: ' . $ content ['display_name ' ]);
207+ if (in_array ($ content ['mime_class ' ], $ this ->util ->getUnscannableFileMimeClasses ())) {
208+ $ this ->updateFileItem ($ course , $ content );
209+ continue ;
210+ }
203211 }
204212
205213 /* Quizzes should not be counted as assignments */
@@ -238,14 +246,31 @@ public function updateCourseContent(Course $course, User $user, $force = false):
238246 $ output ->writeln ('New content item - ' . $ contentType . ': ' . $ lmsContent ['title ' ]);
239247 }
240248
241- /* get page content */
249+ if (!$ contentItem ) {
250+ $ contentItem = new ContentItem ();
251+ $ contentItem ->setCourse ($ course )
252+ ->setLmsContentId ($ lmsContent ['id ' ])
253+ ->setActive (true )
254+ ->setContentType ($ contentType );
255+ $ this ->entityManager ->persist ($ contentItem );
256+ }
257+
242258 if ('page ' === $ contentType ) {
243- $ url = "courses/ {$ course ->getLmsCourseId ()}/pages/ {$ lmsContent ['id ' ]}" ;
244- $ pageResponse = $ canvasApi ->apiGet ($ url );
245- $ pageObj = $ pageResponse ->getContent ();
259+ $ url = "courses/ {$ course ->getLmsCourseId ()}/pages/ {$ lmsContent ['id ' ]}" ;
260+ if ($ asyncFetch ) {
261+ /* NEW PAGE FETCH: New asynchronous batch fetch. The real magic is in the $pageUrls handler beneath this foreach loop (line ~305). */
262+ $ tempContentItems [] = $ contentItem ;
263+ $ pageUrls [] = $ url ;
264+ continue ;
265+ }
266+ else {
267+ /* OLD PAGE FETCH: 1-at-a-time synchronous fetch */
268+ $ pageResponse = $ canvasApi ->apiGet ($ url );
269+ $ pageObj = $ pageResponse ->getContent ();
246270
247- if (!empty ($ pageObj ['body ' ])) {
248- $ lmsContent ['body ' ] = $ pageObj ['body ' ];
271+ if (!empty ($ pageObj ['body ' ])) {
272+ $ lmsContent ['body ' ] = $ pageObj ['body ' ];
273+ }
249274 }
250275 }
251276
@@ -254,15 +279,6 @@ public function updateCourseContent(Course $course, User $user, $force = false):
254279 $ lmsContent ['body ' ] = file_get_contents ($ content ['url ' ]);
255280 }
256281
257- if (!$ contentItem ) {
258- $ contentItem = new ContentItem ();
259- $ contentItem ->setCourse ($ course )
260- ->setLmsContentId ($ lmsContent ['id ' ])
261- ->setActive (true )
262- ->setContentType ($ contentType );
263- $ this ->entityManager ->persist ($ contentItem );
264- }
265-
266282 // some content types don't have an updated date, so we'll compare content
267283 // to find out if content has changed.
268284 if (in_array ($ contentType , ['syllabus ' , 'discussion_topic ' , 'announcement ' , 'quiz ' ])) {
@@ -281,9 +297,42 @@ public function updateCourseContent(Course $course, User $user, $force = false):
281297 }
282298 }
283299
300+ // If there are any pages to fetch, handle that now...
301+ if (count ($ pageUrls ) > 0 ) {
302+
303+ $ output ->writeln ('Fetching contents for ' . count ($ pageUrls ) . ' pages asynchronously... ' );
304+
305+ // Request pages in a batch instead of synchronously
306+ $ allPages = $ canvasApi ->apiGetBatch ($ pageUrls );
307+
308+ // Save indices for the tempContentItems array so it will be easier (O(1)) to match up...
309+ $ tempContentItemsIndexById = [];
310+ foreach ($ tempContentItems as $ index => $ item ) {
311+ $ tempContentItemsIndexById [$ item ->getLmsContentId ()] = $ index ;
312+ }
313+
314+ foreach ($ allPages as $ pageData ) {
315+ $ lmsContent = $ this ->normalizeLmsContent ($ course , 'page ' , json_decode ($ pageData , true ));
316+
317+ if (!empty ($ lmsContent ['body ' ])) {
318+ $ lmsContentId = $ lmsContent ['id ' ];
319+ // If the item exists in the tempContentItems array... Update and add to contentItems to scan.
320+ if (isset ($ tempContentItemsIndexById [$ lmsContentId ])) {
321+ $ index = $ tempContentItemsIndexById [$ lmsContentId ];
322+ $ tempContentItems [$ index ]->update ($ lmsContent );
323+ $ contentItems [] = $ tempContentItems [$ index ];
324+ }
325+ }
326+ }
327+ }
328+
284329 // push any updates made to content items to DB
285330 $ this ->entityManager ->flush ();
286331
332+ // Log how long things took (compare synchronous vs asynchronous page fetch)
333+ $ end_time = microtime (true );
334+ $ output ->writeln ('updateCourseContent - time taken: ' . ($ end_time - $ start_time ) . ' seconds ' );
335+
287336 return $ contentItems ;
288337 }
289338
0 commit comments