Skip to the content
Documentation

Help center

Help for Developers

Build on it: extensions, templates, settings, the APIs, the command line and upgrades.

5997 pages

Start here

Read these pages in this order.

  1. Develop with Git: grow from user to developer The recommended way to build websites with Exponential. Install the kernel and every se7enxweb extension as...
  2. Extension development: the book (start here) A complete book on growing from user to builder, extension developer and theme developer with Exponential:...
  3. Add a database table A migration that creates a table of the site's own on every engine from a share/db_schema.dba definition, w...
  4. AI, agents and agentic: start here The landing page for people who use AI with Exponential and for people who build agents and agentic workflo...
  5. Ecosystem: start here The landing page for the Exponential Ecosystem - the greater Exponential world within the PHP stack, its us...
  6. Integrators: start here The landing page for system integrators and integration developers who connect Exponential with CRM, ERP, P...

Good to know

  • Migrations

    The start of everything about migrations in Exponential 6.0.15 - schema and content changes written once as files under version control and applied to every installation of a site in the same order, with a caption…

  • Migrations: a first PHP migration, step by step

    In this tutorial you write two PHP migrations for a site: one creates a table exp_news_note with a first row, the other publishes a folder "News" below the content root and notes it in the table. You check them, look at…

  • Add a database table

    A migration that creates a table of the site's own on every engine from a share/db_schema.dba definition, writes a first row, and drops it again in down() - with the dry run, the run, the checks and the rollback.

  • Testing migrations: check, simulate, diff and CI

    Four layers of tests for migrations - the lint without a database, the dry run, the simulation with a diff on PostgreSQL or SQLite, and a PHPUnit test on a throwaway SQLite database - and how to run them in CI.

  • Deploying with migrations: CI/CD and GitHub Actions

    Run migrations as part of every deploy - the order of the steps, a complete GitHub Actions workflow that checks pull requests and deploys over SSH, the exit codes a pipeline acts on, the installation lock, and runs…

  • Team workflow with git: branches, conflicts and order

    How several developers write migrations on branches without stepping on each other - timestamps and order, requires for real dependencies, two migrations with the same timestamp, rebasing, renaming only before a merge…

Search by topic

Each button lists the pages of one topic for Developers.

What changed in the source code most recently: the main branch of se7enxweb/exponential, read from its public feed by this server.

Show merge commits too

  1. Updated: The generated help examples show the help's reading_key and … (opens in a new window) ·
    Message
    Updated: The generated help examples show the help's reading_key and report_links fetch functions and its ReportSecurityAnchor setting
    
    The reference examples below doc/eng-us/examples/ and their German pages below
    doc/ger-de/beispiele/ are generated again from the current sources with
    exp:help:examples, so they match what has landed:
    
    - the fetch functions exphelp/reading_key and exphelp/report_links get their
      pages, and the exphelp index counts seven functions;
    - exphelp.ini [ContextHelp] lists ReportSecurityAnchor, and the path rules of
      [AudienceSettings] and [CategorySettings] and the [TreeSettings] and
      [TypeSettings] entries follow the shipped file;
    - the German site.ini [DatabaseSettings] page lists the SQLite busy-wait and
      transaction-wait settings;
    - count_chars, extract_right, html_entity_decode and simplify quote their first
      use in a shipped template, now the help menu and the text part of form mail.
    
    doc/ger-de/.paths.json maps the two new German pages. exp:help:examples --check
    reports no difference for either language.
    ff3d9701b2
  2. Updated: A subtree copy re-points every link and embed of its XML tex… (opens in a new window) ·
    Message
    Updated: A subtree copy re-points every link and embed of its XML text at the copies, also those before a literal block
    
    The string scan of step 5 jumped past the next literal block before it looked for links, so every link and embed
    that came before a literal (code) block in the same text kept pointing at the original; it also took the next
    link before an earlier embed or object. A copy of 2,714 nodes left 730 node ids in 189 XML texts pointing at the
    originals.
    
    The XML text is now parsed as XML by expContentJobCopySubtree::remapXMLText(): node_id and object_id of link,
    embed, embed-inline and a, id of object, and href values eznode:// and ezobject:// are re-pointed wherever
    they are. Nothing inside a literal block is changed, ids outside the copied subtree stay, and a text with nothing
    to change is kept byte for byte. The content job "copy", content/copysubtree,
    eZContentObjectTreeNodeOperations::copySubtree() and bin/php/ezsubtreecopy.php all use it.
    
    Tests with an XML fixture cover links before, between and after literal blocks, several literal blocks, embeds,
    eznode:// and ezobject:// hrefs and ids outside the copy (no database).
    3c24718c25
  3. Updated: Session defaults in the documentation match site.ini (360 days) (opens in a new window) ·
    Message
    Updated: Session defaults in the documentation match site.ini (360 days)
    
    settings/site.ini ships SessionTimeout=31104000 and RememberMeTimeout=31104000
    (360 days, Remember me checked on the login forms by default), but the
    security hardening chapter (13.7) still listed SessionTimeout 259200 and an
    empty RememberMeTimeout, and some 25 help pages in English and German still
    said three days.
    
    - 13.7 lists both shipped values and what they mean; its HTTPS-only example
      shortens RememberMeTimeout together with SessionTimeout, as site.ini asks
      (SessionTimeout at least as long as RememberMeTimeout)
    - the CONFIGURING example no longer sets RememberMeTimeout above SessionTimeout
    - sign-in, retention, accessibility, hosting, trainer and developer pages
      state 360 days, in both languages
    3bc1631261
  4. Updated: Files of the file and media datatypes imported from a packag… (opens in a new window) ·
    Message
    Updated: Files of the file and media datatypes imported from a package get their key and, when the name is taken, their name from the secure random source
    
    The package key of a file is bin2hex( random_bytes( 16 ) ) and the name of an imported file whose own name is taken is eight characters of random_bytes(), instead of md5( mt_rand() ).
    9c43a8706d
  5. Updated: The 6.0.15 changelog describes the random sources of generat… (opens in a new window) ·
    Message
    Updated: The 6.0.15 changelog describes the random sources of generated passwords, keys and file names, Dependabot and CodeQL
    d70f257192
  6. Updated: The MongoDB adapter and its limits page say that code decidi… (opens in a new window) ·
    Message
    Updated: The MongoDB adapter and its limits page say that code deciding access reads an empty result of untranslated SQL as no
    
    The class docblock of expMongoDB also says why escapeString() returns the value unchanged: WHERE values become scalar comparisons, never query operators. English and German limits pages.
    24d7706bd5
  7. Added: Dependabot updates for Composer, npm and GitHub Actions, and a… (opens in a new window) ·
    Message
    Added: Dependabot updates for Composer, npm and GitHub Actions, and a CodeQL workflow for JavaScript and the workflows
    
    Weekly, grouped update pull requests (se7enxweb packages stay pinned by hand). CodeQL analyses the repository's own JavaScript and its workflows; bundled libraries and minified files are left out. CodeQL has no PHP analysis; PHPStan and the tests check the PHP code.
    9bf6c84f79
  8. Added: Tests that generated passwords, REST tokens, forgot-password k… (opens in a new window) ·
    Message
    Added: Tests that generated passwords, REST tokens, forgot-password keys and stored file names come from the secure random source
    
    expRandomSourcesTest (testsuite security, no database): the length, alphabet and uniqueness of eZUser::createPassword(), that a seed does not reproduce a password, that the generator uses random_int() only, 40-character REST tokens without repeats, and that the forgot-password key, the stored file names, the activation hash and the site installer's accounts use random_bytes().
    e4f8bf18c2
  9. Updated: Stored files, uploads and the Word extractor's temporary fil… (opens in a new window) ·
    Message
    Updated: Stored files, uploads and the Word extractor's temporary file are named from the cryptographically secure random source
    
    The file and media datatypes, eZHTTPFile::store() and the Word text
    extractor name their files with bin2hex( random_bytes( 16 ) ) instead of
    md5() of the time and mt_rand(). The names keep their form: 32 hex
    characters and the suffix.
    21afa48343
  10. Updated: Generated passwords, forgot-password keys and token manager … (opens in a new window) ·
    Message
    Updated: Generated passwords, forgot-password keys and token manager tokens come from the cryptographically secure random source
    
    eZUser::createPassword() draws every character of the password character
    table with random_int(); it built the password from md5() of the time and
    mt_rand(). Length and table stay the same; the $seed parameter is accepted
    and no longer used, so a password is never reproducible from it.
    
    The key of a forgot-password link is bin2hex( random_bytes( 16 ) ), 32
    characters as before, without the openssl_random_pseudo_bytes() call and
    its mt_rand() fallback.
    
    ezpRestTokenManager::generateToken() returns a token of
    ezpRestToken::generateToken() instead of the same value on every call.
    
    A user account the site installer creates for an ezuser attribute gets a
    random login, address and password instead of the password "publish".
    
    The file manifest carries the checksums of the files of this change and
    of the commits that follow it.
    ed71cdb9e2

Showing 31–40 of 40 commits

Recently updated

Free documentation: use it to help yourself and others

This help is free documentation, licensed under the GNU Free Documentation License 1.3 or later. You may use it, share it and improve it:

  • Study it Read any page as often as you like, for any purpose.
  • Copy it and share it Give pages to other users, on paper or as files. Keep the copyright notice, the license notice and a copy of the license with every copy.
  • Translate, adapt and improve it Share your version under the same license, with the original notices and a note of what you changed.
  • Cite it Refer to a page by its title and its address in the help, or its file in the doc directory.
  • Contribute fixes back Use "Edit on GitHub" on any page. Changes are accepted under the same license, so they stay free for everyone.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x