| b929bbff | 15-Apr-2026 |
Vyacheslav <bryanskmap@ya.ru> |
Translation update (ru) |
| fe6048cc | 14-Apr-2026 |
Alexander Lehmann <alexlehm@gmail.com> |
remove realip option, add default in conf/dokuwiki.php |
| bfc167db | 11-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
Limit namespace depth in io_createNamespace() #4613
Throw a RuntimeException when the given ID contains 128 or more colon-separated segments, preventing creation of excessively deep directory hierar
Limit namespace depth in io_createNamespace() #4613
Throw a RuntimeException when the given ID contains 128 or more colon-separated segments, preventing creation of excessively deep directory hierarchies.
show more ...
|
| 743a6908 | 11-Apr-2026 |
splitbrain <86426+splitbrain@users.noreply.github.com> |
Rector and PHPCS fixes |
| 867da04d | 11-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
Less ubiquitous feed caching. addresses #4574
Instead of creating caches for each and every requested feed, only the recent feed is still cached.
The number of items is clamped to conf[recent]*5.
Less ubiquitous feed caching. addresses #4574
Instead of creating caches for each and every requested feed, only the recent feed is still cached.
The number of items is clamped to conf[recent]*5.
Plugins can influence the caching behavior via the existing FEED_OPTS_POSTPROCESS event by setting cache_allow to true and optionally adding their own cache key in cache_key
Additionally the per-namespace feed autodiscovery link from <head> pointing to list-mode feeds has been removed.
show more ...
|
| b7c3b74a | 02-Oct-2025 |
Anna Dabrowska <dabrowska@cosmocode.de> |
Add copy-to-clipboard functionality to code blocks |
| 06053dca | 10-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: remove write side effect from retrieveRow()
retrieveRow() padded the index file when the requested RID was beyond the current length. This was an optimization for subsequent changeRow()
SearchIndex: remove write side effect from retrieveRow()
retrieveRow() padded the index file when the requested RID was beyond the current length. This was an optimization for subsequent changeRow() calls, but changeRow() already handles padding on its own. The side effect was also inconsistent with retrieveRows() which is a pure read.
Added a cross-index integration test verifying RID consistency across entity, token, frequency and reverse indexes when multiple entities share tokens.
show more ...
|
| 1e5f7f1f | 10-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
Manifest: add UTF-8 to entity decoding
As recommended in the PHP manual |
| 6beb5edc | 10-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
add gzfile_get_contents() to handle multi-stream gz and corruption
The initial gzdecode() fix only decoded the first gzip stream, breaking append mode where gzopen() creates concatenated streams.
R
add gzfile_get_contents() to handle multi-stream gz and corruption
The initial gzdecode() fix only decoded the first gzip stream, breaking append mode where gzopen() creates concatenated streams.
Replace with a chunk-based reader using inflate_* functions that loops through all streams and still correctly detects corrupt data.
show more ...
|
| 3b335c64 | 10-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
use gzdecode instead of gzfile to work around PHP 8.5.3+ regression
gzfile() no longer detects corrupt gzip data due to a bug in PHP's zlib stream wrapper (php/php-src#21376). Using file_get_content
use gzdecode instead of gzfile to work around PHP 8.5.3+ regression
gzfile() no longer detects corrupt gzip data due to a bug in PHP's zlib stream wrapper (php/php-src#21376). Using file_get_contents() with gzdecode() avoids the stream wrapper and correctly returns false for corrupt files.
show more ...
|
| c553d38d | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: fix TypeError when $QUERY global is null
QueryParser::convert() requires a string argument, but the global $QUERY can be null. Coalesce to empty string to match prior behavior. |
| 9313ce6d | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: fix TypeError when $highlight is passed uninitialized
FulltextSearch::pageSearch() type-hints $highlight as array, but callers passed uninitialized variables (null). Initialize to [] at
SearchIndex: fix TypeError when $highlight is passed uninitialized
FulltextSearch::pageSearch() type-hints $highlight as array, but callers passed uninitialized variables (null). Initialize to [] at all call sites and add a guard in the deprecated ft_pageSearch() wrapper.
show more ...
|
| 5d034a75 | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: increase index version |
| 9369b4a9 | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rector, phpcs, type hint fixes |
| db8be586 | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: review fixes — auto-save MemoryIndex, cast TupleOps counts, style cleanups
- MemoryIndex: auto-save dirty data on unlock/destruction to prevent silent index corruption when indexes ar
SearchIndex: review fixes — auto-save MemoryIndex, cast TupleOps counts, style cleanups
- MemoryIndex: auto-save dirty data on unlock/destruction to prevent silent index corruption when indexes are used in tandem - TupleOps::parseTuples(): cast exploded count strings to int - FileIndex::retrieveRow(): document the write-on-read padding behavior - Fix whitespace issues in ApiCore, common.php, Sitemap/Mapper - Update concept.txt to reflect MemoryIndex auto-save behavior
show more ...
|
| 2a22d4b9 | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: document Tokenizer::isValidSearchTerm() in concept.txt |
| 1148921d | 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: unify CollectionSearch API and optimize search pipeline
- Remove separate lookup() API from CollectionSearch. All searches now use addTerm()/execute() with a single unified pipeline.
SearchIndex: unify CollectionSearch API and optimize search pipeline
- Remove separate lookup() API from CollectionSearch. All searches now use addTerm()/execute() with a single unified pipeline. - Add matches() predicate to Term using efficient string functions (===, str_starts_with, str_ends_with, str_contains) instead of regex. - Add caseInsensitive() support on CollectionSearch and Term for metadata/title searches where indexed values preserve case. - Remove callback support from MetadataSearch::lookupKey() — the only real usage (case-insensitive substring) is replaced by caseInsensitive() + wildcards. - Remove min-length validation from Term. Add Tokenizer::isValidSearchTerm() for callers that need it (FulltextSearch, Indexer::lookup). - Optimize execute() from 4 group passes to 2: scan tokens + resolve frequencies in one pass per group, batch entity name resolution, then populate Terms. - Store full match detail in Term: entity → token → frequency. New accessors getMatches(), getEntityTokens(), getEntityFrequencies() derive different views from this single data structure. - Term no longer used as scratch pad by CollectionSearch. Index-internal data (token IDs, entity IDs) stays local to execute(). Terms receive only final resolved results. - Use title from search results in MetadataSearch::pageLookupCallBack() instead of re-fetching via p_get_first_heading(). - Update concept.txt documentation.
show more ...
|
| b9d7a615 | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: updated documentation
to be moved into the wiki later |
| 0b52f0de | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: use FileIndex for title token index
PageTitleCollection accesses titles by RID (one line at a time), so loading the entire index into memory is wasteful. Override getTokenIndex() to ret
SearchIndex: use FileIndex for title token index
PageTitleCollection accesses titles by RID (one line at a time), so loading the entire index into memory is wasteful. Override getTokenIndex() to return a FileIndex, matching the line-by-line access pattern used on master.
show more ...
|
| e1272c08 | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: add backward compatibility wrappers
Add deprecated wrappers for idx_* and ft_* functions that were removed when inc/indexer.php and inc/fulltext.php were replaced by the new Search clas
SearchIndex: add backward compatibility wrappers
Add deprecated wrappers for idx_* and ft_* functions that were removed when inc/indexer.php and inc/fulltext.php were replaced by the new Search classes. These wrappers delegate to the new architecture and ensure existing plugins continue to work.
Deprecated standalone functions: idx_get_indexer, idx_getIndex, idx_lookup, idx_listIndexLengths, idx_indexLengths, ft_pageSearch, ft_backlinks, ft_mediause, ft_pageLookup, ft_snippet, ft_pagesorter, ft_snippet_re_preprocess, ft_queryParser.
Deprecated methods on Indexer: lookupKey, getPages, addMetaKeys, renameMetaValue, getPID, lookup.
Also migrates remaining core callers (Ajax, FeedCreator, ApiCore) to use the new classes directly and fixes a UTF-8 case folding bug in MetadataSearch title lookups.
show more ...
|
| 74a9499c | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: remove legacy intermediate classes from PR #2943
Remove FulltextIndex, MetadataIndex, and the old AbstractIndex which were introduced as a stepping stone in #2943. All callers now use t
SearchIndex: remove legacy intermediate classes from PR #2943
Remove FulltextIndex, MetadataIndex, and the old AbstractIndex which were introduced as a stepping stone in #2943. All callers now use the Collection/Index architecture directly.
Also fix a bug in detail.php where mediause() was called with ignore_perms=true, leaking references from hidden/protected pages to unprivileged users. This bug existed on master as well.
Old test files replaced by their modernized equivalents in tests/Search/.
show more ...
|
| 21fbd01b | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: add integrity checking to Collection architecture
Add checkIntegrity() to AbstractCollection and DirectCollection that verifies paired indexes have matching line counts (token==frequenc
SearchIndex: add integrity checking to Collection architecture
Add checkIntegrity() to AbstractCollection and DirectCollection that verifies paired indexes have matching line counts (token==frequency, entity==reverse, entity==token for direct collections). Throws IndexIntegrityException on the first inconsistency found.
Add Countable interface to AbstractIndex with count() implementations in MemoryIndex and FileIndex. Add Indexer::checkIntegrity() and Indexer::isIndexEmpty() to orchestrate checks across all collections.
Update infoutils.php to use the new Indexer API instead of the old FulltextIndex/MetadataIndex classes.
Fix range(1, 0) bug in three places that produced [1, 0] instead of an empty array when split-by-length indexes were empty.
show more ...
|
| 6734bb8c | 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rewrite MetadataSearch to use Collection classes
Replace MetadataIndex usage in MetadataSearch with the new Collection/Index architecture. This completes the read-path migration so data
SearchIndex: rewrite MetadataSearch to use Collection classes
Replace MetadataIndex usage in MetadataSearch with the new Collection/Index architecture. This completes the read-path migration so data written by the Collection-based Indexer is read back correctly using TupleOps tuple format.
Generalize FrequencyCollectionSearch into CollectionSearch that works with any AbstractCollection type (Frequency, Lookup, Direct) and handles both split-by-length and non-split index layouts transparently. DirectCollection participates via resolveTokenFrequencies() which maps token RID = entity RID.
Key changes: - AbstractCollection gains isSplitByLength(), resolveTokenFrequencies(), getEntitiesWithData(), and groupToSuffix() with validation - Index groups are now int (0 = non-split, positive = token length) - CollectionSearch provides both addTerm()/execute() for fulltext and lookup() for metadata-style search (exact/wildcard/callback) - MetadataSearch delegates entirely to collection APIs - Shared filterPages() replaces duplicated page filtering logic - All callers updated from MetadataIndex to MetadataSearch - Tests moved to Search namespace with full coverage for new APIs
show more ...
|
| ede46466 | 06-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: reorganize and expand test suite
Move all Search tests from _test/tests/inc/Search/ to _test/tests/Search/ to match the dokuwiki\test autoloader convention. Fix namespaces from tests\*
SearchIndex: reorganize and expand test suite
Move all Search tests from _test/tests/inc/Search/ to _test/tests/Search/ to match the dokuwiki\test autoloader convention. Fix namespaces from tests\* to dokuwiki\test\* so all tests work in isolation.
Extract inline test helpers into separate autoloadable mock files: TestDirectCollection → MockDirectCollection, TestLookupCollection → MockLookupCollection, TestFrequencyCollection → MockFrequencyCollection.
Rename AbstractIndexTest → AbstractIndexTestCase to fix PHPUnit warning about abstract classes with Test suffix.
Replace dead xxxRealWord() with proper testWildcardSearch() verifying exact token matches and frequencies for all three wildcard types. Add testTokenizedPageSearch() using a dedicated test data file. Add testNoMatchReturnsEmptyFrequencies() which exposed a bug in Term where uninitialized $tokens/$frequencies caused crashes on zero-match terms.
Replace fulltext_query.test.php with modern QueryParserTest in the Search\Query namespace.
Add new test files: - LockTest: acquire/release, reference counting, stale lock override, foreign lock rejection, releaseAll, independent locks - NamespacePredicateTest: filter/exclude, sub-namespaces, partial prefix safety, empty sets, score preservation - PageSetTest: intersect, unite, subtract, isEmpty - QueryEvaluatorTest: word lookups, AND/OR/NOT, namespace filtering, combined queries, partial namespace prefix safety
Fix Term.php: initialize $tokens and $frequencies to [] instead of null.
show more ...
|
| 0b1bbbbb | 06-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rewrite FulltextSearch to use FrequencyCollectionSearch
Replace FulltextIndex->lookupWords() with FrequencyCollectionSearch which correctly handles the compact tuple format written by t
SearchIndex: rewrite FulltextSearch to use FrequencyCollectionSearch
Replace FulltextIndex->lookupWords() with FrequencyCollectionSearch which correctly handles the compact tuple format written by the new Indexer.
Introduce QueryEvaluator with typed stack entries (PageSet, NamespacePredicate, NegatedEntry) for RPN query evaluation. NOT wraps its operand instead of computing a universe complement, so AND with a negated operand becomes efficient set subtraction. The full page index is only loaded for standalone negative or namespace-only queries.
Move QueryParser and QueryEvaluator into the new Search\Query namespace along with the stack entry types.
Simplify FulltextSearch to orchestration: parse query, look up words, evaluate, filter, sort. Replace FT_SNIPPET_NUMBER constant with maxSnippets property. Combine ACL/existence/time filtering into a single pass.
show more ...
|