PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/filebrowser/file_info_context_course.php

https://bitbucket.org/synergylearning/campusconnect
PHP | 875 lines | 446 code | 105 blank | 324 comment | 75 complexity | cb2d86cc98cb5423d5d46625cd6a05d3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
  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. * Utility class for browsing of course files.
  18. *
  19. * @package core_files
  20. * @copyright 2008 Petr Skoda (http://skodak.org)
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. defined('MOODLE_INTERNAL') || die();
  24. /**
  25. * Represents a course context in the tree navigated by {@link file_browser}.
  26. *
  27. * @package core_files
  28. * @copyright 2008 Petr Skoda (http://skodak.org)
  29. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30. */
  31. class file_info_context_course extends file_info {
  32. /** @var stdClass course object */
  33. protected $course;
  34. /**
  35. * Constructor
  36. *
  37. * @param file_browser $browser file browser instance
  38. * @param stdClass $context context object
  39. * @param stdClass $course course object
  40. */
  41. public function __construct($browser, $context, $course) {
  42. parent::__construct($browser, $context);
  43. $this->course = $course;
  44. }
  45. /**
  46. * Return information about this specific context level
  47. *
  48. * @param string $component component
  49. * @param string $filearea file area
  50. * @param int $itemid item ID
  51. * @param string $filepath file path
  52. * @param string $filename file name
  53. * @return file_info|null file_info instance or null if not found or access not allowed
  54. */
  55. public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
  56. // try to emulate require_login() tests here
  57. if (!isloggedin()) {
  58. return null;
  59. }
  60. if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $this->context)) {
  61. return null;
  62. }
  63. if (!is_viewing($this->context) and !is_enrolled($this->context)) {
  64. // no peaking here if not enrolled or inspector
  65. return null;
  66. }
  67. if (empty($component)) {
  68. return $this;
  69. }
  70. $methodname = "get_area_{$component}_{$filearea}";
  71. if (method_exists($this, $methodname)) {
  72. return $this->$methodname($itemid, $filepath, $filename);
  73. }
  74. return null;
  75. }
  76. /**
  77. * Gets a stored file for the course summary filearea directory
  78. *
  79. * @param int $itemid item ID
  80. * @param string $filepath file path
  81. * @param string $filename file name
  82. * @return file_info|null file_info instance or null if not found or access not allowed
  83. */
  84. protected function get_area_course_summary($itemid, $filepath, $filename) {
  85. global $CFG;
  86. if (!has_capability('moodle/course:update', $this->context)) {
  87. return null;
  88. }
  89. if (is_null($itemid)) {
  90. return $this;
  91. }
  92. $fs = get_file_storage();
  93. $filepath = is_null($filepath) ? '/' : $filepath;
  94. $filename = is_null($filename) ? '.' : $filename;
  95. if (!$storedfile = $fs->get_file($this->context->id, 'course', 'summary', 0, $filepath, $filename)) {
  96. if ($filepath === '/' and $filename === '.') {
  97. $storedfile = new virtual_root_file($this->context->id, 'course', 'summary', 0);
  98. } else {
  99. // not found
  100. return null;
  101. }
  102. }
  103. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  104. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacourseintro', 'repository'), false, true, true, false);
  105. }
  106. /**
  107. * Gets a stored file for the course images filearea directory
  108. *
  109. * @param int $itemid item ID
  110. * @param string $filepath file path
  111. * @param string $filename file name
  112. * @return file_info|null file_info instance or null if not found or access not allowed
  113. */
  114. protected function get_area_course_overviewfiles($itemid, $filepath, $filename) {
  115. global $CFG;
  116. if (!has_capability('moodle/course:update', $this->context)) {
  117. return null;
  118. }
  119. if (is_null($itemid)) {
  120. return $this;
  121. }
  122. $fs = get_file_storage();
  123. $filepath = is_null($filepath) ? '/' : $filepath;
  124. $filename = is_null($filename) ? '.' : $filename;
  125. if (!$storedfile = $fs->get_file($this->context->id, 'course', 'overviewfiles', 0, $filepath, $filename)) {
  126. if ($filepath === '/' and $filename === '.') {
  127. $storedfile = new virtual_root_file($this->context->id, 'course', 'overviewfiles', 0);
  128. } else {
  129. // not found
  130. return null;
  131. }
  132. }
  133. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  134. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacourseoverviewfiles', 'repository'), false, true, true, false);
  135. }
  136. /**
  137. * Gets a stored file for the course section filearea directory
  138. *
  139. * @param int $itemid item ID
  140. * @param string $filepath file path
  141. * @param string $filename file name
  142. * @return file_info|null file_info instance or null if not found or access not allowed
  143. */
  144. protected function get_area_course_section($itemid, $filepath, $filename) {
  145. global $CFG, $DB;
  146. if (!has_capability('moodle/course:update', $this->context)) {
  147. return null;
  148. }
  149. if (empty($itemid)) {
  150. // list all sections
  151. return new file_info_area_course_section($this->browser, $this->context, $this->course, $this);
  152. }
  153. if (!$section = $DB->get_record('course_sections', array('course'=>$this->course->id, 'id'=>$itemid))) {
  154. return null; // does not exist
  155. }
  156. $fs = get_file_storage();
  157. $filepath = is_null($filepath) ? '/' : $filepath;
  158. $filename = is_null($filename) ? '.' : $filename;
  159. if (!$storedfile = $fs->get_file($this->context->id, 'course', 'section', $itemid, $filepath, $filename)) {
  160. if ($filepath === '/' and $filename === '.') {
  161. $storedfile = new virtual_root_file($this->context->id, 'course', 'section', $itemid);
  162. } else {
  163. // not found
  164. return null;
  165. }
  166. }
  167. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  168. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, $section->section, true, true, true, false);
  169. }
  170. /**
  171. * Gets a stored file for the course legacy filearea directory
  172. *
  173. * @param int $itemid item ID
  174. * @param string $filepath file path
  175. * @param string $filename file name
  176. * @return file_info|null file_info instance or null if not found or access not allowed
  177. */
  178. protected function get_area_course_legacy($itemid, $filepath, $filename) {
  179. if (!has_capability('moodle/course:managefiles', $this->context)) {
  180. return null;
  181. }
  182. if ($this->course->id != SITEID and $this->course->legacyfiles != 2) {
  183. // bad luck, legacy course files not used any more
  184. }
  185. if (is_null($itemid)) {
  186. return $this;
  187. }
  188. $fs = get_file_storage();
  189. $filepath = is_null($filepath) ? '/' : $filepath;
  190. $filename = is_null($filename) ? '.' : $filename;
  191. if (!$storedfile = $fs->get_file($this->context->id, 'course', 'legacy', 0, $filepath, $filename)) {
  192. if ($filepath === '/' and $filename === '.') {
  193. $storedfile = new virtual_root_file($this->context->id, 'course', 'legacy', 0);
  194. } else {
  195. // not found
  196. return null;
  197. }
  198. }
  199. return new file_info_area_course_legacy($this->browser, $this->context, $storedfile);
  200. }
  201. /**
  202. * Gets a stored file for the backup course filearea directory
  203. *
  204. * @param int $itemid item ID
  205. * @param string $filepath file path
  206. * @param string $filename file name
  207. * @return file_info|null file_info instance or null if not found or access not allowed
  208. */
  209. protected function get_area_backup_course($itemid, $filepath, $filename) {
  210. global $CFG;
  211. if (!has_capability('moodle/backup:backupcourse', $this->context) and !has_capability('moodle/restore:restorecourse', $this->context)) {
  212. return null;
  213. }
  214. if (is_null($itemid)) {
  215. return $this;
  216. }
  217. $fs = get_file_storage();
  218. $filepath = is_null($filepath) ? '/' : $filepath;
  219. $filename = is_null($filename) ? '.' : $filename;
  220. if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'course', 0, $filepath, $filename)) {
  221. if ($filepath === '/' and $filename === '.') {
  222. $storedfile = new virtual_root_file($this->context->id, 'backup', 'course', 0);
  223. } else {
  224. // not found
  225. return null;
  226. }
  227. }
  228. $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
  229. $uploadable = has_capability('moodle/restore:uploadfile', $this->context);
  230. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  231. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('coursebackup', 'repository'), false, $downloadable, $uploadable, false);
  232. }
  233. /**
  234. * Gets a stored file for the automated backup filearea directory
  235. *
  236. * @param int $itemid item ID
  237. * @param string $filepath file path
  238. * @param string $filename file name
  239. * @return file_info|null
  240. */
  241. protected function get_area_backup_automated($itemid, $filepath, $filename) {
  242. global $CFG;
  243. if (!has_capability('moodle/restore:viewautomatedfilearea', $this->context)) {
  244. return null;
  245. }
  246. if (is_null($itemid)) {
  247. return $this;
  248. }
  249. $fs = get_file_storage();
  250. $filepath = is_null($filepath) ? '/' : $filepath;
  251. $filename = is_null($filename) ? '.' : $filename;
  252. if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'automated', 0, $filepath, $filename)) {
  253. if ($filepath === '/' and $filename === '.') {
  254. $storedfile = new virtual_root_file($this->context->id, 'backup', 'automated', 0);
  255. } else {
  256. // not found
  257. return null;
  258. }
  259. }
  260. $downloadable = has_capability('moodle/site:config', $this->context);
  261. $uploadable = false;
  262. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  263. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('automatedbackup', 'repository'), true, $downloadable, $uploadable, false);
  264. }
  265. /**
  266. * Gets a stored file for the backup section filearea directory
  267. *
  268. * @param int $itemid item ID
  269. * @param string $filepath file path
  270. * @param string $filename file name
  271. * @return file_info|null file_info instance or null if not found or access not allowed
  272. */
  273. protected function get_area_backup_section($itemid, $filepath, $filename) {
  274. global $CFG, $DB;
  275. if (!has_capability('moodle/backup:backupcourse', $this->context) and !has_capability('moodle/restore:restorecourse', $this->context)) {
  276. return null;
  277. }
  278. if (empty($itemid)) {
  279. // list all sections
  280. return new file_info_area_backup_section($this->browser, $this->context, $this->course, $this);
  281. }
  282. if (!$section = $DB->get_record('course_sections', array('course'=>$this->course->id, 'id'=>$itemid))) {
  283. return null; // does not exist
  284. }
  285. $fs = get_file_storage();
  286. $filepath = is_null($filepath) ? '/' : $filepath;
  287. $filename = is_null($filename) ? '.' : $filename;
  288. if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'section', $itemid, $filepath, $filename)) {
  289. if ($filepath === '/' and $filename === '.') {
  290. $storedfile = new virtual_root_file($this->context->id, 'backup', 'section', $itemid);
  291. } else {
  292. // not found
  293. return null;
  294. }
  295. }
  296. $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
  297. $uploadable = has_capability('moodle/restore:uploadfile', $this->context);
  298. $urlbase = $CFG->wwwroot.'/pluginfile.php';
  299. return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, $section->id, true, $downloadable, $uploadable, false);
  300. }
  301. /**
  302. * Returns localised visible name.
  303. *
  304. * @return string
  305. */
  306. public function get_visible_name() {
  307. return ($this->course->id == SITEID) ? get_string('frontpage', 'admin') : format_string(get_course_display_name_for_list($this->course), true, array('context'=>$this->context));
  308. }
  309. /**
  310. * Whether or not new files or directories can be added
  311. *
  312. * @return bool
  313. */
  314. public function is_writable() {
  315. return false;
  316. }
  317. /**
  318. * Whether or not this is a directory
  319. *
  320. * @return bool
  321. */
  322. public function is_directory() {
  323. return true;
  324. }
  325. /**
  326. * Returns list of children.
  327. *
  328. * @return array of file_info instances
  329. */
  330. public function get_children() {
  331. return $this->get_filtered_children('*', false, true);
  332. }
  333. /**
  334. * Help function to return files matching extensions or their count
  335. *
  336. * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
  337. * @param bool|int $countonly if false returns the children, if an int returns just the
  338. * count of children but stops counting when $countonly number of children is reached
  339. * @param bool $returnemptyfolders if true returns items that don't have matching files inside
  340. * @return array|int array of file_info instances or the count
  341. */
  342. private function get_filtered_children($extensions = '*', $countonly = false, $returnemptyfolders = false) {
  343. $areas = array(
  344. array('course', 'summary'),
  345. array('course', 'overviewfiles'),
  346. array('course', 'section'),
  347. array('backup', 'section'),
  348. array('backup', 'course'),
  349. array('backup', 'automated'),
  350. array('course', 'legacy')
  351. );
  352. $children = array();
  353. foreach ($areas as $area) {
  354. if ($child = $this->get_file_info($area[0], $area[1], 0, '/', '.')) {
  355. if ($returnemptyfolders || $child->count_non_empty_children($extensions)) {
  356. $children[] = $child;
  357. if (($countonly !== false) && count($children) >= $countonly) {
  358. return $countonly;
  359. }
  360. }
  361. }
  362. }
  363. if (!has_capability('moodle/course:managefiles', $this->context)) {
  364. // 'managefiles' capability is checked in every activity module callback.
  365. // Don't even waste time on retrieving the modules if we can't browse the files anyway
  366. } else {
  367. // now list all modules
  368. $modinfo = get_fast_modinfo($this->course);
  369. foreach ($modinfo->cms as $cminfo) {
  370. if (empty($cminfo->uservisible)) {
  371. continue;
  372. }
  373. $modcontext = context_module::instance($cminfo->id, IGNORE_MISSING);
  374. if ($child = $this->browser->get_file_info($modcontext)) {
  375. if ($returnemptyfolders || $child->count_non_empty_children($extensions)) {
  376. $children[] = $child;
  377. if (($countonly !== false) && count($children) >= $countonly) {
  378. return $countonly;
  379. }
  380. }
  381. }
  382. }
  383. }
  384. if ($countonly !== false) {
  385. return count($children);
  386. }
  387. return $children;
  388. }
  389. /**
  390. * Returns list of children which are either files matching the specified extensions
  391. * or folders that contain at least one such file.
  392. *
  393. * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
  394. * @return array of file_info instances
  395. */
  396. public function get_non_empty_children($extensions = '*') {
  397. return $this->get_filtered_children($extensions, false);
  398. }
  399. /**
  400. * Returns the number of children which are either files matching the specified extensions
  401. * or folders containing at least one such file.
  402. *
  403. * @param string|array $extensions, for example '*' or array('.gif','.jpg')
  404. * @param int $limit stop counting after at least $limit non-empty children are found
  405. * @return int
  406. */
  407. public function count_non_empty_children($extensions = '*', $limit = 1) {
  408. return $this->get_filtered_children($extensions, $limit);
  409. }
  410. /**
  411. * Returns parent file_info instance
  412. *
  413. * @return file_info or null for root
  414. */
  415. public function get_parent() {
  416. $parent = $this->context->get_parent_context();
  417. return $this->browser->get_file_info($parent);
  418. }
  419. }
  420. /**
  421. * Subclass of file_info_stored for files in the course files area.
  422. *
  423. * @package core_files
  424. * @copyright 2008 Petr Skoda (http://skodak.org)
  425. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  426. */
  427. class file_info_area_course_legacy extends file_info_stored {
  428. /**
  429. * Constructor
  430. *
  431. * @param file_browser $browser file browser instance
  432. * @param stdClass $context context object
  433. * @param stored_file $storedfile stored_file instance
  434. */
  435. public function __construct($browser, $context, $storedfile) {
  436. global $CFG;
  437. $urlbase = $CFG->wwwroot.'/file.php';
  438. parent::__construct($browser, $context, $storedfile, $urlbase, get_string('coursefiles'), false, true, true, false);
  439. }
  440. /**
  441. * Returns file download url
  442. *
  443. * @param bool $forcedownload whether or not force download
  444. * @param bool $https whether or not force https
  445. * @return string url
  446. */
  447. public function get_url($forcedownload=false, $https=false) {
  448. if (!$this->is_readable()) {
  449. return null;
  450. }
  451. if ($this->lf->is_directory()) {
  452. return null;
  453. }
  454. $filepath = $this->lf->get_filepath();
  455. $filename = $this->lf->get_filename();
  456. $courseid = $this->context->instanceid;
  457. $path = '/'.$courseid.$filepath.$filename;
  458. return file_encode_url($this->urlbase, $path, $forcedownload, $https);
  459. }
  460. /**
  461. * Returns list of children.
  462. *
  463. * @return array of file_info instances
  464. */
  465. public function get_children() {
  466. if (!$this->lf->is_directory()) {
  467. return array();
  468. }
  469. $result = array();
  470. $fs = get_file_storage();
  471. $storedfiles = $fs->get_directory_files($this->context->id, 'course', 'legacy', 0, $this->lf->get_filepath(), false, true, "filepath ASC, filename ASC");
  472. foreach ($storedfiles as $file) {
  473. $result[] = new file_info_area_course_legacy($this->browser, $this->context, $file);
  474. }
  475. return $result;
  476. }
  477. /**
  478. * Returns list of children which are either files matching the specified extensions
  479. * or folders that contain at least one such file.
  480. *
  481. * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
  482. * @return array of file_info instances
  483. */
  484. public function get_non_empty_children($extensions = '*') {
  485. if (!$this->lf->is_directory()) {
  486. return array();
  487. }
  488. $result = array();
  489. $fs = get_file_storage();
  490. $storedfiles = $fs->get_directory_files($this->context->id, 'course', 'legacy', 0,
  491. $this->lf->get_filepath(), false, true, "filepath, filename");
  492. foreach ($storedfiles as $file) {
  493. $extension = core_text::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION));
  494. if ($file->is_directory() || $extensions === '*' || (!empty($extension) && in_array('.'.$extension, $extensions))) {
  495. $fileinfo = new file_info_area_course_legacy($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename,
  496. $this->itemidused, $this->readaccess, $this->writeaccess, false);
  497. if (!$file->is_directory() || $fileinfo->count_non_empty_children($extensions)) {
  498. $result[] = $fileinfo;
  499. }
  500. }
  501. }
  502. return $result;
  503. }
  504. }
  505. /**
  506. * Represents a course category context in the tree navigated by {@link file_browser}.
  507. *
  508. * @package core_files
  509. * @copyright 2008 Petr Skoda (http://skodak.org)
  510. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  511. */
  512. class file_info_area_course_section extends file_info {
  513. /** @var stdClass course object */
  514. protected $course;
  515. /** @var file_info_context_course course file info object */
  516. protected $courseinfo;
  517. /**
  518. * Constructor
  519. *
  520. * @param file_browser $browser file browser instance
  521. * @param stdClass $context context object
  522. * @param stdClass $course course object
  523. * @param file_info_context_course $courseinfo file info instance
  524. */
  525. public function __construct($browser, $context, $course, file_info_context_course $courseinfo) {
  526. parent::__construct($browser, $context);
  527. $this->course = $course;
  528. $this->courseinfo = $courseinfo;
  529. }
  530. /**
  531. * Returns list of standard virtual file/directory identification.
  532. * The difference from stored_file parameters is that null values
  533. * are allowed in all fields
  534. *
  535. * @return array with keys contextid, filearea, itemid, filepath and filename
  536. */
  537. public function get_params() {
  538. return array('contextid' => $this->context->id,
  539. 'component' => 'course',
  540. 'filearea' => 'section',
  541. 'itemid' => null,
  542. 'filepath' => null,
  543. 'filename' => null);
  544. }
  545. /**
  546. * Returns localised visible name.
  547. *
  548. * @return string
  549. */
  550. public function get_visible_name() {
  551. //$format = $this->course->format;
  552. $sectionsname = get_string("coursesectionsummaries");
  553. return $sectionsname;
  554. }
  555. /**
  556. * Return whether or not new files or directories can be added
  557. *
  558. * @return bool
  559. */
  560. public function is_writable() {
  561. return false;
  562. }
  563. /**
  564. * Return whether or not this is a empty area
  565. *
  566. * @return bool
  567. */
  568. public function is_empty_area() {
  569. $fs = get_file_storage();
  570. return $fs->is_area_empty($this->context->id, 'course', 'section');
  571. }
  572. /**
  573. * Return whether or not this is a empty area
  574. *
  575. * @return bool
  576. */
  577. public function is_directory() {
  578. return true;
  579. }
  580. /**
  581. * Returns list of children.
  582. *
  583. * @return array of file_info instances
  584. */
  585. public function get_children() {
  586. global $DB;
  587. $children = array();
  588. $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
  589. foreach ($course_sections as $section) {
  590. if ($child = $this->courseinfo->get_file_info('course', 'section', $section->id, '/', '.')) {
  591. $children[] = $child;
  592. }
  593. }
  594. return $children;
  595. }
  596. /**
  597. * Returns the number of children which are either files matching the specified extensions
  598. * or folders containing at least one such file.
  599. *
  600. * @param string|array $extensions, for example '*' or array('.gif','.jpg')
  601. * @param int $limit stop counting after at least $limit non-empty children are found
  602. * @return int
  603. */
  604. public function count_non_empty_children($extensions = '*', $limit = 1) {
  605. global $DB;
  606. $params1 = array(
  607. 'courseid' => $this->course->id,
  608. 'contextid' => $this->context->id,
  609. 'component' => 'course',
  610. 'filearea' => 'section',
  611. 'emptyfilename' => '.');
  612. $sql1 = "SELECT DISTINCT cs.id FROM {files} f, {course_sections} cs
  613. WHERE cs.course = :courseid
  614. AND f.contextid = :contextid
  615. AND f.component = :component
  616. AND f.filearea = :filearea
  617. AND f.itemid = cs.id
  618. AND f.filename <> :emptyfilename";
  619. list($sql2, $params2) = $this->build_search_files_sql($extensions);
  620. $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2));
  621. $cnt = 0;
  622. foreach ($rs as $record) {
  623. if ((++$cnt) >= $limit) {
  624. break;
  625. }
  626. }
  627. $rs->close();
  628. return $cnt;
  629. }
  630. /**
  631. * Returns parent file_info instance
  632. *
  633. * @return file_info|null file_info or null for root
  634. */
  635. public function get_parent() {
  636. return $this->courseinfo;
  637. }
  638. }
  639. /**
  640. * Implementation of course section backup area
  641. *
  642. * @package core_files
  643. * @copyright 2008 Petr Skoda (http://skodak.org)
  644. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  645. */
  646. class file_info_area_backup_section extends file_info {
  647. /** @var stdClass course object */
  648. protected $course;
  649. /** @var file_info_context_course course file info object */
  650. protected $courseinfo;
  651. /**
  652. * Constructor
  653. *
  654. * @param file_browser $browser file browser instance
  655. * @param stdClass $context context object
  656. * @param stdClass $course course object
  657. * @param file_info_context_course $courseinfo file info instance
  658. */
  659. public function __construct($browser, $context, $course, file_info_context_course $courseinfo) {
  660. parent::__construct($browser, $context);
  661. $this->course = $course;
  662. $this->courseinfo = $courseinfo;
  663. }
  664. /**
  665. * Returns list of standard virtual file/directory identification.
  666. * The difference from stored_file parameters is that null values
  667. * are allowed in all fields
  668. *
  669. * @return array with keys contextid, component, filearea, itemid, filepath and filename
  670. */
  671. public function get_params() {
  672. return array('contextid' => $this->context->id,
  673. 'component' => 'backup',
  674. 'filearea' => 'section',
  675. 'itemid' => null,
  676. 'filepath' => null,
  677. 'filename' => null);
  678. }
  679. /**
  680. * Returns localised visible name.
  681. *
  682. * @return string
  683. */
  684. public function get_visible_name() {
  685. return get_string('sectionbackup', 'repository');
  686. }
  687. /**
  688. * Return whether or not new files and directories can be added
  689. *
  690. * @return bool
  691. */
  692. public function is_writable() {
  693. return false;
  694. }
  695. /**
  696. * Whether or not this is an empty area
  697. *
  698. * @return bool
  699. */
  700. public function is_empty_area() {
  701. $fs = get_file_storage();
  702. return $fs->is_area_empty($this->context->id, 'backup', 'section');
  703. }
  704. /**
  705. * Return whether or not this is a directory
  706. *
  707. * @return bool
  708. */
  709. public function is_directory() {
  710. return true;
  711. }
  712. /**
  713. * Returns list of children.
  714. *
  715. * @return array of file_info instances
  716. */
  717. public function get_children() {
  718. global $DB;
  719. $children = array();
  720. $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
  721. foreach ($course_sections as $section) {
  722. if ($child = $this->courseinfo->get_file_info('backup', 'section', $section->id, '/', '.')) {
  723. $children[] = $child;
  724. }
  725. }
  726. return $children;
  727. }
  728. /**
  729. * Returns the number of children which are either files matching the specified extensions
  730. * or folders containing at least one such file.
  731. *
  732. * @param string|array $extensions, for example '*' or array('.gif','.jpg')
  733. * @param int $limit stop counting after at least $limit non-empty children are found
  734. * @return int
  735. */
  736. public function count_non_empty_children($extensions = '*', $limit = 1) {
  737. global $DB;
  738. $params1 = array(
  739. 'courseid' => $this->course->id,
  740. 'contextid' => $this->context->id,
  741. 'component' => 'backup',
  742. 'filearea' => 'section',
  743. 'emptyfilename' => '.');
  744. $sql1 = "SELECT DISTINCT cs.id AS sectionid FROM {files} f, {course_sections} cs
  745. WHERE cs.course = :courseid
  746. AND f.contextid = :contextid
  747. AND f.component = :component
  748. AND f.filearea = :filearea
  749. AND f.itemid = cs.id
  750. AND f.filename <> :emptyfilename";
  751. list($sql2, $params2) = $this->build_search_files_sql($extensions);
  752. $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2));
  753. $cnt = 0;
  754. foreach ($rs as $record) {
  755. if ((++$cnt) >= $limit) {
  756. break;
  757. }
  758. }
  759. $rs->close();
  760. return $cnt;
  761. }
  762. /**
  763. * Returns parent file_info instance
  764. *
  765. * @return file_info or null for root
  766. */
  767. public function get_parent() {
  768. return $this->browser->get_file_info($this->context);
  769. }
  770. }