PHPackages                             se7enxweb/sevenx\_exponential\_platform\_v5\_database\_translator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. se7enxweb/sevenx\_exponential\_platform\_v5\_database\_translator

ActiveEzpublish-legacy-extension[Database &amp; ORM](/categories/database)

se7enxweb/sevenx\_exponential\_platform\_v5\_database\_translator
=================================================================

7x Exponential Platform v5 Database Translator is an Exponenital Platform Legacy Extension which provides for dynamic sql query drivers which translate all queries and results ensuring compatiblity is retained between the two cms/dxp software stacks. Required to use Exponential 6.x (Legacy) within Exponential Platform v5 due to DXP Internal API Changes. This provides for pain free use of all of legacy within a symfony platform v5 database. Supports MySQL, SQLite, PostgreSQL. Great for all developers!

261

Since Apr 18Compare

[ Source](https://github.com/se7enxweb/sevenx_exponential_platform_v5_database_translator)[ Packagist](https://packagist.org/packages/se7enxweb/sevenx_exponential_platform_v5_database_translator)[ RSS](/packages/se7enxweb-sevenx-exponential-platform-v5-database-translator/feed)WikiDiscussions Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (1)

sevenx\_exponential\_platform\_v5\_database\_translator
=======================================================

[](#sevenx_exponential_platform_v5_database_translator)

An eZ Publish Legacy extension that makes a **fully unmodified eZ Publish Legacy kernel** operate transparently on top of an **Ibexa DXP 5.0+ database schema** — the database whose tables are named `ibexa_*` rather than the legacy `ez*`, `ezcobj_*`, `ezcontentobject_*` prefixes.

It works by subclassing the three concrete DB handler classes (`eZMySQLiDB`, `eZSQLite3DB`, and `eZPostgreSQLDB`) and intercepting every SQL statement and every result row at the lowest possible layer, rewriting legacy names outbound and Ibexa names inbound, so the thousands of `SELECT … FROM ezcontentobject …` queries inside the legacy kernel never need to be touched.

---

Directory layout
----------------

[](#directory-layout)

```
sevenx_exponential_platform_v5_database_translator/
├── README.md                        ← you are here
├── doc/
│   └── THEORY.md                    ← deep technical theory and design rationale
├── extension.xml                    ← extension metadata (no dependencies)
├── autoloads/
│   └── ezp_extension.php            ← eZ Publish class autoload map
├── settings/
│   └── site.ini.append.php          ← DatabaseSettings.ImplementationAlias overrides
└── classes/
    ├── sql_rewriter.php             ← QueryTranslatorSQLRewriter (shared rewriter + row remapper)
    ├── driver_mysqli.php            ← QueryTranslatorDriverMySQLiDB
    ├── driver_sqlite3.php           ← QueryTranslatorDriverSQLite3DB
    └── driver_postgresql.php        ← QueryTranslatorDriverPostgreSQLDB

```

---

What the extension does
-----------------------

[](#what-the-extension-does)

### The problem in one sentence

[](#the-problem-in-one-sentence)

The Ibexa DXP 5.0 upgrade renamed every database table from the legacy `ez*`naming convention to an `ibexa_*` convention (e.g. `ezcontentobject` → `ibexa_content`, `ezcontentclass` → `ibexa_content_type`). A large number of column names changed too (`contentclass_id` → `content_type_id`, `version` → `status` in some tables, etc.). The legacy PHP kernel still generates SQL using the old names. Running the legacy kernel against an Ibexa 5.0 database fails with `table not found` errors on the very first query.

### The solution in one sentence

[](#the-solution-in-one-sentence)

Intercept every SQL query just before it hits the wire and every result row just after it comes back from the wire — rewriting legacy names outbound and Ibexa names inbound — so neither the legacy kernel nor the Ibexa application sees anything unexpected.

---

How activation works
--------------------

[](#how-activation-works)

eZ Publish Legacy's database layer uses a factory pattern keyed by the `DatabaseSettings.ImplementationAlias` INI setting. When the kernel calls `eZDB::instance()` it reads this alias to determine which PHP class to instantiate as the DB handler. By overriding those aliases to point at our subclasses, we drop our translation layer into the execution path with zero modifications to the kernel.

The override is set in `settings/site.ini.append.php` (shipped with this extension and loaded automatically by the legacy INI system because the extension is in `ActiveExtensions`):

```
[DatabaseSettings]
ImplementationAlias[ezmysqli]=QueryTranslatorDriverMySQLiDB
ImplementationAlias[ezmysql]=QueryTranslatorDriverMySQLiDB
ImplementationAlias[mysql]=QueryTranslatorDriverMySQLiDB
ImplementationAlias[mysqli]=QueryTranslatorDriverMySQLiDB
ImplementationAlias[sqlite3]=QueryTranslatorDriverSQLite3DB
ImplementationAlias[ezpostgresql]=QueryTranslatorDriverPostgreSQLDB
ImplementationAlias[postgres]=QueryTranslatorDriverPostgreSQLDB
ImplementationAlias[postgresql]=QueryTranslatorDriverPostgreSQLDB
ImplementationAlias[pgsql]=QueryTranslatorDriverPostgreSQLDB
```

This covers `MySQLi` (production), `SQLite3` (development/testing), and `PostgreSQL`.

---

PHP classes
-----------

[](#php-classes)

### `QueryTranslatorSQLRewriter` — `classes/sql_rewriter.php`

[](#querytranslatorsqlrewriter--classessql_rewriterphp)

A pure static helper class shared by all three driver overrides. It holds the translation maps and exposes two public methods:

#### `rewriteSQL( string $sql ): string`

[](#rewritesql-string-sql--string)

Runs five passes over the SQL string in order:

PassWhat it doesTechnique1Table name rewriting (`ezcontentobject` → `ibexa_content`, etc.)`preg_replace_callback` with `\b` word boundaries, longest-match sorted alternation2Safe global column renames (`contentclass_id` → `content_type_id`, `contentclassattribute_id` → `content_type_field_definition_id`, `contentclass_version` → `content_type_status`)Same regex approach3Table-qualified `version` renames for mixed-table queries (`ibexa_content_type.version` → `ibexa_content_type.status`, `ibexa_content_type_field_definition.version` → `.status`, etc.)`str_ireplace` on fully-qualified `table.column` strings4Context-aware unqualified `\bversion\b` → `status` rename, only when SQL references a content-type table but not any version-number table`preg_replace` guarded by `stripos` checks5Datatype identifier value rewrites (`'ezstring'` → `'ibexa_string'` in quoted SQL literals) so `WHERE data_type_string = 'ezstring'` still finds the right rows`str_ireplace` on `'ezXxx'` quoted literals#### `remapResultRow( array $row ): array`

[](#remapresultrow-array-row--array)

Reverse-maps column names in a result row returned by `arrayQuery()`. Because the legacy kernel often uses `SELECT *` and then reads result array keys by the old column names, we must add the legacy key as an alias alongside the new key rather than replacing it. It also reverses the datatype identifier values in the `data_type_string` column so the legacy kernel's datatype registry (which looks up files like `ezstring.php`) can find the right class.

### `QueryTranslatorDriverMySQLiDB extends eZMySQLiDB` — `classes/driver_mysqli.php`

[](#querytranslatordrivermysqlidb-extends-ezmysqlidb--classesdriver_mysqliphp)

Overrides:

- `query()` — rewrites SQL before executing any statement (INSERT, UPDATE, DELETE, SELECT).
- `arrayQuery()` — rewrites SQL **and** remaps result rows. Although `eZMySQLiDB::arrayQuery()` delegates to `$this->query()` internally (so SQL is already rewritten), the result-row remapping must still happen here because `query()` returns a raw result resource, not an array.

### `QueryTranslatorDriverSQLite3DB extends eZSQLite3DB` — `classes/driver_sqlite3.php`

[](#querytranslatordriversqlite3db-extends-ezsqlite3db--classesdriver_sqlite3php)

Overrides both `query()` and `arrayQuery()`. Unlike MySQL, `eZSQLite3DB::arrayQuery()`calls `$this->DBConnection->query()` **directly** on the underlying `SQLite3` object, completely bypassing `$this->query()`. If we only override `query()`, all SELECT reads go through the raw SQLite3 connection unmodified with untranslated SQL. Both methods must be overridden independently. See `doc/THEORY.md §5`.

### `QueryTranslatorDriverPostgreSQLDB extends eZPostgreSQLDB` — `classes/driver_postgresql.php`

[](#querytranslatordriverpostgresqldb-extends-ezpostgresqldb--classesdriver_postgresqlphp)

Overrides:

- `query()` — rewrites SQL before executing any statement.
- `arrayQuery()` — remaps result row column names. `eZPostgreSQLDB::arrayQuery()`calls `$this->query()` internally (same pattern as MySQL), so SQL is already rewritten there; `arrayQuery()` is overridden only for result-row remapping.

---

Translation maps
----------------

[](#translation-maps)

### Table map (excerpt)

[](#table-map-excerpt)

Legacy nameIbexa DXP 5.0 name`ezcontentobject``ibexa_content``ezcontentobject_version``ibexa_content_version``ezcontentobject_attribute``ibexa_content_field``ezcontentclass``ibexa_content_type``ezcontentclass_attribute``ibexa_content_type_field_definition``ezcontentclassgroup``ibexa_content_type_group``ezcontentclass_classgroup``ibexa_content_type_group_assignment``ezpolicy``ibexa_policy``ezpolicy_limitation``ibexa_policy_limitation``ezpolicy_limitation_value``ibexa_policy_limitation_value``ezrole``ibexa_role``ezuser``ibexa_user``ezuser_role``ibexa_user_role``ezcobj_state``ibexa_object_state``ezcobj_state_group``ibexa_object_state_group``ezurlalias_ml``ibexa_url_alias_ml``eznode_assignment``ibexa_node_assignment``ezsection``ibexa_section``ezdfsfile``ibexa_dfs_file``ezpreferences``ibexa_user_preference``ezcontentbrowsebookmark``ibexa_content_bookmark`Full list in `classes/sql_rewriter.php` → `QueryTranslatorSQLRewriter::$tableMap`.

### Column map

[](#column-map)

Legacy columnIbexa DXP 5.0 column`contentclass_id``content_type_id``contentclassattribute_id``content_type_field_definition_id``contentclass_version``content_type_status``version` *(in content-type tables only)*`status`### Datatype identifier map (excerpt)

[](#datatype-identifier-map-excerpt)

Legacy valueIbexa DXP 5.0 value`ezstring``ibexa_string``ezrichtext``ibexa_richtext``ezinteger``ibexa_integer``ezimage``ibexa_image``ezbinaryfile``ibexa_binaryfile``ezgmaplocation``ibexa_gmap_location``ezobjectrelationlist``ibexa_object_relation_list`---

Activation in `site.ini.append.php` override files
--------------------------------------------------

[](#activation-in-siteiniappendphp-override-files)

The legacy kernel loads INI files in priority order. The extension's own `settings/site.ini.append.php` sets the `ImplementationAlias` entries. The site-level override file(s) must list this extension in `ActiveExtensions` **before**any extension that uses the database, so the subclasses are registered before any `eZDB::instance()` call fires.

`src/LegacySettings/override/site.ini.append.php` (site-level override):

```
[ExtensionSettings]
ActiveExtensions[]
ActiveExtensions[]=sevenx_exponential_platform_v5_database_translator
ActiveExtensions[]=app
ActiveExtensions[]=ngsite
...
```

The extension must be **first** in `ActiveExtensions` for the alias override to take effect before any other extension (such as `ngsymfonytools`) opens a DB connection.

---

Symlink setup
-------------

[](#symlink-setup)

The extension lives in the Symfony project's `src/` tree (so it is tracked in the project's git repository and deployed alongside application code):

```
src/ezpublish_legacy/sevenx_exponential_platform_v5_database_translator/

```

The eZ Publish Legacy kernel discovers extensions only from its own `extension/`directory. A symlink bridges the gap:

```
ezpublish_legacy/extension/sevenx_exponential_platform_v5_database_translator
  → ../../src/ezpublish_legacy/sevenx_exponential_platform_v5_database_translator

```

To recreate the symlink after a fresh checkout:

```
ln -s ../../src/ezpublish_legacy/sevenx_exponential_platform_v5_database_translator \
      ezpublish_legacy/extension/sevenx_exponential_platform_v5_database_translator
```

---

Supported databases
-------------------

[](#supported-databases)

Driver aliasClass activatedFile`ezmysqli`, `ezmysql`, `mysql`, `mysqli``QueryTranslatorDriverMySQLiDB``classes/driver_mysqli.php``sqlite3``QueryTranslatorDriverSQLite3DB``classes/driver_sqlite3.php``ezpostgresql`, `postgres`, `postgresql`, `pgsql``QueryTranslatorDriverPostgreSQLDB``classes/driver_postgresql.php`---

See also
--------

[](#see-also)

- `doc/THEORY.md` — deep technical theory, design decisions, edge cases, and a worked example tracing a query end-to-end through the translation pipeline.
- `autoloads/ezp_extension.php` — eZ Publish class autoload map; maps each class name to its file path for the eZ Publish Legacy autoloader.
- `vendor/ibexa/installer/upgrade/db/mysql/ibexa-4.6.latest-to-5.0.0.sql` — the upstream migration script that defines the authoritative table rename mapping.
- `vendor/se7enxweb/exponential-platform-legacy/lib/ezdb/classes/ezsqlite3db.php` — the patched SQLite3 DB handler (adds `mkdir` recursive flag for DB directory creation) that `QueryTranslatorDriverSQLite3DB` subclasses.
- `vendor/se7enxweb/exponential-platform-legacy/lib/ezdb/classes/ezmysqlidb.php` — the MySQLi DB handler that `QueryTranslatorDriverMySQLiDB` subclasses.
- `vendor/se7enxweb/exponential-platform-legacy/lib/ezdb/classes/ezpostgresqldb.php` — the PostgreSQL DB handler that `QueryTranslatorDriverPostgreSQLDB` subclasses.

---

COPYRIGHT
---------

[](#copyright)

Copyright (C) 1998 - 2026 7x (formerly Brookins Consulting). All rights reserved.

LICENSE
-------

[](#license)

This source code is available separately under the following license:

GNU General Public License, version 2 Grants an copyleft open source license with ABSOLUTELY NO WARRANTY. For the full GPL license text, please see:

---

Copyright © 1998 – 2026 7x (se7enx.com). All rights reserved unless otherwise noted. Exponential Platform Legacy is Open Source software released under the GNU GPL v2 or any later version.

###  Health Score

11

—

LowBetter than 0% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1083669?v=4)[7x](/maintainers/7x)[@7x](https://github.com/7x)

### Embed Badge

![Health badge](/badges/se7enxweb-sevenx-exponential-platform-v5-database-translator/health.svg)

```
[![Health](https://phpackages.com/badges/se7enxweb-sevenx-exponential-platform-v5-database-translator/health.svg)](https://phpackages.com/packages/se7enxweb-sevenx-exponential-platform-v5-database-translator)
```

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k117.2M118](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[jfelder/oracledb

Oracle DB driver for Laravel

11518.4k](/packages/jfelder-oracledb)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
