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

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

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

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

Всего: 1222 Доступных коммитов | Отфильтровано: 1222 Коммиты | Страница: 1 из 123
Вчера (05.10.2026)
Refactor: The document root is public/, every upload leaves through one light path outside it, and nginx ships its own server block
Автор: Eduard Laas | Дата: 23:01 05.10.2026

Batch 2 of docs/0-PRIVATE-DATA-2026.md (step 4 of docs/ROADMAP-2026.md), with the server half of batch 4. The browser now reaches public/ and nothing else: the code, config/, storage/ and the whole uploads/ lie at the project level, so no server misconfiguration can serve a journal, a backup or a closed upload folder. Public upload addresses keep working through a light path of the front controller that answers before the core boots.

Core changes:

  1. The public/ tree (public/*, .htaccess, nginx.conf.example):
  2. templates/, plugins/, sound/, demo/, .htaccess, favicon.ico, robots.txt, error.html and sitemap.xml move into public/
  3. index.php, setup.php and update.php move into public/ whole and define BASE_DIR and PUBLIC_DIR themselves; public/admin.php stays the short file that runs admin/index.php

  4. public/.htaccess drops RewriteBase and refuses the PHP and the markup of the themes; a project-level .htaccess rewrites every request into public/ and refuses everything without mod_rewrite

  5. nginx.conf.example: root on public/, location ^~ /uploads/ to index.php, the theme refusals and the error pages
  6. One upload root and the light path (core/stream.php, core/system.php, core/classes/*):
  7. core/stream.php: UPLOADS_DIR, getUploadPublic(), getUploadUrl(), getUploadRequest(), setUploadStream() and getFileStream()

    • The light path serves a public folder with nosniff, a sandbox policy, a day of public cache, ETag, 304 and ranges
    • Every other folder, a dot segment, a traversal or a missing file answers 404 without loading the core
  8. getFileStream() takes a cache mode (none, private, public) and sends the sandbox policy on every answer
  9. No caller spells 'uploads/' into an address: the parser, getImgText(), the upload rules, avatars, presentation and the file layer ask getUploadUrl(); a private folder has no direct address

  10. The upload service creates a missing folder of its owner on the first write; a missing folder is no refusal of a rule
  11. addEditorUpload() builds the file context after the write, so the first upload into a new folder reports its file
  12. Guards and paths (core/, admin/, modules/, blocks/):
  13. Every .htaccess and guard index.html outside public/ goes, with their writers in FileManager, NodeService, CaptchaStore and update.php; the counters create storage/counter themselves

  14. Every path that relied on the working directory reads BASE_DIR or PUBLIC_DIR: language files, module scans, theme assets, logos, ranks, flags, the sitemap, the file scan, the template editor and the .htaccess and robots.txt editor

  15. The critical files of the file manager follow PUBLIC_DIR, so a document root named public_html keeps them
  16. The installer records the mode of the document root as webroot in config/global.php and shows it as a check row; the avatar folder ships as avatars below uploads/ with its own settings label

  17. Documentation and help (README.md, UPGRADING.md, docs/, admin/info/, modules/*/admin/info/ru.md):
  18. README and the help of the security section explain both modes, Apache, LiteSpeed, nginx and three variants for shared hosting; UPGRADING.md and the help point at nginx.conf.example

  19. The plans record the decisions of the batch, the real entries in public/ and the writer that creates a folder
  20. Tests and tools (tests/, tools/):
  21. New PublicTreeTest: the light path over real HTTP without the core, nothing of the project on public/, both .htaccess files, getUploadUrl() and no guard outside public/

  22. New NginxConfigTest: nginx.conf.example refuses exactly what public/.htaccess refuses, file by file, and passes nginx -t where a binary is set in SLAED_NGINX

  23. The probe servers serve public/ and run the real light path; the probes write no guards
  24. ui-contract, ui-audit and the pre-commit hook watch public/templates and public/plugins

Benefits:

  • No server rule is needed to keep config/, storage/ or a closed upload folder private
  • One sender and one list decide every upload address and its delivery; closing an owner is one line of the list
  • nginx gets a tested server block instead of rules copied from the documentation

Technical notes:

  • Breaking change: the document root of a site must point at public/, or the project-level .htaccess must rewrite into it on Apache or LiteSpeed; a server without .htaccess support needs nginx.conf.example

  • Upload addresses uploads/<folder>/<name> of public folders do not change; files of Node types have no direct address
  • NodeProfileTest fails 11 of 14 on the stand as on the clean HEAD before this change; the installer of the probe does not reach the database there

Refactor: Every Node type keeps its files in uploads/node/<type>, one function names the folder of an owner, and the files plan records its decisions and inventory
Автор: Eduard Laas | Дата: 18:06 05.10.2026

Batches 0 and 1 of docs/1-FILES-2026.md. Node types no longer share the upload root with the modules: they live below one root of their own, so a type can only meet another type there, and every builder of an upload path asks one function instead of spelling 'uploads/'.$mod. The plan carries the owner's decisions and the inventory of the stand database that the later batches rely on.

Core changes:

  1. One root for the types (core/system.php, core/classes/parser.php, modules/node/index.php, update.php):
  2. NODE_DIR is UPLOADS_DIR.'/node'; getUploadFolder($mod, $node) answers node/<type> for a type, the own name for a module

    • The flag names a type the registry does not carry yet or no longer, as type operations and update.php do
  3. getUploadRuleData(), getUploadPlaceRule() (store), getImgText(), Parser::filterAttach() and getNodeAssetPath() ask it
  4. Node service and locks (core/classes/node/service.php, core/classes/filemanager.php):
  5. setTypeRoot(), checkTypeGuard(), setTypeWrite(), updateNodeTypeStatus(), deleteNodeType(), checkNodeFiles(), setNodeWrite() and getNodeFile() build the type folder through getUploadFolder()

  6. checkNewName() drops its scan of the upload root; a module name and a key of config/uploads.php stay refused
  7. FileManager::getPathLock() takes uploads/node/<type> as the root of an upload area, so two types never wait for each other
  8. Administration (core/admin.php, admin/modules/uploads.php):
  9. getAdminUploadRule() reads the type out of a path below uploads/node and hands the owner on as mod
  10. getUploadsFolders() lists the folders of the upload root with the type folders below uploads/node

    • The default folder setting keeps an owner name, its label shows the path
  11. The tree and the documents (uploads/, UPGRADING.md, docs/, modules/node/admin/info/ru.md, admin/info/config/ru.md):
  12. uploads/{content,docs,faq,files,help,links,news} move to uploads/node/, which carries index.html and .htaccess
  13. UPGRADING.md gives the operator the folder move; NODE.md and the help name uploads/node/<type>
  14. docs/1-FILES-2026.md records the decisions of batches 0 and 1 and the inventory; docs/ROADMAP-2026.md ticks steps 2 and 3
  15. Tests and tools (tests/*, tools/node-profile.php, tools/upload-route-check.php):
  16. The probe routers follow the nginx rule below a folder of the upload root instead of one level only
  17. Route, node, install, upload and image probes build their type folders below uploads/node
  18. New: the folder of a type through every rule builder, two types as two lock areas, names a folder of the root carries

Benefits:

  • A type can no longer collide with a module folder, and the type check no longer scans the upload root
  • The place of the types is decided once, which batch 2 of 0-PRIVATE-DATA-2026.md needs to take uploads/node out of public/

Technical notes:

  • Breaking: a site whose type folders sit at uploads/<type>/ moves each to uploads/node/<type>/ before the new files serve
  • No public address changes: texts reach type files through op=attach and op=asset by name, no stored row carries the folder
  • NodeProfileTest fails 11 of 14 as on a clean HEAD (the installer copy never gets config/db.php); not caused by this change
Refactor: Every page is rendered live without the ready-page cache, no secret of a request reaches a journal, and the work before 8.0 runs from one roadmap
Автор: Eduard Laas | Дата: 15:25 05.10.2026

A load test showed the ready-page cache paying only on Node lists while its write guard, generations and signed markers touched every write; it leaves the system and the template, parser and data caches carry a page. Batch 1 of docs/0-PRIVATE-DATA-2026.md lands with it: a refused login no longer records the attempted password, and the request journal moves onto Logger, so its secrets are masked and cookies and the session leave only their names. The four plans before release 8.0 are numbered and ordered by docs/ROADMAP-2026.md.

Core changes:

  1. Ready-page cache removed (core/classes/cache.php, core/system.php, index.php, core/classes/node/*, admin/modules/config.php):
  2. Stored pages, their route contract, the signed dynamic markers of tokens, captcha and polls are gone

    • The write guard around content writes, the cache generation per database write and the Node list deadline go too
  3. One cache API: Cache::getFile(), Cache::deleteStale(), Cache::setHeaders() with none, private or public
  4. Styles and scripts are linked one file at a time; bundling, inlining, CSS compression, data URIs and go=asset are gone
  5. The category map is dropped by every writer of a category title, parent, order or icon
  6. Changelog entries and OAuth key sets live in the data cache; the cachegc job sweeps files older than a day
  7. Settings and schema (config/global.php, config/scheduler.php, update.php, storage/update/sql/*.sql):
  8. cache is the on/off switch of the parser cache; cache_b, cache_l, cache_t, cache_css, cache_script, css_c, css_e, css_h, script_h are gone
  9. The cachegc job is titled Cache cleanup; the dead index expires is dropped from the schema
  10. No secret reaches a journal (core/system.php, core/security.php, core/classes/logger.php, core/monitor.php):
  11. addLoginReport() loses its password parameter; its five call sites in admin/index.php and the account module follow

    • A full login journal is moved away before the file is opened, so the entry that triggers the rotation is kept
  12. addLog() and getVariablesInfo() are removed; the request journal is the Logger channel request, file request.log
  13. getSecurityEventHours() reads request.log; the label key log of the security section becomes request
  14. Presentation, panel and themes (modules/presentation/, plugins/presentation/, templates/, admin/, blocks/*):
  15. The request path of the presentation shows the parser cache, the compiled templates, the category map and the live page
  16. The message page draws its separator as markup; the settings, scheduler and security help follow the changes
  17. Tests, plans and reference (tests/, docs/, tools/*):
  18. JournalSecretTest with tests/Support/journal_probe.php: no password, cookie or session value in any journal, a refused login without the attempted string, the rotation entry in the new file, the dashboard on request.log

  19. CacheContractTest replaces PageCacheContractTest; the Node, rating, route and comment probes lose the page cache
  20. docs/ROADMAP-2026.md orders the plans 0-PRIVATE-DATA, 1-FILES, 2-PROD-FINDINGS and the new 3-ASSET-CACHE; docs/PAGE-CACHE-ROUTES-2026.md is closed and removed, its lasting part is in docs/VERSIONS.md

Benefits:

  • A journal is no longer a credential store travelling into backups and rotation archives
  • One definition of a secret, MASKKEYS of Logger, serves every structured journal
  • Content writes no longer pay for a cache that served only one kind of page

Technical notes:

  • Breaking: addLoginReport(int $id, int $typ, string $login); addLog() and getVariablesInfo() are gone
  • Breaking: the request journal is request.log with one JSON line per request instead of the text of log.log
  • Breaking: NodeException::BLOCKED, the quick-edit result blocked, getPageToken(), getPageCaptcha(), NodeQuery::getNodeDeadline() and setHead() with a closure are gone; Cache::getPath(), getHash(), getQueryVars(), setPrivateHeaders() and getAssetFiles() are replaced

  • The removed settings keys vanish on the next save of the settings form; no migration of existing journals
Эта неделя (04.10.2026)
Docs: The quick edit plan is closed and removed, its lasting part lives in the reference
Автор: Eduard Laas | Дата: 20:43 04.10.2026

All four batches of docs/QUICK-EDIT-2026.md have landed. The protocol, the stamp rule, the status table, the limits and how to add a kind are in docs/ARCHITECTURE.md ("Quick edit"); the Node writer and limits.edit in docs/NODE.md; the release note in docs/VERSIONS.md; the attachment check the forum quick edit still needs is carried by docs/FILES-2026.md, batch 4.

Core changes:

  1. Plan (docs/QUICK-EDIT-2026.md):
  2. Deleted; its final, audited version stays in the history of the previous commit

Technical notes:

  • Documentation only, no code change
Feature: One quick edit serves comments, forum posts and Node materials, keeps the typed text on every refusal and never overwrites a newer text silently
Автор: Eduard Laas | Дата: 20:36 04.10.2026

The two separate inline edits of comments and forum posts become one protocol, QuickEdit, with strict GET and POST routes, a stamp of the stored row and a fixed order under the lock of each kind: existence, the right, an equal text saved without a write, and only then a conflict. Node gains the quick edit of the intro and the body on the public page for its moderator and, inside limits.edit, for the signed-in author; editor assets load once per page, so a fragment no longer leaves the editor hidden or runs an engine twice.

Core changes:

  1. Protocol (core/classes/quick.php, core/system.php, index.php, templates/lite/fragments/quick-edit.html):
  2. QuickEdit: closed forms of kind, id, field and stamp, closed result codes, QuickEdit::getStamp() for texts without a version
  3. getQuickService() builds one adapter per kind; each source renders its editor with the literal store of its column
  4. getQuickEdit (GET) and updateQuickEdit (POST) check the method first, then the token from the X-CSRF-TOKEN header alone

    • 405 / 403 / 404 / 409 / 422 / 500 / 503 per outcome; a conflict answers the current text with its fresh stamp
    • A save answers the region with the edited mark out of band and a note as the event header sl-quick-note
  5. One fragment holds the form, the conflict answer and the always-printed mark wrapper
  6. Comments (core/classes/comment.php, core/user.php):
  7. Comment::updateComment() takes the stamp, decides existence, right, window, equality and stamp under the row lock
  8. setWriteBegin() answers blocked for a closed guard and storage for a failed BEGIN
  9. getCommentBody() renders the body and the mark for the page and the quick edit alike
  10. The route op=updateComment and its handler are gone
  11. Forum (core/user.php, modules/forum/index.php, index.php):
  12. updateForumBody() writes under the write guard: topic row, then post row, the place and the right read again

    • A topic closed or a post moved after the editor opened refuses the author; the page cache moves only after a write
  13. getForumSource() and getForumBody() serve the page and the quick edit
  14. updatePost(), its route, its epoch bump in the router and getTplAjaxTextarea() are gone
  15. Node (core/classes/node/.php, modules/node/, config/node.php, update.php):
  16. NodeService::updateNodeText() and getTextSource(): intro or body of a type without an extension

    • Moderator in every state; author of a pending or published material inside limits.edit from creation
    • An author edit of a published material goes back to Pending in the same write unless the author publishes directly
  17. NodeStatus gains Published -> Pending; NodeException gains BLOCKED (7, HTTP 503) for a closed write guard
  18. setNodeWrite() reports a closed guard as BLOCKED and moves no cache generation for a work that wrote nothing
  19. limits.edit (default 600, 0 off) on the limits tab; update.php adds it to an existing config/node.php
  20. The view partials wrap intro and body in regions; the public page offers the quick edit before the full editor
  21. A material the visitor may neither edit nor read answers 404, as Node answers a missing and a closed one alike
  22. Editor assets (core/classes/editor.php, plugins/editors/, plugins/system/.js, core/helpers.php):
  23. Editor::getAssetTags(): plain tags on a page load, the client loader SlaedEditors on an htmx fragment
  24. Editor::getInitScript(): the init waits for its engine, checks its node and registers its teardown
  25. setQuickEdit in slaed.js: Cancel without a request, Escape and Ctrl+Enter, the warning toast, the conflict question
  26. A region swapped away destroys its editors and clears both Toast UI registries
  27. Tests, language and help:
  28. QuickEditTest drives both routes over real HTTP for comments, forum posts and Node materials
  29. NodeServiceTest covers updateNodeText(); comment, forum and node tests follow the new contracts
  30. Seven site constants, _SAVEBUSY and the panel label _NODE_AEDIT in all six locales
  31. Help of comments, forum, Node, categories and settings; docs/ARCHITECTURE.md, NODE.md, VERSIONS.md, FILES-2026.md

Benefits:

  • A refusal or an expired session no longer swaps an alert over the typed text
  • Two editors of one item can no longer overwrite each other unnoticed; a repeated save writes nothing twice
  • One protocol, one fragment and one client handler instead of two inline paths and HTML built in PHP

Technical notes:

  • Breaking: Comment::updateComment(int $id, string $body, string $stamp) answers a result code
  • Breaking: NodeException::BLOCKED is new; setNodeWrite() reported a closed guard as STORAGE
  • New configuration key node.limits.edit; a limits section missing it makes every Node type invalid until update.php runs
  • No schema change
Эта неделя (02.10.2026)
Feature: Mailings carry a one-click unsubscribe, delivery reports are read from a bounce mailbox and counted, and undeliverable addresses get their own screen
Автор: Eduard Laas | Дата: 23:48 02.10.2026

Site mail is built for deliverability: every mailing carries a signed one-click unsubscribe (RFC 8058) in its body and headers, notices are marked auto-generated, and group and activity audiences keep to subscribers. Delivery reports are read over POP3 from a dedicated bounce mailbox in every maildrain run, so an address that no longer exists leaves mailings without any server setup. The registry of undeliverable addresses is written at last: its upsert repeated a placeholder that native prepares refuse, so it had never stored a single row.

Core changes:

  1. Unsubscribe (core/classes/mail.php, core/system.php, modules/account/index.php):
  2. getUnsubKey() signs the address with getSecret('unsub'); the drain appends the link of each recipient to the body

    • List-Unsubscribe, List-Unsubscribe-Post, List-Id in the site domain and Precedence: bulk on mailings
    • Auto-Submitted: auto-generated on every other message
  3. op=unsub of the account module: GET shows the question and a form, POST sets newslet = 0 for that address

    • The one-click POST of a mail provider carries no session; the signed key authorizes it instead of a token
    • The address is read raw, checked by the key and escaped on output
  4. Audiences (core/system.php, admin/modules/newsletter.php):
  5. group and active select only accounts with newslet = 1; all stays the forced send an administrator chooses
  6. The days field of the activity audience shows again, and an edited campaign keeps its audience and window

    • The option value, its count and the show rule are built from the same number of days
  7. Delivery reports and the registry (core/classes/mail.php, core/system.php, admin/modules/config.php):
  8. A bounce address goes into the envelope of every transport; From is unchanged
  9. Message-ID carries a signature bound to the recipient; addBounce() believes only a failed 5.x.x report quoting it

    • A report naming another address, a soft failure, a wrong signature or an auto-reply marks nobody
  10. updateBounce() reads up to 50 messages over POP3 (none, STARTTLS, SSL) in each maildrain run

    • Verdicts are written only after QUIT committed the deletions, so a broken session counts nothing twice
    • A mailbox that cannot be read is named in the job result and never stops delivery
  11. addDeadMail() names every placeholder once; getDeadList() and deleteDeadMail() serve the new screen
  12. The settings carry the bounce address and the POP3 host, port, encryption, user and password
  13. Admin screen (admin/modules/newsletter.php):
  14. New tab Undeliverable addresses: address, failures, code, date and a button to send to the address again
  15. Text part and parser (core/classes/mail.php, core/classes/parser.php):
  16. The plain-text part starts every list item on its own line with a dash
  17. A line opening with <br> no longer starts a raw HTML block, so Markdown after a list in plain-editor text is parsed
  18. The breaks format also recognizes <br/> and <br /> at a line end
  19. A blank configured sender name falls back to the site name
  20. Languages (lang/.php, modules/account/lang/.php, admin/lang/*.php):
  21. _MAIL_UNSUB; _ACCOUNT_UNSUBASK, _ACCOUNT_UNSUBBAD, _ACCOUNT_UNSUBOK
  22. _MAIL_BOUNCE, _MAIL_BOUNCEI, _MAIL_POP*, _MAIL_DEAD, _MAIL_FAILS, _MAIL_REVIVE
  23. Tests and docs (tests/, admin/info/, docs/PERFORMANCE.md, config/mail.php):
  24. A probe POP3 mailbox; the mail probe covers the envelope, signed ids, forged reports, the registry and POP3 runs
  25. Header, plain-text, config and parser fixture tests for every change above
  26. The newsletter and configuration help describe the unsubscribe, the bounce mailbox and the new tab

Benefits:

  • Mail providers offer their own unsubscribe button instead of the spam button
  • Dead mailboxes stop receiving mailings on any hosting, with nothing to configure on the server
  • The registry of undeliverable addresses finally records what it was built for

Technical notes:

  • No schema change; config/mail.php gains bounce, pophost, poppass, popport, popsecure and popuser
  • New route index.php?name=account&op=unsub, new admin ops dead and revive
  • Unsubscribe links and report signatures depend on a stable site secret in config/security.php
Feature: The installer plan closes with its tests and help, setup.php keeps its token in the session and only refuses an installed site, and site mail leaves as multipart with a site sender
Автор: Eduard Laas | Дата: 11:31 02.10.2026

The last two batches of the installer plan land: the probes walk the new setup.php end to end, the help moves into the permanent references and the plan file is deleted. The installer stops deleting itself on an installed site, which a development copy needs, and its CSRF token moves from storage/install.php into the session. Site mail is sent as multipart/alternative from the site address, with Date and Message-ID on every transport.

Core changes:

  1. Installer (setup.php, templates/admin/pages/setup.html, templates/admin/assets/css/theme.css):
  2. setSetupShut() answers an installed site with the refusal only: no form, no write and no delete

    • The installer deletes itself only on the closing stop of its own installation
    • A file that stays keeps the _DELSETUP warning of the panel
  3. The CSRF token is a random value in the session of the installing browser

    • storage/install.php, getSetupToken() and its two unlink() calls are gone
    • A token of another browser is refused like none
  4. Zip and Zlib are optional: a missing one is a warning row (is_warn, .sl-is-warn) that lets the server stop pass

    • mbstring, PDO MySQL and JSON still hold the stop
  5. Mail (core/classes/mail.php, core/system.php, core/user.php, modules/account, modules/forum, admin/modules/config.php):
  6. Every message is multipart/alternative: a plain-text part derived from the HTML, then the HTML part
  7. Date and Message-ID are written for every transport; X-Priority stays normal
  8. From is the configured identity, else the site address; a form visitor becomes Reply-To, never the sender
  9. getMailFrame() wraps a text into the plain-text mtemp frame; every caller goes through it
  10. addQueue() stores the body through getOutputHtml()
  11. Languages (admin/lang/*.php):
  12. _SETUP_NOOPT for a missing optional extension
  13. _SETUP_ZIP and _SETUP_ZLIB name the ZIP and GZ archives they serve
  14. Tests (tests/Support/, tests/Unit/):
  15. The install probe walks the seven stops over HTTP, checks the refusals with the own and a foreign token, and expects a shut installer to stay in place

  16. Mail tests cover the frame, the queued body format, the sender, Reply-To, Date and Message-ID
  17. Docs and housekeeping (docs/*, README.md, SECURITY.md, UPGRADING.md, CONTRIBUTING.md, .htaccess, robots.txt, admin/modules/editor.php, core/classes/filemanager.php, .gitignore, demo/*):

  18. docs/SETUP-2026.md is deleted; the installer lives in docs/ARCHITECTURE.md "Installation", the 6.3 update in docs/NODE.md "The 6.3 update"

  19. UPGRADING.md states that the release does not update a 6.2 site
  20. The setup/ directory rules and the setup.php entry of the critical files of the file manager are dropped

Benefits:

  • A development copy of an installed site keeps its installer
  • The installer writes nothing outside config/ before the run and leaves no token file behind
  • A server without Zip or Zlib installs
  • Site mail passes SPF and DMARC of the site domain and carries the headers filters score

Technical notes:

  • No schema change
  • storage/install.php is no longer written; an existing one is unused
  • An installed site with setup.php left in the root shows the panel warning until the file is deleted
Эта неделя (01.10.2026)
Fix: The sitemap lists only the forum categories and topics a guest may open, and the forum takes part in the map again
Автор: Eduard Laas | Дата: 23:44 01.10.2026

The XML sitemap listed every forum topic and category, including those whose read right is closed to guests, so the map advertised addresses a search engine could only answer with a refusal.

Core changes:

  1. Sitemap task (core/system.php, addSitemapTask()):
  2. A forum topic enters the map only when the read right of its category opens to a guest
  3. A forum category enters the map only when its view right opens to a guest
  4. The guest branch follows is_acess(): level 0, no group, and an empty right stays closed
  5. Configuration and output (config/sitemap.php, sitemap.xml):
  6. The modules of the map include forum
  7. sitemap.xml is generated again on this rule: 3385 addresses, 2221 of them in the forum

Benefits:

  • The map names only pages a crawler can read

Technical notes:

  • Node types keep their own sitemap integration, read as a guest of the site language
Docs: The Node help explains every screen of the materials section to the operator, with callouts for what is irreversible, required or unsafe
Автор: Eduard Laas | Дата: 23:43 01.10.2026

The help tab of the materials section grew from one page of notes into a full operator guide, written as the current state of the system and checked against modules/node/admin/index.php, the Node classes and docs/NODE.md.

Core changes:

  1. Help (modules/node/admin/info/ru.md):
  2. Terms: type, material, resource and its role, extension, profile
  3. The list: filters, the five states and the allowed moves, the trash, what a permanent deletion removes, the version check

  4. The material form: fields by the features of the type, deferred publication and the nodepublish job, editor attachments [attach=...], concurrent editing, reports on resources

  5. Types: life of a type, the nginx rule for uploads/<type>, records of removed sections, every setting of a type with tables of the seven display modes, the twelve features and the six display modes of a resource role

  6. The ten shipped types, the support extension (queue, working card, states, mail) and the sync extension (source, period, manual check, back-off after errors), the four limits with their defaults, the rights

  7. 14 callouts of the five kinds the parser knows; the nginx rule stands under its callout, because a fence inside a callout is dropped

Benefits:

  • An operator finds the answer on the tab instead of in the developer reference

Technical notes:

  • Russian only, as every help page of the panel; renders cleanly on the stand
Fix: One cron or pseudo-cron call runs every due job in priority order, so a job due every minute no longer keeps the jobs behind it waiting, and the scheduler help describes the scheduler as it is
Автор: Eduard Laas | Дата: 23:42 01.10.2026

A call of the scheduler endpoint ran only the first due job. nodepublish is due every minute, so on a site called once a minute the jobs further down the priority list hardly ever got a turn: on the stand monitor had not run for twenty days, nodesync never, and maildrain ran only now and then although all mail of the site goes through it.

Core changes:

  1. Runner (core/system.php):
  2. addSchedulerBatch() walks the jobs in priority order and runs each due one at most once

    • A job another process holds is passed over, the rest of the call still runs
    • No further job starts once the call has spent 60 per cent of max_execution_time, or 120 s without a limit
  3. Returns status done or idle with the list of jobs it ran
  4. Endpoint (index.php):
  5. A cron or pseudo call without job= runs addSchedulerBatch(); with job= it still runs that one job
  6. Tests (tests/Support/scheduler_probe.php, tests/Unit/SchedulerLockTest.php):
  7. oneCallRunsEveryDueJobOnce: two due jobs run in one call in priority order, a second call finds nothing, and a job held by a second process is passed over while the other one runs

  8. Help (admin/info/scheduler/ru.md):
  9. All nine system jobs with key, schedule and priority, including nodepublish, nodesync and monitor
  10. How a call runs, real cron each minute, the pseudo-cron and when it steps aside, the six top-level settings of config/scheduler.php, the form and its limits, the labels as the screen shows them

Benefits:

  • Every job runs on its own schedule
  • The work per unit of time is the configured one; the runner itself adds a few file reads per call

Technical notes:

  • Manual runs from the panel are unchanged
  • The JSON answer of a call without job= carries jobs[] instead of a single job key; nothing reads it

Страница 1 из 123. Всего: 1222

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

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

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