1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace repository_googledocs\local\node; 18 19 /** 20 * Class used to represent a file node in the googledocs repository. 21 * 22 * @package repository_googledocs 23 * @copyright 2021 Mihail Geshoski <mihail@moodle.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class file_node implements node { 27 28 /** @var string The ID of the file node. */ 29 private $id; 30 31 /** @var string|null The title of the file node. */ 32 private $title; 33 34 /** @var string The name of the file. */ 35 private $name; 36 37 /** @var string|null The file's export format. */ 38 private $exportformat; 39 40 /** @var string The external link to the file. */ 41 private $link; 42 43 /** @var string The timestamp representing the last modified date. */ 44 private $modified; 45 46 /** @var string|null The size of the file. */ 47 private $size; 48 49 /** @var string The thumbnail of the file. */ 50 private $thumbnail; 51 52 /** @var string|null The type of the Google Doc file (document, presentation, etc.), null if it is a regular file. */ 53 private $googledoctype; 54 55 /** 56 * Constructor. 57 * 58 * @param \stdClass $gdfile The Google Drive file object 59 */ 60 public function __construct(\stdClass $gdfile) { 61 $this->id = $gdfile->id; 62 $this->title = $this->generate_file_title($gdfile); 63 $this->name = $gdfile->name; 64 $this->exportformat = $this->generate_file_export_format($gdfile); 65 $this->link = $this->generate_file_link($gdfile); 66 $this->modified = ($gdfile->modifiedTime) ? strtotime($gdfile->modifiedTime) : ''; 67 $this->size = !empty($gdfile->size) ? $gdfile->size : null; 68 // Use iconLink as a file thumbnail if set, otherwise use the default icon depending on the file type. 69 // Note: The Google Drive API can return a link to a preview thumbnail of the file (via thumbnailLink). 70 // However, in many cases the Google Drive files are not public and an authorized request is required 71 // to get the thumbnail which we currently do not support. Therefore, to avoid displaying broken 72 // thumbnail images in the repository, the icon of the Google Drive file is being used as a thumbnail 73 // instead as it does not require an authorized request. 74 // Currently, the returned file icon link points to the 16px version of the icon by default which would result 75 // in displaying 16px file thumbnails in the repository. To avoid this, the link can be slightly modified in 76 // order to get a larger version of the icon as there isn't an option to request this through the API call. 77 $this->thumbnail = !empty($gdfile->iconLink) ? str_replace('/16/', '/64/', $gdfile->iconLink) : ''; 78 $this->googledoctype = !isset($gdfile->fileExtension) ? 79 str_replace('application/vnd.google-apps.', '', $gdfile->mimeType) : null; 80 } 81 82 /** 83 * Create a repository file array. 84 * 85 * This method returns an array which structure is compatible to represent a file node in the repository. 86 * 87 * @return array|null The node array or null if the node could not be created 88 */ 89 public function create_node_array(): ?array { 90 // Cannot create the file node if the file title was not generated or the export format. 91 // This means that the current file type is invalid or unknown. 92 if (!$this->title || !$this->exportformat) { 93 return null; 94 } 95 96 return [ 97 'id' => $this->id, 98 'title' => $this->title, 99 'source' => json_encode( 100 [ 101 'id' => $this->id, 102 'name' => $this->name, 103 'link' => $this->link, 104 'exportformat' => $this->exportformat, 105 'googledoctype' => $this->googledoctype, 106 ] 107 ), 108 'date' => $this->modified, 109 'size' => $this->size, 110 'thumbnail' => $this->thumbnail, 111 'thumbnail_height' => 64, 112 'thumbnail_width' => 64, 113 ]; 114 } 115 116 /** 117 * Generates and returns the title for the file node depending on the type of the Google drive file. 118 * 119 * @param \stdClass $gdfile The Google Drive file object 120 * @return string The file title 121 */ 122 private function generate_file_title(\stdClass $gdfile): ?string { 123 // Determine the file type through the file extension. 124 if (isset($gdfile->fileExtension)) { // The file is a regular file. 125 return $gdfile->name; 126 } else { // The file is probably a Google Doc file. 127 // We need to generate the name by appending the proper google doc extension. 128 $type = str_replace('application/vnd.google-apps.', '', $gdfile->mimeType); 129 130 if ($type === 'document') { 131 return "{$gdfile->name}.gdoc"; 132 } 133 if ($type === 'presentation') { 134 return "{$gdfile->name}.gslides"; 135 } 136 if ($type === 'spreadsheet') { 137 return "{$gdfile->name}.gsheet"; 138 } 139 if ($type === 'drawing') { 140 $config = get_config('googledocs'); 141 $ext = $config->drawingformat; 142 return "{$gdfile->name}.{$ext}"; 143 } 144 } 145 146 return null; 147 } 148 149 /** 150 * Generates and returns the file export format depending on the type of the Google drive file. 151 * 152 * @param \stdClass $gdfile The Google Drive file object 153 * @return string The file export format 154 */ 155 private function generate_file_export_format(\stdClass $gdfile): ?string { 156 // Determine the file type through the file extension. 157 if (isset($gdfile->fileExtension)) { // The file is a regular file. 158 // The file has an extension, therefore we can download it. 159 return 'download'; 160 } else { 161 // The file is probably a Google Doc file, we get the corresponding export link. 162 $type = str_replace('application/vnd.google-apps.', '', $gdfile->mimeType); 163 $types = get_mimetypes_array(); 164 $config = get_config('googledocs'); 165 166 if ($type === 'document' && !empty($config->documentformat)) { 167 $ext = $config->documentformat; 168 if ($ext === 'rtf') { 169 // Moodle user 'text/rtf' as the MIME type for RTF files. 170 // Google uses 'application/rtf' for the same type of file. 171 // See https://developers.google.com/drive/v3/web/manage-downloads. 172 return 'application/rtf'; 173 } else { 174 return $types[$ext]['type']; 175 } 176 } 177 if ($type === 'presentation' && !empty($config->presentationformat)) { 178 $ext = $config->presentationformat; 179 return $types[$ext]['type']; 180 } 181 if ($type === 'spreadsheet' && !empty($config->spreadsheetformat)) { 182 $ext = $config->spreadsheetformat; 183 return $types[$ext]['type']; 184 } 185 if ($type === 'drawing' && !empty($config->drawingformat)) { 186 $ext = $config->drawingformat; 187 return $types[$ext]['type']; 188 } 189 } 190 191 return null; 192 } 193 194 /** 195 * Generates and returns the external link to the file. 196 * 197 * @param \stdClass $gdfile The Google Drive file object 198 * @return string The link to the file 199 */ 200 private function generate_file_link(\stdClass $gdfile): string { 201 // If the google drive file has webViewLink set, use it as an external link. 202 $link = !empty($gdfile->webViewLink) ? $gdfile->webViewLink : ''; 203 // Otherwise, use webContentLink if set or leave the external link empty. 204 if (empty($link) && !empty($gdfile->webContentLink)) { 205 $link = $gdfile->webContentLink; 206 } 207 208 return $link; 209 } 210 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body