Commit e36658c7afa336492a3c12732b2a482bb4d06d7b
1 parent
383b3435
Merged in from DEV trunk...
KTC-327 "The Document Indexing Diagostics does not show problems when in reality they exist" Fixed. Committed By: Conrad Vermeulen Reviewed By: Jonathan Byrne git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/STABLE/trunk@8102 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing
5 changed files
with
196 additions
and
189 deletions
plugins/search2/LuceneStatisticsDashlet.php
| ... | ... | @@ -101,8 +101,11 @@ class LuceneStatisticsDashlet extends KTBaseDashlet |
| 101 | 101 | $docsInIndex = $index->getDocumentsInIndex(); |
| 102 | 102 | |
| 103 | 103 | // we are only interested in documents that are active |
| 104 | - $sql = "SELECT count(*) as docsInQueue FROM index_files q INNER JOIN documents d on q.document_id=d.id WHERE d.status_id=1"; | |
| 105 | - $docsInQueue = DBUtil::getOneResultKey($sql, 'docsInQueue'); | |
| 104 | + $docsInQueue = $index->getIndexingQueue(); | |
| 105 | + $docsInQueue = count($docsInQueue); | |
| 106 | + | |
| 107 | + $errorsInQueue = $index->getIndexingQueue(true); | |
| 108 | + $errorsInQueue = count($errorsInQueue); | |
| 106 | 109 | |
| 107 | 110 | $sql = "SELECT count(*) as docsInRepository FROM documents"; |
| 108 | 111 | $docsInRepository = DBUtil::getOneResultKey($sql, 'docsInRepository'); |
| ... | ... | @@ -138,6 +141,7 @@ class LuceneStatisticsDashlet extends KTBaseDashlet |
| 138 | 141 | 'indexingPeriod'=>$indexingPeriod, |
| 139 | 142 | 'docsInIndex'=>$docsInIndex, |
| 140 | 143 | 'docsInQueue'=>$docsInQueue, |
| 144 | + 'errorsInQueue'=>$errorsInQueue, | |
| 141 | 145 | 'docsInRepository'=>$docsInRepository, |
| 142 | 146 | 'indexingCoverage'=>$indexingCoverage, |
| 143 | 147 | 'queueCoverage'=>$queueCoverage, | ... | ... |
plugins/search2/reporting/IndexErrors.php
| 1 | -<?php | |
| 2 | -/** | |
| 3 | - * $Id:$ | |
| 4 | - * | |
| 5 | - * KnowledgeTree Open Source Edition | |
| 6 | - * Document Management Made Simple | |
| 7 | - * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited | |
| 8 | - * | |
| 9 | - * This program is free software; you can redistribute it and/or modify it under | |
| 10 | - * the terms of the GNU General Public License version 3 as published by the | |
| 11 | - * Free Software Foundation. | |
| 12 | - * | |
| 13 | - * This program is distributed in the hope that it will be useful, but WITHOUT | |
| 14 | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 15 | - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 16 | - * details. | |
| 17 | - * | |
| 18 | - * You should have received a copy of the GNU General Public License | |
| 19 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | - * | |
| 21 | - * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, | |
| 22 | - * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. | |
| 23 | - * | |
| 24 | - * The interactive user interfaces in modified source and object code versions | |
| 25 | - * of this program must display Appropriate Legal Notices, as required under | |
| 26 | - * Section 5 of the GNU General Public License version 3. | |
| 27 | - * | |
| 28 | - * In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 29 | - * these Appropriate Legal Notices must retain the display of the "Powered by | |
| 30 | - * KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 31 | - * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 32 | - * must display the words "Powered by KnowledgeTree" and retain the original | |
| 33 | - * copyright notice. | |
| 34 | - * Contributor( s): ______________________________________ | |
| 35 | - * | |
| 36 | - */ | |
| 37 | - | |
| 38 | -require_once(KT_LIB_DIR . '/dispatcher.inc.php'); | |
| 39 | -require_once(KT_LIB_DIR . '/templating/templating.inc.php'); | |
| 40 | -require_once(KT_LIB_DIR . '/mime.inc.php'); | |
| 41 | - | |
| 42 | -class IndexErrorsDispatcher extends KTAdminDispatcher { | |
| 43 | - | |
| 44 | - function check() { | |
| 45 | - $this->aBreadcrumbs[] = array( | |
| 46 | - 'url' => $_SERVER['PHP_SELF'], | |
| 47 | - 'name' => _kt('Document Indexing Diagnostics'), | |
| 48 | - ); | |
| 49 | - return parent::check(); | |
| 50 | - } | |
| 51 | - | |
| 52 | - function do_main() { | |
| 53 | - | |
| 54 | - //registerTypes registers the mime types and populates the needed tables. | |
| 55 | - $indexer = Indexer::get(); | |
| 56 | - $indexer->registerTypes(); | |
| 57 | - | |
| 58 | - if($_REQUEST['rescheduleValue'] == 'reschedule') | |
| 59 | - { | |
| 60 | - | |
| 61 | - foreach(KTUtil::arrayGet($_REQUEST, 'index_error', array()) as $sDocId => $v) | |
| 62 | - { | |
| 63 | - Indexer::reindexDocument($sDocId); | |
| 64 | - | |
| 65 | - } | |
| 66 | - | |
| 67 | - } | |
| 68 | - else if($_REQUEST['rescheduleValue'] == 'rescheduleall') | |
| 69 | - { | |
| 70 | - $aIndexerValues = Indexer::getIndexingQueue(); | |
| 71 | - foreach ($aIndexerValues as $sDocValues) | |
| 72 | - { | |
| 73 | - Indexer::reindexDocument($sDocValues['document_id']); | |
| 74 | - } | |
| 75 | - | |
| 76 | - } | |
| 77 | - require_once(KT_LIB_DIR . "/templating/templating.inc.php"); | |
| 78 | - $oTemplating =& KTTemplating::getSingleton(); | |
| 79 | - $oTemplating->addLocation('Index Errors', '/plugins/search2/reporting/templates'); | |
| 80 | - | |
| 81 | - $oTemplate =& $oTemplating->loadTemplate('indexerrors'); | |
| 82 | - | |
| 83 | - $aIndexerValues = Indexer::getIndexingQueue(); | |
| 84 | - | |
| 85 | - $oTemplate->setData(array( | |
| 86 | - 'context' => $this, | |
| 87 | - 'index_errors' => $aIndexerValues | |
| 88 | - | |
| 89 | - )); | |
| 90 | - return $oTemplate; | |
| 91 | - } | |
| 92 | - | |
| 93 | - | |
| 94 | - | |
| 95 | -} | |
| 96 | - | |
| 97 | - | |
| 98 | -?> | |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * $Id:$ | |
| 4 | + * | |
| 5 | + * KnowledgeTree Open Source Edition | |
| 6 | + * Document Management Made Simple | |
| 7 | + * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or modify it under | |
| 10 | + * the terms of the GNU General Public License version 3 as published by the | |
| 11 | + * Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
| 14 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 15 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 16 | + * details. | |
| 17 | + * | |
| 18 | + * You should have received a copy of the GNU General Public License | |
| 19 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | + * | |
| 21 | + * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, | |
| 22 | + * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. | |
| 23 | + * | |
| 24 | + * The interactive user interfaces in modified source and object code versions | |
| 25 | + * of this program must display Appropriate Legal Notices, as required under | |
| 26 | + * Section 5 of the GNU General Public License version 3. | |
| 27 | + * | |
| 28 | + * In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 29 | + * these Appropriate Legal Notices must retain the display of the "Powered by | |
| 30 | + * KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 31 | + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 32 | + * must display the words "Powered by KnowledgeTree" and retain the original | |
| 33 | + * copyright notice. | |
| 34 | + * Contributor( s): ______________________________________ | |
| 35 | + * | |
| 36 | + */ | |
| 37 | + | |
| 38 | +require_once(KT_LIB_DIR . '/dispatcher.inc.php'); | |
| 39 | +require_once(KT_LIB_DIR . '/templating/templating.inc.php'); | |
| 40 | +require_once(KT_LIB_DIR . '/mime.inc.php'); | |
| 41 | + | |
| 42 | +class IndexErrorsDispatcher extends KTAdminDispatcher { | |
| 43 | + | |
| 44 | + function check() { | |
| 45 | + $this->aBreadcrumbs[] = array( | |
| 46 | + 'url' => $_SERVER['PHP_SELF'], | |
| 47 | + 'name' => _kt('Document Indexing Diagnostics'), | |
| 48 | + ); | |
| 49 | + return parent::check(); | |
| 50 | + } | |
| 51 | + | |
| 52 | + function do_main() { | |
| 53 | + | |
| 54 | + //registerTypes registers the mime types and populates the needed tables. | |
| 55 | + $indexer = Indexer::get(); | |
| 56 | + $indexer->registerTypes(); | |
| 57 | + | |
| 58 | + if($_REQUEST['rescheduleValue'] == 'reschedule') | |
| 59 | + { | |
| 60 | + | |
| 61 | + foreach(KTUtil::arrayGet($_REQUEST, 'index_error', array()) as $sDocId => $v) | |
| 62 | + { | |
| 63 | + Indexer::reindexDocument($sDocId); | |
| 64 | + | |
| 65 | + } | |
| 66 | + | |
| 67 | + } | |
| 68 | + else if($_REQUEST['rescheduleValue'] == 'rescheduleall') | |
| 69 | + { | |
| 70 | + $aIndexerValues = Indexer::getIndexingQueue(); | |
| 71 | + foreach ($aIndexerValues as $sDocValues) | |
| 72 | + { | |
| 73 | + Indexer::reindexDocument($sDocValues['document_id']); | |
| 74 | + } | |
| 75 | + | |
| 76 | + } | |
| 77 | + | |
| 78 | + $oTemplating =& KTTemplating::getSingleton(); | |
| 79 | + $oTemplating->addLocation('Index Errors', '/plugins/search2/reporting/templates'); | |
| 80 | + | |
| 81 | + $oTemplate =& $oTemplating->loadTemplate('indexerrors'); | |
| 82 | + | |
| 83 | + $aIndexerValues = Indexer::getIndexingQueue(); | |
| 84 | + foreach($aIndexerValues as $key=>$doc) | |
| 85 | + { | |
| 86 | + $extractor=$indexer->getExtractor($doc['extractor']); | |
| 87 | + $doc['extractor'] = $extractor->getDisplayName(); | |
| 88 | + $aIndexerValues[$key] = $doc; | |
| 89 | + } | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + $oTemplate->setData(array( | |
| 94 | + 'context' => $this, | |
| 95 | + 'index_errors' => $aIndexerValues | |
| 96 | + | |
| 97 | + )); | |
| 98 | + return $oTemplate; | |
| 99 | + } | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | +} | |
| 104 | + | |
| 105 | + | |
| 106 | +?> | ... | ... |
plugins/search2/reporting/PendingDocuments.php
| 1 | -<?php | |
| 2 | -/** | |
| 3 | - * $Id:$ | |
| 4 | - * | |
| 5 | - * KnowledgeTree Open Source Edition | |
| 6 | - * Document Management Made Simple | |
| 7 | - * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited | |
| 8 | - * | |
| 9 | - * This program is free software; you can redistribute it and/or modify it under | |
| 10 | - * the terms of the GNU General Public License version 3 as published by the | |
| 11 | - * Free Software Foundation. | |
| 12 | - * | |
| 13 | - * This program is distributed in the hope that it will be useful, but WITHOUT | |
| 14 | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 15 | - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 16 | - * details. | |
| 17 | - * | |
| 18 | - * You should have received a copy of the GNU General Public License | |
| 19 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | - * | |
| 21 | - * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, | |
| 22 | - * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. | |
| 23 | - * | |
| 24 | - * The interactive user interfaces in modified source and object code versions | |
| 25 | - * of this program must display Appropriate Legal Notices, as required under | |
| 26 | - * Section 5 of the GNU General Public License version 3. | |
| 27 | - * | |
| 28 | - * In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 29 | - * these Appropriate Legal Notices must retain the display of the "Powered by | |
| 30 | - * KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 31 | - * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 32 | - * must display the words "Powered by KnowledgeTree" and retain the original | |
| 33 | - * copyright notice. | |
| 34 | - * Contributor( s): ______________________________________ | |
| 35 | - * | |
| 36 | - */ | |
| 37 | - | |
| 38 | -require_once(KT_LIB_DIR . '/dispatcher.inc.php'); | |
| 39 | -require_once(KT_LIB_DIR . '/templating/templating.inc.php'); | |
| 40 | - | |
| 41 | -class PendingDocumentsDispatcher extends KTAdminDispatcher | |
| 42 | -{ | |
| 43 | - function check() { | |
| 44 | - $this->aBreadcrumbs[] = array( | |
| 45 | - 'url' => $_SERVER['PHP_SELF'], | |
| 46 | - 'name' => _kt('Pending Documents Indexing Queue'), | |
| 47 | - ); | |
| 48 | - return parent::check(); | |
| 49 | - } | |
| 50 | - | |
| 51 | - function do_main() { | |
| 52 | - | |
| 53 | - //registerTypes registers the mime types and populates the needed tables. | |
| 54 | - $indexer = Indexer::get(); | |
| 55 | - $indexer->registerTypes(); | |
| 56 | - | |
| 57 | - $aPendingDocs = Indexer::getPendingIndexingQueue(); | |
| 58 | - | |
| 59 | - $oTemplating =& KTTemplating::getSingleton(); | |
| 60 | - $oTemplating->addLocation('Pending Documents', '/plugins/search2/reporting/templates'); | |
| 61 | - $oTemplate =& $oTemplating->loadTemplate('pendingdocuments'); | |
| 62 | - | |
| 63 | - $oTemplate->setData(array( | |
| 64 | - 'context' => $this, | |
| 65 | - 'pending_docs' => $aPendingDocs | |
| 66 | - | |
| 67 | - )); | |
| 68 | - return $oTemplate; | |
| 69 | - } | |
| 70 | - | |
| 71 | -} | |
| 72 | - | |
| 73 | - | |
| 74 | -?> | |
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * $Id:$ | |
| 4 | + * | |
| 5 | + * KnowledgeTree Open Source Edition | |
| 6 | + * Document Management Made Simple | |
| 7 | + * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited | |
| 8 | + * | |
| 9 | + * This program is free software; you can redistribute it and/or modify it under | |
| 10 | + * the terms of the GNU General Public License version 3 as published by the | |
| 11 | + * Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
| 14 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 15 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 16 | + * details. | |
| 17 | + * | |
| 18 | + * You should have received a copy of the GNU General Public License | |
| 19 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | + * | |
| 21 | + * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, | |
| 22 | + * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. | |
| 23 | + * | |
| 24 | + * The interactive user interfaces in modified source and object code versions | |
| 25 | + * of this program must display Appropriate Legal Notices, as required under | |
| 26 | + * Section 5 of the GNU General Public License version 3. | |
| 27 | + * | |
| 28 | + * In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 29 | + * these Appropriate Legal Notices must retain the display of the "Powered by | |
| 30 | + * KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 31 | + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 32 | + * must display the words "Powered by KnowledgeTree" and retain the original | |
| 33 | + * copyright notice. | |
| 34 | + * Contributor( s): ______________________________________ | |
| 35 | + * | |
| 36 | + */ | |
| 37 | + | |
| 38 | +require_once(KT_LIB_DIR . '/dispatcher.inc.php'); | |
| 39 | +require_once(KT_LIB_DIR . '/templating/templating.inc.php'); | |
| 40 | + | |
| 41 | +class PendingDocumentsDispatcher extends KTAdminDispatcher | |
| 42 | +{ | |
| 43 | + function check() { | |
| 44 | + $this->aBreadcrumbs[] = array( | |
| 45 | + 'url' => $_SERVER['PHP_SELF'], | |
| 46 | + 'name' => _kt('Pending Documents Indexing Queue'), | |
| 47 | + ); | |
| 48 | + return parent::check(); | |
| 49 | + } | |
| 50 | + | |
| 51 | + function do_main() { | |
| 52 | + | |
| 53 | + //registerTypes registers the mime types and populates the needed tables. | |
| 54 | + $indexer = Indexer::get(); | |
| 55 | + $indexer->registerTypes(); | |
| 56 | + | |
| 57 | + $aPendingDocs = Indexer::getPendingIndexingQueue(); | |
| 58 | + foreach($aPendingDocs as $key=>$doc) | |
| 59 | + { | |
| 60 | + $extractor = $indexer->getExtractor($doc['extractor']); | |
| 61 | + $doc['extractor'] = $extractor->getDisplayName(); | |
| 62 | + $aPendingDocs[$key] = $doc; | |
| 63 | + } | |
| 64 | + | |
| 65 | + $oTemplating =& KTTemplating::getSingleton(); | |
| 66 | + $oTemplating->addLocation('Pending Documents', '/plugins/search2/reporting/templates'); | |
| 67 | + $oTemplate =& $oTemplating->loadTemplate('pendingdocuments'); | |
| 68 | + | |
| 69 | + $oTemplate->setData(array( | |
| 70 | + 'context' => $this, | |
| 71 | + 'pending_docs' => $aPendingDocs | |
| 72 | + | |
| 73 | + )); | |
| 74 | + return $oTemplate; | |
| 75 | + } | |
| 76 | + | |
| 77 | +} | |
| 78 | + | |
| 79 | + | |
| 80 | +?> | ... | ... |
plugins/search2/reporting/templates/indexerrors.smarty
| ... | ... | @@ -23,10 +23,8 @@ |
| 23 | 23 | <thead> |
| 24 | 24 | <tr> |
| 25 | 25 | <th width="10"></th> |
| 26 | - <th width="80"><nobr>{i18n}Document ID{/i18n}</th> | |
| 26 | + | |
| 27 | 27 | <th ><nobr>{i18n}Filename{/i18n}</th> |
| 28 | - <th width="100"><nobr>{i18n}Extension{/i18n}</th> | |
| 29 | - <th width="100"><nobr>{i18n}Mime Type{/i18n}</th> | |
| 30 | 28 | <th width="100"><nobr>{i18n}Extractor{/i18n}</th> |
| 31 | 29 | <th width="100"><nobr>{i18n}Index Date{/i18n}</th> |
| 32 | 30 | </tr> |
| ... | ... | @@ -36,11 +34,8 @@ |
| 36 | 34 | {foreach key=key from=$index_errors item=indexError} |
| 37 | 35 | <tr> |
| 38 | 36 | <td class="centered"><input type="checkbox" name="index_error[{$indexError.document_id}]" value="1"/></td> |
| 39 | - <td>{$indexError.document_id}</td> | |
| 40 | - <td>{$indexError.filename|truncate:40:'...'}</td> | |
| 41 | - <td>{$indexError.filetypes}</td> | |
| 42 | - <td>{$indexError.mimetypes}</td> | |
| 43 | - <td>{if $pendingDocs.extractor}{$indexError.extractor}{else}<p><font color="#FF9933">{i18n}n/a{/i18n}</font></p>{/if}</td> | |
| 37 | + <td><a href="/view.php?fDocumentId={$pendingDocs.document_id}">{$indexError.filename|truncate:40:'...'}</a></td> | |
| 38 | + <td>{if $indexError.extractor}{$indexError.extractor}{else}<p><font color="#FF9933">{i18n}n/a{/i18n}</font></p>{/if}</td> | |
| 44 | 39 | <td>{$indexError.indexdate}</td> |
| 45 | 40 | |
| 46 | 41 | </tr> | ... | ... |
plugins/search2/reporting/templates/pendingdocuments.smarty
| ... | ... | @@ -15,10 +15,7 @@ |
| 15 | 15 | |
| 16 | 16 | <thead> |
| 17 | 17 | <tr> |
| 18 | - <th width="10"><nobr>{i18n}Document ID{/i18n}</th> | |
| 19 | 18 | <th><nobr>{i18n}Filename{/i18n}</th> |
| 20 | - <th width="100"><nobr>{i18n}Extension{/i18n}</th> | |
| 21 | - <th width="150"><nobr>{i18n}Mime Type{/i18n}</th> | |
| 22 | 19 | <th width="100"><nobr>{i18n}Extractor{/i18n}</th> |
| 23 | 20 | <th width="100"><nobr>{i18n}Index Date{/i18n}</th> |
| 24 | 21 | </tr> |
| ... | ... | @@ -28,10 +25,7 @@ |
| 28 | 25 | |
| 29 | 26 | {foreach key=key from=$pending_docs item=pendingDocs} |
| 30 | 27 | <tr> |
| 31 | - <td><a href="/view.php?fDocumentId={$pendingDocs.document_id}">{$pendingDocs.document_id}</a></td> | |
| 32 | - <td>{$pendingDocs.filename|truncate:40:'...'}</td> | |
| 33 | - <td>{$pendingDocs.filetypes}</td> | |
| 34 | - <td>{$pendingDocs.mimetypes}</td> | |
| 28 | + <td><a href="/view.php?fDocumentId={$pendingDocs.document_id}">{$pendingDocs.filename|truncate:40:'...'}</a></td> | |
| 35 | 29 | <td>{if $pendingDocs.extractor}{$pendingDocs.extractor}{else}<p><font color="#FF9933">{i18n}n/a{/i18n}</font></p>{/if}</td> |
| 36 | 30 | <td>{$pendingDocs.indexdate}</td> |
| 37 | 31 | </tr> | ... | ... |