/** * Converts an html string to PDF * @param string $document_html valid html * @param string $css CSS content of a CSS file * @param string $pdf_name pdf name * @param string $course_code course code * (if you are using html that are located in the document tool you must provide this) * @param string $outputMode the MPDF output mode can be: * 'I' (print on standard output), * 'D' (download file) (this is the default value), * 'F' (save to local file) or * 'S' (return as a string) * @return string Web path */ public function content_to_pdf($document_html, $css = '', $pdf_name = '', $course_code = null, $outputMode = 'D', $saveInFile = false, $fileToSave = null, $returnHtml = false) { global $_configuration; if (empty($document_html)) { return false; } //clean styles and javascript document $clean_search = array('@<script[^>]*?>.*?</script>@si', '@<style[^>]*?>.*?</style>@siU'); // Formatting the pdf $course_data = api_get_course_info($course_code); self::format_pdf($course_data); $document_html = preg_replace($clean_search, '', $document_html); //absolute path for frames.css //TODO: necessary? $absolute_css_path = api_get_path(WEB_CSS_PATH) . api_get_setting('stylesheets') . '/frames.css'; $document_html = str_replace('href="./css/frames.css"', 'href="' . $absolute_css_path . '"', $document_html); $document_html = str_replace('../../', '', $document_html); $document_html = str_replace('../', '', $document_html); $document_html = str_replace((empty($_configuration['url_append']) ? '' : $_configuration['url_append'] . '/') . 'courses/' . $course_code . '/document/', '', $document_html); if (!empty($course_data['path'])) { $document_path = api_get_path(SYS_COURSE_PATH) . $course_data['path'] . '/document/'; $doc = new DOMDocument(); $result = @$doc->loadHTML($document_html); //Fixing only images @todo do the same thing with other elements $elements = $doc->getElementsByTagName('img'); if (!empty($elements)) { foreach ($elements as $item) { $old_src = $item->getAttribute('src'); //$old_src= str_replace('../','',$old_src); if (strpos($old_src, 'http') === false) { if (strpos($old_src, '/main/default_course_document') === false) { if (strpos($old_src, '/main/inc/lib/') === false) { $old_src_fixed = str_replace('/courses/' . $course_data['path'] . '/document/', '', $old_src); $old_src_fixed = str_replace('courses/' . $course_data['path'] . '/document/', '', $old_src_fixed); $new_path = $document_path . $old_src_fixed; $document_html = str_replace($old_src, $new_path, $document_html); } } } } } } //replace relative path by absolute path for resources //$document_html= str_replace('src="/chamilo/main/default_course_document/', 'temp_template_path', $document_html);// before save src templates not apply //$document_html= str_replace('src="/', 'temp_template_path', $document_html);// before save src templates not apply //$document_html= str_replace('src="/chamilo/main/default_course_document/', 'temp_template_path', $document_html);// before save src templates not apply //$src_http_www= 'src="'.api_get_path(WEB_COURSE_PATH).$course_data['path'].'/document/'; //$document_html= str_replace('src="',$src_http_www, $document_html); //$document_html= str_replace('temp_template_path', 'src="/main/default_course_document/', $document_html);// restore src templates api_set_encoding_html($document_html, 'UTF-8'); // The library mPDF expects UTF-8 encoded input data. $title = api_get_title_html($document_html, 'UTF-8', 'UTF-8'); // TODO: Maybe it is better idea the title to be passed through // $_GET[] too, as it is done with file name. // At the moment the title is retrieved from the html document itself. if ($returnHtml) { return "<style>{$css}</style>" . $document_html; } if (!empty($css)) { $this->pdf->WriteHTML($css, 1); } $this->pdf->WriteHTML($document_html, 2); if (empty($pdf_name)) { $output_file = 'pdf_' . date('Y-m-d-his') . '.pdf'; } else { $pdf_name = api_replace_dangerous_char($pdf_name); $output_file = $pdf_name . '.pdf'; } //$this->pdf->Output($output_file, $outputMode); // F to save the pdf in a file if ($outputMode == 'F') { $output_file = api_get_path(SYS_ARCHIVE_PATH) . $output_file; } if ($saveInFile) { $fileToSave = !empty($fileToSave) ? $fileToSave : api_get_path(SYS_ARCHIVE_PATH) . uniqid(); $this->pdf->Output($fileToSave, $outputMode); // F to save the pdf in a file } else { $this->pdf->Output($output_file, $outputMode); // F to save the pdf in a file } if ($outputMode != 'F') { exit; } }
/** * Save the extra fields values * In order to save this function needs a item_id (user id, course id, etc) * This function is used with $extraField->addElements() * @param array $params array for the insertion into the *_field_values table * * @return mixed false on empty params, void otherwise * @assert (array()) === false */ public function saveFieldValues($params) { foreach ($params as $key => $value) { $found = strpos($key, '__persist__'); if ($found) { $tempKey = str_replace('__persist__', '', $key); if (!isset($params[$tempKey])) { $params[$tempKey] = array(); } } } if (empty($params['item_id'])) { return false; } $type = $this->getExtraField()->getExtraFieldType(); // Parse params. foreach ($params as $key => $value) { if (substr($key, 0, 6) == 'extra_' || substr($key, 0, 7) == '_extra_') { // An extra field. $field_variable = substr($key, 6); $extraFieldInfo = $this->getExtraField()->get_handler_field_info_by_field_variable($field_variable); if ($extraFieldInfo) { $commentVariable = 'extra_' . $field_variable . '_comment'; $comment = isset($params[$commentVariable]) ? $params[$commentVariable] : null; switch ($extraFieldInfo['field_type']) { case ExtraField::FIELD_TYPE_TAG: if ($type == EntityExtraField::USER_FIELD_TYPE) { UserManager::delete_user_tags($params['item_id'], $extraFieldInfo['id']); UserManager::process_tags($value, $params['item_id'], $extraFieldInfo['id']); } else { $em = Database::getManager(); $tagValues = is_array($value) ? $value : [$value]; $tags = []; foreach ($tagValues as $tagValue) { $tagsResult = $em->getRepository('ChamiloCoreBundle:Tag')->findBy(['tag' => $tagValue, 'fieldId' => $extraFieldInfo['id']]); if (empty($tagsResult)) { $tag = new \Chamilo\CoreBundle\Entity\Tag(); $tag->setCount(0); $tag->setFieldId($extraFieldInfo['id']); $tag->setTag($tagValue); $tags[] = $tag; } else { $tags = array_merge($tags, $tagsResult); } } foreach ($tags as $tag) { $fieldTags = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')->findBy(['fieldId' => $extraFieldInfo['id'], 'itemId' => $params['item_id'], 'tagId' => $tag->getId()]); foreach ($fieldTags as $fieldTag) { $em->remove($fieldTag); $tag->setCount($tag->getCount() - 1); $em->persist($tag); $em->flush(); } $tag->setCount($tag->getCount() + 1); $em->persist($tag); $em->flush(); $fieldRelTag = new Chamilo\CoreBundle\Entity\ExtraFieldRelTag(); $fieldRelTag->setFieldId($extraFieldInfo['id']); $fieldRelTag->setItemId($params['item_id']); $fieldRelTag->setTagId($tag->getId()); $em->persist($fieldRelTag); $em->flush(); } } break; case ExtraField::FIELD_TYPE_FILE_IMAGE: $dirPermissions = api_get_permissions_for_new_directories(); switch ($this->type) { case 'course': $fileDir = api_get_path(SYS_UPLOAD_PATH) . "courses/"; $fileDirStored = "courses/"; break; case 'session': $fileDir = api_get_path(SYS_UPLOAD_PATH) . "sessions/"; $fileDirStored = "sessions/"; break; case 'user': $fileDir = UserManager::getUserPathById($params['item_id'], 'system'); $fileDirStored = UserManager::getUserPathById($params['item_id'], 'last'); break; } $fileName = ExtraField::FIELD_TYPE_FILE_IMAGE . "_{$params['item_id']}.png"; if (!file_exists($fileDir)) { mkdir($fileDir, $dirPermissions, true); } if ($value['error'] == 0) { $imageExtraField = new Image($value['tmp_name']); $imageExtraField->send_image($fileDir . $fileName, -1, 'png'); $newParams = array('item_id' => $params['item_id'], 'field_id' => $extraFieldInfo['id'], 'value' => $fileDirStored . $fileName, 'comment' => $comment); self::save($newParams); } break; case ExtraField::FIELD_TYPE_FILE: $dirPermissions = api_get_permissions_for_new_directories(); switch ($this->type) { case 'course': $fileDir = api_get_path(SYS_UPLOAD_PATH) . "courses/"; $fileDirStored = "courses/"; break; case 'session': $fileDir = api_get_path(SYS_UPLOAD_PATH) . "sessions/"; $fileDirStored = "sessions/"; break; case 'user': $fileDir = UserManager::getUserPathById($params['item_id'], 'system'); $fileDirStored = UserManager::getUserPathById($params['item_id'], 'last'); break; } $cleanedName = api_replace_dangerous_char($value['name']); $fileName = ExtraField::FIELD_TYPE_FILE . "_{$params['item_id']}_{$cleanedName}"; if (!file_exists($fileDir)) { mkdir($fileDir, $dirPermissions, true); } if ($value['error'] == 0) { moveUploadedFile($value, $fileDir . $fileName); $new_params = array('item_id' => $params['item_id'], 'field_id' => $extraFieldInfo['id'], 'value' => $fileDirStored . $fileName); if ($this->type !== 'session' && $this->type !== 'course') { $new_params['comment'] = $comment; } self::save($new_params); } break; default: $newParams = array('item_id' => $params['item_id'], 'field_id' => $extraFieldInfo['id'], 'value' => $value, 'comment' => $comment); self::save($newParams); } } } } }
} } $ar = Database::fetch_array($result); } } } /* * Export to a CSV file * Force the browser to save the file instead of opening it. */ $len = strlen($title_line . $line); header('Content-type: application/octet-stream'); //header('Content-Type: application/force-download'); header('Content-length: ' . $len); $filename = api_html_entity_decode(str_replace(":", "", str_replace(" ", "_", $title[0] . '_' . $title[1] . '.csv'))); $filename = api_replace_dangerous_char($filename); if (preg_match("/MSIE 5.5/", $_SERVER['HTTP_USER_AGENT'])) { header('Content-Disposition: filename= ' . $filename); } else { header('Content-Disposition: attachment; filename= ' . $filename); } if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) { header('Pragma: '); header('Cache-Control: '); header('Cache-Control: public'); // IE cannot download from sessions without a cache } header('Content-Description: ' . $filename); header('Content-transfer-encoding: binary'); echo api_html_entity_decode($title_line, ENT_COMPAT); echo api_html_entity_decode($line, ENT_COMPAT);
/** * // TODO: The output encoding should be equal to the system encoding. * * Exports the learning path as a SCORM package. This is the main function that * gathers the content, transforms it, writes the imsmanifest.xml file, zips the * whole thing and returns the zip. * * This method needs to be called in PHP5, as it will fail with non-adequate * XML package (like the ones for PHP4), and it is *not* a static method, so * you need to call it on a learnpath object. * @TODO The method might be redefined later on in the scorm class itself to avoid * creating a SCORM structure if there is one already. However, if the initial SCORM * path has been modified, it should use the generic method here below. * @TODO link this function with the export_lp() function in the same class * @param string Optional name of zip file. If none, title of learnpath is * domesticated and trailed with ".zip" * @return string Returns the zip package string, or null if error */ public function scorm_export() { $_course = api_get_course_info(); $course_id = api_get_course_int_id(); $links_to_create = null; // Remove memory and time limits as much as possible as this might be a long process... if (function_exists('ini_set')) { api_set_memory_limit('128M'); ini_set('max_execution_time', 600); } // Create the zip handler (this will remain available throughout the method). $archive_path = api_get_path(SYS_ARCHIVE_PATH); $sys_course_path = api_get_path(SYS_COURSE_PATH); $temp_dir_short = uniqid(); $temp_zip_dir = $archive_path . '/' . $temp_dir_short; $temp_zip_file = $temp_zip_dir . '/' . md5(time()) . '.zip'; $zip_folder = new PclZip($temp_zip_file); $current_course_path = api_get_path(SYS_COURSE_PATH) . api_get_course_path(); $root_path = $main_path = api_get_path(SYS_PATH); $files_cleanup = array(); // Place to temporarily stash the zipfiles. // create the temp dir if it doesn't exist // or do a cleanup befor creating the zipfile. if (!is_dir($temp_zip_dir)) { mkdir($temp_zip_dir, api_get_permissions_for_new_directories()); } else { // Cleanup: Check the temp dir for old files and delete them. $handle = opendir($temp_zip_dir); while (false !== ($file = readdir($handle))) { if ($file != '.' && $file != '..') { unlink("{$temp_zip_dir}/{$file}"); } } closedir($handle); } $zip_files = $zip_files_abs = $zip_files_dist = array(); if (is_dir($current_course_path . '/scorm/' . $this->path) && is_file($current_course_path . '/scorm/' . $this->path . '/imsmanifest.xml')) { // Remove the possible . at the end of the path. $dest_path_to_lp = substr($this->path, -1) == '.' ? substr($this->path, 0, -1) : $this->path; $dest_path_to_scorm_folder = str_replace('//', '/', $temp_zip_dir . '/scorm/' . $dest_path_to_lp); mkdir($dest_path_to_scorm_folder, api_get_permissions_for_new_directories(), true); $zip_files_dist = api_copyr($current_course_path . '/scorm/' . $this->path, $dest_path_to_scorm_folder, array('imsmanifest'), $zip_files); } // Build a dummy imsmanifest structure. Do not add to the zip yet (we still need it). // This structure is developed following regulations for SCORM 1.2 packaging in the SCORM 1.2 Content // Aggregation Model official document, secion "2.3 Content Packaging". $xmldoc = new DOMDocument('1.0'); // We are going to build a UTF-8 encoded manifest. Later we will recode it to the desired (and supported) encoding. $root = $xmldoc->createElement('manifest'); $root->setAttribute('identifier', 'SingleCourseManifest'); $root->setAttribute('version', '1.1'); $root->setAttribute('xmlns', 'http://www.imsproject.org/xsd/imscp_rootv1p1p2'); $root->setAttribute('xmlns:adlcp', 'http://www.adlnet.org/xsd/adlcp_rootv1p2'); $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $root->setAttribute('xsi:schemaLocation', 'http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd'); // Build mandatory sub-root container elements. $metadata = $xmldoc->createElement('metadata'); $md_schema = $xmldoc->createElement('schema', 'ADL SCORM'); $metadata->appendChild($md_schema); $md_schemaversion = $xmldoc->createElement('schemaversion', '1.2'); $metadata->appendChild($md_schemaversion); $root->appendChild($metadata); $organizations = $xmldoc->createElement('organizations'); $resources = $xmldoc->createElement('resources'); // Build the only organization we will use in building our learnpaths. $organizations->setAttribute('default', 'chamilo_scorm_export'); $organization = $xmldoc->createElement('organization'); $organization->setAttribute('identifier', 'chamilo_scorm_export'); // To set the title of the SCORM entity (=organization), we take the name given // in Chamilo and convert it to HTML entities using the Chamilo charset (not the // learning path charset) as it is the encoding that defines how it is stored // in the database. Then we convert it to HTML entities again as the "&" character // alone is not authorized in XML (must be &). // The title is then decoded twice when extracting (see scorm::parse_manifest). $org_title = $xmldoc->createElement('title', api_utf8_encode($this->get_name())); $organization->appendChild($org_title); $folder_name = 'document'; // Removes the learning_path/scorm_folder path when exporting see #4841 $path_to_remove = null; $result = $this->generate_lp_folder($_course); if (isset($result['dir']) && strpos($result['dir'], 'learning_path')) { $path_to_remove = 'document' . $result['dir']; $path_to_replace = $folder_name . '/'; } //Fixes chamilo scorm exports if ($this->ref == 'chamilo_scorm_export') { $path_to_remove = 'scorm/' . $this->path . '/document/'; } // For each element, add it to the imsmanifest structure, then add it to the zip. // Always call the learnpathItem->scorm_export() method to change it to the SCORM format. $link_updates = array(); foreach ($this->items as $index => $item) { if (!in_array($item->type, array(TOOL_QUIZ, TOOL_FORUM, TOOL_THREAD, TOOL_LINK, TOOL_STUDENTPUBLICATION))) { // Get included documents from this item. if ($item->type == 'sco') { $inc_docs = $item->get_resources_from_source(null, api_get_path(SYS_COURSE_PATH) . api_get_course_path() . '/' . 'scorm/' . $this->path . '/' . $item->get_path()); } else { $inc_docs = $item->get_resources_from_source(); } // Give a child element <item> to the <organization> element. $my_item_id = $item->get_id(); $my_item = $xmldoc->createElement('item'); $my_item->setAttribute('identifier', 'ITEM_' . $my_item_id); $my_item->setAttribute('identifierref', 'RESOURCE_' . $my_item_id); $my_item->setAttribute('isvisible', 'true'); // Give a child element <title> to the <item> element. $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8')); $my_item->appendChild($my_title); // Give a child element <adlcp:prerequisites> to the <item> element. $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $this->get_scorm_prereq_string($my_item_id)); $my_prereqs->setAttribute('type', 'aicc_script'); $my_item->appendChild($my_prereqs); // Give a child element <adlcp:maxtimeallowed> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:maxtimeallowed',''); // Give a child element <adlcp:timelimitaction> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:timelimitaction',''); // Give a child element <adlcp:datafromlms> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:datafromlms',''); // Give a child element <adlcp:masteryscore> to the <item> element. $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score()); $my_item->appendChild($my_masteryscore); // Attach this item to the organization element or hits parent if there is one. if (!empty($item->parent) && $item->parent != 0) { $children = $organization->childNodes; $possible_parent =& $this->get_scorm_xml_node($children, 'ITEM_' . $item->parent); if (is_object($possible_parent)) { $possible_parent->appendChild($my_item); } else { if ($this->debug > 0) { error_log('Parent ITEM_' . $item->parent . ' of item ITEM_' . $my_item_id . ' not found'); } } } else { if ($this->debug > 0) { error_log('No parent'); } $organization->appendChild($my_item); } // Get the path of the file(s) from the course directory root. $my_file_path = $item->get_file_path('scorm/' . $this->path . '/'); if (!empty($path_to_remove)) { //From docs $my_xml_file_path = str_replace($path_to_remove, $path_to_replace, $my_file_path); //From quiz if ($this->ref == 'chamilo_scorm_export') { $path_to_remove = 'scorm/' . $this->path . '/'; $my_xml_file_path = str_replace($path_to_remove, '', $my_file_path); } } else { $my_xml_file_path = $my_file_path; } $my_sub_dir = dirname($my_file_path); $my_sub_dir = str_replace('\\', '/', $my_sub_dir); //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8'); $my_xml_sub_dir = $my_sub_dir; // Give a <resource> child to the <resources> element $my_resource = $xmldoc->createElement('resource'); $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id()); $my_resource->setAttribute('type', 'webcontent'); $my_resource->setAttribute('href', $my_xml_file_path); // adlcp:scormtype can be either 'sco' or 'asset'. if ($item->type == 'sco') { $my_resource->setAttribute('adlcp:scormtype', 'sco'); } else { $my_resource->setAttribute('adlcp:scormtype', 'asset'); } // xml:base is the base directory to find the files declared in this resource. $my_resource->setAttribute('xml:base', ''); // Give a <file> child to the <resource> element. $my_file = $xmldoc->createElement('file'); $my_file->setAttribute('href', $my_xml_file_path); $my_resource->appendChild($my_file); // Dependency to other files - not yet supported. $i = 1; foreach ($inc_docs as $doc_info) { if (count($doc_info) < 1 || empty($doc_info[0])) { continue; } $my_dep = $xmldoc->createElement('resource'); $res_id = 'RESOURCE_' . $item->get_id() . '_' . $i; $my_dep->setAttribute('identifier', $res_id); $my_dep->setAttribute('type', 'webcontent'); $my_dep->setAttribute('adlcp:scormtype', 'asset'); $my_dep_file = $xmldoc->createElement('file'); // Check type of URL. //error_log(__LINE__.'Now dealing with '.$doc_info[0].' of type '.$doc_info[1].'-'.$doc_info[2], 0); if ($doc_info[1] == 'remote') { // Remote file. Save url as is. $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', ''); } elseif ($doc_info[1] == 'local') { switch ($doc_info[2]) { case 'url': // Local URL - save path as url for now, don't zip file. $abs_path = api_get_path(SYS_PATH) . str_replace(api_get_path(WEB_PATH), '', $doc_info[0]); $current_dir = dirname($abs_path); $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($abs_path); $file_path = str_replace('\\', '/', $file_path); $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside Chamilo's root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path) - 1); //echo $file_path;echo '<br /><br />'; //error_log(__LINE__.'Reduced url path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (empty($file_path)) { /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH))); if (strpos($document_root, -1) == '/') { $document_root = substr(0, -1, $document_root); }*/ $file_path = $_SERVER['DOCUMENT_ROOT'] . $abs_path; $file_path = str_replace('//', '/', $file_path); if (file_exists($file_path)) { $file_path = substr($file_path, strlen($current_dir)); // We get the relative path. $zip_files[] = $my_sub_dir . '/' . $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); } } break; case 'abs': // Absolute path from DocumentRoot. Save file and leave path as is in the zip. $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', ''); //$current_dir = str_replace('\\', '/', dirname($current_course_path.'/'.$item->get_file_path())).'/'; // The next lines fix a bug when using the "subdir" mode of Chamilo, whereas // an image path would be constructed as /var/www/subdir/subdir/img/foo.bar $abs_img_path_without_subdir = $doc_info[0]; $relp = api_get_path(REL_PATH); // The url-append config param. $pos = strpos($abs_img_path_without_subdir, $relp); if ($pos === 0) { $abs_img_path_without_subdir = '/' . substr($abs_img_path_without_subdir, strlen($relp)); } //$file_path = realpath(api_get_path(SYS_PATH).$doc_info[0]); $file_path = realpath(api_get_path(SYS_PATH) . $abs_img_path_without_subdir); $file_path = str_replace('\\', '/', $file_path); $file_path = str_replace('//', '/', $file_path); //error_log(__LINE__.'Abs path: '.$file_path, 0); // Prepare the current directory path (until just under 'document') with a trailing slash. $cur_path = substr($current_course_path, -1) == '/' ? $current_course_path : $current_course_path . '/'; // Check if the current document is in that path. if (strstr($file_path, $cur_path) !== false) { // The document is in that path, now get the relative path // to the containing document. $orig_file_path = dirname($cur_path . $my_file_path) . '/'; $orig_file_path = str_replace('\\', '/', $orig_file_path); $relative_path = ''; if (strstr($file_path, $cur_path) !== false) { $relative_path = substr($file_path, strlen($orig_file_path)); $file_path = substr($file_path, strlen($cur_path)); } else { // This case is still a problem as it's difficult to calculate a relative path easily // might still generate wrong links. //$file_path = substr($file_path,strlen($cur_path)); // Calculate the directory path to the current file (without trailing slash). $my_relative_path = dirname($file_path); $my_relative_path = str_replace('\\', '/', $my_relative_path); $my_relative_file = basename($file_path); // Calculate the directory path to the containing file (without trailing slash). $my_orig_file_path = substr($orig_file_path, 0, -1); $dotdot = ''; $subdir = ''; while (strstr($my_relative_path, $my_orig_file_path) === false && strlen($my_orig_file_path) > 1 && strlen($my_relative_path) > 1) { $my_relative_path2 = dirname($my_relative_path); $my_relative_path2 = str_replace('\\', '/', $my_relative_path2); $my_orig_file_path = dirname($my_orig_file_path); $my_orig_file_path = str_replace('\\', '/', $my_orig_file_path); $subdir = substr($my_relative_path, strlen($my_relative_path2) + 1) . '/' . $subdir; $dotdot += '../'; $my_relative_path = $my_relative_path2; } $relative_path = $dotdot . $subdir . $my_relative_file; } // Put the current document in the zip (this array is the array // that will manage documents already in the course folder - relative). $zip_files[] = $file_path; // Update the links to the current document in the containing document (make them relative). $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $relative_path); $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside Chamilo's root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path)); //echo $file_path;echo '<br /><br />'; //error_log('Reduced path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (empty($file_path)) { /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH))); if(strpos($document_root,-1) == '/') { $document_root = substr(0, -1, $document_root); }*/ $file_path = $_SERVER['DOCUMENT_ROOT'] . $doc_info[0]; $file_path = str_replace('//', '/', $file_path); if (file_exists($file_path)) { $file_path = substr($file_path, strlen($current_dir)); // We get the relative path. $zip_files[] = $my_sub_dir . '/' . $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } } break; case 'rel': // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path if (substr($doc_info[0], 0, 2) == '..') { // Relative path going up. $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/'; $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($current_dir . $doc_info[0]); $file_path = str_replace('\\', '/', $file_path); //error_log($file_path.' <-> '.$main_path,0); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside Chamilo's root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path)); //error_log('Reduced path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } } else { $zip_files[] = $my_sub_dir . '/' . $doc_info[0]; $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', $my_xml_sub_dir); } break; default: $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', ''); break; } } $my_dep->appendChild($my_dep_file); $resources->appendChild($my_dep); $dependency = $xmldoc->createElement('dependency'); $dependency->setAttribute('identifierref', $res_id); $my_resource->appendChild($dependency); $i++; } //$my_dependency = $xmldoc->createElement('dependency'); //$my_dependency->setAttribute('identifierref', ''); $resources->appendChild($my_resource); $zip_files[] = $my_file_path; //error_log('File '.$my_file_path. ' added to $zip_files', 0); } else { // If the item is a quiz or a link or whatever non-exportable, we include a step indicating it. switch ($item->type) { case TOOL_LINK: $my_item = $xmldoc->createElement('item'); $my_item->setAttribute('identifier', 'ITEM_' . $item->get_id()); $my_item->setAttribute('identifierref', 'RESOURCE_' . $item->get_id()); $my_item->setAttribute('isvisible', 'true'); // Give a child element <title> to the <item> element. $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8')); $my_item->appendChild($my_title); // Give a child element <adlcp:prerequisites> to the <item> element. $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string()); $my_prereqs->setAttribute('type', 'aicc_script'); $my_item->appendChild($my_prereqs); // Give a child element <adlcp:maxtimeallowed> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:maxtimeallowed', ''); // Give a child element <adlcp:timelimitaction> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:timelimitaction', ''); // Give a child element <adlcp:datafromlms> to the <item> element - not yet supported. //$xmldoc->createElement('adlcp:datafromlms', ''); // Give a child element <adlcp:masteryscore> to the <item> element. $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score()); $my_item->appendChild($my_masteryscore); // Attach this item to the organization element or its parent if there is one. if (!empty($item->parent) && $item->parent != 0) { $children = $organization->childNodes; for ($i = 0; $i < $children->length; $i++) { $item_temp = $children->item($i); if ($item_temp->nodeName == 'item') { if ($item_temp->getAttribute('identifier') == 'ITEM_' . $item->parent) { $item_temp->appendChild($my_item); } } } } else { $organization->appendChild($my_item); } $my_file_path = 'link_' . $item->get_id() . '.html'; $sql = 'SELECT url, title FROM ' . Database::get_course_table(TABLE_LINK) . ' WHERE c_id = ' . $course_id . ' AND id=' . $item->path; $rs = Database::query($sql); if ($link = Database::fetch_array($rs)) { $url = $link['url']; $title = stripslashes($link['title']); $links_to_create[$my_file_path] = array('title' => $title, 'url' => $url); //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8'); $my_xml_file_path = $my_file_path; $my_sub_dir = dirname($my_file_path); $my_sub_dir = str_replace('\\', '/', $my_sub_dir); //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8'); $my_xml_sub_dir = $my_sub_dir; // Give a <resource> child to the <resources> element. $my_resource = $xmldoc->createElement('resource'); $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id()); $my_resource->setAttribute('type', 'webcontent'); $my_resource->setAttribute('href', $my_xml_file_path); // adlcp:scormtype can be either 'sco' or 'asset'. $my_resource->setAttribute('adlcp:scormtype', 'asset'); // xml:base is the base directory to find the files declared in this resource. $my_resource->setAttribute('xml:base', ''); // give a <file> child to the <resource> element. $my_file = $xmldoc->createElement('file'); $my_file->setAttribute('href', $my_xml_file_path); $my_resource->appendChild($my_file); $resources->appendChild($my_resource); } break; case TOOL_QUIZ: require_once api_get_path(SYS_CODE_PATH) . 'exercice/exercise.class.php'; $exe_id = $item->path; // Should be using ref when everything will be cleaned up in this regard. $exe = new Exercise(); $exe->read($exe_id); $my_item = $xmldoc->createElement('item'); $my_item->setAttribute('identifier', 'ITEM_' . $item->get_id()); $my_item->setAttribute('identifierref', 'RESOURCE_' . $item->get_id()); $my_item->setAttribute('isvisible', 'true'); // Give a child element <title> to the <item> element. $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8')); $my_item->appendChild($my_title); $my_max_score = $xmldoc->createElement('max_score', $item->get_max()); //$my_item->appendChild($my_max_score); // Give a child element <adlcp:prerequisites> to the <item> element. $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string()); $my_prereqs->setAttribute('type', 'aicc_script'); $my_item->appendChild($my_prereqs); // Give a child element <adlcp:masteryscore> to the <item> element. $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score()); $my_item->appendChild($my_masteryscore); // Attach this item to the organization element or hits parent if there is one. if (!empty($item->parent) && $item->parent != 0) { $children = $organization->childNodes; for ($i = 0; $i < $children->length; $i++) { $item_temp = $children->item($i); if ($item_temp->nodeName == 'item') { if ($item_temp->getAttribute('identifier') == 'ITEM_' . $item->parent) { $item_temp->appendChild($my_item); } } } } else { $organization->appendChild($my_item); } // Include export scripts. require_once api_get_path(SYS_CODE_PATH) . 'exercice/export/scorm/scorm_export.php'; // Get the path of the file(s) from the course directory root //$my_file_path = $item->get_file_path('scorm/'.$this->path.'/'); $my_file_path = 'quiz_' . $item->get_id() . '.html'; // Write the contents of the exported exercise into a (big) html file // to later pack it into the exported SCORM. The file will be removed afterwards. $contents = export_exercise($exe_id, true); $tmp_file_path = $archive_path . $temp_dir_short . '/' . $my_file_path; $res = file_put_contents($tmp_file_path, $contents); if ($res === false) { error_log('Could not write into file ' . $tmp_file_path . ' ' . __FILE__ . ' ' . __LINE__, 0); } $files_cleanup[] = $tmp_file_path; //error_log($tmp_path); die(); //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8'); $my_xml_file_path = $my_file_path; $my_sub_dir = dirname($my_file_path); $my_sub_dir = str_replace('\\', '/', $my_sub_dir); //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8'); $my_xml_sub_dir = $my_sub_dir; // Give a <resource> child to the <resources> element. $my_resource = $xmldoc->createElement('resource'); $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id()); $my_resource->setAttribute('type', 'webcontent'); $my_resource->setAttribute('href', $my_xml_file_path); // adlcp:scormtype can be either 'sco' or 'asset'. $my_resource->setAttribute('adlcp:scormtype', 'sco'); // xml:base is the base directory to find the files declared in this resource. $my_resource->setAttribute('xml:base', ''); // Give a <file> child to the <resource> element. $my_file = $xmldoc->createElement('file'); $my_file->setAttribute('href', $my_xml_file_path); $my_resource->appendChild($my_file); // Get included docs. $inc_docs = $item->get_resources_from_source(null, $tmp_file_path); // Dependency to other files - not yet supported. $i = 1; foreach ($inc_docs as $doc_info) { if (count($doc_info) < 1 || empty($doc_info[0])) { continue; } $my_dep = $xmldoc->createElement('resource'); $res_id = 'RESOURCE_' . $item->get_id() . '_' . $i; $my_dep->setAttribute('identifier', $res_id); $my_dep->setAttribute('type', 'webcontent'); $my_dep->setAttribute('adlcp:scormtype', 'asset'); $my_dep_file = $xmldoc->createElement('file'); // Check type of URL. //error_log(__LINE__.'Now dealing with '.$doc_info[0].' of type '.$doc_info[1].'-'.$doc_info[2], 0); if ($doc_info[1] == 'remote') { // Remote file. Save url as is. $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', ''); } elseif ($doc_info[1] == 'local') { switch ($doc_info[2]) { case 'url': // Local URL - save path as url for now, don't zip file. // Save file but as local file (retrieve from URL). $abs_path = api_get_path(SYS_PATH) . str_replace(api_get_path(WEB_PATH), '', $doc_info[0]); $current_dir = dirname($abs_path); $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($abs_path); $file_path = str_replace('\\', '/', $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside the chamilo root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path)); //echo $file_path;echo '<br /><br />'; //error_log('Reduced path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/' . $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (empty($file_path)) { /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH),api_get_path(REL_PATH))); if (strpos($document_root,-1) == '/') { $document_root = substr(0, -1, $document_root); }*/ $file_path = $_SERVER['DOCUMENT_ROOT'] . $abs_path; $file_path = str_replace('//', '/', $file_path); if (file_exists($file_path)) { $file_path = substr($file_path, strlen($current_dir)); // We get the relative path. $zip_files[] = $my_sub_dir . '/' . $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/' . $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } } break; case 'abs': // Absolute path from DocumentRoot. Save file and leave path as is in the zip. $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/'; $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($doc_info[0]); $file_path = str_replace('\\', '/', $file_path); $my_dep_file->setAttribute('href', $file_path); $my_dep->setAttribute('xml:base', ''); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside the chamilo root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path)); //echo $file_path;echo '<br /><br />'; //error_log('Reduced path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } elseif (empty($file_path)) { /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH))); if (strpos($document_root,-1) == '/') { $document_root = substr(0, -1, $document_root); }*/ $file_path = $_SERVER['DOCUMENT_ROOT'] . $doc_info[0]; $file_path = str_replace('//', '/', $file_path); if (file_exists($file_path)) { $file_path = substr($file_path, strlen($current_dir)); // We get the relative path. $zip_files[] = $my_sub_dir . '/' . $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } } break; case 'rel': // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path if (substr($doc_info[0], 0, 2) == '..') { // Relative path going up. $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/'; $current_dir = str_replace('\\', '/', $current_dir); $file_path = realpath($current_dir . $doc_info[0]); $file_path = str_replace('\\', '/', $file_path); //error_log($file_path.' <-> '.$main_path, 0); if (strstr($file_path, $main_path) !== false) { // The calculated real path is really inside Chamilo's root path. // Reduce file path to what's under the DocumentRoot. $file_path = substr($file_path, strlen($root_path)); $file_path_dest = $file_path; // File path is courses/CHAMILO/document/.... $info_file_path = explode('/', $file_path); if ($info_file_path[0] == 'courses') { // Add character "/" in file path. $file_path_dest = 'document/' . $file_path; } //error_log('Reduced path: '.$file_path, 0); $zip_files_abs[] = $file_path; $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path_dest); $my_dep_file->setAttribute('href', 'document/' . $file_path); $my_dep->setAttribute('xml:base', ''); } } else { $zip_files[] = $my_sub_dir . '/' . $doc_info[0]; $my_dep_file->setAttribute('href', $doc_info[0]); $my_dep->setAttribute('xml:base', $my_xml_sub_dir); } break; default: $my_dep_file->setAttribute('href', $doc_info[0]); // ../../courses/ $my_dep->setAttribute('xml:base', ''); break; } } $my_dep->appendChild($my_dep_file); $resources->appendChild($my_dep); $dependency = $xmldoc->createElement('dependency'); $dependency->setAttribute('identifierref', $res_id); $my_resource->appendChild($dependency); $i++; } $resources->appendChild($my_resource); $zip_files[] = $my_file_path; break; default: // Get the path of the file(s) from the course directory root $my_file_path = 'non_exportable.html'; //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_COMPAT, 'UTF-8'); $my_xml_file_path = $my_file_path; $my_sub_dir = dirname($my_file_path); $my_sub_dir = str_replace('\\', '/', $my_sub_dir); //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_COMPAT, 'UTF-8'); $my_xml_sub_dir = $my_sub_dir; // Give a <resource> child to the <resources> element. $my_resource = $xmldoc->createElement('resource'); $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id()); $my_resource->setAttribute('type', 'webcontent'); $my_resource->setAttribute('href', $folder_name . '/' . $my_xml_file_path); // adlcp:scormtype can be either 'sco' or 'asset'. $my_resource->setAttribute('adlcp:scormtype', 'asset'); // xml:base is the base directory to find the files declared in this resource. $my_resource->setAttribute('xml:base', ''); // Give a <file> child to the <resource> element. $my_file = $xmldoc->createElement('file'); $my_file->setAttribute('href', 'document/' . $my_xml_file_path); $my_resource->appendChild($my_file); $resources->appendChild($my_resource); break; } } } $organizations->appendChild($organization); $root->appendChild($organizations); $root->appendChild($resources); $xmldoc->appendChild($root); // TODO: Add a readme file here, with a short description and a link to the Reload player // then add the file to the zip, then destroy the file (this is done automatically). // http://www.reload.ac.uk/scormplayer.html - once done, don't forget to close FS#138 //error_log(print_r($zip_files,true), 0); foreach ($zip_files as $file_path) { if (empty($file_path)) { continue; } //error_log(__LINE__.'getting document from '.$sys_course_path.$_course['path'].'/'.$file_path.' removing '.$sys_course_path.$_course['path'].'/',0); $dest_file = $archive_path . $temp_dir_short . '/' . $file_path; $this->create_path($dest_file); //error_log('copy '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/'.$file_path.' to '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/'.$file_path,0); //echo $main_path.$file_path.'<br />'; @copy($sys_course_path . $_course['path'] . '/' . $file_path, $dest_file); // Check if the file needs a link update. if (in_array($file_path, array_keys($link_updates))) { $string = file_get_contents($dest_file); unlink($dest_file); foreach ($link_updates[$file_path] as $old_new) { //error_log('Replacing '.$old_new['orig'].' by '.$old_new['dest'].' in '.$file_path, 0); // This is an ugly hack that allows .flv files to be found by the flv player that // will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs // to find the flv to play in document/main/, so we replace main/ in the flv path by // ../../.. to return from inc/lib/flv_player to the document/main path. if (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 5) == 'main/') { $old_new['dest'] = str_replace('main/', '../../../', $old_new['dest']); } elseif (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 6) == 'video/') { $old_new['dest'] = str_replace('video/', '../../../../video/', $old_new['dest']); } //Fix to avoid problems with default_course_document if (strpos("main/default_course_document", $old_new['dest'] === false)) { $new_dest = str_replace('document/', $mult . 'document/', $old_new['dest']); } else { //$new_dest = str_replace('main/default_course_document', $mult.'document/main/default_course_document', $old_new['dest']); $new_dest = $old_new['dest']; } //$string = str_replace($old_new['orig'], $old_new['dest'], $string); $string = str_replace($old_new['orig'], $new_dest, $string); //Add files inside the HTMLs $new_path = str_replace('/courses/', '', $old_new['orig']); //var_dump($sys_course_path.$new_path); var_dump($archive_path.$temp_dir_short.'/'.$old_new['dest']); echo '---'; if (file_exists($sys_course_path . $new_path)) { copy($sys_course_path . $new_path, $archive_path . $temp_dir_short . '/' . $old_new['dest']); } } file_put_contents($dest_file, $string); } } foreach ($zip_files_abs as $file_path) { if (empty($file_path)) { continue; } //error_log(__LINE__.'checking existence of '.$main_path.$file_path.'', 0); if (!is_file($main_path . $file_path) || !is_readable($main_path . $file_path)) { continue; } //error_log(__LINE__.'getting document from '.$main_path.$file_path.' removing '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/', 0); $dest_file = $archive_path . $temp_dir_short . '/document/' . $file_path; $this->create_path($dest_file); //error_log('Created path '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/document/'.$file_path, 0); //error_log('copy '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/'.$file_path.' to '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/'.$file_path, 0); //echo $main_path.$file_path.' - '.$dest_file.'<br />'; copy($main_path . $file_path, $dest_file); // Check if the file needs a link update. if (in_array($file_path, array_keys($link_updates))) { $string = file_get_contents($dest_file); unlink($dest_file); foreach ($link_updates[$file_path] as $old_new) { //error_log('Replacing '.$old_new['orig'].' by '.$old_new['dest'].' in '.$file_path, 0); // This is an ugly hack that allows .flv files to be found by the flv player that // will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs // to find the flv to play in document/main/, so we replace main/ in the flv path by // ../../.. to return from inc/lib/flv_player to the document/main path. if (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 5) == 'main/') { $old_new['dest'] = str_replace('main/', '../../../', $old_new['dest']); } $string = str_replace($old_new['orig'], $old_new['dest'], $string); } file_put_contents($dest_file, $string); } } if (is_array($links_to_create)) { foreach ($links_to_create as $file => $link) { $file_content = '<!DOCTYPE html> <head> <meta charset="' . api_get_language_isocode() . '" /> <title>' . $link['title'] . '</title> </head> <body dir="' . api_get_text_direction() . '"> <div style="text-align:center"> <a href="' . $link['url'] . '">' . $link['title'] . '</a></div> </body> </html>'; file_put_contents($archive_path . $temp_dir_short . '/' . $file, $file_content); } } // Add non exportable message explanation. $lang_not_exportable = get_lang('ThisItemIsNotExportable'); $file_content = '<!DOCTYPE html> <head> <meta charset="' . api_get_language_isocode() . '" /> <title>' . $lang_not_exportable . '</title> <meta http-equiv="Content-Type" content="text/html; charset=' . api_get_system_encoding() . '" /> </head> <body dir="' . api_get_text_direction() . '">'; $file_content .= <<<EOD <style> .error-message { font-family: arial, verdana, helvetica, sans-serif; border-width: 1px; border-style: solid; left: 50%; margin: 10px auto; min-height: 30px; padding: 5px; right: 50%; width: 500px; background-color: #FFD1D1; border-color: #FF0000; color: #000; } </style> <body> <div class="error-message"> {$lang_not_exportable} </div> </body> </html> EOD; if (!is_dir($archive_path . $temp_dir_short . '/document')) { @mkdir($archive_path . $temp_dir_short . '/document', api_get_permissions_for_new_directories()); } file_put_contents($archive_path . $temp_dir_short . '/document/non_exportable.html', $file_content); // Add the extra files that go along with a SCORM package. $main_code_path = api_get_path(SYS_CODE_PATH) . 'newscorm/packaging/'; $extra_files = scandir($main_code_path); foreach ($extra_files as $extra_file) { if (strpos($extra_file, '.') === 0) { continue; } else { $dest_file = $archive_path . $temp_dir_short . '/' . $extra_file; $this->create_path($dest_file); copy($main_code_path . $extra_file, $dest_file); } } // Finalize the imsmanifest structure, add to the zip, then return the zip. $manifest = @$xmldoc->saveXML(); $manifest = Text::api_utf8_decode_xml($manifest); // The manifest gets the system encoding now. file_put_contents($archive_path . '/' . $temp_dir_short . '/imsmanifest.xml', $manifest); $zip_folder->add($archive_path . '/' . $temp_dir_short, PCLZIP_OPT_REMOVE_PATH, $archive_path . '/' . $temp_dir_short . '/'); // Clean possible temporary files. foreach ($files_cleanup as $file) { $res = unlink($file); if ($res === false) { error_log('Could not delete temp file ' . $file . ' ' . __FILE__ . ' ' . __LINE__, 0); } } // Send file to client $name = api_replace_dangerous_char($this->get_name()) . '.zip'; DocumentManager::file_send_for_download($temp_zip_file, true, $name); }
/** * @param string $file * @param string $action_after_conversion * @return bool|int */ public function convert_document($file, $action_after_conversion = 'make_lp') { $_course = api_get_course_info(); $this->file_name = pathinfo($file['name'], PATHINFO_FILENAME); // Create the directory $result = $this->generate_lp_folder($_course, $this->file_name); // Create the directory $this->base_work_dir = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document'; ///learning_path/ppt_dirname directory $this->created_dir = substr($result['dir'], 0, strlen($result['dir']) - 1); $this->file_path = $this->created_dir . '/' . api_replace_dangerous_char($file['name']); //var_dump($this->file_name, $this->file_path, $this->base_work_dir, $this->created_dir); /* * Original code global $_course, $_user, $_configuration; $this->file_name = (strrpos($file['name'], '.') > 0 ? substr($file['name'], 0, strrpos($file['name'], '.')) : $file['name']); $this->file_name = api_replace_dangerous_char($this->file_name, 'strict'); $this->file_name = strtolower($this->file_name); $visio_dir = ($action_after_conversion == 'add_docs_to_visio') ? VIDEOCONF_UPLOAD_PATH : ''; $this->file_path = $visio_dir.'/'.$this->file_name.'.'.pathinfo($file['name'], PATHINFO_EXTENSION); $dir_name = $visio_dir.'/'.$this->file_name; // Create the directory. $this->base_work_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'; $this->created_dir = create_unexisting_directory($_course, $_user['user_id'], api_get_session_id(), 0, 0, $this->base_work_dir, $dir_name); var_dump($this->file_name, $this->file_path, $this->base_work_dir, $this->created_dir); */ $ppt2lp_host = api_get_setting('ppt_to_lp.host'); if ($ppt2lp_host == 'localhost') { move_uploaded_file($file['tmp_name'], $this->base_work_dir . '/' . $this->file_path); //var_dump( $this->base_work_dir.$this->created_dir.$this->file_path); $perm = api_get_setting('permissions_for_new_files'); if (IS_WINDOWS_OS) { // IS_WINDOWS_OS has been defined in main_api.lib.php $converter_path = str_replace('/', '\\', api_get_path(SYS_PATH) . 'main/inc/lib/ppt2png'); $class_path = $converter_path . ';' . $converter_path . '/jodconverter-2.2.2.jar;' . $converter_path . '/jodconverter-cli-2.2.2.jar'; //$cmd = 'java -cp "'.$class_path.'" DokeosConverter'; $cmd = 'java -Dfile.encoding=UTF-8 -cp "' . $class_path . '" DokeosConverter'; } else { $converter_path = api_get_path(SYS_PATH) . 'main/inc/lib/ppt2png'; //$class_path = '-cp .:jodconverter-2.2.1.jar:jodconverter-cli-2.2.1.jar'; $class_path = ' -Dfile.encoding=UTF-8 -cp .:jodconverter-2.2.2.jar:jodconverter-cli-2.2.2.jar'; $cmd = 'cd ' . $converter_path . ' && java ' . $class_path . ' DokeosConverter'; } $cmd .= ' -p ' . api_get_setting('ppt_to_lp.port'); // Call to the function implemented by child. $cmd .= $this->add_command_parameters(); // To allow openoffice to manipulate docs. @chmod($this->base_work_dir, 0777); @chmod($this->base_work_dir . $this->created_dir, 0777); @chmod($this->base_work_dir . $this->file_path, 0777); $locale = $this->original_locale; // TODO: Improve it because we're not sure this locale is present everywhere. putenv('LC_ALL=' . $locale); $files = array(); $return = 0; $shell = exec($cmd, $files, $return); if ($return != 0) { // If the java application returns an error code. switch ($return) { // Can't connect to openoffice. case 1: $this->error = get_lang('CannotConnectToOpenOffice'); break; // Conversion failed in openoffice. // Conversion failed in openoffice. case 2: $this->error = get_lang('OogieConversionFailed'); break; // Conversion can't be launch because command failed. // Conversion can't be launch because command failed. case 255: $this->error = get_lang('OogieUnknownError'); break; } DocumentManager::delete_document($_course, $this->created_dir, $this->base_work_dir); return false; } } else { // get result from webservices $result = $this->_get_remote_ppt2lp_files($file); $result = unserialize($result); // Save remote images to server chmod($this->base_work_dir . $this->created_dir, api_get_permissions_for_new_directories()); if (!empty($result['images'])) { foreach ($result['images'] as $image => $img_data) { $image_path = $this->base_work_dir . $this->created_dir; @file_put_contents($image_path . '/' . $image, base64_decode($img_data)); @chmod($image_path . '/' . $image, 0777); } } // files info $files = $result['files']; } if (!empty($files)) { // Create lp $this->lp_id = learnpath::add_lp($_course['id'], $this->file_name, '', 'guess', 'manual'); // make sure we have a course code available for later $this->cc = $_course['id']; // Call to the function implemented by child following action_after_conversion parameter. switch ($action_after_conversion) { case 'make_lp': $this->make_lp($files); break; case 'add_docs_to_visio': $this->add_docs_to_visio($files); break; } chmod($this->base_work_dir, api_get_permissions_for_new_directories()); } return $this->first_item; }
Display::display_footer(); exit; } } } $tool_name = get_lang('Registration', null, !empty($_POST['language']) ? $_POST['language'] : $_user['language']); if (api_get_setting('registration.allow_terms_conditions') == 'true' && $user_already_registered_show_terms) { $tool_name = get_lang('TermsAndConditions'); } $home = api_get_path(SYS_APP_PATH) . 'home/'; if (api_is_multiple_url_enabled()) { $access_url_id = api_get_current_access_url_id(); if ($access_url_id != -1) { $url_info = api_get_access_url($access_url_id); $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 .= '/'; $home_old = api_get_path(SYS_APP_PATH) . 'home/'; $home = api_get_path(SYS_APP_PATH) . 'home/' . $clean_url; } } if (file_exists($home . 'register_top_' . $user_selected_language . '.html')) { $home_top_temp = @(string) file_get_contents($home . 'register_top_' . $user_selected_language . '.html'); $open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top_temp); $open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open))); if (!empty($open)) { $content = '<div class="well_border">' . $open . '</div>'; } } // Forbidden to self-register
/** * Create a group * @param string $name The name for this group * @param int $category_id * @param int $tutor The user-id of the group's tutor * @param int $places How many people can subscribe to the new group */ public static function create_group($name, $category_id, $tutor, $places) { $courseObj = api_get_user_course_entity(); $_course = api_get_course_info(); $session_id = api_get_session_id(); $currentCourseRepository = $_course['path']; $category = self::get_category($category_id); $places = intval($places); if ($category) { if ($places == 0) { //if the amount of users per group is not filled in, use the setting from the category $places = $category['max_student']; } else { if ($places > $category['max_student'] && $category['max_student'] != 0) { $places = $category['max_student']; } } $docState = $category['doc_state']; $calendarState = $category['calendar_state']; $workState = $category['work_state']; $anonuncementState = $category['announcements_state']; $forumState = $category['forum_state']; $wikiState = $category['wiki_state']; $chatState = $category['chat_state']; $selfRegAllowed = $category['self_reg_allowed']; $selfUnregAllowed = $category['self_unreg_allowed']; } else { $docState = self::TOOL_PRIVATE; $calendarState = self::TOOL_PRIVATE; $workState = self::TOOL_PRIVATE; $anonuncementState = self::TOOL_PRIVATE; $forumState = self::TOOL_PRIVATE; $wikiState = self::TOOL_PRIVATE; $chatState = self::TOOL_PRIVATE; $selfRegAllowed = 0; $selfUnregAllowed = 0; } $group = new CGroupInfo(); $group->setName($name)->setStatus(1)->setDescription('')->setMaxStudent($places)->setAnnouncementsState($anonuncementState)->setDocState($docState)->setCalendarState($calendarState)->setChatState($chatState)->setForumState($forumState)->setWikiState($wikiState)->setWorkState($workState)->setSelfUnregistrationAllowed($selfUnregAllowed)->setSelfRegistrationAllowed($selfRegAllowed)->setSessionId($session_id)->setCourse($courseObj)->setCategoryId($category_id)->setDescription(''); $em = Database::getManager(); $em->persist($group); $em->flush(); $lastId = $group->getIid(); if ($lastId) { $desired_dir_name = '/' . api_replace_dangerous_char($name) . '_groupdocs'; $my_path = api_get_path(SYS_COURSE_PATH) . $currentCourseRepository . '/document'; $newFolderData = create_unexisting_directory($_course, api_get_user_id(), $session_id, $lastId, null, $my_path, $desired_dir_name, null, 1); $unique_name = $newFolderData['path']; $group->setId($lastId); $group->setSecretDirectory($unique_name); $group->setName($name); $em->merge($group); $em->flush(); // create a forum if needed if ($forumState >= 0) { require_once api_get_path(SYS_CODE_PATH) . 'forum/forumconfig.inc.php'; require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; $forum_categories = get_forum_categories(); if (empty($forum_categories)) { $categoryParam = array('forum_category_title' => get_lang('GroupForums')); store_forumcategory($categoryParam); $forum_categories = get_forum_categories(); } $counter = 0; foreach ($forum_categories as $key => $value) { if ($counter == 0) { $forum_category_id = $key; } $counter++; } // A sanity check. if (empty($forum_category_id)) { $forum_category_id = 0; } $values = array(); $values['forum_title'] = $name; $values['group_id'] = $lastId; $values['forum_category'] = $forum_category_id; $values['allow_anonymous_group']['allow_anonymous'] = 0; $values['students_can_edit_group']['students_can_edit'] = 0; $values['approval_direct_group']['approval_direct'] = 0; $values['allow_attachments_group']['allow_attachments'] = 1; $values['allow_new_threads_group']['allow_new_threads'] = 1; $values['default_view_type_group']['default_view_type'] = api_get_setting('forum.default_forum_view'); $values['group_forum'] = $lastId; if ($forumState == '1') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'public'; } elseif ($forumState == '2') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'private'; } elseif ($forumState == '0') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'unavailable'; } store_forum($values); } } return $lastId; }
$message = Display::return_message(get_lang('CannotCreateDir'), 'error'); } else { // dir_id is the parent folder id. if (!empty($_POST['dir_id'])) { // Get the document data from the ID $document_data = DocumentManager::get_document_data_by_id($_POST['dir_id'], api_get_course_id(), false, $sessionId); if ($sessionId != 0 && !$document_data) { // If there is a session defined and asking for the // document * from the session* didn't work, try it from // the course (out of a session context) $document_data = DocumentManager::get_document_data_by_id($_POST['dir_id'], api_get_course_id(), false, 0); } $curdirpath = $document_data['path']; } $added_slash = $curdirpath == '/' ? '' : '/'; $dir_name = $curdirpath . $added_slash . api_replace_dangerous_char($post_dir_name); $dir_name = disable_dangerous_file($dir_name); $dir_check = $base_work_dir . $dir_name; $visibility = empty($groupId) ? null : 1; $newFolderData = create_unexisting_directory($courseInfo, api_get_user_id(), $sessionId, $groupId, $to_user_id, $base_work_dir, $dir_name, $post_dir_name, $visibility); if (!empty($newFolderData)) { $message = Display::return_message(get_lang('DirCr') . ' ' . $newFolderData['title'], 'confirmation'); } else { $message = Display::return_message(get_lang('CannotCreateDir'), 'error'); } } Display::addFlash($message); } // Show them the form for the directory name if (isset($_GET['createdir'])) { $dirForm = DocumentManager::create_dir_form($document_id);
/** * Imports a zip file (presumably AICC) into the Chamilo structure * @param string Zip file info as given by $_FILES['userFile'] * @return string Absolute path to the AICC config files directory or empty string on error */ function import_package($zip_file_info, $current_dir = '') { if ($this->debug > 0) { error_log('In aicc::import_package(' . print_r($zip_file_info, true) . ',"' . $current_dir . '") method', 0); } //ini_set('error_log', 'E_ALL'); $maxFilledSpace = 1000000000; $zip_file_path = $zip_file_info['tmp_name']; $zip_file_name = $zip_file_info['name']; if ($this->debug > 0) { error_log('New LP - aicc::import_package() - Zip file path = ' . $zip_file_path . ', zip file name = ' . $zip_file_name, 0); } $course_rel_dir = api_get_course_path() . '/scorm'; // Scorm dir web path starting from /courses $course_sys_dir = api_get_path(SYS_COURSE_PATH) . $course_rel_dir; // The absolute system path of this course. $current_dir = api_replace_dangerous_char(trim($current_dir), 'strict'); // Current dir we are in, inside scorm/ if ($this->debug > 0) { error_log('New LP - aicc::import_package() - Current_dir = ' . $current_dir, 0); } //$uploaded_filename = $_FILES['userFile']['name']; // Get the name of the zip file without the extension. if ($this->debug > 0) { error_log('New LP - aicc::import_package() - Received zip file name: ' . $zip_file_path, 0); } $file_info = pathinfo($zip_file_name); $filename = $file_info['basename']; $extension = $file_info['extension']; $file_base_name = str_replace('.' . $extension, '', $filename); // Filename without its extension. $this->zipname = $file_base_name; // Save for later in case we don't have a title. if ($this->debug > 0) { error_log('New LP - aicc::import_package() - Base file name is : ' . $file_base_name, 0); } $new_dir = api_replace_dangerous_char(trim($file_base_name), 'strict'); $this->subdir = $new_dir; if ($this->debug > 0) { error_log('New LP - aicc::import_package() - Subdir is first set to : ' . $this->subdir, 0); } /* if (check_name_exist($course_sys_dir.$current_dir.'/'.$new_dir)) { $dialogBox = get_lang('FileExists'); $stopping_error = true; } */ $zipFile = new PclZip($zip_file_path); // Check the zip content (real size and file extension). $zipContentArray = $zipFile->listContent(); $package_type = ''; // The type of the package. Should be 'aicc' after the next few lines. $package = ''; // The basename of the config files (if 'courses.crs' => 'courses'). $at_root = false; // Check if the config files are at zip root. $config_dir = ''; // The directory in which the config files are. May remain empty. $files_found = array(); $subdir_isset = false; // The following loop should be stopped as soon as we found the right config files (.crs, .au, .des and .cst). foreach ($zipContentArray as $thisContent) { if (preg_match('~.(php.*|phtml)$~i', $thisContent['filename'])) { // If a php file is found, do not authorize (security risk). if ($this->debug > 1) { error_log('New LP - aicc::import_package() - Found unauthorized file: ' . $thisContent['filename'], 0); } return api_failure::set_failure('php_file_in_zip_file'); } elseif (preg_match('?.*/aicc/$?', $thisContent['filename'])) { // If a directory named 'aicc' is found, package type = aicc, but continue, // because we need to find the right AICC files; if ($this->debug > 1) { error_log('New LP - aicc::import_package() - Found aicc directory: ' . $thisContent['filename'], 0); } $package_type = 'aicc'; } else { // else, look for one of the files we're searching for (something.crs case insensitive). $res = array(); if (preg_match('?^(.*)\\.(crs|au|des|cst|ore|pre|cmp)$?i', $thisContent['filename'], $res)) { if ($this->debug > 1) { error_log('New LP - aicc::import_package() - Found AICC config file: ' . $thisContent['filename'] . '. Now splitting: ' . $res[1] . ' and ' . $res[2], 0); } if ($thisContent['filename'] == basename($thisContent['filename'])) { if ($this->debug > 2) { error_log('New LP - aicc::import_package() - ' . $thisContent['filename'] . ' is at root level', 0); } $at_root = true; if (!is_array($files_found[$res[1]])) { $files_found[$res[1]] = $this->config_exts; // Initialise list of expected extensions (defined in class definition). } $files_found[$res[1]][api_strtolower($res[2])] = $thisContent['filename']; $subdir_isset = true; } else { if (!$subdir_isset) { if (preg_match('?^.*/aicc$?i', dirname($thisContent['filename']))) { //echo "Cutting subdir<br/>"; $this->subdir .= '/' . substr(dirname($thisContent['filename']), 0, -5); } else { //echo "Not cutting subdir<br/>"; $this->subdir .= '/' . dirname($thisContent['filename']); } $subdir_isset = true; } if ($this->debug > 2) { error_log('New LP - aicc::import_package() - ' . $thisContent['filename'] . ' is not at root level - recording subdir ' . $this->subdir, 0); } $config_dir = dirname($thisContent['filename']); // Just the relative directory inside scorm/ if (!is_array($files_found[basename($res[1])])) { $files_found[basename($res[1])] = $this->config_exts; } $files_found[basename($res[1])][api_strtolower($res[2])] = basename($thisContent['filename']); } $package_type = 'aicc'; } else { if ($this->debug > 3) { error_log('New LP - aicc::import_package() - File ' . $thisContent['filename'] . ' didnt match any check', 0); } } } $realFileSize += $thisContent['size']; } if ($this->debug > 2) { error_log('New LP - aicc::import_package() - $files_found: ' . print_r($files_found, true), 0); } if ($this->debug > 1) { error_log('New LP - aicc::import_package() - Package type is now ' . $package_type, 0); } $mandatory = false; foreach ($files_found as $file_name => $file_exts) { $temp = (!empty($files_found[$file_name]['crs']) and !empty($files_found[$file_name]['au']) and !empty($files_found[$file_name]['des']) and !empty($files_found[$file_name]['cst'])); if ($temp) { if ($this->debug > 1) { error_log('New LP - aicc::import_package() - Found all config files for ' . $file_name, 0); } $mandatory = true; $package = $file_name; // Store base config file name for reuse in parse_config_files(). $this->config_basename = $file_name; // Store filenames for reuse in parse_config_files(). $this->config_files = $files_found[$file_name]; // Get out, we only want one config files set. break; } } if ($package_type == '' || !$mandatory) { return api_failure::set_failure('not_aicc_content'); } if (!FileManager::enough_size($realFileSize, $course_sys_dir, $maxFilledSpace)) { return api_failure::set_failure('not_enough_space'); } // It happens on Linux that $new_dir sometimes doesn't start with '/' if ($new_dir[0] != '/') { $new_dir = '/' . $new_dir; } // Cut trailing slash. if ($new_dir[strlen($new_dir) - 1] == '/') { $new_dir = substr($new_dir, 0, -1); } /* Uncompressing phase */ /* We need to process each individual file in the zip archive to - add it to the database - parse & change relative html links - make sure the filenames are secure (filter funny characters or php extensions) */ if (is_dir($course_sys_dir . $new_dir) or @mkdir($course_sys_dir . $new_dir, api_get_permissions_for_new_directories())) { // PHP method - slower... if ($this->debug >= 1) { error_log('New LP - Changing dir to ' . $course_sys_dir . $new_dir, 0); } $saved_dir = getcwd(); chdir($course_sys_dir . $new_dir); $unzippingState = $zipFile->extract(); for ($j = 0; $j < count($unzippingState); $j++) { $state = $unzippingState[$j]; // TODO: Fix relative links in html files (?) $extension = strrchr($state["stored_filename"], '.'); //if ($this->debug > 1) { error_log('New LP - found extension '.$extension.' in '.$state['stored_filename'], 0); } } if (!empty($new_dir)) { $new_dir = $new_dir . '/'; } // Rename files, for example with \\ in it. if ($dir = @opendir($course_sys_dir . $new_dir)) { if ($this->debug == 1) { error_log('New LP - Opened dir ' . $course_sys_dir . $new_dir, 0); } while ($file = readdir($dir)) { if ($file != '.' && $file != '..') { $filetype = 'file'; if (is_dir($course_sys_dir . $new_dir . $file)) { $filetype = 'folder'; } // TODO: RENAMING FILES CAN BE VERY DANGEROUS AICC-WISE, avoid that as much as possible! //$safe_file = replace_dangerous_char($file, 'strict'); $find_str = array('\\', '.php', '.phtml'); $repl_str = array('/', '.txt', '.txt'); $safe_file = str_replace($find_str, $repl_str, $file); if ($safe_file != $file) { //@rename($course_sys_dir.$new_dir, $course_sys_dir.'/'.$safe_file); $mydir = dirname($course_sys_dir . $new_dir . $safe_file); if (!is_dir($mydir)) { $mysubdirs = split('/', $mydir); $mybasedir = '/'; foreach ($mysubdirs as $mysubdir) { if (!empty($mysubdir)) { $mybasedir = $mybasedir . $mysubdir . '/'; if (!is_dir($mybasedir)) { @mkdir($mybasedir, api_get_permissions_for_new_directories()); if ($this->debug == 1) { error_log('New LP - Dir ' . $mybasedir . ' doesnt exist. Creating.', 0); } } } } } @rename($course_sys_dir . $new_dir . $file, $course_sys_dir . $new_dir . $safe_file); if ($this->debug == 1) { error_log('New LP - Renaming ' . $course_sys_dir . $new_dir . $file . ' to ' . $course_sys_dir . $new_dir . $safe_file, 0); } } } } closedir($dir); chdir($saved_dir); } } else { return ''; } return $course_sys_dir . $new_dir . $config_dir; }
/** * Check if a document width the chosen filename already exists */ function document_exists($filename) { global $dir; $cleanName = api_replace_dangerous_char($filename); // No "dangerous" files $cleanName = disable_dangerous_file($cleanName); return !DocumentManager::documentExists($dir . $cleanName . '.html', api_get_course_info(), api_get_session_id(), api_get_group_id()); }
/** * Upload a submitted user production. * * @param $user_id User id * @return The filename of the new production or FALSE if the upload has failed */ function upload_user_production($user_id) { $production_repository = UserManager::getUserPathById($user_id, 'system'); if (!file_exists($production_repository)) { @mkdir($production_repository, api_get_permissions_for_new_directories(), true); } $filename = api_replace_dangerous_char($_FILES['production']['name']); $filename = disable_dangerous_file($filename); if (filter_extension($filename)) { if (@move_uploaded_file($_FILES['production']['tmp_name'], $production_repository . $filename)) { return $filename; } } return false; // this should be returned if anything went wrong with the upload }
/** * Renames a file or a directory * * @author - Hugues Peeters <*****@*****.**> * @param - $file_path (string) - complete path of the file or the directory * @param - $new_file_name (string) - new name for the file or the directory * @return - boolean - true if succeed * - boolean - false otherwise * @see - rename() uses the check_name_exist() and php2phps() functions */ function my_rename($file_path, $new_file_name) { $save_dir = getcwd(); $path = dirname($file_path); $old_file_name = basename($file_path); $new_file_name = api_replace_dangerous_char($new_file_name); // If no extension, take the old one if (strpos($new_file_name, '.') === false && ($dotpos = strrpos($old_file_name, '.'))) { $new_file_name .= substr($old_file_name, $dotpos); } // Note: still possible: 'xx.yy' -rename-> '.yy' -rename-> 'zz' // This is useful for folder names, where otherwise '.' would be sticky // Extension PHP is not allowed, change to PHPS $new_file_name = php2phps($new_file_name); if ($new_file_name == $old_file_name) { return $old_file_name; } if (strtolower($new_file_name) != strtolower($old_file_name) && check_name_exist($path . '/' . $new_file_name)) { return false; } // On a Windows server, it would be better not to do the above check // because it succeeds for some new names resembling the old name. // But on Unix/Linux the check must be done because rename overwrites. chdir($path); $res = rename($old_file_name, $new_file_name) ? $new_file_name : false; chdir($save_dir); return $res; }
$waminame = $params['waminame']; $wamidir = $params['wamidir']; $wamiuserid = $params['wamiuserid']; } else { api_not_allowed(); die; } if ($wamiuserid != api_get_user_id() || api_get_user_id() == 0 || $wamiuserid == 0) { api_not_allowed(); die; } //clean $waminame = Security::remove_XSS($waminame); $waminame = Database::escape_string($waminame); $waminame = addslashes(trim($waminame)); $waminame = api_replace_dangerous_char($waminame, 'strict'); $waminame = FileManager::disable_dangerous_file($waminame); $wamidir = Security::remove_XSS($wamidir); $content = file_get_contents('php://input'); //security extension $ext = explode('.', $waminame); $ext = strtolower($ext[sizeof($ext) - 1]); if ($ext != 'wav') { die; } //Do not use here check Fileinfo method because return: text/plain $dirBaseDocuments = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document'; $saveDir = $dirBaseDocuments . $wamidir; $current_session_id = api_get_session_id(); $groupId = $_SESSION['_gid']; //avoid duplicates
//create a directory for the missing files $img_directory = str_replace('.', '_', $_POST['related_file'] . "_files"); $folderData = create_unexisting_directory($_course, $_user['user_id'], api_get_session_id(), $to_group_id, $to_user_id, $base_work_dir, $img_directory); $missing_files_dir = $folderData['path']; //put the uploaded files in the new directory and get the paths $paths_to_replace_in_file = move_uploaded_file_collection_into_directory($_course, $_FILES['img_file'], $base_work_dir, $missing_files_dir, $_user['user_id'], $to_group_id, $to_user_id, $max_filled_space); //open the html file and replace the paths replace_img_path_in_html_file($_POST['img_file_path'], $paths_to_replace_in_file, $base_work_dir . $_POST['related_file']); //update parent folders item_property_update_on_folder($_course, $_POST['curdirpath'], $_user['user_id']); } } //they want to create a directory if (isset($_POST['create_dir']) && $_POST['dirname'] != '') { $added_slash = $path == '/' ? '' : '/'; $dir_name = $path . $added_slash . api_replace_dangerous_char($_POST['dirname']); $created_dir = create_unexisting_directory($_course, $_user['user_id'], api_get_session_id(), $to_group_id, $to_user_id, $base_work_dir, $dir_name, $_POST['dirname']); if ($created_dir) { Display::display_normal_message(get_lang('DirCr')); $path = $created_dir; } else { display_error(get_lang('CannotCreateDir')); } } if (isset($_GET['createdir'])) { //create the form that asks for the directory name $new_folder_text = '<form action="' . api_get_self() . '" method="POST">'; $new_folder_text .= '<input type="hidden" name="curdirpath" value="' . $path . '"/>'; $new_folder_text .= get_lang('NewDir') . ' '; $new_folder_text .= '<input type="text" name="dirname"/>'; $new_folder_text .= '<input type="submit" name="create_dir" value="' . get_lang('Ok') . '"/>';
/** * Displays step 3 - a form where the user can enter the installation settings * regarding the databases - login and password, names, prefixes, single * or multiple databases, tracking or not... * @param string $installType * @param string $dbHostForm * @param string $dbUsernameForm * @param string $dbPassForm * @param string $dbNameForm * @param string $installationProfile */ function display_database_settings_form($installType, $dbHostForm, $dbUsernameForm, $dbPassForm, $dbNameForm, $installationProfile = '') { if ($installType == 'update') { global $_configuration; $dbHostForm = $_configuration['db_host']; $dbUsernameForm = $_configuration['db_user']; $dbPassForm = $_configuration['db_password']; $dbNameForm = $_configuration['main_database']; echo '<div class="RequirementHeading"><h2>' . display_step_sequence() . get_lang('DBSetting') . '</h2></div>'; echo '<div class="RequirementContent">'; echo get_lang('DBSettingUpgradeIntro'); echo '</div>'; } else { echo '<div class="RequirementHeading"><h2>' . display_step_sequence() . get_lang('DBSetting') . '</h2></div>'; echo '<div class="RequirementContent">'; echo get_lang('DBSettingIntro'); echo '</div>'; } ?> <div class="panel panel-default"> <div class="panel-body"> <div class="form-group"> <label class="col-sm-4"><?php echo get_lang('DBHost'); ?> </label> <?php if ($installType == 'update') { ?> <div class="col-sm-5"> <input type="hidden" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?> " /><?php echo $dbHostForm; ?> </div> <div class="col-sm-3"></div> <?php } else { ?> <div class="col-sm-5"> <input type="text" size="25" maxlength="50" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?> " /> </div> <div class="col-sm-3"><?php echo get_lang('EG') . ' localhost'; ?> </div> <?php } ?> </div> <div class="form-group"> <?php //database user username $example_login = get_lang('EG') . ' root'; displayDatabaseParameter($installType, get_lang('DBLogin'), 'dbUsernameForm', $dbUsernameForm, $example_login); ?> </div> <div class="form-group"> <?php //database user password $example_password = get_lang('EG') . ' ' . api_generate_password(); displayDatabaseParameter($installType, get_lang('DBPassword'), 'dbPassForm', $dbPassForm, $example_password); ?> </div> <div class="form-group"> <?php //Database Name fix replace weird chars if ($installType != INSTALL_TYPE_UPDATE) { $dbNameForm = str_replace(array('-', '*', '$', ' ', '.'), '', $dbNameForm); $dbNameForm = api_replace_dangerous_char($dbNameForm); } displayDatabaseParameter($installType, get_lang('MainDB'), 'dbNameForm', $dbNameForm, ' ', null, 'id="optional_param1"'); ?> </div> <?php if ($installType != INSTALL_TYPE_UPDATE) { ?> <div class="form-group"> <div class="col-sm-3"></div> <div class="col-sm-9"> <button type="submit" class="btn btn-primary" name="step3" value="step3"> <i class="fa fa-refresh"> </i> <?php echo get_lang('CheckDatabaseConnection'); ?> </button> </div> </div> <?php } ?> </div> </div> <?php $database_exists_text = ''; $manager = null; try { $manager = connectToDatabase($dbHostForm, $dbUsernameForm, $dbPassForm, null); $databases = $manager->getConnection()->getSchemaManager()->listDatabases(); if (in_array($dbNameForm, $databases)) { $database_exists_text = '<div class="alert alert-warning">' . get_lang('ADatabaseWithTheSameNameAlreadyExists') . '</div>'; } } catch (Exception $e) { $database_exists_text = $e->getMessage(); } if ($manager->getConnection()->isConnected()) { ?> <?php echo $database_exists_text; ?> <div id="db_status" class="alert alert-success"> Database host: <strong><?php echo $manager->getConnection()->getHost(); ?> </strong><br /> Database driver: <strong><?php echo $manager->getConnection()->getDriver()->getName(); ?> </strong><br /> </div> <?php } else { ?> <?php echo $database_exists_text; ?> <div id="db_status" style="float:left;" class="alert alert-danger"> <div style="float:left;"> <?php echo get_lang('FailedConectionDatabase'); ?> </strong> </div> </div> <?php } ?> <div class="form-group"> <div class="col-sm-6"> <button type="submit" name="step2" class="btn btn-default pull-right" value="< <?php echo get_lang('Previous'); ?> " > <i class="fa fa-backward"> </i> <?php echo get_lang('Previous'); ?> </button> </div> <div class="col-sm-6"> <input type="hidden" name="is_executable" id="is_executable" value="-" /> <?php if ($manager) { ?> <button type="submit" class="btn btn-success" name="step4" value="<?php echo get_lang('Next'); ?> >" > <i class="fa fa-forward"> </i> <?php echo get_lang('Next'); ?> </button> <?php } else { ?> <button disabled="disabled" type="submit" class="btn btn-success disabled" name="step4" value="<?php echo get_lang('Next'); ?> >" > <i class="fa fa-forward"> </i> <?php echo get_lang('Next'); ?> </button> <?php } ?> </div> </div> <?php }
/** * Export HTML content in a ODF document * @param string $html * @param string $name * @param string $format * * @return bool */ public static function htmlToOdt($html, $name, $format = 'odt') { $unoconv = api_get_configuration_value('unoconv.binaries'); if (empty($unoconv)) { return false; } if (!empty($html)) { $fs = new Filesystem(); $paths = ['root_sys' => api_get_path(SYS_PATH), 'path.temp' => api_get_path(SYS_ARCHIVE_PATH)]; $connector = new Connector(); $drivers = new DriversContainer(); $drivers['configuration'] = array('unoconv.binaries' => $unoconv, 'unoconv.timeout' => 60); $tempFilesystem = TemporaryFilesystem::create(); $manager = new Manager($tempFilesystem, $fs); $alchemyst = new Alchemyst($drivers, $manager); $dataFileSystem = new Data($paths, $fs, $connector, $alchemyst); $content = $dataFileSystem->convertRelativeToAbsoluteUrl($html); $filePath = $dataFileSystem->putContentInTempFile($content, api_replace_dangerous_char($name), 'html'); $try = true; while ($try) { try { $convertedFile = $dataFileSystem->transcode($filePath, $format); $try = false; DocumentManager::file_send_for_download($convertedFile, false, $name . '.' . $format); } catch (Exception $e) { // error_log($e->getMessage()); } } } }
/** * Set header parameters * @param bool $sendHeaders send headers */ private function set_header_parameters($sendHeaders) { global $httpHeadXtra, $interbreadcrumb, $language_file, $_configuration, $this_section; $_course = api_get_course_info(); $help = $this->help; $nameTools = $this->title; $navigation = return_navigation_array(); $this->menu_navigation = $navigation['menu_navigation']; $this->assign('system_charset', api_get_system_encoding()); if (isset($httpHeadXtra) && $httpHeadXtra) { foreach ($httpHeadXtra as &$thisHttpHead) { header($thisHttpHead); } } $this->assign('online_button', Display::return_icon('statusonline.png', null, null, ICON_SIZE_ATOM)); $this->assign('offline_button', Display::return_icon('statusoffline.png', null, null, ICON_SIZE_ATOM)); // 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('platform.institution'); $title_list[] = api_get_setting('platform.site_name'); 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 $css = $this->setCssFiles(); $this->set_js_files(); $this->setCssCustomFiles($css); //$this->set_js_files_post(); $browser = api_browser_support('check_browser'); if ($browser[0] == 'Internet Explorer' && $browser[1] >= '11') { $browser_head = '<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />'; $this->assign('browser_specific_head', $browser_head); } // Implementation of prefetch. // See http://cdn.chamilo.org/main/img/online.png for details $prefetch = ''; if (!empty($_configuration['cdn_enable'])) { $prefetch .= '<meta http-equiv="x-dns-prefetch-control" content="on">'; foreach ($_configuration['cdn'] as $host => $exts) { $prefetch .= '<link rel="dns-prefetch" href="' . $host . '">'; } } $this->assign('prefetch', $prefetch); $this->assign('text_direction', api_get_text_direction()); $this->assign('section_name', 'section-' . $this_section); //Defaul root chamilo favicon $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_PATH) . 'favicon.ico" type="image/x-icon" />'; //Added to verify if in the current Chamilo Theme exist a favicon $favicoThemeUrl = api_get_path(SYS_CSS_PATH) . 'themes/' . $this->theme . '/images/'; //If exist pick the current chamilo theme favicon if (is_file($favicoThemeUrl . 'favicon.ico')) { $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_CSS_PATH) . 'themes/' . $this->theme . '/images/favicon.ico" type="image/x-icon" />'; } if (api_is_multiple_url_enabled()) { $access_url_id = api_get_current_access_url_id(); if ($access_url_id != -1) { $url_info = api_get_access_url($access_url_id); $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_APP_PATH) . 'home/' . $clean_url; //we create the new dir for the new sites if (is_file($icon_real_homep . 'favicon.ico')) { $favico = '<link rel="shortcut icon" href="' . $homep . 'favicon.ico" type="image/x-icon" />'; } } } $this->assign('favico', $favico); $this->setHelp(); //@todo move this in the template $bug_notification_link = ''; if (api_get_setting('show_link_bug_notification') == 'true' && $this->user_is_logged_in) { $bug_notification_link = '<li class="report"> <a href="http://support.chamilo.org/projects/chamilo-18/wiki/How_to_report_bugs" target="_blank"> <img src="' . api_get_path(WEB_IMG_PATH) . 'bug.large.png" style="vertical-align: middle;" alt="' . get_lang('ReportABug') . '" title="' . get_lang('ReportABug') . '"/></a> </li>'; } $this->assign('bug_notification_link', $bug_notification_link); $notification = return_notification_menu(); $this->assign('notification_menu', $notification); $resize = ''; if (api_get_setting('accessibility_font_resize') == 'true') { $resize .= '<div class="resize_font">'; $resize .= '<div class="btn-group">'; $resize .= '<a title="' . get_lang('DecreaseFontSize') . '" href="#" class="decrease_font btn btn-default"><em class="fa fa-font"></em></a>'; $resize .= '<a title="' . get_lang('ResetFontSize') . '" href="#" class="reset_font btn btn-default"><em class="fa fa-font"></em></a>'; $resize .= '<a title="' . get_lang('IncreaseFontSize') . '" href="#" class="increase_font btn btn-default"><em class="fa fa-font"></em></a>'; $resize .= '</div>'; $resize .= '</div>'; } $this->assign('accessibility', $resize); // Preparing values for the menu // Logout link $hideLogout = api_get_setting('hide_logout_button'); if ($hideLogout === 'true') { $this->assign('logout_link', null); } else { $this->assign('logout_link', api_get_path(WEB_PATH) . 'index.php?logout=logout&uid=' . api_get_user_id()); } //Profile link if (api_get_setting('social.allow_social_tool') == 'true') { $profile_url = api_get_path(WEB_CODE_PATH) . 'social/home.php'; $profile_link = Display::url(get_lang('Profile'), $profile_url); } else { $profile_url = api_get_path(WEB_CODE_PATH) . 'auth/profile.php'; $profile_link = Display::url(get_lang('Profile'), $profile_url); } $this->assign('profile_link', $profile_link); $this->assign('profile_url', $profile_url); //Message link $message_link = null; $message_url = null; if (api_get_setting('message.allow_message_tool') == 'true') { $message_url = api_get_path(WEB_CODE_PATH) . 'messages/inbox.php'; $message_link = '<a href="' . api_get_path(WEB_CODE_PATH) . 'messages/inbox.php">' . get_lang('Inbox') . '</a>'; } $this->assign('message_link', $message_link); $this->assign('message_url', $message_url); $institution = api_get_setting('platform.institution'); $portal_name = empty($institution) ? api_get_setting('platform.site_name') : $institution; $this->assign('portal_name', $portal_name); //Menu $menu = return_menu(); $this->assign('menu', $menu); // Setting notifications $count_unread_message = 0; if (api_get_setting('message.allow_message_tool') == 'true') { // get count unread message and total invitations $count_unread_message = MessageManager::get_number_of_messages(true); } $total_invitations = 0; if (api_get_setting('social.allow_social_tool') == 'true') { $number_of_new_messages_of_friend = SocialManager::get_message_number_invitation_by_user_id(api_get_user_id()); $usergroup = new UserGroup(); $group_pending_invitations = $usergroup->get_groups_by_user(api_get_user_id(), GROUP_USER_PERMISSION_PENDING_INVITATION, false); if (!empty($group_pending_invitations)) { $group_pending_invitations = count($group_pending_invitations); } else { $group_pending_invitations = 0; } $total_invitations = intval($number_of_new_messages_of_friend) + $group_pending_invitations + intval($count_unread_message); } $total_invitations = !empty($total_invitations) ? Display::badge($total_invitations) : null; $this->assign('user_notifications', $total_invitations); // Block Breadcrumb $breadcrumb = return_breadcrumb($interbreadcrumb, $language_file, $nameTools); $this->assign('breadcrumb', $breadcrumb); //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); if ($sendHeaders) { header('Content-Type: text/html; charset=' . api_get_system_encoding()); header('X-Powered-By: ' . $_configuration['software_name'] . ' ' . substr($_configuration['system_version'], 0, 1)); } $socialMeta = ''; $metaTitle = api_get_setting('meta_title'); if (!empty($metaTitle)) { $socialMeta .= '<meta name="twitter:card" content="summary" />' . "\n"; $socialMeta .= '<meta property="og:title" content="' . $metaTitle . '" />' . "\n"; $socialMeta .= '<meta property="og:url" content="' . api_get_path(WEB_PATH) . '" />' . "\n"; $metaDescription = api_get_setting('meta_description'); if (!empty($metaDescription)) { $socialMeta .= '<meta property="og:description" content="' . $metaDescription . '" />' . "\n"; } $metaSite = api_get_setting('meta_twitter_site'); if (!empty($metaSite)) { $socialMeta .= '<meta name="twitter:site" content="' . $metaSite . '" />' . "\n"; $metaCreator = api_get_setting('meta_twitter_creator'); if (!empty($metaCreator)) { $socialMeta .= '<meta name="twitter:creator" content="' . $metaCreator . '" />' . "\n"; } } $metaImage = api_get_setting('meta_image_path'); if (!empty($metaImage)) { if (is_file(api_get_path(SYS_PATH) . $metaImage)) { $path = api_get_path(WEB_PATH) . $metaImage; $socialMeta .= '<meta property="og:image" content="' . $path . '" />' . "\n"; } } } $this->assign('social_meta', $socialMeta); }
/** * Create a new empty directory with index.html file * @param string $name The new directory name * @param string $parentDirectory Directory parent directory name * @return boolean Return true if the directory was create. Otherwise return false */ function api_create_protected_dir($name, $parentDirectory) { $isCreated = false; if (!is_writable($parentDirectory)) { return false; } $fullPath = $parentDirectory . api_replace_dangerous_char($name); if (mkdir($fullPath, api_get_permissions_for_new_directories(), true)) { $fp = fopen($fullPath . '/index.html', 'w'); if ($fp) { if (fwrite($fp, '<html><head></head><body></body></html>')) { $isCreated = true; } } fclose($fp); } return $isCreated; }
/** * Quite similar to display_complete_report(), returns an HTML string * that can be used in a csv file * @todo consider merging this function with display_complete_report * @return string The contents of a csv file * @author Patrick Cool <*****@*****.**>, Ghent University * @version February 2007 */ static function export_complete_report_xls($survey_data, $filename, $user_id = 0) { $spreadsheet = new PHPExcel(); $spreadsheet->setActiveSheetIndex(0); $worksheet = $spreadsheet->getActiveSheet(); $line = 0; $column = 1; // Skip the first column (row titles) // Show extra fields blank space (enough for extra fields on next line) //if (!empty($_REQUEST['fields_filter'])) { // Show user fields section with a big th colspan that spans over all fields $extra_user_fields = UserManager::get_extra_fields(0, 0, 5, 'ASC', false, true); $num = count($extra_user_fields); for ($i = 0; $i < $num; $i++) { $worksheet->SetCellValueByColumnAndRow($line, $column, ''); $column++; } $display_extra_user_fields = true; //} // Database table definitions $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION); $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION); $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER); $course_id = api_get_course_int_id(); // First line (questions) $sql = "SELECT\n questions.question_id,\n questions.type,\n questions.survey_question,\n count(options.question_option_id) as number_of_options\n\t\t\t\tFROM {$table_survey_question} questions\n\t\t\t\tLEFT JOIN {$table_survey_question_option} options\n ON questions.question_id = options.question_id AND options.c_id = {$course_id}\n\t\t\t\tWHERE\n\t\t\t\t questions.survey_id = '" . intval($_GET['survey_id']) . "' AND\n\t\t\t\t questions.c_id = {$course_id}\n\t\t\t\tGROUP BY questions.question_id\n\t\t\t\tORDER BY questions.sort ASC"; $result = Database::query($sql); while ($row = Database::fetch_array($result)) { // We show the questions if // 1. there is no question filter and the export button has not been clicked // 2. there is a quesiton filter but the question is selected for display if (!$_POST['submit_question_filter'] || is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter'])) { // We do not show comment and pagebreak question types if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') { if ($row['number_of_options'] == 0 && $row['type'] == 'open') { $worksheet->SetCellValueByColumnAndRow($line, $column, api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)); $column++; } else { for ($ii = 0; $ii < $row['number_of_options']; $ii++) { $worksheet->SetCellValueByColumnAndRow($line, $column, api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)); $column++; } } } } } $line++; $column = 1; // Show extra field values if ($display_extra_user_fields) { // Show the fields names for user fields foreach ($extra_user_fields as &$field) { $worksheet->SetCellValueByColumnAndRow($line, $column, api_html_entity_decode(strip_tags($field[3]), ENT_QUOTES)); $column++; } } // Getting all the questions and options (second line) $sql = "SELECT\n survey_question.question_id, survey_question.survey_id, survey_question.survey_question, survey_question.display, survey_question.sort, survey_question.type,\n survey_question_option.question_option_id, survey_question_option.option_text, survey_question_option.sort as option_sort\n\t\t\t\tFROM {$table_survey_question} survey_question\n\t\t\t\tLEFT JOIN {$table_survey_question_option} survey_question_option\n\t\t\t\tON survey_question.question_id = survey_question_option.question_id AND survey_question_option.c_id = {$course_id}\n\t\t\t\tWHERE survey_question.survey_id = '" . intval($_GET['survey_id']) . "' AND\n\t\t\t\tsurvey_question.c_id = {$course_id}\n\t\t\t\tORDER BY survey_question.sort ASC, survey_question_option.sort ASC"; $result = Database::query($sql); $possible_answers = array(); $possible_answers_type = array(); while ($row = Database::fetch_array($result)) { // We show the options if // 1. there is no question filter and the export button has not been clicked // 2. there is a quesiton filter but the question is selected for display if (!$_POST['submit_question_filter'] || is_array($_POST['questions_filter']) && in_array($row['question_id'], $_POST['questions_filter'])) { // We do not show comment and pagebreak question types if ($row['type'] != 'comment' && $row['type'] != 'pagebreak') { $worksheet->SetCellValueByColumnAndRow($line, $column, api_html_entity_decode(strip_tags($row['option_text']), ENT_QUOTES)); $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id']; $possible_answers_type[$row['question_id']] = $row['type']; $column++; } } } // Getting all the answers of the users $line++; $column = 0; $old_user = ''; $answers_of_user = array(); $sql = "SELECT * FROM {$table_survey_answer}\n WHERE c_id = {$course_id} AND survey_id='" . intval($_GET['survey_id']) . "' "; if ($user_id != 0) { $sql .= "AND user='******' "; } $sql .= "ORDER BY user ASC"; $open_question_iterator = 1; $result = Database::query($sql); while ($row = Database::fetch_array($result)) { if ($old_user != $row['user'] && $old_user != '') { $return = SurveyUtil::export_complete_report_row_xls($survey_data, $possible_answers, $answers_of_user, $old_user, true); foreach ($return as $elem) { $worksheet->SetCellValueByColumnAndRow($line, $column, $elem); $column++; } $answers_of_user = array(); $line++; $column = 0; } if ($possible_answers_type[$row['question_id']] == 'open') { $temp_id = 'open' . $open_question_iterator; $answers_of_user[$row['question_id']][$temp_id] = $row; $open_question_iterator++; } else { $answers_of_user[$row['question_id']][$row['option_id']] = $row; } $old_user = $row['user']; } $return = SurveyUtil::export_complete_report_row_xls($survey_data, $possible_answers, $answers_of_user, $old_user, true); // this is to display the last user foreach ($return as $elem) { $worksheet->SetCellValueByColumnAndRow($line, $column, $elem); $column++; } $file = api_get_path(SYS_ARCHIVE_PATH) . api_replace_dangerous_char($filename); $writer = new PHPExcel_Writer_Excel2007($spreadsheet); $writer->save($file); DocumentManager::file_send_for_download($file, true, $filename); return null; }
/** * This function streams a file to the client * * @param string $full_file_name * @param boolean $forced * @param string $name * @return false if file doesn't exist, true if stream succeeded */ public static function file_send_for_download($full_file_name, $forced = false, $name = '') { if (!is_file($full_file_name)) { return false; } $filename = $name == '' ? basename($full_file_name) : api_replace_dangerous_char($name); $len = filesize($full_file_name); if ($forced) { //force the browser to save the file instead of opening it header('Content-type: application/octet-stream'); //header('Content-Type: application/force-download'); header('Content-length: ' . $len); if (preg_match("/MSIE 5.5/", $_SERVER['HTTP_USER_AGENT'])) { header('Content-Disposition: filename= ' . $filename); } else { header('Content-Disposition: attachment; filename= ' . $filename); } if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) { header('Pragma: '); header('Cache-Control: '); header('Cache-Control: public'); // IE cannot download from sessions without a cache } header('Content-Description: ' . $filename); header('Content-transfer-encoding: binary'); $fp = fopen($full_file_name, 'r'); fpassthru($fp); return true; } else { //no forced download, just let the browser decide what to do according to the mimetype $content_type = self::file_get_mime_type($filename); header('Expires: Wed, 01 Jan 1990 00:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // Commented to avoid double caching declaration when playing with IE and HTTPS //header('Cache-Control: no-cache, must-revalidate'); //header('Pragma: no-cache'); switch ($content_type) { case 'text/html': $encoding = Text::api_detect_encoding_html(file_get_contents($full_file_name)); if (!empty($encoding)) { $content_type .= '; charset=' . $encoding; } break; case 'text/plain': $encoding = Text::api_detect_encoding(strip_tags(file_get_contents($full_file_name))); if (!empty($encoding)) { $content_type .= '; charset=' . $encoding; } break; } header('Content-type: ' . $content_type); header('Content-Length: ' . $len); $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']); if (strpos($user_agent, 'msie')) { header('Content-Disposition: ; filename= ' . $filename); } else { header('Content-Disposition: inline; filename= ' . $filename); } readfile($full_file_name); return true; } }
/** * Imports a zip file into the Chamilo structure * @param string Zip file info as given by $_FILES['userFile'] * @return string Absolute path to the imsmanifest.xml file or empty string on error */ function import_package($zip_file_info, $current_dir = '') { if ($this->debug > 0) { error_log('In scorm::import_package(' . print_r($zip_file_info, true) . ',"' . $current_dir . '") method', 0); } $maxFilledSpace = DocumentManager::get_course_quota(); $zip_file_path = $zip_file_info['tmp_name']; $zip_file_name = $zip_file_info['name']; if ($this->debug > 1) { error_log('New LP - import_package() - zip file path = ' . $zip_file_path . ', zip file name = ' . $zip_file_name, 0); } // scorm dir web path starting from /courses $course_rel_dir = api_get_course_path() . '/scorm'; $course_sys_dir = api_get_path(SYS_COURSE_PATH) . $course_rel_dir; // Absolute system path for this course. if (!is_dir($course_sys_dir)) { mkdir($course_sys_dir, api_get_permissions_for_new_directories()); } $current_dir = api_replace_dangerous_char(trim($current_dir), 'strict'); // Current dir we are in, inside scorm/ if ($this->debug > 1) { error_log('New LP - import_package() - current_dir = ' . $current_dir, 0); } //$uploaded_filename = $_FILES['userFile']['name']; // Get name of the zip file without the extension. if ($this->debug > 1) { error_log('New LP - Received zip file name: ' . $zip_file_path, 0); } $file_info = pathinfo($zip_file_name); $filename = $file_info['basename']; $extension = $file_info['extension']; $file_base_name = str_replace('.' . $extension, '', $filename); // Filename without its extension. $this->zipname = $file_base_name; // Save for later in case we don't have a title. if ($this->debug > 1) { error_log("New LP - base file name is : " . $file_base_name, 0); } $new_dir = api_replace_dangerous_char(trim($file_base_name), 'strict'); $this->subdir = $new_dir; if ($this->debug > 1) { error_log("New LP - subdir is first set to : " . $this->subdir, 0); } $zipFile = new PclZip($zip_file_path); // Check the zip content (real size and file extension). $zipContentArray = $zipFile->listContent(); $package_type = ''; $at_root = false; $manifest = ''; $realFileSize = 0; $manifest_list = array(); // The following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?). foreach ($zipContentArray as $thisContent) { $file = $thisContent['filename']; //error_log('Looking at '.$thisContent['filename'], 0); if (preg_match('~.(php.*|phtml)$~i', $file)) { $this->set_error_msg("File {$file} contains a PHP script"); //return api_failure::set_failure('php_file_in_zip_file'); } elseif (stristr($thisContent['filename'], 'imsmanifest.xml')) { //error_log('Found imsmanifest at '.$thisContent['filename'], 0); if ($thisContent['filename'] == basename($thisContent['filename'])) { $at_root = true; } else { //$this->subdir .= '/'.dirname($thisContent['filename']); if ($this->debug > 2) { error_log("New LP - subdir is now " . $this->subdir, 0); } } $package_type = 'scorm'; $manifest_list[] = $thisContent['filename']; $manifest = $thisContent['filename']; //just the relative directory inside scorm/ } else { // Do nothing, if it has not been set as scorm somewhere else, it stays as '' default. } $realFileSize += $thisContent['size']; } // Now get the shortest path (basically, the imsmanifest that is the closest to the root). $shortest_path = $manifest_list[0]; $slash_count = substr_count($shortest_path, '/'); foreach ($manifest_list as $manifest_path) { $tmp_slash_count = substr_count($manifest_path, '/'); if ($tmp_slash_count < $slash_count) { $shortest_path = $manifest_path; $slash_count = $tmp_slash_count; } } $this->subdir .= '/' . dirname($shortest_path); // Do not concatenate because already done above. $manifest = $shortest_path; if ($this->debug > 1) { error_log('New LP - Package type is now ' . $package_type, 0); } // && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) if ($package_type == '') { if ($this->debug > 1) { error_log('New LP - Package type is empty', 0); } return api_failure::set_failure('not_scorm_content'); } // It happens on Linux that $new_dir sometimes doesn't start with '/' if ($new_dir[0] != '/') { $new_dir = '/' . $new_dir; } if ($new_dir[strlen($new_dir) - 1] == '/') { $new_dir = substr($new_dir, 0, -1); } $isDir = is_dir($course_sys_dir . $new_dir); if ($isDir == false) { mkdir($course_sys_dir . $new_dir, api_get_permissions_for_new_directories()); $isDir = is_dir($course_sys_dir . $new_dir); } /* Uncompressing phase */ /* We need to process each individual file in the zip archive to - add it to the database - parse & change relative html links - make sure the filenames are secure (filter funny characters or php extensions) */ if ($isDir) { if (!FileManager::enough_size($realFileSize, $course_sys_dir, $maxFilledSpace)) { if ($this->debug > 1) { error_log('New LP - Not enough space to store package', 0); } return api_failure::set_failure('not_enough_space'); } // PHP method - slower... if ($this->debug >= 1) { error_log('New LP - Changing dir to ' . $course_sys_dir . $new_dir, 0); } $saved_dir = getcwd(); chdir($course_sys_dir . $new_dir); $unzippingState = $zipFile->extract(); for ($j = 0; $j < count($unzippingState); $j++) { $state = $unzippingState[$j]; // TODO: Fix relative links in html files (?) $extension = strrchr($state['stored_filename'], '.'); if ($this->debug >= 1) { error_log('New LP - found extension ' . $extension . ' in ' . $state['stored_filename'], 0); } } if (!empty($new_dir)) { $new_dir = $new_dir . '/'; } // Rename files, for example with \\ in it. if ($this->debug >= 1) { error_log('New LP - try to open: ' . $course_sys_dir . $new_dir, 0); } if ($dir = @opendir($course_sys_dir . $new_dir)) { if ($this->debug >= 1) { error_log('New LP - Opened dir ' . $course_sys_dir . $new_dir, 0); } while ($file = readdir($dir)) { if ($file != '.' && $file != '..') { $filetype = 'file'; if (is_dir($course_sys_dir . $new_dir . $file)) { $filetype = 'folder'; } // TODO: RENAMING FILES CAN BE VERY DANGEROUS SCORM-WISE, avoid that as much as possible! //$safe_file = replace_dangerous_char($file, 'strict'); $find_str = array('\\', '.php', '.phtml'); $repl_str = array('/', '.txt', '.txt'); $safe_file = str_replace($find_str, $repl_str, $file); if ($this->debug >= 1) { error_log('Comparing: ' . $safe_file, 0); } if ($this->debug >= 1) { error_log('and: ' . $file, 0); } if ($safe_file != $file) { $mydir = dirname($course_sys_dir . $new_dir . $safe_file); if (!is_dir($mydir)) { $mysubdirs = split('/', $mydir); $mybasedir = '/'; foreach ($mysubdirs as $mysubdir) { if (!empty($mysubdir)) { $mybasedir = $mybasedir . $mysubdir . '/'; if (!is_dir($mybasedir)) { @mkdir($mybasedir, api_get_permissions_for_new_directories()); if ($this->debug >= 1) { error_log('New LP - Dir ' . $mybasedir . ' doesnt exist. Creating.', 0); } } } } } @rename($course_sys_dir . $new_dir . $file, $course_sys_dir . $new_dir . $safe_file); if ($this->debug >= 1) { error_log('New LP - Renaming ' . $course_sys_dir . $new_dir . $file . ' to ' . $course_sys_dir . $new_dir . $safe_file, 0); } } } } closedir($dir); chdir($saved_dir); api_chmod_R($course_sys_dir . $new_dir, api_get_permissions_for_new_directories()); if ($this->debug > 1) { error_log('New LP - changed back to init dir: ' . $course_sys_dir . $new_dir, 0); } } } else { return ''; } return $course_sys_dir . $new_dir . $manifest; }
/** * Generates a course code from a course title * @todo Such a function might be useful in other places too. It might be moved in the CourseManager class. * @todo the function might be upgraded for avoiding code duplications (currently, it might suggest a code that is already in use) * @param string $title A course title * @return string A proposed course code * + * @assert (null,null) === false * @assert ('ABC_DEF', null) === 'ABCDEF' * @assert ('ABC09*^[%A', null) === 'ABC09A' */ public static function generate_course_code($title) { return substr(preg_replace('/[^A-Z0-9]/', '', strtoupper(api_replace_dangerous_char($title))), 0, CourseManager::MAX_COURSE_LENGTH_CODE); }
/** * Generate a default certificate for a courses * * @global string $css CSS directory * @global string $img_dir image directory * @global string $default_course_dir Course directory * @global string $js JS directory * @param array $courseData The course info * @param bool $fromBaseCourse * @param int $sessionId */ public static function generateDefaultCertificate($courseData, $fromBaseCourse = false, $sessionId = 0) { global $css, $img_dir, $default_course_dir, $js; $codePath = api_get_path(REL_CODE_PATH); $dir = '/certificates'; $title = get_lang('DefaultCertificate'); $comment = null; $fileName = api_replace_dangerous_char($title); $filePath = api_get_path(SYS_COURSE_PATH) . "{$courseData['path']}/document{$dir}"; $fileFullPath = "{$filePath}/{$fileName}.html"; $fileSize = 0; $fileType = 'file'; $templateContent = file_get_contents(api_get_path(SYS_CODE_PATH) . 'gradebook/certificate_template/template.html'); $search = array('{CSS}', '{IMG_DIR}', '{REL_CODE_PATH}', '{COURSE_DIR}'); $replace = array($css . $js, $img_dir, $codePath, $default_course_dir); $fileContent = str_replace($search, $replace, $templateContent); $saveFilePath = "{$dir}/{$fileName}.html"; if (!is_dir($filePath)) { mkdir($filePath, api_get_permissions_for_new_directories()); } if ($fromBaseCourse) { $defaultCertificateId = self::get_default_certificate_id($courseData['code'], 0); if (!empty($defaultCertificateId)) { // We have a certificate from the course base $documentData = DocumentManager::get_document_data_by_id($defaultCertificateId, $courseData['code'], false, 0); if ($documentData) { $fileContent = file_get_contents($documentData['absolute_path']); } } } $defaultCertificateFile = $fp = @fopen($fileFullPath, 'w'); if ($defaultCertificateFile != false) { @fputs($defaultCertificateFile, $fileContent); fclose($defaultCertificateFile); chmod($fileFullPath, api_get_permissions_for_new_files()); $fileSize = filesize($fileFullPath); } $documentId = add_document($courseData, $saveFilePath, $fileType, $fileSize, $title, $comment, 0, true, null, $sessionId); api_item_property_update($courseData, TOOL_DOCUMENT, $documentId, 'DocumentAdded', api_get_user_id(), null, null, null, null, $sessionId); $defaultCertificateId = self::get_default_certificate_id($courseData['code'], $sessionId); if (!isset($defaultCertificateId)) { self::attach_gradebook_certificate($courseData['code'], $documentId, $sessionId); } }
// end if is_uploaded_file // If file name given to get in /upload/, try importing this way. // A file upload has been detected, now deal with the file... // Directory creation. $stopping_error = false; if (!isset($_POST['file_name'])) { return false; } // Escape path with basename so it can only be directly into the archive/ directory. $s = api_get_path(SYS_ARCHIVE_PATH) . basename($_POST['file_name']); // Get name of the zip file without the extension $info = pathinfo($s); $filename = $info['basename']; $extension = $info['extension']; $file_base_name = str_replace('.' . $extension, '', $filename); $new_dir = api_replace_dangerous_char(trim($file_base_name)); $result = learnpath::verify_document_size($s); if ($result == true) { throw new \Exception(get_lang('UplFileTooBig')); } $type = learnpath::get_package_type($s, basename($s)); switch ($type) { case 'scorm': require_once 'scorm.class.php'; $oScorm = new scorm(); $manifest = $oScorm->import_local_package($s, $current_dir); if ($manifest === false) { throw new \Exception('Error import local package'); } if (!empty($manifest)) { $oScorm->parse_manifest($manifest);
/** * Create a group * @param string $name The name for this group * @param int $tutor The user-id of the group's tutor * @param int $places How many people can subscribe to the new group */ public static function create_group($name, $category_id, $tutor, $places) { $_course = api_get_course_info(); $table_group = Database::get_course_table(TABLE_GROUP); $session_id = api_get_session_id(); $course_id = api_get_course_int_id(); $currentCourseRepository = $_course['path']; $category = self::get_category($category_id); $places = intval($places); if ($places == 0) { //if the amount of users per group is not filled in, use the setting from the category $places = $category['max_student']; } else { if ($places > $category['max_student'] && $category['max_student'] != 0) { $places = $category['max_student']; } } $sql = "INSERT INTO " . $table_group . " SET\n c_id = {$course_id} ,\n category_id='" . Database::escape_string($category_id) . "',\n max_student = '" . $places . "',\n doc_state = '" . $category['doc_state'] . "',\n calendar_state = '" . $category['calendar_state'] . "',\n work_state = '" . $category['work_state'] . "',\n announcements_state = '" . $category['announcements_state'] . "',\n forum_state = '" . $category['forum_state'] . "',\n wiki_state = '" . $category['wiki_state'] . "',\n chat_state = '" . $category['chat_state'] . "',\n self_registration_allowed = '" . $category['self_reg_allowed'] . "',\n self_unregistration_allowed = '" . $category['self_unreg_allowed'] . "',\n session_id='" . Database::escape_string($session_id) . "'"; Database::query($sql); $lastId = Database::insert_id(); if ($lastId) { $desired_dir_name = '/' . api_replace_dangerous_char($name, 'strict') . '_groupdocs'; $my_path = api_get_path(SYS_COURSE_PATH) . $currentCourseRepository . '/document'; $unique_name = FileManager::create_unexisting_directory($_course, api_get_user_id(), $session_id, $lastId, NULL, $my_path, $desired_dir_name); /* Stores the directory path into the group table */ $sql = "UPDATE " . $table_group . " SET name = '" . Database::escape_string($name) . "', secret_directory = '" . $unique_name . "'\n WHERE c_id = {$course_id} AND iid ='" . $lastId . "'"; Database::query($sql); // create a forum if needed if ($category['forum_state'] >= 0) { require_once api_get_path(SYS_CODE_PATH) . 'forum/forumconfig.inc.php'; require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; $forum_categories = get_forum_categories(); $values = array(); $values['forum_title'] = $name; $values['group_id'] = $lastId; $counter = 0; foreach ($forum_categories as $key => $value) { if ($counter == 0) { $forum_category_id = $key; } $counter++; } // A sanity check. if (empty($forum_category_id)) { $forum_category_id = 0; } $values['forum_category'] = $forum_category_id; $values['allow_anonymous_group']['allow_anonymous'] = 0; $values['students_can_edit_group']['students_can_edit'] = 0; $values['approval_direct_group']['approval_direct'] = 0; $values['allow_attachments_group']['allow_attachments'] = 1; $values['allow_new_threads_group']['allow_new_threads'] = 1; $values['default_view_type_group']['default_view_type'] = api_get_setting('default_forum_view'); $values['group_forum'] = $lastId; if ($category['forum_state'] == '1') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'public'; } elseif ($category['forum_state'] == '2') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'private'; } elseif ($category['forum_state'] == '0') { $values['public_private_group_forum_group']['public_private_group_forum'] = 'unavailable'; } store_forum($values); } } return $lastId; }
$webcamname = $params['webcamname']; $webcamdir = $params['webcamdir']; $webcamuserid = $params['webcamuserid']; } else { api_not_allowed(); die; } if ($webcamuserid != api_get_user_id() || api_get_user_id() == 0 || $webcamuserid == 0) { api_not_allowed(); die; } //clean $webcamname = Security::remove_XSS($webcamname); $webcamname = Database::escape_string($webcamname); $webcamname = addslashes(trim($webcamname)); $webcamname = api_replace_dangerous_char($webcamname, 'strict'); $webcamname = FileManager::disable_dangerous_file($webcamname); $webcamdir = Security::remove_XSS($webcamdir); //security extension $ext = explode('.', $webcamname); $ext = strtolower($ext[sizeof($ext) - 1]); if ($ext != 'jpg') { die; } //Do not use here check Fileinfo method because return: text/plain //CHECK THIS BEFORE COMMIT $dirBaseDocuments = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document'; $saveDir = $dirBaseDocuments . $webcamdir; $current_session_id = api_get_session_id(); $groupId = $_SESSION['_gid']; //avoid duplicates $webcamname_to_save = $webcamname;
/** * Creates new group pictures in various sizes of a user, or deletes user pfotos. * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php * @param int The group id * @param string $file The common file name for the newly created photos. * It will be checked and modified for compatibility with the file system. * If full name is provided, path component is ignored. * If an empty name is provided, then old user photos are deleted only, * @see UserManager::delete_user_picture() as the prefered way for deletion. * @param string $source_file The full system name of the image from which user photos will be created. * @return string/bool Returns the resulting common file name of created images which usually should be stored in database. * When an image is removed the function returns an empty string. In case of internal error or negative validation it returns FALSE. */ public function update_group_picture($group_id, $file = null, $source_file = null) { // Validation 1. if (empty($group_id)) { return false; } $delete = empty($file); if (empty($source_file)) { $source_file = $file; } // User-reserved directory where photos have to be placed. $path_info = self::get_group_picture_path_by_id($group_id, 'system', true); $path = $path_info['dir']; // If this directory does not exist - we create it. if (!file_exists($path)) { @mkdir($path, api_get_permissions_for_new_directories(), true); } // The old photos (if any). $old_file = $path_info['file']; // Let us delete them. if (!empty($old_file)) { if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) { $prefix = 'saved_' . date('Y_m_d_H_i_s') . '_' . uniqid('') . '_'; @rename($path . 'small_' . $old_file, $path . $prefix . 'small_' . $old_file); @rename($path . 'medium_' . $old_file, $path . $prefix . 'medium_' . $old_file); @rename($path . 'big_' . $old_file, $path . $prefix . 'big_' . $old_file); @rename($path . $old_file, $path . $prefix . $old_file); } else { @unlink($path . 'small_' . $old_file); @unlink($path . 'medium_' . $old_file); @unlink($path . 'big_' . $old_file); @unlink($path . $old_file); } } // Exit if only deletion has been requested. Return an empty picture name. if ($delete) { return ''; } // Validation 2. $allowed_types = array('jpg', 'jpeg', 'png', 'gif'); $file = str_replace('\\', '/', $file); $filename = ($pos = strrpos($file, '/')) !== false ? substr($file, $pos + 1) : $file; $extension = strtolower(substr(strrchr($filename, '.'), 1)); if (!in_array($extension, $allowed_types)) { return false; } // This is the common name for the new photos. if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && !empty($old_file)) { $old_extension = strtolower(substr(strrchr($old_file, '.'), 1)); $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file; $filename = substr($filename, -1) == '.' ? $filename . $extension : $filename . '.' . $extension; } else { $filename = api_replace_dangerous_char($filename); if (PREFIX_IMAGE_FILENAME_WITH_UID) { $filename = uniqid('') . '_' . $filename; } // We always prefix user photos with user ids, so on setting // api_get_setting('split_users_upload_directory') === 'true' // the correspondent directories to be found successfully. $filename = $group_id . '_' . $filename; } // Storing the new photos in 4 versions with various sizes. /*$image->resize( // get original size and set width (widen) or height (heighten). // width or height will be set maintaining aspect ratio. $image->getSize()->widen( 700 ) );*/ // Usign the Imagine service $imagine = new Imagine\Gd\Imagine(); $image = $imagine->open($source_file); $options = array('quality' => 90); //$image->resize(new Imagine\Image\Box(200, 200))->save($path.'big_'.$filename); $image->resize($image->getSize()->widen(200))->save($path . 'big_' . $filename, $options); $image = $imagine->open($source_file); $image->resize(new Imagine\Image\Box(85, 85))->save($path . 'medium_' . $filename, $options); $image = $imagine->open($source_file); $image->resize(new Imagine\Image\Box(22, 22))->save($path . 'small_' . $filename); /* $small = self::resize_picture($source_file, 22); $medium = self::resize_picture($source_file, 85); $normal = self::resize_picture($source_file, 200); $big = new Image($source_file); // This is the original picture. $ok = $small && $small->send_image($path.'small_'.$filename) && $medium && $medium->send_image($path.'medium_'.$filename) && $normal && $normal->send_image($path.'big_'.$filename) && $big && $big->send_image($path.$filename); return $ok ? $filename : false;*/ return $filename; }
/** * Displays step 3 - a form where the user can enter the installation settings * regarding the databases - login and password, names, prefixes, single * or multiple databases, tracking or not... */ function display_database_settings_form($installType, $dbHostForm, $dbUsernameForm, $dbPassForm, $dbPrefixForm, $enableTrackingForm, $singleDbForm, $dbNameForm) { if ($installType == 'update') { global $_configuration, $update_from_version_6; if (in_array($_POST['old_version'], $update_from_version_6)) { $dbHostForm = get_config_param('dbHost'); $dbUsernameForm = get_config_param('dbLogin'); $dbPassForm = get_config_param('dbPass'); $dbPrefixForm = get_config_param('dbNamePrefix'); $enableTrackingForm = get_config_param('is_trackingEnabled'); $singleDbForm = get_config_param('singleDbEnabled'); $dbHostForm = get_config_param('mainDbName'); $dbStatsForm = get_config_param('statsDbName'); $dbScormForm = get_config_param('scormDbName'); $dbUserForm = get_config_param('user_personal_database'); $dbScormExists = true; } else { $dbHostForm = $_configuration['db_host']; $dbUsernameForm = $_configuration['db_user']; $dbPassForm = $_configuration['db_password']; $dbPrefixForm = $_configuration['db_prefix']; $enableTrackingForm = isset($_configuration['tracking_enabled']) ? $_configuration['tracking_enabled'] : null; $singleDbForm = isset($_configuration['single_database']) ? $_configuration['single_database'] : null; $dbNameForm = $_configuration['main_database']; $dbStatsForm = isset($_configuration['statistics_database']) ? $_configuration['statistics_database'] : null; $dbScormForm = isset($_configuration['scorm_database']) ? $_configuration['scorm_database'] : null; $dbUserForm = isset($_configuration['user_personal_database']) ? $_configuration['user_personal_database'] : null; $dbScormExists = true; } if (empty($dbScormForm)) { if ($singleDbForm) { $dbScormForm = $dbNameForm; } else { $dbScormForm = $dbPrefixForm . 'scorm'; $dbScormExists = false; } } if (empty($dbUserForm)) { $dbUserForm = $singleDbForm ? $dbNameForm : $dbPrefixForm . 'chamilo_user'; } echo '<div class="RequirementHeading"><h2>' . display_step_sequence() . translate('DBSetting') . '</h2></div>'; echo '<div class="RequirementContent">'; echo translate('DBSettingUpgradeIntro'); echo '</div>'; } else { if (empty($dbPrefixForm)) { //make sure there is a default value for db prefix $dbPrefixForm = ''; } echo '<div class="RequirementHeading"><h2>' . display_step_sequence() . translate('DBSetting') . '</h2></div>'; echo '<div class="RequirementContent">'; echo translate('DBSettingIntro'); echo '</div>'; } ?> </td> </tr> <tr> <td> <table class="data_table_no_border"> <tr> <td width="40%"><?php echo translate('DBHost'); ?> </td> <?php if ($installType == 'update') { ?> <td width="30%"><input type="hidden" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?> "/><?php echo $dbHostForm; ?> </td> <td width="30%"> </td> <?php } else { ?> <td width="30%"> <input type="text" size="25" maxlength="50" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?> " /></td> <td width="30%"><?php echo translate('EG') . ' localhost'; ?> </td> <?php } ?> </tr> <tr> <?php //database user username $example_login = translate('EG') . ' root'; display_database_parameter($installType, translate('DBLogin'), 'dbUsernameForm', $dbUsernameForm, $example_login); //database user password $example_password = translate('EG') . ' ' . api_generate_password(); display_database_parameter($installType, translate('DBPassword'), 'dbPassForm', $dbPassForm, $example_password); echo '<input type="hidden" name="enableTrackingForm" value="1" />'; $style = ''; if ($installType == INSTALL_TYPE_UPDATE) { $style = ''; } //Database Name fix replace weird chars if ($installType != INSTALL_TYPE_UPDATE) { $dbNameForm = str_replace(array('-', '*', '$', ' ', '.'), '', $dbNameForm); $dbNameForm = api_replace_dangerous_char($dbNameForm); } display_database_parameter($installType, translate('MainDB'), 'dbNameForm', $dbNameForm, ' ', null, 'id="optional_param1" ' . $style); ?> <tr> <td></td> <td> <button type="submit" class="btn" name="step3"value="<?php echo translate('CheckDatabaseConnection'); ?> "> <?php echo translate('CheckDatabaseConnection'); ?> </button> </td> </tr> <tr> <td> <?php $dbConnect = testDatabaseConnect($dbHostForm, $dbUsernameForm, $dbPassForm, $singleDbForm, $dbPrefixForm, $dbNameForm); $database_exists_text = ''; if ($dbConnect) { $multipleDbCheck = Database::query("CREATE DATABASE " . mysql_real_escape_string($dbNameForm)); if ($multipleDbCheck !== false) { Database::query("DROP DATABASE IF EXISTS " . mysql_real_escape_string($dbNameForm)); $user_can_create_databases = true; } if ($user_can_create_databases) { $database_exists_text = '<div class="normal-message">' . sprintf(translate('DatabaseXWillBeCreated'), $dbNameForm, $dbUsernameForm) . '</div>'; } else { $dbConnect = 0; $database_exists_text = '<div class="warning-message">' . sprintf(translate('DatabaseXCantBeCreatedUserXDoestHaveEnoughPermissions'), $dbNameForm, $dbUsernameForm) . '</div>'; } } else { echo '<div class="warning-message">' . sprintf(translate('UserXCantHaveAccessInTheDatabaseX'), $dbUsernameForm, $dbNameForm) . '</div>'; } if ($dbConnect == 1) { ?> <td colspan="2"> <?php echo $database_exists_text; ?> <div id="db_status" class="confirmation-message"> <div style="clear:both;"></div> </div> </td> <?php } else { ?> <td colspan="2"> <?php echo $database_exists_text; ?> <div id="db_status" style="float:left;" class="error-message"> <div style="float:left;"> <strong><?php echo translate('FailedConectionDatabase'); ?> </strong><br/> </div> </div> </td> <?php } ?> </tr> <tr> <td> <button type="submit" name="step2" class="back" value="< <?php echo translate('Previous'); ?> "><?php echo translate('Previous'); ?> </button> </td> <td> </td> <td align="right"> <input type="hidden" name="is_executable" id="is_executable" value="-"/> <?php if ($dbConnect == 1) { ?> <button type="submit" class="btn next" name="step4" value="<?php echo translate('Next'); ?> >" <?php if ($dbConnect == 1) { echo 'autofocus="autofocus"'; } ?> /><?php echo translate('Next'); ?> </button> <?php } else { ?> <button disabled="disabled" type="submit" class="btn next disabled" name="step4" value="<?php echo translate('Next'); ?> >"/><?php echo translate('Next'); ?> </button> <?php } ?> </td> </tr> </table> <?php }
/** * Check if a document width the choosen filename allready exists */ function document_exists($filename) { global $filepath; $filename = addslashes(trim($filename)); $filename = Security::remove_XSS($filename); $filename = api_replace_dangerous_char($filename); $filename = FileManager::disable_dangerous_file($filename); return !file_exists($filepath . $filename . '.html'); }
if (file_exists($sys_course_path . $_course['path'] . '/' . $not_deleted_file['url']) && !empty($not_deleted_file['url'])) { $files[basename($not_deleted_file['url'])] = $filename; $addStatus = $zip_folder->add($sys_course_path . $_course['path'] . '/' . $not_deleted_file['url'], PCLZIP_OPT_REMOVE_PATH, $sys_course_path . $_course['path'] . '/work', PCLZIP_CB_PRE_ADD, 'my_pre_add_callback'); } else { // Convert texts in html files //if ($not_deleted_file['contains_file'] == 0) { $filename = trim($filename) . ".html"; $work_temp = api_get_path(SYS_ARCHIVE_PATH) . api_get_unique_id() . '_' . $filename; file_put_contents($work_temp, $not_deleted_file['description']); $files[basename($work_temp)] = $filename; $addStatus = $zip_folder->add($work_temp, PCLZIP_OPT_REMOVE_PATH, api_get_path(SYS_ARCHIVE_PATH), PCLZIP_CB_PRE_ADD, 'my_pre_add_callback'); @unlink($work_temp); } } if (!empty($files)) { $fileName = api_replace_dangerous_char($work_data['title']); // Logging Event::event_download($fileName . '.zip (folder)'); //start download of created file $name = $fileName . '.zip'; if (Security::check_abs_path($temp_zip_file, api_get_path(SYS_ARCHIVE_PATH))) { DocumentManager::file_send_for_download($temp_zip_file, true, $name); @unlink($temp_zip_file); exit; } } else { exit; } /* Extra function (only used here) */ function my_pre_add_callback($p_event, &$p_header) {