MDL-55445 core: New setting to host the logos
authorFrederic Massart <fred@moodle.com>
Wed, 3 Aug 2016 09:43:23 +0000 (17:43 +0800)
committerFrederic Massart <fred@moodle.com>
Wed, 17 Aug 2016 02:26:31 +0000 (10:26 +0800)
admin/lib.php
admin/settings/appearance.php
lang/en/admin.php
lib/outputrenderers.php
theme/upgrade.txt
version.php

index c9ddefa..3955084 100644 (file)
@@ -24,6 +24,8 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Return a list of page types
  * @param string $pagetype current page type
@@ -37,3 +39,86 @@ function admin_page_type_list($pagetype, $parentcontext, $currentcontext) {
     );
     return $array;
 }
+
+/**
+ * File serving.
+ *
+ * @param stdClass $course The course object.
+ * @param stdClass $cm The cm object.
+ * @param context $context The context object.
+ * @param string $filearea The file area.
+ * @param array $args List of arguments.
+ * @param bool $forcedownload Whether or not to force the download of the file.
+ * @param array $options Array of options.
+ * @return void|false
+ */
+function core_admin_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
+    global $CFG;
+
+    if (in_array($filearea, ['logo', 'logocompact'])) {
+        $size = array_shift($args); // The path hides the size.
+        $itemid = clean_param(array_shift($args), PARAM_INT);
+        $filename = clean_param(array_shift($args), PARAM_FILE);
+        $themerev = theme_get_revision();
+        if ($themerev <= 0) {
+            // Normalise to 0 as -1 doesn't place well with paths.
+             $themerev = 0;
+        }
+
+        // Extract the requested width and height.
+        $maxwidth = 0;
+        $maxheight = 0;
+        if (preg_match('/^\d+x\d+$/', $size)) {
+            list($maxwidth, $maxheight) = explode('x', $size);
+            $maxwidth = clean_param($maxwidth, PARAM_INT);
+            $maxheight = clean_param($maxheight, PARAM_INT);
+        }
+
+        $lifetime = 0;
+        if ($itemid > 0 && $themerev == $itemid) {
+            // The itemid is $CFG->themerev, when 0 or less no caching. Also no caching when they don't match.
+            $lifetime = DAYSECS * 60;
+        }
+
+        // Anyone, including guests and non-logged in users, can view the logos.
+        $options = ['cacheability' => 'public'];
+
+        // Check if we've got a cached file to return. When lifetime is 0 then we don't want to cached one.
+        $candidate = $CFG->localcachedir . "/core_admin/$themerev/$filearea/{$maxwidth}x{$maxheight}/$filename";
+        if (file_exists($candidate) && $lifetime > 0) {
+            send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options);
+        }
+
+        // Find the original file.
+        $fs = get_file_storage();
+        $filepath = "/{$context->id}/core_admin/{$filearea}/0/{$filename}";
+        if (!$file = $fs->get_file_by_hash(sha1($filepath))) {
+            send_file_not_found();
+        }
+
+        // No need for resizing, but if the file should be cached we save it so we can serve it fast next time.
+        if (empty($maxwidth) && empty($maxheight)) {
+            if ($lifetime) {
+                file_safe_save_content($file->get_content(), $candidate);
+            }
+            send_stored_file($file, $lifetime, 0, false, $options);
+        }
+
+        // Proceed with the resizing.
+        $filedata = $file->resize_image($maxwidth, $maxheight);
+        if (!$filedata) {
+            send_file_not_found();
+        }
+
+        // If we don't want to cached the file, serve now and quit.
+        if (!$lifetime) {
+            send_content_uncached($filedata, $filename);
+        }
+
+        // Save, serve and quit.
+        file_safe_save_content($filedata, $candidate);
+        send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options);
+    }
+
+    send_file_not_found();
+}
index a8b6c6a..d8697d4 100644 (file)
@@ -51,6 +51,26 @@ preferences,moodle|/user/preferences.php|preferences',
         }
     }
 
+    // Logos section.
+    $temp = new admin_settingpage('logos', new lang_string('logossettings', 'admin'));
+
+    // Logo file setting.
+    $title = get_string('logo', 'admin');
+    $description = get_string('logo_desc', 'admin');
+    $setting = new admin_setting_configstoredfile('core_admin/logo', $title, $description, 'logo', 0,
+        ['maxfiles' => 1, 'accepted_types' => ['.jpg', '.png']]);
+    $setting->set_updatedcallback('theme_reset_all_caches');
+    $temp->add($setting);
+
+    // Small logo file setting.
+    $title = get_string('logocompact', 'admin');
+    $description = get_string('logocompact_desc', 'admin');
+    $setting = new admin_setting_configstoredfile('core_admin/logocompact', $title, $description, 'logocompact', 0,
+        ['maxfiles' => 1, 'accepted_types' => ['.jpg', '.png']]);
+    $setting->set_updatedcallback('theme_reset_all_caches');
+    $temp->add($setting);
+
+    $ADMIN->add('appearance', $temp);
 
     // Calendar settings.
     $temp = new admin_settingpage('calendar', new lang_string('calendarsettings','admin'));
index 58448b6..3011ae5 100644 (file)
@@ -657,6 +657,11 @@ $string['loginpageautofocus_help'] = 'Enabling this option improves usability of
 $string['loginpasswordautocomplete'] = 'Prevent password autocompletion on login form';
 $string['loginpasswordautocomplete_help'] = 'If enabled, users are not allowed to save their account password in their browser.';
 $string['loglifetime'] = 'Keep logs for';
+$string['logo'] = 'Logo';
+$string['logo_desc'] = 'Your full logo. The image format must be PNG or JPEG.';
+$string['logocompact'] = 'Compact logo';
+$string['logocompact_desc'] = 'A compact version of your logo, usually this would be your emblem, or iconic symbol. Moodle\'s compact logo is the \'M\' by itself with the cap. The image format must be PNG or JPEG.';
+$string['logossettings'] = 'Logos';
 $string['logstorenotrequired'] = 'Log store not required';
 $string['logstoressupported'] = 'Log stores that support this report';
 $string['longtimewarning'] = '<b>Please note that this process can take a long time.</b>';
index 63be693..97b9543 100644 (file)
@@ -261,6 +261,51 @@ class renderer_base {
     public function pix_url($imagename, $component = 'moodle') {
         return $this->page->theme->pix_url($imagename, $component);
     }
+
+    /**
+     * Return the site's logo URL, if any.
+     *
+     * @param int $maxwidth The maximum width, or null when the maximum width does not matter.
+     * @param int $maxheight The maximum height, or null when the maximum height does not matter.
+     * @return moodle_url|false
+     */
+    public function get_logo_url($maxwidth = null, $maxheight = 100) {
+        global $CFG;
+        $logo = get_config('core_admin', 'logo');
+        if (empty($logo)) {
+            return false;
+        }
+
+        // Hide the requested size in the file path.
+        $filepath = ((int) $maxwidth . 'x' . (int) $maxheight) . '/';
+
+        // Use $CFG->themerev to prevent browser caching when the file changes.
+        return moodle_url::make_pluginfile_url(context_system::instance()->id, 'core_admin', 'logo', $filepath,
+            theme_get_revision(), $logo);
+    }
+
+    /**
+     * Return the site's compact logo URL, if any.
+     *
+     * @param int $maxwidth The maximum width, or null when the maximum width does not matter.
+     * @param int $maxheight The maximum height, or null when the maximum height does not matter.
+     * @return moodle_url|false
+     */
+    public function get_compact_logo_url($maxwidth = 100, $maxheight = 100) {
+        global $CFG;
+        $logo = get_config('core_admin', 'logocompact');
+        if (empty($logo)) {
+            return false;
+        }
+
+        // Hide the requested size in the file path.
+        $filepath = ((int) $maxwidth . 'x' . (int) $maxheight) . '/';
+
+        // Use $CFG->themerev to prevent browser caching when the file changes.
+        return moodle_url::make_pluginfile_url(context_system::instance()->id, 'core_admin', 'logocompact', $filepath,
+            theme_get_revision(), $logo);
+    }
+
 }
 
 
index 47492e5..b7ed8a0 100644 (file)
@@ -1,6 +1,14 @@
 This files describes API changes in /theme/* themes,
 information provided here is intended especially for theme designer.
 
+=== 3.2 ===
+
+* A new core setting now enables admins to upload the logos of their site. Using the
+  following methods, themers can instantly support branding logos without the need
+  to implement specific theme settings:
+  * $OUTPUT->get_logo_url($maxwidth, $maxheight);
+  * $OUTPUT->get_compact_logo_url($maxwidth, $maxheight);
+
 === 3.1 ===
 
 * A new search box for global search has been added to bootstrap and clean layout files, if
index 90b4002..19655fb 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2016081100.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2016081100.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.