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
2 changes: 2 additions & 0 deletions en/extending-modx/di-container/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ title: Dependency Injection Container

MODX 3 introduces a Dependency Injection Container, based on [Pimple 3](https://github.com/silexphp/Pimple), that holds core services and custom services.

`$modx->getService()` still works but is deprecated. Register new services with `add()` / `get()` here instead of `getService()`. See [modX.getService](extending-modx/modx-class/reference/modx.getservice).

The container is available in `modX:$services`, meaning it is typically accessible in one of the following ways:

- `$modx->services` (in snippets, plugins, etc)
Expand Down
73 changes: 52 additions & 21 deletions en/extending-modx/modx-class/reference/modx.getservice.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
---
title: "modX.getService"
description: "getService load and return a named service class instance"
description: "getService loads a named service class. Deprecated in 3.x in favour of the DI container."
---

## modX::getService

**Note**: getService pushed to xPDO layer
**Deprecated in MODX 3.x.** xPDO marks `getService()` as deprecated and points you at the service / DI container (`$modx->services`). PhpStorm therefore warns that it will be removed in 3.1. That removal **did not happen**. The method still exists on current 3.x, and the core still calls it. Prefer `$modx->services` in new code. See [Dependency Injection Container](extending-modx/di-container).

Load and return a named service class instance. Returns either a reference to the service class instance or null if it could not be loaded. You can think of this is a simple dependency injector.

Note that the class is instantiated only once: subsequent calls return a reference to the stored instance.
`getService` lives on xPDO (modX extends xPDO). It loads and returns a named service instance, or `null` if it cannot load the class. The instance is created once. Later calls return the stored object. Internally 3.x stores that object in `$modx->services` as well.

## Syntax

API Doc: [modX::getService()](http://api.modx.com/revolution/2.2/db_core_model_modx_modx.class.html#%5CmodX::getService())

``` php
object getService (string $name, [string $class = ''], [string $path = ''], [array $params = array ()])
```

- `$name` _(string)_ a key which uniquely identifies the service.
- `$class` _(string)_ the full name of the class compatible with the "new" operator OR you can use "dot notation" to specify sub-folders relative to `$path`
- `$path` _(string)_ full path to the directory containing the class in question.
- `$params` _(array)_ passed as the 2nd argument to the constructor. The first argument is always a reference to xPDO/MODX.
- `$name` _(string)_ key that identifies the service.
- `$class` _(string)_ class name for `new`, or dot notation for subfolders under `$path`.
- `$path` _(string)_ directory that contains the class file.
- `$params` _(array)_ second constructor argument. The first argument is always the xPDO/MODX instance.

Defined in [`xPDO::getService()`](https://github.com/modxcms/xpdo/blob/3.x/src/xPDO/xPDO.php).

## Examples
## Examples (still work)

Get the modSmarty service.
Get the Smarty service:

``` php
$modx->getService('smarty','smarty.modSmarty');
```

Get a custom, user-defined service called 'modTwitter' from a custom path ('/path/to/modtwitter.class.php'), and pass in some custom parameters.
Custom service with a path and constructor params:

``` php
$modx->getService('twitter','modTwitter','/path/to/',array(
Expand All @@ -41,23 +39,56 @@ $modx->getService('twitter','modTwitter','/path/to/',array(
$modx->twitter->tweet('Success!');
```

Another example of using getService inside a custom Extra:
Inside an Extra:

``` php
// Use path to point directly to the relevant sub-dir:
// Path points at the class directory:
if(!$Product = $this->modx->getService('mypkg.product','Product',MODX_CORE_PATH.'components/mypkg/model/mypkg/')) {
return 'NOT FOUND';
}
// Or use dot-notation in the classname and point the $path to the model directory:
// Or use dot notation and point $path at the model directory:
if(!$Product = $this->modx->getService('mypkg.product','mypkg.Product',MODX_CORE_PATH.'components/mypkg/model/')) {
return 'NOT FOUND';
}
```

getService may have trouble with PHP namespaces.
`getService` can struggle with PHP namespaces. Pass a fully qualified class name, or register the object on the container yourself.

## Replacement in MODX 3

Use `$modx->services` (`has` / `add` / `get`). Core does the same in `modX::runProcessor()` for lexicon and error.

Register a core-style service (example: `modError`):

``` php
use MODX\Revolution\Error\modError;

if (!$modx->services->has('error')) {
$modx->services->add('error', new modError($modx));
}
$modx->error = $modx->services->get('error');
```

Custom Extra: instantiate the class (Composer / namespace autoload) and add it. A [Namespace `bootstrap.php`](extending-modx/namespaces) is the usual place:

``` php
$modx->services->add('twitter', function($c) use ($modx) {
return new MyPackage\Twitter($modx, ['api_key' => 3212423]);
});
```

Then:

``` php
$twitter = $modx->services->get('twitter');
$twitter->tweet('Success!');
```

`modError` (`$modx->error`) and `modErrorHandler` (`$modx->errorHandler`) are different services. Do not mix the keys.

## See Also

- [modX](extending-modx/core-model/modx "modX")
- [MODX Services](extending-modx/services "MODX Services")
- [xPDO.loadClass](extending-modx/xpdo/class-reference/xpdo/xpdo.loadclass "xPDO.loadClass") – similar to getService, but it just loads the class and doesn't instantiate it.
- [modX](extending-modx/core-model/modx)
- [MODX Services](extending-modx/services)
- [Dependency Injection Container](extending-modx/di-container)
- [xPDO.loadClass](extending-modx/xpdo/class-reference/xpdo/xpdo.loadclass) loads a class without instantiating it
15 changes: 8 additions & 7 deletions en/extending-modx/services/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ _old_uri: "2.x/developing-in-modx/advanced-development/modx-services"

## What is a Service?

A service is any object that is loaded via [$modx->getService](extending-modx/modx-class/reference/modx.getservice "modX.getService"). It can be a custom class provided by the user, or by MODX itself.
A service is any object stored in the [dependency injection container](extending-modx/di-container) (`$modx->services`). In 2.x, and still in 3.x, many extras also load services with [$modx->getService](extending-modx/modx-class/reference/modx.getservice). That helper is deprecated in 3.x. Prefer `has` / `add` / `get` on `$modx->services`.

Once an object is loaded with getService, it is accessible via `$modx->(servicename)`. So, for example:
Once a service is in the container, you can also hang it on `$modx` yourself (`$modx->error = $modx->services->get('error')`). `getService` did that automatically.

``` php
$modx->getService('twitter','myTwitter','/path/to/twitter/model/',array(
'api_key' => 3212423,
));
$modx->twitter->tweet('Success!');
$modx->services->add('twitter', function($c) use ($modx) {
return new MyPackage\Twitter($modx, ['api_key' => 3212423]);
});
$modx->services->get('twitter')->tweet('Success!');
```

## What are the Default Included Services?
Expand All @@ -27,4 +27,5 @@ A list of the core-included MODX Services is as follows:

## See Also

- [modX.getService](extending-modx/modx-class/reference/modx.getservice "modX.getService")
- [modX.getService](extending-modx/modx-class/reference/modx.getservice)
- [Dependency Injection Container](extending-modx/di-container)
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 @@ -15,6 +15,8 @@ You may encounter warnings or errors (including fatal errors) in certain cases:

Most model and service classes that are loaded through `$modx->loadClass` (which includes the xPDO Query builder for model classes) or `$modx->getService` will still work, as `loadClass` internally translates these to their new class names.

`$modx->getService()` itself is **deprecated** in 3.x. xPDO phpdoc (and therefore PhpStorm) still say it will be removed in 3.1. That did not happen: the method remains, and the core still uses it. For new code, register and fetch objects on `$modx->services`. See [modX.getService](extending-modx/modx-class/reference/modx.getservice) and the [DI container](extending-modx/di-container).

For example `$modx->getIterator('modResource')` will still work - _for now_, even though the `\modResource` class is now `\MODX\Revolution\modResource`.

That will log a deprecated message to your error log encouraging you to update your reference. The right call would be `$modx->getIterator(\MODX\Revolution\modResource::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 @@ -21,6 +21,7 @@ After upgrading the core and upgrading your extras, you may encounter some break
- [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)
- [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)
- `$modx->getService()` is deprecated in favour of the [DI container](extending-modx/di-container) (`$modx->services`). The method still works and was **not** removed in 3.1. See [modX.getService](extending-modx/modx-class/reference/modx.getservice).

## Other notable changes and improvements

Expand Down
2 changes: 2 additions & 0 deletions ru/extending-modx/di-container/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ translation: "extending-modx/di-container/config"

MODX 3 представляет контейнер для инъекций зависимости, основанный на [Pimple 3](https://github.com/silexphp/Pimple), который содержит сервисы ядра и кастомные сервисы.

`$modx->getService()` ещё работает, но устарел. Новые сервисы регистрируйте через `add()` / `get()`, а не через `getService()`. См. [modX.getService](extending-modx/modx-class/reference/modx.getservice).

Контейнер доступен в `modX:$services`, что означает, что он обычно доступен одним из следующих способов:

- `$modx->services` (в snippets, plugins, и так далее)
Expand Down
73 changes: 52 additions & 21 deletions ru/extending-modx/modx-class/reference/modx.getservice.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
---
title: "modX.getService"
translation: "extending-modx/modx-class/reference/modx.getservice"
description: "getService() загружает и возвращает экземпляр именованного класса обслуживания"
description: "getService() загружает именованный сервис. В 3.x метод устарел в пользу DI-контейнера."
---

## modX::getService

**Примечание**: getService перемещен на уровень xPDO
**Устарел в MODX 3.x.** xPDO помечает `getService()` как deprecated и отправляет к контейнеру сервисов (`$modx->services`). PhpStorm из-за phpdoc предупреждает об удалении в 3.1. Удаления **не было**. Метод есть в текущих 3.x, ядро само его ещё вызывает. В новом коде берите `$modx->services`. См. [Контейнер внедрения зависимостей](extending-modx/di-container).

Загружает и возвращает экземпляр именованного класса обслуживания. Возвращает ссылку на экземпляр класса обслуживания или значение null, если он не может быть загружен. Вы можете подумать, что это простая инъекция зависимости.

Обратите внимание, что экземпляр класса создается только один раз: последующие вызовы возвращают ссылку на сохраненный экземпляр.
`getService` живёт в xPDO (modX его наследует). Загружает и возвращает экземпляр сервиса или `null`, если класс не поднялся. Экземпляр создаётся один раз. Повторные вызовы отдают тот же объект. В 3.x он ещё кладётся в `$modx->services`.

## Синтаксис

API Doc: [modX::getService()](http://api.modx.com/revolution/2.2/db_core_model_modx_modx.class.html#%5CmodX::getService())

``` php
object getService (string $name, [string $class = ''], [string $path = ''], [array $params = array ()])
```

- `$name` _(string)_ ключ, который однозначно идентифицирует службу.
- `$class` _(string)_ полное имя класса, совместимого с оператором "new", ИЛИ вы можете использовать "точечную нотацию" для указания вложенных папок относительно `$path`.
- `$path` _(string)_ полный путь к каталогу, содержащему рассматриваемый класс.
- `$params` _(array)_ передается в качестве второго аргумента в конструктор. Первый аргумент всегда является ссылкой на xPDO/MODX.
- `$name` _(string)_ ключ сервиса.
- `$class` _(string)_ имя класса для `new` или точечная нотация для подпапок относительно `$path`.
- `$path` _(string)_ каталог с файлом класса.
- `$params` _(array)_ второй аргумент конструктора. Первый всегда экземпляр xPDO/MODX.

Определение: [`xPDO::getService()`](https://github.com/modxcms/xpdo/blob/3.x/src/xPDO/xPDO.php).

## Примеры
## Примеры (по-прежнему работают)

Получение сервиса `modSmarty`.
Сервис Smarty:

``` php
$modx->getService('smarty','smarty.modSmarty');
```

Получить пользовательский, определенный пользователем сервис под названием 'modTwitter' из пользовательского пути ('/path/to/modtwitter.class.php'), и передать некоторые пользовательские параметры.
Свой сервис с путём и параметрами конструктора:

``` php
$modx->getService('twitter','modTwitter','/path/to/',array(
Expand All @@ -42,23 +40,56 @@ $modx->getService('twitter','modTwitter','/path/to/',array(
$modx->twitter->tweet('Успех!');
```

Еще один пример использования getService внутри пользовательского Extra:
В Extra:

``` php
// Используйте путь, чтобы указать непосредственно на соответствующий вложенный каталог:
// Путь сразу в каталог класса:
if(!$Product = $this->modx->getService('mypkg.product','Product',MODX_CORE_PATH.'components/mypkg/model/mypkg/')) {
return 'НЕ НАЙДЕН';
}
// Или используйте точечную нотацию в имени класса и укажите $path на каталог модели:
// Или точечная нотация и $path на каталог модели:
if(!$Product = $this->modx->getService('mypkg.product','mypkg.Product',MODX_CORE_PATH.'components/mypkg/model/')) {
return 'НЕ НАЙДЕН';
}
```

У `getService` могут возникнуть проблемы с пространствами имен PHP.
У `getService` бывают проблемы с PHP-пространствами имён. Передайте FQCN или зарегистрируйте объект в контейнере сами.

## Замена в MODX 3

Используйте `$modx->services` (`has` / `add` / `get`). Ядро так делает в `modX::runProcessor()` для lexicon и error.

Регистрация сервиса ядра (пример: `modError`):

``` php
use MODX\Revolution\Error\modError;

if (!$modx->services->has('error')) {
$modx->services->add('error', new modError($modx));
}
$modx->error = $modx->services->get('error');
```

Свой Extra: создайте класс (Composer / autoload namespace) и добавьте его. Обычно это [`bootstrap.php` пространства имён](extending-modx/namespaces):

``` php
$modx->services->add('twitter', function($c) use ($modx) {
return new MyPackage\Twitter($modx, ['api_key' => 3212423]);
});
```

Дальше:

``` php
$twitter = $modx->services->get('twitter');
$twitter->tweet('Успех!');
```

`modError` (`$modx->error`) и `modErrorHandler` (`$modx->errorHandler`) это разные сервисы. Ключи не путайте.

## Смотрите также

- [modX](extending-modx/core-model/modx "modX")
- [MODX Services](extending-modx/services "MODX Services")
- [xPDO.loadClass](extending-modx/xpdo/class-reference/xpdo/xpdo.loadclass "xPDO.loadClass") – similar to getService, but it just loads the class and doesn't instantiate it.
- [modX](extending-modx/core-model/modx)
- [MODX Services](extending-modx/services)
- [Контейнер внедрения зависимостей](extending-modx/di-container)
- [xPDO.loadClass](extending-modx/xpdo/class-reference/xpdo/xpdo.loadclass) загружает класс без создания экземпляра
15 changes: 8 additions & 7 deletions ru/extending-modx/services/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ translation: "extending-modx/services"

## Что такое сервис?

Сервис - это любой объект, который загружается через [$modx->getService](extending-modx/modx-class/reference/modx.getservice "modX.getService"). Это может быть пользовательский класс, предоставленный пользователем, или самим MODX.
Сервис это объект в [контейнере внедрения зависимостей](extending-modx/di-container) (`$modx->services`). В 2.x и по-прежнему в 3.x многие extras грузят сервисы через [$modx->getService](extending-modx/modx-class/reference/modx.getservice). Этот хелпер в 3.x устарел. Берите `has` / `add` / `get` у `$modx->services`.

Как только объект загружен с помощью getService, он доступен через `$modx->(servicename)`. Так, например:
Когда сервис уже в контейнере, его можно повесить на `$modx` вручную (`$modx->error = $modx->services->get('error')`). `getService` делал это сам.

``` php
$modx->getService('twitter','myTwitter','/path/to/twitter/model/',array(
'api_key' => 3212423,
));
$modx->twitter->tweet('Success!');
$modx->services->add('twitter', function($c) use ($modx) {
return new MyPackage\Twitter($modx, ['api_key' => 3212423]);
});
$modx->services->get('twitter')->tweet('Success!');
```

## Какие сервисы включены по умолчанию?
Expand All @@ -26,4 +26,5 @@ $modx->twitter->tweet('Success!');

## Смотрите также

- [modX.getService](extending-modx/modx-class/reference/modx.getservice "modX.getService")
- [modX.getService](extending-modx/modx-class/reference/modx.getservice)
- [Контейнер внедрения зависимостей](extending-modx/di-container)
Loading
Loading