Готового решения нет, но схема такая, отлавливаете форму, получаете из неё данные, создаёте ресурс, загружаете файлы в галерею, заполняете нужные поля. Вот мой вариант решения. Форма отправляется через AjaxForm + FormIt вот вызов
{'!AjaxForm' | snippet:[
'snippet' =>'custFranchiseEdit',
'form' =>'@FILE chunks/forms/editFranchiseForm.html',
'customValidators' => 'checkFileInForm',
'validate'=>'
longtitle:required:minLength=^3^,
introtext:required:minLength=^60^:maxLength=^1000^,
description:required:maxLength=^130^,
promo:maxLength=^60^,
contact_person:required,
phone_number:required,
payback:required:isNumber,
foundation_date:required:isNumber:minLength=^4^:maxLength=^4^,
price:required:isNumber:minValue=^1^,
lump_sum:isNumber,
franchise_firm:isNumber,
own_firm:isNumber,
catalog_img:checkFileInForm,
logo_fr:checkFileInForm,
presentation:checkFileInForm,
gallery:checkFileInForm,
region_control:required,
email_address:required:email'
'placeholderPrefix' =>'fran.'
]}
<?php
$result = $modx->runSnippet('FormIt', $scriptProperties);
foreach($modx->placeholders as $key => $ph){
if(strpos($key, 'fran.error.') === 0){
$placeholders[$key] = $ph;
}
}
//$modx->log(1, print_r($_POST,1));
if(!count($placeholders) && $_POST['createdby']){
foreach($_POST as $key => $value){
if($key != 'tv' && !is_array($value) && $key != 'content' && $key != 'introtext'){
$_POST[$key] = strip_tags($value);
}
if(strpos('date', $key) !== false && $key != 'foundation_date'){
$_POST[$key] = strtotime($_POST[$key]);
}
}
if($_POST['id'] != 'false'){
$resource = $modx->getObject('msProduct', array('id' => $_POST['id']));
}else{
$resource = $modx->newObject('msProduct');
}
$resource->fromArray($_POST);
$resource->setTVValue('foundation_date', $_POST['foundation_date']);
$resource->save();
if($_POST['flag'] == 'fran'){
$ranges = $modx->getCollection('modResource', array('parent' => 143));
foreach($ranges as $range){
$min = $range->getTVValue('invest_min');
$max = $range->getTVValue('invest_max');
if($_POST['price'] <= $max && $_POST['price'] >= $min){
$resource->set('invest_vol', $range->get('longtitle'));
}
}
$createdbyProfile = $modx->getObject('modUserProfile', ['internalKey' => $resource->get('createdby')]);
$extended = $createdbyProfile->get('extended');
$extended['category'] = $_POST['parent'];
$extended['franchise'] = $resource->get('id');
$createdbyProfile->set('extended', $extended);
$createdbyProfile->save();
$articles = $modx->getObject('modResource', 75);
$tagList = json_decode($articles->getTVValue('taglist'),1);
$tagListCount = count($tagList);
$bool = true;
foreach($tagList as $item){
if($item['tagname'] == ucfirst(trim($_POST['longtitle']))){
$bool = false;
}
}
if($bool){
$tagList[$tagListCount] = array(
'MIGX_id' => $tagListCount + 1,
'tagname' => ucfirst(trim($_POST['longtitle'])),
'popular' => ''
);
$articles->setTVValue('taglist', json_encode($tagList, JSON_UNESCAPED_UNICODE));
$articles->save();
}
}
if(count($_FILES)){
foreach($_FILES as $key => $file){
$modx->runSnippet('removePreviousFiles', array('key' => $key));
$uploadFiles = $modx->runSnippet('loadUserFiles', array('key' => $key, 'id' => $resource->get('id')));
switch($key){
case 'gallery':
$modx->runSnippet('loadInGallery', array('gallery' => $uploadFiles, 'id' => $resource->get('id')));
break;
default:
$search = MODX_BASE_PATH . $modx->getOption('user_files_path');
$resource->setTVValue($key, str_replace($search, '', $uploadFiles[0]));
break;
}
$resource->save();
}
}
if($_POST['tv']){
foreach($_POST['tv'] as $key => $value){
if($key == 'features_fr' || $key == 'steps_fr'){
foreach($value as $k => $v){
if($v['text']){
$v['text'] = strip_tags($v['text']);
$v['MIGX_id'] = $k + 1;
$value[$k] = $v;
}else{
unset($value[$k]);
}
}
$resource->setTVValue($key, json_encode($value, JSON_UNESCAPED_UNICODE));
}else{
$resource->setTVValue($key, strip_tags($value));
}
$resource->save();
}
}
if($resource){
$cacheKey = $resource->getCacheKey();
$modx->cacheManager->refresh(array(
'resource' => array('key' => $cacheKey),
));
}
if($_POST['flag'] = 'fran'){
$pdoTools = $modx->getService('pdoTools');
$html = $modx->runSnippet('msProducts', [
'parents' => 121,
'tpl' => '@FILE chunks/profiles/conferencePreview.html',
'limit' => 9999,
'sortby' => 'createdon',
'sortdir' => 'DESC',
'where' => ['createdby' => $_POST['createdby']],
'includeTVs' => 'conf_logo,startdate,enddate',
'user' => $_POST['createdby'],
'showUnpublished' => 1,
'showDeleted' => 0,
'showHidden' => 1,
]);
}
return $AjaxForm->success('Данные сохранены', array('success' => 'Данные сохранены', 'html' => $html, 'flag' => 'fran'));
}else{
return $AjaxForm->error('В форме содержатся ошибки', array('error' => $placeholders));
}
Код сниппета loadInGallery для загрузки фотографий в галерею
<?php
if(!$gallery){return false;}
if(!$id){return false;}
$resource = $modx->getObject('msProduct', $id);
if($files = $resource->getMany('Files')){
foreach($files as $f){
$f->remove();
}
}
foreach ($gallery as $v) {
if (empty($v)) {continue;}
$image = $v;
if (!file_exists($image)) {
$modx->log(modX::LOG_LEVEL_ERROR, "Could not import image \"$v\" to gallery. File \"$image\" not found on server.");
}
else {
$response = $modx->runProcessor('gallery/upload',
array('id' => $id, 'name' => $v, 'file' => $image),
array('processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/')
);
if ($response->isError()) {
$modx->log(modX::LOG_LEVEL_ERROR, "Error on upload \"$v\": \n". print_r($response->getAllErrors(), 1));
}
else {
$modx->log(modX::LOG_LEVEL_INFO, "Successful upload \"$v\": \n". print_r($response->getObject(), 1));
}
}
}