Replace platform logo with course logo

The update adds the possibility to upload a course logo with the same dimensions as the platform logo. The uploaded course logo can be applied to the header, email-template and pdf-export.
pull/4599/head
TheTomcat14 3 years ago
parent 31635d10ca
commit 19863bbab3
  1. 2
      .htaccess
  2. 40
      app/Migrations/Schema/V111/Version20230202100000.php
  3. 56
      main/course_info/infocours.php
  4. 2
      main/inc/ajax/course.ajax.php
  5. 23
      main/inc/lib/api.lib.php
  6. 22
      main/inc/lib/banner.lib.php
  7. 133
      main/inc/lib/course.lib.php
  8. 11
      main/inc/lib/exercise.lib.php
  9. 12
      main/inc/lib/pdf.lib.php
  10. 26
      main/inc/lib/template.lib.php
  11. 4
      main/install/data.sql
  12. 5
      main/lang/dutch/trad4all.inc.php
  13. 5
      main/lang/english/trad4all.inc.php
  14. 11
      main/survey/surveyUtil.class.php
  15. 13
      main/wiki/wiki.inc.php

@ -46,6 +46,8 @@ RewriteRule ^courses/([^/]+)/work/(.*)$ main/work/download.php?file=work/$2&cDir
RewriteRule ^courses/([^/]+)/course-pic85x85.png$ main/inc/ajax/course.ajax.php?a=get_course_image&code=$1&image=course_image_source [QSA,L]
RewriteRule ^courses/([^/]+)/course-pic.png$ main/inc/ajax/course.ajax.php?a=get_course_image&code=$1&image=course_image_large_source [QSA,L]
RewriteRule ^courses/([^/]+)/course-email-pic85x85.png$ main/inc/ajax/course.ajax.php?a=get_course_image&code=$1&image=course_email_image_source [QSA,L]
RewriteRule ^courses/([^/]+)/course-email-pic.png$ main/inc/ajax/course.ajax.php?a=get_course_image&code=$1&image=course_email_image_large_source [QSA,L]
# Redirect all courses/ to app/courses/
RewriteRule ^courses/([^/]+)/(.*)$ app/courses/$1/$2 [QSA,L]

@ -0,0 +1,40 @@
<?php
/* For licensing terms, see /license.txt */
namespace Application\Migrations\Schema\V111;
use Application\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
/**
* Class Version20160712150000
* Add option to use SVG icons instead of their PNG version
* @package Application\Migrations\Schema\V111
*/
class Version20230202100000 extends AbstractMigrationChamilo
{
/**
* @param Schema $schema
* @throws \Doctrine\DBAL\DBALException
* @throws \Doctrine\DBAL\Schema\SchemaException
*/
public function up(Schema $schema)
{
$this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('use_course_logo_in_course_page', NULL, 'radio', 'Course', 'false', 'UseCourseLogoInCoursePageTitle', 'UseCourseLogoInCoursePageComment','',NULL, 1)");
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('use_course_logo_in_course_page', 'true', 'Yes') ");
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('use_course_logo_in_course_page', 'false', 'No') ");
}
/**
* @param Schema $schema
* @throws \Doctrine\DBAL\DBALException
* @throws \Doctrine\DBAL\Schema\SchemaException
*/
public function down(Schema $schema)
{
$this->addSql("DELETE FROM settings_current WHERE variable = 'use_course_logo_in_course_page'");
$this->addSql("DELETE FROM settings_options WHERE variable = 'use_course_logo_in_course_page'");
}
}

@ -85,14 +85,22 @@ $form->addHtml('
<div class="panel-body">
');
// display regular image
$image = '';
// Display course picture
$course_path = api_get_path(SYS_COURSE_PATH).$currentCourseRepository; // course path
if (file_exists($course_path.'/course-pic85x85.png')) {
if (file_exists($course_path.'/course-pic85x85.png') || file_exists($course_path.'/course-email-pic85x85.png')) {
$image = '<div class="row">';
$course_web_path = api_get_path(WEB_COURSE_PATH).$currentCourseRepository; // course web path
$course_medium_image = $course_web_path.'/course-pic85x85.png?'.rand(1, 1000); // redimensioned image 85x85
$image = '<div class="row"><label class="col-md-2 control-label">'.get_lang('Image').'</label>
<div class="col-md-8"><img src="'.$course_medium_image.'" /></div></div>';
if (file_exists($course_path.'/course-pic85x85.png')) {
$course_medium_image = $course_web_path.'/course-pic85x85.png?'.rand(1, 1000); // redimensioned image 85x85
$image .= '<label class="col-md-2 control-label">'.get_lang('Image').'</label><div class="col-md-4"><img src="'.$course_medium_image.'" /></div>';
}
if (file_exists($course_path.'/course-email-pic85x85.png')) {
$course_medium_image = $course_web_path.'/course-email-pic85x85.png?'.rand(1, 1000); // redimensioned image 85x85
$image .= '<label class="col-md-2 control-label">'.get_lang('EmailImage').'</label><div class="col-md-4"><img src="'.$course_medium_image.'" /></div>';
}
$image .= '</div>';
}
$form->addHtml($image);
$form->addText('title', get_lang('Title'), true);
@ -166,6 +174,24 @@ $form->addRule(
);
$form->addElement('checkbox', 'delete_picture', null, get_lang('DeletePicture'));
// Email Picture
$form->addFile(
'email_picture',
get_lang('AddEmailPicture'),
['id' => 'email_picture', 'class' => 'picture-form', 'crop_image' => true, 'crop_ratio' => '250 / 70']
);
$allowed_picture_types = api_get_supported_image_extensions(false);
$form->addRule(
'email_picture',
get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')',
'filetype',
$allowed_picture_types
);
$form->addElement('checkbox', 'delete_email_picture', null, get_lang('DeleteEmailPicture'));
if (api_get_setting('pdf_export_watermark_by_course') === 'true') {
$url = PDF::get_watermark($course_code);
$form->addText('pdf_export_watermark_text', get_lang('PDFExportWatermarkTextTitle'), false, ['size' => '60']);
@ -1111,6 +1137,23 @@ if ($form->validate() && is_settings_editable()) {
);
}
// update email picture
$emailPicture = $_FILES['email_picture'];
if (!empty($emailPicture['name'])) {
CourseManager::update_course_email_picture(
$_course,
$emailPicture['name'],
$emailPicture['tmp_name'],
$updateValues['email_picture_crop_result']
);
Event::addEvent(
LOG_COURSE_SETTINGS_CHANGED,
'course_email_picture',
$emailPicture['name']
);
}
if ($visibilityChangeable && isset($updateValues['visibility'])) {
$visibility = $updateValues['visibility'];
} else {
@ -1122,6 +1165,11 @@ if ($form->validate() && is_settings_editable()) {
CourseManager::deleteCoursePicture($course_code);
}
$deleteEmailPicture = isset($updateValues['delete_email_picture']) ? $updateValues['delete_email_picture'] : '';
if ($deleteEmailPicture) {
CourseManager::deleteCourseEmailPicture($course_code);
}
global $_configuration;
$urlId = api_get_current_access_url_id();
if (isset($_configuration[$urlId]) &&

@ -33,7 +33,7 @@ switch ($action) {
case 'get_course_image':
$courseId = ChamiloApi::getCourseIdByDirectory($_REQUEST['code']);
$courseInfo = api_get_course_info_by_id($courseId);
$image = isset($_REQUEST['image']) && in_array($_REQUEST['image'], ['course_image_large_source', 'course_image_source']) ? $_REQUEST['image'] : '';
$image = isset($_REQUEST['image']) && in_array($_REQUEST['image'], ['course_image_large_source', 'course_image_source', 'course_email_image_large_source', 'course_email_image_source']) ? $_REQUEST['image'] : '';
if ($courseInfo && $image) {
// Arbitrarily set a cache of 10' for the course image to
// avoid hammering the server with otherwise unfrequently

@ -2532,6 +2532,26 @@ function api_format_course_array($course_data)
$_course['course_image_large'] = $url_image;
// email pictures
// Course image
$url_image = null;
$_course['course_email_image_source'] = '';
if (file_exists($courseSys.'/course-email-pic85x85.png')) {
$url_image = $webCourseHome.'/course-email-pic85x85.png';
$_course['course_email_image_source'] = $courseSys.'/course-email-pic85x85.png';
}
$_course['course_email_image'] = $url_image;
// Course large image
$url_image = null;
$_course['course_email_image_large_source'] = '';
if (file_exists($courseSys.'/course-email-pic.png')) {
$url_image = $webCourseHome.'/course-email-pic.png';
$_course['course_email_image_large_source'] = $courseSys.'/course-email-pic.png';
}
$_course['course_email_image_large'] = $url_image;
return $_course;
}
@ -9527,6 +9547,9 @@ function api_mail_html(
if (isset($additionalParameters['link'])) {
$mailView->assign('link', $additionalParameters['link']);
}
if (isset($additionalParameters['logo'])) {
$mailView->assign('logo', $additionalParameters['logo']);
}
$mailView->assign('mail_header_style', api_get_configuration_value('mail_header_style'));
$mailView->assign('mail_content_style', api_get_configuration_value('mail_content_style'));
$mailView->assign('include_ldjson', (empty($platform_email['EXCLUDE_JSON']) ? true : false));

@ -213,6 +213,28 @@ function return_logo($theme = '', $responsive = true)
$class = '';
}
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
// check if current page is a course page
$courseCode = api_get_course_id();
if (!empty($courseCode)) {
$course = api_get_course_info($courseCode);
if (!empty($course) && !empty($course['course_email_image_large'])) {
$image = \Display::img(
$course['course_email_image_large'],
$course['name'],
[
'title' => $course['name'],
'class' => $class,
'id' => 'header-logo',
]
);
return \Display::url($image, $course['course_public_url']);
}
}
}
return ChamiloApi::getPlatformLogo(
$theme,
[

@ -7400,4 +7400,137 @@ class CourseManager
$courseFieldValue = new ExtraFieldValue('course');
$courseFieldValue->saveFieldValues($params);
}
/**
* Update course email picture.
*
* @param array $courseInfo
* @param string File name
* @param string the full system name of the image
* from which course picture will be created
* @param string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format
*
* @return bool Returns the resulting. In case of internal error or negative validation returns FALSE.
*/
public static function update_course_email_picture(
$courseInfo,
$filename,
$source_file = null,
$cropParameters = null
) {
if (empty($courseInfo)) {
return false;
}
// course path
$store_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'];
// image name for courses
$course_image = $store_path.'/course-email-pic.png';
$course_medium_image = $store_path.'/course-email-pic85x85.png';
if (file_exists($course_image)) {
unlink($course_image);
}
if (file_exists($course_medium_image)) {
unlink($course_medium_image);
}
//Crop the image to adjust 4:3 ratio
$image = new Image($source_file);
$image->crop($cropParameters);
//Resize the images in two formats
$medium = new Image($source_file);
$medium->resize(85);
$medium->send_image($course_medium_image, -1, 'png');
$normal = new Image($source_file);
$normal->resize(250);
$normal->send_image($course_image, -1, 'png');
$result = $medium && $normal;
return $result ? $result : false;
}
/**
* Deletes the course email picture.
*
* @param string $courseCode
*/
public static function deleteCourseEmailPicture($courseCode)
{
$course_info = api_get_course_info($courseCode);
// course path
$storePath = api_get_path(SYS_COURSE_PATH).$course_info['path'];
// image name for courses
$courseImage = $storePath.'/course-email-pic.png';
$courseMediumImage = $storePath.'/course-email-pic85x85.png';
$courseSmallImage = $storePath.'/course-email-pic32.png';
if (file_exists($courseImage)) {
unlink($courseImage);
}
if (file_exists($courseMediumImage)) {
unlink($courseMediumImage);
}
if (file_exists($courseSmallImage)) {
unlink($courseSmallImage);
}
}
/**
* Get the course email picture path.
*
* @param bool $fullSize
*
* @return string|null
*/
public static function getEmailPicturePath(Course $course, $fullSize = false)
{
if (!self::hasPicture($course)) {
return null;
}
if ($fullSize) {
return api_get_path(WEB_COURSE_PATH).$course->getDirectory().'/course-email-pic.png';
}
return api_get_path(WEB_COURSE_PATH).$course->getDirectory().'/course-email-pic85x85.png';
}
/**
* Get the course logo
*
* @param array $course array containing course info, @see api_get_course_info()
* @param array $attributes Array containing extra attributes for the image tag
*
* @return string|null
*/
public static function getCourseLogo($course, $attributes = null)
{
$logo = null;
if (!empty($course)
&& !empty($course['course_email_image_large_source'])
&& file_exists($course['course_email_image_large_source'])
) {
if (is_null($attributes)) {
$attributes = [
'title' => $course['name'],
'class' => 'img-responsive',
'id' => 'header-logo',
'width' => 250,
];
}
$logo = \Display::url(
\Display::img(
$course['course_email_image_large'],
$course['name'],
$attributes
),
api_get_path(WEB_PATH) . 'index.php'
);
}
return $logo;
}
}

@ -7046,10 +7046,16 @@ EOT;
$exercise_stat_info,
$studentId
);
$extraParameters = [];
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
$extraParameters = ['logo' => CourseManager::getCourseLogo($courseInfo)];
}
foreach ($emailList as $email) {
if (empty($email)) {
continue;
}
api_mail_html(
null,
$email,
@ -7058,7 +7064,10 @@ EOT;
null,
null,
[],
$attachments
$attachments,
false,
$extraParameters,
''
);
}
}

@ -738,7 +738,17 @@ class PDF
}
}
$organization = ChamiloApi::getPlatformLogo('', [], true, true);
$organization = null;
// try getting the course logo
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
$organization = CourseManager::getCourseLogo($courseInfo, []);
}
if (empty($organization)) {
$organization = ChamiloApi::getPlatformLogo('', [], false, true);
}
// Use custom logo image.
$pdfLogo = api_get_setting('pdf_logo_header');
if ($pdfLogo === 'true') {

@ -2074,11 +2074,27 @@ class Template
$portalImageMeta .= '<meta property="twitter:image:alt" content="'.$imageAlt.'" />'."\n";
}
} else {
$logo = ChamiloApi::getPlatformLogoPath($this->theme);
if (!empty($logo)) {
$portalImageMeta = '<meta property="og:image" content="'.$logo.'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image" content="'.$logo.'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image:alt" content="'.$imageAlt.'" />'."\n";
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
// check if current page is a course page
$courseCode = api_get_course_id();
if (!empty($courseCode)) {
$course = api_get_course_info($courseCode);
if (!empty($course) && !empty($course['course_email_image_large'])) {
$portalImageMeta = '<meta property="og:image" content="'.$course['course_email_image_large'].'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image" content="'.$course['course_email_image_large'].'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image:alt" content="'.$imageAlt.'" />'."\n";
}
}
}
if (empty($portalImageMeta)) {
$logo = ChamiloApi::getPlatformLogoPath($this->theme);
if (!empty($logo)) {
$portalImageMeta = '<meta property="og:image" content="'.$logo.'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image" content="'.$logo.'" />'."\n";
$portalImageMeta .= '<meta property="twitter:image:alt" content="'.$imageAlt.'" />'."\n";
}
}
}

@ -1969,3 +1969,7 @@ INSERT INTO settings_options (variable, value, display_text) VALUES ('exercise_i
INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('configure_exercise_visibility_in_course',NULL,'radio','Session','false','ConfigureExerciseVisibilityInCourseTitle','ConfigureExerciseVisibilityInCourseComment','',NULL, 1);
INSERT INTO settings_options (variable, value, display_text) VALUES ('configure_exercise_visibility_in_course','true','Yes');
INSERT INTO settings_options (variable, value, display_text) VALUES ('configure_exercise_visibility_in_course','false','No');
INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url, access_url_changeable, access_url_locked) VALUES ('use_course_logo_in_course_page', NULL, 'radio', 'Course', 'true', 'UseCourseLogoInCoursePageTitle', 'UseCourseLogoInCoursePageComment', NULL, NULL, 1, 1, 0);
INSERT INTO settings_options (variable, value, display_text) VALUES ('use_course_logo_in_course_page', 'true', 'Yes');
INSERT INTO settings_options (variable, value, display_text) VALUES ('use_course_logo_in_course_page', 'false', 'No');

@ -6882,4 +6882,9 @@ $FirstLesson = "Eerste lesmoment";
$UserGuides = "Gidsen voor gebruikers";
$OngoingTraining = "Lopende opleiding(en)";
$ThereAreUsersOrCoursesUsingThisLanguageYouWantToDisableThisLanguageAndSetUsersAndCoursesWithTheDefaultPortalLanguage = "Er zijn gebruikers of cursussen die deze taal gebruiken. Wilt u deze taal uitschakelen en alle gebruikers en cursussen de standaard portal taal laten gebruiken?";
$EmailImage = "Site & e-mail banner";
$AddEmailPicture = "Voeg site & e-mail banner toe";
$DeleteEmailPicture = "Verwijder site & e-mail banner";
$UseCourseLogoInCoursePageTitle = "Gebruik het cursus logo in de header";
$UseCourseLogoInCoursePageComment = "In plaats van het platform logo gebruik het cursus logo in de header";
?>

@ -8988,4 +8988,9 @@ $MatchingCombination = "Matching with exact selection";
$HotSpotCombination = "Image zones with exact selection";
$MatchingDraggableCombination = "Match by dragging with exact selection";
$MultipleAnswerDropdownCombination = "Multiple answer dropdown with exact selection";
$EmailImage = "Site & mail banner";
$AddEmailPicture = "Add site & mail banner";
$DeleteEmailPicture = "Delete site & mail banner";
$UseCourseLogoInCoursePageTitle = "Use the course logo in the header";
$UseCourseLogoInCoursePageComment = "Instead of the platform logo, use the course logo in the header";
?>

@ -2993,6 +2993,11 @@ class SurveyUtil
true
);
} else {
$extraParameters = [];
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
$extraParameters = ['logo' => CourseManager::getCourseLogo($_course)];
}
@api_mail_html(
'',
$invitedUser,
@ -3000,7 +3005,11 @@ class SurveyUtil
$full_invitation_text,
$sender_name,
$sender_email,
$replyto
$replyto,
[],
false,
$extraParameters,
''
);
}
}

@ -2253,6 +2253,12 @@ class Wiki
}
///make and send email
if ($allow_send_mail) {
$extraParameters = [];
if (api_get_setting('use_course_logo_in_course_page') === 'true') {
$extraParameters = ['logo' => CourseManager::getCourseLogo($_course)];
}
while ($row = Database::fetch_array($result)) {
$userinfo = api_get_user_info(
$row['user_id']
@ -2289,7 +2295,12 @@ class Wiki
$email_subject,
$email_body,
$sender_name,
$sender_email
$sender_email,
[],
[],
false,
$extraParameters,
''
);
}
}

Loading…
Cancel
Save