Files
sprinkle-organisations/src/Controller/OrganisationController.php

916 lines
33 KiB
PHP

<?php
/*
* AVSDev UF Organisations (https://avsdev.uk)
*
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
*/
namespace UserFrosting\Sprinkle\Organisations\Controller;
use Illuminate\Database\Capsule\Manager as Capsule;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use UserFrosting\Fortress\Adapter\JqueryValidationAdapter;
use UserFrosting\Fortress\RequestDataTransformer;
use UserFrosting\Fortress\RequestSchema;
use UserFrosting\Fortress\ServerSideValidator;
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
use UserFrosting\Sprinkle\Core\Controller\SimpleController;
use UserFrosting\Support\Exception\BadRequestException;
use UserFrosting\Support\Exception\ForbiddenException;
use UserFrosting\Support\Exception\NotFoundException;
/**
* Controller class for organisation-related requests, including listing organisations, CRUD for organisations, etc.
*
* @author Craig Williams (https://avsdev.uk)
*/
class OrganisationController extends SimpleController
{
/**
* Processes the request to create a new organisation.
*
* Processes the request from the organisation creation form, checking that:
* 1. The organisation name and slug are not already in use;
* 2. The user has permission to create a new organisation;
* 3. The submitted data is valid.
* This route requires authentication (and should generally be limited to admins or the root user).
*
* Request type: POST
*
* @see getModalCreateOrganisation
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function create(Request $request, Response $response, $args)
{
// Get POST parameters: name, slug, icon, description
$params = $request->getParsedBody();
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'create_organisation')) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
$ms = $this->ci->alerts;
// Load the request schema
$schema = new RequestSchema('schema://requests/organisation/create.yaml');
// Whitelist and set parameter defaults
$transformer = new RequestDataTransformer($schema);
$data = $transformer->transform($params);
$error = false;
// Validate request data
$validator = new ServerSideValidator($schema, $this->ci->translator);
if (!$validator->validate($data)) {
$ms->addValidationErrors($validator);
$error = true;
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Check if name or slug already exists
if ($classMapper->getClassMapping('organisation')::findUnique($data['name'], 'name')) {
$ms->addMessageTranslated('danger', 'ORGANISATION.NAME.IN_USE', $data);
$error = true;
}
if ($classMapper->getClassMapping('organisation')::findUnique($data['slug'], 'slug')) {
$ms->addMessageTranslated('danger', 'ORGANISATION.SLUG.IN_USE', $data);
$error = true;
}
if ($error) {
return $response->withJson([], 400);
}
/** @var \UserFrosting\Support\Repository\Repository $config */
$config = $this->ci->config;
// All checks passed! log events/activities and create organisation
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($classMapper, $data, $ms, $currentUser) {
// Create the organisation
$organisation = $classMapper->createInstance('organisation', $data);
// Store new organisation to database
$organisation->save();
// Create activity record
$this->ci->userActivityLogger->info("User {$currentUser->user_name} created organisation {$organisation->name}.", [
'type' => 'organisation_create',
'user_id' => $currentUser->id,
]);
$ms->addMessageTranslated('success', 'ORGANISATION.CREATION_SUCCESSFUL', $data);
});
return $response->withJson([], 200);
}
/**
* Returns info for a single organisation.
*
* This page requires authentication.
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param string[] $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
*/
public function getInfo(Request $request, Response $response, array $args)
{
$organisation = $this->getOrganisationFromParams($args);
// If the organisation doesn't exist, return 404
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Join organisation's most recent activity
$organisation = $classMapper->createInstance('organisation')
->where('slug', $organisation->slug)
->joinMemberCounts()
->first();
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'uri_organisation', [
'organisation' => $organisation,
])) {
throw new ForbiddenException();
}
$result = $organisation->toArray();
// Be careful how you consume this data - it has not been escaped and contains untrusted user-supplied content.
// For example, if you plan to insert it into an HTML DOM, you must escape it on the client side (or use client-side templating).
return $response->withJson($result, 200, JSON_PRETTY_PRINT);
}
/**
* Processes the request to update an existing organisation's details.
*
* Processes the request from the organisation update form, checking that:
* 1. The organisation name/slug are not already in use;
* 2. The user has the necessary permissions to update the posted field(s);
* 3. The submitted data is valid.
* This route requires authentication (and should generally be limited to admins or the root user).
*
* Request type: PUT
*
* @see getModalOrganisationEdit
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
*/
public function update(Request $request, Response $response, $args)
{
// Get the organisation based on slug in URL
$organisation = $this->getOrganisationFromParams($args);
if (!$organisation) {
throw new NotFoundException();
}
// Get PUT parameters: (name, slug, icon, description)
$params = $request->getParsedBody();
/** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
$ms = $this->ci->alerts;
// Load the request schema
$schema = new RequestSchema('schema://requests/organisation/edit-info.yaml');
// Whitelist and set parameter defaults
$transformer = new RequestDataTransformer($schema);
$data = $transformer->transform($params);
$error = false;
// Validate request data
$validator = new ServerSideValidator($schema, $this->ci->translator);
if (!$validator->validate($data)) {
$ms->addValidationErrors($validator);
$error = true;
}
// Determine targeted fields
$fieldNames = [];
foreach ($data as $name => $value) {
$fieldNames[] = $name;
}
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled resource - check that currentUser has permission to edit submitted fields for this organisation
if (!$authorizer->checkAccess($currentUser, 'update_organisation_field', [
'organisation' => $organisation,
'fields' => array_values(array_unique($fieldNames)),
])) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Check if name or slug already exists
if (
isset($data['name']) &&
$data['name'] != $organisation->name &&
$classMapper->getClassMapping('organisation')::where('name', $data['name'])->first()
) {
$ms->addMessageTranslated('danger', 'ORGANISATION.NAME.IN_USE', $data);
$error = true;
}
if (
isset($data['slug']) &&
$data['slug'] != $organisation->slug &&
$classMapper->getClassMapping('organisation')::where('slug', $data['slug'])->first()
) {
$ms->addMessageTranslated('danger', 'ORGANISATION.SLUG.IN_USE', $data);
$error = true;
}
if ($error) {
return $response->withJson([], 400);
}
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($data, $organisation, $currentUser) {
// Update the organisation and generate success messages
foreach ($data as $name => $value) {
if ($value != $organisation->$name) {
$organisation->$name = $value;
}
}
$organisation->save();
// Create activity record
$this->ci->userActivityLogger->info("User {$currentUser->user_name} updated details for organisation {$organisation->name}.", [
'type' => 'organisation_update_info',
'user_id' => $currentUser->id,
]);
});
$ms->addMessageTranslated('success', 'ORGANISATION.UPDATE', [
'name' => $organisation->name,
]);
return $response->withJson([], 200);
}
/**
* Processes the request to merge two organisations.
*
* Processes the request from the merge organisation form, checking that:
* 1. The source organisation slug exists;
* 2. The target organisation slug exists;
* 3. The user has permission to merge organisations;
* 4. The submitted data is valid.
* This route requires authentication (and should generally be limited to admins or the root user).
*
* Request type: POST
*
* @see getModalMerge
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function merge(Request $request, Response $response, $args)
{
// Get POST parameters
$params = $request->getParsedBody();
// Load the request schema
$schema = new RequestSchema('schema://requests/organisation/merge.yaml');
// Whitelist and set parameter defaults
$transformer = new RequestDataTransformer($schema);
$data = $transformer->transform($params);
// Validate, and throw exception on validation errors.
$validator = new ServerSideValidator($schema, $this->ci->translator);
if (!$validator->validate($data)) {
$e = new BadRequestException();
foreach ($validator->errors() as $idx => $field) {
foreach ($field as $eidx => $error) {
$e->addUserMessage($error);
}
}
throw $e;
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Get the organisations
$source = $classMapper->getClassMapping('organisation')::where('slug', $data['source_slug'])->first();
$target = $classMapper->getClassMapping('organisation')::where('slug', $data['target_slug'])->first();
// If a organisation doesn't exist, return 404
if (!$source || !$target) {
throw new BadRequestException();
}
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'merge_organisations')) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Support\Repository\Repository $config */
$config = $this->ci->config;
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
$sourceName = $source->name;
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($source, $sourceName, $target, $currentUser) {
$this->ci->get('organisation.beforeMerge')($source, $target);
$source->beforeMerge($target, ['currentUser' => $currentUser]);
$source->delete();
unset($source);
// Create activity record
$this->ci->userActivityLogger->info("User {$currentUser->user_name} merged organisation {$sourceName} into {$target->name}.", [
'type' => 'organisation_merge',
'user_id' => $currentUser->id,
]);
});
/** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
$ms = $this->ci->alerts;
$ms->addMessageTranslated('success', 'ORGANISATION.MERGE_SUCCESSFUL', [
'source' => $sourceName,
'target' => $target->name,
]);
return $response->withJson([], 200);
}
/**
* Processes the request to delete an existing organisation.
*
* Deletes the specified organisation.
* Organisations with members will retain the membership information.
* Before doing so, checks that:
* 1. The user has permission to delete this organisation;
* 2. The submitted data is valid.
* This route requires authentication (and should generally be limited to admins or the root user).
*
* Request type: DELETE
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function delete(Request $request, Response $response, $args)
{
$organisation = $this->getOrganisationFromParams($args);
// If the organisation doesn't exist, return 404
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'delete_organisation', [
'organisation' => $organisation,
])) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Support\Repository\Repository $config */
$config = $this->ci->config;
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
$organisationName = $organisation->name;
// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($organisation, $organisationName, $currentUser) {
$organisation->delete();
unset($organisation);
// Create activity record
$this->ci->userActivityLogger->info("User {$currentUser->user_name} deleted organisation {$organisationName}.", [
'type' => 'organisation_delete',
'user_id' => $currentUser->id,
]);
});
/** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
$ms = $this->ci->alerts;
$ms->addMessageTranslated('success', 'ORGANISATION.DELETION_SUCCESSFUL', [
'name' => $organisationName,
]);
return $response->withJson([], 200);
}
/**
* Returns a list of Organisations.
*
* Generates a list of organisations, optionally paginated, sorted and/or filtered.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function getList(Request $request, Response $response, $args)
{
// GET parameters
$params = $request->getQueryParams();
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'uri_organisations')) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
$sprunje = $classMapper->createInstance('organisation_sprunje', $classMapper, $params);
// Be careful how you consume this data - it has not been escaped and contains untrusted user-supplied content.
// For example, if you plan to insert it into an HTML DOM, you must escape it on the client side (or use client-side templating).
return $sprunje->toResponse($response);
}
/**
* Get deletion confirmation modal.
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
* @throws BadRequestException
*/
public function getModalConfirmDelete(Request $request, Response $response, $args)
{
// GET parameters
$params = $request->getQueryParams();
$organisation = $this->getOrganisationFromParams($params);
// If the organisation no longer exists, forward to main organisation listing page
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'delete_organisation', [
'organisation' => $organisation,
])) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
return $this->ci->view->render($response, 'modals/confirm-delete-organisation.html.twig', [
'organisation' => $organisation,
'form' => [
'action' => "api/organisations/o/{$organisation->slug}",
],
]);
}
/**
* Renders the modal form for creating a new organisation.
*
* This does NOT render a complete page. Instead, it renders the HTML for the modal, which can be embedded in other pages.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function getModalCreate(Request $request, Response $response, $args)
{
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
/** @var \UserFrosting\I18n\Translator $translator */
$translator = $this->ci->translator;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'create_organisation')) {
throw new ForbiddenException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Create a dummy organisation to prepopulate fields
$organisation = $classMapper->createInstance('organisation', []);
$fieldNames = ['name', 'slug', 'description'];
$fields = [
'hidden' => [],
'disabled' => [],
];
// Load validation rules
$schema = new RequestSchema('schema://requests/organisation/create.yaml');
$validator = new JqueryValidationAdapter($schema, $this->ci->translator);
return $this->ci->view->render($response, 'modals/organisation.html.twig', [
'organisation' => $organisation,
'form' => [
'action' => 'api/organisations',
'method' => 'POST',
'fields' => $fields,
'submit_text' => $translator->translate('CREATE'),
],
'page' => [
'validators' => $validator->rules('json', false),
],
]);
}
/**
* Renders the modal form for editing an existing organisation.
*
* This does NOT render a complete page. Instead, it renders the HTML for the modal, which can be embedded in other pages.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws NotFoundException If organisation is not found
* @throws ForbiddenException If user is not authorized to access page
*/
public function getModalEdit(Request $request, Response $response, $args)
{
// GET parameters
$params = $request->getQueryParams();
$organisation = $this->getOrganisationFromParams($params);
// If the organisation doesn't exist, return 404
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
/** @var \UserFrosting\I18n\Translator $translator */
$translator = $this->ci->translator;
// Access-controlled resource - check that currentUser has permission to edit basic fields "name", "slug", "description" for this organisation
$fieldNames = ['name', 'slug', 'description'];
if (!$authorizer->checkAccess($currentUser, 'update_organisation_field', [
'organisation' => $organisation,
'fields' => $fieldNames,
])) {
throw new ForbiddenException();
}
// Generate form
$fields = [
'hidden' => [],
'disabled' => [],
];
// Load validation rules
$schema = new RequestSchema('schema://requests/organisation/edit-info.yaml');
$validator = new JqueryValidationAdapter($schema, $translator);
return $this->ci->view->render($response, 'modals/organisation.html.twig', [
'organisation' => $organisation,
'form' => [
'action' => "api/organisations/o/{$organisation->slug}",
'method' => 'PUT',
'fields' => $fields,
'submit_text' => $translator->translate('UPDATE'),
],
'page' => [
'validators' => $validator->rules('json', false),
],
]);
}
/**
* Renders the modal form for merging two organisations.
*
* This does NOT render a complete page. Instead, it renders the HTML for the modal, which can be embedded in other pages.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function getModalMerge(Request $request, Response $response, $args)
{
// GET parameters
$params = $request->getQueryParams();
$organisation = $this->getOrganisationFromParams($params);
// If the organisation doesn't exist, return 404
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
/** @var \UserFrosting\I18n\Translator $translator */
$translator = $this->ci->translator;
// Access-controlled resource - check that currentUser has permission to merge organisations.
if (!$authorizer->checkAccess($currentUser, 'merge_organisations')) {
throw new ForbiddenException();
}
// Load validation rules
$schema = new RequestSchema('schema://requests/organisation/merge.yaml');
$validator = new JqueryValidationAdapter($schema, $translator);
$otherOrganisations = $classMapper->getClassMapping('organisation')::where('id', '!=', $organisation->id)->get();
return $this->ci->view->render($response, 'modals/organisation-merge.html.twig', [
'organisation' => $organisation,
'other_organisations' => $otherOrganisations,
'form' => [
'action' => "api/organisations/o/{$organisation->slug}/merge",
'method' => 'POST',
'submit_text' => $translator->translate('MERGE'),
],
'page' => [
'validators' => $validator->rules('json', false),
],
]);
}
/**
* Renders a page displaying a organisation's information, in read-only mode.
*
* This checks that the currently logged-in user has permission to view the requested organisation's info.
* It checks each field individually, showing only those that you have permission to view.
* This will also try to show buttons for deleting, and editing the organisation.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function pageInfo(Request $request, Response $response, $args)
{
$organisation = $this->getOrganisationFromParams($args);
// If the organisation no longer exists, forward to main organisation listing page
if (!$organisation) {
throw new NotFoundException();
}
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'uri_organisation', [
'organisation' => $organisation,
])) {
throw new ForbiddenException();
}
// Determine fields that currentUser is authorized to view
$fieldNames = ['name', 'slug', 'description', 'members'];
// Generate form
$fields = [
'hidden' => [],
];
foreach ($fieldNames as $field) {
if (!$authorizer->checkAccess($currentUser, 'view_organisation_field', [
'organisation' => $organisation,
'property' => $field,
])) {
$fields['hidden'][] = $field;
}
}
// Determine buttons to display
$editButtons = [
'hidden' => [],
];
if (!$authorizer->checkAccess($currentUser, 'update_organisation_field', [
'organisation' => $organisation,
'fields' => ['name', 'slug', 'description', 'members'],
])) {
$editButtons['hidden'][] = 'edit';
}
if (!$authorizer->checkAccess($currentUser, 'delete_organisation', [
'organisation' => $organisation,
])) {
$editButtons['hidden'][] = 'delete';
}
return $this->ci->view->render($response, 'pages/organisation.html.twig', [
'organisation' => $organisation,
'fields' => $fields,
'tools' => $editButtons,
'delete_redirect' => $this->ci->router->pathFor('uri_organisations'),
]);
}
/**
* Renders the organisation listing page.
*
* This page renders a table of organisations, with dropdown menus for admin actions for each organisation.
* Actions typically include: edit organisation, delete organisation.
* This page requires authentication.
*
* Request type: GET
*
* @param Request $request
* @param Response $response
* @param array $args
*
* @throws ForbiddenException If user is not authorized to access page
*/
public function pageList(Request $request, Response $response, $args)
{
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
$authorizer = $this->ci->authorizer;
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
$currentUser = $this->ci->currentUser;
// Access-controlled page
if (!$authorizer->checkAccess($currentUser, 'uri_organisations')) {
throw new ForbiddenException();
}
return $this->ci->view->render($response, 'pages/organisations.html.twig');
}
/**
* Get organisation from params.
*
* @param array $params
*
* @throws BadRequestException
*
* @return Organisation
*/
protected function getOrganisationFromParams($params)
{
// Load the request schema
$schema = new RequestSchema('schema://requests/organisation/get-by-slug.yaml');
// Whitelist and set parameter defaults
$transformer = new RequestDataTransformer($schema);
$data = $transformer->transform($params);
// Validate, and throw exception on validation errors.
$validator = new ServerSideValidator($schema, $this->ci->translator);
if (!$validator->validate($data)) {
// TODO: encapsulate the communication of error messages from ServerSideValidator to the BadRequestException
$e = new BadRequestException();
foreach ($validator->errors() as $idx => $field) {
foreach ($field as $eidx => $error) {
$e->addUserMessage($error);
}
}
throw $e;
}
/** @var \UserFrosting\Sprinkle\Core\Util\ClassMapper $classMapper */
$classMapper = $this->ci->classMapper;
// Get the organisation
$organisation = $classMapper->getClassMapping('organisation')::where('slug', $data['slug'])
->first();
return $organisation;
}
}