diff --git a/en/extending-modx/processors/connectors.md b/en/extending-modx/processors/connectors.md index 56b3b6e3a..0f7650667 100644 --- a/en/extending-modx/processors/connectors.md +++ b/en/extending-modx/processors/connectors.md @@ -1,8 +1,61 @@ --- title: 'Connectors' -note: 'This is a stub. You can help by expanding it.' --- -Connectors are simple PHP files that extras can use to expose their processors to manager users. +## What a connector is -The core connector (`connectors/index.php`) only allows routing AJAX requests in the manager to the core processors, so extras typically place their own in `assets/components/NAME-OF-EXTRA/connector.php`, and use that for their own [custom manager pages](extending-modx/custom-manager-pages). +A connector is a PHP entry point for AJAX (and similar) requests that should run a [processor](extending-modx/processors). It boots MODX, checks that the user may load the context, then hands the request to `modX::request->handleRequest()`, which calls [`runProcessor`](extending-modx/modx-class/reference/modx.runprocessor). + +Connectors do not change the database themselves. Processors do. + +## Core connector + +Manager requests for core actions go through files under `connectors/` that include [`connectors/index.php`](https://github.com/modxcms/revolution/blob/3.x/connectors/index.php). That bootstrap: + +1. Loads the MODX instance and initializes a context (default `mgr`, or `ctx` from the request). +2. Enforces a load policy unless the action is explicitly anonymous (for example `security/login`). +3. Sanitizes the request and routes `action` to a core processor. + +Example shape of a request: your ExtJS grid posts to a connector URL with `action=resource/getlist` (plus auth headers MODExt adds for you). + +## Extra connectors + +The core connector only knows core processor paths. Extras add their own file, typically: + +`assets/components/myextra/connector.php` + +Pattern (same idea as in [Developing an Extra, Part II](extending-modx/tutorials/developing-an-extra/part-2)): + +```php +getOption( + 'myextra.core_path', + null, + $modx->getOption('core_path') . 'components/myextra/' +); +// load your service / lexicon as needed … + +$modx->request->handleRequest([ + 'processors_path' => $corePath . 'processors/', + 'location' => '', +]); +``` + +`processors_path` tells MODX where `{action}.class.php` files live. The grid’s `baseParams.action` (for example `mgr/item/getlist`) maps to `processors/mgr/item/getlist.class.php`. + +## Auth and CSRF + +Connectors expect a manager session (unless you deliberately open an anonymous action) and a site auth token. MODExt sends it as the `modAuth` HTTP header (or `HTTP_MODAUTH` in the request). The value is `$modx->siteId`. Do not put that value in public repositories or client-side docs. + +Opening the connector URL in a browser with no session and no `action` usually returns JSON like `success: false` / access denied. That is expected. + +## See also + +- [Processors](extending-modx/processors) +- [Core processor list](extending-modx/processors/list) +- [Custom Manager Pages](extending-modx/custom-manager-pages) +- [MODExt FormPanel](extending-modx/custom-manager-pages/modext/modx.formpanel): posts through a connector URL diff --git a/en/extending-modx/processors/index.md b/en/extending-modx/processors/index.md index f2d473384..2d1e83522 100644 --- a/en/extending-modx/processors/index.md +++ b/en/extending-modx/processors/index.md @@ -1,107 +1,270 @@ --- title: 'Processors' -description: "Processors can be compared to commands or actions" +description: "Processors are PHP classes that run one action: create a resource, list records, log a user in" --- -## Processors in MODX +## What a processor is -Processors can be compared to "commands" or "actions". Before MODX 2.2 they were "simple" PHP files, but they have since been rewritten based on the `modProcessor` class, and its various subtypes. +A processor is a PHP class that runs **one** action against MODX: create a Chunk, list Resources, log a user in, upload a file. The manager UI, connectors, Snippets, and Plugins all reach the same actions through processors. -So, we are talking about processor files, these are PHP scripts that can perform certain functions. For clarity, have a look at [/core/model/modx/processors](https://github.com/modxcms/revolution/tree/2.x/core/model/modx/processors) and you will see how many there are. +Since MODX 2.2 processors are class-based (subclasses of the processor base class). Flat `.php` processor files without a class are gone in MODX 3.0. -You can work with processors from any Snippet or Plugin using [runProcessor](extending-modx/processors/using-runprocessor) method: +Core processor classes live under: -``` php -$response = $modx->runProcessor('action/path/to/processor',$arrayOfProperties,$otherOptions); +- **3.x:** [`core/src/Revolution/Processors/`](https://github.com/modxcms/revolution/tree/3.x/core/src/Revolution/Processors) +- **2.x:** `core/model/modx/processors/` (legacy layout) + +Full catalog of core actions (path, docblock summary, `$permission`): [Core processor list](extending-modx/processors/list). + +You call them from PHP with [`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor). Manager AJAX goes through a [connector](extending-modx/processors/connectors), which ends up in the same method. + +```php +$response = $modx->runProcessor( + 'resource/create', + $properties, + $options // optional; often unused for core processors +); ``` -In response we get [modProcessorResponse](https://github.com/modxcms/revolution/blob/df90fecfdfcf719cabe171ea3db59e47f45d7ee9/core/model/modx/modprocessor.class.php) object with all its methods. +`$response` is a [`ProcessorResponse`](https://github.com/modxcms/revolution/blob/3.x/core/src/Revolution/Processors/ProcessorResponse.php) (3.x) / `modProcessorResponse` (2.x). Check the result before you trust the data: + +```php +if ($response->isError()) { + return $response->getMessage(); +} +$object = $response->getObject(); // array of fields from the processor +``` + +Useful methods: `isError()`, `getMessage()`, `getObject()`, `getResponse()`, `hasFieldErrors()`, `getFieldErrors()`. + +### How `run()` works + +When MODX runs a processor it does this (see `Processor::run()`): + +1. `checkPermissions()`: if it fails, you get a permission error response. +2. Load lexicon topics from `getLanguageTopics()`. +3. `initialize()`: must return `true`, or the return value becomes the failure message. +4. `process()`: the real work. Model helpers (`CreateProcessor`, `GetListProcessor`, ...) implement a fixed pipeline with hooks you override. + +Inside your class you read input with `getProperty()` / `getProperties()`, write with `setProperty()`, and finish with `$this->success($message, $object)` or `$this->failure($message)`. Field-level errors use `addFieldError('field', $msg)` so MODExt forms can highlight inputs. + +### Permissions and context + +Many processors declare `public $permission = 'save_document';` (or similar). The logged-in user in the **current** `$modx` context must pass that permission (and whatever else `checkPermissions()` adds). Controllers and connectors usually initialize `mgr`. From a web Snippet you may need `$modx->initialize('mgr')` or a user who already has the right policies in `web`, or the call fails even when the PHP looks fine. -## Standard processors +### Action path forms (3.x) -As an example please check `security` folder - there are` login` and `logout` processors that control user authorization. Here's how we can authorize the user: +These are equivalent for core processors: -``` php -$username = 'ivanpetrov'; -$password = '*********'; -$data = array( +| Form | Example | +| ---- | ------- | +| Slash path (2.x style) | `resource/create` | +| Relative namespace | `Resource\Create` | +| Fully qualified class | `\MODX\Revolution\Processors\Resource\Create` | + +Special case: Template Variables live under `Element\TemplateVar\...`. Slash `element/templatevar/create` works. Legacy `element/tv/...` is rewritten to `TemplateVar` in the loader. Details: [Processor loading logic](extending-modx/modx-class/reference/modx.runprocessor#processor-loading-logic). + +## Prefer core processors + +When MODX already ships an action you need, call that processor instead of writing raw `newObject()` / `save()` code. You get permissions, validation, alias generation, and plugin events (`OnDocFormSave` and friends) for free. Other extras that listen to those events keep working with your code. + +Browse what exists: [Core processor list](extending-modx/processors/list) (Browser, Context, Element, Resource, Security, System, Workspace, ...). + +### Login and logout + +```php +$data = [ 'username' => $username, 'password' => $password, 'rememberme' => 1, 'login_context' => 'web', -); -$response = $modx->runProcessor('/security/login', $data); +]; +$response = $modx->runProcessor('security/login', $data); if ($response->isError()) { - $modx->log(modX::LOG_LEVEL_ERROR, 'login error. Username: '.$username.', Message: '.$response->getMessage()); + $modx->log( + modX::LOG_LEVEL_ERROR, + 'Login failed for ' . $username . ': ' . $response->getMessage() + ); } ``` -Leaving website is even easier: +```php +$response = $modx->runProcessor('security/logout'); +if ($response->isError()) { + $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage()); +} +``` + +In 3.x you can also pass the namespaced class, for example `\MODX\Revolution\Processors\Security\Login`. -``` php -$response = $modx->runProcessor('/security/logout'); +### Create a Resource + +```php +$response = $modx->runProcessor('resource/create', [ + 'pagetitle' => 'My page', + 'content' => '

Hello

', + 'parent' => 0, + 'template' => 1, + 'context_key' => 'web', +]); if ($response->isError()) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Logout error. Username: '.$modx->user->get('username').', uid: '.$modx->user->get('id').'. Message: '.$response->getMessage()); + return $response->getMessage(); } +$id = $response->getObject()['id']; ``` -This is very convenient and ensures that your's component will work in all MODX versions. Therefore, if possible, you should always use standard processors. +Omit fields you do not care about. The processor fills defaults from System Settings. Set `class_key` when you create a custom Resource type. -Of course, standard processors don't know how to work with your Components. +Typical create/update processors fire before/after save events (for Resources that includes the same family of events the manager uses). That is why search indexers and other plugins still see your programmatic saves. -## Own processors +### Create a Chunk -Using your own processors differs from the standard ones only in that you need to specify the folder where to get them from. Let's see an example from [miniShop2](https://minishop2.com): +```php +$response = $modx->runProcessor('element/chunk/create', [ + 'name' => 'HelloBox', + 'description' => 'Created from a Snippet', + 'snippet' => '
[[*pagetitle]]
', +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` -``` php -// Array we will send to processor, there to catch it in $scriptProperties -$processorProps = array( - 'id' => 55 -); -// Options array for the runProcessor method -$otherProps = array( - // Here we indicate where our processors are located - 'processors_path' => $modx->getOption('core_path') . 'components/minishop/processors/' +More Snippet-oriented examples (update/delete/publish, Snippet/TV, settings, cache, field errors, FQCN): [Using runProcessor](extending-modx/processors/using-runprocessor). + +### Update a Resource + +```php +$response = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => 'My page (edited)', + 'published' => 1, +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Clear the cache + +```php +$response = $modx->runProcessor('system/clearcache'); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### List processors and grids + +`GetList` processors power ExtJS grids. They expect paging/sort properties such as `start`, `limit`, `sort`, `dir`, and often `query`. The JSON shape includes `success`, `total`, and `results` (exact keys depend on the processor). From PHP: + +```php +$response = $modx->runProcessor('resource/getlist', [ + 'start' => 0, + 'limit' => 10, + 'sort' => 'pagetitle', + 'dir' => 'ASC', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$data = $response->getResponse(); +``` + +## Custom processors + +Extras keep processors under their own tree, usually `core/components/myextra/processors/`. Point `runProcessor` at that tree with `processors_path`: + +```php +$response = $modx->runProcessor( + 'web/orders/getlist', + ['id' => 55], + [ + 'processors_path' => $modx->getOption('core_path') + . 'components/myextra/processors/', + ] ); -// Run -$response = $modx->runProcessor('web/orders/getlist', $processorProps, $otherProps); -// And return response from the processor -return $response->response; +if ($response->isError()) { + return $response->getMessage(); +} +return $modx->toJSON($response->getResponse()); ``` -This is a slightly modified example from miniShop Snippet, where it [processes personal account requests](https://github.com/bezumkin/miniShop/blob/master/core/components/minishop/elements/snippets/minishop.php#L26). +The action has no file extension. MODX looks for `{processors_path}web/orders/getlist.class.php` (and expects a processor class that returns its class name or follows the `modFooBarProcessor` naming guess). Same idea as a connector: the connector sets `processors_path`, then routes `action` to a file. -As you can see start processor is specified without extension, by the path from the processor folder. If we do not specify our folder, it will be `/core/model/modx/processors/` by default. In the example above we change it to a folder inside miniShop component. +File naming in extras: `mgr/item/getlist.class.php` paired with action `mgr/item/getlist`. Returning `MyExtra\\Processors\\Item\\GetList::class` from the file avoids ambiguous class guesses. -## Standard processor inside native +### Call a core processor from your own -Here's the most interesting! Let's see an example: +Inside a custom create processor you can run a core one, then continue with your own fields: -``` php -$response = $modx->runProcessor('resource/create', $_POST); +```php +$response = $modx->runProcessor('resource/create', $resourceData); if ($response->isError()) { - return $modx->error->failure($response->getMessage()); + return $this->failure($response->getMessage()); +} +$id = $response->getObject()['id']; +// attach extra records to $id ... +``` + +Plugins on Resource save still fire. Alias and other core behaviour stay consistent with the manager. + +## Writing a class-based processor + +Minimal create processor for a custom xPDO object (3.x class names): + +```php +getProperty('name')); + if ($name === '') { + $this->addFieldError('name', $this->modx->lexicon('myextra.item_err_name')); + } + return parent::beforeSet(); + } } -$id = $response->response['object']['id']; +return Create::class; ``` -Here we create a new resource using standard processor from `$_POST` data and get resource `id` from response. -[Here is the source code](https://github.com/bezumkin/miniShop/blob/master/core/components/minishop/processors/mgr/goods/create.php) the entire miniShop processor to create a new product. +`CreateProcessor::process()` order (simplified): `beforeSet` → `fromArray` → `beforeSave` → validate → before-save event → `saveObject` → `afterSave` → after-save event → `cleanup`. -This approach ensures that regardless of future changes to MODX, its processor will work in all versions. And, very importantly, **plugins will work** that should work when creating new resources. Also, `alias` will be generated (if you use them), and as indicated in the System Settings, through transliteration, or not. -Updating products works the same way, and for example [mSearch](https://docs.modx.pro/en/components/msearch2) gets `OnDocFormSave` event and indexes this resource. +For lists, extend `GetListProcessor` and filter in `prepareQueryBeforeCount` / `prepareQueryAfterCount`. Read incoming filters with `$this->getProperty('resource_id')` (or whatever you put in the grid `baseParams`). Nothing is injected automatically from the Resource panel unless your JS sends it. -You may not use `runProcessor` in such cases and work through` newObject` method - but then you need to additionally generate events for plugins, define unset fields of a new resource, generate `alias` and much more. -For what - if MODX has already foreseen all this? +Common model helpers (3.x → see the [3.0 processors upgrade notes](getting-started/upgrading-to-3.0/processors) for the full map): -## Conclusion +| Role | 3.x class | +| ---- | --------- | +| Create | `\MODX\Revolution\Processors\Model\CreateProcessor` | +| Update | `\MODX\Revolution\Processors\Model\UpdateProcessor` | +| Get | `\MODX\Revolution\Processors\Model\GetProcessor` | +| Get list | `\MODX\Revolution\Processors\Model\GetListProcessor` | +| Remove | `\MODX\Revolution\Processors\Model\RemoveProcessor` | -Processors are a great thing, and you need to make the most of them in all your Snippets. If you want to do something with a resource or other element - please check if there is a ready-made processor in the system for this? -If yes - use it! This saves you a lot of headache and allows other Components and plugins to interact with your code. +In 2.x the same roles use `modObjectCreateProcessor`, `modObjectGetListProcessor`, and so on. Hooks you override most often: `initialize`, `beforeSet`, `beforeSave`, `afterSave`, `prepareQueryBeforeCount` (lists). -## See also +## Next steps -- [Getting started with class-based processors](https://www.markhamstra.com/xpdo/2012/getting-started-with-class-based-processors-2.2/) (at markhamstra.com) -- [Extending modObjectGetListProcessor, a powerful class based processor in MODX 2.2](https://www.markhamstra.com/xpdo/2012/modobjectgetlistprocessor-class-based-processor/) (at markhamstra.com) -- [Full list of MODX Processors](https://bobsguides.com/modx-processor-list.html) (at bobsguides.com) +- [Core processor list](extending-modx/processors/list): all core actions with short descriptions +- [Using runProcessor](extending-modx/processors/using-runprocessor): practical Snippet examples +- [modX.runProcessor](extending-modx/modx-class/reference/modx.runprocessor): parameters and 3.x loading rules +- [Connectors](extending-modx/processors/connectors): AJAX gateway for CMPs +- [Processors in the 3.0 upgrade guide](getting-started/upgrading-to-3.0/processors) +- [Developing an Extra, Part II](extending-modx/tutorials/developing-an-extra/part-2): connector + getlist walkthrough +- [Class-based processors](https://www.markhamstra.com/xpdo/2012/getting-started-with-class-based-processors-2.2/) and [modObjectGetListProcessor](https://www.markhamstra.com/xpdo/2012/modobjectgetlistprocessor-class-based-processor/) (Mark Hamstra) +- [Processor list on Bob's Guides](https://bobsguides.com/modx-processor-list.html) (oriented to 2.x paths) diff --git a/en/extending-modx/processors/list.md b/en/extending-modx/processors/list.md new file mode 100644 index 000000000..7d40a47d9 --- /dev/null +++ b/en/extending-modx/processors/list.md @@ -0,0 +1,470 @@ +--- +title: "Core processor list" +description: "Catalog of core processors in MODX 3.x with action paths, short descriptions, and permissions" +--- + +## Core processor list (MODX 3.x) + +This page lists **callable core processors** under `core/src/Revolution/Processors/`. Paths work with [`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor) as slash actions (`resource/create`) or as namespaced classes (`\\MODX\\Revolution\\Processors\\Resource\\Create`). + +Notes: + +- Built from class docblocks and `$permission` on MODX Revolution **3.x**. Wording follows the source. +- Skips abstract bases, `Model\\*Processor` helpers, and Template Variable Configs/Renders (manager UI pieces, not typical `runProcessor` targets). +- For Template Variables the folder is `Element/TemplateVar/`. Slash form `element/templatevar/` resolves. Legacy `element/tv/` is rewritten to TemplateVar in the loader. +- Permission is the processor `$permission` property when set. An empty cell means the class does not declare one (access may still be checked in `checkPermissions()` or elsewhere). +- Exact required properties differ per processor. Open the class file when a call fails validation. + +Total in this catalog: **379** processors. + +See also: [Processors overview](extending-modx/processors), [Using runProcessor](extending-modx/processors/using-runprocessor). + +## Browser (files and directories) + +16 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `browser/directory/create` | Create a directory. | `directory_create` | +| `browser/directory/getfiles` | Gets all files in a directory | `file_list` | +| `browser/directory/getlist` | Get a list of directories and files, sorting them first by folder/file and then alphanumerically. | `directory_list` | +| `browser/directory/remove` | Remove a directory | `directory_remove` | +| `browser/directory/rename` | Renames a directory | `directory_update` | +| `browser/directory/sort` | Sort a directory. | `directory_update` | +| `browser/directory/update` | Renames a directory. | | +| `browser/file/create` | Creates a file. | `file_create` | +| `browser/file/download` | Send a file to user | `file_view` | +| `browser/file/get` | Gets the contents of a file | `file_view` | +| `browser/file/remove` | Removes a file. | `file_remove` | +| `browser/file/rename` | Renames a file | `file_update` | +| `browser/file/unpack` | Unpacks archives, currently only zip | `file_unpack` | +| `browser/file/update` | Updates a file. | `file_update` | +| `browser/file/upload` | Upload files to a directory | `file_upload` | +| `browser/visibility` | Set visibility on a directory or file | `directory_chmod` | + +## Context + +19 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `context/create` | Creates a context | `new_context` | +| `context/duplicate` | Duplicates a context. | `new_context` | +| `context/get` | Grabs a context | `view_context` | +| `context/getlist` | Grabs a list of contexts. | `view_context` | +| `context/group/create` | Create a Context Group. | `new_context` | +| `context/group/get` | Get a Context Group. | `view_context` | +| `context/group/getlist` | Get a list of Context Groups. | `view_context` | +| `context/group/remove` | Remove a Context Group and unassign its Contexts. | `delete_context` | +| `context/group/update` | Update a Context Group. | `edit_context` | +| `context/group/updatefromgrid` | Update a Context Group from a grid row (JSON data). | | +| `context/remove` | Removes a context | `delete_context` | +| `context/setting/create` | Creates a context setting | `settings` | +| `context/setting/get` | Gets a context setting | `settings` | +| `context/setting/getlist` | Get a list of context settings | `settings` | +| `context/setting/remove` | Removes a context setting. | | +| `context/setting/update` | Updates a context setting | | +| `context/setting/updatefromgrid` | Updates a setting from a grid. Passed as JSON data. | | +| `context/update` | Updates a context. | `edit_context` | +| `context/updatefromgrid` | Update a context from a grid. Passed as JSON data. | | + +## Element (Chunks, Snippets, Plugins, Templates, TVs, Property Sets) + +68 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `element/category/create` | Create a category. | `save_category` | +| `element/category/get` | Gets a category. | `view_category` | +| `element/category/getlist` | Grabs a list of Categories. | | +| `element/category/remove` | Deletes a category. Resets all elements with that category to 0. | `delete_category` | +| `element/category/update` | Update a category. | `save_category` | +| `element/chunk/create` | Creates a chunk. | `new_chunk` | +| `element/chunk/duplicate` | Duplicates a chunk. | `new_chunk` | +| `element/chunk/get` | Gets a chunk. | `view_chunk` | +| `element/chunk/getlist` | Grabs a list of chunks. | `view_chunk` | +| `element/chunk/remove` | Removes a chunk. | `delete_chunk` | +| `element/chunk/update` | Updates a chunk. | `save_chunk` | +| `element/duplicate` | Abstract class for Duplicate Element processors. To be extended for each derivative element type. | | +| `element/exportproperties` | Export properties and output url to download to browser | | +| `element/getclasses` | Outputs a list of Element subclasses | | +| `element/getinsertproperties` | Class GetInsertProperties | | +| `element/getlistbyclass` | Grabs a list of elements by their subclass | | +| `element/getnodes` | Grabs all elements for element tree | | +| `element/importproperties` | Import properties from a file | | +| `element/plugin/activate` | Activate a plugin. | `save_plugin` | +| `element/plugin/create` | Creates a plugin | `new_plugin` | +| `element/plugin/deactivate` | Deactivate a plugin. | `save_plugin` | +| `element/plugin/duplicate` | Duplicate a plugin | `new_plugin` | +| `element/plugin/event/associate` | Associate the event to the plugins. | `save_plugin` | +| `element/plugin/event/get` | Get Plugin event | `view_plugin` | +| `element/plugin/event/getassoc` | Gets a list of plugins associated to system event | `view_plugin` | +| `element/plugin/event/getlist` | Gets a list of system events | `view_plugin` | +| `element/plugin/event/remove` | Remove Event from a Plugin | `delete_plugin` | +| `element/plugin/event/update` | Update Plugin Event | `save_plugin` | +| `element/plugin/event/updatefromgrid` | Update Plugin event from the grid | | +| `element/plugin/get` | Get a plugin | `view_plugin` | +| `element/plugin/getlist` | Grabs a list of plugins. | `view_plugin` | +| `element/plugin/remove` | Delete a plugin. | `delete_plugin` | +| `element/plugin/update` | Update a plugin. | `save_plugin` | +| `element/propertyset/addelement` | Adds an element to a Property Set | `save_propertyset` | +| `element/propertyset/associate` | Associates a property set to an element, or creates a property set | | +| `element/propertyset/create` | Creates a property set | `new_propertyset` | +| `element/propertyset/duplicate` | Duplicates a property set | `new_propertyset` | +| `element/propertyset/get` | Grabs a property set | `view_propertyset` | +| `element/propertyset/getlist` | Grabs a list of property sets for building dropdown (combo) fields. | `view_propertyset` | +| `element/propertyset/getnodes` | Grabs all elements for propertyset tree | `view_propertyset` | +| `element/propertyset/getproperties` | Gets properties for a property set | | +| `element/propertyset/remove` | Removes a property set | `delete_propertyset` | +| `element/propertyset/removeelement` | Removes an element from a Property Set | `delete_propertyset` | +| `element/propertyset/update` | Updates a property set | `save_propertyset` | +| `element/propertyset/updatefromelement` | Saves a property set | | +| `element/snippet/create` | Create a snippet. | `new_snippet` | +| `element/snippet/duplicate` | Duplicate a snippet. | `new_snippet` | +| `element/snippet/get` | Get a snippet. | `view_snippet` | +| `element/snippet/getlist` | Grabs a list of snippets. | `view_snippet` | +| `element/snippet/remove` | Delete a snippet. | `delete_snippet` | +| `element/snippet/update` | Update a snippet | `save_snippet` | +| `element/sort` | Sorts elements in the element tree | | +| `element/template/create` | Create a template | `new_template` | +| `element/template/duplicate` | Duplicate a Template. | `new_template` | +| `element/template/get` | Gets a template | `view_template` | +| `element/template/getlist` | Grabs a list of templates. | `view_template` | +| `element/template/remove` | Deletes a template. | `delete_template` | +| `element/template/templatevar/getlist` | Gets a list of TVs, marking ones associated with the template. | | +| `element/template/update` | Update a template | `save_template` | +| `element/templatevar/create` | Create a Template Variable. | `new_tv` | +| `element/templatevar/duplicate` | Duplicate a TV | `new_tv` | +| `element/templatevar/get` | Gets a TV | `view_tv` | +| `element/templatevar/getlist` | Grabs a list of TVs. | `view_tv` | +| `element/templatevar/remove` | Delete a TV | `delete_tv` | +| `element/templatevar/resourcegroup/getlist` | Gets a list of resource groups associated to a TV. | | +| `element/templatevar/template/getlist` | Grabs a list of templates associated with the TV | | +| `element/templatevar/template/updatefromgrid` | Assigns or unassigns a template to a TV. Passed in JSON data. | | +| `element/templatevar/update` | Updates a TV | `save_tv` | + +## Resource + +27 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `resource/create` | Creates a resource. | `new_document` | +| `resource/data` | Returns resource data. | | +| `resource/delete` | Deletes a resource. | `delete_document` | +| `resource/duplicate` | Duplicates a resource, and optionally, all of its children. | | +| `resource/emptyrecyclebin` | Empties the recycle bin. | | +| `resource/event/getlist` | Grabs the site schedule data. | | +| `resource/event/updatefromgrid` | Update a resource from the site schedule grid. | | +| `resource/get` | Retrieves a resource by its ID. | `view` | +| `resource/getlist` | Gets a list of resources. | `view` | +| `resource/getnodes` | Get nodes for the resource tree | | +| `resource/gettoolbar` | Gets a dynamic toolbar for the Resource tree. | | +| `resource/locks/release` | Release a lock on a resource | | +| `resource/locks/steal` | Steal a lock on a resource | | +| `resource/publish` | Publishes a resource. | | +| `resource/reload` | save resource form data for reload | | +| `resource/resourcegroup/getlist` | Grabs a list of resource groups for a resource. | | +| `resource/resourcegroup/updatefromgrid` | Assign or unassigns a resource group to a resource. | `resource` | +| `resource/search` | Searches for specific resources and returns them in an array. | `search` | +| `resource/sort` | Sorts the resource tree | | +| `resource/translit` | Retrieves a string and returns it transliterated to use in various applications but mainly for real-time alias | | +| `resource/trash/getlist` | Gets a list of resources for trash manager. | `view` | +| `resource/trash/purge` | Empties the recycle bin. | | +| `resource/trash/restore` | Restores deleted files. | | +| `resource/undelete` | Undeletes a resource. | | +| `resource/unpublish` | Unpublishes a resource. | | +| `resource/update` | Updates a resource. | `save_document` | +| `resource/updatefromgrid` | _(no class docblock)_ | `save_document` | + +## Search + +1 processor. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `search/search` | Searches for elements, resources and users | | + +## Security (users, ACLs, forms, messages) + +128 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `security/access/addacl` | Adds an ACL | `access_permissions` | +| `security/access/flush` | Flushes permissions for the logged in user. | | +| `security/access/getacl` | Gets an ACL. | `access_permissions` | +| `security/access/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/getnodes` | Gets a node list of ACLs | `access_permissions` | +| `security/access/permission/getlist` | _(no class docblock)_ | `access_permissions` | +| `security/access/policy/create` | Create an access policy. | `policy_new` | +| `security/access/policy/duplicate` | Duplicates a policy | `policy_new` | +| `security/access/policy/export` | Export a policy template. | `policy_view` | +| `security/access/policy/getlist` | Gets a list of policies. | `policy_view` | +| `security/access/policy/import` | Import a policy template. | `policy_view` | +| `security/access/policy/remove` | Removes a policy | `policy_delete` | +| `security/access/policy/removemultiple` | Removes multiple policies | `policy_delete` | +| `security/access/policy/template/create` | Create an access policy template | `policy_template_new` | +| `security/access/policy/template/duplicate` | Duplicates a policy template | `policy_template_new` | +| `security/access/policy/template/export` | Export a policy template. | `policy_template_view` | +| `security/access/policy/template/getlist` | Gets a list of policy templates. | `policy_template_view` | +| `security/access/policy/template/group/getlist` | Gets a list of policy template groups. | `policy_template_view` | +| `security/access/policy/template/import` | Import a policy template. | `policy_template_view` | +| `security/access/policy/template/remove` | Removes a policy template | `policy_template_delete` | +| `security/access/policy/template/removemultiple` | Removes multiple policy templates | `policy_template_delete` | +| `security/access/policy/template/update` | Updates a policy template | `policy_template_save` | +| `security/access/policy/template/updatefromgrid` | Update a policy template from a grid | | +| `security/access/policy/update` | Updates a policy | `policy_save` | +| `security/access/policy/updatefromgrid` | Update a policy from a grid | | +| `security/access/removeacl` | Remove an ACL. | `access_permissions` | +| `security/access/updateacl` | Update an ACL. | `access_permissions` | +| `security/access/usergroup/accessnamespace/create` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/accessnamespace/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/usergroup/accessnamespace/remove` | Remove a Resource Group ACL for a user group | `access_permissions` | +| `security/access/usergroup/accessnamespace/update` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/category/create` | Class Create | `access_permissions` | +| `security/access/usergroup/category/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/usergroup/category/remove` | Remove a Resource Group ACL for a user group | `access_permissions` | +| `security/access/usergroup/category/update` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/context/create` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/context/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/usergroup/context/remove` | Remove a context ACL for a user group | `access_permissions` | +| `security/access/usergroup/context/update` | Update ACL for Context | `access_permissions` | +| `security/access/usergroup/resourcegroup/create` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/resourcegroup/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/usergroup/resourcegroup/remove` | Remove a Resource Group ACL for a user group | `access_permissions` | +| `security/access/usergroup/resourcegroup/update` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/source/create` | _(no class docblock)_ | `access_permissions` | +| `security/access/usergroup/source/getlist` | Gets a list of ACLs. | `access_permissions` | +| `security/access/usergroup/source/remove` | Remove a Media Source ACL for a user group | `access_permissions` | +| `security/access/usergroup/source/update` | _(no class docblock)_ | `access_permissions` | +| `security/flush` | Flush all sessions | | +| `security/forms/profile/activate` | Activate a FC Profile | `customize_forms` | +| `security/forms/profile/activatemultiple` | Activate multiple FC Profiles | | +| `security/forms/profile/create` | Create a FC Profile | `customize_forms` | +| `security/forms/profile/deactivate` | Deactivate a FC Profile | `customize_forms` | +| `security/forms/profile/deactivatemultiple` | Deactivate multiple FC Profiles | | +| `security/forms/profile/duplicate` | Duplicate a FC Profile | `customize_forms` | +| `security/forms/profile/getlist` | Gets a list of Form Customization profiles. | `customize_forms` | +| `security/forms/profile/remove` | Remove FC Profile | `customize_forms` | +| `security/forms/profile/removemultiple` | Remove multiple FC profiles | | +| `security/forms/profile/update` | Update a FC Profile | `customize_forms` | +| `security/forms/profile/updatefromgrid` | Update a FC Profile from grid | | +| `security/forms/set/activate` | Activate a FC Set | `customize_forms` | +| `security/forms/set/activatemultiple` | Activate multiple FC Sets | | +| `security/forms/set/create` | Create a FC Set | `customize_forms` | +| `security/forms/set/deactivate` | Deactivate a FC Set | `customize_forms` | +| `security/forms/set/deactivatemultiple` | Deactivate multiple FC Sets | | +| `security/forms/set/duplicate` | Duplicate a FC Set | `customize_forms` | +| `security/forms/set/export` | Export a form customization set. | `customize_forms` | +| `security/forms/set/getlist` | Gets a list of Form Customization sets. | `customize_forms` | +| `security/forms/set/import` | Import a Form Customization Set from an XML file | `customize_forms` | +| `security/forms/set/remove` | Remove a FC Set | `customize_forms` | +| `security/forms/set/removemultiple` | Remove multiple FC sets | | +| `security/forms/set/update` | Saves a Form Customization Set. | `customize_forms` | +| `security/forms/set/updatefromgrid` | Update a FC Profile from grid | `customize_forms` | +| `security/group/create` | Create a user group | `usergroup_new` | +| `security/group/getlist` | Gets a list of user groups | `usergroup_view` | +| `security/group/getnodes` | Get the user groups in tree node format | | +| `security/group/remove` | Remove a user group | `usergroup_delete` | +| `security/group/setting/create` | Create a User Group setting | | +| `security/group/setting/getlist` | Gets a list of user group settings | | +| `security/group/setting/remove` | Remove a user group setting and its lexicon strings | | +| `security/group/setting/update` | Update a user group setting | | +| `security/group/setting/updatefromgrid` | Update a user group setting from a grid | | +| `security/group/sort` | Sort users and user groups, effectively repositioning users into proper groups | | +| `security/group/update` | Update a user group | `usergroup_save` | +| `security/group/user/create` | Add a user to a user group | | +| `security/group/user/getlist` | Gets a list of users in a usergroup | `usergroup_user_list` | +| `security/group/user/remove` | Remove a user from a user group | | +| `security/group/user/update` | Update a users role in a user group | | +| `security/login` | Properly log in the user and set up the session. | | +| `security/logout` | Properly log out the user, running any events and flushing the session. | | +| `security/message/create` | Create a message | `messages` | +| `security/message/getlist` | Get a list of messages | `messages` | +| `security/message/read` | Mark a message as read | `messages` | +| `security/message/remove` | Remove a message | `messages` | +| `security/message/unread` | Mark a message as unread | `messages` | +| `security/profile/changepassword` | Change a user's password | | +| `security/profile/get` | Get a user profile | | +| `security/profile/update` | Update a user profile | | +| `security/resourcegroup/create` | Create a resource group | `resourcegroup_new` | +| `security/resourcegroup/getlist` | Gets a list of resource groups | `resourcegroup_view` | +| `security/resourcegroup/getnodes` | Get the resource groups as nodes | | +| `security/resourcegroup/remove` | Remove a resource group | | +| `security/resourcegroup/removeresource` | Remove a resource-resourcegroup pairing | | +| `security/resourcegroup/update` | Update a resource group | | +| `security/resourcegroup/updateresourcesin` | Update documents in a resource group | `resourcegroup_resource_edit` | +| `security/role/create` | Creates a role from a POST request. | `new_role` | +| `security/role/get` | Gets a role | `view_role` | +| `security/role/getauthoritylist` | Gets a list of roles | | +| `security/role/getlist` | Gets a list of roles | `view_role` | +| `security/role/remove` | Removes a role. | `delete_role` | +| `security/role/update` | Update a role from a POST request | `save_role` | +| `security/role/updatefromgrid` | Updates a role from a grid. Passed as JSON data | | +| `security/user/activatemultiple` | Activate multiple users | | +| `security/user/create` | Create a user | `new_user` | +| `security/user/deactivatemultiple` | Deactivate multiple users | | +| `security/user/delete` | Deletes a user | `delete_user` | +| `security/user/duplicate` | Duplicates a user. | `new_user` | +| `security/user/get` | Get a user | `view_user` | +| `security/user/getlist` | Gets a list of users | `view_user` | +| `security/user/getonline` | Gets a list of all users who are online | | +| `security/user/getrecentlyeditedresources` | Gets a list of recently edited resources by a user | `view_document` | +| `security/user/removemultiple` | Remove multiple users | | +| `security/user/setting/create` | Create a user setting | | +| `security/user/setting/getlist` | Gets a list of user settings | | +| `security/user/setting/remove` | Remove a user setting and its lexicon strings | | +| `security/user/setting/update` | Updates a user setting | | +| `security/user/setting/updatefromgrid` | Updates a setting from a grid | | +| `security/user/update` | Update a user. | `save_user` | +| `security/user/updatefromgrid` | Update a user from a grid | | + +## Software update + +3 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `softwareupdate/base` | Provides base methods and shared properties for building status data used in the front end display of software updates (MODX and Extras) | | +| `softwareupdate/getfile` | Retrieves the downloadable file URL and other metadata for the specified MODX upgrade package | | +| `softwareupdate/getlist` | Retrieves status data for use in the front end display of software updates (MODX and Extras) | | + +## Media Source + +8 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `source/create` | Creates a Media Source | `source_save` | +| `source/duplicate` | Duplicates a source. | `source_save` | +| `source/getlist` | Gets a list of Media Sources | `source_view` | +| `source/remove` | Removes a Media Source | `source_delete` | +| `source/removemultiple` | Removes multiple Media Sources | | +| `source/type/getlist` | Gets a list of media source types | | +| `source/update` | Updates a Media Source | `source_save` | +| `source/updatefromgrid` | Update a Source from the grid. Sent through JSON-encoded 'data' parameter. | | + +## System (settings, menus, dashboards, logs) + +72 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `system/activeresource/getlist` | Gets a list of active resources | `view_document` | +| `system/charset/getlist` | Gets a list of charsets | | +| `system/clearcache` | Refreshes the site cache | | +| `system/configcheck` | Runs a config check | | +| `system/configjs` | Outputs the $modx->config to JSON | | +| `system/console` | Read from the registry to console | | +| `system/contenttype/create` | Create a content type | `content_types` | +| `system/contenttype/getlist` | Gets a list of content types | | +| `system/contenttype/remove` | Removes a content type | `content_types` | +| `system/contenttype/update` | Update a content type from the grid. Sent through JSON-encoded 'data' parameter. | `content_types` | +| `system/contenttype/updatefromgrid` | Update a content type from the grid. Sent through JSON-encoded 'data' parameter. | | +| `system/country/getlist` | Gets a list of country codes | | +| `system/dashboard/create` | Creates a Dashboard | `dashboards` | +| `system/dashboard/duplicate` | Duplicates a dashboard. | `dashboards` | +| `system/dashboard/getlist` | Gets a list of dashboards | `dashboards` | +| `system/dashboard/remove` | Removes a Dashboard | `dashboards` | +| `system/dashboard/removemultiple` | Removes multiple Dashboards | | +| `system/dashboard/update` | Updates a Dashboard | `dashboards` | +| `system/dashboard/updatefromgrid` | Update a Dashboard from the grid. Sent through JSON-encoded 'data' parameter. | | +| `system/dashboard/user/create` | Class Create | | +| `system/dashboard/user/getlist` | Class GetList | | +| `system/dashboard/user/remove` | Class Remove | | +| `system/dashboard/user/resize` | Class Resize | | +| `system/dashboard/user/sort` | Class Sort | | +| `system/dashboard/widget/create` | Creates a new Dashboard Widget | `dashboards` | +| `system/dashboard/widget/feed` | Class modDashboardWidgetFeedProcessor Used to load the news and security feeds on the dashboard over AJAX. The processed feed content (i.e. HTML) is returned in object->html. | | +| `system/dashboard/widget/getlist` | Gets a list of dashboards | `dashboards` | +| `system/dashboard/widget/remove` | Removes a Dashboard Widget | `dashboards` | +| `system/dashboard/widget/removemultiple` | Removes multiple Dashboard Widgets | | +| `system/dashboard/widget/update` | Updates a Dashboard Widget | `dashboards` | +| `system/databasetable/getlist` | Gets a list of database tables | | +| `system/databasetable/mysql/getlist` | MySQL-specific table listing processor | | +| `system/databasetable/mysql/optimize` | _(no class docblock)_ | | +| `system/databasetable/mysql/optimizedatabase` | _(no class docblock)_ | | +| `system/databasetable/mysql/truncate` | _(no class docblock)_ | | +| `system/databasetable/optimize` | Optimize a database table | | +| `system/databasetable/optimizedatabase` | Optimize a database | | +| `system/databasetable/truncate` | Truncate a database table | | +| `system/deprecatedlog/clear` | Clear the error log | | +| `system/deprecatedlog/getlist` | Get a list of system settings | | +| `system/derivatives/getlist` | Gets a list of derivative classes for a class | | +| `system/downloadoutput` | Output data to a file for downloading | | +| `system/errorlog/clear` | Clear the error log | | +| `system/errorlog/download` | Grab and download the error log | | +| `system/errorlog/get` | Grab and output the error log | | +| `system/event/create` | Create a system event | `events` | +| `system/event/getlist` | Gets a list of system events | | +| `system/event/grouplist` | Create a system setting | | +| `system/event/remove` | Remove a system even | `events` | +| `system/info` | Removes locks on all objects | | +| `system/language/getlist` | Grabs a list of lexicon languages | | +| `system/log/getlist` | Gets a list of manager log actions | | +| `system/log/truncate` | Clears the manager log actions | | +| `system/menu/create` | Creates a menu item | `menus` | +| `system/menu/getlist` | Get a list of menu items | `menus` | +| `system/menu/getnodes` | Get the menu items, in node format | `menus` | +| `system/menu/remove` | Remove a menu item | `menus` | +| `system/menu/sort` | Sort menu items for a tree | | +| `system/menu/update` | Update a menu item | `menus` | +| `system/phpinfo` | Display phpinfo() | | +| `system/phpthumb` | Generate a thumbnail | | +| `system/refreshuris` | Regenerate the system's Resource URIs in the database | | +| `system/registry/register/read` | Read from the registry | | +| `system/registry/register/send` | Send a message to the registry. | | +| `system/removelocks` | Removes locks on all objects | | +| `system/rte/getlist` | Get a list of registered RTEs | | +| `system/settings/create` | Create a system setting | `settings` | +| `system/settings/getareas` | Get a list of setting areas | `settings` | +| `system/settings/getlist` | Get a list of system settings | `settings` | +| `system/settings/remove` | Remove a system setting | `settings` | +| `system/settings/update` | Update a system setting | `settings` | +| `system/settings/updatefromgrid` | Update a setting from a grid | | + +## Workspace (packages, lexicon, namespaces) + +37 processors. + +| Action | Description | Permission | +| ------ | ----------- | ---------- | +| `workspace/lexicon/create` | Updates a lexicon entry from a grid | | +| `workspace/lexicon/getlist` | Gets a list of lexicon entries | | +| `workspace/lexicon/reloadfrombase` | Regenerates strings from the base lexicon files, resetting any customizations. | | +| `workspace/lexicon/revert` | Updates a lexicon entry from a grid | | +| `workspace/lexicon/topic/getlist` | Gets a list of lexicon topics | | +| `workspace/lexicon/updatefromgrid` | Updates a lexicon entry from a grid | | +| `workspace/packagenamespace/create` | Creates a namespace | `namespaces` | +| `workspace/packagenamespace/getlist` | Gets a list of namespaces | `namespaces` | +| `workspace/packagenamespace/remove` | Removes a namespace. | `namespaces` | +| `workspace/packagenamespace/removemultiple` | Removes namespaces. | | +| `workspace/packagenamespace/update` | Updates a namespace from a grid | `namespaces` | +| `workspace/packagenamespace/updatefromgrid` | Updates a namespace from a grid | | +| `workspace/packages/checkforupdates` | Update a package from its provider. | | +| `workspace/packages/dependency/download` | Download a package by resolving dependent package constraints | | +| `workspace/packages/get` | Gets a Transport Package. | `packages` | +| `workspace/packages/getattribute` | Gets an attribute of a package | | +| `workspace/packages/getdependencies` | Gets a list of packages | `packages` | +| `workspace/packages/getlist` | Gets a list of packages | `packages` | +| `workspace/packages/install` | Install a package | | +| `workspace/packages/purge` | Purge old package versions | | +| `workspace/packages/remove` | Remove a package | | +| `workspace/packages/rest/download` | Download a package by passing in its location | | +| `workspace/packages/rest/getinfo` | _(no class docblock)_ | | +| `workspace/packages/rest/getlist` | _(no class docblock)_ | | +| `workspace/packages/rest/getnodes` | _(no class docblock)_ | | +| `workspace/packages/scanlocal` | Scans for local packages to add to the workspace. | | +| `workspace/packages/uninstall` | Uninstall a package | | +| `workspace/packages/update` | Gets a chunk. | | +| `workspace/packages/upload` | Upload transport package to Packages directory | | +| `workspace/packages/version/getlist` | Gets a list of package versions for a package | `packages` | +| `workspace/packages/version/remove` | Remove a package | | +| `workspace/providers/create` | Create a provider | `providers` | +| `workspace/providers/getlist` | Gets a list of providers | `providers` | +| `workspace/providers/remove` | Remove a provider | `providers` | +| `workspace/providers/update` | Update a provider | `providers` | +| `workspace/providers/updatefromgrid` | Update a provider from a grid | | +| `workspace/theme/getlist` | Grabs a list of manager themes | `settings` | + diff --git a/en/extending-modx/processors/using-runprocessor.md b/en/extending-modx/processors/using-runprocessor.md index 2ef434788..436bcd334 100644 --- a/en/extending-modx/processors/using-runprocessor.md +++ b/en/extending-modx/processors/using-runprocessor.md @@ -4,49 +4,311 @@ _old_id: "493" _old_uri: "2.x/developing-in-modx/advanced-development/using-runprocessor" --- -The usage of runProcessor described here only work in Revolution 2.0.8 and later. Users prior to that will have to use the deprecated [executeProcessor](extending-modx/modx-class/reference/modx.executeprocessor "modX.executeProcessor") method. - ## Using runProcessor -MODX has a specific method that allows you to run processors straight from any PHP file, such as a [Plugin](extending-modx/plugins "Plugins"), [Snippet](extending-modx/snippets "Snippets") or externally. This can be done with the following syntax: +[`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor) runs a processor from any PHP context that has a `$modx` instance: a [Snippet](extending-modx/snippets), [Plugin](extending-modx/plugins), custom script, or another processor. + +```php +$response = $modx->runProcessor($action, $scriptProperties, $options); +``` + +| Argument | Role | +| -------- | ---- | +| `$action` | Processor to run. In 3.x: full class name, `Resource\Create`, or legacy path `resource/create`. | +| `$scriptProperties` | Data the processor reads via `getProperty()` / `getProperties()`. | +| `$options` | Optional. Main key: `processors_path` for extras outside the core tree. | -> $response = $modx->runProcessor('action/path/to/processor',$arrayOfProperties,$otherOptions); +Returns a `ProcessorResponse` (3.x) / `modProcessorResponse` (2.x). Use `isError()`, `getMessage()`, and `getObject()` (array of returned fields). -This will then execute the specified processor and return a modProcessorResponse object, that contains the response from the processor. That can then be checked to see if the process was a success or failure. The first parameter, or action, is the path to the processor (without the file extension) from the core/model/modx/processors/ directory (This directory can also be overridden in the 3rd parameter array with the param 'processors\_path'). +For how MODX resolves `$action` to a class or file in 3.x, read [Processor loading logic](extending-modx/modx-class/reference/modx.runprocessor#processor-loading-logic). -For example, this code creates a new Chunk: +`runProcessor` exists since Revolution 2.0.8. Older installs used the deprecated [`executeProcessor`](extending-modx/modx-class/reference/modx.executeprocessor). -``` php -$response = $modx->runProcessor('element/chunk/create',array( - 'name' => 'NewChunk', - 'description' => 'A test Chunk made with runProcessor.', - 'snippet' => '

Chunkify!

', -)); +Exact property names differ per processor. When validation fails, open the class under `core/src/Revolution/Processors/` (3.x) or check the [Core processor list](extending-modx/processors/list). + +## Handle the response + +```php +$response = $modx->runProcessor('resource/get', ['id' => 10]); if ($response->isError()) { + if ($response->hasFieldErrors()) { + foreach ($response->getFieldErrors() as $error) { + // $error->getField(), $error->getMessage() + $modx->log(modX::LOG_LEVEL_ERROR, $error->getField() . ': ' . $error->getMessage()); + } + } return $response->getMessage(); } -$chunkArray = $response->getObject(); -return 'The chunk "'.$chunkArray['name'].' was created with ID '.$chunkArray['id']; -``` - -This block of code runs the 'element/chunk/create' processor, checks to see if it was successful (with isError()), and if so, returns a message saying the ID and the name of the new Chunk. Note that getObject returns an **array** of the object that is returned by the processor. getMessage will return any message sent back from the processor. - -You can also create an entire user, including Extended Fields, group assignments, a generated password and email notification. - -``` php -$groups = array(); -$groups['Group1']['usergroup'] = '7'; // ID of group -$groups['Group1']['role'] = '1'; // ID of role -$groups['Group2']['usergroup'] = '8'; -$groups['Group2']['role'] = '1'; -$fields = array(); -$fields['active'] = true; -$fields['passwordgenmethod'] = 'g'; -$fields['passwordnotifymethod'] = 'e'; -$fields['email'] = $email; -$fields['username'] = $username; -$fields['fullname'] = $fullname; -$fields['extended']['container']['name'] = $value; -$fields['groups'] = $groups; +$resource = $response->getObject(); +``` + +`$response->getResponse()` returns the full array (`success`, `message`, `object`, `total`, ...). + +## Resources + +### Create + +```php +$response = $modx->runProcessor('resource/create', [ + 'pagetitle' => 'News item', + 'alias' => 'news-item', + 'content' => '

Body

', + 'parent' => 5, + 'template' => 2, + 'context_key' => 'web', + 'published' => 1, + 'class_key' => 'modDocument', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$id = (int)$response->getObject()['id']; +``` + +### Update + +```php +$response = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => 'News item (edited)', + 'content' => '

Updated body

', + 'published' => 1, +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Get one / list + +```php +$response = $modx->runProcessor('resource/get', ['id' => $id]); +if (!$response->isError()) { + $row = $response->getObject(); +} + +$response = $modx->runProcessor('resource/getlist', [ + 'parent' => 5, + 'start' => 0, + 'limit' => 20, + 'sort' => 'menuindex', + 'dir' => 'ASC', +]); +if (!$response->isError()) { + $payload = $response->getResponse(); + // typically: success, total, results +} +``` + +### Publish, unpublish, delete, undelete, duplicate + +```php +$modx->runProcessor('resource/publish', ['id' => $id]); +$modx->runProcessor('resource/unpublish', ['id' => $id]); +$modx->runProcessor('resource/delete', ['id' => $id]); // soft-delete to recycle bin +$modx->runProcessor('resource/undelete', ['id' => $id]); + +$response = $modx->runProcessor('resource/duplicate', [ + 'id' => $id, + 'name' => 'News item copy', +]); +``` + +Always check `isError()` in real code. These one-liners omit it for brevity. + +## Elements + +### Chunk + +```php +$response = $modx->runProcessor('element/chunk/create', [ + 'name' => 'NewChunk', + 'description' => 'A test Chunk made with runProcessor.', + 'snippet' => '

Chunkify!

', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$chunk = $response->getObject(); +return 'Created Chunk "' . $chunk['name'] . '" with ID ' . $chunk['id']; +``` + +### Snippet + +```php +$response = $modx->runProcessor('element/snippet/create', [ + 'name' => 'HelloUser', + 'description' => 'Returns the username', + 'snippet' => 'return $modx->user->get("username");', +]); +``` + +### Template Variable + +```php +$response = $modx->runProcessor('element/templatevar/create', [ + 'name' => 'articleImage', + 'caption' => 'Article image', + 'type' => 'image', + 'category' => 0, +]); +``` + +In 3.x you can also call `\MODX\Revolution\Processors\Element\TemplateVar\Create::class` as `$action`. + +## Users and auth + +### Login / logout + +```php +$response = $modx->runProcessor('security/login', [ + 'username' => $username, + 'password' => $password, + 'rememberme' => 1, + 'login_context' => 'web', +]); +if ($response->isError()) { + return $response->getMessage(); +} + +$response = $modx->runProcessor('security/logout'); +``` + +### Create a user + +```php +$groups = [ + 'Group1' => [ + 'usergroup' => '7', // user group ID + 'role' => '1', // role ID + ], + 'Group2' => [ + 'usergroup' => '8', + 'role' => '1', + ], +]; +$fields = [ + 'active' => true, + 'passwordgenmethod' => 'g', + 'passwordnotifymethod' => 'e', + 'email' => $email, + 'username' => $username, + 'fullname' => $fullname, + 'extended' => [ + 'container' => [ + 'name' => $value, + ], + ], + 'groups' => $groups, +]; $response = $modx->runProcessor('security/user/create', $fields); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Change password + +```php +$response = $modx->runProcessor('security/profile/changepassword', [ + 'password_old' => $oldPassword, + 'password_new' => $newPassword, + 'password_confirm' => $newPassword, +]); +``` + +Property names can vary by MODX version. Confirm them in the processor class if the call fails. + +## System + +### Clear cache + +```php +$response = $modx->runProcessor('system/clearcache'); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Create a system setting + +```php +$response = $modx->runProcessor('system/settings/create', [ + 'key' => 'myextra.some_flag', + 'value' => '1', + 'xtype' => 'combo-boolean', + 'namespace' => 'myextra', + 'area' => 'myextra', +]); ``` + +## Files (media browser) + +Upload and filesystem processors expect media-source paths and manager permissions. Typical actions: `browser/file/upload`, `browser/file/remove`, `browser/directory/create`. Pass the same fields the manager file tree sends (source, path, file). From a web Snippet you rarely call these unless the user is authenticated for `mgr` (or you opened that context on purpose). + +```php +// Example shape only: required keys depend on source and request +$response = $modx->runProcessor('browser/directory/create', [ + 'name' => 'exports', + 'parent' => '/', + 'source' => 1, +]); +``` + +## 3.x class name as action + +```php +use MODX\Revolution\Processors\Resource\Create; + +$response = $modx->runProcessor(Create::class, [ + 'pagetitle' => 'Via FQCN', + 'context_key' => 'web', +]); +``` + +## Nest core processors inside your own + +```php +$response = $modx->runProcessor('resource/create', $resourceData); +if ($response->isError()) { + return $this->failure($response->getMessage()); +} +$id = (int)$response->getObject()['id']; + +$tvResponse = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => $resourceData['pagetitle'], + // include TV values the update processor expects for your setup +]); +``` + +Plugins on Resource save still run for each successful core call. + +## Custom processor path + +```php +$response = $modx->runProcessor( + 'mgr/item/update', + ['id' => 12, 'name' => 'Updated'], + [ + 'processors_path' => $modx->getOption('core_path') + . 'components/myextra/processors/', + ] +); +``` + +## Permissions from the front end + +Many core processors need manager permissions. From a `web` Snippet either: + +1. Run as a user who already has those policies in `web`, or +2. Initialize the manager context for trusted/internal scripts only: `$modx->initialize('mgr');` + +Do not expose privileged processors on public forms without your own auth and CSRF checks. + +## See also + +- [Processors overview](extending-modx/processors) +- [Core processor list](extending-modx/processors/list) +- [modX.runProcessor](extending-modx/modx-class/reference/modx.runprocessor) +- [Connectors](extending-modx/processors/connectors) diff --git a/ru/extending-modx/processors/connectors.md b/ru/extending-modx/processors/connectors.md index 1fad0cf80..65623aa11 100644 --- a/ru/extending-modx/processors/connectors.md +++ b/ru/extending-modx/processors/connectors.md @@ -1,15 +1,62 @@ --- title: "Коннекторы" translation: "extending-modx/processors/connectors" -note: "Это заглушка. Вы можете помочь, расширив это." --- -Коннекторы - это простые PHP-файлы, которые могут использоваться для предоставления своих процессоров пользователям manager. +## Что такое коннектор -Коннектор ядра `connectors/index.php` - данный файл полезен при создании собственных коннекторов. Для этого нужно включить этот файл в коннекторы, а затем обработать запрос, используя `$modx->request->handleRequest();`. +Коннектор: PHP-вход для AJAX (и похожих) запросов, которые должны запустить [процессор](extending-modx/processors). Он поднимает MODX, проверяет, что пользователь может загрузить контекст, и передаёт запрос в `modX::request->handleRequest()`, а тот вызывает [`runProcessor`](extending-modx/modx-class/reference/modx.runprocessor). -Здесь содержаться точки входа для AJAX-запросов, которые в свою очередь не делают никаких манипуляций с базой данных; они просто загружают главный класс MODX, затем проверяют данные запроса, и обрабатывают запрос, указав на соответствующий файл процессора. +Сам коннектор базу не меняет. Это делают процессоры. -Поэтому дополнительные компоненты обычно помещают свои собственные в `assets/components/NAME-of-EXTRA/connector.php`, и используют это для своих собственных [пользовательских страниц менеджера](extending-modx/custom-manager-pages). +## Коннектор ядра -Например, когда мы создаем ресурс, мы спрашиваем `connectors/resource/index.php?action=create`. Файл `index.php` будет включать в себя базовый файл `connectors/index.php` , который инициализирует MODX, обрабатывать любые пользовательские переключения, и сканировать `GET` или `POST` запросы. `connectors/resource/index.php` будет «обрабатывать» запрос и вызывать нужный файл процессор. +Запросы менеджера к действиям ядра идут через файлы в `connectors/`, которые подключают [`connectors/index.php`](https://github.com/modxcms/revolution/blob/3.x/connectors/index.php). Этот bootstrap: + +1. Создаёт экземпляр MODX и инициализирует контекст (по умолчанию `mgr`, либо `ctx` из запроса). +2. Проверяет политику `load`, если действие не помечено как анонимное (например `security/login`). +3. Санитизирует запрос и направляет `action` в процессор ядра. + +Типичный запрос: ExtJS-сетка шлёт POST на URL коннектора с `action=resource/getlist` (плюс заголовки авторизации, которые добавляет MODExt). + +## Коннекторы дополнений + +Коннектор ядра знает только пути процессоров ядра. Дополнения кладут свой файл, обычно: + +`assets/components/myextra/connector.php` + +Шаблон (как в [Developing an Extra, Part II](extending-modx/tutorials/developing-an-extra/part-2)): + +```php +getOption( + 'myextra.core_path', + null, + $modx->getOption('core_path') . 'components/myextra/' +); +// при необходимости загрузите сервис и лексикон … + +$modx->request->handleRequest([ + 'processors_path' => $corePath . 'processors/', + 'location' => '', +]); +``` + +`processors_path` указывает, где лежат `{action}.class.php`. Параметр `baseParams.action` сетки (например `mgr/item/getlist`) соответствует `processors/mgr/item/getlist.class.php`. + +## Авторизация и CSRF + +Коннекторы ждут сессию менеджера (если вы сами не открыли анонимное действие) и токен сайта. MODExt передаёт его заголовком `modAuth` (или `HTTP_MODAUTH` в запросе). Значение: `$modx->siteId`. Не публикуйте его в репозитории и клиентской документации. + +Открыть URL коннектора в браузере без сессии и без `action` обычно даёт JSON вроде `success: false` / access denied. Так и задумано. + +## См. также + +- [Процессоры](extending-modx/processors) +- [Список процессоров ядра](extending-modx/processors/list) +- [Пользовательские страницы менеджера](extending-modx/custom-manager-pages) +- [MODExt FormPanel](extending-modx/custom-manager-pages/modext/modx.formpanel): отправка через URL коннектора diff --git a/ru/extending-modx/processors/index.md b/ru/extending-modx/processors/index.md index cf6017b2b..0e7dc60c8 100644 --- a/ru/extending-modx/processors/index.md +++ b/ru/extending-modx/processors/index.md @@ -1,108 +1,273 @@ --- title: "Процессоры" translation: "extending-modx/processors" -description: "Процессоры можно сравнить с командами или действиями, это такие PHP скрипты, которые могут выполнять определенные функции" +description: "Процессоры: PHP-классы, которые выполняют одно действие: создать ресурс, отдать список, авторизовать пользователя" --- -## Процессоры в MODX +## Что такое процессор -Процессоры можно сравнить с "командами" или "действиями". До MODX 2.2 они были "простыми" PHP-файлами, но с тех пор они были переписаны на базе `modProcessor` класса, и его различных подтипов. +Процессор: PHP-класс, который выполняет **одно** действие в MODX: создать чанк, отдать список ресурсов, авторизовать пользователя, загрузить файл. Интерфейс менеджера, коннекторы, сниппеты и плагины ходят к одним и тем же действиям через процессоры. -Итак, мы говорим про файлы-процессоры, это такие PHP скрипты, которые могут выполнять определенные функции. Для наглядности загляните в [/core/model/modx/processors](https://github.com/modxcms/revolution/tree/2.x/core/model/modx/processors), и вы увидите, как их много. +С MODX 2.2 процессоры классовые (наследники базового класса процессора). Плоские `.php`-файлы без класса в MODX 3.0 больше не поддерживаются. -Работать с процессорами можно из любого Cниппета или Плагина при помощи метода [runProcessor](extending-modx/processors/using-runprocessor): +Где лежат процессоры ядра: -``` php -$response = $modx->runProcessor('action/path/to/processor',$arrayOfProperties,$otherOptions); +- **3.x:** [`core/src/Revolution/Processors/`](https://github.com/modxcms/revolution/tree/3.x/core/src/Revolution/Processors) +- **2.x:** `core/model/modx/processors/` (старая раскладка) + +Полный каталог действий ядра (путь, краткое описание из docblock, `$permission`): [Список процессоров ядра](extending-modx/processors/list). + +Из PHP их вызывают через [`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor). AJAX менеджера идёт через [коннектор](extending-modx/processors/connectors) и в итоге попадает в тот же метод. + +```php +$response = $modx->runProcessor( + 'resource/create', + $properties, + $options // опционально; для процессоров ядра часто не нужен +); +``` + +`$response`: [`ProcessorResponse`](https://github.com/modxcms/revolution/blob/3.x/core/src/Revolution/Processors/ProcessorResponse.php) (3.x) / `modProcessorResponse` (2.x). Сначала проверьте ошибку, потом читайте данные: + +```php +if ($response->isError()) { + return $response->getMessage(); +} +$object = $response->getObject(); // массив полей из ответа процессора ``` -В ответ мы получаем объект [modProcessorResponse](https://github.com/modxcms/revolution/blob/df90fecfdfcf719cabe171ea3db59e47f45d7ee9/core/model/modx/modprocessor.class.php), со всеми его методами. +Полезные методы: `isError()`, `getMessage()`, `getObject()`, `getResponse()`, `hasFieldErrors()`, `getFieldErrors()`. + +### Как работает `run()` + +При запуске процессора MODX делает примерно следующее (см. `Processor::run()`): + +1. `checkPermissions()`: при отказе вернётся ответ с ошибкой прав. +2. Загрузка лексиконов из `getLanguageTopics()`. +3. `initialize()`: должен вернуть `true`, иначе возвращённое значение станет текстом ошибки. +4. `process()`: основная работа. Model-хелперы (`CreateProcessor`, `GetListProcessor`, ...) задают фиксированный пайплайн с хуками, которые вы переопределяете. + +В классе читайте вход через `getProperty()` / `getProperties()`, пишите через `setProperty()`, завершайте через `$this->success($message, $object)` или `$this->failure($message)`. Ошибки полей: `addFieldError('field', $msg)`, чтобы формы MODExt подсветили инпуты. + +### Права и контекст + +У многих процессоров есть `public $permission = 'save_document';` (или похожее). Пользователь в **текущем** контексте `$modx` должен пройти эту проверку (и всё, что добавит `checkPermissions()`). Контроллеры и коннекторы обычно инициализируют `mgr`. Из веб-сниппета может понадобиться `$modx->initialize('mgr')` или пользователь с нужными политиками в `web`. Иначе вызов падает, хотя PHP выглядит корректно. + +### Формы action в 3.x -## Стандартные процессоры +Для процессоров ядра это эквивалентно: -К примеру, в каталоге `security` есть процессоры `login` и `logout`, которые управляют авторизацией пользователей. Вот как мы можем его авторизовать: +| Форма | Пример | +| ----- | ------ | +| Путь со слэшем (стиль 2.x) | `resource/create` | +| Относительный namespace | `Resource\Create` | +| Полное имя класса | `\MODX\Revolution\Processors\Resource\Create` | -``` php -$username = 'ivanpetrov'; -$password = '*********'; -$data = array( +Особый случай: Template Variables лежат в `Element\TemplateVar\...`. Путь `element/templatevar/create` работает. Устаревший `element/tv/...` лоадер переписывает в `TemplateVar`. Подробности: [логика загрузки](extending-modx/modx-class/reference/modx.runprocessor#processor-loading-logic). + +## Берите процессоры ядра + +Если нужное действие уже есть в MODX, вызывайте его процессор вместо сырого `newObject()` / `save()`. Так вы получаете права, валидацию, генерацию `alias` и события плагинов (`OnDocFormSave` и другие). Дополнения, которые слушают эти события, продолжают работать с вашим кодом. + +Что есть в ядре: [Список процессоров ядра](extending-modx/processors/list) (Browser, Context, Element, Resource, Security, System, Workspace, ...). + +### Вход и выход + +```php +$data = [ 'username' => $username, 'password' => $password, 'rememberme' => 1, 'login_context' => 'web', -); -$response = $modx->runProcessor('/security/login', $data); +]; +$response = $modx->runProcessor('security/login', $data); if ($response->isError()) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Ошибка авторизации. Имя пользователя: '.$username.', Сообщение: '.$response->getMessage()); + $modx->log( + modX::LOG_LEVEL_ERROR, + 'Ошибка входа для ' . $username . ': ' . $response->getMessage() + ); } ``` -Выход с сайта и того проще: +```php +$response = $modx->runProcessor('security/logout'); +if ($response->isError()) { + $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage()); +} +``` -``` php -$response = $modx->runProcessor('/security/logout'); +В 3.x можно передать и namespaced-класс, например `\MODX\Revolution\Processors\Security\Login`. + +### Создание ресурса + +```php +$response = $modx->runProcessor('resource/create', [ + 'pagetitle' => 'Моя страница', + 'content' => '

Привет

', + 'parent' => 0, + 'template' => 1, + 'context_key' => 'web', +]); if ($response->isError()) { - $modx->log(modX::LOG_LEVEL_ERROR, 'Ошибка разавторизации. Имя пользователя: '.$modx->user->get('username').', UID: '.$modx->user->get('id').'. Сообщение: '.$response->getMessage()); + return $response->getMessage(); } +$id = $response->getObject()['id']; ``` -Это очень удобно и гарантирует, что компонент будет работать во всех версиях MODX. Поэтому, если возможно, всегда нужно использовать стандартные процессоры. +Ненужные поля можно не передавать. Процессор подставит значения по умолчанию из системных настроек. Для своего типа ресурса укажите `class_key`. -Конечно, стандартные процессоры не умеют работать с вашими расширениями. +Типичные create/update процессоры стреляют событиями до/после сохранения (для ресурсов: то же семейство событий, что и в менеджере). Поэтому поисковые индексаторы и другие плагины видят и программные сохранения. -## Собственные процессоры +### Создание чанка -Использование своих процессоров отличается от стандартных только тем, что нужно указать директорию, откуда их брать. Смотрим пример из [miniShop2](https://minishop2.com): +```php +$response = $modx->runProcessor('element/chunk/create', [ + 'name' => 'HelloBox', + 'description' => 'Создано из сниппета', + 'snippet' => '
[[*pagetitle]]
', +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` -``` php -// Массив, который мы передадим в процессор, там его ловить в $scriptProperties -$processorProps = array( - 'id' => 55 -); -// Массив опций для метода runProcessor -$otherProps = array( - // Здесь указываем где лежат наши процессоры - 'processors_path' => $modx->getOption('core_path') . 'components/minishop/processors/' +Больше примеров из сниппетов (update/delete/publish, сниппет/TV, настройки, кэш, ошибки полей, FQCN): [Использование runProcessor](extending-modx/processors/using-runprocessor). + +### Обновление ресурса + +```php +$response = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => 'Моя страница (правка)', + 'published' => 1, +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Очистка кэша + +```php +$response = $modx->runProcessor('system/clearcache'); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Списки и гриды + +Процессоры `GetList` кормят ExtJS-сетки. Они ждут paging/sort вроде `start`, `limit`, `sort`, `dir`, часто ещё `query`. В JSON обычно есть `success`, `total` и `results` (точные ключи зависят от процессора). Из PHP: + +```php +$response = $modx->runProcessor('resource/getlist', [ + 'start' => 0, + 'limit' => 10, + 'sort' => 'pagetitle', + 'dir' => 'ASC', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$data = $response->getResponse(); +``` + +## Свои процессоры + +Дополнения держат процессоры в своём дереве, обычно `core/components/myextra/processors/`. Укажите этот каталог в `processors_path`: + +```php +$response = $modx->runProcessor( + 'web/orders/getlist', + ['id' => 55], + [ + 'processors_path' => $modx->getOption('core_path') + . 'components/myextra/processors/', + ] ); -// Запускаем -$response = $modx->runProcessor('web/orders/getlist', $processorProps, $otherProps); -// И возвращаем ответ от процессора -return $response->response; +if ($response->isError()) { + return $response->getMessage(); +} +return $modx->toJSON($response->getResponse()); ``` -Это чуть измененный пример из сниппета miniShop, где он [обрабатывает запросы личного кабинета](https://github.com/bezumkin/miniShop/blob/master/core/components/minishop/elements/snippets/minishop.php#L26). +В `action` нет расширения файла. MODX ищет `{processors_path}web/orders/getlist.class.php` и ждёт класс процессора (или угадывает имя вида `modFooBarProcessor`). Коннектор делает то же самое: задаёт `processors_path` и маршрутизирует `action` в файл. -Как вы видите, процессор для запуска указывается без расширения, путем от каталога процессоров. Если мы не указываем свой каталог, то это будет `/core/model/modx/processors/` по умолчанию. В примере выше — мы ее меняем на каталог внутри компонента miniShop. +Имена файлов в extras: `mgr/item/getlist.class.php` и action `mgr/item/getlist`. Возврат `MyExtra\\Processors\\Item\\GetList::class` из файла снимает неоднозначность с угадыванием класса. -## Стандартный процессор внутри собственного +### Вызов процессора ядра из своего -Вот и самое интересное! Смотрим пример: +Внутри своего create-процессора можно сначала вызвать ядерный, затем дописать свои данные: -``` php -$response = $modx->runProcessor('resource/create', $_POST); +```php +$response = $modx->runProcessor('resource/create', $resourceData); if ($response->isError()) { - return $modx->error->failure($response->getMessage()); + return $this->failure($response->getMessage()); } +$id = $response->getObject()['id']; +// дальше привяжите свои записи к $id ... +``` + +Плагины на сохранение ресурса сработают. `alias` и остальное поведение ядра совпадут с менеджером. + +## Классовый процессор -$id = $response->response['object']['id']; +Минимальный create-процессор для своего xPDO-объекта (имена классов 3.x): + +```php +getProperty('name')); + if ($name === '') { + $this->addFieldError('name', $this->modx->lexicon('myextra.item_err_name')); + } + return parent::beforeSet(); + } +} + +return Create::class; ``` -В этом примере мы создаем стандартным процессором новый ресурс из присланных данных, и получаем из ответа `id` этого ресурса, для дальнейшей работы. -[Вот исходный код](https://github.com/bezumkin/miniShop/blob/master/core/components/minishop/processors/mgr/goods/create.php) всего процессора miniShop для создания нового товара. +Порядок `CreateProcessor::process()` (упрощённо): `beforeSet` → `fromArray` → `beforeSave` → validate → событие до сохранения → `saveObject` → `afterSave` → событие после сохранения → `cleanup`. + +Для списков наследуйте `GetListProcessor` и фильтруйте в `prepareQueryBeforeCount` / `prepareQueryAfterCount`. Фильтры читайте через `$this->getProperty('resource_id')` (или что вы положили в `baseParams` сетки). Из панели ресурса само ничего не подставится, пока JS это не отправит. -При таком подходе гарантируется, что независимо от будущих изменений в MODX свой процессор будет работать во всех версиях. И, что очень важно, **будут работать плагины**, которые должны работать при создании новых ресурсов. Также будет сгенерирован `alias` (если вы их используете), причем как это указано в настройках, через транслитерацию, или нет. -Таким же образом работает и обновление товаров, а например [mSearch](https://docs.modx.pro/en/components/msearch2), ловит событие `OnDocFormSave` и индексирует этот ресурс. +Частые model-хелперы (полный список: в [заметках по апгрейду 3.0](getting-started/upgrading-to-3.0/processors)): -Конечно, можно не использовать в таких случаях `runProcessor`, а работать через `newObject` — но тогда нужно самостоятельно генерировать события для плагинов, определять незаданные поля нового ресурса, генерировать `alias` и еще много чего. -Зачем, если MODX все это уже предусмотрел? +| Задача | Класс 3.x | +| ------ | --------- | +| Create | `\MODX\Revolution\Processors\Model\CreateProcessor` | +| Update | `\MODX\Revolution\Processors\Model\UpdateProcessor` | +| Get | `\MODX\Revolution\Processors\Model\GetProcessor` | +| Get list | `\MODX\Revolution\Processors\Model\GetListProcessor` | +| Remove | `\MODX\Revolution\Processors\Model\RemoveProcessor` | -## Заключение +В 2.x те же роли: `modObjectCreateProcessor`, `modObjectGetListProcessor` и т.д. Чаще всего переопределяют `initialize`, `beforeSet`, `beforeSave`, `afterSave`, для списков: `prepareQueryBeforeCount`. -Процессоры — отличная вещь и нужно использовать их по-максимуму, везде, во всех своих Сниппетах. Если вы хотите сделать что-то с ресурсом или другим элементом — посмотрите, нет ли для этого готового процессора в системе? -Если есть — используйте его. Это оградит вас от лишней головной боли, и позволит другим расширениям и плагинам взаимодействовать с вашим кодом. +## Дальше -## Смотрите также +- [Список процессоров ядра](extending-modx/processors/list): все action ядра с краткими описаниями +- [Использование runProcessor](extending-modx/processors/using-runprocessor): примеры из сниппетов +- [modX.runProcessor](extending-modx/modx-class/reference/modx.runprocessor): параметры и правила загрузки в 3.x +- [Коннекторы](extending-modx/processors/connectors): AJAX-вход для CMP +- [Процессоры в гайде по апгрейду на 3.0](getting-started/upgrading-to-3.0/processors) +- [Developing an Extra, Part II](extending-modx/tutorials/developing-an-extra/part-2): коннектор и getlist +- [Class-based processors](https://www.markhamstra.com/xpdo/2012/getting-started-with-class-based-processors-2.2/) и [modObjectGetListProcessor](https://www.markhamstra.com/xpdo/2012/modobjectgetlistprocessor-class-based-processor/) (Mark Hamstra) +- [Список процессоров на Bob's Guides](https://bobsguides.com/modx-processor-list.html) (в основном пути 2.x) -- [Начало работы с процессорами на основе классов](https://www.markhamstra.com/xpdo/2012/getting-started-with-class-based-processors-2.2/) (at markhamstra.com) -- [Расширение modObjectGetListProcessor, мощный процессор на основе классов в MODX 2.2](https://www.markhamstra.com/xpdo/2012/modobjectgetlistprocessor-class-based-processor/) (at markhamstra.com) -- [Полный список процессоров MODX](https://bobsguides.com/modx-processor-list.html) (at bobsguides.com) +Материал опирается в том числе на статью [«Процессоры в MODX»](https://modx.pro/development/3156) на modx.pro, с правками под актуальные пути и классы 3.x. diff --git a/ru/extending-modx/processors/list.md b/ru/extending-modx/processors/list.md new file mode 100644 index 000000000..2ecac0b93 --- /dev/null +++ b/ru/extending-modx/processors/list.md @@ -0,0 +1,470 @@ +--- +title: "Список процессоров ядра" +translation: "extending-modx/processors/list" +description: "Каталог процессоров ядра MODX 3.x: action-пути, краткие описания и permissions" +--- + +## Список процессоров ядра (MODX 3.x) + +Ниже: **вызываемые процессоры ядра** из `core/src/Revolution/Processors/`. Для [`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor) используйте путь со слэшем (`resource/create`) или namespaced-класс (`\\MODX\\Revolution\\Processors\\Resource\\Create`). + +Заметки: + +- Описания переведены с docblock классов и свойства `$permission` в MODX Revolution **3.x**. Термины ACL, FC (Form Customization), TV, Media Source оставлены как в ядре. +- Не включены абстрактные базы, хелперы `Model\\*Processor` и Template Variable Configs/Renders (куски UI менеджера, обычно не цели для `runProcessor`). +- У Template Variables каталог: `Element/TemplateVar/`. Путь `element/templatevar/` резолвится. Устаревший `element/tv/` лоадер переписывает в TemplateVar. +- Permission: свойство `$permission` класса, если задано. Пустая ячейка значит, что свойства нет (проверка прав может быть в `checkPermissions()` или в другом месте). +- Нужные поля у каждого процессора свои. Если валидация падает, откройте файл класса. + +В каталоге: **379** процессоров. + +См. также: [Процессоры](extending-modx/processors), [Использование runProcessor](extending-modx/processors/using-runprocessor). + +## Browser (файлы и каталоги) + +16 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `browser/directory/create` | Создаёт каталог. | `directory_create` | +| `browser/directory/getfiles` | Получает все файлы в каталоге | `file_list` | +| `browser/directory/getlist` | Получает список каталогов и файлов, отсортировав их сначала по папке/файлу, а затем по алфавиту. | `directory_list` | +| `browser/directory/remove` | Удаляет каталог | `directory_remove` | +| `browser/directory/rename` | Переименовывает каталог | `directory_update` | +| `browser/directory/sort` | Сортирует каталог. | `directory_update` | +| `browser/directory/update` | Переименовывает каталог. | | +| `browser/file/create` | Создаёт файл. | `file_create` | +| `browser/file/download` | Отправляет файл пользователю | `file_view` | +| `browser/file/get` | Получает содержимое файла | `file_view` | +| `browser/file/remove` | Удаляет файл. | `file_remove` | +| `browser/file/rename` | Переименовывает файл | `file_update` | +| `browser/file/unpack` | Распаковывает архивы, на данный момент только zip | `file_unpack` | +| `browser/file/update` | Обновляет файл. | `file_update` | +| `browser/file/upload` | Загружает файлы в каталог | `file_upload` | +| `browser/visibility` | Устанавливает видимость каталога или файла | `directory_chmod` | + +## Context + +19 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `context/create` | Создаёт контекст | `new_context` | +| `context/duplicate` | Дублирует контекст. | `new_context` | +| `context/get` | Получает контекст. | `view_context` | +| `context/getlist` | Получает список контекстов. | `view_context` | +| `context/group/create` | Создаёт контекстную группу. | `new_context` | +| `context/group/get` | Получает контекстную группу. | `view_context` | +| `context/group/getlist` | Получает список контекстных групп. | `view_context` | +| `context/group/remove` | Удаляет группу контекстов и снимает назначение ее контекстов. | `delete_context` | +| `context/group/update` | Обновляет группу контекста. | `edit_context` | +| `context/group/updatefromgrid` | Обновляет группу контекста из строки сетки (данные JSON). | | +| `context/remove` | Удаляет контекст | `delete_context` | +| `context/setting/create` | Создаёт настройку контекста | `settings` | +| `context/setting/get` | Получает настройку контекста | `settings` | +| `context/setting/getlist` | Получает список настроек контекста | `settings` | +| `context/setting/remove` | Удаляет настройку контекста. | | +| `context/setting/update` | Обновляет настройку контекста | | +| `context/setting/updatefromgrid` | Обновляет настройку из сетки. Передается как данные JSON. | | +| `context/update` | Обновляет контекст. | `edit_context` | +| `context/updatefromgrid` | Обновляет контекст из сетки. Передается как данные JSON. | | + +## Element (чанки, сниппеты, плагины, шаблоны, TV, наборы свойств) + +68 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `element/category/create` | Создаёт категорию. | `save_category` | +| `element/category/get` | Получает категорию. | `view_category` | +| `element/category/getlist` | Захватывает список категорий. | | +| `element/category/remove` | Удаляет категорию. Сбрасывает все элементы этой категории в 0. | `delete_category` | +| `element/category/update` | Обновляет категорию. | `save_category` | +| `element/chunk/create` | Создаёт чанк. | `new_chunk` | +| `element/chunk/duplicate` | Дублирует фрагмент. | `new_chunk` | +| `element/chunk/get` | Получает кусок. | `view_chunk` | +| `element/chunk/getlist` | Захватывает список кусков. | `view_chunk` | +| `element/chunk/remove` | Удаляет кусок. | `delete_chunk` | +| `element/chunk/update` | Обновляет чанк. | `save_chunk` | +| `element/duplicate` | Абстрактный класс для процессоров дублирования элементов. Расширяется для каждого типа элемента. | | +| `element/exportproperties` | Экспортирует свойства и выходной URL-адрес для загрузки в браузер. | | +| `element/getclasses` | Выводит список подклассов Element. | | +| `element/getinsertproperties` | Возвращает свойства элемента для диалога вставки. | | +| `element/getlistbyclass` | Получает список элементов по их подклассу | | +| `element/getnodes` | Захватывает все элементы дерева элементов | | +| `element/importproperties` | Импортирует свойства из файла | | +| `element/plugin/activate` | Активирует плагин. | `save_plugin` | +| `element/plugin/create` | Создаёт плагин | `new_plugin` | +| `element/plugin/deactivate` | Деактивирует плагин. | `save_plugin` | +| `element/plugin/duplicate` | Дублирует плагин | `new_plugin` | +| `element/plugin/event/associate` | Связывает событие с плагинами. | `save_plugin` | +| `element/plugin/event/get` | Получает событие плагина | `view_plugin` | +| `element/plugin/event/getassoc` | Получает список плагинов, связанных с системным событием. | `view_plugin` | +| `element/plugin/event/getlist` | Получает список системных событий | `view_plugin` | +| `element/plugin/event/remove` | Удаляет событие из плагина | `delete_plugin` | +| `element/plugin/event/update` | Обновляет событие плагина | `save_plugin` | +| `element/plugin/event/updatefromgrid` | Обновляет событие плагина из сетки | | +| `element/plugin/get` | Получает плагин | `view_plugin` | +| `element/plugin/getlist` | Захватывает список плагинов. | `view_plugin` | +| `element/plugin/remove` | Удаляет плагин. | `delete_plugin` | +| `element/plugin/update` | Обновляет плагин. | `save_plugin` | +| `element/propertyset/addelement` | Добавляет элемент в набор свойств. | `save_propertyset` | +| `element/propertyset/associate` | Связывает набор свойств с элементом или создаёт набор свойств. | | +| `element/propertyset/create` | Создаёт набор свойств | `new_propertyset` | +| `element/propertyset/duplicate` | Дублирует набор свойств | `new_propertyset` | +| `element/propertyset/get` | Захватывает набор свойств | `view_propertyset` | +| `element/propertyset/getlist` | Получает список наборов свойств для создания раскрывающихся (комбинированных) полей. | `view_propertyset` | +| `element/propertyset/getnodes` | Захватывает все элементы дерева набора свойств. | `view_propertyset` | +| `element/propertyset/getproperties` | Получает свойства для набора свойств. | | +| `element/propertyset/remove` | Удаляет набор свойств | `delete_propertyset` | +| `element/propertyset/removeelement` | Удаляет элемент из набора свойств. | `delete_propertyset` | +| `element/propertyset/update` | Обновляет набор свойств | `save_propertyset` | +| `element/propertyset/updatefromelement` | Сохраняет набор свойств | | +| `element/snippet/create` | Создаёт фрагмент. | `new_snippet` | +| `element/snippet/duplicate` | Дублирует фрагмент. | `new_snippet` | +| `element/snippet/get` | Получает фрагмент. | `view_snippet` | +| `element/snippet/getlist` | Захватывает список фрагментов. | `view_snippet` | +| `element/snippet/remove` | Удаляет фрагмент. | `delete_snippet` | +| `element/snippet/update` | Обновляет фрагмент | `save_snippet` | +| `element/sort` | Сортирует элементы в дереве элементов. | | +| `element/template/create` | Создаёт шаблон | `new_template` | +| `element/template/duplicate` | Дублирует шаблон. | `new_template` | +| `element/template/get` | Получает шаблон | `view_template` | +| `element/template/getlist` | Захватывает список шаблонов. | `view_template` | +| `element/template/remove` | Удаляет шаблон. | `delete_template` | +| `element/template/templatevar/getlist` | Получает список TVов, отмечая те, которые связаны с шаблоном. | | +| `element/template/update` | Обновляет шаблон | `save_template` | +| `element/templatevar/create` | Создаёт переменную шаблона. | `new_tv` | +| `element/templatevar/duplicate` | Дублирует TV | `new_tv` | +| `element/templatevar/get` | Получает TV | `view_tv` | +| `element/templatevar/getlist` | Захватывает список TVов. | `view_tv` | +| `element/templatevar/remove` | Удаляет TV | `delete_tv` | +| `element/templatevar/resourcegroup/getlist` | Получает список групп ресурсов, связанных с TV. | | +| `element/templatevar/template/getlist` | Получает список шаблонов, связанных с TV. | | +| `element/templatevar/template/updatefromgrid` | Назначает или снимает назначение шаблона для TV. Данные передаются в JSON. | | +| `element/templatevar/update` | Обновляет TV | `save_tv` | + +## Resource + +27 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `resource/create` | Создаёт ресурс. | `new_document` | +| `resource/data` | Возвращает данные ресурса. | | +| `resource/delete` | Удаляет ресурс. | `delete_document` | +| `resource/duplicate` | Дублирует ресурс и, при необходимости, все его дочерние элементы. | | +| `resource/emptyrecyclebin` | Очищает корзину. | | +| `resource/event/getlist` | Собирает данные расписания сайта. | | +| `resource/event/updatefromgrid` | Обновляет ресурс из сетки расписания сайта. | | +| `resource/get` | Извлекает ресурс по его идентификатору. | `view` | +| `resource/getlist` | Получает список ресурсов. | `view` | +| `resource/getnodes` | Получает узлы для дерева ресурсов | | +| `resource/gettoolbar` | Получает динамическую панель инструментов для дерева ресурсов. | | +| `resource/locks/release` | Снять блокировку ресурса | | +| `resource/locks/steal` | Украсть блокировку ресурса | | +| `resource/publish` | Публикует ресурс. | | +| `resource/reload` | сохранить данные формы ресурса для перезагрузки | | +| `resource/resourcegroup/getlist` | Получает список групп ресурсов для ресурса. | | +| `resource/resourcegroup/updatefromgrid` | Назначает или снимает назначение группы ресурсов для ресурса. | `resource` | +| `resource/search` | Ищет определенные ресурсы и возвращает их в массиве. | `search` | +| `resource/sort` | Сортирует дерево ресурсов | | +| `resource/translit` | Извлекает строку и возвращает ее в транслитерированном виде для использования в различных приложениях, но в основном для псевдонима в реальном времени. | | +| `resource/trash/getlist` | Получает список ресурсов для диспетчера мусора. | `view` | +| `resource/trash/purge` | Очищает корзину. | | +| `resource/trash/restore` | Восстанавливает удаленные файлы. | | +| `resource/undelete` | Восстанавливает ресурс. | | +| `resource/unpublish` | Отменяет публикацию ресурса. | | +| `resource/update` | Обновляет ресурс. | `save_document` | +| `resource/updatefromgrid` | _(нет docblock у класса)_ | `save_document` | + +## Search + +1 процессор. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `search/search` | Поиск элементов, ресурсов и пользователей | | + +## Security (пользователи, ACL, формы, сообщения) + +128 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `security/access/addacl` | Добавляет ACL | `access_permissions` | +| `security/access/flush` | Сбрасывает разрешения для вошедшего в систему пользователя. | | +| `security/access/getacl` | Получает ACL. | `access_permissions` | +| `security/access/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/getnodes` | Получает список узлов ACL. | `access_permissions` | +| `security/access/permission/getlist` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/policy/create` | Создаёт политику доступа. | `policy_new` | +| `security/access/policy/duplicate` | Дублирует политику | `policy_new` | +| `security/access/policy/export` | Экспортирует шаблон политики. | `policy_view` | +| `security/access/policy/getlist` | Получает список политик. | `policy_view` | +| `security/access/policy/import` | Импортирует шаблон политики. | `policy_view` | +| `security/access/policy/remove` | Удаляет политику | `policy_delete` | +| `security/access/policy/removemultiple` | Удаляет несколько политик | `policy_delete` | +| `security/access/policy/template/create` | Создаёт шаблон политики доступа | `policy_template_new` | +| `security/access/policy/template/duplicate` | Дублирует шаблон политики | `policy_template_new` | +| `security/access/policy/template/export` | Экспортирует шаблон политики. | `policy_template_view` | +| `security/access/policy/template/getlist` | Получает список шаблонов политик. | `policy_template_view` | +| `security/access/policy/template/group/getlist` | Получает список групп шаблонов политик. | `policy_template_view` | +| `security/access/policy/template/import` | Импортирует шаблон политики. | `policy_template_view` | +| `security/access/policy/template/remove` | Удаляет шаблон политики | `policy_template_delete` | +| `security/access/policy/template/removemultiple` | Удаляет несколько шаблонов политик. | `policy_template_delete` | +| `security/access/policy/template/update` | Обновляет шаблон политики | `policy_template_save` | +| `security/access/policy/template/updatefromgrid` | Обновляет шаблон политики из сетки | | +| `security/access/policy/update` | Обновляет политику | `policy_save` | +| `security/access/policy/updatefromgrid` | Обновляет политику из сетки | | +| `security/access/removeacl` | Удаляет ACL. | `access_permissions` | +| `security/access/updateacl` | Обновляет ACL. | `access_permissions` | +| `security/access/usergroup/accessnamespace/create` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/accessnamespace/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/usergroup/accessnamespace/remove` | Удаляет ACL группы ресурсов для группы пользователей | `access_permissions` | +| `security/access/usergroup/accessnamespace/update` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/category/create` | Создаёт класс | `access_permissions` | +| `security/access/usergroup/category/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/usergroup/category/remove` | Удаляет ACL группы ресурсов для группы пользователей | `access_permissions` | +| `security/access/usergroup/category/update` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/context/create` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/context/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/usergroup/context/remove` | Удаляет контекстного ACL для группы пользователей | `access_permissions` | +| `security/access/usergroup/context/update` | Обновляет ACL для контекста | `access_permissions` | +| `security/access/usergroup/resourcegroup/create` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/resourcegroup/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/usergroup/resourcegroup/remove` | Удаляет ACL группы ресурсов для группы пользователей | `access_permissions` | +| `security/access/usergroup/resourcegroup/update` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/source/create` | _(нет docblock у класса)_ | `access_permissions` | +| `security/access/usergroup/source/getlist` | Получает список ACL. | `access_permissions` | +| `security/access/usergroup/source/remove` | Удаляет ACL источника мультимедиа для группы пользователей | `access_permissions` | +| `security/access/usergroup/source/update` | _(нет docblock у класса)_ | `access_permissions` | +| `security/flush` | Сбрасывает все сеансы | | +| `security/forms/profile/activate` | Активирует профиль FC | `customize_forms` | +| `security/forms/profile/activatemultiple` | Активирует несколько профилей FC | | +| `security/forms/profile/create` | Создаёт профиль FC | `customize_forms` | +| `security/forms/profile/deactivate` | Деактивирует профиль FC | `customize_forms` | +| `security/forms/profile/deactivatemultiple` | Деактивирует несколько профилей FC | | +| `security/forms/profile/duplicate` | Дублирует профиль FC | `customize_forms` | +| `security/forms/profile/getlist` | Получает список профилей настройки формы. | `customize_forms` | +| `security/forms/profile/remove` | Удаляет профиль FC | `customize_forms` | +| `security/forms/profile/removemultiple` | Удаляет несколько профилей FC | | +| `security/forms/profile/update` | Обновляет профиль FC | `customize_forms` | +| `security/forms/profile/updatefromgrid` | Обновляет профиль FC из сетки | | +| `security/forms/set/activate` | Активирует набор FC | `customize_forms` | +| `security/forms/set/activatemultiple` | Активирует несколько наборов FC | | +| `security/forms/set/create` | Создаёт набор FC | `customize_forms` | +| `security/forms/set/deactivate` | Деактивирует набор FC | `customize_forms` | +| `security/forms/set/deactivatemultiple` | Деактивирует несколько наборов FC | | +| `security/forms/set/duplicate` | Дублирует набор FC | `customize_forms` | +| `security/forms/set/export` | Экспортирует набор настроек формы. | `customize_forms` | +| `security/forms/set/getlist` | Получает список наборов настроек формы. | `customize_forms` | +| `security/forms/set/import` | Импортирует набор настроек формы из файла XML | `customize_forms` | +| `security/forms/set/remove` | Удаляет набор FC | `customize_forms` | +| `security/forms/set/removemultiple` | Удаляет несколько наборов FC | | +| `security/forms/set/update` | Сохраняет набор настроек формы. | `customize_forms` | +| `security/forms/set/updatefromgrid` | Обновляет профиль FC из сетки | `customize_forms` | +| `security/group/create` | Создаёт группу пользователей | `usergroup_new` | +| `security/group/getlist` | Получает список групп пользователей | `usergroup_view` | +| `security/group/getnodes` | Получает группы пользователей в формате узла дерева. | | +| `security/group/remove` | Удаляет группы пользователей | `usergroup_delete` | +| `security/group/setting/create` | Создаёт настройку группы пользователей | | +| `security/group/setting/getlist` | Получает список настроек группы пользователей. | | +| `security/group/setting/remove` | Удаляет настройки группы пользователей и ее словарных строк. | | +| `security/group/setting/update` | Обновляет настройки группы пользователей | | +| `security/group/setting/updatefromgrid` | Обновляет настройки группы пользователей из сетки | | +| `security/group/sort` | Сортирует пользователей и группы пользователей, эффективно распределяя пользователей по нужным группам. | | +| `security/group/update` | Обновляет группы пользователей | `usergroup_save` | +| `security/group/user/create` | Добавляет пользователя в группу пользователей | | +| `security/group/user/getlist` | Получает список пользователей в группе пользователей | `usergroup_user_list` | +| `security/group/user/remove` | Удаляет пользователя из группы пользователей | | +| `security/group/user/update` | Обновляет роли пользователей в группе пользователей | | +| `security/login` | Правильно войдите в систему и настройте сеанс. | | +| `security/logout` | Правильно выйдите из системы, запустив все события и очистив сеанс. | | +| `security/message/create` | Создаёт сообщение | `messages` | +| `security/message/getlist` | Получает список сообщений | `messages` | +| `security/message/read` | Отметить сообщение как прочитанное | `messages` | +| `security/message/remove` | Удаляет сообщение | `messages` | +| `security/message/unread` | Отметить сообщение как непрочитанное | `messages` | +| `security/profile/changepassword` | Изменяет пароль пользователя | | +| `security/profile/get` | Получает профиль пользователя | | +| `security/profile/update` | Обновляет профиль пользователя | | +| `security/resourcegroup/create` | Создаёт группу ресурсов | `resourcegroup_new` | +| `security/resourcegroup/getlist` | Получает список групп ресурсов | `resourcegroup_view` | +| `security/resourcegroup/getnodes` | Получает группы ресурсов как узлы | | +| `security/resourcegroup/remove` | Удаляет группы ресурсов | | +| `security/resourcegroup/removeresource` | Удаляет пары ресурс-группа ресурсов | | +| `security/resourcegroup/update` | Обновляет группы ресурсов | | +| `security/resourcegroup/updateresourcesin` | Обновляет документов в группе ресурсов | `resourcegroup_resource_edit` | +| `security/role/create` | Создаёт роль на основе запроса POST. | `new_role` | +| `security/role/get` | Получает роль | `view_role` | +| `security/role/getauthoritylist` | Получает список ролей | | +| `security/role/getlist` | Получает список ролей | `view_role` | +| `security/role/remove` | Удаляет роль. | `delete_role` | +| `security/role/update` | Обновляет роли из POST-запроса | `save_role` | +| `security/role/updatefromgrid` | Обновляет роль из сетки. Передано как данные JSON | | +| `security/user/activatemultiple` | Активирует несколько пользователей | | +| `security/user/create` | Создаёт пользователя | `new_user` | +| `security/user/deactivatemultiple` | Деактивирует несколько пользователей | | +| `security/user/delete` | Удаляет пользователя | `delete_user` | +| `security/user/duplicate` | Дублирует пользователя. | `new_user` | +| `security/user/get` | Получает пользователя | `view_user` | +| `security/user/getlist` | Получает список пользователей | `view_user` | +| `security/user/getonline` | Получает список всех пользователей, находящихся в сети. | | +| `security/user/getrecentlyeditedresources` | Получает список недавно отредактированных пользователем ресурсов. | `view_document` | +| `security/user/removemultiple` | Удаляет несколько пользователей | | +| `security/user/setting/create` | Создаёт пользовательскую настройку | | +| `security/user/setting/getlist` | Получает список пользовательских настроек | | +| `security/user/setting/remove` | Удаляет пользовательской настройки и ее словарных строк. | | +| `security/user/setting/update` | Обновляет настройку пользователя | | +| `security/user/setting/updatefromgrid` | Обновляет настройку из сетки | | +| `security/user/update` | Обновляет пользователя. | `save_user` | +| `security/user/updatefromgrid` | Обновляет пользователя из сетки | | + +## Software update + +3 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `softwareupdate/base` | Предоставляет базовые методы и общие свойства для построения данных о состоянии, используемых при отображении обновлений программного обеспечения (MODX и Extras). | | +| `softwareupdate/getfile` | Получает URL-адрес загружаемого файла и другие метаданные для указанного пакета обновления MODX. | | +| `softwareupdate/getlist` | Извлекает данные о состоянии для использования во внешнем интерфейсе обновлений программного обеспечения (MODX и Extras). | | + +## Media Source + +8 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `source/create` | Создаёт источник мультимедиа | `source_save` | +| `source/duplicate` | Дублирует источник. | `source_save` | +| `source/getlist` | Получает список источников мультимедиа. | `source_view` | +| `source/remove` | Удаляет источник мультимедиа | `source_delete` | +| `source/removemultiple` | Удаляет несколько источников мультимедиа | | +| `source/type/getlist` | Получает список типов медиа-источников. | | +| `source/update` | Обновляет источник мультимедиа | `source_save` | +| `source/updatefromgrid` | Обновляет источник из сетки. Отправляется через параметр data в формате JSON. | | + +## System (настройки, меню, дашборды, логи) + +72 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `system/activeresource/getlist` | Получает список активных ресурсов | `view_document` | +| `system/charset/getlist` | Получает список кодировок | | +| `system/clearcache` | Обновляет кэш сайта | | +| `system/configcheck` | Запускает проверку конфигурации | | +| `system/configjs` | Выводит $modx->config в JSON. | | +| `system/console` | Читает данные реестра в консоль. | | +| `system/contenttype/create` | Создаёт тип контента | `content_types` | +| `system/contenttype/getlist` | Получает список типов контента | | +| `system/contenttype/remove` | Удаляет тип контента | `content_types` | +| `system/contenttype/update` | Обновляет тип контента из сетки. Отправляется через параметр data в формате JSON. | `content_types` | +| `system/contenttype/updatefromgrid` | Обновляет тип контента из сетки. Отправляется через параметр data в формате JSON. | | +| `system/country/getlist` | Получает список кодов стран | | +| `system/dashboard/create` | Создаёт панель мониторинга | `dashboards` | +| `system/dashboard/duplicate` | Дублирует панель мониторинга. | `dashboards` | +| `system/dashboard/getlist` | Получает список информационных панелей | `dashboards` | +| `system/dashboard/remove` | Удаляет панель мониторинга | `dashboards` | +| `system/dashboard/removemultiple` | Удаляет несколько информационных панелей | | +| `system/dashboard/update` | Обновляет панель мониторинга | `dashboards` | +| `system/dashboard/updatefromgrid` | Обновляет панель мониторинга из сетки. Отправляется через параметр data в формате JSON. | | +| `system/dashboard/user/create` | Создаёт класс | | +| `system/dashboard/user/getlist` | Получает список виджетов дашборда пользователя. | | +| `system/dashboard/user/remove` | Удаляет размещение виджета на дашборде пользователя. | | +| `system/dashboard/user/resize` | Изменяет размер виджета на дашборде пользователя. | | +| `system/dashboard/user/sort` | Сортирует виджеты дашборда пользователя. | | +| `system/dashboard/widget/create` | Создаёт новый виджет панели мониторинга. | `dashboards` | +| `system/dashboard/widget/feed` | Загружает ленты новостей и безопасности на дашборде через AJAX. Обработанный HTML возвращается в object->html. | | +| `system/dashboard/widget/getlist` | Получает список информационных панелей | `dashboards` | +| `system/dashboard/widget/remove` | Удаляет виджет информационной панели | `dashboards` | +| `system/dashboard/widget/removemultiple` | Удаляет несколько виджетов информационной панели | | +| `system/dashboard/widget/update` | Обновляет виджет информационной панели | `dashboards` | +| `system/databasetable/getlist` | Получает список таблиц базы данных | | +| `system/databasetable/mysql/getlist` | MySQL-специфичный процессор листинга таблиц | | +| `system/databasetable/mysql/optimize` | _(нет docblock у класса)_ | | +| `system/databasetable/mysql/optimizedatabase` | _(нет docblock у класса)_ | | +| `system/databasetable/mysql/truncate` | _(нет docblock у класса)_ | | +| `system/databasetable/optimize` | Оптимизирует таблицу базы данных | | +| `system/databasetable/optimizedatabase` | Оптимизирует базу данных | | +| `system/databasetable/truncate` | Усечь таблицу базы данных | | +| `system/deprecatedlog/clear` | Очищает журнал ошибок | | +| `system/deprecatedlog/getlist` | Получает список настроек системы | | +| `system/derivatives/getlist` | Получает список производных классов для класса. | | +| `system/downloadoutput` | Вывод данных в файл для скачивания | | +| `system/errorlog/clear` | Очищает журнал ошибок | | +| `system/errorlog/download` | Возьмите и загрузите журнал ошибок | | +| `system/errorlog/get` | Захватывает и выведите журнал ошибок | | +| `system/event/create` | Создаёт системное событие | `events` | +| `system/event/getlist` | Получает список системных событий | | +| `system/event/grouplist` | Создаёт системную настройку | | +| `system/event/remove` | Удаляет систему даже | `events` | +| `system/info` | Снимает блокировки со всех объектов | | +| `system/language/getlist` | Захватывает список языков лексики | | +| `system/log/getlist` | Получает список действий журнала менеджера. | | +| `system/log/truncate` | Очищает журнал действий менеджера. | | +| `system/menu/create` | Создаёт пункт меню | `menus` | +| `system/menu/getlist` | Получает список пунктов меню | `menus` | +| `system/menu/getnodes` | Получает пункты меню в формате узла | `menus` | +| `system/menu/remove` | Удаляет пункт меню | `menus` | +| `system/menu/sort` | Сортирует пункты меню в дереве. | | +| `system/menu/update` | Обновляет пункт меню | `menus` | +| `system/phpinfo` | Отобразить phpinfo() | | +| `system/phpthumb` | Создаёт миниатюру | | +| `system/refreshuris` | Восстанавливает URI ресурсов системы в базе данных. | | +| `system/registry/register/read` | Читает данные из реестра. | | +| `system/registry/register/send` | Отправляет сообщение в реестр. | | +| `system/removelocks` | Снимает блокировки со всех объектов | | +| `system/rte/getlist` | Получает список зарегистрированных RTE | | +| `system/settings/create` | Создаёт системную настройку | `settings` | +| `system/settings/getareas` | Получает список областей настройки | `settings` | +| `system/settings/getlist` | Получает список настроек системы | `settings` | +| `system/settings/remove` | Удаляет системной настройки | `settings` | +| `system/settings/update` | Обновляет системные настройки | `settings` | +| `system/settings/updatefromgrid` | Обновляет настройки из сетки | | + +## Workspace (пакеты, лексикон, namespaces) + +37 процессоров. + +| Action | Описание | Permission | +| ------ | -------- | ---------- | +| `workspace/lexicon/create` | Обновляет словарную статью из сетки | | +| `workspace/lexicon/getlist` | Получает список записей словаря | | +| `workspace/lexicon/reloadfrombase` | Восстанавливает строки из файлов базового словаря, сбрасывая любые настройки. | | +| `workspace/lexicon/revert` | Обновляет словарную статью из сетки | | +| `workspace/lexicon/topic/getlist` | Получает список тем словаря | | +| `workspace/lexicon/updatefromgrid` | Обновляет словарную статью из сетки | | +| `workspace/packagenamespace/create` | Создаёт пространство имен | `namespaces` | +| `workspace/packagenamespace/getlist` | Получает список пространств имен | `namespaces` | +| `workspace/packagenamespace/remove` | Удаляет пространство имен. | `namespaces` | +| `workspace/packagenamespace/removemultiple` | Удаляет пространства имен. | | +| `workspace/packagenamespace/update` | Обновляет пространство имен из сетки | `namespaces` | +| `workspace/packagenamespace/updatefromgrid` | Обновляет пространство имен из сетки | | +| `workspace/packages/checkforupdates` | Обновляет пакет от его поставщика. | | +| `workspace/packages/dependency/download` | Загружает пакет, устранив ограничения зависимого пакета. | | +| `workspace/packages/get` | Получает транспортный пакет. | `packages` | +| `workspace/packages/getattribute` | Получает атрибут пакета | | +| `workspace/packages/getdependencies` | Получает список пакетов | `packages` | +| `workspace/packages/getlist` | Получает список пакетов | `packages` | +| `workspace/packages/install` | Устанавливает пакет | | +| `workspace/packages/purge` | Очищает старые версии пакета | | +| `workspace/packages/remove` | Удаляет пакет | | +| `workspace/packages/rest/download` | Загружает пакет, указав его местоположение. | | +| `workspace/packages/rest/getinfo` | _(нет docblock у класса)_ | | +| `workspace/packages/rest/getlist` | _(нет docblock у класса)_ | | +| `workspace/packages/rest/getnodes` | _(нет docblock у класса)_ | | +| `workspace/packages/scanlocal` | Сканирует локальные пакеты для добавления в рабочую область. | | +| `workspace/packages/uninstall` | Удаляет пакет | | +| `workspace/packages/update` | Получает кусок. | | +| `workspace/packages/upload` | Загружает транспортный пакет в каталог Packages. | | +| `workspace/packages/version/getlist` | Получает список версий пакета для пакета. | `packages` | +| `workspace/packages/version/remove` | Удаляет пакет | | +| `workspace/providers/create` | Создаёт поставщика | `providers` | +| `workspace/providers/getlist` | Получает список провайдеров | `providers` | +| `workspace/providers/remove` | Удаляет провайдера | `providers` | +| `workspace/providers/update` | Обновляет провайдера | `providers` | +| `workspace/providers/updatefromgrid` | Обновляет провайдера из сетки | | +| `workspace/theme/getlist` | Получает список тем менеджера | `settings` | diff --git a/ru/extending-modx/processors/using-runprocessor.md b/ru/extending-modx/processors/using-runprocessor.md index 3e78b5c1b..df2a4a830 100644 --- a/ru/extending-modx/processors/using-runprocessor.md +++ b/ru/extending-modx/processors/using-runprocessor.md @@ -3,49 +3,311 @@ title: "Использование runProcessor" translation: "extending-modx/processors/using-runprocessor" --- -Использование runProcessor, описанное здесь, работает только в Revolution 2.0.8 и более поздних версиях. Пользователи до этого должны будут использовать устаревшие [executeProcessor](extending-modx/modx-class/reference/modx.executeprocessor "modX.executeProcessor") методы. - ## Использование runProcessor -У MODX есть специальный метод, который позволяет вам запускать процессоры прямо из любого файла PHP, такого как [Плагин](extending-modx/plugins "Плагины"), [Сниппет](extending-modx/snippets "Сниппет") или внешне. Это можно сделать с помощью следующего синтаксиса: +[`modX::runProcessor`](extending-modx/modx-class/reference/modx.runprocessor) запускает процессор из любого PHP-контекста с экземпляром `$modx`: [сниппет](extending-modx/snippets), [плагин](extending-modx/plugins), свой скрипт или другой процессор. + +```php +$response = $modx->runProcessor($action, $scriptProperties, $options); +``` + +| Аргумент | Назначение | +| -------- | ---------- | +| `$action` | Какой процессор вызвать. В 3.x: полное имя класса, `Resource\Create` или путь в стиле 2.x `resource/create`. | +| `$scriptProperties` | Данные, которые процессор читает через `getProperty()` / `getProperties()`. | +| `$options` | Опционально. Главный ключ: `processors_path` для процессоров вне дерева ядра. | -> $response = $modx->runProcessor('action/path/to/processor',$arrayOfProperties,$otherOptions); +Возвращает `ProcessorResponse` (3.x) / `modProcessorResponse` (2.x). Смотрите `isError()`, `getMessage()` и `getObject()` (массив полей). -Затем он выполнит указанный процессор и вернет объект modProcessorResponse, который содержит ответ от процессора. Затем можно проверить, был ли процесс успешным или неудачным. Первый параметр или действие - это путь к процессору (без расширения файла) из папки `core/model/modx/processors/` (Этот каталог также может быть переопределен в массиве 3-х параметров с помощью параметра `processors_path`). +Как 3.x превращает `$action` в класс или файл: [логика загрузки](extending-modx/modx-class/reference/modx.runprocessor#processor-loading-logic). -Например, этот код создает новый Чанк: +`runProcessor` есть с Revolution 2.0.8. Раньше использовали устаревший [`executeProcessor`](extending-modx/modx-class/reference/modx.executeprocessor). -``` php -$response = $modx->runProcessor('element/chunk/create',array( - 'name' => 'NewChunk', - 'description' => 'Тестовый чанк создан с runProcessor.', - 'snippet' => '

Chunkify!

', -)); +Точные имена свойств зависят от процессора. Если валидация падает, откройте класс в `core/src/Revolution/Processors/` (3.x) или смотрите [Список процессоров ядра](extending-modx/processors/list). + +## Обработка ответа + +```php +$response = $modx->runProcessor('resource/get', ['id' => 10]); if ($response->isError()) { + if ($response->hasFieldErrors()) { + foreach ($response->getFieldErrors() as $error) { + // $error->getField(), $error->getMessage() + $modx->log(modX::LOG_LEVEL_ERROR, $error->getField() . ': ' . $error->getMessage()); + } + } return $response->getMessage(); } -$chunkArray = $response->getObject(); -return 'The chunk "'.$chunkArray['name'].' was created with ID '.$chunkArray['id']; -``` - -Этот блок кода запускает процессор `element/chunk/create`, проверяет, был ли он успешным (с помощью `isError()`), и, если так, возвращает сообщение с указанием идентификатора и имени нового чанка. Обратите внимание, что getObject возвращает **массив** объекта, который возвращается процессором. `getMessage` вернет любое сообщение, отправленное обратно процессором. - -Вы также можете создать целого пользователя, включая Расширенные поля, групповые назначения, сгенерированный пароль и уведомление по электронной почте. - -``` php -$groups = array(); -$groups['Group1']['usergroup'] = '7'; // ID of group -$groups['Group1']['role'] = '1'; // ID of role -$groups['Group2']['usergroup'] = '8'; -$groups['Group2']['role'] = '1'; -$fields = array(); -$fields['active'] = true; -$fields['passwordgenmethod'] = 'g'; -$fields['passwordnotifymethod'] = 'e'; -$fields['email'] = $email; -$fields['username'] = $username; -$fields['fullname'] = $fullname; -$fields['extended']['container']['name'] = $value; -$fields['groups'] = $groups; +$resource = $response->getObject(); +``` + +`$response->getResponse()` возвращает весь массив (`success`, `message`, `object`, `total`, ...). + +## Ресурсы + +### Создание + +```php +$response = $modx->runProcessor('resource/create', [ + 'pagetitle' => 'Новость', + 'alias' => 'news-item', + 'content' => '

Текст

', + 'parent' => 5, + 'template' => 2, + 'context_key' => 'web', + 'published' => 1, + 'class_key' => 'modDocument', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$id = (int)$response->getObject()['id']; +``` + +### Обновление + +```php +$response = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => 'Новость (правка)', + 'content' => '

Обновлённый текст

', + 'published' => 1, +]); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Получить один / список + +```php +$response = $modx->runProcessor('resource/get', ['id' => $id]); +if (!$response->isError()) { + $row = $response->getObject(); +} + +$response = $modx->runProcessor('resource/getlist', [ + 'parent' => 5, + 'start' => 0, + 'limit' => 20, + 'sort' => 'menuindex', + 'dir' => 'ASC', +]); +if (!$response->isError()) { + $payload = $response->getResponse(); + // обычно: success, total, results +} +``` + +### Публикация, удаление, дублирование + +```php +$modx->runProcessor('resource/publish', ['id' => $id]); +$modx->runProcessor('resource/unpublish', ['id' => $id]); +$modx->runProcessor('resource/delete', ['id' => $id]); // в корзину +$modx->runProcessor('resource/undelete', ['id' => $id]); + +$response = $modx->runProcessor('resource/duplicate', [ + 'id' => $id, + 'name' => 'Копия новости', +]); +``` + +В боевом коде всегда проверяйте `isError()`. В однострочниках выше проверка опущена для краткости. + +## Элементы + +### Чанк + +```php +$response = $modx->runProcessor('element/chunk/create', [ + 'name' => 'NewChunk', + 'description' => 'Тестовый чанк через runProcessor.', + 'snippet' => '

Chunkify!

', +]); +if ($response->isError()) { + return $response->getMessage(); +} +$chunk = $response->getObject(); +return 'Создан чанк "' . $chunk['name'] . '" с ID ' . $chunk['id']; +``` + +### Сниппет + +```php +$response = $modx->runProcessor('element/snippet/create', [ + 'name' => 'HelloUser', + 'description' => 'Возвращает имя пользователя', + 'snippet' => 'return $modx->user->get("username");', +]); +``` + +### TV + +```php +$response = $modx->runProcessor('element/templatevar/create', [ + 'name' => 'articleImage', + 'caption' => 'Картинка статьи', + 'type' => 'image', + 'category' => 0, +]); +``` + +В 3.x `$action` может быть и `\MODX\Revolution\Processors\Element\TemplateVar\Create::class`. + +## Пользователи и авторизация + +### Вход / выход + +```php +$response = $modx->runProcessor('security/login', [ + 'username' => $username, + 'password' => $password, + 'rememberme' => 1, + 'login_context' => 'web', +]); +if ($response->isError()) { + return $response->getMessage(); +} + +$response = $modx->runProcessor('security/logout'); +``` + +### Создание пользователя + +```php +$groups = [ + 'Group1' => [ + 'usergroup' => '7', // ID группы + 'role' => '1', // ID роли + ], + 'Group2' => [ + 'usergroup' => '8', + 'role' => '1', + ], +]; +$fields = [ + 'active' => true, + 'passwordgenmethod' => 'g', + 'passwordnotifymethod' => 'e', + 'email' => $email, + 'username' => $username, + 'fullname' => $fullname, + 'extended' => [ + 'container' => [ + 'name' => $value, + ], + ], + 'groups' => $groups, +]; $response = $modx->runProcessor('security/user/create', $fields); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Смена пароля + +```php +$response = $modx->runProcessor('security/profile/changepassword', [ + 'password_old' => $oldPassword, + 'password_new' => $newPassword, + 'password_confirm' => $newPassword, +]); +``` + +Имена полей могут отличаться по версии MODX. Если вызов падает, сверьте их в классе процессора. + +## Система + +### Очистка кэша + +```php +$response = $modx->runProcessor('system/clearcache'); +if ($response->isError()) { + return $response->getMessage(); +} +``` + +### Создание системной настройки + +```php +$response = $modx->runProcessor('system/settings/create', [ + 'key' => 'myextra.some_flag', + 'value' => '1', + 'xtype' => 'combo-boolean', + 'namespace' => 'myextra', + 'area' => 'myextra', +]); ``` + +## Файлы (media browser) + +Процессоры загрузки и ФС ждут пути media source и права менеджера. Типичные action: `browser/file/upload`, `browser/file/remove`, `browser/directory/create`. Передавайте те же поля, что шлёт дерево файлов в менеджере (source, path, file). Из веб-сниппета их вызывают редко, пока пользователь не аутентифицирован для `mgr` (или вы сами не открыли этот контекст). + +```php +// Только форма вызова: нужные ключи зависят от источника и запроса +$response = $modx->runProcessor('browser/directory/create', [ + 'name' => 'exports', + 'parent' => '/', + 'source' => 1, +]); +``` + +## Action как класс 3.x + +```php +use MODX\Revolution\Processors\Resource\Create; + +$response = $modx->runProcessor(Create::class, [ + 'pagetitle' => 'Через FQCN', + 'context_key' => 'web', +]); +``` + +## Ядерный процессор внутри своего + +```php +$response = $modx->runProcessor('resource/create', $resourceData); +if ($response->isError()) { + return $this->failure($response->getMessage()); +} +$id = (int)$response->getObject()['id']; + +$tvResponse = $modx->runProcessor('resource/update', [ + 'id' => $id, + 'pagetitle' => $resourceData['pagetitle'], + // добавьте значения TV, которые ждёт update в вашей схеме +]); +``` + +Плагины на сохранение ресурса сработают на каждый успешный вызов ядра. + +## Свой каталог процессоров + +```php +$response = $modx->runProcessor( + 'mgr/item/update', + ['id' => 12, 'name' => 'Updated'], + [ + 'processors_path' => $modx->getOption('core_path') + . 'components/myextra/processors/', + ] +); +``` + +## Права с фронтенда + +Многим процессорам ядра нужны права менеджера. Из сниппета в `web` либо: + +1. Работайте под пользователем, у которого эти политики уже есть в `web`, либо +2. Для доверенных/внутренних скриптов инициализируйте менеджер: `$modx->initialize('mgr');` + +Не отдавайте привилегированные процессоры на публичные формы без своей авторизации и CSRF. + +## См. также + +- [Процессоры](extending-modx/processors) +- [Список процессоров ядра](extending-modx/processors/list) +- [modX.runProcessor](extending-modx/modx-class/reference/modx.runprocessor) +- [Коннекторы](extending-modx/processors/connectors)