* @todo better organization of the class, methods and variables * * */ use \ChamiloSession as Session; use Silex\Application; class Template { private $app; public $preview_theme = null; public $theme; // the chamilo theme public_admin, chamilo, chamilo_red, etc public $title = null; public $show_header; public $show_footer; public $help; public $menu_navigation = array(); public $show_learnpath = false; // This is a learnpath section or not? public $plugin = null; public $course_id = null; public $user_is_logged_in = false; public $twig = null; public $jquery_ui_theme; public $force_plugin_load = true; public $navigation_array; public $loadBreadcrumb = true; /** @var Symfony\Component\Security\Core\SecurityContext */ private $security; /** * @param Application $app */ public function __construct(Application $app, $database, $security) { $this->app = &$app; $this->security = $security; $this->app['classic_layout'] = true; $this->navigation_array = $this->returnNavigationArray(); // Just in case global $tool_name; // Page title $this->title = isset($app['title']) ? $app['title'] : $tool_name; $this->show_learnpath = $app['template.show_learnpath']; /* Current themes: cupertino, smoothness, ui-lightness. Find the themes folder in main/inc/lib/javascript/jquery-ui */ $this->jquery_ui_theme = 'smoothness'; // Setting system variables. $this->setSystemParameters(); // Setting user variables. $this->setUserParameters(); // Setting course variables. $this->setCourseParameters(); // header and footer are showed by default $this->setFooter($app['template.show_footer']); $this->setHeader($app['template.show_header']); $this->setHeaderParameters(); $this->setFooterParameters(); $this->assign('style', $app['template_style']); //Chamilo plugins if ($this->show_header) { if ($app['template.load_plugins'] && !empty($app['plugins'])) { $this->plugin = new AppPlugin(); //1. Showing installed plugins in regions $plugin_regions = $this->plugin->get_plugin_regions(); foreach ($plugin_regions as $region) { $this->set_plugin_region($region); } //2. Loading the course plugin info global $course_plugin; if (isset($course_plugin) && !empty($course_plugin) && !empty($this->course_id)) { //Load plugin get_langs $this->plugin->load_plugin_lang_variables($course_plugin); } } } } /** * @param array $interbreadcrumb */ public function setBreadcrumb($interbreadcrumb) { if (isset($this->app['breadcrumb']) && !empty($this->app['breadcrumb'])) { if (empty($interbreadcrumb)) { $interbreadcrumb = $this->app['breadcrumb']; } else { $interbreadcrumb = array_merge($interbreadcrumb, $this->app['breadcrumb']); } } if (!empty($interbreadcrumb)) { $this->app['breadcrumb'] = $interbreadcrumb; } } /** * Get icon path * @param string $image * @param int $size * * @return string */ public static function get_icon_path($image, $size = ICON_SIZE_SMALL) { return Display:: return_icon($image, '', array(), $size, false, true); } /** * Format date * @param string $timestamp * @param string $format * * @return string */ public static function format_date($timestamp, $format = null) { return api_format_date($timestamp, $format); } /** * @param string $help_input */ public function setHelp($help_input = null) { if (!empty($help_input)) { $help = $help_input; } else { $help = $this->help; } $this->assign('help_content', $help); } /** * Use template system to parse the actions menu * @todo finish it! * @param array $actions * **/ public function setActions($actions) { $action_string = ''; if (!empty($actions)) { foreach ($actions as $action) { $action_string .= $action; } } $this->assign('actions', $actions); } /** * Shortcut to display a 1 col layout (index.php) * */ public function display_one_col_template() { $tpl = $this->get_template('layout/layout_1_col.tpl'); $this->display($tpl); } /** * Shortcut to display a 2 col layout (userportal.php) * */ public function display_two_col_template() { $tpl = $this->get_template('layout/layout_2_col.tpl'); $this->display($tpl); } /** * Displays an empty template */ public function display_blank_template() { $tpl = $this->get_template('layout/blank.tpl'); $this->display($tpl); } /** * Displays an empty template */ public function display_no_layout_template() { $tpl = $this->get_template('layout/no_layout.tpl'); $this->display($tpl); } /** * Sets the footer visibility * @param bool true if we show the footer */ public function setFooter($status) { $this->show_footer = $status; $this->assign('show_footer', $status); } /** * Sets the header visibility * @param bool true if we show the header */ public function setHeader($status) { $this->show_header = $status; $this->assign('show_header', $status); //Toolbar $show_admin_toolbar = api_get_setting('show_admin_toolbar'); $show_toolbar = 0; switch ($show_admin_toolbar) { case 'do_not_show': break; case 'show_to_admin': if (api_is_platform_admin()) { $show_toolbar = 1; } break; case 'show_to_admin_and_teachers': if (api_is_platform_admin() || api_is_allowed_to_edit()) { $show_toolbar = 1; } break; case 'show_to_all': $show_toolbar = 1; break; } $this->assign('show_toolbar', $show_toolbar); //Only if course is available $show_course_shortcut = null; $show_course_navigation_menu = null; if (!empty($this->course_id) && $this->user_is_logged_in) { if (api_get_setting('show_toolshortcuts') != 'false') { //Course toolbar $show_course_shortcut = CourseHome::show_navigation_tool_shortcuts(); } if (api_get_setting('show_navigation_menu') != 'false') { //Course toolbar $show_course_navigation_menu = CourseHome::show_navigation_menu(); } } $this->assign('show_course_shortcut', $show_course_shortcut); $this->assign('show_course_navigation_menu', $show_course_navigation_menu); } /** * @param string $name * @return string */ public function get_template($name) { return $this->app['template_style'].'/'.$name; } /** Set course parameters */ private function setCourseParameters() { //Setting course id $this->course_id = api_get_course_int_id(); $this->app['course_code'] = api_get_course_id(); $this->app['session_id'] = api_get_session_id(); } /** * Set user parameters */ private function setUserParameters() { $user_info = array(); $user_info['logged'] = 0; $this->user_is_logged_in = false; $user_info = isset($this->app['current_user']) ? $this->app['current_user'] : null; if (api_user_is_login() && !empty($user_info)) { $user_info['logged'] = 1; $user_info['is_admin'] = 0; if (api_is_platform_admin()) { $user_info['is_admin'] = 1; } $new_messages = MessageManager::get_new_messages(); $user_info['messages_count'] = $new_messages != 0 ? Display::label($new_messages, 'warning') : null; /*$usergroup = new UserGroup(); $messages_invitations_count = $usergroup->get_groups_by_user_count($user_info['user_id'], GROUP_USER_PERMISSION_PENDING_INVITATION, false); $user_info['messages_invitations_count'] = $messages_invitations_count != 0 ? Display::label( $messages_invitations_count, 'warning' ) : null;*/ $this->user_is_logged_in = true; } //Setting the $_u array that could be use in any template $this->assign('_u', $user_info); } /** * Set system parameters */ private function setSystemParameters() { global $_configuration; //Setting app paths/URLs $_p = array( 'web' => api_get_path(WEB_PATH), 'web_course' => api_get_path(WEB_COURSE_PATH), 'web_main' => api_get_path(WEB_CODE_PATH), 'web_css' => api_get_path(WEB_CSS_PATH), 'web_ajax' => api_get_path(WEB_AJAX_PATH), 'web_img' => api_get_path(WEB_IMG_PATH), 'web_plugin' => api_get_path(WEB_PLUGIN_PATH), 'web_lib' => api_get_path(WEB_LIBRARY_PATH), 'public_web' => api_get_path(WEB_PUBLIC_PATH) ); $this->assign('_p', $_p); //Here we can add system parameters that can be use in any template $_s = array( 'software_name' => api_get_software_name(), 'system_version' => $_configuration['system_version'], 'site_name' => api_get_setting('siteName'), 'institution' => api_get_setting('Institution') ); $this->assign('_s', $_s); } /** * Set theme, include CSS files */ private function setCssFiles() { global $disable_js_and_css_files; $css = array(); $this->theme = api_get_visual_theme(); if (isset($_POST['style']) && api_is_platform_admin()) { $this->preview_theme = $_POST['style']; } if (!empty($this->preview_theme)) { $this->theme = $this->preview_theme; } $this->app['theme'] = $this->theme; $cssPath = api_get_path(WEB_CSS_PATH); // Loads only 1 css file if ($this->app['assetic.enabled']) { $css[] = api_get_path(WEB_PUBLIC_PATH).'css/'.$this->theme.'/style.css'; } else { // Base CSS. $css[] = api_get_cdn_path($cssPath.'base.css'); // Default theme CSS. $css[] = api_get_cdn_path($cssPath.$this->theme.'/default.css'); $css[] = api_get_cdn_path($cssPath.'bootstrap-responsive.css'); $css[] = api_get_cdn_path($cssPath.'responsive.css'); // Extra CSS files. if ($this->show_learnpath) { $css[] = $cssPath.$this->theme.'/learnpath.css'; $css[] = $cssPath.$this->theme.'/scorm.css'; } if (api_is_global_chat_enabled()) { $css[] = api_get_path(WEB_LIBRARY_PATH).'javascript/chat/css/chat.css'; } $css[] = api_get_path(WEB_LIBRARY_PATH).'javascript/jquery-ui/'.$this->jquery_ui_theme.'/jquery-ui-custom.css'; $css[] = api_get_path(WEB_LIBRARY_PATH).'javascript/jquery-ui/default.css'; } $css[] = api_get_cdn_path($cssPath.'font_awesome/css/font-awesome.css'); $css[] = api_get_path(WEB_LIBRARY_PATH).'javascript/thickbox.css'; $css[] = api_get_path(WEB_LIBRARY_PATH).'javascript/chosen/chosen.css'; $css_file_to_string = null; foreach ($css as $file) { $css_file_to_string .= api_get_css($file); } // @todo move this somewhere else. Special fix when using tablets in order to see the text near icons if (SHOW_TEXT_NEAR_ICONS == true) { //hack in order to fix the actions buttons $css_file_to_string .= ''; } $navigator_info = api_get_navigator(); if ($navigator_info['name'] == 'Internet Explorer' && $navigator_info['version'] == '6') { $css_file_to_string .= 'img, div { behavior: url('.api_get_path( WEB_LIBRARY_PATH ).'javascript/iepngfix/iepngfix.htc) } '."\n"; } if (!$disable_js_and_css_files) { $this->assign('css_file_to_string', $css_file_to_string); $style_print = api_get_css(api_get_cdn_path($cssPath.$this->theme.'/print.css'), 'print'); $this->assign('css_style_print', $style_print); } } /** * @param array $htmlHeadXtra */ public function addJsFiles($htmlHeadXtra = array()) { $extra_headers = null; if (isset($htmlHeadXtra) && $htmlHeadXtra) { foreach ($htmlHeadXtra as $this_html_head) { $extra_headers .= $this_html_head."\n"; } } if (isset($this->app['extraJS'])) { foreach ($this->app['extraJS'] as $this_html_head) { $extra_headers .= $this_html_head."\n"; } } $this->assign('extra_headers', $extra_headers); } /** * Sets JS files */ private function setJsFiles() { global $disable_js_and_css_files, $htmlHeadXtra; $jsFolder = api_get_path(WEB_LIBRARY_PATH).'javascript/'; if ($this->app['assetic.enabled']) { $js_files = array( api_get_path(WEB_PATH).'web/js/script.js', $jsFolder.'chosen/chosen.jquery.min.js', $jsFolder.'thickbox.js', $jsFolder.'ckeditor/ckeditor.js', ); } else { //JS files $js_files = array( $jsFolder.'modernizr.js', $jsFolder.'jquery.min.js', $jsFolder.'chosen/chosen.jquery.min.js', $jsFolder.'jquery-ui/'.$this->jquery_ui_theme.'/jquery-ui-custom.min.js', //$jsFolder.'jquery-ui/jquery.ui.touch-punch.js', $jsFolder.'thickbox.js', $jsFolder.'ckeditor/ckeditor.js', //$jsFolder.'tinymce/tinymce.min.js', $jsFolder.'bootstrap/bootstrap.js', ); } if (api_is_global_chat_enabled()) { //Do not include the global chat in LP if ($this->show_learnpath == false && $this->show_footer == true && $this->app['template.hide_global_chat'] == false) { $js_files[] = $jsFolder.'chat/js/chat.js'; } } if (api_get_setting('accessibility_font_resize') == 'true') { $js_files[] = $jsFolder.'fontresize.js'; } if (api_get_setting('include_asciimathml_script') == 'true') { $js_files[] = $jsFolder.'asciimath/ASCIIMathML.js'; } if (api_get_setting('disable_copy_paste') == 'true') { $js_files[] = $jsFolder.'jquery.nocutcopypaste.js'; } $js_file_to_string = null; foreach ($js_files as $js_file) { $js_file_to_string .= api_get_js_simple($js_file); } // Loading email_editor js. if (!api_is_anonymous() && api_get_setting('allow_email_editor') == 'true') { $js_file_to_string .= $this->fetch($this->app['template_style'].'/mail_editor/email_link.js.tpl'); } if (!$disable_js_and_css_files) { $this->assign('js_file_to_string', $js_file_to_string); $extra_headers = null; if (isset($htmlHeadXtra) && $htmlHeadXtra) { foreach ($htmlHeadXtra as $this_html_head) { $extra_headers .= $this_html_head."\n"; } } if (isset($this->app['extraJS'])) { foreach ($this->app['extraJS'] as $this_html_head) { $extra_headers .= $this_html_head."\n"; } } $this->assign('extra_headers', $extra_headers); } } /** * Set header parameters */ private function setHeaderParameters() { $_course = api_get_course_info(); $_configuration = $this->app['configuration']; $this_section = $this->app['this_section']; $nameTools = $this->title; $navigation = $this->navigation_array; $this->menu_navigation = $navigation['menu_navigation']; $this->assign('system_charset', api_get_system_encoding()); $this->assign('online_button', Display::return_icon('online.png')); $this->assign('offline_button', Display::return_icon('offline.png')); // Get language iso-code for this page - ignore errors $this->assign('document_language', api_get_language_isocode()); $course_title = isset($_course['name']) ? $_course['name'] : null; $title_list = array(); $title_list[] = api_get_setting('Institution'); $title_list[] = api_get_setting('siteName'); if (!empty($course_title)) { $title_list[] = $course_title; } if ($nameTools != '') { $title_list[] = $nameTools; } $title_string = ''; for ($i = 0; $i < count($title_list); $i++) { $title_string .= $title_list[$i]; if (isset($title_list[$i + 1])) { $item = trim($title_list[$i + 1]); if (!empty($item)) { $title_string .= ' - '; } } } $this->assign('title_string', $title_string); //Setting the theme and CSS files $this->setCssFiles(); $this->setJsFiles(); // Implementation of prefetch. // See http://cdn.chamilo.org/main/img/online.png for details $prefetch = ''; if (!empty($_configuration['cdn_enable'])) { $prefetch .= ''; foreach ($_configuration['cdn'] as $host => $exts) { $prefetch .= ''; } } $this->assign('prefetch', $prefetch); $this->assign('text_direction', api_get_text_direction()); $this->assign('section_name', 'section-'.$this_section); $favico = ''; if (isset($_configuration['multiple_access_urls']) && $_configuration['multiple_access_urls']) { $access_url_id = api_get_current_access_url_id(); if ($access_url_id != -1) { $url_info = api_get_current_access_url_info(); $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url'])); $clean_url = api_replace_dangerous_char($url); $clean_url = str_replace('/', '-', $clean_url); $clean_url .= '/'; $homep = api_get_path(REL_PATH).'home/'.$clean_url; //homep for Home Path $icon_real_homep = api_get_path(SYS_PATH).'home/'.$clean_url; //we create the new dir for the new sites if (is_file($icon_real_homep.'favicon.ico')) { $favico = ''; } } } $this->assign('favico', $favico); $this->setHelp(); $notification = $this->returnNotificationMenu(); $this->assign('notification_menu', $notification); // Preparing values for the menu // Profile link. $this->assign('is_profile_editable', api_is_profile_readable()); $profile_link = null; if (api_get_setting('allow_social_tool') == 'true') { $profile_link = ''.get_lang('Profile').''; } else { if (api_is_profile_readable()) { $profile_link = ''.get_lang('Profile').''; } } $this->assign('profile_link', $profile_link); // Message link. $message_link = null; if (api_get_setting('allow_message_tool') == 'true') { $message_link = ''.get_lang('Inbox').''; } $this->assign('message_link', $message_link); $institution = api_get_setting('Institution'); $portal_name = empty($institution) ? api_get_setting('siteName') : $institution; $this->assign('portal_name', $portal_name); // Menu. $menu = $this->returnMenu(); $this->assign('menu', $menu); // Breadcrumb if ($this->loadBreadcrumb) { $this->loadBreadcrumbToTemplate(); } // Extra content $extra_header = null; if (!api_is_platform_admin()) { $extra_header = trim(api_get_setting('header_extra_content')); } $this->assign('header_extra_content', $extra_header); } /** * */ public function loadBreadcrumbToTemplate() { if (api_get_setting('breadcrumb_navigation_display') == 'false') { return; } $breadcrumb = $this->returnBreadcrumb(); $this->assign('breadcrumb', $breadcrumb); } /** * Set footer parameters */ private function setFooterParameters() { //Show admin data //$this->assign('show_administrator_data', api_get_setting('show_administrator_data')); if (api_get_setting('show_administrator_data') == 'true') { //Administrator name $administrator_data = get_lang('Manager').' : '.Display::encrypted_mailto_link( api_get_setting('emailAdministrator'), api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname')) ); $this->assign('administrator_name', $administrator_data); } //Loading footer extra content if (!api_is_platform_admin()) { $extra_footer = trim(api_get_setting('footer_extra_content')); if (!empty($extra_footer)) { $this->assign('footer_extra_content', $extra_footer); } } $courseId = api_get_course_int_id(); //Tutor name if (api_get_setting('show_tutor_data') == 'true') { // Course manager $id_session = api_get_session_id(); if (isset($courseId) && $courseId != -1 && !empty($courseId)) { $tutor_data = ''; if ($id_session != 0) { $coachs_email = CourseManager::get_email_of_tutor_to_session($id_session, $courseId); $email_link = array(); foreach ($coachs_email as $coach) { $email_link[] = Display::encrypted_mailto_link($coach['email'], $coach['complete_name']); } if (count($coachs_email) > 1) { $tutor_data .= get_lang('Coachs').' : '; $tutor_data .= ArrayClass::array_to_string($email_link, CourseManager::USER_SEPARATOR); } elseif (count($coachs_email) == 1) { $tutor_data .= get_lang('Coach').' : '; $tutor_data .= ArrayClass::array_to_string($email_link, CourseManager::USER_SEPARATOR); } elseif (count($coachs_email) == 0) { $tutor_data .= ''; } } $this->assign('session_teachers', $tutor_data); } } if (api_get_setting('show_teacher_data') == 'true') { // course manager if (isset($courseId) && $courseId != -1 && !empty($courseId)) { $courseInfo = api_get_course_info(); $teacher_data = null; $label = get_lang('Teacher'); if (count($courseInfo['teacher_list']) > 1) { $label = get_lang('Teachers'); } $teacher_data .= $label.' : '.$courseInfo['teacher_list_formatted']; $this->assign('teachers', $teacher_data); } } } public function manageDisplay($content) { //$this->assign('content', $content); } /** * Sets the plugin content in a template variable * @param string */ private function set_plugin_region($plugin_region) { if (!empty($plugin_region)) { $region_content = $this->plugin->load_region($this->app['plugins'], $plugin_region, $this, $this->force_plugin_load); if (!empty($region_content)) { $this->assign('plugin_'.$plugin_region, $region_content); } else { $this->assign('plugin_'.$plugin_region, null); } } } /** * @param string $template * @return mixed */ public function fetch($template = null) { $template = $this->app['twig']->loadTemplate($template); return $template->render(array()); } public function assign($key, $value = null) { if ($this->app['allowed'] == true) { $this->app['twig']->addGlobal($key, $value); } } public function display($template = null) { if (!empty($template)) { $this->app['default_layout'] = $template; } } /** * @return null|string */ public function returnMenu() { $navigation = $this->navigation_array; $navigation = $navigation['navigation']; // Displaying the tabs $lang = api_get_user_language(); // Preparing home folder for multiple urls if (api_get_multiple_access_url()) { $access_url_id = api_get_current_access_url_id(); if ($access_url_id != -1) { $url_info = api_get_current_access_url_info(); $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url'])); $clean_url = api_replace_dangerous_char($url); $clean_url = str_replace('/', '-', $clean_url); $clean_url .= '/'; $homep = api_get_path(SYS_DATA_PATH).'home/'.$clean_url; //homep for Home Path //we create the new dir for the new sites if (!is_dir($homep)) { mkdir($homep, api_get_permissions_for_new_directories()); } } } else { $homep = api_get_path(SYS_PATH).'home/'; } $ext = '.html'; $menutabs = 'home_tabs'; $home_top = ''; if (is_file($homep.$menutabs.'_'.$lang.$ext) && is_readable($homep.$menutabs.'_'.$lang.$ext)) { $home_top = @(string)file_get_contents($homep.$menutabs.'_'.$lang.$ext); } elseif (is_file($homep.$menutabs.$lang.$ext) && is_readable($homep.$menutabs.$lang.$ext)) { $home_top = @(string)file_get_contents($homep.$menutabs.$lang.$ext); } else { //$errorMsg = get_lang('HomePageFilesNotReadable'); } $home_top = api_to_system_encoding($home_top, api_detect_encoding(strip_tags($home_top))); $open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top); $open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open))); $lis = ''; if (!empty($open)) { if (strpos($open, 'show_menu') === false) { if (api_is_anonymous()) { $navigation[SECTION_CAMPUS] = null; } } else { //$lis .= Display::tag('li', $open); $lis .= $open; } } if (count($navigation) > 0 || !empty($lis)) { $pre_lis = ''; foreach ($navigation as $section => $navigation_info) { if (isset($GLOBALS['this_section'])) { $current = $section == $GLOBALS['this_section'] ? ' id="current" class="active" ' : ''; } else { $current = ''; } if (!empty($navigation_info['title'])) { $pre_lis .= '