Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.11.x will end 9 May 2022 (12 months).
  • Bug fixes for security issues in 3.11.x will end 14 November 2022 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
  • Differences Between: [Versions 36 and 311] [Versions 37 and 311]

       1  <?php
       2  
       3  // This file is part of Moodle - http://moodle.org/
       4  //
       5  // Moodle is free software: you can redistribute it and/or modify
       6  // it under the terms of the GNU General Public License as published by
       7  // the Free Software Foundation, either version 3 of the License, or
       8  // (at your option) any later version.
       9  //
      10  // Moodle is distributed in the hope that it will be useful,
      11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13  // GNU General Public License for more details.
      14  //
      15  // You should have received a copy of the GNU General Public License
      16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
      17  //
      18  
      19  /**
      20   * This file is used to browse repositories in non-javascript mode
      21   *
      22   * @since Moodle 2.0
      23   * @package    core
      24   * @subpackage repository
      25   * @copyright  2009 Dongsheng Cai <dongsheng@moodle.com>
      26   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      27   */
      28  
      29  require_once('../config.php');
      30  require_once($CFG->libdir.'/filelib.php');
      31  require_once ('lib.php');
      32  /// Wait as long as it takes for this script to finish
      33  core_php_time_limit::raise();
      34  
      35  require_sesskey();
      36  require_login();
      37  
      38  // disable blocks in this page
      39  $PAGE->set_pagelayout('embedded');
      40  
      41  // general parameters
      42  $action      = optional_param('action', '',        PARAM_ALPHA);
      43  $client_id   = optional_param('client_id', '', PARAM_RAW);    // client ID
      44  $itemid      = optional_param('itemid', '',        PARAM_INT);
      45  
      46  // parameters for repository
      47  $callback    = optional_param('callback', '',      PARAM_CLEANHTML);
      48  $contextid   = optional_param('ctx_id',    SYSCONTEXTID, PARAM_INT);    // context ID
      49  $courseid    = optional_param('course',    SITEID, PARAM_INT);    // course ID
      50  $env         = optional_param('env', 'filepicker', PARAM_ALPHA);  // opened in file picker, file manager or html editor
      51  $filename    = optional_param('filename', '',      PARAM_FILE);
      52  $fileurl     = optional_param('fileurl', '',       PARAM_RAW);
      53  $thumbnail   = optional_param('thumbnail', '',     PARAM_RAW);
      54  $targetpath  = optional_param('targetpath', '',    PARAM_PATH);
      55  $repo_id     = optional_param('repo_id', 0,        PARAM_INT);    // repository ID
      56  $req_path    = optional_param('p', '',             PARAM_RAW);    // the path in repository
      57  $curr_page   = optional_param('page', '',          PARAM_RAW);    // What page in repository?
      58  $search_text = optional_param('s', '',             PARAM_CLEANHTML);
      59  $maxfiles    = optional_param('maxfiles', -1,      PARAM_INT);    // maxfiles
      60  $maxbytes    = optional_param('maxbytes',  0,      PARAM_INT);    // maxbytes
      61  $subdirs     = optional_param('subdirs',  0,       PARAM_INT);    // maxbytes
      62  $areamaxbytes   = optional_param('areamaxbytes', FILE_AREA_MAX_BYTES_UNLIMITED, PARAM_INT);    // Area maxbytes.
      63  $accepted_types = optional_param_array('accepted_types', '*', PARAM_RAW);
      64  
      65  // the path to save files
      66  $savepath = optional_param('savepath', '/',    PARAM_PATH);
      67  // path in draft area
      68  $draftpath = optional_param('draftpath', '/',    PARAM_PATH);
      69  
      70  
      71  // user context
      72  $user_context = context_user::instance($USER->id);
      73  
      74  $PAGE->set_context($user_context);
      75  if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
      76      print_error('invalidcourseid');
      77  }
      78  $PAGE->set_course($course);
      79  
      80  if ($repo_id) {
      81      // Get repository instance information
      82      $repooptions = array(
      83          'ajax' => false,
      84          'mimetypes' => $accepted_types
      85      );
      86      $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions);
      87  
      88      // Check permissions
      89      $repo->check_capability();
      90  }
      91  
      92  $context = context::instance_by_id($contextid);
      93  
      94  // Make sure maxbytes passed is within site filesize limits.
      95  $maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $course->maxbytes, $maxbytes);
      96  
      97  $params = array('ctx_id' => $contextid, 'itemid' => $itemid, 'env' => $env, 'course'=>$courseid, 'maxbytes'=>$maxbytes, 'areamaxbytes'=>$areamaxbytes, 'maxfiles'=>$maxfiles, 'subdirs'=>$subdirs, 'sesskey'=>sesskey());
      98  $params['action'] = 'browse';
      99  $params['draftpath'] = $draftpath;
     100  $home_url = new moodle_url('/repository/draftfiles_manager.php', $params);
     101  
     102  $params['savepath'] = $savepath;
     103  $params['repo_id'] = $repo_id;
     104  $url = new moodle_url("/repository/filepicker.php", $params);
     105  $PAGE->set_url('/repository/filepicker.php', $params);
     106  
     107  switch ($action) {
     108  case 'upload':
     109      // The uploaded file has been processed in plugin construct function
     110      // redirect to default page
     111      try {
     112          $repo->upload('', $maxbytes);
     113          redirect($home_url, get_string('uploadsucc','repository'));
     114      } catch (moodle_exception $e) {
     115          // inject target URL
     116          $e->link = $PAGE->url->out();
     117          echo $OUTPUT->header(); // hack: we need the embedded header here, standard error printing would not use it
     118          throw $e;
     119      }
     120      break;
     121  
     122  case 'search':
     123      echo '<div><a href="' . $home_url->out() . '">'.get_string('back', 'repository')."</a></div>";
     124      try {
     125          $search_result = $repo->search($search_text);
     126          $search_result['issearchresult'] = true;
     127          $search_result['repo_id'] = $repo_id;
     128  
     129          // TODO: need a better solution
     130          $purl = new moodle_url($url, array('search_paging' => 1, 'action' => 'search', 'repo_id' => $repo_id));
     131          $pagingbar = new paging_bar($search_result['total'], $search_result['page'] - 1, $search_result['perpage'], $purl, 'p');
     132          echo $OUTPUT->render($pagingbar);
     133  
     134          echo '<table>';
     135          foreach ($search_result['list'] as $item) {
     136              echo '<tr>';
     137              echo '<td>';
     138              $style = '';
     139              if (isset($item['thumbnail_height'])) {
     140                  $style .= 'max-height:'.$item['thumbnail_height'].'px;';
     141              }
     142              if (isset($item['thumbnail_width'])) {
     143                  $style .= 'max-width:'.$item['thumbnail_width'].'px;';
     144              }
     145              echo html_writer::empty_tag('img', array('src' => $item['thumbnail'], 'alt' => '', 'style' => $style));
     146              echo '</td><td>';
     147              if (!empty($item['url'])) {
     148                  echo html_writer::link($item['url'], s($item['title']), array('target'=>'_blank'));
     149              } else {
     150                  echo s($item['title']);
     151              }
     152              echo '</td>';
     153              echo '<td>';
     154              echo '<form method="post">';
     155              echo '<input type="hidden" name="fileurl" value="'.s($item['source']).'"/>';
     156              echo '<input type="hidden" name="action" value="confirm"/>';
     157              echo '<input type="hidden" name="filename" value="'.s($item['title']).'"/>';
     158              echo '<input type="hidden" name="thumbnail" value="'.s($item['thumbnail']).'"/>';
     159              echo '<input type="submit" value="'.s(get_string('select','repository')).'" />';
     160              echo '</form>';
     161              echo '</td>';
     162              echo '</tr>';
     163          }
     164          echo '</table>';
     165      } catch (repository_exception $e) {
     166      }
     167      break;
     168  
     169  case 'list':
     170  case 'sign':
     171      echo $OUTPUT->header();
     172  
     173      echo $OUTPUT->container_start();
     174      echo html_writer::link($url, get_string('back', 'repository'));
     175      echo $OUTPUT->container_end();
     176  
     177      if ($repo->check_login()) {
     178          $list = $repo->get_listing($req_path, $curr_page);
     179          $dynload = !empty($list['dynload'])?true:false;
     180          if (!empty($list['upload'])) {
     181              echo '<form action="'.$url->out().'" method="post" enctype="multipart/form-data" style="display:inline">';
     182              echo '<label>'.$list['upload']['label'].': </label>';
     183              echo '<input type="file" name="repo_upload_file" /><br />';
     184              echo '<input type="hidden" name="action" value="upload" /><br />';
     185              echo '<input type="hidden" name="draftpath" value="'.s($draftpath).'" /><br />';
     186              echo '<input type="hidden" name="savepath" value="'.s($savepath).'" /><br />';
     187              echo '<input type="hidden" name="repo_id" value="'.s($repo_id).'" /><br />';
     188              echo '<input type="submit" value="'.s(get_string('upload', 'repository')).'" />';
     189              echo '</form>';
     190          } else {
     191              if (!empty($list['path'])) {
     192                  foreach ($list['path'] as $p) {
     193                      //echo '<form method="post" style="display:inline">';
     194                      //echo '<input type="hidden" name="p" value="'.s($p['path']).'"';
     195                      //echo '<input type="hidden" name="action" value="list"';
     196                      //echo '<input type="hidden" name="draftpath" value="'.s($draftpath).'" /><br />';
     197                      //echo '<input type="hidden" name="savepath" value="'.s($savepath).'" /><br />';
     198                      //echo '<input style="display:inline" type="submit" value="'.s($p['name']).'" />';
     199                      //echo '</form>';
     200  
     201                      $pathurl = new moodle_url($url, array(
     202                          'p'=>$p['path'],
     203                          'action'=>'list',
     204                          'draftpath'=>$draftpath,
     205                          'savepath'=>$savepath
     206                          ));
     207                      echo '<strong>' . html_writer::link($pathurl, s($p['name'])) . '</strong>';
     208                      echo '<span> / </span>';
     209                  }
     210              }
     211              if (!empty($list['page'])) {
     212                  // TODO MDL-28482: need a better solution
     213                  // paging_bar is not a good option because it starts page numbering from 0 and
     214                  // repositories number pages starting from 1.
     215                  $pagingurl = new moodle_url("/repository/filepicker.php?action=list&itemid=$itemid&ctx_id=$contextid&repo_id=$repo_id&course=$courseid&sesskey=".  sesskey());
     216                  if (!isset($list['perpage']) && !isset($list['total'])) {
     217                      $list['perpage'] = 10; // instead of setting perpage&total we use number of pages, the result is the same
     218                  }
     219                  if (empty($list['total'])) {
     220                      if ($list['pages'] == -1) {
     221                          $total = ($list['page'] + 2) * $list['perpage'];
     222                      } else {
     223                          $total = $list['pages'] * $list['perpage'];
     224                      }
     225                  } else {
     226                      $total = $list['total'];
     227                  }
     228                  echo $OUTPUT->paging_bar($total, $list['page'], $list['perpage'], $pagingurl);
     229              }
     230              echo '<table>';
     231              foreach ($list['list'] as $item) {
     232                  echo '<tr>';
     233                  echo '<td>';
     234                  $style = '';
     235                  if (isset($item['thumbnail_height'])) {
     236                      $style .= 'max-height:'.$item['thumbnail_height'].'px;';
     237                  }
     238                  if (isset($item['thumbnail_width'])) {
     239                      $style .= 'max-width:'.$item['thumbnail_width'].'px;';
     240                  }
     241                  echo html_writer::empty_tag('img', array('src' => $item['thumbnail'], 'style' => $style));
     242                  echo '</td><td>';
     243                  if (!empty($item['url'])) {
     244                      echo html_writer::link($item['url'], s($item['title']), array('target'=>'_blank'));
     245                  } else {
     246                      echo s($item['title']);
     247                  }
     248                  echo '</td>';
     249                  echo '<td>';
     250                  if (!isset($item['children'])) {
     251                      echo '<form method="post">';
     252                      echo '<input type="hidden" name="fileurl" value="'.s($item['source']).'"/>';
     253                      echo '<input type="hidden" name="action" value="confirm"/>';
     254                      echo '<input type="hidden" name="draftpath" value="'.s($draftpath).'" /><br />';
     255                      echo '<input type="hidden" name="savepath" value="'.s($savepath).'" /><br />';
     256                      echo '<input type="hidden" name="filename" value="'.s($item['title']).'"/>';
     257                      echo '<input type="hidden" name="thumbnail" value="'.s($item['thumbnail']).'"/>';
     258                      echo '<input type="submit" value="'.s(get_string('select','repository')).'" />';
     259                      echo '</form>';
     260                  } else {
     261                      echo '<form method="post">';
     262                      echo '<input type="hidden" name="p" value="'.s($item['path']).'"/>';
     263                      echo '<input type="submit" value="'.s(get_string('enter', 'repository')).'" />';
     264                      echo '</form>';
     265                  }
     266                  echo '</td>';
     267                  echo '</tr>';
     268              }
     269              echo '</table>';
     270          }
     271      } else {
     272          echo '<form method="post">';
     273          echo '<input type="hidden" name="action" value="sign" />';
     274          echo '<input type="hidden" name="repo_id" value="'.s($repo_id).'" />';
     275          $repo->print_login();
     276          echo '</form>';
     277      }
     278      echo $OUTPUT->footer();
     279      break;
     280  
     281  case 'download':
     282      // Check that user has permission to access this file
     283      if (!$repo->file_is_accessible($fileurl)) {
     284          print_error('storedfilecannotread');
     285      }
     286      $record = new stdClass();
     287      $reference = $repo->get_file_reference($fileurl);
     288  
     289      $sourcefield = $repo->get_file_source_info($fileurl);
     290      $record->source = repository::build_source_field($sourcefield);
     291  
     292      // If file is already a reference, set $fileurl = file source, $repo = file repository
     293      // note that in this case user may not have permission to access the source file directly
     294      // so no file_browser/file_info can be used below
     295      if ($repo->has_moodle_files()) {
     296          $file = repository::get_moodle_file($reference);
     297          if ($file && $file->is_external_file()) {
     298              $sourcefield = $file->get_source(); // remember the original source
     299              $record->source = $repo::build_source_field($sourcefield);
     300              $reference = $file->get_reference();
     301              $repo_id = $file->get_repository_id();
     302              $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions);
     303          }
     304      }
     305  
     306      $record->filepath = $savepath;
     307      $record->filename = $filename;
     308      $record->component = 'user';
     309      $record->filearea = 'draft';
     310      $record->itemid   = $itemid;
     311      $record->license  = '';
     312      $record->author   = '';
     313  
     314      $now = time();
     315      $record->timecreated  = $now;
     316      $record->timemodified = $now;
     317      $record->userid       = $USER->id;
     318      $record->contextid = $user_context->id;
     319      $record->sortorder = 0;
     320  
     321      if ($repo->has_moodle_files()) {
     322          $fileinfo = $repo->copy_to_area($reference, $record, $maxbytes, $areamaxbytes);
     323          redirect($home_url, get_string('downloadsucc', 'repository'));
     324      } else {
     325          $thefile = $repo->get_file($reference, $filename);
     326          if (!empty($thefile['path'])) {
     327              $filesize = filesize($thefile['path']);
     328              if ($maxbytes != -1 && $filesize>$maxbytes) {
     329                  unlink($thefile['path']);
     330                  print_error('maxbytes');
     331              }
     332              // Ensure the file will not make the area exceed its size limit.
     333              if (file_is_draft_area_limit_reached($record->itemid, $areamaxbytes, $filesize)) {
     334                  unlink($thefile['path']);
     335                  print_error('maxareabytes');
     336              }
     337              // Ensure the user does not upload too many draft files in a short period.
     338              if (file_is_draft_areas_limit_reached($USER->id)) {
     339                  unlink($thefile['path']);
     340                  print_error('maxdraftitemids');
     341              }
     342              try {
     343                  $info = repository::move_to_filepool($thefile['path'], $record);
     344                  redirect($home_url, get_string('downloadsucc', 'repository'));
     345              } catch (moodle_exception $e) {
     346                  // inject target URL
     347                  $e->link = $PAGE->url->out();
     348                  echo $OUTPUT->header(); // hack: we need the embedded header here, standard error printing would not use it
     349                  throw $e;
     350              }
     351          } else {
     352              print_error('cannotdownload', 'repository');
     353          }
     354      }
     355  
     356      break;
     357  
     358  case 'confirm':
     359      echo $OUTPUT->header();
     360      echo '<div><a href="'.s($PAGE->url->out(false)).'">'.get_string('back', 'repository').'</a></div>';
     361      echo '<img src="'.$thumbnail.'" />';
     362      echo '<form method="post">';
     363      echo '<table>';
     364      echo '  <tr>';
     365      echo '    <td>'. html_writer::label(get_string('filename', 'repository'), 'filename'). '</td>';
     366      echo '    <td><input type="text" id="filename" name="filename" value="'.s($filename).'" /></td>';
     367      echo '    <td><input type="hidden" name="fileurl" value="'.s($fileurl).'" /></td>';
     368      echo '    <td><input type="hidden" name="action" value="download" /></td>';
     369      echo '    <td><input type="hidden" name="itemid" value="'.s($itemid).'" /></td>';
     370      echo '  </tr>';
     371      echo '</table>';
     372      echo '<div>';
     373      // the save path
     374      echo ' <input name="draftpath" type="hidden" value="'.s($draftpath).'" />';
     375      echo ' <input name="savepath" type="hidden" value="'.s($savepath).'" />';
     376      echo ' <input type="submit" value="'.s(get_string('download', 'repository')).'" />';
     377      echo '</div>';
     378      echo '</form>';
     379      echo $OUTPUT->footer();
     380      break;
     381  
     382  default:
     383  case 'plugins':
     384      $params = array();
     385      $params['context'] = array($user_context, context_system::instance());
     386      $params['currentcontext'] = $PAGE->context;
     387      $params['return_types'] = FILE_INTERNAL;
     388  
     389      $repos = repository::get_instances($params);
     390      echo $OUTPUT->header();
     391      echo html_writer::link($home_url->out(false), get_string('backtodraftfiles', 'repository'));
     392      echo '<div>';
     393      echo '<ul>';
     394      foreach($repos as $repo) {
     395          $info = $repo->get_meta();
     396  
     397          $aurl = clone($url);
     398          $aurl->params(array('savepath'=>$savepath, 'action' => 'list', 'repo_id' => $info->id, 'draftpath'=>$draftpath));
     399  
     400          echo '<li>';
     401          echo html_writer::empty_tag('img', array('src'=>$info->icon, 'alt'=>$info->name, 'class'=>'icon icon-pre'));
     402          echo html_writer::link($aurl, s($info->name));
     403          echo '</li>';
     404      }
     405      echo '</ul>';
     406      echo '</div>';
     407      echo $OUTPUT->footer();
     408      break;
     409  }