237 lines
9.2 KiB
PHP
237 lines
9.2 KiB
PHP
<?php
|
|
|
|
/*
|
|
* AVSDev UF Tweaks (https://avsdev.uk)
|
|
*
|
|
* @link https://git.avsdev.uk/avsdev/sprinkle-uf-tweaks
|
|
* @license https://git.avsdev.uk/avsdev/sprinkle-uf-tweaks/blob/master/LICENSE.md (LGPL-3.0 License)
|
|
*/
|
|
|
|
namespace UserFrosting\Sprinkle\UFTweaks\ServicesProvider;
|
|
|
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
|
use Monolog\Formatter\LineFormatter;
|
|
use Monolog\Handler\StreamHandler;
|
|
use Monolog\Logger;
|
|
use Psr\Container\ContainerInterface;
|
|
use Psr\Http\Message\ResponseInterface as Response;
|
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
use UserFrosting\Sprinkle\Core\Log\MixedFormatter;
|
|
use UserFrosting\Sprinkle\UFTweaks\Twig\HasRoleExtension;
|
|
use UserFrosting\Sprinkle\UFTweaks\Twig\LocaleOverrideExtension;
|
|
use UserFrosting\Sprinkle\UFTweaks\Twig\MobileDetectExtension;
|
|
use UserFrosting\Sprinkle\UFTweaks\Mail\RetryMailer;
|
|
|
|
|
|
/**
|
|
* Registers services for the UFTweaks sprinkle.
|
|
*
|
|
* @author Craig Williams (https://avsdev.uk)
|
|
*/
|
|
class ServicesProvider
|
|
{
|
|
/**
|
|
* Register UserFrosting's services.
|
|
*
|
|
* @param ContainerInterface $container A DI container implementing ArrayAccess and psr-container.
|
|
*/
|
|
public function register(ContainerInterface $container)
|
|
{
|
|
/*
|
|
* Extend the 'classMapper' service to register sprunje classes.
|
|
*
|
|
* Mappings added: 'activity_sprunje'
|
|
*
|
|
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
|
*/
|
|
$container->extend('classMapper', function ($classMapper, $c) {
|
|
$classMapper->setClassMapping('activity_sprunje', 'UserFrosting\Sprinkle\UFTweaks\Sprunje\ActivitySprunje');
|
|
$classMapper->setClassMapping('user', 'UserFrosting\Sprinkle\UFTweaks\Database\Models\User');
|
|
$classMapper->setClassMapping('user_sprunje', 'UserFrosting\Sprinkle\Organisations\Sprunje\UserSprunje');
|
|
|
|
return $classMapper;
|
|
});
|
|
|
|
/*
|
|
* Returns a callback that forwards to dashboard if user is already logged in.
|
|
*
|
|
* @return callable
|
|
*/
|
|
$container['redirect.onAlreadyLoggedIn'] = function ($c) {
|
|
/*
|
|
* This method is invoked when a user attempts to perform certain public actions when they are already logged in.
|
|
*
|
|
* @todo Forward to user's landing page or last visited page
|
|
* @param \Psr\Http\Message\ServerRequestInterface $request
|
|
* @param \Psr\Http\Message\ResponseInterface $response
|
|
* @param array $args
|
|
* @return \Psr\Http\Message\ResponseInterface
|
|
*/
|
|
return function (Request $request, Response $response, array $args) use ($c) {
|
|
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager */
|
|
$authorizer = $c->authorizer;
|
|
|
|
$currentUser = $c->authenticator->user();
|
|
|
|
if ($authorizer->checkAccess($currentUser, 'uri_dashboard')) {
|
|
return $response->withRedirect($c->router->pathFor('dashboard'));
|
|
} else {
|
|
return $response->withRedirect($c->router->pathFor('index'));
|
|
}
|
|
};
|
|
};
|
|
|
|
/*
|
|
* Returns a callback that handles setting the `UF-Redirect` header after a successful login.
|
|
*
|
|
* Overrides the service definition in the account Sprinkle.
|
|
*
|
|
* @return callable
|
|
*/
|
|
$container['redirect.onLogin'] = function ($c) {
|
|
/*
|
|
* This method is invoked when a user completes the login process.
|
|
*
|
|
* Returns a callback that handles setting the `UF-Redirect` header after a successful login.
|
|
* @param \Psr\Http\Message\ServerRequestInterface $request
|
|
* @param \Psr\Http\Message\ResponseInterface $response
|
|
* @param array $args
|
|
* @return \Psr\Http\Message\ResponseInterface
|
|
*/
|
|
return function (Request $request, Response $response, array $args) use ($c) {
|
|
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager */
|
|
$authorizer = $c->authorizer;
|
|
|
|
$currentUser = $c->authenticator->user();
|
|
|
|
if ($authorizer->checkAccess($currentUser, 'uri_dashboard')) {
|
|
return $response->withHeader('UF-Redirect', $c->router->pathFor('dashboard'));
|
|
} else {
|
|
return $response->withHeader('UF-Redirect', $c->router->pathFor('index'));
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
* Extend the 'authorizer' service to fix some callbacks
|
|
*
|
|
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
|
*/
|
|
$container->extend('authorizer', function ($authorizer, $c) {
|
|
/*
|
|
* Check if all values in the array $needle are present in the values of $haystack.
|
|
*
|
|
* @param array[mixed] $needle the array whose values we should look for in $haystack
|
|
* @param array[mixed] $haystack the array of values to search.
|
|
* @return bool true if every value in $needle is present in the values of $haystack, false otherwise.
|
|
*/
|
|
$authorizer->addCallback(
|
|
'subset',
|
|
function ($needle, $haystack) {
|
|
if (!is_countable($needle)) {
|
|
$needle = [ $needle ];
|
|
}
|
|
return count($needle) == count(array_intersect($needle, $haystack));
|
|
}
|
|
);
|
|
|
|
/*
|
|
* Check if all keys of the array $needle are present in the values of $haystack.
|
|
*
|
|
* This function is useful for whitelisting an array of key-value parameters.
|
|
* @param array[mixed] $needle the array whose keys we should look for in $haystack
|
|
* @param array[mixed] $haystack the array of values to search.
|
|
* @return bool true if every key in $needle is present in the values of $haystack, false otherwise.
|
|
*/
|
|
$authorizer->addCallback(
|
|
'subset_keys',
|
|
function ($needle, $haystack) {
|
|
if (!is_countable($needle)) {
|
|
$needle = [ $needle ];
|
|
}
|
|
return count($needle) == count(array_intersect(array_keys($needle), $haystack));
|
|
}
|
|
);
|
|
|
|
/*
|
|
* Check if the specified user (by user_id) has a particular permission.
|
|
*
|
|
* @param int $user_id the id of the user.
|
|
* @param int $permission_slug slug of the permission to check.
|
|
* @return bool true if the user has the permission, false otherwise.
|
|
*/
|
|
$authorizer->addCallback(
|
|
'has_permission',
|
|
function ($user_id, $permission_slug) {
|
|
return Capsule::table('role_users')
|
|
->join('permission_roles', 'role_users.role_id', '=', 'permission_roles.role_id')
|
|
->join('permissions', 'permission_roles.permission_id', '=', 'permissions.id')
|
|
->where('user_id', $user_id)
|
|
->where('slug', $permission_slug)
|
|
->count() > 0;
|
|
}
|
|
);
|
|
|
|
return $authorizer;
|
|
});
|
|
|
|
/*
|
|
* Extends the 'view' service with the HasRole extension for Twig.
|
|
*
|
|
* @return \Slim\Views\Twig
|
|
*/
|
|
$container->extend('view', function ($view, $c) {
|
|
$twig = $view->getEnvironment();
|
|
|
|
$twig->addExtension(new HasRoleExtension($c));
|
|
$twig->addExtension(new MobileDetectExtension($c));
|
|
$twig->addExtension(new LocaleOverrideExtension($c));
|
|
|
|
return $view;
|
|
});
|
|
|
|
/*
|
|
* Token logging with Monolog.
|
|
*
|
|
* Extend this service to push additional handlers onto the 'tokens' log stack.
|
|
*
|
|
* @return \Monolog\Logger
|
|
*/
|
|
$container['tokenLogger'] = function ($c) {
|
|
$logger = new Logger('tokens');
|
|
|
|
$logFile = $c->locator->findResource('log://userfrosting.log', true, true);
|
|
|
|
$handler = new StreamHandler($logFile);
|
|
|
|
$formatter = new MixedFormatter(null, null, true);
|
|
|
|
$handler->setFormatter($formatter);
|
|
$logger->pushHandler($handler);
|
|
|
|
return $logger;
|
|
};
|
|
|
|
/*
|
|
* Mail service.
|
|
*
|
|
* @return \UserFrosting\Sprinkle\Core\Mail\Mailer
|
|
* @return \UserFrosting\Sprinkle\UFTweaks\Mail\RetryMailer
|
|
*/
|
|
$container->extend('mailer', function ($mailer, $c) {
|
|
if (!$c->config['retry_mailer.enabled']) {
|
|
return $mailer;
|
|
}
|
|
|
|
$retryMailer = new RetryMailer($c->mailLogger, $c->config['mail']);
|
|
|
|
// Use UF debug settings to override any service-specific log settings.
|
|
if (!$c->config['debug.smtp']) {
|
|
$retryMailer->getPhpMailer()->SMTPDebug = 0;
|
|
}
|
|
|
|
return $retryMailer;
|
|
});
|
|
}
|
|
} |