Skip to content

Commit

Permalink
add all replacement functionality, relay more information to user in …
Browse files Browse the repository at this point in the history
…replacement modal
  • Loading branch information
taheralfayad committed May 16, 2024
1 parent 35c319e commit 95037a4
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 92 deletions.
6 changes: 6 additions & 0 deletions assets/js/Components/FilesModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ class FilesModal extends React.Component {
return
}

const userConfirmed = window.confirm(this.props.t('msg.confirmation'));

if (!userConfirmed) {
return;
}

let api = new Api(this.props.settings)
api.postFile(activeFile, this.state.replaceFileObj)
.then((responsStr) => responsStr.json())
Expand Down
267 changes: 191 additions & 76 deletions src/Lms/Canvas/CanvasApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function apiPost($url, $options, $sendAuthorized = true)
}

// Posts a file to Canvas
public function apiFilePost(string $url, array $options, string $filepath, string $newFileName, $moduleInstances = null, $courseId = null, $replacePages = null, $replaceAssignments = null) : LmsResponse
public function apiFilePost(string $url, array $options, string $filepath, string $newFileName, $changeReferences = null) : LmsResponse
{
$fileResponse = $this->apiGet($url);
$file = $fileResponse->getContent();
Expand All @@ -122,8 +122,6 @@ public function apiFilePost(string $url, array $options, string $filepath, strin
$endpointResponse = $this->apiPost($options['postUrl'], ['query' => $endpointOptions], true);
$endpointContent = $endpointResponse->getContent();

$this->apiDelete($url);

// TODO: handle failed call

$formFields = $endpointContent['upload_params'];
Expand All @@ -137,79 +135,13 @@ public function apiFilePost(string $url, array $options, string $filepath, strin

$fileResponseContent = $fileResponse->getContent();

if($moduleInstances) {
foreach ($moduleInstances as $moduleInstance) {
$response = $this->apiPost("courses/{$courseId}/modules/{$moduleInstance}/items", [
'json' => [
'module_item' => [
'title' => $newFileName,
'type' => 'File',
'content_id' => $fileResponseContent['id'],
],
],
]);

}
}

if($replacePages) {
foreach ($replacePages as $page) {
$dom = new \DOMDocument();
$dom->loadHTML($page['body']);
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $anchor) {
preg_match('/files\/(\d+)/', $anchor->getAttribute('href'), $matches);
if (isset($matches[1]) && $matches[1] == $file['id']) {
$anchor->setAttribute('href', $fileResponseContent['url']);
$anchor->setAttribute('title', $newFileName);
$anchor->nodeValue = $newFileName;
}
$page['body'] = $dom->saveHTML();
$response = $this->apiPut("courses/{$courseId}/pages/{$page['page_id']}", [
'json' => [
'wiki_page' => [
'title' => $page['title'],
'body' => $page['body'],
'editing_roles' => $page['editing_roles'],
'published' => $page['published'],
'front_page' => $page['front_page'],
'hide_from_students' => $page['hide_from_students'],
'notify_of_update' => $page['notify_of_update'],
'attachments' => [
[
'url' => $fileResponseContent['url'],
'filename' => $newFileName,
],
],
],
],
]);
}
}
}

if ($replaceAssignments) {
foreach ($replaceAssignments as $assignment) {
$dom = new \DOMDocument();
$dom->loadHTML($assignment['description']);
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $anchor) {
preg_match('/files\/(\d+)/', $anchor->getAttribute('href'), $matches);
if (isset($matches[1]) && $matches[1] == $file['id']) {
$anchor->setAttribute('href', $fileResponseContent['url']);
$anchor->setAttribute('title', $newFileName);
$anchor->nodeValue = $newFileName;
}
$assignment['description'] = $dom->saveHTML();
$response = $this->apiPut("courses/{$courseId}/assignments/{$assignment['id']}", [
'json' => [
'assignment' => [
'description' => $assignment['description'],
],
],
]);
}
}
if($changeReferences) {
$this->changeLinksInSyllabus($changeReferences['course_id'], $file['id'], $fileResponseContent['url'], $newFileName);
$this->changeModuleItemInstances($changeReferences['course_id'], $changeReferences['modules'], $newFileName, $fileResponseContent['id']);
$this->changeLinksInPages($changeReferences['course_id'], $file['id'], $changeReferences['pages'], $fileResponseContent['url'], $newFileName);
$this->changeLinksInAssignments($changeReferences['course_id'], $file['id'], $changeReferences['assignments'], $fileResponseContent['url'], $newFileName);
$this->changeLinksInQuizzes($changeReferences['course_id'], $file['id'], $changeReferences['quizzes'], $fileResponseContent['url'], $newFileName);
$this->changeLinksInQuizQuestions($changeReferences['course_id'], $file['id'], $changeReferences['quizQuestions'], $fileResponseContent['url'], $newFileName);
}

return $fileResponse;
Expand Down Expand Up @@ -266,6 +198,18 @@ public function apiDelete($url) {

}

public function getCourse($courseId, $includeSyllabus = false)
{
if ($includeSyllabus) {
$url = "courses/{$courseId}?include[]=syllabus_body";
}
else {
$url = "courses/{$courseId}";
}
$response = $this->apiGet($url);
return $response->getContent();
}

public function listModules($courseId)
{
$url = "courses/{$courseId}/modules";
Expand Down Expand Up @@ -317,4 +261,175 @@ public function listAssignments($courseId)
return $response->getContent();
}

public function listQuizzes($courseId)
{
$url = "courses/{$courseId}/quizzes";
$response = $this->apiGet($url);
return $response->getContent();
}

public function listQuizQuestions($courseId, $quizId)
{
$url = "courses/{$courseId}/quizzes/{$quizId}/questions";
$response = $this->apiGet($url);
return $response->getContent();
}

public function updateCourse($courseId, $options)
{
$url = "courses/{$courseId}";
$response = $this->apiPut($url, $options);
return $response->getContent();
}

public function uploadModuleItem($courseId, $moduleId, $options)
{
$url = "courses/{$courseId}/modules/{$moduleId}/items";
$response = $this->apiPost($url, $options);
return $response->getContent();
}

public function updatePage($courseId, $pageId, $options)
{
$url = "courses/{$courseId}/pages/{$pageId}";
$response = $this->apiPut($url, $options);
return $response->getContent();
}

public function updateAssignment($courseId, $assignmentId, $options)
{
$url = "courses/{$courseId}/assignments/{$assignmentId}";
$response = $this->apiPut($url, $options);
return $response->getContent();
}

public function updateQuiz($courseId, $quizId, $options)
{
$url = "courses/{$courseId}/quizzes/{$quizId}";
$response = $this->apiPut($url, $options);
return $response->getContent();
}

public function updateQuizQuestion($courseId, $quizId, $questionId, $options)
{
$url = "courses/{$courseId}/quizzes/{$quizId}/questions/{$questionId}";
$response = $this->apiPut($url, $options);
return $response->getContent();
}

/**********************
* PROTECTED FUNCTIONS
**********************/


protected function changeLinksInSyllabus($courseId, $oldFileId, $newUrl, $newFileName)
{
$course = $this->getCourse($courseId, true);
$dom = new \DOMDocument();

$dom->loadHTML($course['syllabus_body']);
$anchors = $dom->getElementsByTagName('a');
$newSyllabus = $this->changeAnchorTags($dom, $oldFileId, $newUrl, $newFileName);
if ($newSyllabus != $course['syllabus_body']) {
$this->updateCourse($courseId, ['json' => ['course' => ['syllabus_body' => $newSyllabus]]]);
}
}

protected function changeModuleItemInstances($courseId, $moduleInstances, $newFileName, $newFileId) {
foreach ($moduleInstances as $moduleInstance) {
$this->uploadModuleItem($courseId, $moduleInstance, [
'json' => [
'module_item' => [
'title' => $newFileName,
'type' => 'File',
'content_id' => $newFileId,
],
],
]);
}
}

protected function changeLinksInPages($courseId, $oldFileId, $pages, $newUrl, $newFileName) {
foreach ($pages as $page) {
$dom = new \DOMDocument();
$dom->loadHTML($page['body']);
$newPage = $this->changeAnchorTags($dom, $oldFileId, $newUrl, $newFileName);
if ($newPage != $page['body']) {
$this->updatePage($courseId, $page['page_id'], [
'json' => [
'wiki_page' => [
'body' => $newPage,
],
],
]);
}
}
}

protected function changeLinksInAssignments($courseId, $oldFileId, $assignments, $newUrl, $newFileName) {
foreach ($assignments as $assignment) {
$dom = new \DOMDocument();
$dom->loadHTML($assignment['description']);
$newAssignment = $this->changeAnchorTags($dom, $oldFileId, $newUrl, $newFileName);
if ($newAssignment != $assignment['description']) {
$this->updateAssignment($courseId, $assignment['id'], [
'json' => [
'assignment' => [
'description' => $newAssignment,
],
],
]);
}
}
}

protected function changeLinksInQuizzes($courseId, $oldFileId, $quizzes, $newUrl, $newFileName) {
foreach ($quizzes as $quiz) {
$dom = new \DOMDocument();
$dom->loadHTML($quiz['description']);
$newQuiz = $this->changeAnchorTags($dom, $oldFileId, $newUrl, $newFileName);
if ($newQuiz != $quiz['description']) {
$this->updateQuiz($courseId, $quiz['id'], [
'json' => [
'quiz' => [
'description' => $newQuiz,
'notify_of_update' => $quiz['notify_of_update'],
],
],
]);
}
}
}

public function changeLinksInQuizQuestions($courseId, $oldFileId, $replaceQuizQuestions, $newUrl, $newFileName) {
foreach ($replaceQuizQuestions as $quizQuestion) {
$dom = new \DOMDocument();
$dom->loadHTML($quizQuestion['question_text']);
$newQuestion = $this->changeAnchorTags($dom, $oldFileId, $newUrl, $newFileName);
if ($newQuestion != $quizQuestion['question_text']) {
$this->updateQuizQuestion($courseId, $quizQuestion['quiz_id'], $quizQuestion['id'], [
'json' => [
'question' => [
'question_text' => $newQuestion,
],
],
]);
}
}
}

protected function changeAnchorTags($dom, $fileId, $newUrl, $newFileName) {
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $anchor) {
preg_match('/files\/(\d+)/', $anchor->getAttribute('href'), $matches);
if (isset($matches[1]) && $matches[1] == $fileId) {
$anchor->setAttribute('href', $newUrl);
$anchor->setAttribute('title', $newFileName);
$anchor->nodeValue = $newFileName;
}
}

return $dom->saveHTML();
}

}
40 changes: 25 additions & 15 deletions src/Lms/Canvas/CanvasLms.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,8 @@ public function postFileItem(FileItem $file, string $newFileName)
$modules = $canvasApi->listModules($file->getCourse()->getLmsCourseId());
$pages = $canvasApi->listPages($file->getCourse()->getLmsCourseId());
$assignments = $canvasApi->listAssignments($file->getCourse()->getLmsCourseId());
$refillModules = [];
$changePages = [];
$changeAssignments = [];
$quizzes = $canvasApi->listQuizzes($file->getCourse()->getLmsCourseId());
$changeReferences = ['course_id' => $file->getCourse()->getLmsCourseId(),'modules' => [], 'pages' => [], 'assignments' => [], 'quizzes' => [], 'quizQuestions' => []];

// Delete any existing module items with the same file name
foreach ($modules as $module) {
Expand All @@ -391,28 +390,39 @@ public function postFileItem(FileItem $file, string $newFileName)
foreach ($instances as $instance) {
$canvasApi->deleteModuleItem($file->getCourse()->getLmsCourseId(), $module['id'], $instance['id']);
}
$refillModules[] = $module['id'];
$changeReferences['modules'][] = $module['id'];
}
}

// Find all wiki pages that contain this file in their HTML
foreach ($pages as $page) {
$dom = new \DOMDocument();
$dom->loadHTML($page['body']);
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $anchor) {
preg_match('/files\/(\d+)/', $anchor->getAttribute('href'), $matches);
if(isset($matches[1]) && $matches[1] == $file->getLmsFileId()) {
$changePages[] = $page;
break;
}
if ($this->fileIsInLink($file->getLmsFileId(), $page['body'])) {
$changeReferences['pages'][] = $page;
}
}

// Find all assignments that contain this file in their description HTML
foreach ($assignments as $assignment) {
if ($this->fileIsInLink($file->getLmsFileId(), $assignment['description'])) {
$changeAssignments[] = $assignment;
$changeReferences['assignments'][] = $assignment;
}
}

// Find all quizzes that contain this file in their description HTML
foreach ($quizzes as $quiz) {
if ($this->fileIsInLink($file->getLmsFileId(), $quiz['description'])) {
$changeReferences['quizzes'][] = $quiz;
}

// Check quiz questions for references to the file
$questions[] = $canvasApi->listQuizQuestions($file->getCourse()->getLmsCourseId(), $quiz['id']);

$questions = $questions[0];

foreach ($questions as $question) {
if ($this->fileIsInLink($file->getLmsFileId(), $question['question_text'])) {
$changeReferences['quizQuestions'][] = $question;
}
}
}

Expand All @@ -422,7 +432,7 @@ public function postFileItem(FileItem $file, string $newFileName)
'postUrl' => "courses/{$file->getCourse()->getLmsCourseId()}/files"
];

$fileResponse = $canvasApi->apiFilePost($url, $options, $filepath, $newFileName, $refillModules, $file->getCourse()->getLmsCourseId(), $changePages, $changeAssignments);
$fileResponse = $canvasApi->apiFilePost($url, $options, $filepath, $newFileName, $changeReferences);
$fileObj = $fileResponse->getContent();

if (isset($fileObj['id'])) {
Expand Down
Loading

0 comments on commit 95037a4

Please sign in to comment.