Commit d594c708 authored by Kasper Skårhøj's avatar Kasper Skårhøj
Browse files

* Added 3 hooks for each hardcoded function in css_styled_content so extensions can be written which provides alternative renderings without XCLASSING.


git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@564 709f56b5-9817-0410-a4d7-c38de5d9e867
parent 8008e7ed
2005-02-17 Kasper Skårhøj,,, <kasper@typo3.com>
* Added 3 hooks for each hardcoded function in css_styled_content so extensions can be written which provides alternative renderings without XCLASSING.
2005-02-15 Kasper Skårhøj,,, <kasper@typo3.com>
* The indexed-search lexer has been updated so it supports "printjoins" (characters like ' or - which are allowed inside of words) and there is also support for Chinese/Japanese/Korean (CJK) indexing/searching.
......
......@@ -90,33 +90,39 @@ class tx_cssstyledcontent_pi1 extends tslib_pibase {
*/
function render_bullets($content,$conf) {
// Get bodytext field content, returning blank if empty:
$content = trim($this->cObj->data['bodytext']);
if (!strcmp($content,'')) return '';
// Split into single lines:
$lines = t3lib_div::trimExplode(chr(10),$content);
while(list($k)=each($lines)) {
$lines[$k]='
<li>'.$this->cObj->stdWrap($lines[$k],$conf['innerStdWrap.']).'</li>';
}
// Look for hook before running default code for function
if ($hookObj = &$this->hookRequest('render_bullets')) {
return $hookObj->render_bullets($content,$conf);
} else {
// Get bodytext field content, returning blank if empty:
$content = trim($this->cObj->data['bodytext']);
if (!strcmp($content,'')) return '';
// Split into single lines:
$lines = t3lib_div::trimExplode(chr(10),$content);
while(list($k)=each($lines)) {
$lines[$k]='
<li>'.$this->cObj->stdWrap($lines[$k],$conf['innerStdWrap.']).'</li>';
}
// Set header type:
$type = intval($this->cObj->data['layout']);
// Set header type:
$type = intval($this->cObj->data['layout']);
// Compile list:
$out = '
<ul class="csc-bulletlist csc-bulletlist-'.$type.'">'.
implode('',$lines).'
</ul>';
// Compile list:
$out = '
<ul class="csc-bulletlist csc-bulletlist-'.$type.'">'.
implode('',$lines).'
</ul>';
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
}
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
}
// Return value
return $out;
// Return value
return $out;
}
}
/**
......@@ -129,55 +135,61 @@ class tx_cssstyledcontent_pi1 extends tslib_pibase {
*/
function render_table($content,$conf) {
// Get bodytext field content
$content = trim($this->cObj->data['bodytext']);
if (!strcmp($content,'')) return '';
// Split into single lines (will become table-rows):
$rows = t3lib_div::trimExplode(chr(10),$content);
// Find number of columns to render:
$cols = t3lib_div::intInRange($this->cObj->data['cols']?$this->cObj->data['cols']:count(explode('|',current($rows))),0,100);
// Traverse rows (rendering the table here)
$rCount = count($rows);
foreach($rows as $k => $v) {
$cells = explode('|',$v);
$newCells=array();
for($a=0;$a<$cols;$a++) {
if (!strcmp(trim($cells[$a]),'')) $cells[$a]='&nbsp;';
$cellAttribs = ($a>0 && ($cols-1)==$a) ? ' class="td-last"' : ' class="td-'.$a.'"';
$newCells[$a] = '
<td'.$cellAttribs.'><p>'.$this->cObj->stdWrap($cells[$a],$conf['innerStdWrap.']).'</p></td>';
// Look for hook before running default code for function
if ($hookObj = &$this->hookRequest('render_table')) {
return $hookObj->render_table($content,$conf);
} else {
// Get bodytext field content
$content = trim($this->cObj->data['bodytext']);
if (!strcmp($content,'')) return '';
// Split into single lines (will become table-rows):
$rows = t3lib_div::trimExplode(chr(10),$content);
// Find number of columns to render:
$cols = t3lib_div::intInRange($this->cObj->data['cols']?$this->cObj->data['cols']:count(explode('|',current($rows))),0,100);
// Traverse rows (rendering the table here)
$rCount = count($rows);
foreach($rows as $k => $v) {
$cells = explode('|',$v);
$newCells=array();
for($a=0;$a<$cols;$a++) {
if (!strcmp(trim($cells[$a]),'')) $cells[$a]='&nbsp;';
$cellAttribs = ($a>0 && ($cols-1)==$a) ? ' class="td-last"' : ' class="td-'.$a.'"';
$newCells[$a] = '
<td'.$cellAttribs.'><p>'.$this->cObj->stdWrap($cells[$a],$conf['innerStdWrap.']).'</p></td>';
}
$oddEven = $k%2 ? 'tr-odd' : 'tr-even';
$rowAttribs = ($k>0 && ($rCount-1)==$k) ? ' class="'.$oddEven.' tr-last"' : ' class="'.$oddEven.' tr-'.$k.'"';
$rows[$k]='
<tr'.$rowAttribs.'>'.implode('',$newCells).'
</tr>';
}
$oddEven = $k%2 ? 'tr-odd' : 'tr-even';
$rowAttribs = ($k>0 && ($rCount-1)==$k) ? ' class="'.$oddEven.' tr-last"' : ' class="'.$oddEven.' tr-'.$k.'"';
$rows[$k]='
<tr'.$rowAttribs.'>'.implode('',$newCells).'
</tr>';
}
// Set header type:
$type = intval($this->cObj->data['layout']);
// Set header type:
$type = intval($this->cObj->data['layout']);
// Table tag params.
$tableTagParams = $this->getTableAttributes($conf,$type);
$tableTagParams['class'] = 'contenttable contenttable-'.$type;
// Table tag params.
$tableTagParams = $this->getTableAttributes($conf,$type);
$tableTagParams['class'] = 'contenttable contenttable-'.$type;
// Compile table output:
$out = '
<table '.t3lib_div::implodeAttributes($tableTagParams).'>'. // Omitted xhtmlSafe argument TRUE - none of the values will be needed to be converted anyways, no need to spend processing time on that.
implode('',$rows).'
</table>';
// Compile table output:
$out = '
<table '.t3lib_div::implodeAttributes($tableTagParams).'>'. // Omitted xhtmlSafe argument TRUE - none of the values will be needed to be converted anyways, no need to spend processing time on that.
implode('',$rows).'
</table>';
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
}
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
// Return value
return $out;
}
// Return value
return $out;
}
/**
......@@ -190,99 +202,105 @@ class tx_cssstyledcontent_pi1 extends tslib_pibase {
*/
function render_uploads($content,$conf) {
$out = '';
// Set layout type:
$type = intval($this->cObj->data['layout']);
// Get the list of files (using stdWrap function since that is easiest)
$lConf=array();
$lConf['override.']['filelist.']['field'] = 'select_key';
$fileList = $this->cObj->stdWrap($this->cObj->data['media'],$lConf);
// Explode into an array:
$fileArray = t3lib_div::trimExplode(',',$fileList,1);
// If there were files to list...:
if (count($fileArray)) {
// Get the path from which the images came:
$selectKeyValues = explode('|',$this->cObj->data['select_key']);
$path = trim($selectKeyValues[0]) ? trim($selectKeyValues[0]) : 'uploads/media/';
// Get the descriptions for the files (if any):
$descriptions = t3lib_div::trimExplode(chr(10),$this->cObj->data['imagecaption']);
// Adding hardcoded TS to linkProc configuration:
$conf['linkProc.']['path.']['current'] = 1;
$conf['linkProc.']['icon'] = 1; // Always render icon - is inserted by PHP if needed.
$conf['linkProc.']['icon.']['wrap'] = ' | //**//'; // Temporary, internal split-token!
$conf['linkProc.']['icon_link'] = 1; // ALways link the icon
$conf['linkProc.']['icon_image_ext_list'] = ($type==2 || $type==3) ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] : ''; // If the layout is type 2 or 3 we will render an image based icon if possible.
// Traverse the files found:
$filesData = array();
foreach($fileArray as $key => $fileName) {
$absPath = t3lib_div::getFileAbsFileName($path.$fileName);
if (@is_file($absPath)) {
$fI = pathinfo($fileName);
$filesData[$key] = array();
$filesData[$key]['filename'] = $fileName;
$filesData[$key]['path'] = $path;
$filesData[$key]['filesize'] = filesize($absPath);
$filesData[$key]['fileextension'] = strtolower($fI['extension']);
$filesData[$key]['description'] = trim($descriptions[$key]);
$this->cObj->setCurrentVal($path);
$GLOBALS['TSFE']->register['ICON_REL_PATH'] = $path.$fileName;
$filesData[$key]['linkedFilenameParts'] = explode('//**//',$this->cObj->filelink($fileName, $conf['linkProc.']));
// Look for hook before running default code for function
if ($hookObj = &$this->hookRequest('render_uploads')) {
return $hookObj->render_uploads($content,$conf);
} else {
$out = '';
// Set layout type:
$type = intval($this->cObj->data['layout']);
// Get the list of files (using stdWrap function since that is easiest)
$lConf=array();
$lConf['override.']['filelist.']['field'] = 'select_key';
$fileList = $this->cObj->stdWrap($this->cObj->data['media'],$lConf);
// Explode into an array:
$fileArray = t3lib_div::trimExplode(',',$fileList,1);
// If there were files to list...:
if (count($fileArray)) {
// Get the path from which the images came:
$selectKeyValues = explode('|',$this->cObj->data['select_key']);
$path = trim($selectKeyValues[0]) ? trim($selectKeyValues[0]) : 'uploads/media/';
// Get the descriptions for the files (if any):
$descriptions = t3lib_div::trimExplode(chr(10),$this->cObj->data['imagecaption']);
// Adding hardcoded TS to linkProc configuration:
$conf['linkProc.']['path.']['current'] = 1;
$conf['linkProc.']['icon'] = 1; // Always render icon - is inserted by PHP if needed.
$conf['linkProc.']['icon.']['wrap'] = ' | //**//'; // Temporary, internal split-token!
$conf['linkProc.']['icon_link'] = 1; // ALways link the icon
$conf['linkProc.']['icon_image_ext_list'] = ($type==2 || $type==3) ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] : ''; // If the layout is type 2 or 3 we will render an image based icon if possible.
// Traverse the files found:
$filesData = array();
foreach($fileArray as $key => $fileName) {
$absPath = t3lib_div::getFileAbsFileName($path.$fileName);
if (@is_file($absPath)) {
$fI = pathinfo($fileName);
$filesData[$key] = array();
$filesData[$key]['filename'] = $fileName;
$filesData[$key]['path'] = $path;
$filesData[$key]['filesize'] = filesize($absPath);
$filesData[$key]['fileextension'] = strtolower($fI['extension']);
$filesData[$key]['description'] = trim($descriptions[$key]);
$this->cObj->setCurrentVal($path);
$GLOBALS['TSFE']->register['ICON_REL_PATH'] = $path.$fileName;
$filesData[$key]['linkedFilenameParts'] = explode('//**//',$this->cObj->filelink($fileName, $conf['linkProc.']));
}
}
}
// Now, lets render the list!
$tRows = array();
foreach($filesData as $key => $fileD) {
// Setting class of table row for odd/even rows:
$oddEven = $key%2 ? 'tr-odd' : 'tr-even';
// Render row, based on the "layout" setting
$tRows[]='
<tr class="'.$oddEven.'">'.($type>0 ? '
<td class="csc-uploads-icon">
'.$fileD['linkedFilenameParts'][0].'
</td>' : '').'
<td class="csc-uploads-fileName">
<p>'.$fileD['linkedFilenameParts'][1].'</p>'.
($fileD['description'] ? '
<p class="csc-uploads-description">'.htmlspecialchars($fileD['description']).'</p>' : '').'
</td>'.($this->cObj->data['filelink_size'] ? '
<td class="csc-uploads-fileSize">
<p>'.t3lib_div::formatSize($fileD['filesize']).'</p>
</td>' : '').'
</tr>';
}
// Now, lets render the list!
$tRows = array();
foreach($filesData as $key => $fileD) {
// Setting class of table row for odd/even rows:
$oddEven = $key%2 ? 'tr-odd' : 'tr-even';
// Render row, based on the "layout" setting
$tRows[]='
<tr class="'.$oddEven.'">'.($type>0 ? '
<td class="csc-uploads-icon">
'.$fileD['linkedFilenameParts'][0].'
</td>' : '').'
<td class="csc-uploads-fileName">
<p>'.$fileD['linkedFilenameParts'][1].'</p>'.
($fileD['description'] ? '
<p class="csc-uploads-description">'.htmlspecialchars($fileD['description']).'</p>' : '').'
</td>'.($this->cObj->data['filelink_size'] ? '
<td class="csc-uploads-fileSize">
<p>'.t3lib_div::formatSize($fileD['filesize']).'</p>
</td>' : '').'
</tr>';
}
// Table tag params.
$tableTagParams = $this->getTableAttributes($conf,$type);
$tableTagParams['class'] = 'csc-uploads csc-uploads-'.$type;
// Table tag params.
$tableTagParams = $this->getTableAttributes($conf,$type);
$tableTagParams['class'] = 'csc-uploads csc-uploads-'.$type;
// Compile it all into table tags:
$out = '
<table '.t3lib_div::implodeAttributes($tableTagParams).'>
'.implode('',$tRows).'
</table>';
}
// Compile it all into table tags:
$out = '
<table '.t3lib_div::implodeAttributes($tableTagParams).'>
'.implode('',$tRows).'
</table>';
}
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
}
// Calling stdWrap:
if ($conf['stdWrap.']) {
$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
}
// Return value
return $out;
// Return value
return $out;
}
}
......@@ -332,6 +350,25 @@ class tx_cssstyledcontent_pi1 extends tslib_pibase {
// Return result:
return $tableTagParams;
}
/**
* Returns an object reference to the hook object if any
*
* @param string Name of the function you want to call / hook key
* @return object Hook object, if any. Otherwise null.
*/
function &hookRequest($functionName) {
global $TYPO3_CONF_VARS;
// Hook: menuConfig_preProcessModMenu
if ($TYPO3_CONF_VARS['EXTCONF']['css_styled_content']['pi1_hooks'][$functionName]) {
$hookObj = &t3lib_div::getUserObj($TYPO3_CONF_VARS['EXTCONF']['css_styled_content']['pi1_hooks'][$functionName]);
if (method_exists ($hookObj, $functionName)) {
$hookObj->pObj = &$this;
return $hookObj;
}
}
}
}
......
......@@ -349,12 +349,13 @@ class tx_indexedsearch_lexer {
// Looking for CJK (Chinese / Japanese / Korean)
// Ranges are not certain - deducted from the translation tables in t3lib/csconvtbl/
// Verified with http://www.unicode.org/charts/ (16/2) - may still not be complete.
if (
($cp >= 0x4E02 && $cp <= 0x9FA5) || // CJK UNIFIED IDEOGRAPH
($cp >= 0xAC02 && $cp <= 0xD79D) || // HANGUL SYLLABLE
($cp >= 0x3131 && $cp <= 0x318E) || // HANGUL LETTER
($cp >= 0x3041 && $cp <= 0x3093) || // HIRAGANA letters
($cp >= 0x30A1 && $cp <= 0x30F6) // KATAKANA letters
($cp >= 0x4E00 && $cp <= 0x9FAF) || // CJK Unified Ideographs
($cp >= 0xAC00 && $cp <= 0xD7AF) || // Hangul Syllables
($cp >= 0x3130 && $cp <= 0x318F) || // Hangul Compatibility Jamo
($cp >= 0x3040 && $cp <= 0x309F) || // HIRAGANA letters
($cp >= 0x30A0 && $cp <= 0x30FF) // KATAKANA letters
) {
return array('cjk');
}
......
ONSDAG:
- Crawler
TORSDAG / FREDAG:
- Test / Koordinering.
<diverse>
Search test:
......@@ -11,49 +10,133 @@ Search test:
- external media on multiple pages with DIFFERENT languages?
- checkResume: Should it also check for gr_list "0,-1"?
- case-sensitivity?
- Warning: phash-row "114682730" didn't have a representation in the index_section table! on references page!
Example på alternativ søgning!
- Warning: phash-row "114682730" didn't have a representation in the index_section table! on references page! (typo3site_live)
Example på alternativ søgnings SQL
XHTML i frontend?
Backend modules:
- Proper skinning? / getLL? / XHTML
Implement stop-word setting in: ""Top-20 words by count:" and a list seperate from that (in main module?)
- Display filters:
- The checkbox "No Search" in the page header is only respected by indexed_search during indexing! (A page will not be indexed when "No Search" is set). However when searching results are not filtered based on this flag - so if a page is indexed before the no search flag is set it will be found in search results. To change this is hard because the getTreeList() function that fetches all page ids cannot take a where-clause to filter it out but must have hardcoded support. Alternatively the pages table must be joined into the search result so we can select on the field. A solution is still not agreed upon.
- For tt_news with access restricted records: don't show the title of page since it can reveal information
SOLUTIONS: Maybe just hide search results where "resume" is normally just not shown?
</diverse>
Unittest for t3lib_cs converting Euc/shift_jis
- Søgning i tabeller (reg. tabeller!)
- Alternative presentationer af når records er indexerede.
- incl. meta-data?
- Tabelvælger som en del af sektionsvælgeren
- Support for visning i extra niveaer?
Test kaniner (indexed search / caching?):
- 3DS
- TYPO3.org copy
- Metropol
- FI
- Link Factory
- Brunata
- TYPO3.org copy
**************
getLL with XML-support?
CLI:
- Removal of old indexes
- delete results with large tstamp (thats all....)
- Indexing configurations
- (Indexing of records from tables should be done automatically in TCEmain with a hook for create/update/delete)
- Look up all index configurations
- Look up phash records (field tstamp) based on config-uid
- For files: read files from directories, compare mtime with records;
- For URLs: Forced
- For records: read records
- All new files are indexed, all old are removed, all changed are re-indexed
CRAWLER:
Purpose: To request URLs
Special instructions:
- Re-cache
- Publish
- Index
(combinations?)
(status data can be stored back in URL-record)
&L=[_TABLE:sys_language;_PID:0:_tx_indexedsearch_fields:bodytext,header]
&[_LOGIN]=[,kasper,francis;_PID:]
&myext[uid]=[1-34,35,36-10]&another=1?
(cache mgm / crawler / publishing)
-> parameters "_TABLE" can instruct indexed_Search which table to index records from!
-> default is flush, INHERIT can
-> crawler gets result back?
Main components:
Page tree module:
- Purger:
- On page id/tree depth: creating URLs from parameters, inserting those URLs in crawler-queue, setting a tstamp which distributes requests over time.
- Backend module
- shows for each parameter line the calculated URLs before submitting them (each parameter in a column showing values or count of UIDs for tables)
- Starttime can be set.
- Alternative: Export URLs to script that WGET can run?
- CLI enables this to be done periodically, walking the page tree.
- Crawler:
- Looking up URLs from queue, sending requests based on that, storing result in log (linked to unique ID for queue entry) (removing log entries if more than 10...)
- Backend module
- shows queue entries with log entries as well
- can initiate a request by force of course
- CLI enables automatic crawling
Root level in page tree:
- Showing overall log / status.
- Flush log
Frontend link generator can also store a URL in the queue!
- Kun cachable URLs
- Either standard params like MP / id / type or cHashed params
crawlerCfg {
procInstructions = ...
clientIdentity = msie etc....
userGroupLists = [0,-1|1,2,3|4]
paramSets {
# Parameters should be url-encoded already:
# Special tokens are: ";:,-"
100 = &L=[|1|2] // Three values for language: "", "1" and "2"
110 = &myext[uid]=[1-34|35|36-10]&another=[1|2|N%20A] // Creating URls with the ranges of integers combined with three positions of "another" which are "1", "2" and "N A"
120 = &print=1
130 = &=[_TABLE:sys_language; _PID:0 (optional, default is current id)]&L=[|1|2] // If no records are selected from table, no URLs are generated
130.pidsOnly = 123,456
130.procInstructions = RECACHE, INDEX, PUBLISH
130.clientIdentity = msie etc....
140.userGroupLists = [0,-1|1,2,3|4]
}
}
Request:
- Header has "X-T3crawler : [qid]:[md5()-hash of qid combined with encryptionKey]
- Header has "X-T3crawler-ProcInstruction : ..."
- Header has "X-T3crawler-UserGroup : ..."
- Request is authenticated by looking up qid and calculating hash. (might include IP lock)
- If OK, then the result is info-array rather than HTML output.
Queue:
qid (int hash of page_id / parameters are unique id / procIn / clientID / usergroup lists) - PRIMARY KEY
page_id (if zero: Function call , see special instructioncs)
parameters (or serialized parameters for function call)
domain
special_instructions (function call)
starttime // Scheduled to being processed at this point
exec_time // Zero when not done, otherwise set to execution time. This will help us to spot "outdated" entries by time since this
When a URL is reindexed the SAME record is used (qid), starttime set and exec_time reset
Log entries are kept
Log:
uid // Autoincr.
qid // Queue ID
result // serialized data
exec_time
- cached?
- parsetime?
- strlen?
- messages?
***************
......@@ -72,11 +155,10 @@ Statistics module:
Olivier Dobberkau / dkd is on this.
Various:
- The checkbox "No Search" in the page header is only respected by indexed_search during indexing! (A page will not be indexed when "No Search" is set). However when searching results are not filtered based on this flag - so if a page is indexed before the no search flag is set it will be found in search results. To change this is hard because the getTreeList() function that fetches all page ids cannot take a where-clause to filter it out but must have hardcoded support. Alternatively the pages table must be joined into the search result so we can select on the field. A solution is still not agreed upon.
- The Tools>Indexing module could need some shining up and more useful features (Someone else does this?)
- CLI script for removal of old indexes: First set flag, then 14 days later remove the records.
Templating / Display in plugin:
- Templating
- with new Template API?
- Still need to put a group together.