Add app/upload/badges

1.10.x
Julio Montoya 10 years ago
parent 110b31075d
commit 417f86f54a
  1. 0
      app/upload/badges/.gitkeep
  2. 35
      main/admin/skill_badge_create.php
  3. 3
      main/admin/skill_badge_list.php
  4. 2
      main/badge/class.php
  5. 19
      main/inc/lib/api.lib.php
  6. 2
      main/inc/lib/group_portal_manager.lib.php
  7. 113
      main/inc/lib/image.lib.php
  8. 38
      main/inc/lib/model.lib.php
  9. 2
      main/inc/lib/template.lib.php
  10. 2
      main/inc/lib/usermanager.lib.php
  11. 22
      main/install/update-files-1.9.0-1.10.0.inc.php
  12. 2
      main/template/default/skill/badge_create.tpl
  13. 3
      main/template/default/skill/badge_list.tpl
  14. 2
      main/template/default/skill/skill_wheel_student.tpl
  15. 11
      src/Chamilo/CoreBundle/Component/Editor/Connector.php
  16. 5
      src/Chamilo/CoreBundle/Component/Editor/Driver/CourseDriver.php

@ -5,7 +5,7 @@
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @package chamilo.admin.openbadges
*/
use \ChamiloSession as Session;
use ChamiloSession as Session;
$cidReset = true;
@ -32,46 +32,39 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['image']) && $_FILES['image']['error'] == 0) {
$dirPermissions = api_get_permissions_for_new_directories();
$sysPath = api_get_path(SYS_PATH);
$sysDataPath = api_get_path(SYS_DATA_PATH);
$existsDataDirectory = is_dir($sysDataPath);
if (!$existsDataDirectory) {
$existsDataDirectory = api_create_protected_dir('data', $sysPath);
}
$fileDir = "badges/";
$fileName = sha1($_POST['name']);
$existsBadgesDirectory = is_dir($sysDataPath . 'badges/');
$badgePath = api_get_path(SYS_UPLOAD_PATH).'badges/';
$existsBadgesDirectory = is_dir($badgePath);
if (!$existsBadgesDirectory) {
$existsBadgesDirectory = api_create_protected_dir('badges', $sysDataPath);
$existsBadgesDirectory = api_create_protected_dir('badges', api_get_path(SYS_UPLOAD_PATH));
}
if ($existsBadgesDirectory) {
if (!empty($skill['icon'])) {
$iconFileAbsolutePath = $sysDataPath . $skill['icon'];
$iconDirAbsolutePath = $sysDataPath . $fileDir;
if (Security::check_abs_path($iconFileAbsolutePath, $iconDirAbsolutePath)) {
unlink($sysDataPath . $skill['icon']);
}
/*if (!empty($skill['icon'])) {
$iconFileAbsolutePath = $badgePath . $skill['icon'];
if (Security::check_abs_path($iconFileAbsolutePath, $badgePath)) {
unlink($badgePath . $skill['icon']);
}
}*/
$skillImagePath = sprintf("%s%s%s.png", $sysDataPath, $fileDir, $fileName);
$skillImagePath = sprintf("%s%s.png", $badgePath, $fileName);
$skillImage = new Image($_FILES['image']['tmp_name']);
$skillImage->send_image($skillImagePath, -1, 'png');
$skillThumbPath = sprintf("%s%s%s-small.png", $sysDataPath, $fileDir, $fileName);
$skillThumbPath = sprintf("%s%s-small.png", $badgePath, $fileName);
$skillImageThumb = new Image($skillImagePath);
$skillImageThumb->resize(ICON_SIZE_BIG, ICON_SIZE_BIG);
$skillImageThumb->send_image($skillThumbPath);
$params['icon'] = sprintf("%s%s.png", $fileDir, $fileName);
$params['icon'] = sprintf("%s.png", $fileName);
} else {
Session::write('errorMessage', get_lang('UplUnableToSaveFile'));
}

@ -1,11 +1,12 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Show information about Mozilla OpenBadges
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @package chamilo.admin.openbadges
*/
use \ChamiloSession as Session;
use ChamiloSession as Session;
$cidReset = true;

@ -17,7 +17,7 @@ $skill = $objSkill->get($skillId);
$json = array(
'name' => $skill['name'],
'description' => $skill['description'],
'image' => api_get_path(WEB_DATA_PATH) . $skill['icon'],
'image' => api_get_path(WEB_UPLOAD_PATH) . $skill['icon'],
'criteria' => api_get_path(WEB_CODE_PATH) . "badge/criteria.php?id=$skillId",
'issuer' => api_get_path(WEB_CODE_PATH) . "badge/issuer.php",
);

@ -274,6 +274,8 @@ define('WEB_PATH', 'WEB_PATH');
define('SYS_PATH', 'SYS_PATH');
define('SYS_APP_PATH', 'SYS_APP_PATH');
define('SYS_UPLOAD_PATH', 'SYS_UPLOAD_PATH');
define('WEB_UPLOAD_PATH', 'WEB_UPLOAD_PATH');
define('REL_PATH', 'REL_PATH');
define('WEB_SERVER_ROOT_PATH', 'WEB_SERVER_ROOT_PATH');
define('SYS_SERVER_ROOT_PATH', 'SYS_SERVER_ROOT_PATH');
@ -303,8 +305,6 @@ define('WEB_TEMPLATE_PATH', 'WEB_TEMPLATE_PATH');
define('SYS_TEMPLATE_PATH', 'SYS_TEMPLATE_PATH');
define('WEB_FONTS_PATH', 'WEB_FONTS_PATH');
define('SYS_FONTS_PATH', 'SYS_FONTS_PATH');
define('SYS_DATA_PATH', 'SYS_DATA_PATH');
define('WEB_DATA_PATH', 'WEB_DATA_PATH');
define('SYS_DEFAULT_COURSE_DOCUMENT_PATH', 'SYS_DEFAULT_COURSE_DOCUMENT_PATH');
define('REL_DEFAULT_COURSE_DOCUMENT_PATH', 'REL_DEFAULT_COURSE_DOCUMENT_PATH');
@ -580,11 +580,9 @@ require_once __DIR__.'/internationalization.lib.php';
* api_get_path(SYS_PATH) /var/www/chamilo/
* api_get_path(SYS_APP_PATH) /var/www/chamilo/app/
* api_get_path(SYS_UPLOAD_PATH) /var/www/chamilo/app/upload/
*
* api_get_path(SYS_ARCHIVE_PATH) /var/www/chamilo/app/cache
* api_get_path(SYS_COURSE_PATH) /var/www/chamilo/app/courses/
* api_get_path(SYS_CODE_PATH) /var/www/chamilo/main/
* api_get_path(SYS_DATA_PATH) /var/www/chamilo/data/
* api_get_path(INCLUDE_PATH) /var/www/chamilo/main/inc/
* api_get_path(LIBRARY_PATH) /var/www/chamilo/main/inc/lib/
* api_get_path(CONFIGURATION_PATH) /var/www/chamilo/main/inc/conf/
@ -598,7 +596,6 @@ require_once __DIR__.'/internationalization.lib.php';
* api_get_path(WEB_PATH) http://www.mychamilo.org/chamilo/
* api_get_path(WEB_COURSE_PATH) http://www.mychamilo.org/chamilo/courses/
* api_get_path(WEB_CODE_PATH) http://www.mychamilo.org/chamilo/main/
* api_get_path(WEB_DATA_PATH) http://www.mychamilo.org/chamilo/data/
* api_get_path(WEB_PLUGIN_PATH) http://www.mychamilo.org/chamilo/plugin/
* api_get_path(WEB_ARCHIVE_PATH) http://www.mychamilo.org/chamilo/app/cache/
* api_get_path(WEB_IMG_PATH) http://www.mychamilo.org/chamilo/main/img/
@ -606,6 +603,8 @@ require_once __DIR__.'/internationalization.lib.php';
* api_get_path(WEB_LIBRARY_PATH) http://www.mychamilo.org/chamilo/main/inc/lib/
* api_get_path(WEB_LIBRARY_JS_PATH) http://www.mychamilo.org/chamilo/web/Chamilo/javascript
* api_get_path(WEB_TEMPLATE_PATH) http://www.mychamilo.org/chamilo/main/template/
* api_get_path(WEB_UPLOAD_PATH) http://www.mychamilo.org/chamilo/app/upload/
*
*
*
* This is how we retrieve paths of "registerd" resource files (scripts, players, etc.):
@ -626,14 +625,12 @@ require_once __DIR__.'/internationalization.lib.php';
function api_get_path($path_type, $path = null)
{
static $paths = array(
SYS_DATA_PATH => '',
WEB_PATH => '',
SYS_PATH => '',
REL_PATH => '',
WEB_SERVER_ROOT_PATH => '',
SYS_SERVER_ROOT_PATH => '',
WEB_COURSE_PATH => '',
WEB_DATA_PATH => '',
SYS_COURSE_PATH => '',
REL_COURSE_PATH => '',
REL_CODE_PATH => '',
@ -657,6 +654,7 @@ function api_get_path($path_type, $path = null)
WEB_AJAX_PATH => 'inc/ajax/',
SYS_TEST_PATH => 'tests/',
WEB_TEMPLATE_PATH => 'template/',
WEB_UPLOAD_PATH => 'app/upload/',
SYS_TEMPLATE_PATH => 'template/',
WEB_FONTS_PATH => 'fonts/',
SYS_FONTS_PATH => 'fonts/',
@ -759,8 +757,6 @@ function api_get_path($path_type, $path = null)
$paths[REL_CODE_PATH] = $root_rel.$code_folder;
$paths[WEB_CODE_PATH] = $root_web.$code_folder;
$paths[SYS_CODE_PATH] = $root_sys.$code_folder;
$paths[SYS_DATA_PATH] = $root_sys.$data_folder;
$paths[WEB_DATA_PATH] = $root_web.$data_folder;
$paths[WEB_DEFAULT_COURSE_DOCUMENT_PATH] = $paths[WEB_CODE_PATH].'default_course_document/';
$paths[REL_DEFAULT_COURSE_DOCUMENT_PATH] = $paths[REL_PATH].'main/default_course_document/';
@ -790,6 +786,7 @@ function api_get_path($path_type, $path = null)
$paths[WEB_ARCHIVE_PATH] = $paths[WEB_PATH].$paths[WEB_ARCHIVE_PATH];
$paths[WEB_TEMPLATE_PATH] = $paths[WEB_CODE_PATH].$paths[WEB_TEMPLATE_PATH];
$paths[WEB_UPLOAD_PATH] = $paths[WEB_PATH].$paths[WEB_UPLOAD_PATH];
$paths[INCLUDE_PATH] = $paths[SYS_CODE_PATH].$paths[INCLUDE_PATH];
$paths[LIBRARY_PATH] = $paths[SYS_CODE_PATH].$paths[LIBRARY_PATH];
@ -812,8 +809,7 @@ function api_get_path($path_type, $path = null)
WEB_PLUGIN_PATH => 'plugin/',
WEB_ARCHIVE_PATH => 'archive/',
WEB_LIBRARY_PATH => 'inc/lib/',
WEB_AJAX_PATH => 'inc/ajax/',
WEB_DATA_PATH => '',
WEB_AJAX_PATH => 'inc/ajax/'
);
$root_web = api_add_trailing_slash($root_web);
@ -825,7 +821,6 @@ function api_get_path($path_type, $path = null)
$paths[WEB_SERVER_ROOT_PATH] = $server_base_web.'/';
$paths[WEB_COURSE_PATH] = $root_web.$course_folder;
$paths[WEB_CODE_PATH] = $root_web.$code_folder;
$paths[WEB_DATA_PATH] = $root_web.$data_folder;
$paths[WEB_IMG_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_IMG_PATH];
$paths[WEB_CSS_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_CSS_PATH];

@ -960,7 +960,7 @@ class GroupPortalManager
break;
case 'web': // Base: absolute web path.
default:
$base = api_get_path(WEB_PATH).'app/uploads/';
$base = api_get_path(WEB_UPLOAD_PATH);
break;
}

@ -6,19 +6,20 @@
* @package chamilo.include.image
* @todo move in a DB configuration setting
*/
/**
* Code
*/
define('IMAGE_PROCESSOR', 'gd'); // imagick or gd strings
/**
* Image class
* @package chamilo.include.image
*/
class Image {
var $image_wrapper = null;
function __construct($path) {
$path = preg_match(VALID_WEB_PATH, $path) ? (api_is_internal_path($path) ? api_get_path(TO_SYS, $path) : $path) : $path;
class Image
{
public $image_wrapper = null;
function __construct($path)
{
$path = preg_match(VALID_WEB_PATH, $path) ? (api_is_internal_path(
$path
) ? api_get_path(TO_SYS, $path) : $path) : $path;
if (IMAGE_PROCESSOR == 'gd') {
$this->image_wrapper = new GDWrapper($path);
} else {
@ -30,16 +31,35 @@ class Image {
}
}
}
public function resize($thumbw, $thumbh, $border = 0, $specific_size = false) {
public function resize(
$thumbw,
$thumbh,
$border = 0,
$specific_size = false
) {
$this->image_wrapper->resize($thumbw, $thumbh, $border, $specific_size);
}
public function send_image($file = '', $compress = -1, $convert_file_to = null) {
return $this->image_wrapper->send_image($file, $compress, $convert_file_to);
public function send_image(
$file = '',
$compress = -1,
$convert_file_to = null
) {
return $this->image_wrapper->send_image(
$file,
$compress,
$convert_file_to
);
}
public function get_image_size() {
public function get_image_size()
{
return $this->image_wrapper->get_image_size();
}
public function get_image_info() {
public function get_image_info()
{
return $this->image_wrapper->get_image_info();
}
}
@ -196,7 +216,8 @@ class GDWrapper extends ImageWrapper {
parent::__construct($path);
}
public function set_image_wrapper() {
public function set_image_wrapper()
{
$handler = null;
$this->fill_image_info();
@ -225,7 +246,8 @@ class GDWrapper extends ImageWrapper {
}
}
public function get_image_size() {
public function get_image_size()
{
$return_array = array('width'=>0,'height'=>0);
if ($this->image_validated) {
$return_array = array('width'=>$this->width,'height'=>$this->height);
@ -233,7 +255,8 @@ class GDWrapper extends ImageWrapper {
return $return_array;
}
public function fill_image_info() {
public function fill_image_info()
{
if (file_exists($this->path)) {
$image_info = getimagesize($this->path);
$this->width = $image_info[0];
@ -246,7 +269,8 @@ class GDWrapper extends ImageWrapper {
}
}
public function resize($thumbw, $thumbh, $border, $specific_size = false) {
public function resize($thumbw, $thumbh, $border, $specific_size = false)
{
if (!$this->image_validated) return false;
if ($border == 1) {
if ($specific_size) {
@ -322,60 +346,5 @@ class GDWrapper extends ImageWrapper {
}
// TODO: Occupied memory is not released, because the following fragment of code is actually dead.
@imagedestroy($this->bg);
//@imagedestroy($this->logo);
}
/*
* @deprecated
*
function addlogo($file) {
$this->logo = image::createimagefromtype($file, 'logo');
@imagealphablending($this->logo , true);
$size = api_getimagesize($file);
$this->logox = $size['width'];
$this->logoy = $size['height'];
}*/
/* @deprecated
function addtext ($text, $x = 0, $y = 0, $size = 12, $angle = 0) {
putenv('GDFONTPATH=' . realpath('.'));
$this->fontfile='verdana';
$text= preg_replace('`(?<!\r)\n`', "\r\n", $text);
$box = @imagettfbbox($size, $angle, $this->fontfile, $text);
if ($x < 0) {
$x = $this->width - max($box[2], $box[4]) + $x;
} else {
$x = max(-$box[0], -$box[6]) + $x;
}
if ($y < 0) {
$y = $this->height - max($box[1], $box[3]) + $y;
} else {
$y = max(-$box[7], -$box[5]) + $y;
}
@imagettftext($this->bg, $size, $angle, $x, $y, $this->color, $this->fontfile , $text);
}
*/
/* //@deprecated
function mergelogo($x, $y, $alpha = 100) {
if ($x < 0) $x = $this->width - $this->logox + $x;
if ($y < 0) $y = $this->height - $this->logoy + $y;
return @imagecopymerge($this->bg, $this->logo, $x, $y, 0, 0, $this->logox, $this->logoy, $alpha);
}*/
/* //@deprecated
function makecolor($red, $green, $blue) {
$this->color = @imagecolorallocate($this->bg, $red, $green, $blue);
}
*/
/* //@deprecated
function setfont($fontfile) {
$this->fontfile = $fontfile;
}*/
}

@ -3,8 +3,10 @@
/**
* Class Model
* This class provides basic methods to implement a CRUD for a new table in the database see examples in: career.lib.php and promotion.lib.php
* This class provides basic methods to implement a CRUD for a new table in the
* database see examples in: career.lib.php and promotion.lib.php
* Include/require it in your code to use its features.
*
* @package chamilo.library
*/
class Model
@ -14,6 +16,9 @@ class Model
public $required;
public $is_course_model = false;
/**
* Constructor
*/
public function __construct()
{
}
@ -37,6 +42,9 @@ class Model
/**
* Deletes an item
* @param int $id
*
* @return bool
*/
public function delete($id)
{
@ -53,11 +61,13 @@ class Model
if ($result != 1) {
return false;
}
return true;
}
/**
* @param array $params
*
* @return array
*/
private function clean_parameters($params)
@ -70,17 +80,22 @@ class Model
}
}
}
return $clean_params;
}
/**
* Displays the title + grid
*/
public function display() {
public function display()
{
}
/**
* Gets an element
* @param int $id
*
* @return array|mixed
*/
public function get($id)
{
@ -92,12 +107,19 @@ class Model
$course_id = api_get_course_int_id();
$params = array('id = ? AND c_id = ?' => array($id, $course_id));
}
$result = Database::select('*',$this->table, array('where' => $params),'first');
$result = Database::select(
'*',
$this->table,
array('where' => $params),
'first'
);
return $result;
}
/**
* @param array $options
*
* @return array
*/
public function get_all($options = null)
@ -120,7 +142,13 @@ class Model
*/
public function get_count()
{
$row = Database::select('count(*) as count', $this->table, array('where' => array('parent_id = ?' => '0')),'first');
$row = Database::select(
'count(*) as count',
$this->table,
array('where' => array('parent_id = ?' => '0')),
'first'
);
return $row['count'];
}
@ -178,6 +206,7 @@ class Model
/**
* Updates the obj in the database. The $params['id'] must exist in order to update a record
* @param array $params
*
* @return bool
*
*/
@ -210,6 +239,7 @@ class Model
}
}
}
return false;
}
}

@ -441,7 +441,7 @@ class Template
'web_img' => api_get_path(WEB_IMG_PATH),
'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
'web_lib' => api_get_path(WEB_LIBRARY_PATH),
'web_data' => api_get_path(WEB_DATA_PATH),
'web_upload' => api_get_path(WEB_UPLOAD_PATH),
'web_self' => api_get_self(),
'web_query_vars' => api_htmlentities($_SERVER['QUERY_STRING']),
'web_self_query_vars' => api_htmlentities($_SERVER['REQUEST_URI']),

@ -1296,7 +1296,7 @@ class UserManager
$userPath = api_get_path(SYS_UPLOAD_PATH).$userPath;
break;
case 'web': // Base: absolute web path.
$userPath = api_get_path(WEB_PATH).'app/upload/'.$userPath;
$userPath = api_get_path(WEB_UPLOAD_PATH).$userPath;
break;
}

@ -138,7 +138,8 @@ if (defined('SYSTEM_INSTALLATION')) {
);
$list = scandir($langPath);
foreach ($list as $entry) {
if (is_dir($langPath . $entry) && in_array($entry, $officialLanguages)
if (is_dir($langPath . $entry) &&
in_array($entry, $officialLanguages)
) {
foreach ($filesToDelete as $file) {
if (is_file($langPath . $entry . '/' . $file . '.inc.php')) {
@ -147,6 +148,7 @@ if (defined('SYSTEM_INSTALLATION')) {
}
}
}
// Remove the "main/conference/" directory that wasn't used since years long
// past - see rrmdir function declared below
@rrmdir(api_get_path(SYS_CODE_PATH).'conference');
@ -156,6 +158,24 @@ if (defined('SYSTEM_INSTALLATION')) {
@unlink(api_get_path(LIBRARY_PATH).'events.lib.inc.php');
}
if (is_file(api_get_path(SYS_PATH).'courses/.htaccess')) {
unlink(api_get_path(SYS_PATH).'courses/.htaccess');
}
// Move files and dirs.
$movePathList = [
api_get_path(SYS_CODE_PATH).'upload/users/groups' => api_get_path(SYS_UPLOAD_PATH).'groups',
api_get_path(SYS_CODE_PATH).'upload/users' => api_get_path(SYS_UPLOAD_PATH).'users',
api_get_path(SYS_CODE_PATH).'upload/badges' => api_get_path(SYS_UPLOAD_PATH).'badges',
api_get_path(SYS_PATH).'courses' => api_get_path(SYS_COURSE_PATH),
];
foreach ($movePathList as $origin => $destination) {
if (is_dir($origin)) {
rename($origin, $destination);
}
}
} else {
echo 'You are not allowed here !'. __FILE__;
}

@ -111,7 +111,7 @@
</div>
<p class="openbadges-text">{{'BadgePreview' | get_lang }}</p>
<div class="openbadges-img {{ skill.icon ? '' : 'hide' }}" id="badge-container">
<img id="badge-preview" alt="{{ 'BadgePreview' | get_lang }}" src="{{ skill.icon ? [_p.web_data, skill.icon] | join('') : '' }}">
<img id="badge-preview" alt="{{ 'BadgePreview' | get_lang }}" src="{{ skill.icon ? [_p.web_upload, skill.icon] | join('') : '' }}">
</div>
</div>
</div>

@ -33,8 +33,9 @@
{% if skill.icon is empty %}
<img src="{{ 'badges-default.png' | icon(128) }}" width="50" alt="{{ skill.name }}">
{% else %}
<img src="{{ [_p.web_data, skill.icon] | join('') }}" width="50" alt="{{ skill.name }}">
<img src="{{ [_p.web_upload, 'badges/', skill.icon] | join('') }}" width="50" alt="{{ skill.name }}">
{% endif %}
{{ skill.name }}
</td>
<td>{{ skill.description }}</td>

@ -172,7 +172,7 @@ $(document).ready(function() {
{% if skill.iconThumb is empty %}
<img src="{{ 'badges.png' | icon(32) }}" alt="{{ skill.name }}" title="{{ skill.name }}">
{% else %}
<img src="{{ _p.web_data }}{{ skill.iconThumb }}" alt="{{ skill.name }}" title="{{ skill.name }}">
<img src="{{ _p.web_upload }}{{ skill.iconThumb }}" alt="{{ skill.name }}" title="{{ skill.name }}">
{% endif %}
{% endfor %}
{% endif %}

@ -3,13 +3,12 @@
namespace Chamilo\CoreBundle\Component\Editor;
use Doctrine\ORM\EntityManager;
use Chamilo\UserBundle\Entity\User;
use Chamilo\CoreBundle\Component\Editor\Driver\Driver;
use Chamilo\CoreBundle\Entity\Course;
use Symfony\Component\Translation\Translator;
use Chamilo\UserBundle\Entity\User;
use Symfony\Component\Routing\Router;
use Chamilo\CoreBundle\Component\Editor\Driver\Driver;
use Symfony\Component\Translation\Translator;
//use Symfony\Component\Security\Core\SecurityContext;
/**
@ -51,7 +50,7 @@ class Connector
$this->paths = array(
'root_sys' => api_get_path(SYS_PATH),
'sys_root' => api_get_path(SYS_PATH), // just an alias
'sys_data_path' => api_get_path(SYS_COURSE_PATH),
'sys_course_path' => api_get_path(SYS_COURSE_PATH),
// 'sys_config_path' => $app['path.config'],
'path.temp' => api_get_path(SYS_ARCHIVE_PATH),
//'sys_log_path' => $app['path.logs']

@ -111,10 +111,9 @@ class CourseDriver extends Driver implements DriverInterface
{
$url = null;
if ($this->allow()) {
//$directory = $this->connector->course->getDirectory();
$directory = $this->connector->course['directory'];
$dataPath = $this->connector->paths['sys_data_path'];
$url = $dataPath.$directory.'/document/';
$coursePath = $this->connector->paths['sys_course_path'];
$url = $coursePath.$directory.'/document/';
}
return $url;

Loading…
Cancel
Save