Help center

Path

7x / help / developers


Caution: This documentation is for Exponential, from version 3.x to 6.x.
For 5.x documentation covering Platform see Exponential Platform Documentation, for difference between legacy and Platform see 5.x Architecture overview.

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 documentation names expcomponents as the kernel's librar… (opens in a new window) ·
    Message
    Updated: The documentation names expcomponents as the kernel's libraries, in English and German
    
    Every page that described the Zeta Components as the kernel's current
    libraries now names expcomponents, the fork of them that the kernel
    requires since 6.0.15, and links to the new pages. Historical statements
    (eZ Components in 4.x, Zeta Components up to 6.0.14, the security pull
    requests of April 2026) stay in the past tense.
    
    - Installation: INSTALL.md, UPDATE.md, the introduction, requirements,
      getting the code, setup wizard, troubleshooting and migrating from 4.x
      chapters; the console upgrade guide says that the libraries stage swaps
      the packages
    - Standards: APIs and protocols name the fork packages for SMTP, REST,
      WebDAV and feeds; PHP and Composer says that Composer's class map, not
      ezcBase::autoload, loads the libraries
    - Licensing: the documentation license page, copyright and copyleft,
      third-party components, license compatibility, the licensing and
      bundler FAQs say that the libraries are Apache 2.0 and how that combines
      with the kernel's GPL version 2 or later (not legal advice)
    - Help center: the ecosystem pages, map and glossary, the hosting,
      integrator, PHP developer, trainer, project and contributing pages, who
      is 7x and who is the Exponential Foundation, the PHP developer and
      ecosystem FAQs
    - The glossary has the terms expcomponents, eZ Components and Zeta
      Components; the ezie page, the REST guide, the goals and the support
      page name the fork
    200d7edc15
  2. Added: Documentation of expcomponents, the fork of the Zeta Component… (opens in a new window) ·
    Message
    Added: Documentation of expcomponents, the fork of the Zeta Components the kernel requires, in English and German
    
    Exponential officially forks the Zeta Components under their Apache License
    2.0 as expcomponents (se7enxweb/expcomponents-) and modernizes them
    internally. Four new pages, each in English and German, describe the fork
    in detail:
    
    - The feature page Exponential Components (expcomponents): what the
      libraries are, their history from eZ Components (eZ Systems, New BSD)
      through Apache Zeta Components and Zeta Components (Apache 2.0), why they
      are forked, what stays the same (ezc* classes, APIs, license and
      notices), the package map with each fork's repository and its released
      or proposed version, Composer's replace, how Apache 2.0 combines with
      the kernel's GPL version 2 or later, where the repositories and packages
      are, releases, issues and the intent of the modernization
    - The upgrade notes The switch to expcomponents: who is affected, the
      composer.json before and after, the upgrade by console and by hand,
      projects and extensions that required zetacomponents/* themselves, the
      replace semantics, autoloading, verifying with composer show,
      troubleshooting and rollback
    - The specification The expcomponents packages: per library its purpose,
      the kernel classes, files and features that use it, the replaced
      package and the repository
    - The guide Contributing to expcomponents: clone, tests on every
      supported PHP version, the rules a change keeps, license headers and
      notices, commit messages, the ChangeLog, pull requests, releases and
      versions, syncing with upstream, security reports
    
    The feature, specification and guide indexes list the pages, the German
    path map knows them, and the 6.0.15 changelog has a section and item 30 of
    the upgrade checklist. Versions of forks that are not released yet are
    marked as proposed.
    a3f58e9c65
  3. Updated: The kernel requires Exponential's forks of every Zeta Compon… (opens in a new window) ·
    Message
    Updated: The kernel requires Exponential's forks of every Zeta Component it uses
    
    composer.json and composer.json.dist require the se7enxweb/expcomponents-*
    packages in place of the zetacomponents/* ones: authentication, base, cache,
    configuration, console-tools, database, debug, event-log, feed,
    image-conversion (with image-analysis), mail, mvc-tools, persistent-object,
    signal-slot and system-information, next to archive and webdav. Each fork
    replaces its upstream package, so nothing that requires an upstream name
    breaks, and keeps the ezc* class names and the API. The forks are maintained
    by 7x and the Exponential Foundation under the Apache License 2.0 and are
    tested on PHP 7.4 to 8.5.
    
    expComposerKernelRequirementsTest CR-03 and CR-04 check the fork names.
    The mail fork refuses an address with whitespace or < > , ; " before it
    writes a header: ezpMailMessageIdTest MI-04 checks the localhost Message-Id
    with a valid address whose domain is no host name, and MI-05 the refusal.
    c04189621f
  4. Updated: The tutorial Migrating URLs, the feature page and the URL ma… (opens in a new window) ·
    Message
    Updated: The tutorial Migrating URLs, the feature page and the URL map examples use the migration helpers
    
    The steps of a migration now use the helpers of the import instead of shell
    commands, in English and German:
    
    - Collecting the old addresses: exp:url:from-sitemap and exp:url:from-404, and
      the tabs From the old sitemap and From the 404 log of the import screen; the
      404 log gives paths only, as it hides the values of a query
    - Building the map: exp:url:suggest and the tab Suggest targets, with
      --fill-above and the other suggestions in the note
    - Testing: exp:url:test and Test the old addresses after an import, with the
      states it reports and its exit code
    - The feature page has a section on the helpers and their commands; the
      examples show how to test a file after an import
    - Changelog 6.0.15
    43304f1d6b
  5. Updated: exp:url:test follows a redirect whose answer it stops readin… (opens in a new window) ·
    Message
    Updated: exp:url:test follows a redirect whose answer it stops reading early
    
    The test asks for no body and stops each transfer at its first bytes; curl
    then leaves the redirect address empty, so every 301 and 302 was reported as
    "not redirected" (found on alpha with pages of its own sitemap that move). The
    Location header is now read as the answer arrives and used when curl has none.
    9d746b1336
  6. Added: URL map helpers as tabs of the import screen, and a test of th… (opens in a new window) ·
    Message
    Added: URL map helpers as tabs of the import screen, and a test of the old addresses after an import
    
    The import screen of the administration gets the helpers of the console, so
    a site can be moved without a shell.
    
    - content/urlimport/(source)/sitemap: the old site's addresses from its
      sitemap (an address of a public host only: every address of the host is
      checked and the connection is pinned to it, so nothing on the server's own
      network is fetched), or an uploaded sitemap or list; /(source)/404: this
      site's 404 log, by hits, within the last days; /(source)/suggest: a map
      whose rows lack a target
    - Each with the targets suggested and filled in from a score; the map is
      downloaded as CSV to complete in a spreadsheet, or opened as an import to
      preview (rows without a target are not importable there)
    - After an import, Test requests its old addresses (the first 500) on the
      site of its siteaccess (its SiteURL), follows the redirects and lists the
      rows that did not land; the result stays with the import
    - The tabs are links with the view parameter source; forms post, nothing
      is read from the query string. Shared components and tokens only, in the
      admin4 and admin designs
    - The strings in every administration catalogue
    - The BC note in English and German, the changelog, the generated page of
      the view
    - Tests: the form of a helper, the tab addresses, the site address of the
      test and the kept results of an import, without a database
    b30c01fa63
  7. Added: Documentation of the URL map helpers in the BC note, the chang… (opens in a new window) ·
    Message
    Added: Documentation of the URL map helpers in the BC note, the changelog and the generated command pages
    
    - The BC note "URL map import and export" has the section "Helpers for
      moving a site": what exp:url:from-sitemap, exp:url:suggest, exp:url:from-404
      and exp:url:test do, that the 404 source is the not-found log the kernel
      already writes (no new log or table), the limits of the requests, and the
      contract they follow; also in German
    - The changelog of 6.0.15 has the helpers and the PathPrefix fix of URL map
      targets
    - The generated pages of the four commands in English and German, the
      changed option help of the other exp:url commands, and the module view
      pages of the URL map screens generated again from their sources
    67868df148
  8. Added: URL map helpers: from an old sitemap, from the 404 log, sugges… (opens in a new window) ·
    Message
    Added: URL map helpers: from an old sitemap, from the 404 log, suggested targets, and a test against the site
    
    Four helpers around exp:url:import for moving a site: start a map from the old
    site's addresses, fill in the new ones, and check after the import that every
    old address lands where it should.
    
    - exp:url:from-sitemap and expUrlMapSitemapSource: a sitemap, a sitemap
      index with the sitemaps it names (relative ones too), gzip-compressed, or a
      crawl list with one address per line; only the sitemap's host unless
      --only-host or --any-host, every address once, --limit; XML read without
      the network and never with a DOCTYPE, malformed XML read for its 
      elements with a warning
    - exp:url:suggest and expUrlMapSuggester: for every row without a target,
      the visible pages of the siteaccess scored from 0 to 100 by their URL alias
      and name against the old address (decoded, camelCase split, transliterated,
      endings such as .html and index pages dropped, words that differ only in an
      ending count most of a match); --fill-above writes the best one into
      new_url (never a tie), the others go into the note or --report. Targets are
      written as visitors use them (without the PathPrefix). The pages are
      indexed once by word: 4,811 old addresses against 4,496 pages take seconds
    - exp:url:from-404 and expUrlMap404Source: the addresses of the not-found log
      (404.log and its rotated and gzip files) or of web server access logs, the
      most asked first, with --min-hits and --since; assets, bots and methods
      other than GET and HEAD left out; a query the log hides is dropped
    - exp:url:test and expUrlMapTester: every old address requested on --base,
      several at a time, the redirects followed hop by hop: landed, wrong-status
      (a permanent redirect where a temporary one is asked, or the other way),
      wrong-target, not-redirected, error (no answer, a loop, too many redirects);
      wildcards tested with a sample, node targets by the node's address, the
      PathPrefix taken as…
    c9118c9eeb
  9. Updated: Expiring the wildcard cache removes its index, so a new wild… (opens in a new window) ·
    Message
    Updated: Expiring the wildcard cache removes its index, so a new wildcard answers at once
    
    Expiring the wildcard cache only moved its expiry timestamp. An index
    built in the same second still counted as current, and a PHP-FPM worker
    whose OPcache held the previous expiry.php kept the old index for up to
    opcache.revalidate_freq seconds: right after an import made in the
    administration, a new wildcard answered 404 for a while. The index file
    is now removed as well, as the cache of the redirects already is, and
    the next request builds it again.
    7caccc0a69
  10. Updated: A wildcard or redirect added or removed answers at once inst… (opens in a new window) ·
    Message
    Updated: A wildcard or redirect added or removed answers at once instead of after a minute
    
    The wildcard cache and the cache of the redirects are PHP files written
    again under the same name. OPcache kept serving the old copy until
    opcache.revalidate_freq passed (60 seconds on alpha's PHP-FPM), so right
    after an import, an undo or a wildcard made by hand the old addresses
    still answered as before for up to a minute. Reading either cache now
    drops the cached copy when the file is newer than it (one stat per
    request, nothing when OPcache is off).
    9ce358c12c

Showing 11–20 of 46 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