/** * Restore a course. * @param string The code of the Chamilo-course in * @param int The session id * @param bool Course settings are going to be restore? */ public function restore($destination_course_code = '', $session_id = 0, $update_course_settings = false, $respect_base_content = false) { if ($destination_course_code == '') { $course_info = api_get_course_info(); $this->destination_course_info = $course_info; $this->course->destination_path = $course_info['path']; } else { $course_info = api_get_course_info($destination_course_code); $this->destination_course_info = $course_info; $this->course->destination_path = $course_info['path']; } $this->destination_course_id = $course_info['real_id']; //Getting first teacher (for the forums) $teacher_list = CourseManager::get_teacher_list_from_course_code($course_info['real_id']); $this->first_teacher_id = api_get_user_id(); if (!empty($teacher_list)) { foreach ($teacher_list as $teacher) { $this->first_teacher_id = $teacher['user_id']; break; } } if (empty($this->course)) { return false; } // Source platform encoding - reading/detection // The correspondent data field has been added as of version 1.8.6.1 if (empty($this->course->encoding)) { // The archive has been created by a system which is prior to 1.8.6.1 version. // In this case we have to detect the encoding. $sample_text = $this->course->get_sample_text() . "\n"; // Let us exclude ASCII lines, probably they are English texts. $sample_text = explode("\n", $sample_text); foreach ($sample_text as $key => &$line) { if (api_is_valid_ascii($line)) { unset($sample_text[$key]); } } $sample_text = join("\n", $sample_text); $this->course->encoding = api_detect_encoding($sample_text, $course_info['language']); } // Encoding conversion of the course, if it is needed. $this->course->to_system_encoding(); foreach ($this->tools_to_restore as $tool) { $function_build = 'restore_' . $tool; $this->{$function_build}($session_id, $respect_base_content, $destination_course_code); } if ($update_course_settings) { $this->restore_course_settings($destination_course_code); } // Restore the item properties $table = Database::get_course_table(TABLE_ITEM_PROPERTY); $condition_session = ""; if (!empty($session_id)) { $condition_session = " , id_session='" . intval($session_id) . "'"; } foreach ($this->course->resources as $type => $resources) { if (is_array($resources)) { foreach ($resources as $id => $resource) { foreach ($resource->item_properties as $property) { // First check if there isn't allready a record for this resource $sql = "SELECT * FROM {$table} WHERE c_id = " . $this->destination_course_id . " AND tool = '" . $property['tool'] . "' AND ref = '" . $resource->destination_id . "'"; $res = Database::query($sql); if (Database::num_rows($res) == 0) { // The to_group_id and to_user_id are set to default values as users/groups possibly not exist in the target course $sql = "INSERT INTO {$table} SET\n\t\t\t\t\t\t\t\t\tc_id \t\t\t\t= '" . $this->destination_course_id . "',\n\t\t\t\t\t\t\t\t\ttool \t\t\t\t= '" . self::DBUTF8escapestring($property['tool']) . "',\n\t\t\t\t\t\t\t\t\tinsert_user_id \t\t= '" . self::DBUTF8escapestring($property['insert_user_id']) . "',\n\t\t\t\t\t\t\t\t\tinsert_date \t\t= '" . self::DBUTF8escapestring($property['insert_date']) . "',\n\t\t\t\t\t\t\t\t\tlastedit_date \t\t= '" . self::DBUTF8escapestring($property['lastedit_date']) . "',\n\t\t\t\t\t\t\t\t\tref \t\t\t\t= '" . self::DBUTF8escapestring($resource->destination_id) . "',\n\t\t\t\t\t\t\t\t\tlastedit_type \t\t= '" . self::DBUTF8escapestring($property['lastedit_type']) . "',\n\t\t\t\t\t\t\t\t\tlastedit_user_id \t= '" . self::DBUTF8escapestring($property['lastedit_user_id']) . "',\n\t\t\t\t\t\t\t\t\tvisibility \t\t\t= '" . self::DBUTF8escapestring($property['visibility']) . "',\n\t\t\t\t\t\t\t\t\tstart_visible \t\t= '" . self::DBUTF8escapestring($property['start_visible']) . "',\n\t\t\t\t\t\t\t\t\tend_visible \t\t= '" . self::DBUTF8escapestring($property['end_visible']) . "',\n\t\t\t\t\t\t\t\t\tto_user_id \t\t= '" . self::DBUTF8escapestring($property['to_user_id']) . "',\n\t\t\t\t\t\t\t\t\tto_group_id \t\t= '0' {$condition_session}"; Database::query($sql); } } } } } }
/** * Transliterates a string with arbitrary encoding into a plain ASCII string. * * Example: * echo api_transliterate(api_html_entity_decode( * 'Фёдор '. * 'Михайлович '. * 'Достоевкий', * ENT_QUOTES, 'UTF-8'), 'X', 'UTF-8'); * The output should be: Fyodor Mihaylovich Dostoevkiy * * @param string $string The input string. * @param string $unknown (optional) Replacement character for unknown characters and illegal UTF-8 sequences. * @param string $from_encoding (optional) The encoding of the input string. If it is omited, the platform character set is assumed. * @return string Plain ASCII output. * * Based on Drupal's module "Transliteration", version 6.x-2.1, 09-JUN-2009: * @author Stefan M. Kudwien (smk-ka) * @author Daniel F. Kudwien (sun) * @link http://drupal.org/project/transliteration * * See also MediaWiki's UtfNormal.php and CPAN's Text::Unidecode library * @link http://www.mediawiki.org * @link http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm). * * Adaptation for Chamilo 1.8.7, 2010 * Initial implementation for Dokeos 1.8.6.1, 12-JUN-2009 * @author Ivan Tcholakov */ function api_transliterate($string, $unknown = '?', $from_encoding = null) { static $map = array(); $string = api_utf8_encode($string, $from_encoding); // Screen out some characters that eg won't be allowed in XML. $string = preg_replace('/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/', $unknown, $string); // ASCII is always valid NFC! // If we're only ever given plain ASCII, we can avoid the overhead // of initializing the decomposition tables by skipping out early. if (api_is_valid_ascii($string)) { return $string; } static $tail_bytes; if (!isset($tail_bytes)) { // Each UTF-8 head byte is followed by a certain // number of tail bytes. $tail_bytes = array(); for ($n = 0; $n < 256; $n++) { if ($n < 0xc0) { $remaining = 0; } elseif ($n < 0xe0) { $remaining = 1; } elseif ($n < 0xf0) { $remaining = 2; } elseif ($n < 0xf8) { $remaining = 3; } elseif ($n < 0xfc) { $remaining = 4; } elseif ($n < 0xfe) { $remaining = 5; } else { $remaining = 0; } $tail_bytes[chr($n)] = $remaining; } } // Chop the text into pure-ASCII and non-ASCII areas; // large ASCII parts can be handled much more quickly. // Don't chop up Unicode areas for punctuation, though, // that wastes energy. preg_match_all('/[\\x00-\\x7f]+|[\\x80-\\xff][\\x00-\\x40\\x5b-\\x5f\\x7b-\\xff]*/', $string, $matches); $result = ''; foreach ($matches[0] as $str) { if ($str[0] < "€") { // ASCII chunk: guaranteed to be valid UTF-8 // and in normal form C, so skip over it. $result .= $str; continue; } // We'll have to examine the chunk byte by byte to ensure // that it consists of valid UTF-8 sequences, and to see // if any of them might not be normalized. // // Since PHP is not the fastest language on earth, some of // this code is a little ugly with inner loop optimizations. $head = ''; $chunk = api_byte_count($str); // Counting down is faster. I'm *so* sorry. $len = $chunk + 1; for ($i = -1; --$len;) { $c = $str[++$i]; if ($remaining = $tail_bytes[$c]) { // UTF-8 head byte! $sequence = $head = $c; do { // Look for the defined number of tail bytes... if (--$len && ($c = $str[++$i]) >= "€" && $c < "À") { // Legal tail bytes are nice. $sequence .= $c; } else { if ($len == 0) { // Premature end of string! // Drop a replacement character into output to // represent the invalid UTF-8 sequence. $result .= $unknown; break 2; } else { // Illegal tail byte; abandon the sequence. $result .= $unknown; // Back up and reprocess this byte; it may itself // be a legal ASCII or UTF-8 sequence head. --$i; ++$len; continue 2; } } } while (--$remaining); $n = ord($head); if ($n <= 0xdf) { $ord = ($n - 192) * 64 + (ord($sequence[1]) - 128); } else { if ($n <= 0xef) { $ord = ($n - 224) * 4096 + (ord($sequence[1]) - 128) * 64 + (ord($sequence[2]) - 128); } else { if ($n <= 0xf7) { $ord = ($n - 240) * 262144 + (ord($sequence[1]) - 128) * 4096 + (ord($sequence[2]) - 128) * 64 + (ord($sequence[3]) - 128); } else { if ($n <= 0xfb) { $ord = ($n - 248) * 16777216 + (ord($sequence[1]) - 128) * 262144 + (ord($sequence[2]) - 128) * 4096 + (ord($sequence[3]) - 128) * 64 + (ord($sequence[4]) - 128); } else { if ($n <= 0xfd) { $ord = ($n - 252) * 1073741824 + (ord($sequence[1]) - 128) * 16777216 + (ord($sequence[2]) - 128) * 262144 + (ord($sequence[3]) - 128) * 4096 + (ord($sequence[4]) - 128) * 64 + (ord($sequence[5]) - 128); } } } } } // Lookup and replace a character from the transliteration database. $bank = $ord >> 8; // Check if we need to load a new bank if (!isset($map[$bank])) { $file = dirname(__FILE__) . '/internationalization_database/transliteration/' . sprintf('x%02x', $bank) . '.php'; if (file_exists($file)) { $map[$bank] = (include $file); } else { $map[$bank] = array('en' => array()); } } $ord = $ord & 255; $result .= isset($map[$bank]['en'][$ord]) ? $map[$bank]['en'][$ord] : $unknown; $head = ''; } elseif ($c < "€") { // ASCII byte. $result .= $c; $head = ''; } elseif ($c < "À") { // Illegal tail bytes. if ($head == '') { $result .= $unknown; } } else { // Miscellaneous freaks. $result .= $unknown; $head = ''; } } } return $result; }