extensions->modules()->enabled(StudioRunController::MODULE)) { return $this->error(__('Content Studio is switched off. An administrator can switch it on in Tools → Extensions.', 'maze-graph'), 503); } $name = Redactor::cleanText((string) $request->input('name', '')); if ($name === '' || mb_strlen($name) > 80) { return $this->validationError(['name' => [__('Give the template a name of up to 80 characters.', 'maze-graph')]]); } $description = mb_substr(Redactor::cleanText((string) $request->input('description', '')), 0, 300); $base = $this->extensions->definitions()->get('template', (string) $request->input('base', '')); if ($base === null || ($base['data']['studio'] ?? '') !== StudioRunController::STUDIO) { return $this->validationError(['base' => [__('Choose a Content Studio template to start from.', 'maze-graph')]]); } $values = is_array($request->input('values')) ? $request->input('values') : []; $slug = sanitize_title($name); $definition = [ 'kind' => 'template', 'id' => Definitions::STORED . '/' . ($slug !== '' ? substr($slug, 0, 40) : 'template'), 'name' => $name, 'description' => $description, 'studio' => StudioRunController::STUDIO, 'post_type' => (string) ($base['data']['post_type'] ?? 'post'), 'source' => (string) ($base['data']['source'] ?? 'none'), 'fields' => $this->fields((array) ($base['data']['fields'] ?? []), $values), 'instructions' => (string) $base['data']['instructions'], ]; // The stages and instructions the person set up on the brief travel with the template (decision 052). $fromPost = $definition['source'] === 'post'; $optional = array_values(array_diff(Stages::resolve(is_array($request->input('stages')) ? $request->input('stages') : (array) ($base['data']['stages'] ?? []), $fromPost), [Stages::BRIEF, Stages::WRITE, Stages::HANDOFF])); $definition['stages'] = $optional; $slots = InstructionSet::cleanMap($request->input('instructions', $base['data']['stage_instructions'] ?? null)); if ($slots !== []) { $definition['stage_instructions'] = $slots; } if (is_string($base['data']['agent'] ?? null)) { $definition['agent'] = $base['data']['agent']; } $key = substr((string) preg_replace('/[^A-Za-z0-9-]/', '', (string) $request->input('action_id', '')), 0, 64); $outcome = $tools->execute(ToolContext::forPerson((int) get_current_user_id(), 'studio-template:' . ($key !== '' ? $key : wp_generate_uuid4())), DefinitionAbilities::SAVE, ['definition' => $definition]); if ($outcome->status !== 'ok') { return $this->error($outcome->error !== '' ? $outcome->error : __('The template could not be saved.', 'maze-graph'), 422); } return $this->ok(['id' => $definition['id'], 'change' => $outcome->ui['change'] ?? null, 'summary' => StoredMessage::render((string) ($outcome->ui['summary'] ?? ''))]); } /** * The base template's fields, each with the person's answer as its default when it is usable. * * @param array $fields * @param array $values * @return list> */ protected function fields(array $fields, array $values): array { $out = []; foreach ($fields as $field) { if (!is_array($field)) { continue; } $value = Redactor::cleanText(is_scalar($values[(string) $field['id']] ?? null) ? (string) $values[(string) $field['id']] : ''); $type = (string) ($field['type'] ?? 'text'); if ($value !== '' && ($type !== 'select' || in_array($value, (array) ($field['options'] ?? []), true)) && mb_strlen($value) <= 2000) { $field['default'] = $type === 'number' && is_numeric($value) ? $value + 0 : $value; } $out[] = $field; } return $out; } }