MDL-61657 block_myoverview: implement course images for the myoverview block

This commit is contained in:
Bas Brands
2018-04-20 08:28:22 +02:00
committed by Eloy Lafuente (stronk7)
parent 4450d19ae1
commit c8cc25caba
24 changed files with 1825 additions and 31 deletions

View File

@ -60,6 +60,7 @@ lib/fonts/
lib/amd/src/adapter.js
lib/validateurlsyntax.php
lib/amd/src/popper.js
lib/geopattern-php/
media/player/videojs/amd/src/video-lazy.js
media/player/videojs/amd/src/Youtube-lazy.js
media/player/videojs/videojs/

View File

@ -61,6 +61,7 @@ lib/fonts/
lib/amd/src/adapter.js
lib/validateurlsyntax.php
lib/amd/src/popper.js
lib/geopattern-php/
media/player/videojs/amd/src/video-lazy.js
media/player/videojs/amd/src/Youtube-lazy.js
media/player/videojs/videojs/

View File

@ -65,6 +65,7 @@ class courses_view implements renderable, templatable {
public function export_for_template(renderer_base $output) {
global $CFG;
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot.'/lib/coursecatlib.php');
// Build courses view data structure.
$coursesview = [
@ -83,6 +84,29 @@ class courses_view implements renderable, templatable {
// Convert summary to plain text.
$exportedcourse->summary = content_to_text($exportedcourse->summary, $exportedcourse->summaryformat);
$course = new \course_in_list($course);
foreach ($course->get_course_overviewfiles() as $file) {
$isimage = $file->is_valid_image();
if ($isimage) {
$url = file_encode_url("$CFG->wwwroot/pluginfile.php",
'/'. $file->get_contextid(). '/'. $file->get_component(). '/'.
$file->get_filearea(). $file->get_filepath(). $file->get_filename(), !$isimage);
$exportedcourse->courseimage = $url;
$exportedcourse->classes = 'courseimage';
break;
}
}
$exportedcourse->color = $this->coursecolor($course->id);
if (!isset($exportedcourse->courseimage)) {
$pattern = new \core_geopattern();
$pattern->setColor($exportedcourse->color);
$pattern->patternbyid($courseid);
$exportedcourse->classes = 'coursepattern';
$exportedcourse->courseimage = $pattern->datauri();
}
// Include course visibility.
$exportedcourse->visible = (bool)$course->visible;
@ -148,4 +172,19 @@ class courses_view implements renderable, templatable {
return $coursesview;
}
/**
* Generate a semi-random color based on the courseid number (so it will always return
* the same color for a course)
*
* @param int $courseid
* @return string $color, hexvalue color code.
*/
protected function coursecolor($courseid) {
// The colour palette is hardcoded for now. It would make sense to combine it with theme settings.
$basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894', '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
$color = $basecolors[$courseid % 10];
return $color;
}
}

View File

@ -38,7 +38,7 @@
}
}}
{{< block_myoverview/paging-content-item }}
{{$classes}}row{{/classes}}
{{$classes}}row card-deck{{/classes}}
{{$content}}
{{#courses}}
{{> block_myoverview/courses-view-course-item }}

View File

@ -26,22 +26,24 @@
"summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
}
}}
<div class="col-lg-6">
<div class="card mb-3 courses-view-course-item">
<div class="card-body course-info-container" id="course-info-container-{{id}}">
<div class="media">
<div class="mr-2">
{{> block_myoverview/progress-chart}}
</div>
<div class="media-body">
<h4 class="h5"><a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a></h4>
</div>
</div>
<p class="text-muted">
{{#shortentext}} 140, {{summary}}{{/shortentext}}
</p>
<div class="card mb-3 courses-view-course-item">
<a href="{{viewurl}}">
<div class="card-img-top myoverviewimg {{classes}}" style='background-image: url("{{{courseimage}}}");'>
</div>
</a>
<div class="card-body course-info-container" id="course-info-container-{{id}}">
<div class="media">
<div class="mr-2">
{{> block_myoverview/progress-chart}}
</div>
<div class="media-body">
<h4 class="h5"><a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a></h4>
</div>
</div>
<p class="text-muted">
{{#shortentext}} 140, {{summary}}{{/shortentext}}
</p>
</div>
</div>

View File

@ -85,6 +85,7 @@ class core_component {
'IMSGlobal\LTI' => 'lib/ltiprovider/src',
'Phpml' => 'lib/mlbackend/php/phpml/src/Phpml',
'PHPMailer\\PHPMailer' => 'lib/phpmailer/src',
'RedeyeVentures\\GeoPattern' => 'lib/geopattern-php/GeoPattern',
);
/**

View File

@ -0,0 +1,45 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Geopatterns for images.
*
* @package core
* @copyright 2018 Moodle
* @author Bas Brands
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
class core_geopattern extends \RedeyeVentures\GeoPattern\GeoPattern {
/**
* Add variables.
*
* @param array $scss Associative array of variables and their values.
* @return void
*/
public function patternbyid($uniqueid) {
$this->setString($uniqueid);
}
public function datauri() {
return $this->toDataURI();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
<?php namespace RedeyeVentures\GeoPattern;
use RedeyeVentures\GeoPattern\SVGElements\Group;
use RedeyeVentures\GeoPattern\SVGElements\Polyline;
use RedeyeVentures\GeoPattern\SVGElements\Rectangle;
use RedeyeVentures\GeoPattern\SVGElements\Circle;
use RedeyeVentures\GeoPattern\SVGElements\Path;
class SVG {
protected $width;
protected $height;
protected $svgString;
function __construct($options=array())
{
$this->width = 100;
$this->height = 100;
$this->svgString = '';
}
public function setWidth($width)
{
$this->width = floor($width);
return $this;
}
public function setHeight($height)
{
$this->height = floor($height);
return $this;
}
protected function getSvgHeader()
{
return "<?xml version=\"1.0\"?><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{$this->width}\" height=\"{$this->height}\">";
}
protected function getSvgFooter()
{
return '</svg>';
}
public function addRectangle($x, $y, $width, $height, $args=array())
{
$rectangle = new Rectangle($x, $y, $width, $height, $args);
$this->svgString .= $rectangle;
return $this;
}
public function addCircle($cx, $cy, $r, $args=array())
{
$circle = new Circle($cx, $cy, $r, $args);
$this->svgString .= $circle;
return $this;
}
public function addPath($d, $args=array())
{
$path = new Path($d, $args);
$this->svgString .= $path;
return $this;
}
public function addPolyline($points, $args=array())
{
$polyline = new Polyline($points, $args);
$this->svgString .= $polyline;
return $this;
}
public function addGroup($group, $args=array())
{
if ($group instanceof Group)
{
$group->setArgs($args);
$this->svgString .= $group;
return $this;
}
throw new \InvalidArgumentException("The group provided is not a valid instance of Group.");
}
public function getString()
{
return $this->getSvgHeader().$this->svgString.$this->getSvgFooter();
}
public function __toString()
{
return $this->getString();
}
}

View File

@ -0,0 +1,55 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
abstract class Base
{
protected $tag;
protected $elements;
protected $args;
function __construct($args)
{
$this->args = $args;
}
public function elementsToString()
{
$string = ' ';
foreach ($this->elements as $key => $value)
{
$string .= "$key=\"$value\" ";
}
return $string;
}
public function argsToString()
{
$string = '';
foreach ($this->args as $key => $value)
{
if (is_array($value))
{
$string .= "$key=\"";
foreach ($value as $k => $v)
{
$string .= "$k:$v;";
}
$string .= '" ';
}
else
{
$string .= "$key=\"$value\" ";
}
}
return $string;
}
public function getString()
{
return "<{$this->tag}{$this->elementsToString()}{$this->argsToString()}/>";
}
function __toString()
{
return $this->getString();
}
}

View File

@ -0,0 +1,16 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
class Circle extends Base
{
protected $tag = 'circle';
function __construct($cx, $cy, $r, $args=array())
{
$this->elements = [
'cx' => $cx,
'cy' => $cy,
'r' => $r,
];
parent::__construct($args);
}
}

View File

@ -0,0 +1,38 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
class Group extends Base
{
protected $tag = 'g';
protected $items;
function __construct($items=array(), $args=array())
{
$this->items = $items;
$this->args = $args;
}
function addItem($item)
{
$this->items[] = $item;
return $this;
}
function setArgs($args)
{
$this->args = $args;
return $this;
}
function getString()
{
$svgString = '';
$svgString .= "<{$this->tag} {$this->argsToString($this->args)}>";
foreach ($this->items as $item)
{
$svgString .= $item;
}
$svgString .= "</{$this->tag}>";
return $svgString;
}
}

View File

@ -0,0 +1,14 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
class Path extends Base
{
protected $tag = 'path';
function __construct($d, $args=array())
{
$this->elements = [
'd' => $d,
];
parent::__construct($args);
}
}

View File

@ -0,0 +1,14 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
class Polyline extends Base
{
protected $tag = 'polyline';
function __construct($points, $args=array())
{
$this->elements = [
'points' => $points,
];
parent::__construct($args);
}
}

View File

@ -0,0 +1,17 @@
<?php namespace RedeyeVentures\GeoPattern\SVGElements;
class Rectangle extends Base
{
protected $tag = 'rect';
function __construct($x, $y, $width, $height, $args=array())
{
$this->elements = [
'x' => $x,
'y' => $y,
'width' => $width,
'height' => $height,
];
parent::__construct($args);
}
}

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Redeye Ventures
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,14 @@
scssphp
-------
Downloaded from: https://github.com/RedeyeGroup/geopattern-php
Last commit on download: 26d9f8aa7a8b00c8afc120d706f6bdd7a9965b87
Import procedure:
- Copy all the files from the folder 'src' this directory.
- Copy the license file from the project root.
- Remove the geopattern_loader.php file from the src directory, it is not needed.
Licensed under MIT, Copyright (c) 2015 Leaf Corcoran.

View File

@ -317,4 +317,10 @@
<version>v1.12.6</version>
<licenseversion></licenseversion>
</library>
<library>
<location>geopattern-php</location>
<name>Generate tiling SVG patterns from a string</name>
<license>MIT</license>
<version>1.1.1</version>
</library>
</libraries>

View File

@ -199,6 +199,30 @@ $doughnut-fill-colour: $brand-warning;
}
}
.card-deck {
.card {
$card-gutter : $card-deck-margin * 2;
flex-grow: 0;
flex-shrink: 0;
flex-basis: calc(50% - #{$card-gutter});
}
.myoverviewimg {
height: 150px;
&.courseimage {
background-position: center;
background-size: cover;
}
}
}
@media (min-width: 1600px) {
.block_myoverview {
.courses-view-course-item {
height: 190px;
}
}
}
// Show expand collapse with font-awesome.
.block_settings .block_tree [aria-expanded="true"],
.block_settings .block_tree [aria-expanded="true"].emptybranch,

View File

@ -343,6 +343,10 @@
.block_myoverview {
background-color: transparent;
.row-fluid [class*="span"] {
margin-left:0px;
}
.event-list-item {
border-bottom: 1px solid @tableBorder;
padding-bottom: 10px;
@ -395,5 +399,13 @@
.well {
background-color: @white;
box-shadow: none;
margin: 0 5px 10px;
}
.myoverviewimg {
height: 150px;
&.courseimage {
background-position: center;
background-size: cover;
}
}
}

View File

@ -16487,6 +16487,9 @@ body {
.block_myoverview {
background-color: transparent;
}
.block_myoverview .row-fluid [class*="span"] {
margin-left: 0px;
}
.block_myoverview .event-list-item {
border-bottom: 1px solid #ddd;
padding-bottom: 10px;
@ -16529,6 +16532,14 @@ body {
.block_myoverview .well {
background-color: #fff;
box-shadow: none;
margin: 0 5px 10px;
}
.block_myoverview .myoverviewimg {
height: 150px;
}
.block_myoverview .myoverviewimg.courseimage {
background-position: center;
background-size: cover;
}
/**
* Moodle forms HTML isn't changeable via renderers (yet?) so this

View File

@ -42,5 +42,6 @@
{{#courses}}
{{> block_myoverview/courses-view-course-item }}
{{/courses}}
<div class="clearfix"></div>
{{/content}}
{{/ block_myoverview/paging-content-item }}

View File

@ -26,22 +26,28 @@
"summary": "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."
}
}}
<div class="well well-small">
<div class="course-info-container" id="course-info-container-{{id}}">
<div class="media">
<div class="pull-left">
<div class="media-object">
{{> block_myoverview/progress-chart}}
<div class="span6">
<div class="well well-small">
<a href="{{viewurl}}">
<div class="myoverviewimg m-b-1 {{classes}}" style='background-image: url("{{{courseimage}}}");'>
</div>
</a>
<div class="course-info-container" id="course-info-container-{{id}}">
<div class="media">
<div class="pull-left">
<div class="media-object">
{{> block_myoverview/progress-chart}}
</div>
</div>
<div class="media-body">
<h4 class="media-heading">
<a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a>
</h4>
</div>
</div>
<div class="media-body">
<h4 class="media-heading">
<a href="{{viewurl}}" class="{{^visible}}dimmed{{/visible}}">{{{fullnamedisplay}}}</a>
</h4>
</div>
<p class="text-muted">
{{#shortentext}} 140, {{{summary}}}{{/shortentext}}
</p>
</div>
<p class="text-muted">
{{#shortentext}} 140, {{{summary}}}{{/shortentext}}
</p>
</div>
</div>

View File

@ -0,0 +1,36 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template block_myoverview/paging-content-item
This template renders the content of a page. It is to be used with
the paging bar to toggle visibility of the content items.
Example context (json):
{
"active": true,
"page": 1,
"content": "<p>Some page content</p>"
}
}}
<div data-region="paging-content-item"
data-page="{{page}}"
class="row-fluid {{^active}}hidden{{/active}} {{$classes}}{{/classes}}">
{{$content}}
{{{content}}}
{{/content}}
</div>