yui_image.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. * This file is responsible for serving of yui images
  18. *
  19. * @package core
  20. * @copyright 2009 Petr Skoda (skodak) {@link http://skodak.org}
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. // disable moodle specific debug messages and any errors in output,
  24. // comment out when debugging or better look into error log!
  25. define('NO_DEBUG_DISPLAY', true);
  26. // we need just the values from config.php and minlib.php
  27. define('ABORT_AFTER_CONFIG', true);
  28. require('../config.php'); // this stops immediately at the beginning of lib/setup.php
  29. if ($slashargument = min_get_slash_argument()) {
  30. $path = ltrim($slashargument, '/');
  31. } else {
  32. $path = min_optional_param('file', '', 'SAFEPATH');
  33. }
  34. $etag = sha1($path);
  35. $parts = explode('/', $path);
  36. $version = array_shift($parts);
  37. if ($version === 'm') {
  38. $version = 'moodle';
  39. }
  40. if ($version == 'moodle' && count($parts) >= 3) {
  41. $frankenstyle = array_shift($parts);
  42. $module = array_shift($parts);
  43. $image = array_pop($parts);
  44. $subdir = join('/', $parts);
  45. $dir = core_component::get_component_directory($frankenstyle);
  46. // For shifted YUI modules, we need the YUI module name in frankenstyle format.
  47. $frankenstylemodulename = join('-', array($version, $frankenstyle, $module));
  48. // By default, try and use the /yui/build directory.
  49. $imagepath = $dir . '/yui/build/' . $frankenstylemodulename . '/assets/skins/sam/' . $image;
  50. // If the shifted versions don't exist, fall back to the non-shifted file.
  51. if (!file_exists($imagepath) or !is_file($imagepath)) {
  52. $imagepath = $dir . '/yui/' . $module . '/assets/skins/sam/' . $image;
  53. }
  54. } else if ($version == 'gallery' && count($parts) >= 3) {
  55. list($revision, $module, , , , $image) = $parts;
  56. $imagepath = "$CFG->dirroot/lib/yuilib/gallery/$module/assets/skins/sam/$image";
  57. } else {
  58. // Allow support for revisions on YUI between official releases.
  59. // We can just discard the subrevision since it is only used to invalidate the browser cache.
  60. $yuipatchedversion = explode('_', $version);
  61. $yuiversion = $yuipatchedversion[0];
  62. if (count($parts) == 1 && ($yuiversion == $CFG->yui3version || $yuiversion == $CFG->yui2version)) {
  63. list($image) = $parts;
  64. if ($yuiversion == $CFG->yui3version) {
  65. $imagepath = "$CFG->dirroot/lib/yuilib/$CFG->yui3version/assets/skins/sam/$image";
  66. } else {
  67. $imagepath = "$CFG->dirroot/lib/yuilib/2in3/$CFG->yui2version/build/assets/skins/sam/$image";
  68. }
  69. } else {
  70. yui_image_not_found();
  71. }
  72. }
  73. if (!file_exists($imagepath)) {
  74. yui_image_not_found();
  75. }
  76. $pathinfo = pathinfo($imagepath);
  77. $imagename = $pathinfo['filename'].'.'.$pathinfo['extension'];
  78. switch($pathinfo['extension']) {
  79. case 'gif' : $mimetype = 'image/gif'; break;
  80. case 'png' : $mimetype = 'image/png'; break;
  81. case 'jpg' : $mimetype = 'image/jpeg'; break;
  82. case 'jpeg' : $mimetype = 'image/jpeg'; break;
  83. case 'ico' : $mimetype = 'image/vnd.microsoft.icon'; break;
  84. default: $mimetype = 'document/unknown';
  85. }
  86. // if they are requesting a revision that's not -1, and they have supplied an
  87. // If-Modified-Since header, we can send back a 304 Not Modified since the
  88. // content never changes (the rev number is increased any time the content changes)
  89. if (strpos($path, '/-1/') === false and (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE']))) {
  90. $lifetime = 60*60*24*360; // 1 year, we do not change YUI versions often, there are a few custom yui modules
  91. header('HTTP/1.1 304 Not Modified');
  92. header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($imagepath)) .' GMT');
  93. header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
  94. header('Cache-Control: public, max-age='.$lifetime.', no-transform');
  95. header('Content-Type: '.$mimetype);
  96. header('Etag: "'.$etag.'"');
  97. die;
  98. }
  99. yui_image_cached($imagepath, $imagename, $mimetype, $etag);
  100. function yui_image_cached($imagepath, $imagename, $mimetype, $etag) {
  101. global $CFG;
  102. require("$CFG->dirroot/lib/xsendfilelib.php");
  103. $lifetime = 60*60*24*360; // 1 year, we do not change YUI versions often, there are a few custom yui modules
  104. header('Content-Disposition: inline; filename="'.$imagename.'"');
  105. header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($imagepath)) .' GMT');
  106. header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
  107. header('Pragma: ');
  108. header('Cache-Control: public, max-age=315360000, no-transform');
  109. header('Accept-Ranges: none');
  110. header('Content-Type: '.$mimetype);
  111. header('Content-Length: '.filesize($imagepath));
  112. header('Etag: "'.$etag.'"');
  113. if (xsendfile($imagepath)) {
  114. die;
  115. }
  116. // no need to gzip already compressed images ;-)
  117. readfile($imagepath);
  118. die;
  119. }
  120. function yui_image_not_found() {
  121. header('HTTP/1.0 404 not found');
  122. die('Image was not found, sorry.');
  123. }