Example #1
0
 /**
  * Get dictionary detail page
  */
 function show_phrase()
 {
     global $_GET;
     $lex_classes = $this->db->get_row_assoc('SELECT * FROM lexical_class', 'lex_class', 'lex_class_name');
     $this->phrase = $this->get_phrase();
     $phrase = $this->phrase;
     $this->kbbi = new kbbi($this->msg, &$this->db);
     // if it's not marked created
     if (!$phrase['created']) {
         $this->kbbi->force_refresh = true;
         $this->kbbi->parse($_GET['phrase']);
         if ($this->kbbi->found) {
             $this->save_kbbi($_GET['phrase']);
         }
         $this->kbbi->force_refresh = false;
         $this->phrase = $this->get_phrase();
         $phrase = $this->phrase;
     }
     // if it's not marked created
     if (!$phrase['kbbi_updated']) {
         $this->kbbi->force_refresh = true;
         $this->kbbi->parse($_GET['phrase']);
         if ($this->kbbi->found) {
             $this->save_kbbi2($_GET['phrase']);
         }
         $this->kbbi->force_refresh = false;
         $this->phrase = $this->get_phrase();
         $phrase = $this->phrase;
     }
     // header
     if ($phrase['pronounciation']) {
         $pronounce = sprintf(' <small>/%s/</small>', $phrase['pronounciation']);
     }
     $ret .= sprintf('<h1>%1$s%2$s</h1>' . LF, $_GET['phrase'], $pronounce);
     // buttons
     if ($this->auth->checkAuth()) {
         $actions = array('new' => array('url' => './?mod=dictionary&action=form'), 'edit' => array('url' => './?mod=dictionary&action=form&phrase=' . $_GET['phrase']), 'delete' => array('url' => './?mod=dictionary&action=delete&phrase=' . $_GET['phrase']), 'get_kbbi' => array('url' => './?mod=dictionary&action=kbbi&phrase=' . $_GET['phrase']));
         $ret .= $this->get_action_buttons($actions, $phrase ? null : array('new', 'get_kbbi'));
     }
     $panel_head = '<div class="panel-heading">' . '<h4 class="panel-title">' . '<a data-toggle="collapse" data-parent="#accordion" ' . 'href="#%s">%s</a></h4>' . '</div>';
     // found?
     if ($phrase) {
         $i = 0;
         // PREPROCESSING
         // definition: get from actual phrase or definition
         if ($phrase['actual_phrase']) {
             $defs = array(array('def_num' => 1, 'def_text' => $phrase['actual_phrase'], 'see' => $phrase['actual_phrase']));
         } else {
             $defs = $phrase['definition'];
         }
         for ($j = 0; $j < count($defs); $j++) {
             if ($defs[$j]['lex_class'] == '') {
                 $defs[$j]['lex_class'] = $phrase['lex_class'];
             }
             $lex_class = $defs[$j]['lex_class'];
             $def_group[$lex_class][] = $defs[$j];
         }
         if ($phrase['info']) {
             $tags = explode(',', $phrase['info']);
         }
         if ($tag_count = count($tags)) {
             for ($j = 0; $j < $tag_count; $j++) {
                 $tags[$j] = trim($tags[$j]);
             }
         }
         if ($phrase['actual_phrase']) {
             $tags[] = 'var';
         }
         // show definition
         $def_count = count($defs);
         if ($def_group) {
             foreach ($def_group as $lex_key => $defs) {
                 $lex_name = $lex_classes[$lex_key] . ' (' . $lex_key . ')';
                 $ret .= sprintf('<h4>%s</h4>', $lex_name) . LF;
                 $ret .= '<ol>' . LF;
                 foreach ($defs as $def) {
                     // discipline
                     // $discipline = ($i == 0) ? $phrase['info'] : '';
                     $discipline = '';
                     if ($def['discipline']) {
                         $discipline .= $discipline ? ', ' : '';
                         $discipline .= $def['discipline'];
                     }
                     $dsc = $discipline ? '<em>(' . $this->get_abbrev($discipline) . ')</em> ' : '';
                     // start
                     $ret .= '<li>';
                     if ($def['see']) {
                         $ret .= sprintf('%3$s%4$s&rarr; <a href="%2$s%1$s">%1$s</a>', $def['see'], './?mod=dictionary&action=view&phrase=', $lex, $dsc);
                     } else {
                         $ret .= sprintf('%4$s%2$s%1$s%3$s', $def['def_text'], $dsc, $def['sample'] ? ': <span class="sample">' . $def['sample'] . '</span>' : '', $lex);
                     }
                     $ret .= '</li>' . LF;
                     $i++;
                 }
                 $ret .= '</ol>' . LF;
             }
         } else {
             $ret .= '<p>' . $this->msg['na'] . '</p>' . LF;
         }
         // labels
         $ret .= '<div style="margin-bottom:20px">';
         if ($phrase['ref_source']) {
             $ret .= sprintf('<span><a href="./?mod=dictionary&src=%2$s&srch=Cari" class="label label-info">%1$s</a></span>', $phrase['ref_source_name'], $phrase['ref_source']) . LF;
         }
         if ($tags) {
             foreach ($tags as $tag) {
                 if (array_key_exists($tag, $this->abbrevs)) {
                     $ret .= sprintf('<span class="label label-info">%1$s</span>', $this->abbrevs[$tag]) . LF;
                 }
             }
         }
         $ret .= '</div>' . LF;
         // additional info
         if ($phrase['root'] || $phrase['etymology'] || $phrase['notes'] || $phrase['reference']) {
             $ret .= '<div class="row" style="margin-bottom:20px;">' . LF;
             if ($phrase['root'] || $phrase['etymology']) {
                 $ret .= '<div class="col-sm-6">' . LF;
                 if ($phrase['root']) {
                     $ret .= '<h4 style="color:#999;">Kata Dasar</h4>' . LF;
                     $ret .= sprintf('<p style="margin-left:20px;">%s</p>' . LF, $this->merge_phrase_list($phrase['root'], 'root_phrase'));
                 }
                 // etymology
                 if ($phrase['etymology']) {
                     $ret .= '<h4 style="color:#999;">Etimologi</h4>' . LF;
                     $ret .= sprintf('<p style="margin-left:20px;">%s</p>', $phrase['etymology']) . LF;
                 }
                 $ret .= '</div>' . LF;
             }
             // reference
             if ($phrase['notes'] || $phrase['reference']) {
                 $ret .= '<div class="col-sm-6">' . LF;
                 // notes
                 if ($phrase['notes']) {
                     $ret .= '<h4 style="color:#999;">Catatan</h4>' . LF;
                     $ret .= sprintf('<p style="margin-left:20px;">%s</p>', $phrase['notes']) . LF;
                 }
                 if ($phrase['reference']) {
                     $ret .= '<h4 style="color:#999;">Tautan</h4>' . LF;
                     $ret .= '<ul>' . LF;
                     foreach ($phrase['reference'] as $reference) {
                         $ret .= sprintf('<li><a href="%2$s">%1$s</a></li>' . LF, $reference['label'] ? $reference['label'] : $reference['url'], $reference['url']);
                     }
                     $ret .= '</ul>' . LF;
                 }
                 $ret .= '</div>' . LF;
             }
             $ret .= '</div>' . LF;
         }
         // misc
         $template = '<dt>%1$s</dt><dd>' . LF . '%2$s</dd>' . LF;
         $ret .= '<div class="panel-group" id="accordion">';
         // relation and derivation
         if ($ret_related = $this->show_relation($phrase, 'related_phrase')) {
             $ret .= $this->show_panel('panelRelated', 'Kata Terkait', $ret_related);
         }
         // peribahasa
         if ($phrase['proverbs']) {
             $ret_proverb .= '<ul>' . LF;
             foreach ($phrase['proverbs'] as $proverb) {
                 $ret_proverb .= sprintf('<li><em>%1$s</em>: %2$s</li>' . LF, $proverb['proverb'], $proverb['meaning']);
             }
             $ret_proverb .= '</ul>' . LF;
             $ret .= $this->show_panel('panelProverb', 'Peribahasa', $ret_proverb);
         }
         // translation
         if ($phrase['translations']) {
             $ret_translation .= '<ul>' . LF;
             foreach ($phrase['translations'] as $translation) {
                 $ret_translation .= sprintf('<li><em>%1$s</em>: %2$s</li>' . LF, $translation['ref_source'], $translation['translation']);
             }
             $ret_translation .= '</ul>' . LF;
             $ret .= $this->show_panel('panelTranslation', 'Terjemahan', $ret_translation);
         }
         // kbbi
         if ($ret_kbbi = $this->show_kbbi()) {
             $ret .= $this->show_panel('panelKBBI', 'KBBI', $ret_kbbi);
         }
         // additional process: update relation
         if ($phrase['relation']['d']) {
             $word = $_GET['phrase'];
             $tmp = '';
             foreach ($phrase['relation']['d'] as $rel) {
                 $pattern = '/\\b' . $word . '\\b/';
                 if (preg_match($pattern, $rel['related_phrase']) && !strpos($rel['related_phrase'], '-')) {
                     $tmp .= $tmp ? ', ' : '';
                     $tmp .= "'" . $rel['related_phrase'] . "'";
                 }
             }
             if ($tmp) {
                 $sql = sprintf('UPDATE relation SET
                     rel_type = \'c\',
                     updater = \'%3$s\',
                     updated = NOW()
                     WHERE root_phrase = \'%1$s\'
                     AND related_phrase IN (%2$s);', $word, $tmp, 'compounder');
                 $this->db->exec($sql);
             }
         }
         // additional process: insert new root
         if ($phrase['root']) {
             $words = "'" . str_replace(' ', "', '", $_GET['phrase']) . "'";
             $sql = sprintf('
                 INSERT INTO relation
                 (root_phrase, related_phrase, rel_type, updater, updated)
                 SELECT phrase, \'%2$s\', \'c\', \'rooter\', NOW()
                 FROM phrase
                 WHERE phrase <> \'%2$s\' AND phrase IN (%1$s) AND phrase NOT IN
                     (SELECT root_phrase FROM relation
                     WHERE related_phrase = \'%2$s\');', $words, $_GET['phrase']);
             $this->db->exec($sql);
         }
     } else {
         $ret .= sprintf('<p style="margin-bottom:20px;">%1$s</p>', sprintf($this->msg['phrase_na'], $_GET['phrase']));
         // derivation and relation
         $this->get_relation(&$phrase, 'related_phrase', true);
         $ret .= $this->show_panel('panelRelated', 'Kata Terkait', $this->show_relation($phrase, 'root_phrase'));
     }
     // glosarium
     $_GET['lang'] = 'id';
     $glossary = new glossary(&$this->db, &$this->auth, $this->msg);
     $glos_in = isset($_GET['p']) ? ' in' : '';
     $glossary->sublist = true;
     if ($ret_glossary = $glossary->show_result()) {
         $glossary_label = sprintf('Glosarium <span class="badge">%s</span>', $glossary->db->pager['rcount']);
         $ret .= $this->show_panel('panelGlossary', $glossary_label, $ret_glossary, $glos_in);
     }
     $ret .= '</div>' . LF;
     // navigation
     if ($phrase) {
         $ret .= '<div style="margin-top:20px; text-align:center;">' . $this->get_prev_next($_GET['phrase']) . '</div>';
     }
     return $ret;
 }
Example #2
0
 /**
  * Clear duplicate glossary terms
  *
  * There are times that the system may end up with duplicate glossary terms, like when
  * copying content. This function is used to effectively eliminate duplicates.
  * <br/>Example:
  * <code>
  * glossary :: clearDuplicates($currentLesson);
  * </code>
  *
  * @param mixed $lesson a lesson id or an EfrontLesson object
  * @access public
  * @static
  * @since 3.6.0
  */
 public static function clearDuplicates($lesson)
 {
     if ($lesson instanceof EfrontLesson) {
         $lessonId = $lesson->lesson['id'];
     } elseif (eF_checkParameter($lesson, 'id')) {
         $lessonId = $lesson;
     } else {
         throw new EfrontLessonException(_INVALIDID . ": {$lesson}", EfrontLessonException::INVALID_ID);
     }
     $result = eF_getTableData("glossary", "*", "lessons_ID=" . $lessonId, "id");
     foreach ($result as $value) {
         $glossaryTerms[$value['id']] = $value;
         $id = $value['id'];
         unset($value['id']);
         $checksums[$id] = md5(serialize($value));
     }
     $uniques = array_unique($checksums);
     $duplicates = array_diff_key($checksums, $uniques);
     foreach ($duplicates as $key => $value) {
         $glossary = new glossary($glossaryTerms[$key]);
         $glossary->delete();
     }
 }
     $smarty->assign("T_SCORM", true);
     $smarty->assign("T_SCORM_VERSION", $scormVersion);
 }
 $userObj = new stdClass();
 $userObj->name = array($currentUser->user['name'] . ' ' . $currentUser->user['surname']);
 $userObj->account = new stdClass();
 $userObj->account->accountServiceHomePage = array($_SERVER['HTTP_HOST']);
 //These 2 for 0.9
 $userObj->account->accountName = array($currentUser->user['login']);
 $userObj->account->homePage = $_SERVER['HTTP_HOST'];
 //These 2 for 0.95
 $userObj->account->name = $currentUser->user['login'];
 $currentUnit['data'] = str_replace(array(urlencode('###LRS###'), urlencode('###actor###'), urlencode('###auth###'), urlencode('###unit_id###')), array(urlencode(G_SERVERNAME . 'XAPI/'), urlencode(json_encode($userObj)), urlencode(base64_encode('auth')), urlencode($currentUnit['id'])), $currentUnit['data']);
 //If glossary is activated, transform content data accordingly
 if (EfrontUser::isOptionVisible('glossary') && !isset($_GET['print'])) {
     $currentUnit['data'] = glossary::applyGlossary($currentUnit['data'], $currentLesson->lesson['id']);
 }
 //Replace inner links. Inner links are created when linking from one unit to another, so they must point either to professor.php or student.php, depending on the user viewing the content
 $currentUnit['data'] = str_replace("##EFRONTINNERLINK##", $_SESSION['s_lesson_user_type'], $currentUnit['data']);
 $currentUnit['data'] = str_replace(array("##USER_NAME##", "##USER_LAST_NAME##"), array($currentUser->user['name'], $currentUser->user['surname']), $currentUnit['data']);
 if ($currentUnit['ctg_type'] == 'tests' || $currentUnit['ctg_type'] == 'feedback') {
     $loadScripts[] = 'scriptaculous/dragdrop';
     $loadScripts[] = 'includes/tests';
     include "tests/show_unsolved_test.php";
 }
 if (isset($_GET['print'])) {
     $currentUnit['data'] = preg_replace("#<script.*?>.*?</script>#", "&lt;script removed&gt;", $currentUnit['data']);
     $currentUnit['data'] = strip_tags($currentUnit['data'], '<img><applet><iframe><div><br><p><ul><li><ol><span><sub><sup><hr><h1><h2><h3><h4><h5><h6><table><tbody><tr><th><td><font><em><i><strong><u><b><blockquote><big><center><code>');
 }
 //in case unit is simply an iframe,do not load the print it button
 $contentStripped = strip_tags($currentUnit['data'], '<img><applet><iframe><div><br><p><ul><li><ol><span><sub><sup><hr><h1><h2><h3><h4><h5><h6><table><tbody><tr><th><td><font><em><i><strong><u><b><blockquote><big><center><code>');
Example #4
0
                                 $createdUnit = $currentContent->copyUnit($id, $map[$parentContentId], $map[$previousContentId], $linked);
                                 $transferedNodes[] = intval($id);
                                 //#1383
                                 $currentIds[] = $createdUnit['id'];
                                 $map[intval($id)] = $createdUnit['id'];
                             } catch (Exception $e) {
                                 $errorMessages[] = $e->getMessage() . ' ' . $e->getCode();
                             }
                         } else {
                             $map[intval($id)] = $id;
                         }
                         $previousContentId = $id;
                     }
                 }
                 Question::clearDuplicates($currentLesson);
                 glossary::clearDuplicates($currentLesson);
                 if (isset($errorMessages) && $errorMessages) {
                     header("HTTP/1.0 500 ");
                     echo _ERRORSAVINGTREE . "\n" . implode("\n", $errorMessages);
                 } else {
                     echo serialize($transferedNodes);
                 }
                 exit;
             }
         } catch (Exception $e) {
             header("HTTP/1.0 500 ");
             echo $e->getMessage() . ' (' . $e->getCode() . ')';
             exit;
         }
     }
 }
Example #5
0
 /**
  * Create HTML version of unsolved question
  *
  * This function is used to create the HTML code corresponding
  * to the question. The HTML is created using the question form
  * fields, so the proper form must be specified. A form renderer
  * is used to output the fields. The function calls internally
  * toHTMLQuickForm()
  * <br/>Example:
  * <code>
  * $question = new DragDropQuestion(3);                                        //Instantiate question
  * $form = new HTML_QuickForm("questionForm", "post", "", "", null, true);      //Create a form
  * echo $question -> toHTML($form);                                             //Output question HTML code
  * </code>
  *
  * @param HTML_QuickForm $form The form to add fields to and display
  * @return string The HTML code for the question
  * @since 3.5.0
  * @access public
  */
 public function toHTML(&$form)
 {
     $this->toHTMLQuickForm($form);
     //Assign proper elements to the form
     $renderer = new HTML_QuickForm_Renderer_ArraySmarty($foo);
     //Get a smarty renderer, only because it reforms the form in a very convenient way for printing html
     $form->accept($renderer);
     //Render the form
     $formArray = $renderer->toArray();
     //Get the rendered form fields
     $random = range(0, sizeof($this->answer) - 1);
     //$random is a temporary array used only for creating a random ordering
     shuffle($random);
     $questionString = "\r\n        <script>\r\n        \tif (typeof(dragDropQuestions) == 'undefined') {\r\n        \t\tdragDropQuestions = new Array();\r\n        \t}\r\n        \tif (typeof(dragDropQuestionKeys) == 'undefined') {\r\n        \t\tdragDropQuestionKeys = new Array();\r\n        \t}\r\n        \tdragDropQuestionKeys[" . $this->question['id'] . "] = new Array();\r\n        \tdragDropQuestions.push(" . $this->question['id'] . ");\r\n        \t//var questionId = '" . $this->question['id'] . "';\r\n        </script>";
     $questionString .= '
                 <table class = "unsolvedQuestion dragDropQuestion" style = "width:auto;min-width:300px">
                     <tr><td colspan = "3">' . (EfrontUser::isOptionVisible('test_glossary') ? glossary::applyGlossary($this->question['text'], $this->question['lessons_ID']) : $this->question['text']) . ' ' . $this->getCounter() . '</td></tr>';
     foreach ($formArray['question'][$this->question['id']] as $key => $value) {
         if ($this->preview_correct) {
             $label = $formArray['question'][$this->question['id']][$key]['label'];
         } else {
             $label = $formArray['question'][$this->question['id']][$random[$key]]['label'];
         }
         $questionString .= "\r\n        \t\t\t\t<tr><td style = 'min-width:100px;' class = 'droppable' id = 'secondlist_" . $this->question['id'] . "_{$key}'>\r\n        \t\t\t\t\t\t<input type = 'hidden' value = '" . $random[$key] . "'>\r\n        \t\t\t\t\t\t" . $label . "\r\n        \t\t\t\t\t\t<script>dragDropQuestionKeys[" . $this->question['id'] . "].push({$key});\r\n        \t\t\t\t\t\t\t//Droppables.add('secondlist_" . $this->question['id'] . "_{$key}', {accept:'draggable', onDrop:handleDrop});\r\n        \t\t\t\t\t\t</script>\r\n        \t\t\t\t\t</td>\r\n        \t\t\t\t\t<td style = 'min-width:50px;' class = 'dragDropTarget'></td>\r\n        \t\t\t\t\t<td style = 'min-width:100px;height:100%;border:1px dotted gray' id = 'source_" . $this->question['id'] . "_{$key}'>\r\n        \t\t\t\t\t\t<div class = 'draggable' id = 'firstlist_" . $this->question['id'] . "_{$key}'>" . $this->answer[$key] . $value['html'] . "</div>\r\n            \t\t\t\t\t<script>\r\n            \t\t\t\t\t\t//new Draggable('firstlist_" . $this->question['id'] . "_{$key}', {revert:'failure', onStart:handleDrag});\r\n            \t\t\t\t\t</script>\r\n        \t\t\t\t\t</td>\r\n        \t\t\t\t</tr>\r\n        \t\t\t\t<tr><td colspan = '3' style = 'height:25px'></td></tr>";
     }
     $questionString .= '</table>';
     return bypassCommonPoolCheck($questionString);
 }
Example #6
0
            }
            $entries = array();
            foreach ($terms as $value) {
                $entries[] = array("name" => $value[0], "info" => $value[1], "lessons_ID" => $_SESSION['s_lessons_ID'], "type" => 'general');
            }
            eF_insertTableDataMultiple("glossary", $entries);
        }
    } catch (Exception $e) {
        $smarty->assign("T_EXCEPTION_TRACE", $e->getTraceAsString());
        $message = $e->getMessage() . ' (' . $e->getCode() . ') &nbsp;<a href = "javascript:void(0)" onclick = "eF_js_showDivPopup(event, \'' . _ERRORDETAILS . '\', 2, \'error_details\')">' . _MOREINFO . '</a>';
        $message_type = 'failure';
    }
}
$renderer = new HTML_QuickForm_Renderer_ArraySmarty($smarty);
$importForm->setJsWarnings(_BEFOREJAVASCRIPTERROR, _AFTERJAVASCRIPTERROR);
$importForm->setRequiredNote(_REQUIREDNOTE);
$importForm->accept($renderer);
$smarty->assign('T_IMPORT_FORM', $renderer->toArray());
$load_editor = true;
$entityName = 'glossary';
if (EfrontUser::isOptionVisible('shared_glossary')) {
    $glossary = eF_getTableData("glossary", "id,name,info", "lessons_ID=" . $currentLesson->lesson['id'] . " OR lessons_ID=0");
} else {
    $glossary = eF_getTableData("glossary", "id,name,info", "lessons_ID=" . $currentLesson->lesson['id']);
}
foreach ($glossary as $value) {
    $legalValues[] = $value['id'];
}
$words = glossary::getGlossaryWords($glossary);
$smarty->assign("T_GLOSSARY", $words);
include "entity.php";
 /**
  * Alternate display
  */
 function show_phrase2()
 {
     global $_GET;
     $lex_classes = $this->db->get_row_assoc('SELECT * FROM lexical_class', 'lex_class', 'lex_class_name');
     $this->phrase = $this->get_phrase();
     $phrase = $this->phrase;
     $this->kbbi = new kbbi($this->msg, &$this->db);
     // if it's not marked created
     if (!$phrase['created']) {
         $this->kbbi->force_refresh = true;
         $this->kbbi->parse($_GET['phrase']);
         if ($this->kbbi->found) {
             $this->save_kbbi($_GET['phrase']);
         }
         $this->kbbi->force_refresh = false;
         $this->phrase = $this->get_phrase();
         $phrase = $this->phrase;
     }
     // if it's not marked created
     if (!$phrase['kbbi_updated']) {
         $this->kbbi->force_refresh = true;
         $this->kbbi->parse($_GET['phrase']);
         if ($this->kbbi->found) {
             $this->save_kbbi2($_GET['phrase']);
         }
         $this->kbbi->force_refresh = false;
         $this->phrase = $this->get_phrase();
         $phrase = $this->phrase;
     }
     // header
     $ret .= sprintf('<h1>%1$s</h1>' . LF, $_GET['phrase']);
     // kbbi header
     $ret .= '<table width="100%" cellpadding="0" cellspacing="0"><tr valign="top"><td width="60%">' . LF;
     if ($this->auth->checkAuth()) {
         $actions = array('new' => array('url' => './?mod=dictionary&action=form'), 'edit' => array('url' => './?mod=dictionary&action=form&phrase=' . $_GET['phrase']), 'delete' => array('url' => './?mod=dictionary&action=delete&phrase=' . $_GET['phrase']), 'get_kbbi' => array('url' => './?mod=dictionary&action=kbbi&phrase=' . $_GET['phrase']));
         $ret .= $this->get_action_buttons($actions, $phrase ? null : array('new', 'get_kbbi'));
     }
     // found?
     if ($phrase) {
         $i = 0;
         // definition: get from actual phrase or definition
         if ($phrase['actual_phrase']) {
             $defs = array(array('def_num' => 1, 'def_text' => $phrase['actual_phrase'], 'see' => $phrase['actual_phrase']));
         } else {
             $defs = $phrase['definition'];
         }
         $ret .= '<p>';
         $ret .= sprintf('<strong>%1$s</strong> ', $phrase['phrase']);
         if ($phrase['pronounciation']) {
             $ret .= sprintf(' /%2$s/ ', $this->msg['pronounciation'], $phrase['pronounciation']);
         }
         if ($phrase['lex_class_name']) {
             $lex_name = $phrase['lex_class_name'];
             if ($phrase['lex_class_ref']) {
                 $lex_name = sprintf('<a href="./?mod=dictionary&action=view&phrase=%2$s">%1$s</a>', $phrase['lex_class_name'], $phrase['lex_class_ref']);
             }
             $ret .= sprintf(' <em>%2$s</em> ', $this->msg['lex_class'], strtolower($lex_name));
         }
         // show definition
         $def_count = count($defs);
         if ($defs) {
             foreach ($defs as $def) {
                 $discipline = $i == 0 ? $phrase['info'] : '';
                 if ($def_count > 1) {
                     $ret .= '<strong>' . ($i + 1) . '.</strong> ';
                 }
                 if ($def['see']) {
                     $ret .= sprintf('lihat <b><a href="./?mod=dictionary&action=view&phrase=%2$s">%1$s</a></b>', $def['see'], $def['see']);
                 } else {
                     if ($def['discipline']) {
                         $discipline .= $discipline ? ', ' : '';
                         $discipline .= $def['discipline'];
                     }
                     $lex_name = $def['lex_class'];
                     $lex_title = $lex_classes[$def['lex_class']];
                     if ($def['lex_class_ref']) {
                         $lex_name = sprintf('<a href="./?mod=dictionary&action=view&phrase=%2$s" title="%3$s">%1$s</a>', $def['lex_class'], $def['lex_class_ref'], $lex_title);
                     }
                     $ret .= sprintf('%4$s%2$s%1$s%3$s', $def['def_text'], $discipline ? '<em>(' . $this->get_abbrev($discipline) . ')</em> ' : '', $def['sample'] ? ': <em>' . $def['sample'] . '</em> ' : '', $def['lex_class'] ? '<em>' . $lex_name . '</em> ' : '');
                 }
                 if ($def_count > 1) {
                     $ret .= '; ';
                 }
                 $i++;
             }
         } else {
             $ret .= $this->msg['na'];
         }
         $ret .= '</p>' . LF;
         // misc
         $template = '<p><b>%1$s:</b><br />' . LF . '%2$s</p>' . LF;
         $template = '<dl><dt>%1$s:</dt><dd>' . LF . '%2$s</dd></dl>' . LF;
         $template = '<p><em>%1$s:</em> ' . LF . '%2$s</p>' . LF;
         if ($phrase['etymology']) {
             $ret .= sprintf($template, $this->msg['etymology'], $phrase['etymology']);
         }
         if ($phrase['root']) {
             $ret .= sprintf($template, $this->msg['root_phrase'], $this->merge_phrase_list($phrase['root'], 'root_phrase'));
         }
         if ($phrase['roget_class']) {
             $ret .= sprintf($template, $this->msg['roget_class'], $phrase['roget_name']);
         }
         if ($phrase['ref_source']) {
             $ret .= sprintf($template, $this->msg['ref_source'], $phrase['ref_source_name']);
         }
         // reference
         if ($phrase['reference']) {
             $ret .= '<p>' . $this->msg['external_ref'] . ':</p>' . LF;
             $ret .= '<ul>' . LF;
             foreach ($phrase['reference'] as $reference) {
                 $ret .= sprintf('<li><a href="%2$s">%1$s</a></li>' . LF, $reference['label'] ? $reference['label'] : $reference['url'], $reference['url']);
             }
             $ret .= '</ul>' . LF;
         }
         // relation and derivation
         $ret .= $this->show_relation($phrase, 'related_phrase');
         // peribahasa
         if ($phrase['proverbs']) {
             $ret .= sprintf('<h2>%1$s</h2>' . LF, $this->msg['proverb']);
             $ret .= '<ul>' . LF;
             foreach ($phrase['proverbs'] as $proverb) {
                 $ret .= sprintf('<li><em>%1$s</em>: %2$s</li>' . LF, $proverb['proverb'], $proverb['meaning']);
             }
             $ret .= '</ul>' . LF;
         }
         // translation
         if ($phrase['translations']) {
             $ret .= sprintf('<h2>%1$s</h2>' . LF, $this->msg['translation']);
             $ret .= '<ul>' . LF;
             foreach ($phrase['translations'] as $translation) {
                 $ret .= sprintf('<li><em>%1$s</em>: %2$s</li>' . LF, $translation['ref_source'], $translation['translation']);
             }
             $ret .= '</ul>' . LF;
         }
     } else {
         $ret .= sprintf('<p>%1$s</p>', sprintf($this->msg['phrase_na'], $_GET['phrase']));
         // derivation and relation
         $this->get_relation(&$phrase, 'related_phrase', true);
         $ret .= $this->show_relation($phrase, 'root_phrase');
     }
     // glosarium
     $ret .= sprintf('<h2>%1$s</h2>' . LF, $this->msg['glossary']);
     $_GET['lang'] = 'id';
     $glossary = new glossary(&$this->db, &$this->auth, $this->msg);
     $glossary->sublist = true;
     $ret .= $glossary->show_result();
     $ret .= $this->show_kbbi();
     return $ret;
 }