History log of /dokuwiki/_test/ (Results 1 – 25 of 1005)
Revision Date Author Comments
(<<< Hide modified files)
(Show modified files >>>)
36ba8ead12-May-2026 Andreas Gohr <andi@splitbrain.org>

test: add tests to catch #4637

Issue #4637 was fixed in 7686f2030b19f948d2e50df1613ef6592fa44b46 but I
didn't like that no test had caught the issue.

This adds a specific test for the issue as a Ha

test: add tests to catch #4637

Issue #4637 was fixed in 7686f2030b19f948d2e50df1613ef6592fa44b46 but I
didn't like that no test had caught the issue.

This adds a specific test for the issue as a HandlerTest. Additionally a
simple smoke test is added that renders the wiki:syntax page and
inspects the created DOM. It's not comprehensive but might help flagging
similar issue in the future.

show more ...

01e8d73925-Apr-2026 Andreas Gohr <andi@splitbrain.org>

refactor(changelog): persist external-edit detection on first read

This addresses the flaky test that makes tests randomly fail (mostly on
windows runners).

The flake in common_saveWikiText_test::t

refactor(changelog): persist external-edit detection on first read

This addresses the flaky test that makes tests randomly fail (mostly on
windows runners).

The flake in common_saveWikiText_test::test_savesequence5 came from
this line in ChangeLog::getCurrentRevisionInfo():

'date' => max($lastRev + 1, time() - 1)

The synthesized "external delete" entry was kept in memory only and
only persisted later, when saveWikiText next called detectExternalEdit.
That meant the formula was evaluated twice on different ChangeLog
instances — once during the test's inspection, and again during the
following saveWikiText — and the two evaluations could pick different
seconds depending on how long the surrounding I/O took. The test
cached the first result in $expectExternal and asserted it against the
on-disk entry written during the second call. On the slower Windows
runner the second call sometimes crossed a second boundary, producing
the off-by-one date mismatch.

The questions I had was, why are we persisting external file deletions
(or edits) only when a page is saved when we are obviously already
detecting it earlier during the changelog read already?

Instead of recording the external delete at the time a new page is
written, it makes sense to record it as soon as we detect it (when the
changelog is requested by a user or a bot). This will make the recoded
timestamp closer to the actual deletion.

This patch refactors the changelog accordingly, but still tries to be
minimal invasive (I think the changelog handling would need much more
refactoring, but that's beyond the scope of this change).

To enable proper locking (when logging an external edit and copying
the attic file), locking had to be moved to the Changelog class,
duplicating some code of io_saveFile.

PageFile::detectExternalEdit() and the deprecated procedural wrapper
detectExternalEdit() in inc/common.php are removed. A codesearch.dokuwiki.org
check confirmed no plugin calls the method directly; the only external
caller of the procedural function is the farmsync plugin, which needs
a parallel update.

show more ...

dd9e8e5e23-Apr-2026 Andreas Gohr <andi@splitbrain.org>

fix EXIF-rotated images shown cropped in previews, closes #4482

JPEGs with EXIF orientation 5/6/7/8 were rendered cropped in the
mediamanager detail view, the image diff view and the fullscreen
deta

fix EXIF-rotated images shown cropped in previews, closes #4482

JPEGs with EXIF orientation 5/6/7/8 were rendered cropped in the
mediamanager detail view, the image diff view and the fullscreen
detail page: getimagesize() / JpegMeta report raw (rotation-unaware)
pixel dimensions, and passing both w and h to fetch.php defaults to
center-crop.

- Bump splitbrain/slika to 1.1, which ships ImageInfo: a rotation-
aware, metadata-only dimension simulator mirroring Adapter's
fluent API (autorotate/resize/crop).
- Add fit=1 to fetch.php: when both w and h are given, route to
media_resize_image() (bbox fit) instead of media_crop_image().
Token hashes only (id, w, h) so existing tokens stay valid.
- Add MediaFile::getDisplayDimensions($w, $h, $crop) which delegates
to ImageInfo and returns the dims fetch.php would produce.
- Add Display::getDetailHtml() and retire media_preview() / the old
media_image_preview_size() helper. media_tab_view and MediaDiff
now share the Display-based renderer.
- Rewrite tpl_img() (lib/tpl/*/detail.php) to use MediaFile dims +
fit=1 URL; drops the manual ratio math.
- Tests: MediaFileTest covers the dims math, DisplayTest covers the
detail-view HTML (rotated dims, rev-vs-timestamp URL selection,
structure), fetch_imagetoken gains a fit-token compat test.
Fixture _test/data/media/wiki/exif-orient-6.jpg: 20x30 JPEG with
EXIF orientation 6.

show more ...

90c2f6e318-Apr-2026 Andreas Gohr <andi@splitbrain.org>

Clean up stale realip references after client_ip_header rename

Update docblocks in Ip.php and common.php, fix old tests to use
the new config key, remove outdated translations, fix method casing
in

Clean up stale realip references after client_ip_header rename

Update docblocks in Ip.php and common.php, fix old tests to use
the new config key, remove outdated translations, fix method casing
in test, and add example to English config description.

show more ...

504c13e818-Apr-2026 Andreas Gohr <andi@splitbrain.org>

migrate parser tests to modern namespaced classes

Move old-style parser tests from _test/tests/inc/parser/ to namespaced
test classes under _test/tests/Parsing/ParserMode/ and
_test/tests/Parsing/Le

migrate parser tests to modern namespaced classes

Move old-style parser tests from _test/tests/inc/parser/ to namespaced
test classes under _test/tests/Parsing/ParserMode/ and
_test/tests/Parsing/Lexer/.

- Add ParserTestBase with assertCalls() helper for comparing handler
call sequences with byte index stripping
- Split lexer.test.php into ParallelRegexTest, StateStackTest, and
LexerTest with a RecordingHandler that extends Handler
- Merge handler_parse_highlight_options tests into CodeTest
- Add new tests for previously untested modes: Nocache, Notoc, Rss,
and all individual formatting modes (Strong, Emphasis, etc.)
- Modernize test code: [] syntax, lowercase null, correct assertEquals
argument order, replace deprecated withConsecutive and string callables
- Renderer tests remain in old location (renderers not yet migrated)

show more ...

71096e4618-Apr-2026 Andreas Gohr <andi@splitbrain.org>

move handler methods into ParserMode classes and rename Handler

Each ParserMode class now implements handle() from ModeInterface,
containing the token handling logic that previously lived as individ

move handler methods into ParserMode classes and rename Handler

Each ParserMode class now implements handle() from ModeInterface,
containing the token handling logic that previously lived as individual
methods on Doku_Handler.

The Handler class (formerly Doku_Handler) is the single dispatch point:
Lexer passes tokens to Handler::handleToken() which routes to mode
objects, plugins, or returns false. The Lexer only tokenizes and
resolves mapHandler aliases.

Key changes:
- Add handle() to ModeInterface, implemented by all mode classes
- Move Doku_Handler to dokuwiki\Parsing\Handler namespace
- File extends Code (shared parsing via $type property)
- Quotes uses mapHandler() + Handler::getModeName() for sub-modes
- Media::parseMedia() replaces Doku_Handler_Parse_Media()
- Code::parseHighlightOptions() replaces parse_highlight_options()
- Per-parse state (footnote, doublequote) stays on Handler
- Deprecated wrappers kept for base/header/internallink/media
- Class alias and rector rules added for backward compatibility

show more ...


rector.php
tests/Parsing/HandlerTest.php
tests/Parsing/ModeRegistryTest.php
tests/inc/parser/handler_parse_highlight_options.test.php
tests/inc/parser/lexer.test.php
tests/inc/parser/parser.inc.php
tests/inc/parser/parser_quotes.test.php
/dokuwiki/inc/Cache/CacheParser.php
/dokuwiki/inc/Extension/SyntaxPlugin.php
/dokuwiki/inc/Parsing/Handler.php
/dokuwiki/inc/Parsing/Handler/CallWriter.php
/dokuwiki/inc/Parsing/Lexer/Lexer.php
/dokuwiki/inc/Parsing/Parser.php
/dokuwiki/inc/Parsing/ParserMode/AbstractFormatting.php
/dokuwiki/inc/Parsing/ParserMode/Acronym.php
/dokuwiki/inc/Parsing/ParserMode/Base.php
/dokuwiki/inc/Parsing/ParserMode/Camelcaselink.php
/dokuwiki/inc/Parsing/ParserMode/Code.php
/dokuwiki/inc/Parsing/ParserMode/Deleted.php
/dokuwiki/inc/Parsing/ParserMode/Emaillink.php
/dokuwiki/inc/Parsing/ParserMode/Emphasis.php
/dokuwiki/inc/Parsing/ParserMode/Entity.php
/dokuwiki/inc/Parsing/ParserMode/Eol.php
/dokuwiki/inc/Parsing/ParserMode/Externallink.php
/dokuwiki/inc/Parsing/ParserMode/File.php
/dokuwiki/inc/Parsing/ParserMode/Filelink.php
/dokuwiki/inc/Parsing/ParserMode/Footnote.php
/dokuwiki/inc/Parsing/ParserMode/Header.php
/dokuwiki/inc/Parsing/ParserMode/Hr.php
/dokuwiki/inc/Parsing/ParserMode/Internallink.php
/dokuwiki/inc/Parsing/ParserMode/Linebreak.php
/dokuwiki/inc/Parsing/ParserMode/Listblock.php
/dokuwiki/inc/Parsing/ParserMode/Media.php
/dokuwiki/inc/Parsing/ParserMode/ModeInterface.php
/dokuwiki/inc/Parsing/ParserMode/Monospace.php
/dokuwiki/inc/Parsing/ParserMode/Multiplyentity.php
/dokuwiki/inc/Parsing/ParserMode/Nocache.php
/dokuwiki/inc/Parsing/ParserMode/Notoc.php
/dokuwiki/inc/Parsing/ParserMode/Preformatted.php
/dokuwiki/inc/Parsing/ParserMode/Quote.php
/dokuwiki/inc/Parsing/ParserMode/Quotes.php
/dokuwiki/inc/Parsing/ParserMode/Rss.php
/dokuwiki/inc/Parsing/ParserMode/Smiley.php
/dokuwiki/inc/Parsing/ParserMode/Strong.php
/dokuwiki/inc/Parsing/ParserMode/Subscript.php
/dokuwiki/inc/Parsing/ParserMode/Superscript.php
/dokuwiki/inc/Parsing/ParserMode/Table.php
/dokuwiki/inc/Parsing/ParserMode/Underline.php
/dokuwiki/inc/Parsing/ParserMode/Unformatted.php
/dokuwiki/inc/Parsing/ParserMode/Windowssharelink.php
/dokuwiki/inc/Parsing/ParserMode/Wordblock.php
/dokuwiki/inc/deprecated.php
/dokuwiki/inc/legacy.php
/dokuwiki/inc/load.php
/dokuwiki/inc/parserutils.php
7958e69816-Apr-2026 Andreas Gohr <andi@splitbrain.org>

decouple hardcoded mode names in Eol and Preformatted

Eol.php hardcoded ['listblock', 'table'] as modes to skip, and
Preformatted.php hardcoded [\*\-] as a negative lookahead for list
markers. Both

decouple hardcoded mode names in Eol and Preformatted

Eol.php hardcoded ['listblock', 'table'] as modes to skip, and
Preformatted.php hardcoded [\*\-] as a negative lookahead for list
markers. Both embed knowledge that belongs to the respective block
modes, not to Eol/Preformatted. Adding a new block mode that handles
its own EOL or uses different line start markers would require editing
these unrelated files — a hidden coupling.

Listblock and Table now register themselves on ModeRegistry during
preConnect(). Eol queries getBlockEolModes() and Preformatted queries
getLineStartMarkers() to build its lookahead dynamically. Each mode
owns its own data, and new block modes can participate without touching
unrelated files.

show more ...

dba14ea316-Apr-2026 Andreas Gohr <andi@splitbrain.org>

add unit tests for ModeRegistry

1f44347616-Apr-2026 Andreas Gohr <andi@splitbrain.org>

split Formatting into individual classes per formatting type

Introduce AbstractFormatting as a base class and seven concrete
classes (Strong, Emphasis, Underline, Monospace, Subscript,
Superscript,

split Formatting into individual classes per formatting type

Introduce AbstractFormatting as a base class and seven concrete
classes (Strong, Emphasis, Underline, Monospace, Subscript,
Superscript, Deleted) that each define their own patterns and
sort order. Delete the old Formatting class and update tests
to use the new classes directly. ModeRegistry now treats
formatting modes as regular built-in modes.

show more ...

c8dd1b9d16-Apr-2026 Andreas Gohr <andi@splitbrain.org>

introduce ModeRegistry to encapsulate parser mode categories

Replace the global $PARSER_MODES definition in inc/parser/parser.php
with a ModeRegistry singleton that initializes and manages the mode

introduce ModeRegistry to encapsulate parser mode categories

Replace the global $PARSER_MODES definition in inc/parser/parser.php
with a ModeRegistry singleton that initializes and manages the mode
categories. The global array is still populated for backward
compatibility with plugins that access it directly.

Mode constructors now use ModeRegistry::getModesForCategories()
instead of accessing the global directly. p_get_parsermodes() and
p_sort_modes() are moved to inc/deprecated.php as thin wrappers.

show more ...

8ab4ec3016-Apr-2026 Andreas Gohr <gohr@cosmocode.de>

remove dead ParallelRegex::apply() method

Remove apply() which was never called from production code. Rewrite
the inherited SimpleTest tests to use split() instead, and add a
test for pre/post-match

remove dead ParallelRegex::apply() method

Remove apply() which was never called from production code. Rewrite
the inherited SimpleTest tests to use split() instead, and add a
test for pre/post-match splitting.

show more ...

fe6048cc14-Apr-2026 Alexander Lehmann <alexlehm@gmail.com>

remove realip option, add default in conf/dokuwiki.php

bfc167db11-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 ...

894c157711-Apr-2026 Andreas Gohr <andi@splitbrain.org>

skip strict types rector

even though this rule only adds strict type checking for classes that
already are fully typed, I am a bit hesitant to add the strict type
declaration yet. maybe later


rector.php
/dokuwiki/composer.lock
/dokuwiki/inc/Manifest.php
/dokuwiki/inc/lang/de-informal/lang.php
/dokuwiki/inc/lang/de/lang.php
/dokuwiki/inc/lang/en/lang.php
/dokuwiki/inc/lang/pl/lang.php
/dokuwiki/lib/scripts/page.js
/dokuwiki/lib/styles/screen.css
/dokuwiki/lib/tpl/dokuwiki/css/content.less
/dokuwiki/vendor/composer/installed.json
/dokuwiki/vendor/composer/installed.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
867da04d11-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 ...


tests/Feed/FeedCreatorOptionsTest.php
/dokuwiki/composer.lock
/dokuwiki/feed.php
/dokuwiki/inc/Feed/FeedCreatorOptions.php
/dokuwiki/inc/Manifest.php
/dokuwiki/inc/lang/de-informal/lang.php
/dokuwiki/inc/lang/de/lang.php
/dokuwiki/inc/lang/en/lang.php
/dokuwiki/inc/lang/pl/lang.php
/dokuwiki/inc/template.php
/dokuwiki/lib/scripts/page.js
/dokuwiki/lib/styles/screen.css
/dokuwiki/lib/tpl/dokuwiki/css/content.less
/dokuwiki/vendor/composer/installed.json
/dokuwiki/vendor/composer/installed.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
/dokuwiki/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
7383ed4010-Apr-2026 Andreas Gohr <andi@splitbrain.org>

Replace deprecated idx_addPage/ft_backlinks calls in ApiCoreTest

Use Indexer::addPage() and MetadataSearch::backlinks() directly.

b188a75b10-Apr-2026 Andreas Gohr <andi@splitbrain.org>

SearchIndex: fix IntegrityTest not re-indexing between tests

The .indexed metadata tag persisted between test methods, causing
needsIndexing() to skip re-indexing when saveWikiText() didn't
update t

SearchIndex: fix IntegrityTest not re-indexing between tests

The .indexed metadata tag persisted between test methods, causing
needsIndexing() to skip re-indexing when saveWikiText() didn't
update the wiki file (identical content). Clean the tag in setUp.

show more ...

06053dca10-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 ...

b2c5d21010-Apr-2026 Andreas Gohr <andi@splitbrain.org>

updated dependencies (core and test)

Using our own php-ixr fork until the following PRs are merged upstream:

https://github.com/kissifrot/php-ixr/pull/13
https://github.com/kissifrot/php-ixr/pull/14

1148921d08-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 ...

5e9d26e307-Apr-2026 Andreas Gohr <andi@splitbrain.org>

SearchIndex: move search() function tests back to tests/inc/search/

The search.test.php file tests the search() function from inc/search.php,
not the Search namespace classes. It was incorrectly mov

SearchIndex: move search() function tests back to tests/inc/search/

The search.test.php file tests the search() function from inc/search.php,
not the Search namespace classes. It was incorrectly moved into
tests/Search/ during the test suite reorganization. Move it and its
data files (ns1/, ns2/) back to their original location, keeping only
searchtest.txt in tests/Search/data/ where it belongs.

show more ...

e1272c0807-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 ...

74a9499c07-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 ...

21fbd01b07-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 ...

6734bb8c07-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 ...

12345678910>>...41