Журнал изменений

Официальный сайт SLAED CMS

Журнал изменений

Фильтр и поиск

Всего: 1107 Доступных коммитов | Отфильтровано: 1107 Коммиты | Страница: 1 / 111
Сегодня (12.08.2026)
Fix: the script bundle stops rewriting the code it serves, and the feeds become documents a parser accepts
Автор: Eduard Laas | Дата: 15:39 12.08.2026

The JS minifier rewrote whole files with regular expressions, so it reached inside string literals and turned a subtraction into a decrement, and the bundler glued sources with a space, which let a file ending in a line comment swallow the next one. Both are gone. The RSS and OpenSearch documents carried raw ampersands and a wrong date format, so neither was well formed and every timestamp reported the month in place of the minutes.

Core changes:

  1. Script bundling keeps the sources intact (core/system.php, admin/modules/config.php, config/global.php, admin/lang/*.php):
  2. script_c and getCompressCode() are removed, together with the field, its writer entry and the constant

    • A regular expression cannot tell code from the inside of a string, so the pass rewrote both
    • On top of the transport compression a server applies to scripts it saved six to eight per cent
  3. Sources are concatenated with a semicolon and a line break instead of a space

    • A file ending in a line comment without a trailing break swallowed the first line of the next one
    • A statement left without its own semicolon joined the following file instead of ending
  4. ASSETS_VER becomes 3, because the key covers the sources and the settings but not the code that joins them
  5. Style bundling skips what is already minified (core/system.php):
  6. A file whose name carries .min. is stored as it is

    • The regex pass gains nothing there and costs build time on every rebuild
    • It also stripped the /*! license banner of vendor files, which is not ours to remove
  7. The feeds become well-formed XML (core/user.php):
  8. Every address is escaped before it enters the document, in the channel, the items and the search templates

    • An ampersand of a query string is a character reference in XML, so a strict reader rejected the file
    • The item address is built once per row instead of three times in three branches
  9. The date format is D, j M Y H:i:s O: the minute field held the month
  10. The image element of the OpenSearch document loses a literal backslash n from a single-quoted string
  11. Content-Encoding: none is dropped from both documents, so the server may compress them
  12. Compression covers the pages themselves (.htaccess):
  13. The deflate filter is selected by response type rather than by file name

    • A page is built by index.php, so no rule matching file names reaches the largest response of the site
  14. text/xsl is served with its own type, so a browser applies the sitemap stylesheet
  15. Cache housekeeping (core/system.php, core/classes/cache.php, admin/info/scheduler/ru.md):
  16. The sweep collects asset bundles as well

    • A bundle in use is rewritten on every rebuild, so only one no page points at reaches the retention window
  17. A public response drops the Pragma that PHP emits for every session: a response cannot both invite caching and forbid it

  18. getOutputHtml() loses its unused full mode, which stripped comments and glued tags
  19. Documentation and help (docs/PERFORMANCE.md, docs/PARSER.md, admin/info/*, UPGRADING.md):
  20. The security help states which field names are masked in the request context of a log entry
  21. The upgrade notes list the four cache fields and the action they need, without the history behind them
  22. The scheduler and parser pages describe the current behaviour of the sweep and of the format argument

Benefits:

  • A bundled script is byte for byte the sources it was built from, verified against a parser
  • Feed readers, validators and browser search integration accept the documents
  • Every page of the site is compressed on Apache as it already is on nginx
  • Asset bundles no longer accumulate on disk once their sources change

Technical notes:

  • Breaking: script_c disappears from config/global.php; an installation that had it set needs no action
  • ASSETS_VER = 3 rebuilds every CSS and JS bundle on the first request after the upgrade
  • The feeds keep their element order and their content; only escaping, the date field and the header change
Perf: the parser cache stops storing what it cannot repay, and the cache settings become four honest fields
Автор: Eduard Laas | Дата: 14:17 12.08.2026

The rendered-content cache kept every fragment, so short comments and teasers filled the directory while a daily rewrite cost more than the hits it saved. A size threshold now decides, the sweep that ages the leftovers out is enabled, and the settings screen loses the two fields that described the same decision twice or described nothing. On the way through, request logs stopped carrying the passwords a warning used to record.

Core changes:

  1. A size threshold for the rendered-content cache (core/classes/parser.php):
  2. CACHEMIN is 2048 bytes of source and getCachePath() returns nothing below it

    • The gate sits in the one function both the read and the write pass, so the two stay symmetric
    • The unit is bytes because parsing cost scales with bytes, not with characters
    • The empty-source case is covered by the threshold, so no separate check remains
  3. Break-even is near 700 bytes, but only at some thirty hits a day per fragment; from 2 KB a write repays after three or four hits, which is almost any traffic level

  4. The sweep that removes what already accumulated (config/scheduler.php):
  5. The cachegc job is enabled; it removes files older than max(cache_t * 24, 86400), never below CACHETTL
  6. The threshold stops new sub-threshold files but never removes existing ones: nothing else ages them
  7. Secrets stop reaching the logs (core/classes/logger.php, core/security.php, admin/modules/config.php):
  8. Logger masks request data by key name before it is bounded, in getContext() and only there

    • Any key holding pass, pwd, secret, token, key or code keeps its name and loses its value
    • The diagnostic context of a call is left alone, because it carries keys a name rule would destroy
  9. The address is masked as well, in url and referer: an OAuth callback and a reset link carry their secret in the query string

  10. The flood report names the posted fields instead of dumping them, so a password cannot arrive through the message text either

  11. The hand-written unset() in mailtest() is gone: one rule replaces one special case
  12. Four cache settings instead of six (admin/modules/config.php, config/global.php, core/system.php, index.php):
  13. cache_c and the second minify pass are gone; the stored page is now exactly the page that was served
  14. cache_d is merged into cache_b, which becomes a number of days with 0 for off
  15. Browser caching no longer depends on db_t; the publicly cached response drops the generation-time marker instead, decided where the public headers are actually sent

  16. OpenSearch, XSL and the asset route stop reading a setting: the first two take Cache::STATICDAYS, the third keeps its immutable year

  17. The page identity becomes pc3 and cache_version becomes 4, so no entry written under the old rules can be served and every install rebuilds its merged configuration

  18. The configuration writer stops mangling what it stores (core/system.php, setup/index.php, config/filetype.php):
  19. One value is one line however long it is; a configuration file is data, and the line limit governs code a person writes

    • The line-splitting cut multibyte characters in half, so one save of a localized form produced a
file that was no longer valid UTF-8
  • The installer carried a second copy of the same splitter and would have produced files the panel
does not
  • Line endings are normalized on the way in, because a textarea posts CRLF into a source file of this repository

  • One blind spot of the cache gets a record (core/classes/cache.php):
  • A stored file that exists but cannot be read is written to the file channel once per process

    • The page re-renders and the guard prevents the warning that would otherwise name it
    • One record per process, because a locked append per read would cost more than the fact is worth
  • Documentation and help (docs/PERFORMANCE.md, docs/PARSER.md, admin/info/config/ru.md, admin/info/scheduler/ru.md, UPGRADING.md):
  • The performance guide gains the parser layer it never described, with the threshold and its reason
  • The parser guide loses a cache guard that does not exist: the exclusion is $this->vary in the class
  • The configuration help describes what pages/data really stores, the new field set and the real scope of the caching options, which is the front page and the news list, not every section

  • The scheduler help had the cachegc job as disabled and as a full wipe; it is enabled and removes stale files only

  • docs/PAGE-CACHE-ROUTES-2026.md is the plan for widening the page cache to the other modules

Benefits:

  • The rendered-content directory holds the few documents that are expensive to parse instead of thousands of fragments that never repaid their write

  • A warning raised during a login, a registration or a profile save no longer records the password
  • Two settings fewer to explain, and the stored page can no longer differ from the served one
  • Saving the settings form on a localized installation no longer corrupts config/global.php

Technical notes:

  • Breaking: an installation running cache_b = '1' must set cache_b to its former cache_d, because a bare 1 now means one day. This install runs cache_b = '0' and carries nothing over

  • Breaking: cache_c and cache_d are removed from config/global.php; cache_version = 4 forces every install to rebuild config/local.php on the first request

  • Every stored page becomes unreachable at once through the pc3 prefix; cachegc removes the files
  • The browser-cache branch for HTML stays unreachable in practice while any page carries a CSRF token marker, which makes its entry dynamic and therefore no-store

Вчера (11.08.2026)
Style: line endings stop depending on the host, and the retired repair files leave the tree
Автор: Eduard Laas | Дата: 20:54 11.08.2026

Every writer in the project emitted PHP_EOL, so the same code produced CRLF on a Windows host and LF on a Linux one - in JSON log records, in generated PHP files and in the configuration the installer writes. All of them now emit "\n", and CRLF is produced only where a protocol requires it. The two hand-repair SQL files are gone with everything that referenced them.

Core changes:

  1. Log writers emit LF (core/classes/logger.php, admin/modules/database.php, core/security.php, core/system.php):
  2. The JSONL record terminator of all six channels, database.log, log.log and days.log

    • A record separator that depends on the host makes one machine format two ways
    • The reader was already tolerant, splitting on any break, so no stored log breaks
  3. Generated files emit LF (setup/index.php, admin/modules/lang.php, admin/modules/editor.php, admin/modules/blocks.php):
  4. The installer carried its own copy of setConfigFile() and wrote the same config files with CRLF

    • A configuration file therefore ended up mixed, depending on whether the installer or the panel touched it last
  5. Language files, block files, editor templates and robots.txt follow the same rule
  6. The block generator loses the hardcoded CRLF around its heredoc marker, which also removes a parser risk
  7. The admin IP filter stops missing a break (admin/modules/security.php):
  8. strtr() stripped PHP_EOL and therefore missed a lone LF on Linux and a lone CR on Windows
  9. It now strips CR, LF and space, so the stored list cannot carry a stray break on either host
  10. Mail bodies and assembled text emit LF (core/classes/mail.php, core/security.php, admin/modules/*, modules/help):
  11. The SMTP transport already normalises a body to CRLF before the dialogue, so that boundary is the only place CRLF belongs
  12. The retired repair files leave the tree (setup/sql/, docs/VERSIONS.md, tests/):
  13. update6_3_patch.sql and update6_3_text_once.sql are gone, and nothing references them any more
  14. The upgrade matrix drops to two rows, the hand-patch section and its recount route are removed
  15. The splitter scenario moves onto the shipped upgrade channel instead of the deleted file
  16. The privat probe drives one channel, and its expectation follows

Benefits:

  • A log, a generated file and a configuration read the same on every host the project runs on
  • One rule instead of a per-call-site choice: LF inside the application, CRLF only at the protocol boundary
  • The suite covers seven scenarios that were silently skipping on the missing files

Technical notes:

  • Existing logs stay mixed; old CRLF records are still read, because the reader splits on any break
  • A raw editor file written by the previous code on Windows shows its guard prefix once, and the first save repairs it
  • No schema change, no route contract change, and no compatibility layer for the removed files
Fix: the secret stops travelling with the release, and the upload walk finds its own field again
Автор: Eduard Laas | Дата: 19:46 11.08.2026

The shipped configuration carried a live master secret, and the route walk still addressed the upload record by positions that moved a release ago. Both are corrected here, together with the leftovers the audit of the editor upload plan surfaced.

Core changes:

  1. The master secret becomes per installation (config/security.php):
  2. The shipped secret is emptied, so getSecret() generates one on first use

    • core/security.php already carries that branch; it never fired while a value shipped
    • setup/index.php writes back the value it reads, so every installation ran on the same secret
    • The secret feeds csrf, dynreg, captcha, field, stats and upload
  3. The route walk addresses fields by name (tools/upload-route-check.php):
  4. setUploadSwitch() reads the key order out of setUploadRuleData() instead of naming positions

    • The record lost adminlist and holds twelve fields; the walk still wrote to positions ten and eleven
    • The access matrix and the guest isolation skipped silently, and the run still exited zero
  5. A skipped row can be marked required, and a required skip now fails the run

    • Skips shaped by the stand stay non fatal: no remote URL, captcha left on, no image on the page
  6. The configuration cache is dropped without suppression (core/system.php):
  7. The suppressed unlink becomes a guarded one, so a missing cache is no error and a real one is not hidden
  8. Documentation and the avatar library (UPGRADING.md, templates/lite/images/avatars):
  9. The runtime cache step deletes config/local.php, which no fingerprint ever invalidates
  10. The two closed plan documents leave the tree
  11. The 0-NEW staging tree is gone; presets holds the library and system holds user, guest and deleted
  12. Tests and one locale (tests/Unit, admin/lang/fr.php):
  13. CommentWriteTest passes over a module with no writable target, which carries no delta to compare
  14. Two file manager tests lose the double quoted string the formatter rejected
  15. _EDFILEG takes the single quoted form the constant rules require

Benefits:

  • Two installations no longer share one secret, so a token forged against one does not travel
  • The acceptance walk of the editor upload runs its access matrix and its guest isolation again
  • A green suite: no formatter finding and no PHPUnit warning

Technical notes:

  • The secret is regenerated per installation; the previous value remains in the history of this file
  • Every session and CSRF token is invalidated once the configuration cache is rebuilt
  • No schema change, no route contract change and no runtime compatibility layer added
Feature: the head of a window becomes its handle, the settings become one page and the help says what the section does
Автор: Eduard Laas | Дата: 15:50 11.08.2026

The editor windows are moved by their whole head and show the handle where a hand looks for one, the upload preferences stop hiding half of themselves behind a sub-tab, and the documentation of the section is written against the screens as they are. The one writing route that reached the disk without a record now leaves one behind.

Core changes:

  1. Head of the editor windows (templates/{admin,lite}/partials/editor-toastui-*.html, plugins/editors/toastui/assets/editor-upload.js, templates/{admin,lite}/assets/editors/toastui/skin.css):
  2. The whole plate of the head carries the window, under the left button alone

    • A button of the head keeps its own press, so closing still closes and expanding expands
    • An expanded window hides the handle and drops the cursor: it has nowhere left to move
  3. The handle moved to the right beside the other two buttons and became a grip

    • The computed styles of the three icons were compared first: no overlay and no filter
    • arrows-move draws four arrows and a crossing at sixteen pixels and reads as a blot
  4. Hovering paints the button in a system tone by the chip formula: green, blue, red
  5. The caption carries the icon of the button that opens the window, in the folder family
  6. Upload preferences on one page (admin/modules/uploads.php):
  7. The sub-tabs are gone: the general block and the module blocks stand in the one form they always shared, under the one save button they always had

  8. The directory picker is drawn on the catalogue alone, which is the screen it navigates

    • getUploadsSearch() loses the argument it never received and the dead branch behind it
  9. Captions that name what a field does (admin/lang/{locale}.php, lang/{locale}.php):
  10. The general block speaks of attachments and their output template, not of applications

    • The width and the height name the placeholder they are substituted into
  11. The note of the link section of the rail matches its neighbours in length and in ending
  12. Journal of the editor upload (core/system.php):
  13. addEditorUpload() writes one record per submitted file, as the two other routes of the window already did for deletion and packing

    • A refusal is recorded with the reason the upload service answered
    • Until now this was the one route of the project that stored a file and left no trace
  14. Documentation of the section (admin/info/uploads/ru.md):
  15. Rewritten against the screens: the system files tab it never described, the desk conveniences, the policy of closed paths, the source editor and the window of the editor

  16. The removed sub-tabs, the retired setting and the paginator leave the text with them
  17. The opening names the tabs in one sentence, the way the newest help documents do

Benefits:

  • A window says by its cursor and its handle exactly what it can do, and hides both where it cannot do it

  • One page of preferences instead of two panels behind a switch nobody needed
  • A caption that names its own effect instead of a word that means nothing here
  • Every route that puts a file on the disk can be accounted for afterwards

Technical notes:

  • No schema change, no configuration change and no route contract changed
  • tests/Unit/FileManagerCatalogTest.php gains the journal of the editor upload
  • uploads/files/files-WGVl13gb5m-7885.png is a test image found in the working tree; it is committed with the set because the tree is committed whole and may be removed

Feature: the file browser gains a desk, sheds its leftovers and shows a directory whole
Автор: Eduard Laas | Дата: 13:55 11.08.2026

Stages 8 and 9 of docs/FILE-MANAGER-CONCEPT-2026.md close the plan. Both screens answer the pointer and the keyboard the way a file manager on a desktop does, the last duplicate list and the last legacy download helper are gone, and the catalogue scrolls with the page while holding nothing back from an administrator.

Core changes:

  1. Desk conveniences on both screens (plugins/system/slaed.js, templates/admin/assets/js/admin-ui.js, plugins/editors/toastui/assets/editor-upload.js):
  2. The right button opens the fan of the object under the pointer, where the pointer stands

    • The owner is the box holding exactly one fan, so the empty ground of a tile grid keeps the browser menu
    • The direction is read off the theme instead of being known by the client
  3. A modifier marks instead of navigating: Ctrl one object, Shift the whole span

    • The marking press is caught in the capture phase, so a row does not follow its own address
    • The current object does not move, because the panel beside the list describes it
  4. Arrows walk what is visible, Space marks, Enter does what a press does
  5. A file dropped anywhere reaches the shown directory, an object dropped on a directory is moved

    • The move opens the same operation form with the target filled in, because a moved file loses its published address
  6. The window of the editor opens on the first available rail section and returns the focus that opened it
  7. Cleanup of the file layer (core/admin.php, admin/modules/uploads.php, index.php, core/system.php):
  8. getAdminUploadFiles() and the two quick lists it fed are gone together with their go=5 route

    • The catalogue is now the only list of the upload tree the administration has
    • The directory selector stays, because it is what walks the browser to a module
  9. stream() becomes getFileStream(), the single download path of the project

    • The opaque type replaces application/force-download and the empty Content-Range
    • The name reaches the header encoded and reduced to its own last segment
    • A missing or unreadable file answers 404 instead of an empty attachment
    • getAdminFileDownload() decides the right and hands the file over; four callers outside the file manager follow the same path
  10. modules/files takes a streaming branch only for a file that lies on this server
  11. The catalogue scrolls with the page (core/admin.php, templates/admin/partials/*, templates/admin/assets/css/theme.css):
  12. No pager and no box of its own: a directory stands at its full length
  13. The tree, the properties, the column titles and the bulk bar hold themselves in the window

    • The card and the admin wrapper clip with overflow: clip, because hidden makes a scroll container and kills every sticky inside it
  14. An administrator is answered the whole directory; what may not be seen is decided by the path policy and never by a number
  15. The retired list length leaves the project (core/system.php, admin/modules/uploads.php, config/uploads.php, admin/lang/*):
  16. adminlist was the page size of the removed quick list and had no reader left
  17. The module rule drops the field and carries twelve, config/uploads.php is migrated record by record
  18. The settings form loses the input, six locales lose _F_5, _UPLOADS_SEEN and _UPLOADS_CUT
  19. Visual corrections against the approved mockup (templates/admin/, demo/):
  20. The tile leaves room for its fan, marks on a plate under the name the editor window already uses, and names size and day
  21. The fan of a tile opens as one row, the shape it has in a list and in the editor window
  22. The tree step is 8px, both side columns are 250px, the filter group stands over the properties column
  23. The type column is gone: the extension is in the name and the kind is in the icon
  24. bi-folder replaces bi-folder2, and bi-folder-fill marks the open node
  25. Tests and plan (tests/Unit/, tools/upload-route-check.php, docs/):
  26. DeskKeysTest holds the context menu, the modifiers, the keys, the focus and the two kinds of dragging
  27. FileManagerCatalogTest holds the single list, the single download path and the scrolled directory
  28. The plan marks stages 8 and 9 closed and records every decision taken after them, with its price

Benefits:

  • One download path writes the headers of every download in the project, so a stored file can no longer be answered with a type that executes
  • One list of the upload tree instead of three, and one place where a directory turns into rows and tiles
  • An administrator sees a directory whole, and the settings that count files stay where they belong: the editor window and the visitor
  • The two screens carry the same components under the same names, so a component fixed once is fixed on both

Technical notes:

  • Breaking change: the module upload rule loses adminlist and holds twelve pipe-separated fields; config/uploads.php is migrated in this commit and a rule written for the previous format would be read shifted
  • A rule written short by hand still answers the guest limit with the user one, because zero in that position would mean no limit for the one role that never had one
  • New helper getFileStream() replaces stream(); admin/modules/security.php, modules/clients, modules/files and modules/shop are migrated to it
  • Removed route: index.php go=5 getAdminUploadFiles; no other route changed its contract
  • No schema change; no stored file is touched or renamed
Эта неделя (10.08.2026)
Feature: the file layer gains its writing half, and the editor window becomes its third screen
Автор: Eduard Laas | Дата: 23:55 10.08.2026

Stages 4 through 7 of docs/FILE-MANAGER-CONCEPT-2026.md close together: the system area can be edited and rewritten under one lock protocol, the upload catalogue and the editor window are both drawn from the same descriptor, and every changing action of either screen travels by POST with a token and leaves an entry in the journal behind it.

Core changes:

  1. Source editor of the system area (core/classes/filemanager.php, admin/modules/uploads.php):
  2. getFileBody() and setFileBody() read and replace the body of one text file

    • the version is the digest of the bytes on disk and is compared inside the directory lock
    • a mismatch answers 409, writes nothing and hands the fresh version back to the author
    • the line separator is taken from the file, so a save never rewrites every line of it
  3. fmedit() and fmsave() put the editor in the place of the list while the tree stays
  4. the guard of an unsaved edit reaches htmx swaps, links and beforeunload alike
  5. Writing operations of the system area (core/classes/filemanager.php, admin/modules/uploads.php):
  6. addFileEntry(), addDirectory(), updateFileName(), addFileCopy(), updateFilePath(), deleteFileEntry(), addFileArchive() and addFilesArchive()

    • both sides of a compound path are asked of the policy separately
    • two directories are locked in sorted order, so two writers never wait on each other
    • a name already taken is refused inside the lock, where the answer is still current
  7. one form of the browser carries the argument of a rename, a copy and a move
  8. Catalogue of the administration (core/admin.php, admin/modules/uploads.php, templates/admin/*):
  9. the whole upload tree is browsed with the rights of an administrator: tree, crumbs, rows and tiles, properties, fan, marks, bulk bar, gallery, upload queue and pager

  10. deletion and archiving left their GET links for POST routes of the module
  11. the server path moved out of the heading of the section into a property of the object
  12. Window of the editor (plugins/editors/toastui/, templates/lite|admin/partials/):
  13. editorFiles answers the descriptor of the file layer together with capabilities and quota
  14. getEditorRouteRule() asks the three questions every route of go=4 asks
  15. editorDelete and editorArchive hand a module moderator the two operations section 14 named
  16. the window follows the approved mock-up: a rail of insertion ways, sections that state the rights they were given, compact and expanded catalogue, filter, fan, marks, gallery and an upload queue, with the five states of the process each carrying its own words

  17. Language constants (lang/{locale}.php, admin/lang/{locale}.php):
  18. EDITOR for the window and UPLOADS for the catalogue, in all six locales
  19. _RETRY becomes a global constant and its scoped copy is dropped

Benefits:

  • one file layer answers three screens, so a path, a name and a lock are decided in one place
  • a permission is read off the descriptor of the object instead of a role derived in the client
  • every changing action is a POST with a token and an entry in storage/logs/error_file.log
  • the two themes carry the same components under the same names

Technical notes:

  • new routes: index.php go=4 editorDelete and editorArchive; the contract of editorUpload and editorFiles is otherwise unchanged and their token now travels in the body

  • the JSON of the editor never carries an absolute server path; only the administrative context receives realpath, and it is shown in the properties of the selected object

  • getEditorImageData() is gone together with the row it used to build; the one list of embeddable types is read from Parser::EMBEDIMG by the editor driver

  • _UPLOADS_RETRY is removed in favour of the global _RETRY
  • no schema change, no configuration change, backward compatible
Feature: the filesystem gets one layer of its own and the administration gets its first screen of it
Автор: Eduard Laas | Дата: 15:30 10.08.2026

Stages 1, 2a, 2b and 3 of docs/FILE-MANAGER-CONCEPT-2026.md: FileManager reads one filesystem area below a server-chosen root, the managed name format and the lock protocol leave Upload for it, and a System files tab browses BASE_DIR and writes nothing.

Core changes:

  1. File layer (core/classes/filemanager.php):
  2. Three contexts over one root the server chooses: uploads, editor, system

    • Canonicalization refuses traversal, absolute paths, stream wrappers and symlink escape
    • One policy method answers list, read, download, write and delete for every path
    • The descriptor carries the absolute path in administrative contexts and never in the editor
  3. The managed name format lives here alone

    • SALTLEN, checkFileName() and getFileOwner() replace the two former regular expressions
  4. getPathLock() and deletePathLock() are the one lock protocol of the project

    • The key is the directory, because the upload service draws a free name below it
  5. Upload service (core/classes/upload.php, core/system.php):
  6. Upload requires the file layer and takes the shared lock when it publishes and when it deletes
  7. The name pattern and the salt length come from FileManager, and the constructor drops its lock argument
  8. getEditorFileJson() reads the owner through FileManager::getFileOwner()
  9. System files tab (admin/modules/uploads.php, core/admin.php, index.php):
  10. sysfiles() draws the browser: tree along the open path, crumbs, list, tiles, properties
  11. Four go=5 routes: getAdminFileList, getAdminFileData, getAdminFilePreview, getAdminFileDownload

    • Every one of them asks isAdmin(true) and checkFileAccess() again before it answers
    • A download is always application/octet-stream, because a guessed type executes in the admin origin
    • An image preview takes its type from a closed table and answers under a sandbox policy
  12. The tab carries no upload directory selector and no writing action
  13. Templates and theme (templates/admin/*):
  14. New partials file-browser, file-browser-tree, file-browser-list
  15. New fragments file-browser-row, file-browser-tile, file-browser-props
  16. The theme gets the three columns, the tree, the tiles, the properties panel and the empty states
  17. admin-ui.js holds the view, the current object, the way back and the filter of the open directory
  18. Language constants (admin/lang/, lang/):
  19. 29 UPLOADS* names in six locales, plus _FRESET and _DOWNLOAD in the site scope
  20. Mockups, tests and plan (demo/, tests/Unit/, docs/FILE-MANAGER-CONCEPT-2026.md):
  21. Both mockups show the states of the process: queue, skeleton, empty, failed, busy and rename
  22. FileManagerPathTest covers the path list of the plan, the policy rows and the capability tables
  23. FileManagerLockTest proves that two writers serialize on one key through one protocol
  24. The plan marks stages 1, 2a, 2b and 3 closed and names the routes that exist

Benefits:

  • One filesystem layer serves the administration, the editor window and the upload service
  • Path traversal, symlink escape and closed paths are refused in one place instead of per route
  • The system area is readable through the browser without a link that would execute a file
  • Two writers of the same directory wait for each other, because there is only one lock protocol
Docs: the file manager plan names its stages, and the two themes stop disagreeing
Автор: Eduard Laas | Дата: 12:17 10.08.2026

The file manager concept becomes an implementation plan: every stage carries its own reading map, acceptance rule and stop condition, so one session opens the document, reads its stage and works. The mockups both screens are built from are committed beside it, and the theme gaps found while building them are closed in the themes rather than patched in the mockups.

Core changes:

  1. Implementation plan (docs/FILE-MANAGER-CONCEPT-2026.md):
  2. The document turns from a concept into a plan of ten stages

    • Every stage names why it comes now, what to do, how to verify, what to
commit and when to stop and ask
  • Every stage carries a reading map: the plan sections, the source files with
line numbers and the tests it needs, so a session reads about 500 lines
instead of the whole document
  • Stage 2 is split: 2a builds the class, 2b moves the managed name and the
lock out of Upload and migrates both callers
  • The FileManager contract is renamed to the project rule

    • getFileList, getFileData, getFileBody, setFileBody, addFileEntry,
addDirectory, deleteFileEntry, updateFileName, addFileCopy, updateFilePath,
addFileArchive, getFileOwner, checkFileAccess, isFileEditable
  • list, stat, read and write are refused as names: none of them passes the
verb plus noun rule and half are taken by PHP itself
  • Three mechanisms are described once and shared by both screens: the sl-dial action fan, the sl-modal preview gallery, and the checkbox selection with its bulk bar

  • The save protocol takes the lock around the whole compare and replace, because a version check beside the lock protects nothing

  • The path policy answers per operation instead of hiding entries from a listing, and rename, copy and move check both sides of the path

  • System files gain their own download route: a direct link would let the server execute index.php instead of handing it over

  • Language constants go to UPLOADS and EDITOR, each matching its own configuration namespace

  • Editor uploads plan (docs/EDITOR-UPLOADS-2026.md):
  • The plan is closed: the editor mode of tools/upload-route-check.php was walked against a live stand with every row passing

    • The access matrix of four settings combinations against three roles
    • The guest isolation of two sessions
    • The write guard over real HTTP
  • The walk needs two accounts and not four: is_moder() reads the admin session only, so one account answers as moderator in one cookie jar and as a member in the other

  • Admin theme (templates/admin/assets/css/theme.css):
  • sl-but-mini drops the browser chrome that drew a second border over its round fill, as the lite theme already did

  • sl-is-muted, the disabled state, sl-bulk-bar and sl-bulk-count arrive under the names they already carry in lite

  • sl-modal-wide and sl-modal-image arrive so a gallery has a frame to open in
  • A selected table row is now distinguishable from a hovered one
  • Lite theme (templates/lite/assets/css/theme.css):
  • sl-bulk-count joins sl-bulk-bar under the name the admin theme uses
  • Approved mockups (demo/filemanager-*.html):
  • filemanager-v2-rail.html is the editor window: a side rail of three insert ways, the module storage, four permission scenarios, the action fan, the gallery and multiple selection

  • filemanager-admin-2026.html is the admin full mode: file catalogue and system files on one shell, built from existing theme components

  • Eight earlier variants are kept as the record of why the rail was chosen

Benefits:

  • A session can work on one stage without reading the whole plan
  • The mockups are a working reference, not a picture: they use production classes, so moving them into code is mechanical

  • The two themes now carry the same component set under the same names, which removes the need to redefine anything locally

Technical notes:

  • No PHP was touched; the file manager itself is not implemented yet
  • The theme additions are new rules only, no existing selector changed its meaning, verified against the live admin and front pages

  • The next stage is 1: the loading and error states in the mockups
Эта неделя (07.08.2026)
Feature: the settings decide what a visitor may do with a file, and the field decides what it may hold
Автор: Eduard Laas | Дата: 12:18 07.08.2026

The content editor no longer keeps rules of its own beside the module upload settings. Access is answered by one function, the width of the target column decides whether a field may carry an embedded image, and one guard holds every write to the room its column has instead of letting the database answer with a lost post. Batches 1 to 6 of docs/EDITOR-UPLOADS-2026.md land together.

Core changes:

  1. Settings and ownership (core/system.php, core/classes/upload.php, admin/modules/uploads.php):
  2. The module rule gains the key guestfiles, appended so a stored rule keeps working

    • A rule written before this release normalises on its first write and keeps every value it carried
    • The new key falls back to userfiles when its position is absent, because zero means no limit
  3. A guest owns the own uploads by a token derived from the session, never by the shared zero

    • The owner segment of a stored name widened from an integer to alphanumerics
    • The listing compares it as a string, so one guest can no longer match another
  4. The guest guard on the listing route is gone; checkEditorUploadAccess() alone decides

    • The one role rule left is its first line, a moderator of the module
    • Which of the three listing limits applies is role, what each is worth is settings
  5. The storage contract (core/helpers.php, setup/sql/*.sql, 18 modules):
  6. Every one of the 54 editor call sites declares where its text is stored
  7. getEditorRoomData() turns that name into a column type, and the type into bytes

    • Seventeen body columns are MEDIUMTEXT, so an embed at the cap fits
    • Summary columns and signatures stay TEXT, which is how a field says it holds no data URI
    • auto_links.intro and users.sig leave VARCHAR, where a rich editor never belonged
  8. checkEditorTextRoom() refuses before the query and answers a ready message

    • Length is measured in bytes, because bytes are what a column bounds
    • Embedded weight and media type are measured beside it
    • The content feed writer keeps the stored body and logs the reason instead of failing
  9. One window and one bounded embed path (plugins/editors/toastui/, templates//partials/*):
  10. The image dialog and the file catalogue became one window behind one icon

    • setImageChrome() and setPopupChrome() are gone with the popup they measured
    • The icon is there for every visitor, because the address field inside it always is
  11. The blob hook is registered unconditionally

    • A denied upload no longer falls through to the vendor default, which embedded with no bound at all
    • Picked, dropped and pasted files reach one guarded path that checks room, type and size
  12. The cap and the list of embeddable types reach the editor from PHP
  13. The proof (tests/Unit/EditorRoomTest.php, tests/Support/editor_probe.php, tools/upload-route-check.php):
  14. The room table is held against setup/sql/table.sql in both directions

    • No store may resolve to a column that is neither TEXT nor MEDIUMTEXT
    • Every call site names a storage the table carries
  15. The write guard runs against the real core in an isolated process
  16. The tool gained an editor mode for what only exists as a request handler

    • The access matrix, the guest isolation and the write guard over real HTTP

Benefits:

  • A setting the administrator changes is the setting the editor obeys
  • A refusal reaches the author at the moment they act instead of as ERROR 1406
  • One definition each for the cap, the embeddable types and the room a field has
  • A wrong column name fails a test rather than costing an author a post

Technical notes:

  • Storage: seventeen columns widened to MEDIUMTEXT, auto_links.intro and users.sig to TEXT, in all three schema paths
  • Config: one key appended to the upload rule; no migration needed and no value reordered
  • Files stored under the old name pattern keep resolving; no migration of stored files
  • The editor mode of tools/upload-route-check.php needs a stand and four credentials and is not run by the suite

Всего: 1107 на 111 страницах по 10 на каждой странице

1 2 3 4 5 6 7 8 9 10 111
Хотите опробовать SLAED CMS в действии?
Идеи и предложения
Обратная связь
Подтверждение

Поделиться
QR-код