Elgg  Version 7.1
FormsService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
10 use Elgg\Traits\Loggable;
11 
18 class FormsService {
19 
20  use Loggable;
21 
22  protected bool $rendering = false;
23 
24  protected string $footer = '';
25 
34  public function __construct(
35  protected ViewsService $views,
36  protected EventsService $events,
37  protected ESMService $esm,
38  protected FieldsService $fields,
39  ) {
40  }
41 
77  public function render(string $action, array $form_vars = [], array $body_vars = []): string {
78  $defaults = [
79  'action' => elgg_generate_action_url($action, [], false),
80  'method' => 'post',
81  'ajax' => false,
82  'sticky_enabled' => false,
83  'sticky_form_name' => $action,
84  'sticky_ignored_fields' => [],
85  ];
86 
87  // append elgg-form class to any class options set
89  'elgg-form-' . preg_replace('/[^a-z0-9]/i', '-', $action)],
90  );
91 
92  $form_vars = array_merge($defaults, $form_vars);
93 
94  if (!isset($form_vars['enctype']) && strtolower($form_vars['method']) == 'post') {
95  $form_vars['enctype'] = 'multipart/form-data';
96  }
97 
98  if (elgg_extract('ajax', $form_vars)) {
99  $this->esm->import('input/form-ajax');
100  $form_vars['class'][] = 'elgg-js-ajax-form';
101  unset($form_vars['ajax']);
102  }
103 
104  $form_vars['action_name'] = $action;
105 
106  $form_vars['ignore_empty_body'] = (bool) elgg_extract('ignore_empty_body', $form_vars, false);
107 
108  $form_vars['prevent_double_submit'] = (bool) elgg_extract('prevent_double_submit', $form_vars, true);
109 
110  if (!isset($form_vars['body'])) {
111  // prepare body vars
112  $body_vars = (array) $this->events->triggerResults('form:prepare:fields', $action, $form_vars, $body_vars);
113 
114  $this->rendering = true;
115  $this->footer = '';
116 
117  // Render form body
118  $body = $this->views->renderView("forms/{$action}", $body_vars);
119 
120  if (!empty($body)) {
121  // wrap form body
122  $body = $this->views->renderView('elements/forms/body', [
123  'body' => $body,
124  'action_name' => $action,
125  'body_vars' => $body_vars,
126  'form_vars' => $form_vars,
127  ]);
128 
129  // Grab the footer if one was set during form rendering
130  $body .= $this->views->renderView('elements/forms/footer', [
131  'footer' => $this->getFooter(),
132  'action_name' => $action,
133  'body_vars' => $body_vars,
134  'form_vars' => $form_vars,
135  ]);
136  }
137 
138  $this->rendering = false;
139 
140  $form_vars['body'] = $body;
141  }
142 
143  return elgg_view('input/form', $form_vars);
144  }
145 
162  public function renderEntity(string $entity_type, string $entity_subtype, ?\ElggEntity $entity = null, array $vars = []): string {
163  if ($entity instanceof \ElggEntity && ($entity->getType() !== $entity_type || $entity->getSubtype() !== $entity_subtype)) {
164  throw new InvalidArgumentException("The provided entity doesn't match the given entity type/subtype");
165  }
166 
167  $view = (string) elgg_extract('view', $vars, $this->getFormView($entity_type, $entity_subtype));
168  $action = (string) elgg_extract('action', $vars, $this->getFormAction($entity_type, $entity_subtype));
169 
170  $fields = $this->fields->get($entity_type, $entity_subtype);
171  $fields = (array) $this->events->triggerResults('form:register:fields', "{$entity_type}:{$entity_subtype}", [
172  'entity' => $entity,
173  'entity_type' => $entity_type,
174  'entity_subtype' => $entity_subtype,
175  ], $fields);
176 
177  $default_form_vars = [
178  'sticky_enabled' => true,
179  'action' => $action,
180  ];
181  $form_vars = array_merge((array) elgg_extract('form_vars', $vars), $default_form_vars);
182 
183  $default_body_vars = [
184  'entity_type' => $entity_type,
185  'entity_subtype' => $entity_subtype,
186  'entity' => $entity,
187  'fields' => $fields,
188  ];
189  $body_vars = array_merge((array) elgg_extract('body_vars', $vars), $default_body_vars);
190 
191  return $this->render($view, $form_vars, $body_vars);
192  }
193 
203  protected function getFormView(string $entity_type, string $entity_subtype): string {
204  $forms = [
205  "{$entity_type}/{$entity_subtype}/edit",
206  "{$entity_subtype}/edit",
207  ];
208 
209  foreach ($forms as $view) {
210  if (elgg_view_exists("forms/{$view}")) {
211  return $view;
212  }
213  }
214 
215  return 'entity/edit';
216  }
217 
228  protected function getFormAction(string $entity_type, string $entity_subtype): string {
229  $actions = [
230  "{$entity_type}/{$entity_subtype}/edit",
231  "{$entity_subtype}/edit",
232  ];
233 
234  foreach ($actions as $action) {
236  return elgg_generate_action_url($action, [], false);
237  }
238  }
239 
240  throw new DomainException("No form action found for {$entity_type}/{$entity_subtype}");
241  }
242 
253  public function setFooter(string $footer = ''): void {
254  if (!$this->rendering) {
255  throw new LogicException('Form footer can only be set and retrieved during form rendering, anywhere in elgg_view_form() call stack (e.g. form view, extending views, or view events)');
256  }
257 
258  $this->footer = $footer;
259  }
260 
267  public function getFooter(): string {
268  if (!$this->rendering) {
269  throw new LogicException('Form footer can only be set and retrieved during form rendering, anywhere in elgg_view_form() call stack (e.g. form view, extending views, or view events)');
270  }
271 
272  return $this->footer;
273  }
274 }
$fields
Save the configuration of the security.txt contents.
Definition: security_txt.php:6
$vars
Definition: theme.php:3
$entity
Definition: reset.php:8
if(!empty($avatar) &&! $avatar->isValid()) elseif(empty($avatar)) if(! $owner->saveIconFromUploadedFile('avatar')) if(!elgg_trigger_event('profileiconupdate', $owner->type, $owner)) $view
Definition: upload.php:39
if(!elgg_view_exists("plugins/{$plugin_id}/settings")) $form_vars
foreach($categories as $key=> $category) $body
Definition: categories.php:38
Events service.
Exception thrown if a value does not adhere to a defined valid data domain.
Exception thrown if an argument is not of the expected type.
Exception that represents error in the program logic.
Forms service.
getFooter()
Returns currently set footer.
getFormView(string $entity_type, string $entity_subtype)
Get the form view for edit/add of an entity type/subtype.
setFooter(string $footer='')
Sets form footer and defers its rendering until the form view and extensions have been rendered.
__construct(protected ViewsService $views, protected EventsService $events, protected ESMService $esm, protected FieldsService $fields,)
Constructor.
render(string $action, array $form_vars=[], array $body_vars=[])
renderEntity(string $entity_type, string $entity_subtype, ?\ElggEntity $entity=null, array $vars=[])
Render an entity edit/add form.
getFormAction(string $entity_type, string $entity_subtype)
Get the form action for edit/add of an entity type/subtype.
Service for getting field definitions for type/subtype combinations.
Keeps track of ES modules.
Definition: ESMService.php:16
Views service.
$views
Definition: item.php:17
$body_vars
$footer
Wrap form footer.
Definition: footer.php:11
elgg_extract_class(array $array, array|string $existing=[], string $extract_key='class')
Extract class names from an array, optionally merging into a preexisting set.
Definition: elgglib.php:273
elgg_extract($key, $array, $default=null, bool $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:246
$defaults
Generic entity header upload helper.
Definition: header.php:6
$entity_subtype
Definition: edit.php:15
$entity_type
Generic entity edit/add form.
Definition: edit.php:14
elgg_action_exists(string $action)
Check if an action is registered and its script exists.
Definition: actions.php:69
elgg_view_exists(string $view, string $viewtype='', bool $recurse=true)
Returns whether the specified view exists.
Definition: views.php:131
elgg_view(string $view, array $vars=[], string $viewtype='')
Return a parsed view.
Definition: views.php:156
elgg_generate_action_url(string $action, array $query=[], bool $add_csrf_tokens=true)
Generate an action URL.
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
$action
Definition: subscribe.php:11
if(! $menu instanceof \Elgg\Menu\PreparedMenu) $actions
Definition: user_hover.php:21