Index: trunk/extensions/DynamicPageList/DynamicPageList2.php |
— | — | @@ -1,4 +1,5 @@ |
2 | 2 | <?php |
| 3 | + |
3 | 4 | /** |
4 | 5 | * Main include file for the DynamicPageList2 extension of MediaWiki. |
5 | 6 | * This code is released under the GNU General Public License. |
— | — | @@ -291,7 +292,13 @@ |
292 | 293 | * Bugfix: labeled section inclusion did not work because content was automatically truncated to a length of zero |
293 | 294 | * added minrevisions & maxrevisions |
294 | 295 | * @version 1.7.9 |
295 | | - * ... |
| 296 | + * Bugfix in errorhandling: parameter substitution within error message did not work. |
| 297 | + * Bugfix in ordermethod=lastedit, firstedit -- led to the effect that too few pages/revisions were shown |
| 298 | + * new feature: dplcache |
| 299 | + * bugfix: with include=* a php warning could arise (Call-time pass-by-reference has been deprecated ..) |
| 300 | + * new variable %IMAGE% contains image path |
| 301 | + * new variable: %PAGEID% |
| 302 | + * DPL command line argument: DPL_offset |
296 | 303 | * ! when making changes here you must update the VERSION constant at the beginning of class ExtDynamicPageList2 ! |
297 | 304 | */ |
298 | 305 | |
— | — | @@ -330,8 +337,9 @@ |
331 | 338 | |
332 | 339 | class ExtDynamicPageList2 |
333 | 340 | { |
334 | | - const VERSION = '1.7.8'; // current version |
335 | 341 | |
| 342 | + const VERSION = '1.7.9'; // current version |
| 343 | + |
336 | 344 | /** |
337 | 345 | * Extension options |
338 | 346 | */ |
— | — | @@ -406,6 +414,10 @@ |
407 | 415 | * shall the result set be distinct (=default) or not? |
408 | 416 | */ |
409 | 417 | 'distinct' => array('default' => 'true', 'strict', 'false', 'no', 'yes', '0', '1', 'off', 'on'), |
| 418 | + |
| 419 | + 'dplcache' => array('default' => ''), |
| 420 | + 'dplcacheperiod' => array('default' => '86400', 'pattern' => '/^\d+$/'), // 86400 = # seconds for one day |
| 421 | + |
410 | 422 | /** |
411 | 423 | * number of columns for output, default is 1 |
412 | 424 | */ |
— | — | @@ -1106,7 +1118,7 @@ |
1107 | 1119 | return ''; |
1108 | 1120 | } |
1109 | 1121 | |
1110 | | - // The real callback function for converting the input text to HTML output |
| 1122 | + // The real callback function for converting the input text to wiki text output |
1111 | 1123 | private static function dynamicPageList( $input, $params, &$parser, &$bReset, $calledInMode ) { |
1112 | 1124 | |
1113 | 1125 | error_reporting(E_ALL); |
— | — | @@ -1162,6 +1174,10 @@ |
1163 | 1175 | |
1164 | 1176 | // Options |
1165 | 1177 | |
| 1178 | + $DPLCache = ''; |
| 1179 | + $buildDPLCache=false; |
| 1180 | + $iDPLCachePeriod = 24* 60 * 60; |
| 1181 | + |
1166 | 1182 | $sGoal = self::$options['goal']['default']; |
1167 | 1183 | |
1168 | 1184 | $bSelectionCriteriaFound=false; |
— | — | @@ -1235,6 +1251,8 @@ |
1236 | 1252 | $bAddLastEditor = self::argBoolean(self::$options['addlasteditor']['default']); |
1237 | 1253 | |
1238 | 1254 | $bAllowCachedResults = self::argBoolean(self::$options['allowcachedresults']['default']); |
| 1255 | + // disable parser cache if desired |
| 1256 | + $parser->disableCache(!$bAllowCachedResults); |
1239 | 1257 | $bWarnCachedResults = false; |
1240 | 1258 | |
1241 | 1259 | $sUserDateFormat = self::$options['userdateformat']['default']; |
— | — | @@ -1260,8 +1278,9 @@ |
1261 | 1279 | $aSecSeparators = explode(',', self::$options['secseparators']['default']); |
1262 | 1280 | $aMultiSecSeparators = explode(',', self::$options['multisecseparators']['default']); |
1263 | 1281 | $iDominantSection = self::$options['dominantsection']['default']; |
1264 | | - |
1265 | | - $_sOffset = self::$options['offset']['default']; |
| 1282 | + |
| 1283 | + global $wgRequest; |
| 1284 | + $_sOffset=$wgRequest->getVal('DPL_offset',self::$options['offset']['default']); |
1266 | 1285 | $iOffset = ($_sOffset == '') ? 0: intval($_sOffset); |
1267 | 1286 | |
1268 | 1287 | $_sCount = self::$options['count']['default']; |
— | — | @@ -1349,17 +1368,20 @@ |
1350 | 1369 | // ###### PARSE PARAMETERS ###### |
1351 | 1370 | |
1352 | 1371 | // we replace double angle brackets by < > ; thus we avoid premature tag expansion in the input |
1353 | | - $input = str_replace('»','>',$input); |
1354 | | - $input = str_replace('«','<',$input); |
| 1372 | + $input = str_replace('»','>',$input); |
| 1373 | + $input = str_replace('«','<',$input); |
1355 | 1374 | |
1356 | 1375 | // use the ¦ as a general alias for | |
1357 | | - $input = str_replace('¦','|',$input); // the symbol is utf8-escaped |
| 1376 | + $input = str_replace('¦','|',$input); // the symbol is utf8-escaped |
1358 | 1377 | |
1359 | 1378 | // the combination '²{' and '}²'will be translated to double curly braces; this allows postponed template execution |
1360 | 1379 | // which is crucial for DPL queries which call other DPL queries |
1361 | | - $input = str_replace('²{','{{',$input); |
1362 | | - $input = str_replace('}²','}}',$input); |
1363 | | - |
| 1380 | + $input = str_replace('²{','{{',$input); |
| 1381 | + $input = str_replace('}²','}}',$input); |
| 1382 | + |
| 1383 | + // commandline parameters like %DPL_offset% are replaced |
| 1384 | + $input = str_replace('%DPL_offset%',$iOffset,$input); |
| 1385 | + |
1364 | 1386 | $aParams = explode("\n", $input); |
1365 | 1387 | $bIncludeUncat = false; // to check if pseudo-category of Uncategorized pages is included |
1366 | 1388 | |
— | — | @@ -1395,10 +1417,59 @@ |
1396 | 1418 | $output .= $logger->escapeMsg(DPL2_i18n::WARN_UNKNOWNPARAM, $sType, implode(', ', array_keys(self::$options))); |
1397 | 1419 | continue; |
1398 | 1420 | } |
1399 | | - |
| 1421 | + |
1400 | 1422 | switch ($sType) { |
1401 | | - |
| 1423 | + |
1402 | 1424 | /** |
| 1425 | + * CACHE |
| 1426 | + */ |
| 1427 | + case 'dplcache': |
| 1428 | + if ($sArg!='') { |
| 1429 | + global $wgUploadDirectory, $wgRequest, $wgArticle; |
| 1430 | + $DPLCache = $wgArticle->getID().'_'.$sArg.'.txt'; |
| 1431 | + $cacheFile= "$wgUploadDirectory/dplcache/$DPLCache"; |
| 1432 | + if ($wgRequest->getVal('action','view')=='submit') { |
| 1433 | + // when the page containing the DPL statement is changed we must recreate the cache |
| 1434 | + // as the DPL statement may have changed |
| 1435 | + $buildDPLCache=true; |
| 1436 | + } else if ($wgRequest->getVal('dplrefresh','')=='yes') { |
| 1437 | + // when the page containing the DPL statement is changed we must recreate the cache |
| 1438 | + // as the DPL statement may have changed |
| 1439 | + $buildDPLCache=true; |
| 1440 | + } else if (file_exists($cacheFile)) { |
| 1441 | + // find out if cache is acceptable or too old |
| 1442 | + $diff = time() - filemtime($cacheFile); |
| 1443 | + $cacheTimeStamp = date('YmdHis',filemtime($cacheFile)); |
| 1444 | + $buildDPLCache = ($diff > $iDPLCachePeriod); |
| 1445 | + $cacheTimeStamp = ExtDynamicPageList2::prettyTimeStamp($cacheTimeStamp); |
| 1446 | + $cachePeriod = ExtDynamicPageList2::durationTime($iDPLCachePeriod); |
| 1447 | + $diffTime = ExtDynamicPageList2::durationTime($diff); |
| 1448 | + } |
| 1449 | + else { |
| 1450 | + $buildDPLCache=true; |
| 1451 | + } |
| 1452 | + if (!$buildDPLCache) { |
| 1453 | + // take result from cache article |
| 1454 | + if ($logger->iDebugLevel>=2) $output .= "{{Extension DPL cache|mode=get|pos=top|page={{FULLPAGENAME}}|cache=$DPLCache|date=$cacheTimeStamp|age=$diffTime|period=$cachePeriod}}"; |
| 1455 | + $output .= file_get_contents($cacheFile); |
| 1456 | + if ($logger->iDebugLevel>=2) $output .= "{{Extension DPL cache|mode=get|pos=bottom|page={{FULLPAGENAME}}|cache=$DPLCache|date=$cacheTimeStamp|age=$diffTime|period=$cachePeriod}}"; |
| 1457 | + // ignore further parameters, stop processing, return cache content |
| 1458 | + return $output; |
| 1459 | + } |
| 1460 | + } |
| 1461 | + else { |
| 1462 | + $output .= $logger->msgWrongParam('dplcache', $sArg); |
| 1463 | + } |
| 1464 | + break; |
| 1465 | + |
| 1466 | + case 'dplcacheperiod': |
| 1467 | + if( preg_match(self::$options['dplcacheperiod']['pattern'], $sArg) ) |
| 1468 | + $iDPLCachePeriod = ($sArg == '') ? self::$options['dplcacheperiod']['default']: intval($sArg); |
| 1469 | + else |
| 1470 | + $output .= $logger->msgWrongParam('dplcacheperiod', $sArg); |
| 1471 | + break; |
| 1472 | + |
| 1473 | + /** |
1403 | 1474 | * GOAL |
1404 | 1475 | */ |
1405 | 1476 | case 'goal': |
— | — | @@ -1680,6 +1751,7 @@ |
1681 | 1752 | $bSelectionCriteriaFound=true; |
1682 | 1753 | $bConflictsWithOpenReferences=true; |
1683 | 1754 | $bAllowCachedResults = true; |
| 1755 | + $parser->disableCache(false); |
1684 | 1756 | } |
1685 | 1757 | break; |
1686 | 1758 | |
— | — | @@ -2077,7 +2149,7 @@ |
2078 | 2150 | // parsing of wikitext will happen at the end of the output phase |
2079 | 2151 | // we replace '\n' in the input by linefeed because wiki syntax depends on linefeeds |
2080 | 2152 | $sArg = str_replace( '\n', "\n", $sArg ); |
2081 | | - $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
| 2153 | + $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
2082 | 2154 | $aListSeparators = explode (',', $sArg, 4); |
2083 | 2155 | // mode=userformat will be automatically assumed |
2084 | 2156 | $sPageListMode='userformat'; |
— | — | @@ -2087,25 +2159,25 @@ |
2088 | 2160 | case 'secseparators': |
2089 | 2161 | // we replace '\n' by newline to support wiki syntax within the section separators |
2090 | 2162 | $sArg = str_replace( '\n', "\n", $sArg ); |
2091 | | - $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
| 2163 | + $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
2092 | 2164 | $aSecSeparators = explode (',',$sArg); |
2093 | 2165 | break; |
2094 | 2166 | |
2095 | 2167 | case 'multisecseparators': |
2096 | 2168 | // we replace '\n' by newline to support wiki syntax within the section separators |
2097 | 2169 | $sArg = str_replace( '\n', "\n", $sArg ); |
2098 | | - $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
| 2170 | + $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
2099 | 2171 | $aMultiSecSeparators = explode (',',$sArg); |
2100 | 2172 | break; |
2101 | 2173 | |
2102 | 2174 | case 'table': |
2103 | 2175 | $sArg = str_replace( '\n', "\n", $sArg ); |
2104 | | - $sTable = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
| 2176 | + $sTable = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
2105 | 2177 | break; |
2106 | 2178 | |
2107 | 2179 | case 'tablerow': |
2108 | 2180 | $sArg = str_replace( '\n', "\n", $sArg ); |
2109 | | - $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
| 2181 | + $sArg = str_replace( "¶", "\n", $sArg ); // the paragraph delimiter is utf8-escaped |
2110 | 2182 | if (trim($sArg)=='') $aTableRow = array(); |
2111 | 2183 | else $aTableRow = explode (',',$sArg); |
2112 | 2184 | break; |
— | — | @@ -2220,6 +2292,7 @@ |
2221 | 2293 | $bAllowCachedResults = true; |
2222 | 2294 | $bWarnCachedResults = true; |
2223 | 2295 | } |
| 2296 | + $parser->disableCache(!$bAllowCachedResults); |
2224 | 2297 | } |
2225 | 2298 | else |
2226 | 2299 | $output .= $logger->msgWrongParam('allowcachedresults', $sArg); |
— | — | @@ -2275,6 +2348,7 @@ |
2276 | 2349 | default: |
2277 | 2350 | $output .= $logger->escapeMsg(DPL2_i18n::WARN_UNKNOWNPARAM, $sType, implode(', ', array_keys(self::$options))); |
2278 | 2351 | } |
| 2352 | + |
2279 | 2353 | } |
2280 | 2354 | |
2281 | 2355 | // debug level 5 puts nowiki tags around the output |
— | — | @@ -2294,9 +2368,6 @@ |
2295 | 2369 | $iExcludeCatCount = count($aExcludeCategories); |
2296 | 2370 | $iTotalCatCount = $iTotalIncludeCatCount + $iExcludeCatCount; |
2297 | 2371 | |
2298 | | - // disable parser cache |
2299 | | - if ( !$bAllowCachedResults) $parser->disableCache(); |
2300 | | - |
2301 | 2372 | // place cache warning in resultsheader |
2302 | 2373 | if ($bWarnCachedResults) $sResultsHeader = '{{DPL Cache Warning}}' . $sResultsHeader; |
2303 | 2374 | |
— | — | @@ -2335,8 +2406,8 @@ |
2336 | 2407 | |
2337 | 2408 | // no selection criteria!! Warn only if no debug level is set |
2338 | 2409 | if ($iTotalCatCount == 0 && $bSelectionCriteriaFound==false) { |
2339 | | - if ($logger->iDebugLevel >= 1) return $output; |
2340 | | - else return $output . $logger->escapeMsg(DPL2_i18n::FATAL_NOSELECTION); |
| 2410 | + if ($logger->iDebugLevel <= 1) return $output; |
| 2411 | + return $output . $logger->escapeMsg(DPL2_i18n::FATAL_NOSELECTION); |
2341 | 2412 | } |
2342 | 2413 | |
2343 | 2414 | // ordermethod=sortkey requires ordermethod=category |
— | — | @@ -2466,6 +2537,8 @@ |
2467 | 2538 | } |
2468 | 2539 | } |
2469 | 2540 | |
| 2541 | + $output.='{{Extension DPL}}'; |
| 2542 | + |
2470 | 2543 | // ###### BUILD SQL QUERY ###### |
2471 | 2544 | $sSqlPage_counter = ''; |
2472 | 2545 | $sSqlPage_size = ''; |
— | — | @@ -2525,12 +2598,14 @@ |
2526 | 2599 | case 'firstedit': |
2527 | 2600 | $sSqlRevisionTable = $sRevisionTable . ' AS rev, '; |
2528 | 2601 | $sSqlRev_timestamp = ', rev_timestamp'; |
2529 | | - $sSqlCond_page_rev = ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
| 2602 | + // deleted because of conflict with revsion-parameters |
| 2603 | + // $sSqlCond_page_rev = ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
2530 | 2604 | break; |
2531 | 2605 | case 'lastedit': |
2532 | 2606 | $sSqlRevisionTable = $sRevisionTable . ' AS rev, '; |
2533 | 2607 | $sSqlRev_timestamp = ', rev_timestamp'; |
2534 | | - $sSqlCond_page_rev = ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
| 2608 | + // deleted because of conflict with revsion-parameters |
| 2609 | + // $sSqlCond_page_rev = ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
2535 | 2610 | break; |
2536 | 2611 | case 'sortkey': |
2537 | 2612 | // We need the namespaces with strictly positive indices (DPL2 allowed namespaces, except the first one: Main). |
— | — | @@ -2544,14 +2619,14 @@ |
2545 | 2620 | // UTF-8 created problems with non-utf-8 MySQL databases |
2546 | 2621 | //see line 2011 (order method sortkey requires category |
2547 | 2622 | if (in_array('category',$aOrderMethods)) { |
2548 | | - $sSqlSortkey = ", IFNULL(cl_head.cl_sortkey, REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'â£','⣣')) ".$sOrderCollation." as sortkey"; |
| 2623 | + $sSqlSortkey = ", IFNULL(cl_head.cl_sortkey, REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'♣','⣣')) ".$sOrderCollation." as sortkey"; |
2549 | 2624 | } |
2550 | 2625 | else { |
2551 | | - $sSqlSortkey = ", IFNULL(cl0.cl_sortkey, REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'â£','⣣')) ".$sOrderCollation." as sortkey"; |
| 2626 | + $sSqlSortkey = ", IFNULL(cl0.cl_sortkey, REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'♣','⣣')) ".$sOrderCollation." as sortkey"; |
2552 | 2627 | } |
2553 | 2628 | break; |
2554 | 2629 | case 'titlewithoutnamespace': |
2555 | | - $sSqlSortkey = ", REPLACE(page_title,'â£','⣣') ".$sOrderCollation." as sortkey"; |
| 2630 | + $sSqlSortkey = ", REPLACE(page_title,'♣','⣣') ".$sOrderCollation." as sortkey"; |
2556 | 2631 | break; |
2557 | 2632 | case 'pagesel': |
2558 | 2633 | $sSqlSortkey = ", CONCAT(pl.pl_namespace,pl.pl_title) ".$sOrderCollation." as sortkey"; |
— | — | @@ -2564,7 +2639,7 @@ |
2565 | 2640 | foreach($aStrictNs as $iNs => $sNs) |
2566 | 2641 | $sSqlNsIdToText .= ' WHEN ' . intval( $iNs ) . " THEN " . $dbr->addQuotes( $sNs ) ; |
2567 | 2642 | $sSqlNsIdToText .= ' END'; |
2568 | | - $sSqlSortkey = ", REPLACE(REPLACE(CONCAT( IF(pl_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), pl_title), '_', ' '),'â£','⣣') ".$sOrderCollation." as sortkey"; |
| 2643 | + $sSqlSortkey = ", REPLACE(REPLACE(CONCAT( IF(pl_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), pl_title), '_', ' '),'♣','⣣') ".$sOrderCollation." as sortkey"; |
2569 | 2644 | } |
2570 | 2645 | else { |
2571 | 2646 | $sSqlNsIdToText = 'CASE '.$sPageTable.'.page_namespace'; |
— | — | @@ -2572,7 +2647,7 @@ |
2573 | 2648 | $sSqlNsIdToText .= ' WHEN ' . intval( $iNs ) . " THEN " . $dbr->addQuotes( $sNs ) ; |
2574 | 2649 | $sSqlNsIdToText .= ' END'; |
2575 | 2650 | // Generate sortkey like for category links. UTF-8 created problems with non-utf-8 MySQL databases |
2576 | | - $sSqlSortkey = ", REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'â£','⣣') ".$sOrderCollation." as sortkey"; |
| 2651 | + $sSqlSortkey = ", REPLACE(REPLACE(CONCAT( IF(".$sPageTable.".page_namespace=0, '', CONCAT(" . $sSqlNsIdToText . ", ':')), ".$sPageTable.".page_title), '_', ' '),'♣','⣣') ".$sOrderCollation." as sortkey"; |
2577 | 2652 | } |
2578 | 2653 | break; |
2579 | 2654 | case 'user': |
— | — | @@ -2790,11 +2865,11 @@ |
2791 | 2866 | |
2792 | 2867 | if ($bAddAuthor && $sSqlRevisionTable =='') { |
2793 | 2868 | $sSqlRevisionTable = $sRevisionTable . ' AS rev, '; |
2794 | | - $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
| 2869 | + $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux_min.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux_min WHERE rev_aux_min.rev_page=rev.rev_page )'; |
2795 | 2870 | } |
2796 | 2871 | if ($bAddLastEditor && $sSqlRevisionTable =='') { |
2797 | 2872 | $sSqlRevisionTable = $sRevisionTable . ' AS rev, '; |
2798 | | - $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page )'; |
| 2873 | + $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux_max.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux_max WHERE rev_aux_max.rev_page=rev.rev_page )'; |
2799 | 2874 | } |
2800 | 2875 | |
2801 | 2876 | if ($sLastRevisionBefore.$sAllRevisionsBefore.$sFirstRevisionSince.$sAllRevisionsSince != '') { |
— | — | @@ -2808,13 +2883,13 @@ |
2809 | 2884 | $sSqlRev_timestamp = ', rev_timestamp'; |
2810 | 2885 | $sSqlRev_id = ', rev_id'; |
2811 | 2886 | if ($sLastRevisionBefore!='') { |
2812 | | - $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page AND rev_aux.rev_timestamp < '.$sLastRevisionBefore.')'; |
| 2887 | + $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux_bef.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux_bef WHERE rev_aux_bef.rev_page=rev.rev_page AND rev_aux_bef.rev_timestamp < '.$sLastRevisionBefore.')'; |
2813 | 2888 | } |
2814 | 2889 | if ($sAllRevisionsBefore!='') { |
2815 | 2890 | $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp < '.$sAllRevisionsBefore; |
2816 | 2891 | } |
2817 | 2892 | if ($sFirstRevisionSince!='') { |
2818 | | - $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux WHERE rev_aux.rev_page=rev.rev_page AND rev_aux.rev_timestamp >= '.$sFirstRevisionSince.')'; |
| 2893 | + $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp=( SELECT MAX(rev_aux_snc.rev_timestamp) FROM ' . $sRevisionTable . ' AS rev_aux_snc WHERE rev_aux_snc.rev_page=rev.rev_page AND rev_aux_snc.rev_timestamp >= '.$sFirstRevisionSince.')'; |
2819 | 2894 | } |
2820 | 2895 | if ($sAllRevisionsSince!='') { |
2821 | 2896 | $sSqlCond_page_rev .= ' AND '.$sPageTable.'.page_id=rev.rev_page AND rev.rev_timestamp >= '.$sAllRevisionsSince; |
— | — | @@ -2863,7 +2938,7 @@ |
2864 | 2939 | } |
2865 | 2940 | else |
2866 | 2941 | $sSqlSelectFrom = "SELECT $sSqlCalcFoundRows $sSqlDistinct " . $sSqlCl_to . $sPageTable.'.page_namespace as page_namespace,'. |
2867 | | - $sPageTable.'.page_title as page_title' . $sSqlSelPage . $sSqlSortkey . $sSqlPage_counter . |
| 2942 | + $sPageTable.'.page_title as page_title ,page_id' . $sSqlSelPage . $sSqlSortkey . $sSqlPage_counter . |
2868 | 2943 | $sSqlPage_size . $sSqlPage_touched . $sSqlRev_user . |
2869 | 2944 | $sSqlRev_timestamp . $sSqlRev_id . $sSqlCats . $sSqlCl_timestamp . |
2870 | 2945 | ' FROM ' . $sSqlRevisionTable . $sSqlRCTable . $sSqlPageLinksTable . $sPageTable; |
— | — | @@ -3089,8 +3164,8 @@ |
3090 | 3165 | } |
3091 | 3166 | |
3092 | 3167 | if ($dbr->numRows( $res ) <= 0) { |
3093 | | - if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader)); |
3094 | | - if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter)); |
| 3168 | + if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader)); |
| 3169 | + if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter)); |
3095 | 3170 | if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL2_i18n::WARN_NORESULTS); |
3096 | 3171 | $dbr->freeResult( $res ); |
3097 | 3172 | return $output; |
— | — | @@ -3186,6 +3261,9 @@ |
3187 | 3262 | if( isset($row->sortkey) ) { |
3188 | 3263 | $dplArticle->mStartChar = $wgContLang->convert($wgContLang->firstChar($row->sortkey)); |
3189 | 3264 | } |
| 3265 | + // page_id |
| 3266 | + $dplArticle->mID = $row->page_id; |
| 3267 | + |
3190 | 3268 | //SHOW PAGE_COUNTER |
3191 | 3269 | if( isset($row->page_counter) ) |
3192 | 3270 | $dplArticle->mCounter = $row->page_counter; |
— | — | @@ -3312,14 +3390,14 @@ |
3313 | 3391 | if ($sOneResultHeader != '' && $rowcount==1) { |
3314 | 3392 | $header = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',1,$sOneResultHeader)); |
3315 | 3393 | } else if ($rowcount==0) { |
3316 | | - if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader)); |
3317 | | - if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter)); |
| 3394 | + if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader)); |
| 3395 | + if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter)); |
3318 | 3396 | if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL2_i18n::WARN_NORESULTS); |
3319 | 3397 | } |
3320 | 3398 | else { |
3321 | 3399 | if ($sResultsHeader != '') $header = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',$dpl->getRowCount(),$sResultsHeader)); |
3322 | 3400 | } |
3323 | | - $header = str_replace( '\n', "\n", str_replace( "¶", "\n", $header )); |
| 3401 | + $header = str_replace( '\n', "\n", str_replace( "¶", "\n", $header )); |
3324 | 3402 | $header = str_replace('%VERSION%', self::VERSION,$header); |
3325 | 3403 | $footer=''; |
3326 | 3404 | if ($sOneResultFooter != '' && $rowcount==1) { |
— | — | @@ -3327,11 +3405,21 @@ |
3328 | 3406 | } else { |
3329 | 3407 | if ($sResultsFooter != '') $footer = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',$rowcount,$sResultsFooter)); |
3330 | 3408 | } |
3331 | | - $footer = str_replace( '\n', "\n", str_replace( "¶", "\n", $footer )); |
| 3409 | + $footer = str_replace( '\n', "\n", str_replace( "¶", "\n", $footer )); |
3332 | 3410 | $footer = str_replace('%VERSION%', self::VERSION, $footer); |
3333 | 3411 | |
3334 | 3412 | $output .= $header . $dpl2result . $footer; |
| 3413 | + |
3335 | 3414 | |
| 3415 | + // save generated wiki text to dplcache page if desired |
| 3416 | + if ($buildDPLCache) { |
| 3417 | + if (!file_exists(dirname($cacheFile))) mkdir(dirname($cacheFile)); |
| 3418 | + $cacheTimeStamp = ExtDynamicPageList2::prettyTimeStamp(date('YmdHis')); |
| 3419 | + file_put_contents($cacheFile,$output); |
| 3420 | + if ($logger->iDebugLevel>=2) $output .= "{{Extension DPL cache|pos=bottom|mode=update|page={{FULLPAGENAME}}|cache=$DPLCache|date=$cacheTimeStamp|age=0}}"; |
| 3421 | + } |
| 3422 | + |
| 3423 | + |
3336 | 3424 | // The following requires an extra parser step which may consume some time |
3337 | 3425 | // we parse the DPL output and save all referenced found in that output in a global list |
3338 | 3426 | // in a final user exit after the whole document processing we eliminate all these links |
— | — | @@ -3380,6 +3468,7 @@ |
3381 | 3469 | } |
3382 | 3470 | |
3383 | 3471 | return $output; |
| 3472 | + |
3384 | 3473 | |
3385 | 3474 | } |
3386 | 3475 | |
— | — | @@ -3421,6 +3510,17 @@ |
3422 | 3511 | $dbr->freeResult( $res ); |
3423 | 3512 | return $cats; |
3424 | 3513 | } |
| 3514 | + |
| 3515 | + private static function prettyTimeStamp($t) { |
| 3516 | + return substr($t,0,4).'/'.substr($t,4,2).'/'.substr($t,6,2).' '.substr($t,8,2).':'.substr($t,10,2).':'.substr($t,12,2); |
| 3517 | + } |
| 3518 | + private static function durationTime($t) { |
| 3519 | + if ($t<60) return "00:00:".str_pad($t,2,"0",STR_PAD_LEFT); |
| 3520 | + if ($t<3600) return "00:".str_pad(floor($t/60),2,"0",STR_PAD_LEFT).':'.str_pad(floor(fmod($t,60)),2,"0",STR_PAD_LEFT); |
| 3521 | + if ($t<86400) return str_pad(floor($t/3600),2,"0",STR_PAD_LEFT).':'.str_pad(floor(fmod(floor($t/60),60)),2,"0",STR_PAD_LEFT).':'.str_pad(fmod($t,60),2,"0",STR_PAD_LEFT); |
| 3522 | + if ($t<2*86400) return "1 day"; |
| 3523 | + return floor($t/86400). ' days'; |
| 3524 | + } |
3425 | 3525 | |
3426 | 3526 | public static function endReset( &$parser, $text ) { |
3427 | 3527 | if (!self::$createdLinks['resetdone']) { |
— | — | @@ -3492,6 +3592,7 @@ |
3493 | 3593 | class DPL2Article { |
3494 | 3594 | var $mTitle = ''; // title |
3495 | 3595 | var $mNamespace = -1; // namespace (number) |
| 3596 | + var $mID = 0; // page_id |
3496 | 3597 | var $mSelTitle = ''; // selected title of initial page |
3497 | 3598 | var $mSelNamespace = -1;// selected namespace (number) of initial page |
3498 | 3599 | var $mImageSelTitle = ''; // selected title of image |
— | — | @@ -3770,14 +3871,16 @@ |
3771 | 3872 | } |
3772 | 3873 | |
3773 | 3874 | // substitute symbolic names within a user defined format tag |
3774 | | - function substTagParm($tag, $pagename, $article, $nr, $titleMaxLength) { |
| 3875 | + function substTagParm($tag, $pagename, $article, $imageUrl, $nr, $titleMaxLength) { |
3775 | 3876 | global $wgLang; |
3776 | 3877 | if (strchr($tag,'%')<0) return $tag; |
3777 | 3878 | $sTag = str_replace('%PAGE%',$pagename,$tag); |
| 3879 | + $sTag = str_replace('%PAGEID%',$article->mID,$sTag); |
3778 | 3880 | $sTag = str_replace('%NAMESPACE%',$this->nameSpaces[$article->mNamespace],$sTag); |
| 3881 | + $sTag = str_replace('%IMAGE%',$imageUrl,$sTag); |
3779 | 3882 | |
3780 | 3883 | $title = $article->mTitle->getText(); |
3781 | | - if (strpos($title,'%TITLE')>=0) { |
| 3884 | + if (strpos($title,'%TITLE%')>=0) { |
3782 | 3885 | if ($this->mReplaceInTitle[0]!='') $title = preg_replace($this->mReplaceInTitle[0],$this->mReplaceInTitle[1],$title); |
3783 | 3886 | if( isset($titleMaxLength) && (strlen($title) > $titleMaxLength)) $title = substr($title, 0, $titleMaxLength) . '...'; |
3784 | 3887 | $sTag = str_replace('%TITLE%',$title,$sTag); |
— | — | @@ -3840,6 +3943,12 @@ |
3841 | 3944 | |
3842 | 3945 | $article = $this->mArticles[$i]; |
3843 | 3946 | $pagename = $article->mTitle->getPrefixedText(); |
| 3947 | + $imageUrl=''; |
| 3948 | + if ($article->mNamespace==6) { |
| 3949 | + // calculate URL for existing images |
| 3950 | + $img = Image::newFromName($article->mTitle->getText()); |
| 3951 | + if ($img && $img->exists()) $imageUrl = $img->getURL(); |
| 3952 | + } |
3844 | 3953 | if ($this->mEscapeLinks && ($article->mNamespace==14 || $article->mNamespace==6) ) { |
3845 | 3954 | // links to categories or images need an additional ":" |
3846 | 3955 | $pagename = ':'.$pagename; |
— | — | @@ -3877,9 +3986,9 @@ |
3878 | 3987 | else { |
3879 | 3988 | // append full text to output |
3880 | 3989 | if (array_key_exists('0',$mode->sSectionTags)){ |
3881 | | - $incwiki .= $this->substTagParm($mode->sSectionTags[0], $pagename, $article,$this->filteredCount, $iTitleMaxLen); |
| 3990 | + $incwiki .= $this->substTagParm($mode->sSectionTags[0], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen); |
3882 | 3991 | $pieces = array(0=>$text); |
3883 | | - $this->formatSingleItems(&$pieces, 0); |
| 3992 | + $this->formatSingleItems($pieces, 0); |
3884 | 3993 | $incwiki .= $pieces[0]; |
3885 | 3994 | } |
3886 | 3995 | else $incwiki .= $text; |
— | — | @@ -3949,7 +4058,7 @@ |
3950 | 4059 | for ($sp=1;$sp<count($secPieces);$sp++) { |
3951 | 4060 | if (isset($mode->aMultiSecSeparators[$s])) { |
3952 | 4061 | $secPiece[$s] .= str_replace('%SECTION%',$sectionHeading[$sp], |
3953 | | - $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, |
| 4062 | + $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, |
3954 | 4063 | $this->filteredCount, $iTitleMaxLen)); |
3955 | 4064 | } |
3956 | 4065 | $secPiece[$s] .= $secPieces[$sp]; |
— | — | @@ -3968,7 +4077,7 @@ |
3969 | 4078 | $template2, $template2.$defaultTemplateSuffix,$mustMatch, |
3970 | 4079 | $mustNotMatch,$this->mIncParsed,$iTitleMaxLen); |
3971 | 4080 | $secPiece[$s] = implode(isset($mode->aMultiSecSeparators[$s])? |
3972 | | - $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
| 4081 | + $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
3973 | 4082 | if ($mode->iDominantSection>=0 && $s==$mode->iDominantSection && count($secPieces)>1) $dominantPieces=$secPieces; |
3974 | 4083 | if (($mustMatch!='' || $mustNotMatch!='') && count($secPieces)<=1 && $secPieces[0]=='') { |
3975 | 4084 | $matchFailed=true; // NOTHING MATCHED |
— | — | @@ -3978,7 +4087,7 @@ |
3979 | 4088 | // Uses DPL2Include::includeSection() from LabeledSectionTransclusion extension to include labeled sections from the page |
3980 | 4089 | $secPieces = DPL2Include::includeSection($this->mParser, $article->mTitle->getPrefixedText(), $sSecLabel,'', false, $bIncludeTrim); |
3981 | 4090 | $secPiece[$s] = implode(isset($mode->aMultiSecSeparators[$s])? |
3982 | | - $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
| 4091 | + $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
3983 | 4092 | if ($mode->iDominantSection>=0 && $s==$mode->iDominantSection && count($secPieces)>1) $dominantPieces=$secPieces; |
3984 | 4093 | if ( ($mustMatch !='' && preg_match($mustMatch ,$secPiece[$s])==false) || |
3985 | 4094 | ($mustNotMatch !='' && preg_match($mustNotMatch,$secPiece[$s])!=false) ) { |
— | — | @@ -3990,14 +4099,14 @@ |
3991 | 4100 | // separator tags |
3992 | 4101 | if (count($mode->sSectionTags)==1) { |
3993 | 4102 | // If there is only one separator tag use it always |
3994 | | - $septag[$s*2] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[0], $pagename, $article, $this->filteredCount, $iTitleMaxLen)); |
| 4103 | + $septag[$s*2] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[0], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen)); |
3995 | 4104 | } |
3996 | 4105 | else if (isset($mode->sSectionTags[$s*2])) { |
3997 | | - $septag[$s*2] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[$s*2], $pagename, $article, $this->filteredCount, $iTitleMaxLen)); |
| 4106 | + $septag[$s*2] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[$s*2], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen)); |
3998 | 4107 | } |
3999 | 4108 | else $septag[$s*2] = ''; |
4000 | 4109 | if (isset($mode->sSectionTags[$s*2+1])) { |
4001 | | - $septag[$s*2+1] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[$s*2+1], $pagename, $article, $this->filteredCount, $iTitleMaxLen)); |
| 4110 | + $septag[$s*2+1] = str_replace('%SECTION%',$sectionHeading[0],$this->substTagParm($mode->sSectionTags[$s*2+1], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen)); |
4002 | 4111 | } |
4003 | 4112 | else $septag[$s*2+1]=''; |
4004 | 4113 | |
— | — | @@ -4032,7 +4141,7 @@ |
4033 | 4142 | |
4034 | 4143 | // symbolic substitution of %PAGE% by the current article's name |
4035 | 4144 | if ($mode->name == 'userformat') { |
4036 | | - $rBody .= $this->substTagParm($mode->sItemStart, $pagename, $article,$this->filteredCount, $iTitleMaxLen); |
| 4145 | + $rBody .= $this->substTagParm($mode->sItemStart, $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen); |
4037 | 4146 | } |
4038 | 4147 | else { |
4039 | 4148 | $rBody .= $mode->sItemStart; |
— | — | @@ -4073,7 +4182,7 @@ |
4074 | 4183 | } |
4075 | 4184 | |
4076 | 4185 | if ($mode->name == 'userformat') { |
4077 | | - $rBody .= $this->substTagParm($mode->sItemEnd, $pagename, $article, $this->filteredCount, $iTitleMaxLen); |
| 4186 | + $rBody .= $this->substTagParm($mode->sItemEnd, $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen); |
4078 | 4187 | } |
4079 | 4188 | else { |
4080 | 4189 | $rBody .= $mode->sItemEnd; |
— | — | @@ -4237,7 +4346,7 @@ |
4238 | 4347 | // links to categories or images need an additional ":" |
4239 | 4348 | $pagename = ':'.$pagename; |
4240 | 4349 | } |
4241 | | - return $this->substTagParm($tag, $pagename, $article, $this->filteredCount, $iTitleMaxLen); |
| 4350 | + return $this->substTagParm($tag, $pagename, $article, $this->filteredCount, '', $iTitleMaxLen); |
4242 | 4351 | } |
4243 | 4352 | |
4244 | 4353 | //format one item of an entry in the output list (i.e. the collection of occurences of one item from the include parameter) |
— | — | @@ -4379,10 +4488,15 @@ |
4380 | 4489 | if($this->iDebugLevel >= ExtDynamicPageList2::$debugMinLevels[$msgid]) { |
4381 | 4490 | $args = func_get_args(); |
4382 | 4491 | array_shift( $args ); |
| 4492 | + $val=''; |
| 4493 | + if (array_key_exists(0,$args)) $val = $args[0]; |
| 4494 | + array_shift( $args ); |
4383 | 4495 | /** |
4384 | 4496 | * @todo add a DPL id to identify the DPL tag that generates the message, in case of multiple DPLs in the page |
4385 | 4497 | */ |
4386 | | - return '<p>%DPL-' . ExtDynamicPageList2::VERSION . '-' . wfMsg('dpl2_log_' . $msgid, $args) . '</p>'; |
| 4498 | + $text = wfMsg('dpl2_log_' . $msgid, $args); |
| 4499 | + $text = str_replace('$0',$val,$text); |
| 4500 | + return '<p>%DPL-' . ExtDynamicPageList2::VERSION . '-' . $text . '</p>'; |
4387 | 4501 | } |
4388 | 4502 | return ''; |
4389 | 4503 | } |
— | — | @@ -4391,7 +4505,7 @@ |
4392 | 4506 | * Get a message. |
4393 | 4507 | * Parameters may be unescaped, this function will escape them for HTML. |
4394 | 4508 | */ |
4395 | | - function escapeMsg( $msgid /*, ... */ ) { |
| 4509 | + function escapeMsg( $msgid ) { |
4396 | 4510 | $args = func_get_args(); |
4397 | 4511 | $args = array_map( 'htmlspecialchars', $args ); |
4398 | 4512 | return call_user_func_array( array( $this, 'msg' ), $args ); |
— | — | @@ -4428,4 +4542,5 @@ |
4429 | 4543 | sort($paramoptions); |
4430 | 4544 | return $this->escapeMsg( $msgid, $paramvar, htmlspecialchars( $val ), ExtDynamicPageList2::$options[$paramvar]['default'], implode(' | ', $paramoptions )); |
4431 | 4545 | } |
| 4546 | + |
4432 | 4547 | } |