Naučite se upravljati dolgotrajne procese s Pimcore Process Managerjem
2. okt. 2025 • 5 min branja
Uradna stran Process Managerja: https://github.com/elements-at/ProcessManager
Da bi razumeli in sledili temu vodiču, potrebujete srednje dobro poznavanje Pimcore in Symfony ogrodja.
Če morate ustvariti bundle za integracijo te rešitve, lahko sledite uradni dokumentaciji:
https://pimcore.com/docs/pimcore/current/Development_Documentation/Extending_Pimcore/Bundle_Developers_Guide/index.html
Za potrebe vodiča sem ustvaril bundle ExampleBundle.
Namestitev Process Manager bundle-a
Najprej želimo dodati Process Manager bundle v naš Pimcore projekt. Za to uporabimo composer.
composer require elements/process-manager-bundle
Po namestitvi moramo bundle omogočiti in ga namestiti:
bin/console pimcore:bundle:enable ElementsProcessManagerBundle
bin/console pimcore:bundle:install ElementsProcessManagerBundle
Process Manager potrebuje vzdrževalni cron job, ki teče v ozadju, zato odprite crontab (ali alternativo) in dodajte naslednjo vrstico:
* * * * * php /var/www/html/bin/console process-manager:maintenance > /dev/null 2>&1
Pomembno: vaša pot je lahko drugačna od moje – preverite!
Ustvarjanje novega ukaza (Command)
Znotraj bundle-a ustvarite novo mapo Command → v njej ustvarimo Symfony Command (uradni Pimcore primer).
Namig: Ne pozabite registrirati ukaza v services!
services:
ExampleBundle\Command\:
resource: '../../Command'
public: true
tags: [ 'console.command' ]
bundles/ExampleBundle/Resources/config/services.yml
Pomembno je dodati ExecutionTrait – tako lahko Process Manager komunicira z ukazom:
use ExecutionTrait;
Ukaz sem konfiguriral takole:
protected function configure()
{
$this->setName('example:generate-changes')
->setDescription('Will generate changes to selected item')
->addOption(
'monitoring-item-id',
null,
InputOption::VALUE_REQUIRED,
'Contains the monitoring item if executed via the Pimcore backend'
);
}
Za metodo execute bomo logiko implementirali kasneje, za zdaj naj samo vrne uspeh:
protected function execute(InputInterface $input, OutputInterface $output): int
{
return self::SUCCESS;
}
Konfiguracija novega Process Manager ukaza
Po namestitvi Process Manager bundle-a v administraciji vidimo nov meni: Tools → Process Manager.
Videti bi morali zelen gumb »Add Pimcore Command«.
Moja konfiguracija:
- ID: 1
- Name: Generate Changes
- Command: example:generate-changes
Ko shranite konfiguracijo, shranite ID tudi v kodi. Lahko ga dodate v constants.php ali pa ustvarite Config razred v bundle-u (kar sem jaz naredil):
bundles/ExampleBundle/Config/ExampleConfig.php
class ExampleConfig
{
public const GENERATE_CHANGES = 1;
}
Frontend handler
Na frontendu želimo simulirati handler. Tukaj dodamo splitbutton v razred (pri meni ExampleClass, lahko pa je karkoli).
Primer – funkcija, ki se zažene po odprtju objekta v startup.js:
postOpenObject: function (object, type) {
if (object.data.general.o_className === 'ExampleClass') {
object.toolbar.add(
{
xtype: 'splitbutton',
tooltip: 'Changes',
iconCls: 'pimcore_icon_area pimcore_material_icon',
scale: 'medium',
handler: function () {
},
menu: new Ext.menu.Menu({
items: [
{
text: 'Generate Changes', iconCls: 'pimcore_icon_area', handler: function () {
Ext.Ajax.request({
url: '/admin/example/generate-changes',
method: 'GET',
params: {
isAjax: true,
objectID: object.id,
},
success: function (response) {
console.log(response);
},
failure: function (response) {
console.log(response);
let responseObj = Ext.decode(response.responseText);
Ext.Msg.alert('Contact administrator!', responseObj.msg + ' Contact administrator.');
}
}, this);
}
}
]
})
});
pimcore.layout.refresh();
}
}
Ko smo frontend del uredili, moramo implementirati controller za obravnavo zahtevka.
Implementacija kontrolerja
V Pimcore obstajata dva tipa kontrolerjev:
- frontend kontroler
- admin kontroler (za izvajanje v administraciji)
Uporabili bomo admin kontroler.
Ustvarite:
bundles/ExampleBundle/Controller/Admin/GenerateChangesController.php
use Elements\Bundle\ProcessManagerBundle\Helper;
class GenerateChangesController extends AdminController
{
/**
* @Route("/admin/example/generate-changes")
* @throws Exception
*/
public function generateChangesAction(Request $request): Response
{
$getParams = $request->query->all();
if (!isset($getParams['objectID'])) {
throw new Exception("Missing request parameter!");
}
$metaData = [
'objectID' => $getParams['objectID']
];
Helper::executeJob(ExampleConfig::GENERATE_CHANGES_PROCESS_ID, [], $this->getAdminUser()->getId(), $metaData);
return new Response(json_encode(["success" => true]));
}
}
Kaj se tukaj dogaja?
Prejeli smo zahtevek iz administracije (prek gumba). Ta zahtevek poda ID objekta, s katerim bomo delali.
Process Manager lahko shranjuje informacije – to so Meta Data datoteke. Tukaj uporabljamo poenostavljeno verzijo.
Razred Helper ponuja statično funkcijo executeJob, ki v ozadju zažene opravilo prek \Pimcore\Tool\Console::execInBackground($command). Določiti moramo samo:
- ID procesa
- kdo ga izvaja
- podatke, ki jih posredujemo
Dokončanje ukaza
Sedaj v ukaz dodamo logiko – pridobimo objekt po ID-ju, mu spremenimo polje in ga shranimo.
bundles/ExampleBundle/Command/GenerateChangesCommand.php
protected function execute(InputInterface $input, OutputInterface $output): int
{
$monitoringItemId = $input->getOption('monitoring-item-id');
if (is_null($monitoringItemId)) {
throw new Exception('Missing Monitoring Item ID (--monitoring-item-id=?? ...)');
}
$monitoringItem = $this->initProcessManager($monitoringItemId, ["autoCreate" => true]);
$monitoringItem->setName("Generate random changes.");
$monitoringItem->setCurrentWorkload(0)->setTotalWorkload(1)->setMessage("Starting process")->save();
$stringifyMetaData = $monitoringItem->getMetaData();
$metaData = json_decode($stringifyMetaData, true);
if (!isset($metaData['objectID'])) {
return self::FAILURE;
}
try {
$exampleClass = ExampleClass::getById($metaData['objectID']);
$exampleClass->setSku(rand(100000, 999999));
$exampleClass->save();
} catch (Exception $e) {
Simple::log('generate-changes', date("h:i:sa") . $e->getMessage());
return self::FAILURE;
}
$monitoringItem->setMessage("Job finished => Success")->setCompleted();
$output->writeln("DONE process | Success");
return self::SUCCESS;
}
Kaj se zgodi tukaj?
- Process Manager vedno posreduje monitoring-item-id.
- To pridobimo z metodo initProcessManager iz ExecutionTrait.
- Tako dobimo objekt, kjer nastavimo ime procesa, obremenitev, sporočila, dnevnike …
- Potrebujemo tudi object ID, ki smo ga prej shranili v Meta Data.
- Podatki so shranjeni kot JSON, zato jih dekodiramo z json_decode.
- Nato izvedemo logiko (v mojem primeru nastavimo naključno vrednost polja).
- Ko zaključimo, označimo proces kot dokončan.
Dodatni nasveti
- Dnevnike preverite v Tools → Process Manager → Process Logs.
- V podrobnostih procesa vidite ukaz, ki se izvaja, npr.:
/usr/local/bin/php /var/www/html/bin/console example:generate-changes --monitoring-item-id=10
To lahko uporabite za razhroščevanje z XDebug korak za korakom.
Primer ukaza za konzolo z XDebug:
XDEBUG_CONFIG=idekey=PHPSTORM PHP_IDE_CONFIG=serverName=pim.localhost bin/console example:generate-changes --monitoring-item-id=10
Za to potrebujete pravilno konfiguriran strežnik v IDE in omogočen Xdebug v PHP.
Povzetek
- Ustvarili smo kontroler, ki prejme zahtevek iz administracije.
- Kontroler ustvari nov proces, ki smo ga konfigurirali v administraciji.
- Process Manager izvede proces glede na konfiguracijo.
- Ustvarili smo ukaz, ki uporablja ExecutionTrait.
- Za prenos informacij med kontrolerjem in ukazom smo uporabili Meta Data.