Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ MODX 3 brings PHP Namespaces to your XML Schema and class files, and a new boots

**NOTE**: This was converted from the previous "StoreFinder" example.

**ALSO NOTE**: This methodology is not backwards compatible to MODX 2.x. This tutorial is intended to be run and used in MODX 3. You can see the equivalent guide for 2.x here: [Using Custom Database Tables](/2.x/en/extending-modx/tutorials/using-custom-database-tables "Using Custom Database Tables")
**ALSO NOTE**: This methodology is not backwards compatible to MODX 2.x. This tutorial is intended to be run and used in MODX 3. You can see the equivalent guide for 2.x here: [Using Custom Database Tables](/2.x/en/extending-modx/tutorials/using-custom-database-tables "Using Custom Database Tables"). For a shorter upgrade checklist (Composer, `metadata.mysql.php`, `instanceof`, `addPackage`), see [xPDO 3](getting-started/upgrading-to-3.0/xpdo).

## Key Terminology and Standards

Expand Down
8 changes: 4 additions & 4 deletions en/extending-modx/xpdo/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ note: "This page is a stub. You can help by expanding it."

xPDO is the object-relational-bridge that is built into MODX. Simply put, it's how MODX connects to the database, and how it interacts with different tables.

In MODX 2.x, the `modX` class directly extends `xPDO`. While in hindsight that's not the best development pattern, it does mean that whenever you have access to the `modX` instance, you can use any of the `xPDO` methods on it as well.
In MODX 2.x and 3.x, the `modX` class extends `xPDO`, so any time you have the `modX` instance you can call xPDO methods on it. In MODX 3 that parent is the namespaced `xPDO\xPDO` class loaded through Composer. For upgrade and Extra migration details, see [xPDO 3](getting-started/upgrading-to-3.0/xpdo).

## What is xPDO?

Expand All @@ -17,10 +17,10 @@ xPDO is our name for open eXtensions to PDO. It's a light-weight ORB (object-rel

In the context of xPDO, the following terms are important to know:

- **Packages** are collections of models. In the MODX core, all models are part of the `modx` package, plus there are a few sub-packages like `modx.media` and `modx.package`. To make xPDO aware of the models in a package, it needs to be registered with `$xpdo->addPackage()`.
- **Packages** are collections of models. In the MODX 3 core, models live under namespaces such as `MODX\Revolution` (plus sub-packages like Sources and Transport). Register a package with `$xpdo->addPackage()` (and a `$namespacePrefix` when you use PSR-4).
- **Models** are classes that represent a specific database table. They are the abstraction you will use most often; rather than interacting with SQL directly, you load a model, adjust its properties, and save it.
- **Schemas** are XML files that define the different models that are available in a package, and what their fields (properties) are. They are used only in development, during which they will be processed (typically called being "built") into the model classes and maps.
- **Maps** are PHP files containing arrays that define the metadata for packages and schemas. They are in the database driver-specific model directory (e.g. `model/modx/mysql/modresource.map.inc.php`). These files are not typically managed manually, instead they are generated from a schema file.
- **Schemas** are XML files that define the different models that are available in a package, and what their fields (properties) are. They are used only in development, during which they will be processed (typically called being "built") into the model classes and maps. In MODX 3 set `version="3.0"` and put the PHP namespace in the `package` attribute.
- **Maps** are PHP metadata for packages and schemas. In MODX 3 / xPDO 3 a package ships `metadata.{dbtype}.php` (with a `class_map`) plus platform files under a driver folder (for example `mysql/`). Older 2.x docs often show only `*.map.inc.php` files; regenerate with schema `version="3.0"` when you target MODX 3.

There are a lot more things to learn about xPDO, but if you understand these 4 you have a solid foundation to make sense of the rest of the documentation.

Expand Down
1 change: 1 addition & 0 deletions en/getting-started/upgrading-to-3.0/breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The biggest breaking changes can be summarised as follows:
- [It's no longer possible to use a custom core folder/path](getting-started/upgrading-to-3.0/core-folder)
- [sqlsrv support has been removed](getting-started/upgrading-to-3.0/sqlsrv)
- [A large number of (previously unnamespaced) classes have been renamed and moved](getting-started/upgrading-to-3.0/class-names), including processors and model classes.
- [xPDO 3 ships via Composer with PSR-4 models; migrate custom packages](getting-started/upgrading-to-3.0/xpdo)
- [All processors have been renamed, including base processors](getting-started/upgrading-to-3.0/processors)
- [modAction and related functionality has been removed](getting-started/upgrading-to-3.0/actions)
- modRestClient has been removed [#15781](https://github.com/modxcms/revolution/pull/15781) and has been [replaced with a new PSR-7/17/18 HTTP service](extending-modx/services/http)
Expand Down
2 changes: 2 additions & 0 deletions en/getting-started/upgrading-to-3.0/class-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ This layer of backwards compatibility is likely to be fully removed in MODX 4.0.
| \xPDO\Transport\xPDOTransport | \xPDOTransport |
| \xPDO\Transport\xPDOObjectVehicle | \xPDOObjectVehicle |

How Composer, PSR-4, `metadata.mysql.php`, and Extra `addPackage` calls fit together: [xPDO 3](getting-started/upgrading-to-3.0/xpdo).

### MODX Core & Controllers

| New Class | Old Class |
Expand Down
1 change: 1 addition & 0 deletions en/getting-started/upgrading-to-3.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ After upgrading the core and upgrading your extras, you may encounter some break
- ⚠️ Important: [MODX 3.0 required PHP 7.2; current 3.x (3.2+) requires PHP 8.1+](getting-started/upgrading-to-3.0/requirements)
- ⚠️ Important: [sqlsrv support has been removed](getting-started/upgrading-to-3.0/sqlsrv)
- [A list of breaking changes can be found here](getting-started/upgrading-to-3.0/breaking-changes), most notably [many core classes have been moved and renamed](getting-started/upgrading-to-3.0/class-names)
- [xPDO 3, Composer, and migrating custom models](getting-started/upgrading-to-3.0/xpdo)
- [The manager language is now dynamic](getting-started/upgrading-to-3.0/manager-language)
- [Various system settings have been removed or changed](getting-started/upgrading-to-3.0/system-settings)

Expand Down
149 changes: 149 additions & 0 deletions en/getting-started/upgrading-to-3.0/xpdo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
title: "xPDO 3"
description: "Composer, PSR-4, and migrating custom models from MODX 2.x to MODX 3 / xPDO 3."
sortorder: 5
---

MODX 3 ships **xPDO 3** under `core/vendor/xpdo/` (Composer package `xpdo/xpdo`). The library no longer lives as loose files under `core/xpdo/`. Model classes use PHP namespaces and PSR-4 autoloading.

This page is the upgrade-oriented reference. For a full walkthrough that builds a new Extra from scratch, use [Using Custom Database Tables](extending-modx/tutorials/using-custom-database-tables). For API methods, start at [xPDO](extending-modx/xpdo).

## What changed for you

| Topic | MODX 2 / xPDO 2 | MODX 3 / xPDO 3 |
| --- | --- | --- |
| Where xPDO lives | `core/xpdo/` | `core/vendor/xpdo/` (bundled with the release) |
| Autoload | MODX / xPDO class loaders | Composer `autoload.php` + PSR-4 |
| Core models | `core/model/modx/*.class.php` | `core/src/Revolution/` under `MODX\Revolution\` |
| Schema `package` | Short package folder name (`modx`) | PHP namespace (`MODX\Revolution\`) |
| Base classes | `xPDOObject`, `xPDOSimpleObject` | `xPDO\Om\xPDOObject`, `xPDO\Om\xPDOSimpleObject` |
| Package metadata | `metadata.mysql.php` plus per-class maps under `mysql/` (schema `version` 1.x) | Same filename, but schema `version="3.0"` metadata with `namespace`, `namespacePrefix`, and a `class_map` for PSR-4 |
| `addPackage` | Path + package folder | Path + namespaced package + optional `$namespacePrefix` |

`modX` still extends `xPDO\xPDO`, so `$modx->getObject()`, `newQuery()`, and friends stay on the main MODX instance.

## Vendor layout and PSR-4

A normal download or Package Manager upgrade already includes `core/vendor/` and `core/vendor/autoload.php`. You do **not** need a project-level `composer.json` or a manual `composer install` to get xPDO 3. Setup and front controllers load that bundled autoloader. You do not `require` individual xPDO class files.

Composer matters if you develop from a Git checkout of Revolution, rebuild core models, or ship an Extra that manages its own Composer dependencies. Those workflows use the release `composer.json` (or the Extra’s) and write libraries into `core/vendor/`.

MODX core code maps through Composer as well (`"MODX\\": "core/src/"`). That is why the [core folder must stay at `/core/`](getting-started/upgrading-to-3.0/core-folder) in the project root.

## Core model layout

Schemas still live under `core/model/schema/` (for example `modx.mysql.schema.xml`). Generated classes and maps go to `core/src/`:

- Class: `core/src/Revolution/modResource.php` → `MODX\Revolution\modResource`
- Package metadata: `core/src/Revolution/metadata.mysql.php`
- Platform maps: `core/src/Revolution/mysql/*.php`

Core rebuild (Git / contributor workflow):

```bash
composer run-script parse-schema
```

That runs `core/vendor/bin/xpdo parse-schema` with `--psr4=MODX\\` into `core/src/`. Details: [Building model/schema](contribute/code/tooling/model).

## Loading an Extra package

Register a namespaced model from a component bootstrap (paths vary; `$namespace['path']` is the Extra core path):

```php
$modx->addPackage(
'ToDo\\Model',
$namespace['path'] . 'src/',
null,
'ToDo\\'
);
```

- First argument: PHP package / namespace segment that holds `metadata.{dbtype}.php`.
- Second: filesystem root for that PSR-4 prefix (often `.../src/`).
- Third: table prefix override, or `null` to use the site prefix.
- Fourth: `$namespacePrefix` so xPDO registers PSR-4 correctly when the package path is nested under that prefix.

After `addPackage` succeeds, use FQCNs:

```php
$item = $modx->newObject(\ToDo\Model\Task::class);
$item = $modx->getObject(\ToDo\Model\Task::class, $id);
```

See [xPDO.addPackage](extending-modx/xpdo/class-reference/xpdo/xpdo.addpackage) for prefix pitfalls.

## Schema and generated files

Minimal MODX 3 schema shape:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<model package="ToDo\Model" baseClass="xPDO\Om\xPDOObject" platform="mysql"
defaultEngine="InnoDB" version="3.0">
<object class="Task" table="todo_task" extends="xPDO\Om\xPDOSimpleObject">
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
</object>
</model>
```

Generate classes with your build script or the xPDO CLI (`core/vendor/bin/xpdo parse-schema ...`). Expect:

- `src/Model/Task.php` with `namespace ToDo\Model;`
- `src/Model/metadata.mysql.php` (`version` ≥ `3.0`, `namespace`, `namespacePrefix`, `class_map`)
- `src/Model/mysql/Task.php` (platform map)

MODX 2.x Extras already shipped a `metadata.mysql.php`. For MODX 3 regenerate it from a `version="3.0"` schema so it includes the namespace fields and `class_map`. A 2.x metadata file (or a layout that never got a 3.0 metadata rebuild) will not register PSR-4 the same way and can log a package metadata warning.

## Migrating a 2.x Extra model

Work through this checklist for each custom package:

1. **Move classes** into a `src/` tree that mirrors the PHP namespace (`MyExtra\Model\...`).
2. **Rewrite the schema**: set `package` to the PHP namespace, `version="3.0"`, and namespaced `extends` / relation `class` values (`xPDO\Om\...`, `MODX\Revolution\...` when you relate to core objects).
3. **Regenerate** maps and classes. Commit `metadata.mysql.php` and the `mysql/` maps your generator writes.
4. **Update `addPackage`** to the four-argument (or namespaced) form and load it from [`bootstrap.php`](extending-modx/namespaces) when the Extra boots.
5. **Replace string class keys** in PHP with `::class` or FQCNs in `getObject`, `newObject`, `newQuery`, processors, and vehicle attributes.
6. **Fix `instanceof` and type hints** to the namespaced classes. Short names like `modResource` or your old `MyObject` are not real PHP classes in 3.x.
7. **Drop** `require`/`include` of `xpdo.class.php` or per-class model files. Rely on the bundled vendor autoloader + `addPackage`.

### Before / after (core object)

```php
// MODX 2.x
$resource = $modx->getObject('modResource', $id);
if ($resource instanceof modResource) { /* ... */ }

// MODX 3.x
use MODX\Revolution\modResource;

$resource = $modx->getObject(modResource::class, $id);
if ($resource instanceof modResource) { /* ... */ }
```

`$modx->getObject('modResource', $id)` may still resolve through `loadClass` translation and log a deprecation. Prefer the namespaced form. `instanceof modResource` against the old global name is always false. Full alias table: [Changed Class Names](getting-started/upgrading-to-3.0/class-names).

### Before / after (custom package)

```php
// MODX 2.x
$modx->addPackage('myextra', MODX_CORE_PATH . 'components/myextra/model/');
$row = $modx->getObject('myExtraItem', $id);

// MODX 3.x
$modx->addPackage('MyExtra\\Model', MODX_CORE_PATH . 'components/myextra/src/', null, 'MyExtra\\');
$row = $modx->getObject(\MyExtra\Model\Item::class, $id);
```

## xPDO CLI

xPDO 3 exposes `core/vendor/bin/xpdo`. The core uses it from Composer scripts (`parse-schema`). Extras can call the same binary with their schema path and `--psr4=YourPrefix\\`. Wire it into the Extra’s own `composer.json` if you maintain the package with Composer.

## Related pages

- [Using Custom Database Tables](extending-modx/tutorials/using-custom-database-tables) — step-by-step Extra model
- [Changed Class Names](getting-started/upgrading-to-3.0/class-names) — aliases and `instanceof`
- [Core folder](getting-started/upgrading-to-3.0/core-folder) — why `/core/` is fixed
- [Directory structure](getting-started/directory-structure) — `vendor/` and `src/`
- [xPDO.addPackage](extending-modx/xpdo/class-reference/xpdo/xpdo.addpackage)
- [Building model/schema](contribute/code/tooling/model) — core schema rebuild
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ MODX 3 приносит пространства имён PHP в XML-схему

**ПРИМЕЧАНИЕ**: материал переработан из прежнего примера StoreFinder.

**ЕЩЁ ПРИМЕЧАНИЕ**: эта методология не обратно совместима с MODX 2.x. Руководство рассчитано на MODX 3. Эквивалент для 2.x: [Using Custom Database Tables](/2.x/en/extending-modx/tutorials/using-custom-database-tables "Using Custom Database Tables")
**ЕЩЁ ПРИМЕЧАНИЕ**: эта методология не обратно совместима с MODX 2.x. Руководство рассчитано на MODX 3. Эквивалент для 2.x: [Using Custom Database Tables](/2.x/en/extending-modx/tutorials/using-custom-database-tables "Using Custom Database Tables"). Краткий чеклист апгрейда (Composer, `metadata.mysql.php`, `instanceof`, `addPackage`): [xPDO 3](getting-started/upgrading-to-3.0/xpdo).

## Ключевые термины и стандарты

Expand Down
8 changes: 4 additions & 4 deletions ru/extending-modx/xpdo/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ translation: "extending-modx/xpdo"

xPDO - это объектно-реляционный мост, встроенный в MODX. Проще говоря, это то, как MODX подключается к базе данных и как он взаимодействует с различными таблицами.

В MODX 2.x, класс `modX` непосредственно расширяет `xPDO`. Хотя в ретроспективе это не лучший шаблон разработки, это означает, что всякий раз, когда у вас есть доступ к экземпляру `modX`, вы можете использовать любой из методов `xPDO` на нем.
В MODX 2.x и 3.x класс `modX` расширяет `xPDO`, поэтому на экземпляре MODX доступны методы xPDO. В MODX 3 родитель — namespaced-класс `xPDO\xPDO` из Composer. Апгрейд и миграция Extra: [xPDO 3](getting-started/upgrading-to-3.0/xpdo).

## Что такое xPDO?

Expand All @@ -19,10 +19,10 @@ xPDO (open eXtensions to PDO) - это легковесная ORB (object-relati

В контексте xPDO важно знать следующие термины:

- **Packages** - коллекции моделей. В ядре MODX все модели являются частью пакета `modx`, плюс есть несколько подпакетов, таких как`modx.media` и `modx.package`. Чтобы xPDO узнал о моделях в пакете, его необходимо зарегистрировать с помощью `$xpdo->addPackage()`.
- **Packages** - коллекции моделей. В ядре MODX 3 модели живут в namespaces вроде `MODX\Revolution` (плюс подпакеты Sources, Transport). Регистрируйте пакет через `$xpdo->addPackage()` (и `$namespacePrefix` при PSR-4).
- **Models** - классы, которые представляют конкретную таблицу базы данных. Это абстракция, которую вы будете использовать чаще всего: вместо непосредственного взаимодействия с SQL вы загружаете модель, настраиваете ее свойства и сохраняете.
- **Schemas** - XML-файлы, которые определяют различные модели, доступные в пакете, и их поля (свойства). Они используются только в разработке, во время которой они будут обрабатываться (обычно называемые «встроенными») в модельных классах и картах.
- **Maps** - php-файлы, содержащие массивы, которые определяют метаданные для пакетов и схем. Они находятся в директории модели драйвера базы данных (например: `model/modx/mysql/modresource.map.inc.php`). Эти файлы обычно не обрабатываются вручную, а создаются из файла схемы.
- **Schemas** - XML-файлы, которые определяют различные модели, доступные в пакете, и их поля (свойства). Они используются только в разработке, во время которой они будут обрабатываться (обычно называемые «встроенными») в модельных классах и картах. В MODX 3 укажите `version="3.0"` и PHP-namespace в атрибуте `package`.
- **Maps** - PHP-метаданные пакетов и схем. В MODX 3 / xPDO 3 пакет отдаёт `metadata.{dbtype}.php` (с `class_map`) и файлы платформы в каталоге драйвера (например `mysql/`). В старых доках 2.x часто фигурируют только `*.map.inc.php`. Для MODX 3 перегенерируйте schema с `version="3.0"`.

Есть еще много вещей, которые нужно узнать о xPDO, но если вы понимаете эти 4, у вас есть прочная основа, чтобы разобраться в остальной части документации.

Expand Down
Loading
Loading