Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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;
  18  
  19  use repository_googledocs\local\browser\googledocs_root_content;
  20  use repository_googledocs\local\browser\googledocs_shared_drives_content;
  21  use repository_googledocs\local\browser\googledocs_drive_content;
  22  use repository_googledocs\local\node\node;
  23  use repository_googledocs\local\node\file_node;
  24  use repository_googledocs\local\node\folder_node;
  25  
  26  /**
  27   * Helper class for the googledocs repository.
  28   *
  29   * @package    repository_googledocs
  30   * @copyright  2021 Mihail Geshoski <mihail@moodle.com>
  31   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   */
  33  class helper {
  34  
  35      /**
  36       * Generates a safe path to a node.
  37       *
  38       * Typically, a node will be id|name of the node.
  39       *
  40       * @param string $id The ID of the node
  41       * @param string $name The name of the node, will be URL encoded
  42       * @param string $root The path to append the node on (must be a result of this function)
  43       * @return string The path to the node
  44       */
  45      public static function build_node_path(string $id, string $name = '', string $root = ''): string {
  46          $path = $id;
  47          if (!empty($name)) {
  48              $path .= '|' . urlencode($name);
  49          }
  50          if (!empty($root)) {
  51              $path = trim($root, '/') . '/' . $path;
  52          }
  53          return $path;
  54      }
  55  
  56      /**
  57       * Returns information about a node in a path.
  58       *
  59       * @param string $node The node string to extract information from
  60       * @return array The array containing the information about the node
  61       * @see self::build_node_path()
  62       */
  63      public static function explode_node_path(string $node): array {
  64          if (strpos($node, '|') !== false) {
  65              list($id, $name) = explode('|', $node, 2);
  66              $name = urldecode($name);
  67          } else {
  68              $id = $node;
  69              $name = '';
  70          }
  71          $id = urldecode($id);
  72  
  73          return [
  74              0 => $id,
  75              1 => $name,
  76              'id' => $id,
  77              'name' => $name,
  78          ];
  79      }
  80  
  81      /**
  82       * Returns the relevant googledocs content browser class based on the given path.
  83       *
  84       * @param rest $service The rest API object
  85       * @param string $path The current path
  86       * @return googledocs_content The googledocs repository content browser
  87       */
  88      public static function get_browser(rest $service, string $path): googledocs_content {
  89          $pathnodes = explode('/', $path);
  90          $currentnode = self::explode_node_path(array_pop($pathnodes));
  91  
  92          // Return the relevant content browser class based on the ID of the current path node.
  93          switch ($currentnode['id']) {
  94              case \repository_googledocs::REPOSITORY_ROOT_ID:
  95                  return new googledocs_root_content($service, $path, false);
  96              case \repository_googledocs::SHARED_DRIVES_ROOT_ID:
  97                  return new googledocs_shared_drives_content($service, $path);
  98              default:
  99                  return new googledocs_drive_content($service, $path);
 100          }
 101      }
 102  
 103      /**
 104       * Returns the relevant repository content node class based on the Google Drive file's mimetype.
 105       *
 106       * @param \stdClass $gdcontent The Google Drive content (file/folder) object
 107       * @param string $path The current path
 108       * @return node The content node object
 109       */
 110      public static function get_node(\stdClass $gdcontent, string $path): node {
 111          // Return the relevant content browser class based on the ID of the current path node.
 112          switch ($gdcontent->mimeType) {
 113              case 'application/vnd.google-apps.folder':
 114                  return new folder_node($gdcontent, $path);
 115              default:
 116                  return new file_node($gdcontent);
 117          }
 118      }
 119  
 120      /**
 121       * Wrapper function to perform an API call and also catch and handle potential exceptions.
 122       *
 123       * @param rest $service The rest API object
 124       * @param string $api The name of the API call
 125       * @param array $params The parameters required by the API call
 126       * @return \stdClass The response object
 127       * @throws \repository_exception
 128       */
 129      public static function request(rest $service, string $api, array $params): ?\stdClass {
 130          try {
 131              // Retrieving files and folders.
 132              $response = $service->call($api, $params);
 133          } catch (\Exception $e) {
 134              if ($e->getCode() == 403 && strpos($e->getMessage(), 'Access Not Configured') !== false) {
 135                  // This is raised when the service Drive API has not been enabled on Google APIs control panel.
 136                  throw new \repository_exception('servicenotenabled', 'repository_googledocs');
 137              }
 138              throw $e;
 139          }
 140  
 141          return $response;
 142      }
 143  }