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

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

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

Всего: 1347 Доступных коммитов | Отфильтровано: 1347 Коммиты | Страница: 28 из 135
28.07.2026
Docs: record mail stage 2 in the plan
Автор: Eduard Laas | Дата: 20:41 28.07.2026

The mail plan gains its stage 2 entry and is corrected wherever the implementation measured something the plan had assumed, so a session reading only the plan sees the delivered design rather than the designed one.

Core changes:

  1. Progress and decisions (docs/MAIL-2026.md):
  • stage 2 recorded: what was built, what was verified and against what
  • the claim is described as it is implemented and measured: the predicate is the leading columns of the claim index, and exclusivity comes from the claim moving a row behind the lock window
    • the measurement that decided it is written down, 202 ms against 1.9 ms
  • the upgrade statement lives in table_update6_3.sql, with the reason: 6.3 is the release this ships in, and a new file would give a fresh install the table and an upgraded one nothing
  • the drain job is priority 2, as the plan's own paragraph argues; its code block said 1 and is corrected
  • an empty drain run reports success and never idle, because the scheduler counts every other status as a failure and this job runs every five minutes
  • retention is keyed on the creation stamp, the only one the table has
  • the test send reports what the run did, not what the queue accepted
  1. Blockers (docs/MAIL-2026.md):
  • concurrency closed: two processes racing one queue of 400 rows claimed 200 each with no overlap
  • added: delivery is still proven only against a loopback sink, the transactional retention delete cannot use an index prefix, and the queue rows on the mail tab were verified as controls rather than as behaviour
  1. Facts re-measured:
  • the admin config module line references, shifted by the six queue rows

Benefits:

  • the two places where the plan contradicted itself or the engine are settled in the plan rather than only in the code
  • the next stage starts from measured numbers

Technical notes:

  • no code changes
  • the execution cookbook is left untouched; marking the order table is the reader's step after the commit
Feature: outgoing mail is queued and drained instead of sent inside the request
Автор: Eduard Laas | Дата: 20:40 28.07.2026

Stage 2 of docs/MAIL-2026.md. addQueue() stores a row and answers accepted into the queue; delivery moves to a scheduler job that claims, sends and records under a lock, so no request waits on a transport and no failure stays invisible. No call site changes: all 26 moved to $mailer->addQueue() in stage 1.

Core changes:

  1. The queue table (setup/sql/table.sql, setup/sql/table_update6_3.sql):
  • {prefix}_mail holds kind, sender, email, title, body, ref, prio, time, ntime, tries, status, camp, hold, locked, lockid, phase, code and error
  • the claim index leads with hold, status, prio, ntime, id; kind_status_time and kind_ref_status serve retention and the campaign queries stage 3 adds
  • the upgrade statement creates the table with its primary key alone and adds every secondary index through addidx, so a half-applied schema is repaired instead of refused
  1. Queue and drain (core/classes/mail.php):
  • addQueue() stores instead of delivering; every value is bounded against the column that holds it, and an oversized subject is refused where the caller can still be told rather than by a failing write
  • getBatch() claims one batch in a single conditional UPDATE and moves the rows behind the lock window, which is what makes the claim exclusive
    • the predicate is exactly what the claim index leads with: with a marker column in it the optimizer left that index and filesorted 99 267 rows
  • setResult() records the outcome, grows the backoff per attempt and fails the row at the attempt cap; a reference to a body that is gone is not retried
  • updateQueue() is time-boxed rather than count-boxed, honours mail.rate across runs through the job state, and keeps one transport connection for the run
  • deleteQueue() prunes accepted rows per kind and never touches a failed one
  • sending is private: the queue is the only way out
  1. Scheduler job (config/scheduler.php, core/system.php, setup/index.php):
  • maildrain ships active, runs every five minutes and stays manually triggerable
  • addMailTask() maps a run to the job status: an empty queue is a success, a run that refused everything it tried is a failure
  • the upgrade inserts the job into an existing config/scheduler.php
  1. Queue settings and the test send (admin/modules/config.php, admin/lang/*.php):
  • batch, rate, tries, backoff, keep and keepbulk get a row on the mail tab and are validated on save
  • the test send queues and then drains inside the request, so the button still reports the transport's own words; a run that sent nothing says so instead of claiming a delivery nobody observed
  • seven constants added to all six locales
  1. Tests (tests/Unit/MailQueueTest.php, tests/Unit/MailDrainTest.php, tests/Support/):
  • 25 tests over the statements the queue issues and the bounds it holds
  • 15 tests driving the live database and a loopback SMTP sink through tests/Support/mail_probe.php and tests/Support/mail_relay.php
  • the stage 1 transport tests now enter delivery the way the drain does

Benefits:

  • a request that sends mail returns at once: the security notice measured here queues in 0.11 s where the same path used to wait on mail()
  • a refused delivery is retried behind a backoff and recorded instead of being discarded
  • one SMTP handshake per drain run rather than one per message
  • the claim reads its 25 rows in 1.9 ms with 100 000 pending, against 202 ms before the predicate was written against the index

Technical notes:

  • new table {prefix}_mail; a fresh install and an upgrade produce the same definition, the upgrade is idempotent and repairs a partially applied one
  • two processes racing one queue of 400 rows claimed 200 each with no overlap
  • breaking change: mail becomes asynchronous on every installation that takes this release, and addQueue() answers accepted into the queue, never delivered
  • no compatibility layer and no runtime schema detection
  • config/mail.php is unchanged: stage 1 already shipped every queue key
Docs: plan the Backup and Upload class migrations
Автор: Eduard Laas | Дата: 19:16 28.07.2026

Two more procedural core subsystems get a concrete migration plan in the shape the 2026 plans already use, and the analysis document that only listed candidates is retired now that its two remaining entries have plans of their own.

Core changes:

  1. Database backup (docs/BACKUP-2026.md):
  • addBackupTask() is replaced by one final Backup class owning database export and the creation of one verified, restorable artifact
  • scheduler access, locking, state and presentation stay in the scheduler
  • named Backup rather than DatabaseBackup, with addDatabaseBackup() as its first public operation so the short class name does not imply filesystem coverage
  • one atomic replacement: atomic output, consistent reading, checked writes, exact artifact identity, cleanup and restore verification are part of the first implementation rather than a later hardening pass
  1. Uploads (docs/UPLOAD-2026.md):
  • upload(), check_file() and check_size() are replaced by one Upload class
  • the separate editor upload implementation joins the same validation and storage boundary
  • owner context, quota locking, DNS-pinned remote transfer, stale-partial recovery and the supported-flow criteria are settled without fallbacks
  1. Retired analysis (docs/REFACTOR_CLASS_CANDIDATES.md):
  • removed; the candidates it ranked are covered by the mail, comment, backup and upload plans

Benefits:

  • both subsystems now have a plan that states a final contract instead of a direction, so neither can be half-migrated
  • the docs directory holds plans that are executed rather than a list that is read

Technical notes:

  • no PHP source changed
  • both plans are proposed, not started
  • both replace their contracts outright: no compatibility wrapper and no behavior-preserving intermediate implementation
Docs: record stage 1 batch 6 and close the comment plan stage
Автор: Eduard Laas | Дата: 19:16 28.07.2026

The comment plan gains its last stage 1 entry and is re-measured against the code the batch left behind, so a session reading only the plan sees the delivered state rather than the designed one.

Core changes:

  1. Progress and decisions (docs/COMMENTS-REDESIGN-2026.md):
  • batch 6 recorded: what moved, what was measured and how
  • eight decisions added, covering the single module map, the public resolver against the private counter, the deletion of ashowcom() rather than a rename, the precomputed sidebar count and the shape the guard has to look for
  • deviations added: the render defect moved verbatim, the unstable sort that makes an ascending capture differ from itself, two measurement artefacts, and the config cache that silently defeats a sort change
  1. Facts re-measured after the move:
  • core/system.php 5944 to 5689 lines; the render is 136 lines in core/user.php
  • seven defined('ADMIN_FILE') branches inside the deleted function, not eight
  • no stored comment carries a module outside the eight-entry map
  • line references refreshed across the Facts, Target design and Stage 2 sections
  1. Blockers closed:
  • the frontend page-cache mechanism is index.php:130 through Cache::addEpoch(), mixed into every page key by getPageHash(); the two halves of the contract it does not meet are named and handed to stage 4
  • the admin sidebar chip entry of the consumer list is struck through
  1. Execution cookbook (docs/EXECUTION-2026.md):
  • comments stage 0, mail stage 1 and comments stage 1 marked done in the order table, so the next chat starts at mail stage 2

Benefits:

  • the plan states what was delivered and what was deliberately not, so the next stage does not rediscover either
  • every number quoted in it was measured against the current tree

Technical notes:

  • no code changes
  • one item of the stage is recorded as not delivered: deleteUser(), because the behaviour it would replace has never been decided
  • the markup baseline is left reporting CHANGED for three modules; the cause is recorded with the statement that restores it
Refactor: the comment counter and the target resolver move into the Comment class
Автор: Eduard Laas | Дата: 19:15 28.07.2026

Stage 1 of docs/COMMENTS-REDESIGN-2026.md closes here. The comment table now has exactly one owner: the three global helpers that shared it are gone, the last consumer reaching it through an assembled table name is closed, and a guard test asserts the boundary for the whole stage rather than for one batch.

Core changes:

  1. Counter and resolver absorbed (core/classes/comment.php):
  • numcom() becomes the private updateTargetCount()
    • three unreachable branches dropped: account/members, gallery, multimedia
    • their points slots 3, 17 and 29 leave the code; the users.points CSV keeps all 45 positions, because the list is indexed positionally
  • getCommentMode() becomes the public getTargetMode()
  • both index one MODULES map holding the target table and the points slot of the eight modules that render comments
    • the counter map and the supported-module list stop being two lists
  • getStatusCount() added for the admin sidebar
  1. The HTML monolith is deleted (core/system.php, core/user.php):
  • ashowcom() removed; its frontend half is getCommentList() in core/user.php, directly above setComShow(), which is where the design puts the rendering
  • the seven defined('ADMIN_FILE') branches are deleted rather than moved
    • core/user.php is required only under MODULE_FILE, so they were unreachable
  • core/system.php shrinks from 5944 to 5689 lines
  1. The last direct consumer is closed (core/admin.php):
  • the waiting-content chip reads getStatusCount(CommentStatus::Pending)
  • getAdminCountRow() takes an optional precomputed count and skips its own query when it is given; the other fifteen sidebar rows are unchanged
  • the dead table, where and rate keys leave the comment entry of getProfileModules(), which is the shape that hid two consumers from earlier sweeps
  1. Stage guard (tests/Unit/CommentIsolationTest.php):
  • no production file but the class names the comment table
  • the files that build a table name from a variable are a closed list, and neither getProfileModules() nor getAdminCountRow() can be handed comments
  • the retired globals are defined nowhere and named nowhere
  • the module map keeps its eight modules and their slots; the points CSV keeps its length

Benefits:

  • one reader and one writer for the comment table, so a counter can no longer drift from the rows it counts
  • the resolver that authorizes a target and the counter that follows a write sit behind the same private boundary, so the trust boundary stage 0 closed cannot be reopened from inside the project
  • the render is 135 lines of markup assembly with no SQL and no dead branches

Technical notes:

  • no table or column changes
  • behaviour and markup preserved: 80 URLs per round compared against the pre-move tree, 80/80 identical descending, and the moderator branch the guest probe cannot reach proven by source equivalence
  • measured on the live table: no stored row carries a module outside the map, so the dropped counter branches were unreachable in data as well as in code
  • breaking change for third-party code: ashowcom(), numcom() and getCommentMode() no longer exist; no wrapper and no alias is provided
Docs: record stage 1 batch 5 of the comment plan
Автор: Eduard Laas | Дата: 17:58 28.07.2026

The Progress section is the only place decisions of a finished batch survive into the next chat, so batch 5 writes down what it moved, what it measured, and the two consumers the plan's own fact list had missed.

Core changes:

  1. Progress and decisions (docs/COMMENTS-REDESIGN-2026.md):
  • batch 5 row: what moved, the three parity measurements, and the checks that ran
  • decisions: why deleteTarget() binds one placeholder per id and moves no counter, why it does not re-validate the module, why the whole shop id list was bound rather than the comment statement alone, what the two extra round trips per profile page buy, and where the unreachable feed guard went
  1. Consumers found by reading rather than grepping:
  • modules/account/index.php built the profile hub from the same module map as the feed, so it reached the comment table through an assembled name and never appeared in a search for the literal; batch 5 migrated it
  • core/admin.php:319 counts pending comments the same way through getAdminCountRow() and is recorded as open, with what it would take
  • the stage 1 acceptance criterion now says a sweep for the literal name is not enough, and names both shapes seen so far
  1. Re-measured facts (docs/COMMENTS-REDESIGN-2026.md):
  • the comment table holds 7353 rows and 3 pending, not 7357 and 4; the distribution moved with it, and the stage 2 body migration must measure the table it actually runs on
  • the class line numbers cited across the plan are refreshed
  • the shop id-list interpolation is struck from the fact list
  1. Deviations worth carrying (docs/COMMENTS-REDESIGN-2026.md):
  • comment-baseline verify reported CHANGED for three modules and the cause was the verification itself: one point per rendered admin page moved a counter the author card shows; the value was restored and the baseline deliberately not re-captured
  • the comment entry of the profile module map now carries three dead keys, and that is the disguise which hid two consumers
  • two log entries found and left alone, neither owned by this batch

Benefits:

  • a new chat reading only this file sees why each deviation exists
  • batch 6 inherits a stage guard that knows what to look for

Technical notes:

  • no code changes in this commit
Refactor: the activity feed and the target deletions move into the Comment class
Автор: Eduard Laas | Дата: 17:58 28.07.2026

Stage 1, batch 5 of docs/COMMENTS-REDESIGN-2026.md. The profile feed, the profile hub and the eight module delete handlers stop reaching the comment table themselves, which leaves one runtime consumer outside the class and removes the last statement that pasted an id list into IN (...).

Core changes:

  1. Target deletion and the profile count (core/classes/comment.php):
  • deleteTarget() removes the comments of target rows a module admin has just deleted
    • one placeholder per id, so a bulk selection reaches the statement as bound values and the single case needs no second method
    • no counter is moved: a target that is gone has no row left to hold one, which is what the eight handlers did before the move
  • getUserCount() answers the published comment count of one account, the number the profile hub shows beside its other module counters
  1. Profile reads (core/user.php, modules/account/index.php):
  • getProfileLastView() drops the comment branch of its UNION and fills the comment tab from getUserList()
  • the profile hub drops the same branch and takes its count from getUserCount(), keeping the rating and favourites values it wrote before
  • the unreachable "no parts" guard of the feed moved to the query itself, so a comment-only feed still renders and the empty case is unchanged
  1. Module delete handlers (eight admin modules):
  • faq, files, links, media, news, pages, shop and voting call deleteTarget() and hold no comment statement any more
  1. Bulk id list (modules/shop/admin/index.php):
  • productops() builds $keys/$pars the way the news and pages handlers already did
    • all six IN (...) clauses bind, closing the interpolation the plan lists as an acceptance criterion of this stage
  1. Parity probe and guard (tests/):
  • contract_probe.php gains three modes: the pre-move feed function beside the migrated one, deleteTarget() driven inside a rolled-back transaction, and the hub values of both versions
  • CommentTargetTest.php asserts the migrated call sites and the measured behaviour, and pins the comment entry out of both UNION branches

Benefits:

  • every runtime comment read and write goes through one class, except the admin sidebar chip recorded as open in the plan
  • a target delete can no longer reach past the module it names
  • the shop handler stops assembling SQL from a joined id list

Technical notes:

  • no table or column changes; no behaviour change intended, and none measured
  • the feed renders byte for byte against the UNION it replaces: 10 accounts, six with comments, one without, plus a missing, a zero and a negative id
  • deleteTarget() measured on all eight modules, on a bulk selection, on a target id shared by five modules, and against crafted id lists and a crafted module name, all inside a transaction that is rolled back
  • the eight routes exercised over real HTTP with a signed-in administrator: each removed only its own module's rows, a wrong token removed none, a repeated delete was a no-op, every per-module total returned to the value it started from
  • core/admin.php:319 still counts pending comments through getAdminCountRow(), which assembles the table name from a variable; it is left for a batch that owns the admin sidebar
Docs: record stage 1 batch 4 of the comment plan
Автор: Eduard Laas | Дата: 15:42 28.07.2026

The Progress section is the only place decisions of a finished batch survive into the next chat, so batch 4 writes down what it moved, what it measured and where it had to change behaviour.

Core changes:

  1. Progress and decisions (docs/COMMENTS-REDESIGN-2026.md):
  • batch 4 row: what moved, the 42-URL and 16-scenario parity measurement, and the checks that ran
  • decisions: why setStatus() took the moderation guard, why the body save is its own method, why updateBody() checks no moderator, and how the admin list lost its second description of itself
  • deviations: the page clamp, the "LIMIT -25, 25" it removes, and the delete() redirect that no longer follows the deleted row's status
  • two runtime log entries found and deliberately left alone, because neither is comment SQL and both behave alike in either version
  1. Re-measured facts (docs/COMMENTS-REDESIGN-2026.md):
  • the frontend handlers and the admin module are struck from the list of direct comment-table consumers
  • numcom() is called from the Comment class alone
  • the class and admin line numbers cited across the plan are refreshed
  • the concurrency section states what the new guard does and does not close, so stage 2 still owes the conditional update
  1. Table rendering (docs/COMMENTS-REDESIGN-2026.md):
  • blank lines had split the Progress table into three, the last two without a header; the table is one again

Benefits:

  • a new chat reading only this file sees why each deviation exists
  • the public method list matches the class that actually exists

Technical notes:

  • no code changes in this commit
Refactor: the comment moderation module moves into the Comment class
Автор: Eduard Laas | Дата: 15:42 28.07.2026

Stage 1, batch 4 of docs/COMMENTS-REDESIGN-2026.md. The admin comment module no longer touches the comment table: every read and write it performed now goes through the Comment class, which leaves the class as the only place that knows how a comment is stored, permitted and counted.

Core changes:

  1. Moderation write methods (core/classes/comment.php):
  • deleteComment() removes one comment and takes the target counter and the author points back when the removed row was published
    • the module and the target come from the stored row, never from the request, so the stage 0 trust boundary holds for deletion too
  • updateBody() stores the body a moderator typed, verbatim
    • the moderation form is not the author edit path and applies neither checkEditRules() nor filterHtml() nor the edit window
  • setStatus() takes the read-then-compare guard the moderation module always had
    • a comment already carrying the wanted status is answered as done without writing, so a repeated click cannot count its target twice
    • the frontend path inherits the guard and loses a double count it never intended; the rendered fragment is unchanged
  1. Moderation module (admin/modules/comments.php):
  • the module selector reads getModuleList(), the list and its count read getAdminList(), the edit form reads getComment()
  • the four write handlers call setStatus(), deleteComment() and updateBody(); no handler takes $db any more
  • the pager renders through getTplPagerView() from the total the list itself counted, replacing getTplPager() and its separate COUNT
    • the $where/$wcnt pair is gone, and with it the second, differently spelled description of one list
  • the rewritten list loop drops its snake_case names per .rules/global.md
  1. Trust boundary guard (tests/Unit/CommentTrustBoundaryTest.php):
  • deleteComment() joined the methods asserted to read module and target from the stored row
  • the numcom() assertion follows the $cid the new status guard needs

Benefits:

  • the moderation list can no longer count one thing and show another
  • a repeated approve or delete leaves counters and points untouched
  • the admin panel gains prepared statements everywhere it had them by hand, and loses one hand-built subquery

Technical notes:

  • no table or column changes; the current sort is untouched
  • three measured behaviour changes, each a consequence of the move: an out-of-range page now clamps instead of answering "no information", &num=0 no longer builds "LIMIT -25, 25", and delete() redirects by the tab the request came from instead of by the deleted row's status
  • parity measured over real HTTP with a signed-in administrator: 42 URLs in two rounds, 39 byte-identical in the module content region, the three others being the page clamp above; 16 write scenarios left identical rows, bodies, target counters, points and row count
Docs: record stage 1 batch 3 of the comment plan
Автор: Eduard Laas | Дата: 14:50 28.07.2026

A new chat starts from this file rather than from the working tree, so the batch that moved the frontend writes has to leave behind what it decided, what it measured and which defects it found and deliberately did not touch.

Core changes:

  1. Comment plan progress (docs/COMMENTS-REDESIGN-2026.md):
  • Batch 3 recorded with what landed, which checks ran and what they reported
  • Decisions written down: why the class still calls numcom() and getCommentMode() as globals, why both validation copies moved unmerged, why the falsy body test was kept, why CommentStatus is applied and CommentMode is not, and why the captcha rule moved with the others
  • The write parity method recorded: a rolled-back transaction against the live rows, which is what makes a real published add checkable on the stand the markup baseline is captured from
  • Three defects recorded with file:line and left untouched: the anchor query that matches without modul, the edit alert that index.php discards, and is_moder('') deciding rights for a row that is gone
  • The clock skew of this installation recorded: MySQL at Etc/GMT-1 against PHP at Europe/Berlin, which keeps the flood window from ever firing and closes the edit window before the author sees their own comment
  • Verification gaps named: the moderator paths and the ajax textarea branch need a browser session no CLI probe can hold
  • Line references re-measured after the move: the resolver, numcom() and its dead branches, the flood query, the anchor query, the word length defect, the render sites and the callers of ashowcom()
  • The render sites are three, not four: batch 3 merged the two inside updateComment(), and the fourth sits in the unreachable admin branch that batch 6 deletes with the function

Benefits:

  • The stage keeps one place where every decision of every batch survives
  • Stage 2 inherits a measured list of what it has to fix rather than a guess

Technical notes:

  • Documentation only; no code, schema or behaviour is touched by this commit
Хотите опробовать SLAED CMS в действии?
Идеи и предложения
Обратная связь
Подтверждение

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

Предварительный просмотр