diff --git a/core/src/Revolution/Processors/Resource/Create.php b/core/src/Revolution/Processors/Resource/Create.php index 1737358248d..c0648a8a843 100644 --- a/core/src/Revolution/Processors/Resource/Create.php +++ b/core/src/Revolution/Processors/Resource/Create.php @@ -247,7 +247,9 @@ public function cleanup() public function setFieldDefaults() { $scriptProperties = $this->getProperties(); - $scriptProperties['template'] = !isset($scriptProperties['template']) ? (int)$this->workingContext->getOption('default_template', 0) : (int)$scriptProperties['template']; + $scriptProperties['template'] = !isset($scriptProperties['template']) + ? $this->resolveDefaultTemplate() + : (int)$scriptProperties['template']; $scriptProperties['hidemenu'] = !isset($scriptProperties['hidemenu']) ? (int)$this->workingContext->getOption('hidemenu_default', 0) : (empty($scriptProperties['hidemenu']) ? 0 : 1); $scriptProperties['isfolder'] = empty($scriptProperties['isfolder']) ? 0 : 1; $scriptProperties['richtext'] = !isset($scriptProperties['richtext']) ? (int)$this->workingContext->getOption('richtext_default', 1) : (empty($scriptProperties['richtext']) ? 0 : 1); @@ -315,6 +317,24 @@ public function setFieldDefaults() return true; } + /** + * Resolve default template for the new resource. + * Uses parent template's childTemplate property when present and valid; otherwise context default. + * + * @return int Template ID + */ + protected function resolveDefaultTemplate(): int + { + $childTemplateId = $this->parentResource !== null + ? modTemplate::getChildTemplateId($this->parentResource) + : 0; + if ($childTemplateId > 0) { + return $childTemplateId; + } + + return (int)$this->workingContext->getOption('default_template', 0); + } + /** * Handle if parent is a context */ diff --git a/core/src/Revolution/modTemplate.php b/core/src/Revolution/modTemplate.php index 3ae17a0d4af..b7459a7b4d3 100644 --- a/core/src/Revolution/modTemplate.php +++ b/core/src/Revolution/modTemplate.php @@ -224,6 +224,53 @@ public function getTemplateVarList(array $sort = ['name' => 'ASC'], $limit = 0, return $this->xpdo->call(modTemplate::class, 'listTemplateVars', [&$this, $sort, $limit, $offset, $conditions]); } + /** + * Get the template ID from the childTemplate property for a parent resource. + * Returns the template ID that should be used for child resources, or 0 if not set or invalid. + * + * @param modResource $parent The parent resource. + * @return int Template ID or 0 when not applicable. + */ + public static function getChildTemplateId(modResource $parent): int + { + $xpdo = $parent->xpdo; + if (!$xpdo instanceof modX) { + return 0; + } + + $parentTemplateId = (int)$parent->get('template'); + if ($parentTemplateId <= 0) { + return 0; + } + + $parentTemplate = $xpdo->getObject(modTemplate::class, $parentTemplateId); + if ($parentTemplate === null) { + return 0; + } + + $properties = $parentTemplate->get('properties'); + if (empty($properties) || !is_array($properties)) { + return 0; + } + + $childTemplateProp = $properties['childTemplate'] ?? null; + $value = is_array($childTemplateProp) ? ($childTemplateProp['value'] ?? null) : $childTemplateProp; + if ($value === null || $value === '') { + return 0; + } + + $templateId = (int)$value; + if ($templateId <= 0) { + return 0; + } + + if ($xpdo->getCount(modTemplate::class, ['id' => $templateId]) === 0) { + return 0; + } + + return $templateId; + } + /** * Check to see if this Template is assigned the specified Template Var * diff --git a/manager/controllers/default/resource/create.class.php b/manager/controllers/default/resource/create.class.php index d48b03c8ece..06ada981221 100644 --- a/manager/controllers/default/resource/create.class.php +++ b/manager/controllers/default/resource/create.class.php @@ -13,6 +13,7 @@ use MODX\Revolution\modFormCustomizationProfileUserGroup; use MODX\Revolution\modFormCustomizationSet; use MODX\Revolution\modResource; +use MODX\Revolution\modTemplate; use xPDO\Om\xPDOQuery; require_once __DIR__ . '/resource.class.php'; @@ -162,8 +163,11 @@ public function process(array $scriptProperties = []) $this->resourceArray = array_merge($this->resourceArray, $reloadData); $this->resourceArray['resourceGroups'] = []; $this->resourceArray['parents'] = $this->getParents(); - $this->resourceArray['resource_groups'] = $this->modx->getOption('resource_groups', - $this->resourceArray, []); + $this->resourceArray['resource_groups'] = $this->modx->getOption( + 'resource_groups', + $this->resourceArray, + [] + ); $this->resourceArray['resource_groups'] = is_array($this->resourceArray['resource_groups']) ? $this->resourceArray['resource_groups'] : json_decode($this->resourceArray['resource_groups'], true); @@ -224,31 +228,40 @@ public function getDefaultTemplate() if (isset($this->scriptProperties['template'])) { $defaultTemplate = $this->scriptProperties['template']; } else { - switch ($this->context->getOption('automatic_template_assignment', 'parent', $this->modx->_userConfig)) { - case 'parent': - if (!empty($this->parent->id)) - $defaultTemplate = $this->parent->get('template'); - break; - case 'sibling': - if (!empty($this->parent->id)) { - $c = $this->modx->newQuery(modResource::class); - $c->where(['parent' => $this->parent->id, 'context_key' => $this->ctx]); - $c->sortby('id', 'DESC'); - $c->limit(1); - if ($siblings = $this->modx->getCollection(modResource::class, $c)) { - /** @var modResource $sibling */ - foreach ($siblings as $sibling) { - $defaultTemplate = $sibling->get('template'); + $childTemplateId = $this->parent !== null + ? modTemplate::getChildTemplateId($this->parent) + : 0; + if ($childTemplateId > 0) { + $defaultTemplate = $childTemplateId; + } else { + switch ($this->context->getOption('automatic_template_assignment', 'parent', $this->modx->_userConfig)) { + case 'parent': + if (!empty($this->parent->id)) { + $defaultTemplate = $this->parent->get('template'); + } + break; + case 'sibling': + if (!empty($this->parent->id)) { + $c = $this->modx->newQuery(modResource::class); + $c->where(['parent' => $this->parent->id, 'context_key' => $this->ctx]); + $c->sortby('id', 'DESC'); + $c->limit(1); + if ($siblings = $this->modx->getCollection(modResource::class, $c)) { + /** @var modResource $sibling */ + foreach ($siblings as $sibling) { + $defaultTemplate = $sibling->get('template'); + } + } else { + if (!empty($this->parent->id)) { + $defaultTemplate = $this->parent->get('template'); + } } - } else { - if (!empty($this->parent->id)) - $defaultTemplate = $this->parent->get('template'); } - } - break; - case 'system': - // already established - break; + break; + case 'system': + // already established + break; + } } } $userGroups = $this->modx->user->getUserGroups();