add jwt token users

This commit is contained in:
gerchek 2022-02-16 22:54:44 +05:00
parent c5dbac8940
commit 662301bf47
617 changed files with 53259 additions and 79 deletions

View File

@ -57,4 +57,8 @@
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Authorization header
# RewriteCond %{HTTP:Authorization} ^(.*)
# RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
</IfModule>

View File

@ -66,7 +66,10 @@
]
},
"config": {
"preferred-install": "dist"
"preferred-install": "dist",
"allow-plugins": {
"composer/installers": true
}
},
"minimum-stability": "dev",
"prefer-stable": true

View File

@ -16,7 +16,7 @@ return [
|
*/
'debug' => true,
'debug' => env('APP_DEBUG', true),
/*
|--------------------------------------------------------------------------
@ -41,7 +41,7 @@ return [
|
*/
'url' => 'http://localhost',
'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
@ -137,7 +137,7 @@ return [
|
*/
'key' => 'G0tXuSIIGZxHT8GyAhIF38OYxKrdW9CB',
'key' => env('APP_KEY', ''),
'cipher' => 'AES-256-CBC',

View File

@ -1,39 +1,91 @@
<?php
return [
'throttle' => [
/*
|--------------------------------------------------------------------------
| Enable throttling of Backend authentication attempts
|--------------------------------------------------------------------------
|
| If set to true, users will be given a limited number of attempts to sign
| in to the Backend before being blocked for a specified number of minutes.
|
*/
'enabled' => true,
/*
|--------------------------------------------------------------------------
| Failed Authentication Attempt Limit
|--------------------------------------------------------------------------
|
| Number of failed attempts allowed while trying to authenticate a user.
|
*/
'attemptLimit' => 5,
/*
|--------------------------------------------------------------------------
| Suspension Time
|--------------------------------------------------------------------------
|
| The number of minutes to suspend further attempts on authentication once
| the attempt limit is reached.
|
*/
'suspensionTime' => 15,
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => env('AUTH_DEFAULT_GUARD', 'web'),
'passwords' => env('AUTH_DEFAULT_PASSWORDS', 'users'),
],
];
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => env('AUTH_GUARDS_WEB_DRIVER', 'session'),
'provider' => env('AUTH_GUARDS_WEB_PROVIDER', 'users'),
],
'api' => [
'driver' => env('AUTH_GUARDS_API_DRIVER', 'token'),
'provider' => env('AUTH_GUARDS_API_PROVIDER', 'users'),
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => env('AUTH_PROVIDERS_USERS_DRIVER', 'eloquent'),
'model' => env('AUTH_PROVIDERS_USERS_MODEL', '\RainLab\User\Models\User'),
],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| Here you may set the options for resetting passwords including the view
| that is your password reset e-mail. You may also set the name of the
| table that maintains all of the reset tokens for your application.
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => env('AUTH_PASSWORDS_USERS_PROVIDER', 'users'),
'email' => env('AUTH_PASSWORDS_USERS_EMAIL', 'auth.emails.password'),
'table' => env('AUTH_PASSWORDS_USERS_TABLE', 'password_resets'),
'expire' => env('AUTH_PASSWORDS_USERS_EXPIRE', 60),
],
],
];

View File

@ -13,7 +13,7 @@ return [
|
*/
'default' => 'file',
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------

View File

@ -156,7 +156,7 @@ return [
|
*/
'enableRoutesCache' => false,
'enableRoutesCache' => env('ROUTES_CACHE', false),
/*
|--------------------------------------------------------------------------
@ -196,7 +196,7 @@ return [
|
*/
'enableAssetCache' => false,
'enableAssetCache' => env('ASSET_CACHE', false),
/*
|--------------------------------------------------------------------------
@ -250,7 +250,7 @@ return [
|
*/
'databaseTemplates' => false,
'databaseTemplates' => env('DATABASE_TEMPLATES', false),
/*
|--------------------------------------------------------------------------
@ -360,7 +360,7 @@ return [
|
*/
'linkPolicy' => 'detect',
'linkPolicy' => env('LINK_POLICY', 'detect'),
/*
|--------------------------------------------------------------------------
@ -396,7 +396,7 @@ return [
|
*/
'enableCsrfProtection' => true,
'enableCsrfProtection' => env('ENABLE_CSRF', true),
/*
|--------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@ return [
|
*/
'default' => 'mysql',
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
@ -48,18 +48,18 @@ return [
'sqlite' => [
'driver' => 'sqlite',
'database' => 'storage/database.sqlite',
'database' => env('DB_DATABASE', 'storage/database.sqlite'),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'engine' => 'InnoDB',
'host' => '192.168.1.2',
'port' => 3306,
'database' => 'bank_form',
'username' => 'orient',
'password' => 'orient',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'halk_bank_form'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
@ -68,11 +68,11 @@ return [
'pgsql' => [
'driver' => 'pgsql',
'host' => 'localhost',
'port' => 5432,
'database' => 'database',
'username' => 'root',
'password' => '',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 5432),
'database' => env('DB_DATABASE', 'database'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
@ -80,11 +80,11 @@ return [
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => 'localhost',
'port' => 1433,
'database' => 'database',
'username' => 'root',
'password' => '',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 5432),
'database' => env('DB_DATABASE', 'database'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'prefix' => '',
],
@ -120,9 +120,9 @@ return [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
@ -143,6 +143,6 @@ return [
|
*/
'useConfigForTesting' => false,
'useConfigForTesting' => env('DB_USE_CONFIG_FOR_TESTING', false),
];

View File

@ -16,7 +16,7 @@ return [
|
*/
'driver' => 'smtp',
'driver' => env('MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
@ -29,7 +29,7 @@ return [
|
*/
'host' => 'smtp.mailgun.org',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
@ -42,7 +42,7 @@ return [
|
*/
'port' => 587,
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
@ -71,7 +71,7 @@ return [
|
*/
'encryption' => 'tls',
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
@ -84,7 +84,7 @@ return [
|
*/
'username' => null,
'username' => env('MAIL_USERNAME', null),
/*
|--------------------------------------------------------------------------
@ -97,7 +97,7 @@ return [
|
*/
'password' => null,
'password' => env('MAIL_PASSWORD', null),
/*
|--------------------------------------------------------------------------

View File

@ -16,7 +16,7 @@ return [
|
*/
'default' => 'sync',
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------

View File

@ -16,7 +16,7 @@ return [
|
*/
'driver' => 'file',
'driver' => env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
<?php if (!isset($error)): ?>
<div class="control-status-list">
<ul>
<li>
<!-- <li>
<?php if ($updates): ?>
<span class="status-icon warning"><i class="icon-exclamation"></i></span>
<span class="status-text warning">
@ -19,8 +19,8 @@
<?= e(trans('backend::lang.dashboard.status.updates_nil')) ?>
</span>
<?php endif ?>
</li>
<li>
</li> -->
<!-- <li>
<?php if ($warnings): ?>
<span class="status-icon warning"><i class="icon-exclamation"></i></span>
<span class="status-text warning">
@ -38,7 +38,7 @@
<?= e(trans('backend::lang.dashboard.status.warnings_nil')) ?>
</span>
<?php endif ?>
</li>
</li> -->
<?php if ($coreBuild): ?>
<li>
<span class="status-icon"><i class="icon-info"></i></span>

View File

@ -0,0 +1,18 @@
<?php namespace AhmadFatoni\ApiGenerator;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public $require = [
'RainLab.Builder'
];
public function registerComponents()
{
}
public function registerSettings()
{
}
}

View File

@ -0,0 +1,50 @@
# API Generator
> October CMS plugin to build RESTful APIs.
## Features
- Auto generate routes
- Auto Generate Controller (CRUD)
- Support relationship restful API
## Install
```
composer require AhmadFatoni.ApiGenerator
```
## Usage
### Form
- API Name : Name of your API module
- Base Endpoint : Base endpoint of your API, ex : api/v1/modulename
- Short Description : Describe your API
- Model : select model that will be created API
- Custom Condition : Build customer response using JSON modeling
### Custom Condition Example
```
{
'fillable': 'id,title,content',
'relation': [{
'name': 'user',
'fillable': 'id,first_name'
}, {
'name': 'categories',
'fillable': 'id,name
}]
}
```
* please replace single quote with quote
## Contribute
Pull Requests accepted.
## Contact
You can communicate with me using [linkedin](https://www.linkedin.com/in/ahmad-fatoni)
## License
The OctoberCMS platform is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

View File

@ -0,0 +1,8 @@
{
"name": "ahmadfatoni/apigenerator-plugin",
"type": "october-plugin",
"description": "None",
"require": {
"composer/installers": "~1.0"
}
}

View File

@ -0,0 +1,336 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers;
use Backend\Classes\Controller;
use AhmadFatoni\ApiGenerator\Models\ApiGenerator;
use BackendMenu;
use Backend;
use Illuminate\Http\Request;
use Illuminate\Filesystem\Filesystem;
use Redirect;
use Flash;
class ApiGeneratorController extends Controller
{
public $implement = ['Backend\Behaviors\ListController','Backend\Behaviors\FormController','Backend\Behaviors\ReorderController'];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
protected $path = "/api/";
private $homePage = 'ahmadfatoni/apigenerator/apigeneratorcontroller';
protected $files;
public $requiredPermissions = ['ahmadfatoni.apigenerator.manage'];
public function __construct(Filesystem $files)
{
parent::__construct();
BackendMenu::setContext('AhmadFatoni.ApiGenerator', 'api-generator');
$this->files = $files;
}
/**
* delete selected data (multiple delete)
* @return [type] [description]
*/
public function index_onDelete()
{
if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {
foreach ($checkedIds as $id) {
if ((!$item = ApiGenerator::find($id)))
continue;
$name = $item->name;
if($item->delete()){
$this->deleteApi($name);
}
}
Flash::success('Successfully deleted those data.');
}
return $this->listRefresh();
}
/**
* generate API
* @param Request $request [description]
* @return [type] [description]
*/
public function generateApi(Request $request){
$data['model'] = $request->model;
$modelname = explode("\\", $request->model);
$modelname = $modelname[count($modelname)-1];
$data['modelname'] = $modelname;
$data['controllername'] = str_replace(" ", "", $request->name);
$data['endpoint'] = $request->endpoint;
$data['custom_format'] = $request->custom_format;
if( strpos($data['controllername'], ".") OR strpos($data['controllername'], "/") ){
Flash::success('Failed to create data, invalid API name.');
return Redirect::to( Backend::url($this->homePage));
}
if( isset($request->id) ){
$this->deleteApi($request->oldname, 'false');
}
$this->files->put(__DIR__ . $this->path . $data['controllername'].'Controller.php', $this->compile($data));
$this->files->put(__DIR__ . '/'.'../routes.php', $this->compileRoute($data));
return Redirect::to( Backend::url($this->homePage));
}
/**
* delete available API
* @param [type] $name [description]
* @param [type] $redirect [description]
* @return [type] [description]
*/
public function deleteApi($name, $redirect = null){
$fileLocation = __DIR__ . $this->path.$name;
$fileLocation = str_replace(".", "", $fileLocation);
if( ! file_exists($fileLocation.'Controller.php') ){
Flash::success('Failed to delete data, invalid file location.');
return Redirect::to( Backend::url($this->homePage));
}
if( strpos( strtolower($name), 'apigenerator' ) === false){
$data = [];
//generate new route
$this->files->put(__DIR__ . '/'.'../routes.php', $this->compileRoute($data));
//remove controller
if (file_exists( __DIR__ . $this->path.$name.'Controller.php' )) {
unlink(__DIR__ . $this->path.$name.'Controller.php');
}
if( $redirect != null ){
return 'success without redirect';
}
}
return Redirect::to( Backend::url($this->homePage));
}
public function updateApi($name){
}
/**
* compile controller from template
* @param [type] $data [description]
* @return [type] [description]
*/
public function compile($data){
if( $data['custom_format'] != ''){
$template = $this->files->get(__DIR__ .'/../template/customcontroller.dot');
$template = $this->replaceAttribute($template, $data);
$template = $this->replaceCustomAttribute($template, $data);
}else{
$template = $this->files->get(__DIR__ .'/../template/controller.dot');
$template = $this->replaceAttribute($template, $data);
}
return $template;
}
/**
* replace attribute
* @param [type] $template [description]
* @param [type] $data [description]
* @return [type] [description]
*/
public function replaceAttribute($template, $data){
if( isset( $data['model'] ) ){
$template = str_replace('{{model}}', $data['model'], $template);
}
$template = str_replace('{{modelname}}', $data['modelname'], $template);
$template = str_replace('{{controllername}}', $data['controllername'], $template);
return $template;
}
/**
* replace custom attribute
* @param [type] $template [description]
* @param [type] $data [description]
* @return [type] [description]
*/
public function replaceCustomAttribute($template, $data){
$arr = str_replace('\t', '', $data['custom_format']);
$arr = json_decode($arr);
$select = str_replace('<br />', '', $this->compileOpenIndexFunction($data['modelname'], 'index'));
$show = str_replace('<br />', '', $this->compileOpenIndexFunction($data['modelname'], 'show'));
$fillableParent = '';
if( isset($arr->fillable) AND $arr->fillable != null ) {
$fillableParent = $this->compileFillableParent($arr->fillable);
}
if( isset($arr->relation) AND $arr->relation != null AND is_array($arr->relation) AND count($arr->relation) > 0) {
$select .= str_replace('<br />', '', $this->compileFillableChild($arr->relation));
$show .= str_replace('<br />', '', $this->compileFillableChild($arr->relation));
}
$select .= "->select(".$fillableParent.")";
$show .= "->select(".$fillableParent.")->where('id', '=', \$id)->first();";
( $fillableParent != '') ? $select .= "->get()->toArray();" : $select .= "->toArray();" ;
$closeFunction = str_replace('<br />', '', nl2br(
"
return \$this->helpers->apiArrayResponseBuilder(200, 'success', \$data);
}"));
$select .= $closeFunction;
$show .= $closeFunction;
$template = str_replace('{{select}}', $select, $template);
$template = str_replace('{{show}}', $show, $template);
return $template;
}
public function compileOpenIndexFunction($modelname, $type){
if( $type == 'index'){
return nl2br("
public function index(){
\$data = \$this->".$modelname);
}else{
return nl2br("
public function show(\$id){
\$data = \$this->".$modelname);
}
}
public function compileFillableParent($fillable){
$fillableParentArr = explode(",", $fillable);
$fillableParent = '';
foreach ($fillableParentArr as $key) {
$fillableParent .= ",'".$key."'";
}
$fillableParent = substr_replace($fillableParent, '', 0 , 1);
return $fillableParent;
}
public function compileFillableChild($fillable){
$select = "->with(array(";
foreach ($fillable as $key) {
$fillableChild = "";
if( isset($key->fillable) AND $key->fillable != null ){
$fillableChildArr = explode(",", $key->fillable);
foreach ($fillableChildArr as $key2) {
$fillableChild .= ",'".$key2."'";
}
$fillableChild = substr_replace($fillableChild, '', 0 , 1);
}
$select .= nl2br(
"
'".$key->name."'=>function(\$query){
\$query->select(".$fillableChild.");
},");
}
$select .= " ))";
return $select;
}
public function compileRoute($data){
$oldData = ApiGenerator::all();
$routeList = "";
if( count($oldData) > 0 ){
$routeList .= $this->parseRouteOldData($oldData, $data);
}
if( count($data) > 0 ){
$data['modelname'] = $data['endpoint'];
if( $data['modelname'][0] == "/" ){
$data['modelname'] = substr_replace($data['modelname'], '', 0 , 1);
}
$routeList .= $this->parseRoute($data);
}
$route = $this->files->get(__DIR__ .'/../template/routes.dot');
$route = str_replace('{{route}}', $routeList, $route);
return $route;
}
public function parseRouteOldData($oldData, $data = null){
$routeList = "";
if( count($data) == 0 ) $data['modelname']='';
foreach ( $oldData as $key ) {
$modelname = explode("\\", $key->model);
$modelname = $modelname[count($modelname)-1];
$old['modelname'] = $key->endpoint;
$old['controllername'] = $key->name;
if( $data['modelname'] != $modelname ){
if( $old['modelname'][0] == "/" ){
$old['modelname'] = substr_replace($old['modelname'], '', 0 , 1);
}
$routeList .= $this->parseRoute($old);
}
}
return $routeList;
}
public function parseRoute($data){
$template = $this->files->get(__DIR__ .'/../template/route.dot');
$template = $this->replaceAttribute($template, $data);
return $template;
}
public static function getAfterFilters() {return [];}
public static function getBeforeFilters() {return [];}
public function callAction($method, $parameters=false) {
return call_user_func_array(array($this, $method), $parameters);
}
}

View File

@ -0,0 +1 @@
api controller here

View File

@ -0,0 +1,99 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use AhmadFatoni\ApiGenerator\Helpers\Helpers;
use Illuminate\Support\Facades\Validator;
use RainLab\User\Models\User;
class usersigninController extends Controller
{
protected $User;
protected $helpers;
public function __construct(User $User, Helpers $helpers)
{
parent::__construct();
$this->User = $User;
$this->helpers = $helpers;
}
public function index(){
$data = $this->User->all()->toArray();
return $this->helpers->apiArrayResponseBuilder(200, 'success', $data);
}
public function show($id){
$data = $this->User::find($id);
if ($data){
return $this->helpers->apiArrayResponseBuilder(200, 'success', [$data]);
} else {
$this->helpers->apiArrayResponseBuilder(404, 'not found', ['error' => 'Resource id=' . $id . ' could not be found']);
}
}
public function store(Request $request){
$arr = $request->all();
while ( $data = current($arr)) {
$this->User->{key($arr)} = $data;
next($arr);
}
$validation = Validator::make($request->all(), $this->User->rules);
if( $validation->passes() ){
$this->User->save();
return $this->helpers->apiArrayResponseBuilder(201, 'created', ['id' => $this->User->id]);
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'fail', $validation->errors() );
}
}
public function update($id, Request $request){
$status = $this->User->where('id',$id)->update($data);
if( $status ){
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been updated successfully.');
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'bad request', 'Error, data failed to update.');
}
}
public function delete($id){
$this->User->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public function destroy($id){
$this->User->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public static function getAfterFilters() {return [];}
public static function getBeforeFilters() {return [];}
public static function getMiddleware() {return [];}
public function callAction($method, $parameters=false) {
return call_user_func_array(array($this, $method), $parameters);
}
}

View File

@ -0,0 +1,18 @@
<div data-control="toolbar">
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller/create') ?>" class="btn btn-primary oc-icon-plus"><?= e(trans('backend::lang.form.create')) ?></a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
</div>

View File

@ -0,0 +1,3 @@
<div data-control="toolbar">
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-primary oc-icon-caret-left"><?= e(trans('backend::lang.form.return_to_list')) ?></a>
</div>

View File

@ -0,0 +1,10 @@
name: ApiGeneratorController
form: $/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml
modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator
defaultRedirect: ahmadfatoni/apigenerator/apigeneratorcontroller
create:
redirect: 'ahmadfatoni/apigenerator/apigeneratorcontroller/update/:id'
redirectClose: ahmadfatoni/apigenerator/apigeneratorcontroller
update:
redirect: ahmadfatoni/apigenerator/apigeneratorcontroller
redirectClose: ahmadfatoni/apigenerator/apigeneratorcontroller

View File

@ -0,0 +1,11 @@
list: $/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml
modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator
title: ApiGeneratorController
noRecordsMessage: 'backend::lang.list.no_records'
showSetup: true
showCheckboxes: true
toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'
recordUrl: 'ahmadfatoni/apigenerator/apigeneratorcontroller/update/:id'

View File

@ -0,0 +1,4 @@
title: ApiGeneratorController
modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator
toolbar:
buttons: reorder_toolbar

View File

@ -0,0 +1,97 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiListController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Custom Condition</h4>
</div>
<div class="modal-body">
<?php
$data = '{
"fillable": "id,title,content",
"relation": [{
"name": "user",
"fillable": "id,first_name"
}, {
"name": "categories",
"fillable": "id,name"
}]
}';
echo $data ;
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-success="saveData()"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<a data-toggle="modal" href='#modal-id'>
<button type="button" class="btn btn-default">
Example Custom Condition
</button>
</a>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-warning">Cancel</a>
</div>
</div>
<?= Form::close() ?>
<form method="post" id="generate" accept-charset="utf-8" action="<?= route('fatoni.generate.api') ?>" style="display:none">
<input type='text' name='name' id="name">
<input type='text' name='model' id="model">
<input type='text' name='custom_format' id="custom_format">
<input type='text' name='endpoint' id="endpoint">
<button
type="submit"
class="btn btn-primary" name="send" id="send">
send
</button>
</form>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>
<script type="text/javascript">
function saveData(){
document.getElementById('name').value = document.getElementById('Form-field-ApiGenerator-name').value;
document.getElementById('model').value = document.getElementById('Form-field-ApiGenerator-model').value;
document.getElementById('custom_format').value = document.getElementById('Form-field-ApiGenerator-custom_format').value;
document.getElementById('endpoint').value = document.getElementById('Form-field-ApiGenerator-endpoint').value;
document.getElementById('send').click();
}
</script>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,22 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiGeneratorController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<?php endif ?>
<p>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default oc-icon-chevron-left">
<?= e(trans('backend::lang.form.return_to_list')) ?>
</a>
</p>

View File

@ -0,0 +1,8 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiGeneratorController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?= $this->reorderRender() ?>

View File

@ -0,0 +1,133 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiListController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Custom Condition</h4>
</div>
<div class="modal-body">
<?php
$data = '{
"fillable": "id,title,content",
"relation": [{
"name": "user",
"fillable": "id,first_name"
}, {
"name": "categories",
"fillable": "id,name"
}]
}';
echo $data ;
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-success="saveData()"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-warning"><div id="cancel">Cancel</div></a>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-request-success="delData()"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
</button>
<a data-toggle="modal" href='#modal-id'>
<button type="button" class="btn btn-default">
Example Custom Condition
</button>
</a>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>
<form method="get" id="del" style="display:none" action="<?= route('fatoni.delete.api', ['id'=> $this->widget->form->data->attributes['name'] ]) ?>">
<button
type="submit"
class="btn btn-primary" name="send" id="send">
send
</button>
</form>
<form method="post" id="generate" accept-charset="utf-8" action="<?= route('fatoni.generate.api') ?>" style="display:none">
<input type='text' name='id' id="id" value="<?= $this->widget->form->data->attributes['id'] ?>">
<input type='text' name='name' id="name">
<input type='text' name='endpoint' id="endpoint">
<input type='text' name='oldname' id="oldname" value="<?= $this->widget->form->data->attributes['name'] ?>">
<input type='text' name='oldmodel' id="oldmodel" value="<?= $this->widget->form->data->attributes['model'] ?>">
<input type='text' name='oldendpoint' id="oldendpoint" value="<?= $this->widget->form->data->attributes['endpoint'] ?>">
<textarea name='oldcustom_format' id="oldcustom_format"><?= $this->widget->form->data->attributes['custom_format'] ?></textarea>
<input type='text' name='model' id="model">
<input type='text' name='custom_format' id="custom_format">
<button
type="submit"
class="btn btn-primary" name="save" id="save">
send
</button>
</form>
<script type="text/javascript">
function delData(){
document.getElementById('send').click();
}
</script>
<script type="text/javascript">
function saveData(){
document.getElementById('name').value = document.getElementById('Form-field-ApiGenerator-name').value;
document.getElementById('model').value = document.getElementById('Form-field-ApiGenerator-model').value;
document.getElementById('custom_format').value = document.getElementById('Form-field-ApiGenerator-custom_format').value;
document.getElementById('endpoint').value = document.getElementById('Form-field-ApiGenerator-endpoint').value;
if (
document.getElementById('name').value != document.getElementById('oldname').value ||
document.getElementById('Form-field-ApiGenerator-model').value != document.getElementById('oldmodel').value ||
document.getElementById('Form-field-ApiGenerator-custom_format').value != document.getElementById('oldcustom_format').value ||
document.getElementById('Form-field-ApiGenerator-endpoint').value != document.getElementById('oldendpoint').value
){
document.getElementById('save').click();
}else{
document.getElementById('cancel').click();
}
}
</script>

View File

@ -0,0 +1,19 @@
<?php namespace AhmadFatoni\ApiGenerator\Helpers;
Class Helpers {
public function apiArrayResponseBuilder($statusCode = null, $message = null, $data = [])
{
$arr = [
'status_code' => (isset($statusCode)) ? $statusCode : 500,
'message' => (isset($message)) ? $message : 'error'
];
if (count($data) > 0) {
$arr['data'] = $data;
}
return response()->json($arr, $arr['status_code']);
//return $arr;
}
}

View File

@ -0,0 +1,6 @@
<?php return [
'plugin' => [
'name' => 'API-Generator',
'description' => 'Generate API base on Builder Plugin'
]
];

View File

@ -0,0 +1,76 @@
<?php namespace AhmadFatoni\ApiGenerator\Models;
use Model, Log;
use RainLab\Builder\Classes\ComponentHelper;
/**
* Model
*/
class ApiGenerator extends Model
{
use \October\Rain\Database\Traits\Validation;
/*
* Validation
*/
public $rules = [
'name' => 'required|unique:ahmadfatoni_apigenerator_data,name|regex:/^[\pL\s\-]+$/u',
'endpoint' => 'required|unique:ahmadfatoni_apigenerator_data,endpoint',
'custom_format' => 'json'
];
public $customMessages = [
'custom_format.json' => 'Invalid Json Format Custom Condition'
];
/*
* Disable timestamps by default.
* Remove this line if timestamps are defined in the database table.
*/
public $timestamps = false;
/**
* @var string The database table used by the model.
*/
public $table = 'ahmadfatoni_apigenerator_data';
/**
* get model List
* @return [type] [description]
*/
public function getModelOptions(){
return ComponentHelper::instance()->listGlobalModels();
}
/**
* [setCustomFormatAttribute description]
* @param [type] $value [description]
*/
public function setCustomFormatAttribute($value){
$json = str_replace('\t', '', $value);
$json = json_decode($json);
if( $json != null){
if( ! isset($json->fillable) AND ! isset($json->relation) ){
return $this->attributes['custom_format'] = 'invalid format';
}
if( isset($json->relation) AND $json->relation != null ){
foreach ($json->relation as $key) {
if( !isset($key->name) OR $key->name == null ){
return $this->attributes['custom_format'] = 'invalid format';
}
}
}
}
return $this->attributes['custom_format'] = $value;
}
}

View File

@ -0,0 +1,9 @@
columns:
name:
label: 'API NAME'
type: text
searchable: true
sortable: true
endpoint:
label: 'BASE ENDPOINT'
type: text

View File

@ -0,0 +1,33 @@
fields:
name:
label: 'API Name'
oc.commentPosition: ''
span: auto
placeholder: 'Name of your API'
required: 1
type: text
endpoint:
label: 'Base Endpoint'
oc.commentPosition: ''
span: auto
placeholder: api/v1/modulename
required: 1
type: text
description:
label: 'Short Description'
oc.commentPosition: ''
span: auto
placeholder: 'Descript your API'
type: text
model:
label: 'Select Model'
oc.commentPosition: ''
span: auto
required: 1
type: dropdown
custom_format:
label: 'Custom Condition (Fillable and Relation)'
size: large
oc.commentPosition: ''
span: full
type: textarea

View File

@ -0,0 +1,17 @@
plugin:
name: 'ahmadfatoni.apigenerator::lang.plugin.name'
description: 'ahmadfatoni.apigenerator::lang.plugin.description'
author: AhmadFatoni
icon: oc-icon-bolt
homepage: ''
navigation:
api-generator:
label: 'API Generator'
url: ahmadfatoni/apigenerator/apigeneratorcontroller
icon: icon-cogs
permissions:
- ahmadfatoni.apigenerator.manage
permissions:
ahmadfatoni.apigenerator.manage:
tab: 'API Generator'
label: 'Manage the API Generator'

View File

@ -0,0 +1,8 @@
<?php
Route::post('fatoni/generate/api', array('as' => 'fatoni.generate.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@generateApi'));
Route::post('fatoni/update/api/{id}', array('as' => 'fatoni.update.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@updateApi'));
Route::get('fatoni/delete/api/{id}', array('as' => 'fatoni.delete.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@deleteApi'));
Route::resource('user_sign_in', 'AhmadFatoni\ApiGenerator\Controllers\API\usersigninController', ['except' => ['destroy', 'create', 'edit']]);
Route::get('user_sign_in/{id}/delete', ['as' => 'user_sign_in.delete', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\API\usersigninController@destroy']);

View File

@ -0,0 +1,99 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use AhmadFatoni\ApiGenerator\Helpers\Helpers;
use Illuminate\Support\Facades\Validator;
use {{model}};
class {{controllername}}Controller extends Controller
{
protected ${{modelname}};
protected $helpers;
public function __construct({{modelname}} ${{modelname}}, Helpers $helpers)
{
parent::__construct();
$this->{{modelname}} = ${{modelname}};
$this->helpers = $helpers;
}
public function index(){
$data = $this->{{modelname}}->all()->toArray();
return $this->helpers->apiArrayResponseBuilder(200, 'success', $data);
}
public function show($id){
$data = $this->{{modelname}}::find($id);
if ($data){
return $this->helpers->apiArrayResponseBuilder(200, 'success', [$data]);
} else {
$this->helpers->apiArrayResponseBuilder(404, 'not found', ['error' => 'Resource id=' . $id . ' could not be found']);
}
}
public function store(Request $request){
$arr = $request->all();
while ( $data = current($arr)) {
$this->{{modelname}}->{key($arr)} = $data;
next($arr);
}
$validation = Validator::make($request->all(), $this->{{modelname}}->rules);
if( $validation->passes() ){
$this->{{modelname}}->save();
return $this->helpers->apiArrayResponseBuilder(201, 'created', ['id' => $this->{{modelname}}->id]);
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'fail', $validation->errors() );
}
}
public function update($id, Request $request){
$status = $this->{{modelname}}->where('id',$id)->update($data);
if( $status ){
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been updated successfully.');
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'bad request', 'Error, data failed to update.');
}
}
public function delete($id){
$this->{{modelname}}->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public function destroy($id){
$this->{{modelname}}->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public static function getAfterFilters() {return [];}
public static function getBeforeFilters() {return [];}
public static function getMiddleware() {return [];}
public function callAction($method, $parameters=false) {
return call_user_func_array(array($this, $method), $parameters);
}
}

View File

@ -0,0 +1,35 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use {{model}};
class ApiListController extends Controller
{
protected ${{modelname}};
public function __construct({{modelname}} ${{modelname}})
{
parent::__construct();
$this->{{modelname}} = ${{modelname}};
}
public static function getAfterFilters() {return [];}
public static function getBeforeFilters() {return [];}
public static function getMiddleware() {return [];}
public function callAction($method, $parameters=false) {
return call_user_func_array(array($this, $method), $parameters);
}
// public function create(Request $request){
// $arr = $request->all();
// while ( $data = current($arr)) {
// $this->
// }
// return json_encode($this->{{modelname}}->store($request));
// }
}

View File

@ -0,0 +1,83 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use AhmadFatoni\ApiGenerator\Helpers\Helpers;
use {{model}};
class {{controllername}}Controller extends Controller
{
protected ${{modelname}};
protected $helpers;
public function __construct({{modelname}} ${{modelname}}, Helpers $helpers)
{
parent::__construct();
$this->{{modelname}} = ${{modelname}};
$this->helpers = $helpers;
}
{{select}}
{{show}}
public function store(Request $request){
$arr = $request->all();
while ( $data = current($arr)) {
$this->{{modelname}}->{key($arr)} = $data;
next($arr);
}
$validation = Validator::make($request->all(), $this->{{modelname}}->rules);
if( $validation->passes() ){
$this->{{modelname}}->save();
return $this->helpers->apiArrayResponseBuilder(201, 'created', ['id' => $this->{{modelname}}->id]);
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'fail', $validation->errors() );
}
}
public function update($id, Request $request){
$status = $this->{{modelname}}->where('id',$id)->update($data);
if( $status ){
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been updated successfully.');
}else{
return $this->helpers->apiArrayResponseBuilder(400, 'bad request', 'Error, data failed to update.');
}
}
public function delete($id){
$this->{{modelname}}->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public function destroy($id){
$this->{{modelname}}->where('id',$id)->delete();
return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.');
}
public static function getAfterFilters() {return [];}
public static function getBeforeFilters() {return [];}
public static function getMiddleware() {return [];}
public function callAction($method, $parameters=false) {
return call_user_func_array(array($this, $method), $parameters);
}
}

View File

@ -0,0 +1,3 @@
Route::resource('{{modelname}}', 'AhmadFatoni\ApiGenerator\Controllers\API\{{controllername}}Controller', ['except' => ['destroy', 'create', 'edit']]);
Route::get('{{modelname}}/{id}/delete', ['as' => '{{modelname}}.delete', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\API\{{controllername}}Controller@destroy']);

View File

@ -0,0 +1,6 @@
<?php
Route::post('fatoni/generate/api', array('as' => 'fatoni.generate.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@generateApi'));
Route::post('fatoni/update/api/{id}', array('as' => 'fatoni.update.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@updateApi'));
Route::get('fatoni/delete/api/{id}', array('as' => 'fatoni.delete.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@deleteApi'));
{{route}}

View File

@ -0,0 +1,26 @@
<?php namespace AhmadFatoni\ApiGenerator\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableCreateAhmadfatoniApigeneratorData extends Migration
{
public function up()
{
Schema::create('ahmadfatoni_apigenerator_data', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name');
$table->string('endpoint');
$table->string('model');
$table->string('description')->nullable();
$table->text('custom_format')->nullable();
});
}
public function down()
{
Schema::dropIfExists('ahmadfatoni_apigenerator_data');
}
}

View File

@ -0,0 +1,15 @@
1.0.1:
- 'Initialize plugin.'
1.0.2:
- 'Database implementation'
1.0.3:
- 'add builder plugin on requirements dependency'
- builder_table_create_ahmadfatoni_apigenerator_data.php
1.0.4:
- 'fixing bug on PHP 7'
1.0.5:
- 'fixing bug on request delete data'
1.0.6:
- 'fixing bug on generate endpoint'
1.0.7:
- 'fixing bug on October CMS v1.0.456'

3
plugins/rainlab/user/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.phpunit.result.cache
composer.lock
vendor

View File

@ -0,0 +1,19 @@
# MIT license
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,193 @@
<?php namespace RainLab\User;
use App;
use Auth;
use Event;
use Backend;
use System\Classes\PluginBase;
use System\Classes\SettingsManager;
use Illuminate\Foundation\AliasLoader;
use RainLab\User\Classes\UserRedirector;
use RainLab\User\Models\MailBlocker;
use RainLab\Notify\Classes\Notifier;
class Plugin extends PluginBase
{
/**
* @var boolean Determine if this plugin should have elevated privileges.
*/
public $elevated = true;
public function pluginDetails()
{
return [
'name' => 'rainlab.user::lang.plugin.name',
'description' => 'rainlab.user::lang.plugin.description',
'author' => 'Alexey Bobkov, Samuel Georges',
'icon' => 'icon-user',
'homepage' => 'https://github.com/rainlab/user-plugin'
];
}
public function register()
{
$alias = AliasLoader::getInstance();
$alias->alias('Auth', \RainLab\User\Facades\Auth::class);
App::singleton('user.auth', function () {
return \RainLab\User\Classes\AuthManager::instance();
});
App::singleton('redirect', function ($app) {
// overrides with our own extended version of Redirector to support
// seperate url.intended session variable for frontend
$redirector = new UserRedirector($app['url']);
// If the session is set on the application instance, we'll inject it into
// the redirector instance. This allows the redirect responses to allow
// for the quite convenient "with" methods that flash to the session.
if (isset($app['session.store'])) {
$redirector->setSession($app['session.store']);
}
return $redirector;
});
/*
* Apply user-based mail blocking
*/
Event::listen('mailer.prepareSend', function ($mailer, $view, $message) {
return MailBlocker::filterMessage($view, $message);
});
/*
* Compatability with RainLab.Notify
*/
$this->bindNotificationEvents();
}
public function registerComponents()
{
return [
\RainLab\User\Components\Session::class => 'session',
\RainLab\User\Components\Account::class => 'account',
\RainLab\User\Components\ResetPassword::class => 'resetPassword'
];
}
public function registerPermissions()
{
return [
'rainlab.users.access_users' => [
'tab' => 'rainlab.user::lang.plugin.tab',
'label' => 'rainlab.user::lang.plugin.access_users'
],
'rainlab.users.access_groups' => [
'tab' => 'rainlab.user::lang.plugin.tab',
'label' => 'rainlab.user::lang.plugin.access_groups'
],
'rainlab.users.access_settings' => [
'tab' => 'rainlab.user::lang.plugin.tab',
'label' => 'rainlab.user::lang.plugin.access_settings'
],
'rainlab.users.impersonate_user' => [
'tab' => 'rainlab.user::lang.plugin.tab',
'label' => 'rainlab.user::lang.plugin.impersonate_user'
],
];
}
public function registerNavigation()
{
return [
'user' => [
'label' => 'rainlab.user::lang.users.menu_label',
'url' => Backend::url('rainlab/user/users'),
'icon' => 'icon-user',
'iconSvg' => 'plugins/rainlab/user/assets/images/user-icon.svg',
'permissions' => ['rainlab.users.*'],
'order' => 500,
'sideMenu' => [
'users' => [
'label' => 'rainlab.user::lang.users.menu_label',
'icon' => 'icon-user',
'url' => Backend::url('rainlab/user/users'),
'permissions' => ['rainlab.users.access_users']
],
'usergroups' => [
'label' => 'rainlab.user::lang.groups.menu_label',
'icon' => 'icon-users',
'url' => Backend::url('rainlab/user/usergroups'),
'permissions' => ['rainlab.users.access_groups']
]
]
]
];
}
public function registerSettings()
{
return [
'settings' => [
'label' => 'rainlab.user::lang.settings.menu_label',
'description' => 'rainlab.user::lang.settings.menu_description',
'category' => SettingsManager::CATEGORY_USERS,
'icon' => class_exists('System') ? 'octo-icon-user-actions-key' : 'icon-cog',
'class' => 'RainLab\User\Models\Settings',
'order' => 500,
'permissions' => ['rainlab.users.access_settings']
]
];
}
public function registerMailTemplates()
{
return [
'rainlab.user::mail.activate',
'rainlab.user::mail.welcome',
'rainlab.user::mail.restore',
'rainlab.user::mail.new_user',
'rainlab.user::mail.reactivate',
'rainlab.user::mail.invite',
];
}
public function registerNotificationRules()
{
return [
'groups' => [
'user' => [
'label' => 'User',
'icon' => 'icon-user'
],
],
'events' => [
\RainLab\User\NotifyRules\UserActivatedEvent::class,
\RainLab\User\NotifyRules\UserRegisteredEvent::class,
],
'actions' => [],
'conditions' => [
\RainLab\User\NotifyRules\UserAttributeCondition::class
],
];
}
protected function bindNotificationEvents()
{
if (!class_exists(Notifier::class)) {
return;
}
Notifier::bindEvents([
'rainlab.user.activate' => \RainLab\User\NotifyRules\UserActivatedEvent::class,
'rainlab.user.register' => \RainLab\User\NotifyRules\UserRegisteredEvent::class
]);
Notifier::instance()->registerCallback(function ($manager) {
$manager->registerGlobalParams([
'user' => Auth::getUser()
]);
});
}
}

View File

@ -0,0 +1,351 @@
# Front-end user plugin
Front-end user management for October CMS.
## Requirements
This plugin requires the [Ajax Framework](https://octobercms.com/docs/cms/ajax) to be included in your layout/page in order to handle form requests.
## Managing users
Users are managed on the Users tab found in the back-end. Each user provides minimal data fields - **Name**, **Surname**, **Email** and **Password**. The Name can represent either the person's first name or their full name, making the Surname field optional, depending on the complexity of your site.
Below the **Email** field is an checkbox to block all outgoing mail sent to the user. This is a useful feature for accounts with an email address that is bouncing mail or has reported spam. When checked, no mail will ever be sent to this address, except for the mail template used for resetting the password.
## Plugin settings
This plugin creates a Settings menu item, found by navigating to **Settings > Users > User settings**. This page allows the setting of common features, described in more detail below.
#### Registration
Registration to the site is allowed by default. If you are running a closed site, or need to temporarily disable registration, you may disable this feature by switching **Allow user registration** to the OFF setting.
#### Activation
Activation is a process of vetting a user who joins the site. By default, users are activated automatically when they register and an activated account is required to sign in.
The **Activation mode** specifies the activation workflow:
- **Automatic**: This mode will automatically activate a user when they first register. This is the same as disabling activation entirely and is the default setting.
- **User**: The user can activate their account by responding to a confirmation message sent to their nominated email address.
- **Administrator**: The user can only be activated by an administrator via the back-end area.
You can allow users to sign in without activating by switching **Sign in requires activation** to the OFF setting. This is useful for minimising friction when registering, however with this approach it is often a good idea to disable any "identity sensitive" features until the user has been activated, such as posting content. Alternatively, you could implement a grace period that deletes users (with sufficient warning!) who have not activated within a given period of time.
Users have the ability to resend the activation email by clicking **Send the verification email again** found in the Account component.
#### Sign in
By default a User will sign in to the site using their email address as a unique identifier. You may use a unique login name instead by changing the **Login attribute** value to Username. This will introduce a new field called **Username** for each user, allowing them to specify their own short name or alias for identification. Both the Email address and Username must be unique to the user.
If a user experiences too many failed sign in attempts, their account will be temporarily suspended for a period of time. This feature is enabled by default and will suspend an account for 15 minutes after 5 failed sign in attempts, for a given IP address. You may disable this feature by switching **Throttle attempts** to the OFF setting.
As a security precaution, you may restrict users from having sessions across multiple devices at the same time. Enable the **Prevent concurrent sessions** setting to use this feature. When a user signs in to their account, it will automatically sign out the user for all other sessions.
#### Notifications
This feature is implemented by the Notify plugin. How to use this feature:
- Install the **RainLab.Notify** plugin
- Navigate to **Settings > Notification** rules
- Click **New notification rule**
- Select **User > Activated**
- Click **Add action**
- Select **Compose a mail message**
- Select **User email address** for the **Send to** field
- Here you may select the Mail template previously defined in the user settings.
- Click **Save**
## Extended features
For extra functionality, consider also installing the [User Plus+ plugin](http://octobercms.com/plugin/rainlab-userplus) (`RainLab.UserPlus`).
## Session component
The session component should be added to a layout that has registered users. It has no default markup.
### User variable
You can check the logged in user by accessing the **{{ user }}** Twig variable:
{% if user %}
<p>Hello {{ user.name }}</p>
{% else %}
<p>Nobody is logged in</p>
{% endif %}
### Signing out
The Session component allows a user to sign out of their session.
<a data-request="onLogout" data-request-data="redirect: '/good-bye'">Sign out</a>
### Page restriction
The Session component allows the restriction of a page or layout by allowing only signed in users, only guests or no restriction. This example shows how to restrict a page to users only:
title = "Restricted page"
url = "/users-only"
[session]
security = "user"
redirect = "home"
The `security` property can be user, guest or all. The `redirect` property refers to a page name to redirect to when access is restricted.
### Route restriction
Access to routes can be restricted by applying the `AuthMiddleware`.
Route::group(['middleware' => 'RainLab\User\Classes\AuthMiddleware'], function () {
// All routes here will require authentication
});
## Account component
The account component provides a user sign in form, registration form, activation form and update form. To display the form:
title = "Account"
url = "/account/:code?"
[account]
redirect = "home"
paramCode = "code"
==
{% component 'account' %}
If the user is logged out, this will display a sign in and registration form. Otherwise, it will display an update form. The `redirect` property is the page name to redirect to after the submit process is complete. The `paramCode` is the URL routing code used for activating the user, only used if the feature is enabled.
## Reset Password component
The reset password component allows a user to reset their password if they have forgotten it.
title = "Forgotten your password?"
url = "/forgot-password/:code?"
[resetPassword]
paramCode = "code"
==
{% component 'resetPassword' %}
This will display the initial restoration request form and also the password reset form used after the verification email has been received by the user. The `paramCode` is the URL routing code used for resetting the password.
## Using a login name
By default the User plugin will use the email address as the login name. To switch to using a user defined login name, navigate to the backend under System > Users > User Settings and change the Login attribute under the Sign in tab to be **Username**. Then simply ask for a username upon registration by adding the username field:
<form data-request="onRegister">
<label>Full Name</label>
<input name="name" type="text" placeholder="Enter your full name">
<label>Email</label>
<input name="email" type="email" placeholder="Enter your email">
<label>Username</label>
<input name="username" placeholder="Pick a login name">
<label>Password</label>
<input name="password" type="password" placeholder="Choose a password">
<button type="submit">Register</button>
</form>
We can add any other additional fields here too, such as `phone`, `company`, etc.
## Password length requirements
By default, the User plugin requires a minimum password length of 8 characters for all users when registering or changing their password. You can change this length requirement by going to backend and navigating to System > Users > User Settings. Inside the Registration tab, a **Minimum password length** field is provided, allowing you to increase or decrease this limit to your preferred length.
## Error handling
### Flash messages
This plugin makes use of October's [`Flash API`](http://octobercms.com/docs/markup/tag-flash). In order to display the error messages, you need to place the following snippet in your layout or page.
{% flash %}
<div class="alert alert-{{ type == 'error' ? 'danger' : type }}">{{ message }}</div>
{% endflash %}
### AJAX errors
The User plugin displays AJAX error messages in a simple ``alert()``-box by default. However, this might scare non-technical users. You can change the default behavior of an AJAX error from displaying an ``alert()`` message, like this:
<script>
$(window).on('ajaxErrorMessage', function (event, message){
// This can be any custom JavaScript you want
alert('Something bad happened, mate, here it is: ' + message);
// This will stop the default alert() message
event.preventDefault();
})
</script>
### Checking if a login name is already taken
Here is a simple example of how you can quickly check if an email address / username is available in your registration forms. First, inside the page code, define the following AJAX handler to check the login name, here we are using the email address:
public function onCheckEmail()
{
return ['isTaken' => Auth::findUserByLogin(post('email')) ? 1 : 0];
}
For the email input we use the `data-request` and `data-track-input` attributes to call the `onCheckEmail` handler any time the field is updated. The `data-request-success` attribute will call some jQuery code to toggle the alert box.
<div class="form-group">
<label>Email address</label>
<input
name="email"
type="email"
class="form-control"
data-request="onCheckEmail"
data-request-success="$('#loginTaken').toggle(!!data.isTaken)"
data-track-input />
</div>
<div id="loginTaken" class="alert alert-danger" style="display: none">
Sorry, that login name is already taken.
</div>
## Overriding functionality
Here is how you would override the `onSignin()` handler to log any error messages. Inside the page code, define this method:
function onSignin()
{
try {
return $this->account->onSignin();
}
catch (Exception $ex) {
Log::error($ex);
}
}
Here the local handler method will take priority over the **account** component's event handler. Then we simply inherit the logic by calling the parent handler manually, via the component object (`$this->account`).
## Auth facade
There is an `Auth` facade you may use for common tasks, it primarily inherits the `October\Rain\Auth\Manager` class for functionality.
You may use `Auth::register` to register an account:
$user = Auth::register([
'name' => 'Some User',
'email' => 'some@website.tld',
'password' => 'changeme',
'password_confirmation' => 'changeme',
]);
The second argument can specify if the account should be automatically activated:
// Auto activate this user
$user = Auth::register([...], true);
The `Auth::check` method is a quick way to check if the user is signed in.
// Returns true if signed in.
$loggedIn = Auth::check();
To return the user model that is signed in, use `Auth::getUser` instead.
// Returns the signed in user
$user = Auth::getUser();
You may authenticate a user by providing their login and password with `Auth::authenticate`.
// Authenticate user by credentials
$user = Auth::authenticate([
'login' => post('login'),
'password' => post('password')
]);
The second argument is used to store a non-expire cookie for the user.
$user = Auth::authenticate([...], true);
You can also authenticate as a user simply by passing the user model along with `Auth::login`.
// Sign in as a specific user
Auth::login($user);
The second argument is the same.
// Sign in and remember the user
Auth::login($user, true);
You may look up a user by their login name using the `Auth::findUserByLogin` method.
$user = Auth::findUserByLogin('some@email.tld');
## Guest users
Creating a guest user allows the registration process to be deferred. For example, making a purchase without needing to register first. Guest users are not able to sign in and will be added to the user group with the code `guest`.
Use the `Auth::registerGuest` method to create a guest user, it will return a user object and can be called multiple times. The unique identifier is the email address, which is a required field.
$user = Auth::registerGuest(['email' => 'person@acme.tld']);
When a user registers with the same email address using the `Auth::register` method, they will inherit the existing guest user account.
// This will not throw an "Email already taken" error
$user = Auth::register([
'email' => 'person@acme.tld',
'password' => 'changeme',
'password_confirmation' => 'changeme',
]);
> **Important**: If you are using guest accounts, it is important to disable sensitive functionality for user accounts that are not verified, since it may be possible for anyone to inherit a guest account.
You may also convert a guest to a registered user with the `convertToRegistered` method. This will generate a random password and sends an invitation using the `rainlab.user::mail.invite` template.
$user->convertToRegistered();
To disable the notification and password reset, pass the first argument as false.
$user->convertToRegistered(false);
## Events
This plugin will fire some global events that can be useful for interacting with other plugins.
- **rainlab.user.beforeRegister**: Before the user's registration is processed. Passed the `$data` variable by reference to enable direct modifications to the `$data` provided to the `Auth::register()` method.
- **rainlab.user.register**: The user has successfully registered. Passed the `$user` object and the submitted `$data` variable.
- **rainlab.user.beforeAuthenticate**: Before the user is attempting to authenticate using the Account component.
- **rainlab.user.login**: The user has successfully signed in.
- **rainlab.user.logout**: The user has successfully signed out.
- **rainlab.user.deactivate**: The user has opted-out of the site by deactivating their account. This should be used to disable any content the user may want removed.
- **rainlab.user.reactivate**: The user has reactivated their own account by signing back in. This should revive the users content on the site.
- **rainlab.user.getNotificationVars**: Fires when sending a user notification to enable passing more variables to the email templates. Passes the `$user` model the template will be for.
- **rainlab.user.view.extendListToolbar**: Fires when the user listing page's toolbar is rendered.
- **rainlab.user.view.extendPreviewToolbar**: Fires when the user preview page's toolbar is rendered.
Here is an example of hooking an event:
Event::listen('rainlab.user.deactivate', function($user) {
// Hide all posts by the user
});
A common requirement is to adapt another to a legacy authentication system. In the example below, the `WordPressLogin::check` method would check the user password using an alternative hashing method, and if successful, update to the new one used by October.
Event::listen('rainlab.user.beforeAuthenticate', function($component, $credentials) {
$login = array_get($credentials, 'login');
$password = array_get($credentials, 'password');
/*
* No such user exists
*/
if (!$user = Auth::findUserByLogin($login)) {
return;
}
/*
* The user is logging in with their old WordPress account
* for the first time. Rehash their password using the new
* October system.
*/
if (WordPressLogin::check($user->password, $password)) {
$user->password = $user->password_confirmation = $password;
$user->forceSave();
}
});

View File

@ -0,0 +1,31 @@
# Upgrade guide
- [Upgrading to 1.1 from 1.0](#upgrade-1.1)
- [Upgrading to 1.4 from 1.3](#upgrade-1.4)
<a name="upgrade-1.1"></a>
## Upgrading To 1.1
The User plugin has been split apart in to smaller more manageable plugins. These fields are no longer provided by the User plugin: `company`, `phone`, `street_addr`, `city`, `zip`, `country`, `state`. This is a non-destructive upgrade so the columns will remain in the database untouched.
Country and State models have been removed and can be replaced by installing the plugin **RainLab.Location**. The remaining profiles fields can be replaced by installing the plugin **RainLab.UserPlus**.
In short, to retain the old functionaliy simply install the following plugins:
- RainLab.Location
- RainLab.UserPlus
<a name="upgrade-1.4"></a>
## Upgrading To 1.4
The Notifications tab in User settings has been removed. This feature has been replaced by the [Notify plugin](https://octobercms.com/plugin/rainlab-notify). How to replace this feature:
1. Install the `RainLab.Notify` plugin
1. Navigate to Settings > Notification rules
1. Click **New notification** rule
1. Select User > **Activated**
1. Click **Add action**
1. Select **Compose a mail message**
1. Select **User email address** for the **Send to field**
1. Here you may select the **Mail template** previously defined in the user settings.
1. Click **Save**

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="65px" height="64px" viewBox="0 0 65 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="Group" sketch:type="MSLayerGroup" transform="translate(1.000000, 0.000000)">
<path fill="#FFB74D" d="M47.446 15.86c0 8.598-6.877 15.474-15.474 15.474-8.596 0-15.473-6.876-15.473-15.473C16.5 7.266 23.375.39 31.97.39c8.597 0 15.474 6.878 15.474 15.473"/>
<path fill="#607D8B" d="M62.918 53.855S54.322 36.49 31.973 36.49c-22.35 0-30.946 17.365-30.946 17.365V64h61.89V53.855z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 966 B

View File

@ -0,0 +1,100 @@
/*
* Bulk actions plugin
*
* Data attributes:
* - data-control="bulk-actions" - enables the plugin on an element
*
* JavaScript API:
* $('div').bulkActions()
*/
+function ($) { "use strict";
// BULK ACTIONS CLASS DEFINITION
// ============================
var BulkActions = function(element, options) {
this.options = options
this.$el = $(element)
// Init
this.init()
}
BulkActions.DEFAULTS = {}
BulkActions.prototype.init = function() {
this.activeAction = null
this.$primaryBtn = $('[data-primary-button]', this.$el)
this.$toggleBtn = $('.dropdown-toggle', this.$el)
this.$dropdownMenu = $('.dropdown-menu', this.$el)
this.baseCss = this.$primaryBtn.attr('class')
this.$primaryBtn.on('click', $.proxy(this.onClickPrimaryButton, this))
this.$dropdownMenu.on('click', 'li > a', $.proxy(this.onClickMenuItem, this))
this.setActiveItem($('li > a:first', this.$dropdownMenu))
}
BulkActions.prototype.onClickPrimaryButton = function() {
if (!this.activeAction) {
throw new Error('Bulk action not found')
}
this.$primaryBtn.data('request-data', {
checked: $('.control-list').listWidget('getChecked'),
action: this.activeAction
})
}
BulkActions.prototype.onClickMenuItem = function(ev) {
this.setActiveItem($(ev.target))
this.$primaryBtn.click()
}
BulkActions.prototype.setActiveItem = function($el) {
this.$toggleBtn.blur()
this.activeAction = $el.data('action')
this.$primaryBtn.text($el.text())
this.$primaryBtn.attr('class', this.baseCss)
this.$primaryBtn.addClass($el.attr('class'))
this.$primaryBtn.data('request-confirm', $el.data('confirm'))
}
// BULK ACTIONS PLUGIN DEFINITION
// ============================
var old = $.fn.bulkActions
$.fn.bulkActions = function (option) {
var args = Array.prototype.slice.call(arguments, 1), result
this.each(function () {
var $this = $(this)
var data = $this.data('oc.bulkactions')
var options = $.extend({}, BulkActions.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('oc.bulkactions', (data = new BulkActions(this, options)))
if (typeof option == 'string') result = data[option].apply(data, args)
if (typeof result != 'undefined') return false
})
return result ? result : this
}
$.fn.bulkActions.Constructor = BulkActions
// BULK ACTIONS NO CONFLICT
// =================
$.fn.bulkActions.noConflict = function () {
$.fn.bulkActions = old
return this
}
// BULK ACTIONS DATA-API
// ===============
$(document).render(function() {
$('[data-control="bulk-actions"]').bulkActions()
});
}(window.jQuery);

View File

@ -0,0 +1,129 @@
<?php namespace RainLab\User\Classes;
use October\Rain\Auth\Manager as RainAuthManager;
use RainLab\User\Models\Settings as UserSettings;
use RainLab\User\Models\UserGroup as UserGroupModel;
class AuthManager extends RainAuthManager
{
protected static $instance;
protected $sessionKey = 'user_auth';
protected $userModel = 'RainLab\User\Models\User';
protected $groupModel = 'RainLab\User\Models\UserGroup';
protected $throttleModel = 'RainLab\User\Models\Throttle';
public function init()
{
$this->useThrottle = UserSettings::get('use_throttle', $this->useThrottle);
$this->requireActivation = UserSettings::get('require_activation', $this->requireActivation);
parent::init();
}
/**
* {@inheritDoc}
*/
public function extendUserQuery($query)
{
$query->withTrashed();
}
/**
* {@inheritDoc}
*/
public function register(array $credentials, $activate = false, $autoLogin = true)
{
if ($guest = $this->findGuestUserByCredentials($credentials)) {
return $this->convertGuestToUser($guest, $credentials, $activate);
}
return parent::register($credentials, $activate, $autoLogin);
}
//
// Guest users
//
public function findGuestUserByCredentials(array $credentials)
{
if ($email = array_get($credentials, 'email')) {
return $this->findGuestUser($email);
}
return null;
}
public function findGuestUser($email)
{
$query = $this->createUserModelQuery();
return $user = $query
->where('email', $email)
->where('is_guest', 1)
->first();
}
/**
* Registers a guest user by giving the required credentials.
*
* @param array $credentials
* @return Models\User
*/
public function registerGuest(array $credentials)
{
$user = $this->findGuestUserByCredentials($credentials);
$newUser = false;
if (!$user) {
$user = $this->createUserModel();
$newUser = true;
}
$user->fill($credentials);
$user->is_guest = true;
$user->save();
// Add user to guest group
if ($newUser && $group = UserGroupModel::getGuestGroup()) {
$user->groups()->add($group);
}
// Prevents revalidation of the password field
// on subsequent saves to this model object
$user->password = null;
return $this->user = $user;
}
/**
* Converts a guest user to a registered user.
*
* @param Models\User $user
* @param array $credentials
* @param bool $activate
* @return Models\User
*/
public function convertGuestToUser($user, $credentials, $activate = false)
{
$user->fill($credentials);
$user->convertToRegistered(false);
// Remove user from guest group
if ($group = UserGroupModel::getGuestGroup()) {
$user->groups()->remove($group);
}
if ($activate) {
$user->attemptActivation($user->getActivationCode());
}
// Prevents revalidation of the password field
// on subsequent saves to this model object
$user->password = null;
return $this->user = $user;
}
}

View File

@ -0,0 +1,17 @@
<?php namespace RainLab\User\Classes;
use Auth;
use Closure;
use Response;
class AuthMiddleware
{
public function handle($request, Closure $next)
{
if (!Auth::check()) {
return Response::make('Forbidden', 403);
}
return $next($request);
}
}

View File

@ -0,0 +1,40 @@
<?php namespace RainLab\User\Classes;
use RainLab\Notify\Classes\EventBase;
class UserEventBase extends EventBase
{
/**
* @var array Local conditions supported by this event.
*/
public $conditions = [
\RainLab\User\NotifyRules\UserAttributeCondition::class
];
/**
* Defines the usable parameters provided by this class.
*/
public function defineParams()
{
return [
'name' => [
'title' => 'Name',
'label' => 'Name of the user',
],
'email' => [
'title' => 'Email',
'label' => "User's email address",
],
];
}
public static function makeParamsFromEvent(array $args, $eventName = null)
{
$user = array_get($args, 0);
$params = $user->getNotificationVars();
$params['user'] = $user;
return $params;
}
}

View File

@ -0,0 +1,41 @@
<?php namespace RainLab\User\Classes;
use App;
use Illuminate\Routing\Redirector;
class UserRedirector extends Redirector
{
/**
* Create a new redirect response, while putting the current URL in the session.
*
* @param string $path
* @param int $status
* @param array $headers
* @param bool $secure
* @return \Illuminate\Http\RedirectResponse
*/
public function guest($path, $status = 302, $headers = [], $secure = null)
{
$sessionKey = App::runningInBackend() ? 'url.intended' : 'url.frontend.intended';
$this->session->put($sessionKey, $this->generator->full());
return $this->to($path, $status, $headers, $secure);
}
/**
* Create a new redirect response to the previously intended location.
*
* @param string $default
* @param int $status
* @param array $headers
* @param bool $secure
* @return \Illuminate\Http\RedirectResponse
*/
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$sessionKey = App::runningInBackend() ? 'url.intended' : 'url.frontend.intended';
$path = $this->session->pull($sessionKey, $default);
return $this->to($path, $status, $headers, $secure);
}
}

View File

@ -0,0 +1,674 @@
<?php namespace RainLab\User\Components;
use Lang;
use Auth;
use Mail;
use Event;
use Flash;
use Input;
use Request;
use Redirect;
use Validator;
use ValidationException;
use ApplicationException;
use October\Rain\Auth\AuthException;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Models\Settings as UserSettings;
use Exception;
/**
* Account component
*
* Allows users to register, sign in and update their account. They can also
* deactivate their account and resend the account verification email.
*/
class Account extends ComponentBase
{
public function componentDetails()
{
return [
'name' => /*Account*/'rainlab.user::lang.account.account',
'description' => /*User management form.*/'rainlab.user::lang.account.account_desc'
];
}
public function defineProperties()
{
return [
'redirect' => [
'title' => /*Redirect to*/'rainlab.user::lang.account.redirect_to',
'description' => /*Page name to redirect to after update, sign in or registration.*/'rainlab.user::lang.account.redirect_to_desc',
'type' => 'dropdown',
'default' => ''
],
'paramCode' => [
'title' => /*Activation Code Param*/'rainlab.user::lang.account.code_param',
'description' => /*The page URL parameter used for the registration activation code*/ 'rainlab.user::lang.account.code_param_desc',
'type' => 'string',
'default' => 'code'
],
'activationPage' => [
'title' => /* Activation Page */'rainlab.user::lang.account.activation_page',
'description' => /* Select a page to use for activating the user account */'rainlab.user::lang.account.activation_page_comment',
'type' => 'dropdown',
'default' => ''
],
'forceSecure' => [
'title' => /*Force secure protocol*/'rainlab.user::lang.account.force_secure',
'description' => /*Always redirect the URL with the HTTPS schema.*/'rainlab.user::lang.account.force_secure_desc',
'type' => 'checkbox',
'default' => 0
],
'requirePassword' => [
'title' => /*Confirm password on update*/'rainlab.user::lang.account.update_requires_password',
'description' => /*Require the current password of the user when changing their profile.*/'rainlab.user::lang.account.update_requires_password_comment',
'type' => 'checkbox',
'default' => 0
],
];
}
/**
* getRedirectOptions
*/
public function getRedirectOptions()
{
return [
'' => '- refresh page -',
'0' => '- no redirect -'
] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
/**
* getActivationPageOptions
*/
public function getActivationPageOptions()
{
return [
'' => '- current page -',
] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
/**
* Executed when this component is initialized
*/
public function prepareVars()
{
$this->page['user'] = $this->user();
$this->page['canRegister'] = $this->canRegister();
$this->page['loginAttribute'] = $this->loginAttribute();
$this->page['loginAttributeLabel'] = $this->loginAttributeLabel();
$this->page['updateRequiresPassword'] = $this->updateRequiresPassword();
$this->page['rememberLoginMode'] = $this->rememberLoginMode();
}
/**
* Executed when this component is bound to a page or layout.
*/
public function onRun()
{
/*
* Redirect to HTTPS checker
*/
if ($redirect = $this->redirectForceSecure()) {
return $redirect;
}
/*
* Activation code supplied
*/
if ($code = $this->activationCode()) {
$this->onActivate($code);
}
$this->prepareVars();
}
//
// Properties
//
/**
* Returns the logged in user, if available
*/
public function user()
{
if (!Auth::check()) {
return null;
}
return Auth::getUser();
}
/**
* Flag for allowing registration, pulled from UserSettings
*/
public function canRegister()
{
return UserSettings::get('allow_registration', true);
}
/**
* Returns the login model attribute.
*/
public function loginAttribute()
{
return UserSettings::get('login_attribute', UserSettings::LOGIN_EMAIL);
}
/**
* Returns the login label as a word.
*/
public function loginAttributeLabel()
{
return Lang::get($this->loginAttribute() == UserSettings::LOGIN_EMAIL
? /*Email*/'rainlab.user::lang.login.attribute_email'
: /*Username*/'rainlab.user::lang.login.attribute_username'
);
}
/**
* Returns the update requires password setting
*/
public function updateRequiresPassword()
{
return $this->property('requirePassword', false);
}
/**
* Returns the login remember mode.
*/
public function rememberLoginMode()
{
return UserSettings::get('remember_login', UserSettings::REMEMBER_ALWAYS);
}
/**
* useRememberLogin returns true if persistent authentication should be used.
*/
protected function useRememberLogin(): bool
{
switch ($this->rememberLoginMode()) {
case UserSettings::REMEMBER_ALWAYS:
return true;
case UserSettings::REMEMBER_NEVER:
return false;
case UserSettings::REMEMBER_ASK:
return (bool) post('remember', false);
}
}
/**
* Looks for the activation code from the URL parameter. If nothing
* is found, the GET parameter 'activate' is used instead.
* @return string
*/
public function activationCode()
{
$routeParameter = $this->property('paramCode');
if ($code = $this->param($routeParameter)) {
return $code;
}
return get('activate');
}
//
// AJAX
//
/**
* Sign in the user
*/
public function onSignin()
{
try {
/*
* Validate input
*/
$data = post();
$rules = [];
$rules['login'] = $this->loginAttribute() == UserSettings::LOGIN_USERNAME
? 'required|between:2,255'
: 'required|email|between:6,255';
$rules['password'] = 'required|between:4,255';
if (!array_key_exists('login', $data)) {
$data['login'] = post('username', post('email'));
}
$data['login'] = trim($data['login']);
$validation = Validator::make(
$data,
$rules,
$this->getValidatorMessages(),
$this->getCustomAttributes()
);
if ($validation->fails()) {
throw new ValidationException($validation);
}
/*
* Authenticate user
*/
$credentials = [
'login' => array_get($data, 'login'),
'password' => array_get($data, 'password')
];
Event::fire('rainlab.user.beforeAuthenticate', [$this, $credentials]);
$user = Auth::authenticate($credentials, $this->useRememberLogin());
if ($user->isBanned()) {
Auth::logout();
throw new AuthException(/*Sorry, this user is currently not activated. Please contact us for further assistance.*/'rainlab.user::lang.account.banned');
}
/*
* Record IP address
*/
if ($ipAddress = Request::ip()) {
$user->touchIpAddress($ipAddress);
}
/*
* Redirect
*/
if ($redirect = $this->makeRedirection(true)) {
return $redirect;
}
}
catch (Exception $ex) {
if (Request::ajax()) throw $ex;
else Flash::error($ex->getMessage());
}
}
/**
* Register the user
*/
public function onRegister()
{
try {
if (!$this->canRegister()) {
throw new ApplicationException(Lang::get(/*Registrations are currently disabled.*/'rainlab.user::lang.account.registration_disabled'));
}
if ($this->isRegisterThrottled()) {
throw new ApplicationException(Lang::get(/*Registration is throttled. Please try again later.*/'rainlab.user::lang.account.registration_throttled'));
}
/*
* Validate input
*/
$data = post();
if (!array_key_exists('password_confirmation', $data)) {
$data['password_confirmation'] = post('password');
}
$rules = (new UserModel)->rules;
if ($this->loginAttribute() !== UserSettings::LOGIN_USERNAME) {
unset($rules['username']);
}
$validation = Validator::make(
$data,
$rules,
$this->getValidatorMessages(),
$this->getCustomAttributes()
);
if ($validation->fails()) {
throw new ValidationException($validation);
}
/*
* Record IP address
*/
if ($ipAddress = Request::ip()) {
$data['created_ip_address'] = $data['last_ip_address'] = $ipAddress;
}
/*
* Register user
*/
Event::fire('rainlab.user.beforeRegister', [&$data]);
$requireActivation = UserSettings::get('require_activation', true);
$automaticActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_AUTO;
$userActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_USER;
$adminActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_ADMIN;
$user = Auth::register($data, $automaticActivation);
Event::fire('rainlab.user.register', [$user, $data]);
/*
* Activation is by the user, send the email
*/
if ($userActivation) {
$this->sendActivationEmail($user);
Flash::success(Lang::get(/*An activation email has been sent to your email address.*/'rainlab.user::lang.account.activation_email_sent'));
}
$intended = false;
/*
* Activation is by the admin, show message
* For automatic email on account activation RainLab.Notify plugin is needed
*/
if ($adminActivation) {
Flash::success(Lang::get(/*You have successfully registered. Your account is not yet active and must be approved by an administrator.*/'rainlab.user::lang.account.activation_by_admin'));
}
/*
* Automatically activated or not required, log the user in
*/
if ($automaticActivation || !$requireActivation) {
Auth::login($user, $this->useRememberLogin());
$intended = true;
}
/*
* Redirect to the intended page after successful sign in
*/
if ($redirect = $this->makeRedirection($intended)) {
return $redirect;
}
}
catch (Exception $ex) {
if (Request::ajax()) throw $ex;
else Flash::error($ex->getMessage());
}
}
/**
* Activate the user
* @param string $code Activation code
*/
public function onActivate($code = null)
{
try {
$code = post('code', $code);
$errorFields = ['code' => Lang::get(/*Invalid activation code supplied.*/'rainlab.user::lang.account.invalid_activation_code')];
/*
* Break up the code parts
*/
$parts = explode('!', $code);
if (count($parts) != 2) {
throw new ValidationException($errorFields);
}
list($userId, $code) = $parts;
if (!strlen(trim($userId)) || !strlen(trim($code))) {
throw new ValidationException($errorFields);
}
if (!$user = Auth::findUserById($userId)) {
throw new ValidationException($errorFields);
}
if (!$user->attemptActivation($code)) {
throw new ValidationException($errorFields);
}
Flash::success(Lang::get(/*Successfully activated your account.*/'rainlab.user::lang.account.success_activation'));
/*
* Sign in the user
*/
Auth::login($user, $this->useRememberLogin());
}
catch (Exception $ex) {
if (Request::ajax()) throw $ex;
else Flash::error($ex->getMessage());
}
}
/**
* Update the user
*/
public function onUpdate()
{
if (!$user = $this->user()) {
return;
}
$data = post();
if ($this->updateRequiresPassword()) {
if (!$user->checkHashValue('password', $data['password_current'])) {
throw new ValidationException(['password_current' => Lang::get('rainlab.user::lang.account.invalid_current_pass')]);
}
}
if (Input::hasFile('avatar')) {
$user->avatar = Input::file('avatar');
}
$user->fill($data);
$user->save();
/*
* Password has changed, reauthenticate the user
*/
if (array_key_exists('password', $data) && strlen($data['password'])) {
Auth::login($user->reload(), true);
}
Flash::success(post('flash', Lang::get(/*Settings successfully saved!*/'rainlab.user::lang.account.success_saved')));
/*
* Redirect
*/
if ($redirect = $this->makeRedirection()) {
return $redirect;
}
$this->prepareVars();
}
/**
* Deactivate user
*/
public function onDeactivate()
{
if (!$user = $this->user()) {
return;
}
if (!$user->checkHashValue('password', post('password'))) {
throw new ValidationException(['password' => Lang::get('rainlab.user::lang.account.invalid_deactivation_pass')]);
}
Auth::logout();
$user->delete();
Flash::success(post('flash', Lang::get(/*Successfully deactivated your account. Sorry to see you go!*/'rainlab.user::lang.account.success_deactivation')));
/*
* Redirect
*/
if ($redirect = $this->makeRedirection()) {
return $redirect;
}
}
/**
* Trigger a subsequent activation email
*/
public function onSendActivationEmail()
{
try {
if (!$user = $this->user()) {
throw new ApplicationException(Lang::get(/*You must be logged in first!*/'rainlab.user::lang.account.login_first'));
}
if ($user->is_activated) {
throw new ApplicationException(Lang::get(/*Your account is already activated!*/'rainlab.user::lang.account.already_active'));
}
Flash::success(Lang::get(/*An activation email has been sent to your email address.*/'rainlab.user::lang.account.activation_email_sent'));
$this->sendActivationEmail($user);
}
catch (Exception $ex) {
if (Request::ajax()) throw $ex;
else Flash::error($ex->getMessage());
}
/*
* Redirect
*/
if ($redirect = $this->makeRedirection()) {
return $redirect;
}
}
//
// Helpers
//
/**
* Returns a link used to activate the user account.
* @return string
*/
protected function makeActivationUrl($code)
{
$params = [
$this->property('paramCode') => $code
];
if ($pageName = $this->property('activationPage')) {
$url = $this->pageUrl($pageName, $params);
}
else {
$url = $this->currentPageUrl($params);
}
if (strpos($url, $code) === false) {
$url .= '?activate=' . $code;
}
return $url;
}
/**
* Sends the activation email to a user
* @param User $user
* @return void
*/
protected function sendActivationEmail($user)
{
$code = implode('!', [$user->id, $user->getActivationCode()]);
$link = $this->makeActivationUrl($code);
$data = [
'name' => $user->name,
'link' => $link,
'code' => $code
];
Mail::send('rainlab.user::mail.activate', $data, function($message) use ($user) {
$message->to($user->email, $user->name);
});
}
/**
* Redirect to the intended page after successful update, sign in or registration.
* The URL can come from the "redirect" property or the "redirect" postback value.
* @return mixed
*/
protected function makeRedirection($intended = false)
{
$method = $intended ? 'intended' : 'to';
$property = post('redirect', $this->property('redirect'));
// No redirect
if ($property === '0') {
return;
}
// Refresh page
if ($property === '') {
return Redirect::refresh();
}
$redirectUrl = $this->pageUrl($property) ?: $property;
if ($redirectUrl) {
return Redirect::$method($redirectUrl);
}
}
/**
* Checks if the force secure property is enabled and if so
* returns a redirect object.
* @return mixed
*/
protected function redirectForceSecure()
{
if (
Request::secure() ||
Request::ajax() ||
!$this->property('forceSecure')
) {
return;
}
return Redirect::secure(Request::path());
}
/**
* Returns true if user is throttled.
* @return bool
*/
protected function isRegisterThrottled()
{
if (!UserSettings::get('use_register_throttle', false)) {
return false;
}
return UserModel::isRegisterThrottled(Request::ip());
}
/**
* getValidatorMessages
*/
protected function getValidatorMessages(): array
{
return (array) (new UserModel)->customMessages;
}
/**
* getCustomAttributes
*/
protected function getCustomAttributes(): array
{
return [
'login' => $this->loginAttributeLabel(),
'password' => Lang::get('rainlab.user::lang.account.password'),
'email' => Lang::get('rainlab.user::lang.account.email'),
'username' => Lang::get('rainlab.user::lang.user.username'),
'name' => Lang::get('rainlab.user::lang.account.full_name')
];
}
}

View File

@ -0,0 +1,187 @@
<?php namespace RainLab\User\Components;
use Auth;
use Lang;
use Mail;
use Validator;
use ValidationException;
use ApplicationException;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\User as UserModel;
/**
* ResetPassword controls the password reset workflow
*
* When a user has forgotten their password, they are able to reset it using
* a unique token that, sent to their email address upon request.
*/
class ResetPassword extends ComponentBase
{
public function componentDetails()
{
return [
'name' => /*Reset Password*/'rainlab.user::lang.reset_password.reset_password',
'description' => /*Forgotten password form.*/'rainlab.user::lang.reset_password.reset_password_desc'
];
}
public function defineProperties()
{
return [
'paramCode' => [
'title' => /*Reset Code Param*/'rainlab.user::lang.reset_password.code_param',
'description' => /*The page URL parameter used for the reset code*/'rainlab.user::lang.reset_password.code_param_desc',
'type' => 'string',
'default' => 'code'
],
'resetPage' => [
'title' => /* Reset Page */'rainlab.user::lang.account.reset_page',
'description' => /* Select a page to use for resetting the account password */'rainlab.user::lang.account.reset_page_comment',
'type' => 'dropdown',
'default' => ''
],
];
}
/**
* getResetPageOptions
*/
public function getResetPageOptions()
{
return [
'' => '- current page -',
] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
//
// Properties
//
/**
* Returns the reset password code from the URL
* @return string
*/
public function code()
{
$routeParameter = $this->property('paramCode');
if ($code = $this->param($routeParameter)) {
return $code;
}
return get('reset');
}
//
// AJAX
//
/**
* Trigger the password reset email
*/
public function onRestorePassword()
{
$rules = [
'email' => 'required|email|between:6,255'
];
$validation = Validator::make(post(), $rules);
if ($validation->fails()) {
throw new ValidationException($validation);
}
$user = UserModel::findByEmail(post('email'));
if (!$user || $user->is_guest) {
throw new ApplicationException(Lang::get(/*A user was not found with the given credentials.*/'rainlab.user::lang.account.invalid_user'));
}
$code = implode('!', [$user->id, $user->getResetPasswordCode()]);
$link = $this->makeResetUrl($code);
$data = [
'name' => $user->name,
'username' => $user->username,
'link' => $link,
'code' => $code
];
Mail::send('rainlab.user::mail.restore', $data, function($message) use ($user) {
$message->to($user->email, $user->full_name);
});
}
/**
* Perform the password reset
*/
public function onResetPassword()
{
$rules = [
'code' => 'required',
'password' => 'required|between:' . UserModel::getMinPasswordLength() . ',255'
];
$validation = Validator::make(post(), $rules);
if ($validation->fails()) {
throw new ValidationException($validation);
}
$errorFields = ['code' => Lang::get(/*Invalid activation code supplied.*/'rainlab.user::lang.account.invalid_activation_code')];
/*
* Break up the code parts
*/
$parts = explode('!', post('code'));
if (count($parts) != 2) {
throw new ValidationException($errorFields);
}
list($userId, $code) = $parts;
if (!strlen(trim($userId)) || !strlen(trim($code)) || !$code) {
throw new ValidationException($errorFields);
}
if (!$user = Auth::findUserById($userId)) {
throw new ValidationException($errorFields);
}
if (!$user->attemptResetPassword($code, post('password'))) {
throw new ValidationException($errorFields);
}
// Check needed for compatibility with legacy systems
if (method_exists(\RainLab\User\Classes\AuthManager::class, 'clearThrottleForUserId')) {
Auth::clearThrottleForUserId($user->id);
}
}
//
// Helpers
//
/**
* Returns a link used to reset the user account.
* @return string
*/
protected function makeResetUrl($code)
{
$params = [
$this->property('paramCode') => $code
];
if ($pageName = $this->property('resetPage')) {
$url = $this->pageUrl($pageName, $params);
}
else {
$url = $this->currentPageUrl($params);
}
if (strpos($url, $code) === false) {
$url .= '?reset=' . $code;
}
return $url;
}
}

View File

@ -0,0 +1,225 @@
<?php namespace RainLab\User\Components;
use Lang;
use Auth;
use Event;
use Flash;
use Request;
use Redirect;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\UserGroup;
use SystemException;
/**
* Session component
*
* This will inject the user object to every page and provide the ability for
* the user to sign out. This can also be used to restrict access to pages.
*/
class Session extends ComponentBase
{
const ALLOW_ALL = 'all';
const ALLOW_GUEST = 'guest';
const ALLOW_USER = 'user';
public function componentDetails()
{
return [
'name' => 'rainlab.user::lang.session.session',
'description' => 'rainlab.user::lang.session.session_desc'
];
}
public function defineProperties()
{
return [
'security' => [
'title' => 'rainlab.user::lang.session.security_title',
'description' => 'rainlab.user::lang.session.security_desc',
'type' => 'dropdown',
'default' => 'all',
'options' => [
'all' => 'rainlab.user::lang.session.all',
'user' => 'rainlab.user::lang.session.users',
'guest' => 'rainlab.user::lang.session.guests'
]
],
'allowedUserGroups' => [
'title' => 'rainlab.user::lang.session.allowed_groups_title',
'description' => 'rainlab.user::lang.session.allowed_groups_description',
'placeholder' => '*',
'type' => 'set',
'default' => []
],
'redirect' => [
'title' => 'rainlab.user::lang.session.redirect_title',
'description' => 'rainlab.user::lang.session.redirect_desc',
'type' => 'dropdown',
'default' => ''
]
];
}
/**
* getRedirectOptions
*/
public function getRedirectOptions()
{
return [''=>'- none -'] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
/**
* getAllowedUserGroupsOptions
*/
public function getAllowedUserGroupsOptions()
{
return UserGroup::lists('name','code');
}
/**
* Component is initialized.
*/
public function init()
{
// Inject security logic pre-AJAX
$this->controller->bindEvent('page.init', function() {
if (Request::ajax() && ($redirect = $this->checkUserSecurityRedirect())) {
return ['X_OCTOBER_REDIRECT' => $redirect->getTargetUrl()];
}
});
}
/**
* Executed when this component is bound to a page or layout.
*/
public function onRun()
{
if ($redirect = $this->checkUserSecurityRedirect()) {
return $redirect;
}
$this->page['user'] = $this->user();
}
/**
* Returns the logged in user, if available, and touches
* the last seen timestamp.
* @return RainLab\User\Models\User
*/
public function user()
{
if (!$user = Auth::getUser()) {
return null;
}
if (!Auth::isImpersonator()) {
$user->touchLastSeen();
}
return $user;
}
/**
* Returns the previously signed in user when impersonating.
*/
public function impersonator()
{
return Auth::getImpersonator();
}
/**
* Log out the user
*
* Usage:
* <a data-request="onLogout">Sign out</a>
*
* With the optional redirect parameter:
* <a data-request="onLogout" data-request-data="redirect: '/good-bye'">Sign out</a>
*
*/
public function onLogout()
{
$user = Auth::getUser();
Auth::logout();
if ($user) {
Event::fire('rainlab.user.logout', [$user]);
}
$url = post('redirect', Request::fullUrl());
Flash::success(Lang::get('rainlab.user::lang.session.logout'));
return Redirect::to($url);
}
/**
* If impersonating, revert back to the previously signed in user.
* @return Redirect
*/
public function onStopImpersonating()
{
if (!Auth::isImpersonator()) {
return $this->onLogout();
}
Auth::stopImpersonate();
$url = post('redirect', Request::fullUrl());
Flash::success(Lang::get('rainlab.user::lang.session.stop_impersonate_success'));
return Redirect::to($url);
}
/**
* checkUserSecurityRedirect will return a redirect if the user cannot access the page.
*/
protected function checkUserSecurityRedirect()
{
// No security layer enabled
if ($this->checkUserSecurity()) {
return;
}
if (!$this->property('redirect')) {
throw new SystemException('Redirect property is empty on Session component.');
}
$redirectUrl = $this->controller->pageUrl($this->property('redirect'));
return Redirect::guest($redirectUrl);
}
/**
* checkUserSecurity checks if the user can access this page based on the security rules.
*/
protected function checkUserSecurity(): bool
{
$allowedGroup = $this->property('security', self::ALLOW_ALL);
$allowedUserGroups = (array) $this->property('allowedUserGroups', []);
$isAuthenticated = Auth::check();
if ($isAuthenticated) {
if ($allowedGroup == self::ALLOW_GUEST) {
return false;
}
if (!empty($allowedUserGroups)) {
$userGroups = Auth::getUser()->groups->lists('code');
if (!count(array_intersect($allowedUserGroups, $userGroups))) {
return false;
}
}
}
else {
if ($allowedGroup == self::ALLOW_USER) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,9 @@
{% if not user.is_activated %}
<h3>Your email address has not yet been verified.</h3>
<p>
You should verify your account otherwise it may be deleted. Please check your email to verify.
<a href="javascript:;" data-request="onSendActivationEmail">Send the verification email again</a>.
</p>
{% endif %}

View File

@ -0,0 +1,28 @@
<a
href="javascript:;"
onclick="$('#accountDeactivateForm').toggle()">
Deactivate account
</a>
<div id="accountDeactivateForm" style="display: none">
{{ form_ajax('onDeactivate') }}
<hr />
<h3>Deactivate your account?</h3>
<p>
Your account will be disabled and your details removed from the site.
You can reactivate your account any time by signing back in.
</p>
<div class="form-group">
<label for="accountDeletePassword">To continue, please enter your password:</label>
<input name="password" type="password" class="form-control" id="accountDeletePassword" />
</div>
<button type="submit" class="btn btn-danger">
Confirm Deactivate Account
</button>
<a
href="javascript:;"
onclick="$('#accountDeactivateForm').toggle()">
I changed my mind
</a>
{{ form_close() }}
</div>

View File

@ -0,0 +1,24 @@
{% if not user %}
<div class="row">
<div class="col-md-6">
<h3>Sign in</h3>
{% partial __SELF__ ~ '::signin' %}
</div>
<div class="col-md-6">
{% partial __SELF__ ~ '::register' %}
</div>
</div>
{% else %}
{% partial __SELF__ ~ '::activation_check' %}
{% partial __SELF__ ~ '::update' %}
{% partial __SELF__ ~ '::deactivate_link' %}
{% endif %}

View File

@ -0,0 +1,53 @@
{% if canRegister %}
<h3>Register</h3>
{{ form_ajax('onRegister') }}
<div class="form-group">
<label for="registerName">Full Name</label>
<input
name="name"
type="text"
class="form-control"
id="registerName"
placeholder="Enter your full name" />
</div>
<div class="form-group">
<label for="registerEmail">Email</label>
<input
name="email"
type="email"
class="form-control"
id="registerEmail"
placeholder="Enter your email" />
</div>
{% if loginAttribute == "username" %}
<div class="form-group">
<label for="registerUsername">Username</label>
<input
name="username"
type="text"
class="form-control"
id="registerUsername"
placeholder="Enter your username" />
</div>
{% endif %}
<div class="form-group">
<label for="registerPassword">Password</label>
<input
name="password"
type="password"
class="form-control"
id="registerPassword"
placeholder="Choose a password" />
</div>
<button type="submit" class="btn btn-default">Register</button>
{{ form_close() }}
{% else %}
<!-- Registration is disabled. -->
{% endif %}

View File

@ -0,0 +1,33 @@
{{ form_ajax('onSignin') }}
<div class="form-group">
<label for="userSigninLogin">{{ loginAttributeLabel }}</label>
<input
name="login"
type="text"
class="form-control"
id="userSigninLogin"
placeholder="Enter your {{ loginAttributeLabel|lower }}" />
</div>
<div class="form-group">
<label for="userSigninPassword">Password</label>
<input
name="password"
type="password"
class="form-control"
id="userSigninPassword"
placeholder="Enter your password" />
</div>
{% if rememberLoginMode == 'ask' %}
<div class="form-group">
<div class="checkbox">
<label><input name="remember" type="checkbox" value="1">Stay logged in</label>
</div>
</div>
{% endif %}
<button type="submit" class="btn btn-default">Sign in</button>
{{ form_close() }}

View File

@ -0,0 +1,33 @@
{{ form_ajax('onUpdate') }}
<div class="form-group">
<label for="accountName">Full Name</label>
<input name="name" type="text" class="form-control" id="accountName" value="{{ user.name }}">
</div>
<div class="form-group">
<label for="accountEmail">Email</label>
<input name="email" type="email" class="form-control" id="accountEmail" value="{{ user.email }}">
</div>
<div class="form-group">
<label for="accountPassword">New Password</label>
<input name="password" type="password" class="form-control" id="accountPassword">
</div>
<div class="form-group">
<label for="accountPasswordConfirm">Confirm New Password</label>
<input name="password_confirmation" type="password" class="form-control" id="accountPasswordConfirm">
</div>
{% if updateRequiresPassword %}
<p>To change these details, please confirm your current password.</p>
<div class="form-group">
<label for="accountPasswordCurrent">Current Password <small class="text-danger">* required</small></label>
<input name="password_current" type="password" class="form-control" id="accountPasswordCurrent">
</div>
{% endif %}
<button type="submit" class="btn btn-default">Save</button>
{{ form_close() }}

View File

@ -0,0 +1 @@
<p>Password reset complete, you may now sign in.</p>

View File

@ -0,0 +1,7 @@
<div id="partialUserResetForm">
{% if __SELF__.code == null %}
{% partial __SELF__ ~ '::restore' %}
{% else %}
{% partial __SELF__ ~ '::reset' %}
{% endif %}
</div>

View File

@ -0,0 +1,19 @@
<p class="lead">
Please check your email for the activation code.
</p>
<form
data-request="{{ __SELF__ }}::onResetPassword"
data-request-update="'{{ __SELF__ }}::complete': '#partialUserResetForm'">
<div class="form-group">
<label for="resetCode">Activation Code</label>
<input name="code" type="text" class="form-control" id="resetCode" placeholder="Enter the activation code" value="{{ __SELF__.code }}">
</div>
<div class="form-group">
<label for="resetPassword">New Password</label>
<input name="password" type="password" class="form-control" id="resetPassword" placeholder="Enter a new password">
</div>
<button type="submit" class="btn btn-default">Reset password</button>
</form>

View File

@ -0,0 +1,14 @@
<p class="lead">
<strong>Lost your password?</strong> No problem! Enter your email address to verify your account.
</p>
<form
data-request="{{ __SELF__ }}::onRestorePassword"
data-request-update="'{{ __SELF__ }}::reset': '#partialUserResetForm'">
<div class="form-group">
<label for="userRestoreEmail">Email</label>
<input name="email" type="email" class="form-control" id="userRestoreEmail" placeholder="Enter your email">
</div>
<button type="submit" class="btn btn-default">Restore password</button>
</form>

View File

@ -0,0 +1,25 @@
{
"name": "rainlab/user-plugin",
"type": "october-plugin",
"description": "User plugin for October CMS",
"homepage": "https://octobercms.com/plugin/rainlab-user",
"keywords": ["october", "octobercms", "user"],
"license": "MIT",
"authors": [
{
"name": "Alexey Bobkov",
"email": "aleksey.bobkov@gmail.com",
"role": "Co-founder"
},
{
"name": "Samuel Georges",
"email": "daftspunky@gmail.com",
"role": "Co-founder"
}
],
"require": {
"php": ">=5.5.9",
"composer/installers": "~1.0"
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,116 @@
<?php
use RainLab\User\Models\Settings;
return [
/*
|--------------------------------------------------------------------------
| Activation mode
|--------------------------------------------------------------------------
|
| Select how a user account should be activated.
|
| ACTIVATE_ADMIN Administrators must activate users manually.
| ACTIVATE_AUTO Users are activated automatically upon registration.
| ACTIVATE_USER The user activates their own account using a link sent to them via email.
|
*/
'activateMode' => Settings::ACTIVATE_AUTO,
/*
|--------------------------------------------------------------------------
| Allow user registration
|--------------------------------------------------------------------------
|
| If this is disabled users can only be created by administrators.
|
*/
'allowRegistration' => true,
/*
|--------------------------------------------------------------------------
| Prevent concurrent sessions
|--------------------------------------------------------------------------
|
| When enabled users cannot sign in to multiple devices at the same time.
|
*/
'blockPersistence' => false,
/*
|--------------------------------------------------------------------------
| Login attribute
|--------------------------------------------------------------------------
|
| Select what primary user detail should be used for signing in.
|
| LOGIN_EMAIL Authenticate users by email.
| LOGIN_USERNAME Authenticate users by username.
|
*/
'loginAttribute' => Settings::LOGIN_EMAIL,
/*
|--------------------------------------------------------------------------
| Minimum Password Length
|--------------------------------------------------------------------------
|
| The minimum length of characters required for user passwords.
|
*/
'minPasswordLength' => 8,
/*
|--------------------------------------------------------------------------
| Remember login mode
|--------------------------------------------------------------------------
|
| Select if the user session should be persistent.
|
| REMEMBER_ALWAYS Always persist user session.
| REMEMBER_ASK Ask if session should be persistent.
| REMEMBER_NEVER Never persist user session.
|
*/
'rememberLogin' => Settings::REMEMBER_ALWAYS,
/*
|--------------------------------------------------------------------------
| Sign in requires activation
|--------------------------------------------------------------------------
|
| Users must have an activated account to sign in.
|
*/
'requireActivation' => true,
/*
|--------------------------------------------------------------------------
| Throttle registration
|--------------------------------------------------------------------------
|
| Prevent multiple registrations from the same IP in short succession.
|
*/
'useRegisterThrottle' => true,
/*
|--------------------------------------------------------------------------
| Throttle attempts
|--------------------------------------------------------------------------
|
| Repeat failed sign in attempts will temporarily suspend the user.
|
*/
'useThrottle' => true,
];

View File

@ -0,0 +1,50 @@
<?php namespace RainLab\User\Controllers;
use Flash;
use BackendMenu;
use Backend\Classes\Controller;
use RainLab\User\Models\UserGroup;
/**
* User Groups Back-end Controller
*/
class UserGroups extends Controller
{
/**
* @var array Extensions implemented by this controller.
*/
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class
];
/**
* @var array `FormController` configuration.
*/
public $formConfig = 'config_form.yaml';
/**
* @var array `ListController` configuration.
*/
public $listConfig = 'config_list.yaml';
/**
* @var array `RelationController` configuration, by extension.
*/
public $relationConfig;
/**
* @var array Permissions required to view this page.
*/
public $requiredPermissions = ['rainlab.users.access_groups'];
/**
* Constructor.
*/
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RainLab.User', 'user', 'usergroups');
}
}

View File

@ -0,0 +1,308 @@
<?php namespace RainLab\User\Controllers;
use Auth;
use Lang;
use Flash;
use Response;
use Redirect;
use BackendMenu;
use BackendAuth;
use Backend\Classes\Controller;
use System\Classes\SettingsManager;
use RainLab\User\Models\User;
use RainLab\User\Models\UserGroup;
use RainLab\User\Models\MailBlocker;
use RainLab\User\Models\Settings as UserSettings;
class Users extends Controller
{
/**
* @var array Extensions implemented by this controller.
*/
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class
];
/**
* @var array `FormController` configuration.
*/
public $formConfig = 'config_form.yaml';
/**
* @var array `ListController` configuration.
*/
public $listConfig = 'config_list.yaml';
/**
* @var array `RelationController` configuration, by extension.
*/
public $relationConfig;
/**
* @var array Permissions required to view this page.
*/
public $requiredPermissions = ['rainlab.users.access_users'];
/**
* @var string HTML body tag class
*/
public $bodyClass = 'compact-container';
/**
* Constructor.
*/
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RainLab.User', 'user', 'users');
SettingsManager::setContext('RainLab.User', 'settings');
}
public function index()
{
$this->addJs('/plugins/rainlab/user/assets/js/bulk-actions.js');
$this->asExtension('ListController')->index();
}
/**
* {@inheritDoc}
*/
public function listInjectRowClass($record, $definition = null)
{
$classes = [];
if ($record->trashed()) {
$classes[] = 'strike';
}
if ($record->isBanned()) {
$classes[] = 'negative';
}
if (!$record->is_activated) {
$classes[] = 'disabled';
}
if (count($classes) > 0) {
return join(' ', $classes);
}
}
public function listExtendQuery($query)
{
$query->withTrashed();
}
public function formExtendQuery($query)
{
$query->withTrashed();
}
/**
* Display username field if settings permit
*/
public function formExtendFields($form)
{
/*
* Show the username field if it is configured for use
*/
if (
UserSettings::get('login_attribute') == UserSettings::LOGIN_USERNAME &&
array_key_exists('username', $form->getFields())
) {
$form->getField('username')->hidden = false;
}
}
public function formAfterUpdate($model)
{
$blockMail = post('User[block_mail]', false);
if ($blockMail !== false) {
$blockMail ? MailBlocker::blockAll($model) : MailBlocker::unblockAll($model);
}
}
public function formExtendModel($model)
{
$model->block_mail = MailBlocker::isBlockAll($model);
$model->bindEvent('model.saveInternal', function() use ($model) {
unset($model->attributes['block_mail']);
});
}
/**
* Manually activate a user
*/
public function preview_onActivate($recordId = null)
{
$model = $this->formFindModelObject($recordId);
$model->attemptActivation($model->activation_code);
Flash::success(Lang::get('rainlab.user::lang.users.activated_success'));
if ($redirect = $this->makeRedirect('update-close', $model)) {
return $redirect;
}
}
/**
* Manually unban a user
*/
public function preview_onUnban($recordId = null)
{
$model = $this->formFindModelObject($recordId);
$model->unban();
Flash::success(Lang::get('rainlab.user::lang.users.unbanned_success'));
if ($redirect = $this->makeRedirect('update-close', $model)) {
return $redirect;
}
}
/**
* Display the convert to registered user popup
*/
public function preview_onLoadConvertGuestForm($recordId)
{
$this->vars['groups'] = UserGroup::where('code', '!=', UserGroup::GROUP_GUEST)->get();
return $this->makePartial('convert_guest_form');
}
/**
* Manually convert a guest user to a registered one
*/
public function preview_onConvertGuest($recordId)
{
$model = $this->formFindModelObject($recordId);
// Convert user and send notification
$model->convertToRegistered(post('send_registration_notification', false));
// Remove user from guest group
if ($group = UserGroup::getGuestGroup()) {
$model->groups()->remove($group);
}
// Add user to new group
if (
($groupId = post('new_group')) &&
($group = UserGroup::find($groupId))
) {
$model->groups()->add($group);
}
Flash::success(Lang::get('rainlab.user::lang.users.convert_guest_success'));
if ($redirect = $this->makeRedirect('update-close', $model)) {
return $redirect;
}
}
/**
* Impersonate this user
*/
public function preview_onImpersonateUser($recordId)
{
if (!$this->user->hasAccess('rainlab.users.impersonate_user')) {
return Response::make(Lang::get('backend::lang.page.access_denied.label'), 403);
}
$model = $this->formFindModelObject($recordId);
Auth::impersonate($model);
Flash::success(Lang::get('rainlab.user::lang.users.impersonate_success'));
}
/**
* Unsuspend this user
*/
public function preview_onUnsuspendUser($recordId)
{
$model = $this->formFindModelObject($recordId);
$model->unsuspend();
Flash::success(Lang::get('rainlab.user::lang.users.unsuspend_success'));
return Redirect::refresh();
}
/**
* Force delete a user.
*/
public function update_onDelete($recordId = null)
{
$model = $this->formFindModelObject($recordId);
$model->forceDelete();
Flash::success(Lang::get('backend::lang.form.delete_success'));
if ($redirect = $this->makeRedirect('delete', $model)) {
return $redirect;
}
}
/**
* Perform bulk action on selected users
*/
public function index_onBulkAction()
{
if (
($bulkAction = post('action')) &&
($checkedIds = post('checked')) &&
is_array($checkedIds) &&
count($checkedIds)
) {
foreach ($checkedIds as $userId) {
if (!$user = User::withTrashed()->find($userId)) {
continue;
}
switch ($bulkAction) {
case 'delete':
$user->forceDelete();
break;
case 'activate':
$user->attemptActivation($user->activation_code);
break;
case 'deactivate':
$user->clearPersistCode();
$user->delete();
break;
case 'restore':
$user->restore();
break;
case 'ban':
$user->ban();
break;
case 'unban':
$user->unban();
break;
}
}
Flash::success(Lang::get('rainlab.user::lang.users.'.$bulkAction.'_selected_success'));
}
else {
Flash::error(Lang::get('rainlab.user::lang.users.'.$bulkAction.'_selected_empty'));
}
return $this->listRefresh();
}
}

View File

@ -0,0 +1,7 @@
<div data-control="toolbar">
<a
href="<?= Backend::url('rainlab/user/usergroups/create') ?>"
class="btn btn-primary oc-icon-plus">
<?= e(trans('rainlab.user::lang.groups.new_group')) ?>
</a>
</div>

View File

@ -0,0 +1,31 @@
# ===================================
# Form Behavior Config
# ===================================
# Record name
name: rainlab.user::lang.group.label
# Model Form Field configuration
form: $/rainlab/user/models/usergroup/fields.yaml
# Model Class name
modelClass: RainLab\User\Models\UserGroup
# Default redirect location
defaultRedirect: rainlab/user/usergroups
# Create page
create:
title: rainlab.user::lang.groups.create_title
redirect: rainlab/user/usergroups/update/:id
redirectClose: rainlab/user/usergroups
# Update page
update:
title: rainlab.user::lang.groups.update_title
redirect: rainlab/user/usergroups
redirectClose: rainlab/user/usergroups
# Preview page
preview:
title: rainlab.user::lang.groups.update_title

View File

@ -0,0 +1,44 @@
# ===================================
# List Behavior Config
# ===================================
# Model List Column configuration
list: $/rainlab/user/models/usergroup/columns.yaml
# Model Class name
modelClass: RainLab\User\Models\UserGroup
# List Title
title: rainlab.user::lang.groups.list_title
# Link URL for each record
recordUrl: rainlab/user/usergroups/update/:id
# Message to display if the list is empty
noRecordsMessage: backend::lang.list.no_records
# Records to display per page
recordsPerPage: 20
# Displays the list column set up button
showSetup: true
# Displays the sorting link on each column
showSorting: true
# Default sorting column
# defaultSort:
# column: created_at
# direction: desc
# Display checkboxes next to each record
# showCheckboxes: true
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: list_toolbar
# Search widget configuration
search:
prompt: backend::lang.list.search_prompt

View File

@ -0,0 +1,48 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/usergroups') ?>"><?= e(trans('rainlab.user::lang.groups.all_groups')) ?></a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name'=>$formRecordName])) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name'=>$formRecordName])) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/user/usergroups') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('rainlab/user/usergroups') ?>" class="btn btn-default"><?= e(trans('rainlab.user::lang.groups.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,2 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,19 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/usergroups') ?>">User Groups</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('rainlab/user/usergroups') ?>" class="btn btn-default">Return to user groups list</a></p>
<?php endif ?>

View File

@ -0,0 +1,56 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/usergroups') ?>"><?= e(trans('rainlab.user::lang.groups.all_groups')) ?></a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name'=>$formRecordName])) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name'=>$formRecordName])) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting_name', ['name'=>$formRecordName])) ?>"
data-request-confirm="<?= e(trans('rainlab.user::lang.groups.delete_confirm')) ?>">
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/user/usergroups') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('rainlab/user/usergroups') ?>" class="btn btn-default"><?= e(trans('rainlab.user::lang.groups.return_to_list')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,48 @@
<?= Form::open(['id' => 'convertGuestForm']) ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Convert guest user</h4>
</div>
<div class="modal-body">
<?php if ($this->fatalError): ?>
<p class="flash-message static error"><?= $fatalError ?></p>
<?php endif ?>
<div class="form-group dropdown-field span-full">
<label>Select a new user group</label>
<select class="form-control custom-select" name="new_group">
<option selected="selected" value="">- No group -</option>
<?php foreach ($groups as $group): ?>
<option value="<?= $group->id ?>"><?= e($group->name) ?></option>
<?php endforeach ?>
</select>
</div>
<div class="form-group checkbox-field span-full">
<div class="checkbox custom-checkbox">
<input type="hidden" class="checkbox" value="" name="send_registration_notification">
<input name="send_registration_notification" value="1" type="checkbox" id="sendNotification" checked="checked" />
<label for="sendNotification">Send registration notification</label>
<p class="help-block">Use this checkbox to generate new random password for the user and send a registration notification email.</p>
</div>
</div>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary"
data-popup-load-indicator
data-request="onConvertGuest">
Convert to registered
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?= Form::close() ?>

View File

@ -0,0 +1,16 @@
<div class="layout-row min-size">
<div class="callout callout-warning">
<div class="header">
<i class="icon-warning"></i>
<h3><?= e(trans('rainlab.user::lang.users.activate_warning_title')) ?></h3>
<p>
<?= e(trans('rainlab.user::lang.users.activate_warning_desc')) ?>
<a href="javascript:;"
data-request="onActivate"
data-request-confirm="<?= e(trans('rainlab.user::lang.users.activate_confirm')) ?>"
data-stripe-load-indicator
><?= e(trans('rainlab.user::lang.users.activate_manually')) ?></a>.
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,16 @@
<div class="layout-row min-size">
<div class="callout callout-danger">
<div class="header">
<i class="icon-ban"></i>
<h3><?= e(trans('rainlab.user::lang.users.banned_hint_title')) ?></h3>
<p>
<?= e(trans('rainlab.user::lang.users.banned_hint_desc')) ?>
<a href="javascript:;"
data-request="onUnban"
data-request-confirm="<?= e(trans('rainlab.user::lang.users.unban_confirm')) ?>"
data-stripe-load-indicator
><?= e(trans('rainlab.user::lang.users.unban_user')) ?></a>.
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
<div class="layout-row min-size">
<div class="callout callout-info">
<div class="header">
<i class="icon-info"></i>
<h3><?= e(trans('rainlab.user::lang.users.guest_hint_title')) ?></h3>
<p>
<?= e(trans('rainlab.user::lang.users.guest_hint_desc')) ?>
<a href="javascript:;"
data-control="popup"
data-handler="onLoadConvertGuestForm"
><?= e(trans('rainlab.user::lang.users.convert_guest_manually')) ?></a>.
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="layout-row min-size">
<div class="callout callout-danger">
<div class="header">
<i class="icon-minus-circle"></i>
<h3><?= e(trans('rainlab.user::lang.users.trashed_hint_title')) ?></h3>
<p><?= e(trans('rainlab.user::lang.users.trashed_hint_desc')) ?></p>
</div>
</div>
</div>

View File

@ -0,0 +1,84 @@
<div data-control="toolbar">
<a
href="<?= Backend::url('rainlab/user/users/create') ?>"
class="btn btn-primary oc-icon-plus">
<?= e(trans('rainlab.user::lang.users.new_user')) ?>
</a>
<div class="btn-group dropdown dropdown-fixed" data-control="bulk-actions">
<button
data-primary-button
type="button"
class="btn btn-default"
data-request="onBulkAction"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true).next().prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('rainlab.user::lang.users.bulk_actions')) ?>
</button>
<button
type="button"
class="btn btn-default dropdown-toggle"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu" data-dropdown-title="<?= e(trans('rainlab.user::lang.users.bulk_actions')) ?>">
<li>
<a href="javascript:;" class="oc-icon-trash-o" data-action="delete" data-confirm="<?= e(trans('rainlab.user::lang.users.delete_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.delete_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-user-plus" data-action="activate" data-confirm="<?= e(trans('rainlab.user::lang.users.activate_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.activate_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-user-times" data-action="deactivate" data-confirm="<?= e(trans('rainlab.user::lang.users.deactivate_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.deactivate_selected')) ?>
</a>
</li>
<li>
<a href="javascript:;" class="oc-icon-user-plus" data-action="restore" data-confirm="<?= e(trans('rainlab.user::lang.users.restore_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.restore_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-ban" data-action="ban" data-confirm="<?= e(trans('rainlab.user::lang.users.ban_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.ban_selected')) ?>
</a>
</li>
<li>
<a href="javascript:;" class="oc-icon-circle-o-notch" data-action="unban" data-confirm="<?= e(trans('rainlab.user::lang.users.unban_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.unban_selected')) ?>
</a>
</li>
</ul>
</div>
<?=
/**
* @event rainlab.user.view.extendListToolbar
* Fires when user list toolbar is rendered.
*
* Example usage:
*
* Event::listen('rainlab.user.view.extendListToolbar', function (
* (RainLab\User\Controllers\Users) $controller
* ) {
* return $controller->makePartial('~/path/to/partial');
* });
*
*/
$this->fireViewEvent('rainlab.user.view.extendListToolbar');
?>
</div>

View File

@ -0,0 +1,40 @@
<div class="scoreboard-item title-value">
<h4><?= e(trans('rainlab.user::lang.user.label')) ?></h4>
<?php if ($formModel->name): ?>
<p><?= e($formModel->name) ?></p>
<?php else: ?>
<p><em><?= e(trans('rainlab.user::lang.user.name_empty')) ?></em></p>
<?php endif ?>
<p class="description">
<a href="mailto:<?= e($formModel->email) ?>">
<?= e($formModel->email) ?>
</a>
</p>
</div>
<?php if ($formModel->created_at): ?>
<div class="scoreboard-item title-value">
<h4><?= e(trans('rainlab.user::lang.user.joined')) ?></h4>
<p title="<?= $formModel->created_at->diffForHumans() ?>">
<?= $formModel->created_at->toFormattedDateString() ?>
</p>
<p class="description">
<?= e(trans('rainlab.user::lang.user.status_label')) ?>:
<?php if ($formModel->is_guest): ?>
<?= e(trans('rainlab.user::lang.user.status_guest')) ?>
<?php elseif ($formModel->is_activated): ?>
<?= e(trans('rainlab.user::lang.user.status_activated')) ?>
<?php else: ?>
<?= e(trans('rainlab.user::lang.user.status_registered')) ?>
<?php endif ?>
</p>
</div>
<?php endif ?>
<?php if ($formModel->last_seen): ?>
<div class="scoreboard-item title-value">
<h4><?= e(trans('rainlab.user::lang.user.last_seen')) ?></h4>
<p><?= $formModel->last_seen->diffForHumans() ?></p>
<p class="description">
<?= $formModel->isOnline() ? e(trans('rainlab.user::lang.user.is_online')) : e(trans('rainlab.user::lang.user.is_offline')) ?>
</p>
</div>
<?php endif ?>

View File

@ -0,0 +1,71 @@
<a
href="<?= Backend::url('rainlab/user/users') ?>"
class="btn btn-default oc-icon-chevron-left">
<?= e(trans('rainlab.user::lang.groups.return_to_users')) ?>
</a>
<a
href="<?= Backend::url('rainlab/user/users/update/'.$formModel->id) ?>"
class="btn btn-primary oc-icon-pencil">
<?= e(trans('rainlab.user::lang.users.update_details')) ?>
</a>
<?php if ($this->user->hasAccess('rainlab.users.impersonate_user')): ?>
<a
href="javascript:;"
data-request="onImpersonateUser"
data-request-confirm="<?= e(trans('rainlab.user::lang.users.impersonate_confirm')) ?>"
class="btn btn-default oc-icon-user-secret">
<?= e(trans('rainlab.user::lang.users.impersonate_user')) ?>
</a>
<?php endif ?>
<?php if ($formModel->isSuspended()): ?>
<a
href="javascript:;"
data-request="onUnsuspendUser"
data-request-confirm="<?= e(trans('rainlab.user::lang.users.unsuspend_confirm')) ?>"
class="btn btn-default oc-icon-unlock-alt">
<?= e(trans('rainlab.user::lang.users.unsuspend')) ?>
</a>
<?php endif ?>
<?php
/* @todo
<div class="btn-group">
<a
href="<?= Backend::url('rainlab/user/users/update/'.$formModel->id) ?>"
class="btn btn-default oc-icon-pencil">
Deactivate
</a>
<a
href="<?= Backend::url('rainlab/user/users/update/'.$formModel->id) ?>"
class="btn btn-default oc-icon-pencil">
Ban user
</a>
<a
href="<?= Backend::url('rainlab/user/users/update/'.$formModel->id) ?>"
class="btn btn-default oc-icon-pencil">
Delete
</a>
</div>
*/
?>
<?=
/**
* @event rainlab.user.view.extendPreviewToolbar
* Fires when preview user toolbar is rendered.
*
* Example usage:
*
* Event::listen('rainlab.user.view.extendPreviewToolbar', function (
* (RainLab\User\Controllers\Users) $controller,
* (RainLab\User\Models\User) $record
* ) {
* return $controller->makePartial('~/path/to/partial');
* });
*
*/
$this->fireViewEvent('rainlab.user.view.extendPreviewToolbar', [
'record' => $formModel
]);
?>

View File

@ -0,0 +1,30 @@
# ===================================
# Filter Scope Definitions
# ===================================
scopes:
groups:
# Filter name
label: rainlab.user::lang.group.label
# Model Class name
modelClass: RainLab\User\Models\UserGroup
# Model attribute to display for the name
nameFrom: name
# Filter scope
scope: filterByGroup
created_date:
label: rainlab.user::lang.user.created_at
type: daterange
conditions: created_at >= ':after' AND created_at <= ':before'
activated:
# Filter name
label: rainlab.user::lang.user.status_activated
# Filter type
type: switch
# SQL conditions
conditions:
- is_activated = '0'
- is_activated = '1'

View File

@ -0,0 +1,25 @@
# ===================================
# Form Behavior Config
# ===================================
# Record name
name: rainlab.user::lang.user.label
# Model Form Field configuration
form: $/rainlab/user/models/user/fields.yaml
# Model Class name
modelClass: RainLab\User\Models\User
# Default redirect location
defaultRedirect: rainlab/user/users
# Create page
create:
redirect: rainlab/user/users/preview/:id
redirectClose: rainlab/user/users
# Update page
update:
redirect: rainlab/user/users/update/:id
redirectClose: rainlab/user/users/preview/:id

View File

@ -0,0 +1,40 @@
# ===================================
# List Behavior Config
# ===================================
# List Title
title: rainlab.user::lang.users.list_title
# Model List Column configuration
list: $/rainlab/user/models/user/columns.yaml
# Model Class name
modelClass: RainLab\User\Models\User
# Link URL for each record
recordUrl: rainlab/user/users/preview/:id
# Message to display if the list is empty
noRecordsMessage: backend::lang.list.no_records
# Records to display per page
recordsPerPage: 20
# Display checkboxes next to each record
showCheckboxes: true
# Displays the list column set up button
showSetup: true
# Filter widget configuration
filter: config_filter.yaml
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: list_toolbar
# Search widget configuration
search:
prompt: backend::lang.list.search_prompt

View File

@ -0,0 +1,64 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/users') ?>"><?= e(trans('rainlab.user::lang.users.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<div class="layout-row min-size">
<?= $this->formRenderOutsideFields() ?>
</div>
<div class="layout-row">
<?= $this->formRenderPrimaryTabs() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name'=>$formRecordName])) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.creating_name', ['name'=>$formRecordName])) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/user/users') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open(['class'=>'layout stretch']) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/user/users') ?>" class="btn btn-default"><?= e(trans('rainlab.user::lang.users.return_to_list')) ?></a></p>
</div>
<?php endif ?>

View File

@ -0,0 +1,2 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,61 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/users') ?>"><?= e(trans('rainlab.user::lang.users.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<?php if ($formModel->is_guest): ?>
<?= $this->makePartial('hint_guest') ?>
<?php elseif ($formModel->isBanned()): ?>
<?= $this->makePartial('hint_banned') ?>
<?php elseif ($formModel->trashed()): ?>
<?= $this->makePartial('hint_trashed') ?>
<?php elseif (!$formModel->is_activated): ?>
<?= $this->makePartial('hint_activate') ?>
<?php endif ?>
<div class="scoreboard">
<div data-control="toolbar">
<?= $this->makePartial('preview_scoreboard') ?>
</div>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<?= $this->makePartial('preview_toolbar') ?>
</div>
</div>
<div class="layout-row min-size">
<?= $this->formRender(['preview' => true, 'section' => 'outside']) ?>
</div>
<div class="layout-row">
<?= $this->formRender(['preview' => true, 'section' => 'primary']) ?>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRender(['preview' => true, 'section' => 'secondary']) ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open(['class'=>'layout stretch']) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="padded-container container-flush">
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('rainlab/user/users') ?>" class="btn btn-default"><?= e(trans('rainlab.user::lang.users.return_to_list')) ?></a></p>
</div>
<?php endif ?>

View File

@ -0,0 +1,72 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/user/users') ?>"><?= e(trans('rainlab.user::lang.users.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<div class="layout-row min-size">
<?= $this->formRenderOutsideFields() ?>
</div>
<div class="layout-row">
<?= $this->formRenderPrimaryTabs() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name'=>$formRecordName])) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving_name', ['name'=>$formRecordName])) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/user/users/preview/'.$formModel->id) ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
<button
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting_name', ['name'=>$formRecordName])) ?>"
data-request-confirm="<?= e(trans('rainlab.user::lang.users.delete_confirm')) ?>">
</button>
</div>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open(['class'=>'layout stretch']) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/user/users') ?>" class="btn btn-default"><?= e(trans('rainlab.user::lang.users.return_to_list')) ?></a></p>
</div>
<?php endif ?>

View File

@ -0,0 +1,15 @@
<?php namespace RainLab\User\Facades;
use October\Rain\Support\Facade;
/**
* @see \RainLab\User\Classes\AuthManager
*/
class Auth extends Facade
{
/**
* Get the registered name of the component.
* @return string
*/
protected static function getFacadeAccessor() { return 'user.auth'; }
}

View File

@ -0,0 +1,190 @@
<?php
return [
'plugin' => [
'name' => 'Uživatelé',
'description' => 'Správa front-end uživatelů.',
'tab' => 'Uživatelé',
'access_users' => 'Správa uživatelů',
'access_groups' => 'Správa uživatelských skupin',
'access_settings' => 'Správa nastavení uživatelů',
],
'users' => [
'menu_label' => 'Uživatelé',
'all_users' => 'Seznam uživatelů',
'new_user' => 'Vytvořit uživatele',
'list_title' => 'Správa uživatelů',
'activating' => 'Povoluji...',
'trashed_hint_title' => 'Uživatel deaktivoval svůj účet',
'trashed_hint_desc' => 'Uživatel zablokoval svůj účet a nechce se dále objevovat na stránkách. Může však svůj účet kdykoli obnovit přihlášením se zpět.',
'banned_hint_title' => 'Uživatel byl zabanován',
'banned_hint_desc' => 'Tento uživatel byl zablokován administrátorem a nebude moct se přihlásit.',
'guest_hint_title' => 'Tento uživatel je host',
'guest_hint_desc' => 'Tento uživatel je uložen pouze jako reference a musí se zaregistrovat před přihlášením.',
'activate_warning_title' => 'Uživatel není aktivní!',
'activate_warning_desc' => 'Tento uživatel nemohl být aktivován a nebude mít možnost se přihlásit.',
'activate_confirm' => 'Opravdu chcete aktivovat tohoto uživatele?',
'activated_success' => 'Uživatel byl úspěšně aktivován!',
'activate_manually' => 'Aktivovat uživatele manuálně',
'convert_guest_confirm' => 'Chcete převést hosta na uživatele?',
'convert_guest_manually' => 'Převést na zaregistrovaného uživatele',
'convert_guest_success' => 'Uživatel byl převeden na registrovaného uživatele',
'delete_confirm' => 'Opravdu chcete smazat tohoto uživatele?',
'unban_user' => 'Zrušit ban tohoto uživatele',
'unban_confirm' => 'Opravdu chcete zrušit ban tohoto uživatele?',
'unbanned_success' => 'Uživateli byl zrušen ban',
'return_to_list' => 'Zpět na seznam uživatelů',
'update_details' => 'Upravit detaily',
'bulk_actions' => 'Hromadné akce',
'delete_selected' => 'Odstranit vybrané',
'delete_selected_confirm' => 'Chcete smazat vybrané uživatele?',
'delete_selected_empty' => 'Nejdříve vyberte uživatele, které chcete smazat.',
'delete_selected_success' => 'Vybraní uživatelé úspěšně odstraněni.',
'deactivate_selected' => 'Deaktivovat vybrané',
'deactivate_selected_confirm' => 'Deaktivovat vybrané uživatele?',
'deactivate_selected_empty' => 'Musíte vybrat uživatele, které chcete deaktivovat.',
'deactivate_selected_success' => 'Vybraní uživatelé byli úspěšně deaktivování.',
'restore_selected' => 'Obnovit vybrané',
'restore_selected_confirm' => 'Opravdu chcete obnovit vybrané uživatele?',
'restore_selected_empty' => 'Musíte vybrat uživatele, které chcete obnovit.',
'restore_selected_success' => 'Vybraní uživatele byli úspěšně obnoveni.',
'ban_selected' => 'Zabanovat vybrané',
'ban_selected_confirm' => 'Opravdu chcete zabanovat vybrané uživatele?',
'ban_selected_empty' => 'Musíte vybrat uživatele, které chcete zabanovat.',
'ban_selected_success' => 'Vybraní uživatelé byli úspěšně zabanováni.',
'unban_selected' => 'Odbanovat vybrané',
'unban_selected_confirm' => 'Opravdu chcete odbanovat vybrané uživatele?',
'unban_selected_empty' => 'Musíte vybrat uživatele, které chcete odbanovat.',
'unban_selected_success' => 'Vybraní uživatelé byli úspěšně odbanováni.',
],
'settings' => [
'users' => 'Uživatelé',
'menu_label' => 'Správa uživatelů',
'menu_description' => 'Správa nastavení uživatelů',
'activation_tab' => 'Aktivace',
'signin_tab' => 'Přihlášení',
'registration_tab' => 'Registrace',
'notifications_tab' => 'Notifikace',
'allow_registration' => 'Povolit registraci uživatelů',
'allow_registration_comment' => 'Pokud je registrace zakázaná, uživatelé lze vytvářet pouze v administraci.',
'activate_mode' => 'Režim aktivace',
'activate_mode_comment' => 'Vyberte jak má být uživatel aktivován.',
'activate_mode_auto' => 'Automaticky',
'activate_mode_auto_comment' => 'Aktivován automaticky ihned po registraci.',
'activate_mode_user' => 'Aktivační e-mail',
'activate_mode_user_comment' => 'Uživatel si aktivuje účet pomocí aktivačního e-mailu.',
'activate_mode_admin' => 'Administrátorem',
'activate_mode_admin_comment' => 'Pouze administrátor může aktivovat uživatele.',
'require_activation' => 'Přihlášení vyžaduje aktivaci uživatele',
'require_activation_comment' => 'Uživatelé musí mít aktivovaný účet, aby se mohl přihlásit.',
'use_throttle' => 'Omezit opakované pokusy o přihlášení',
'use_throttle_comment' => 'Při opakovaném pokusu o přihlášení dojde k suspendování uživatele.',
'login_attribute' => 'Přihlašovací atribut',
'login_attribute_comment' => 'Zvolte, jaký atribut bude použitý k přihlášení uživatele.',
],
'user' => [
'label' => 'Uživatel',
'id' => 'ID',
'username' => 'Uživatelské jméno',
'name' => 'Jméno',
'name_empty' => 'Anonym',
'surname' => 'Příjmení',
'email' => 'E-mail',
'created_at' => 'Datum registrace',
'last_seen' => 'Poslední přihlášení',
'is_guest' => 'Host',
'joined' => 'Registrován',
'is_online' => 'Nyní on-line',
'is_offline' => 'Nyní offline',
'send_invite' => 'Poslat pozvánku e-mailem',
'send_invite_comment' => 'Poslat uvítací e-mail obsahující přihlašovací jméno a heslo.',
'create_password' => 'Vytvořit heslo',
'create_password_comment' => 'Zadejte heslo které se bude používat k přihlašování.',
'reset_password' => 'Nové heslo',
'reset_password_comment' => 'Pro změnu hesla, zadejte nové heslo.',
'confirm_password' => 'Nové heslo znovu pro kontrolu',
'confirm_password_comment' => 'Zadejte heslo znovu pro kontrolu správnosti.',
'groups' => 'Skupiny',
'empty_groups' => 'V této skupině nejsou žádní uživatelé.',
'avatar' => 'Obrázek',
'details' => 'Detaily',
'account' => 'Účet',
'block_mail' => 'Zablokovat všechny odchozí e-maily pro tohoto uživatele.',
'status_guest' => 'Host',
'status_activated' => 'Aktivován',
'status_registered' => 'Registrován',
],
'group' => [
'label' => 'Skupina',
'id' => 'ID',
'name' => 'Název',
'description_field' => 'Popis skupiny',
'code' => 'Kód',
'code_comment' => 'Zadejte unikátní kód pro jednoznačnou identifikaci této skupiny.',
'created_at' => 'Vytvořeno',
'users_count' => 'Počet uživatelů',
],
'groups' => [
'menu_label' => 'Skupiny',
'all_groups' => 'Uživatelské skupiny',
'new_group' => 'Nová skupina',
'delete_selected_confirm' => 'Opravdu chcete smazat vybrané skupiny?',
'list_title' => 'Správa skupin',
'delete_confirm' => 'Opravdu chcete odstranit tuto skupinu?',
'delete_selected_success' => 'Vybrané skupiny byly úspěšně odstraněny.',
'delete_selected_empty' => 'Musíte nejdřív vybrat skupiny které chcete smazat.',
'return_to_list' => 'Zpět na seznam skupin',
'return_to_users' => 'Zpět na seznam uživatelů',
'create_title' => 'Vytvořit skupinu',
'update_title' => 'Upravit skupinu',
'preview_title' => 'Náhled skupiny',
],
'login' => [
'attribute_email' => 'E-mail',
'attribute_username' => 'Uživatelské jméno',
],
'account' => [
'account' => 'Správa účtu',
'account_desc' => 'Formuláře správy účtu a přihlášení',
'redirect_to' => 'Přesměrovat na',
'redirect_to_desc' => 'Název stránky pro přesměrování po úpravě údajů, přihlášení nebo registraci.',
'code_param' => 'Parametr aktivačního kódu',
'code_param_desc' => 'Parametr z URL stránky, který se použije pro aktivační kód',
'invalid_user' => 'Uživatel s těmito údaji nebyl nalezen.',
'invalid_activation_code' => 'Zadán nesprávný parametr pro aktivační kód',
'invalid_deactivation_pass' => 'Zadané heslo není správné.',
'success_activation' => 'Váš účet byl úspěšně aktivován.',
'success_deactivation' => 'Váš účet byl úspěšně deaktivován. Mrzí nás, že odcházíte!',
'success_saved' => 'Nastavení bylo úspěšně uloženo!',
'login_first' => 'Nejdříve musíte být přihlášeni!',
'already_active' => 'Váš účet je již aktivován!',
'activation_email_sent' => 'Aktivační e-mail byl zaslán na e-mail, který byl zadán při registraci.',
'registration_disabled' => 'Registrace jsou dočasně pozastaveny.',
'sign_in' => 'Přihlášení',
'register' => 'Registrace',
'full_name' => 'Celé jméno',
'email' => 'E-mail',
'password' => 'Heslo',
'login' => 'Přihlášení',
'new_password' => 'Nové heslo',
'new_password_confirm' => 'Potvrzení nového hesla'
],
'reset_password' => [
'reset_password' => 'Obnova hesla',
'reset_password_desc' => 'Formulář obnovy hesla',
'code_param' => 'Parametr kódu pro obnovu hesla',
'code_param_desc' => 'Parametr URL použitý pro obnovu hesla'
],
'session' => [
'session' => 'Session',
'session_desc' => 'Vloží do stránky informace o přihlášení s možností omezení přístupových práv.',
'security_title' => 'Povolit pouze',
'security_desc' => 'Kdo má přístup k této stránce.',
'all' => 'Všichni',
'users' => 'Uživatelé',
'guests' => 'Hosti',
'redirect_title' => 'Přesměrovat na',
'redirect_desc' => 'Stránka pro přesměrování, pokud je přístup zamítnut.',
'logout' => 'Byli jste úspěšně odhlášeni!'
]
];

View File

@ -0,0 +1,248 @@
<?php
return [
'plugin' => [
'name' => 'Benutzer',
'description' => 'Frontend-Benutzer-Verwaltung.',
'tab' => 'Benutzer',
'access_users' => 'Benutzer verwalten',
'access_groups' => 'Benutzergruppen verwalten',
'access_settings' => 'Benutzereinstellungen verwalten',
'impersonate_user' => 'Als Benutzer einloggen',
],
'location' => [
'label' => 'Standort',
'new' => 'Neuer Standort',
'create_title' => 'Standort anlegen',
'update_title' => 'Standort bearbeiten',
'preview_title' => 'Standort ansehen',
],
'locations' => [
'menu_label' => 'Standorte',
'menu_description' => 'Verfügbare Benutzer-Standorte und Provinzen verwalten.',
'hide_disabled' => 'Deaktivierte verbergen',
'enabled_label' => 'Aktiviert',
'enabled_help' => 'Deaktivierte Standorte sind im Frontend nicht sichtbar.',
'enable_or_disable_title' => 'Standorte aktivieren oder deaktivieren',
'enable_or_disable' => 'Aktivieren oder deaktivieren',
'selected_amount' => 'Standorte ausgewählt: :amount',
'enable_success' => 'Standorte erfolgreich aktiviert.',
'disable_success' => 'Standorte erfolgreich deaktiviert.',
'disable_confirm' => 'Sind Sie sicher?',
'list_title' => 'Standorte verwalten',
'delete_confirm' => 'Möchten Sie diesen Standort wirklich löschen?',
'return_to_list' => 'Zurück zur Standortliste',
],
'users' => [
'menu_label' => 'Benutzer',
'all_users' => 'Alle Benutzer',
'new_user' => 'Neuer Benutzer',
'list_title' => 'Benutzer verwalten',
'trashed_hint_title' => 'Benutzer hat sein Konto deaktiviert.',
'trashed_hint_desc' => 'Dieser Benutzer hat sein Konto deaktiviert und möchte nicht mehr auf der Seite erscheinen. Er kann sein Konto jederzeit durch eine Anmeldung reaktivieren.',
'banned_hint_title' => 'Benutzer wurde gesperrt.',
'banned_hint_desc' => 'Dieser Benutzer wurde von einem Adminstrator gesperrt und kann sich somit nicht mehr anmelden.',
'guest_hint_title' => 'Dieser Benutzer ist ein Gast',
'guest_hint_desc' => 'Dieser Benutzer ist nur zu Referenzzwecken gespeichert und muss sich vor dem nächsten Login nochmals registrieren.',
'activate_warning_title' => 'Benutzer nicht aktiviert!',
'activate_warning_desc' => 'Dieser Benutzer wurde noch nicht aktiviert und kann sich nicht einloggen.',
'activate_confirm' => 'Möchten Sie diesen Benutzer wirklich aktivieren?',
'activated_success' => 'Benutzer erfolgreich aktiviert!',
'activate_manually' => 'Benutzer manuell aktivieren',
'convert_guest_confirm' => 'Soll dieser Benutzer zu einem Gast umgewandelt werden?',
'convert_guest_manually' => 'Benutzer zu einem Gast umwandeln',
'convert_guest_success' => 'Der Benutzer wurde zu einem Gast umgewandelt',
'impersonate_user' => 'Als Benutzer einloggen',
'impersonate_confirm' => 'Soll die Anmeldung mit diesem Benutzerkonto erfolgen? Nach der Abmeldung wird die bestehende Sitzung wiederhergestellt.',
'impersonate_success' => 'Sie sind nun als diesen Benutzer angemeldet',
'delete_confirm' => 'Möchten Sie diesen Benutzer wirklich löschen?',
'unban_user' => 'Diesen Benutzer entsperren',
'unban_confirm' => 'Möchten Sie diesen Benutzer wirklich entsperren?',
'unbanned_success' => 'Der Benutzer wurde entsperrt',
'return_to_list' => 'Zurück zur Benutzerliste',
'update_details' => 'Update details',
'bulk_actions' => 'Stapelbearbeitung',
'delete_selected' => 'Ausgewählte löschen',
'delete_selected_confirm' => 'Ausgewählte Benutzer löschen?',
'delete_selected_empty' => 'Keine Benutzer zum Löschen ausgewählt.',
'delete_selected_success' => 'Ausgewählte Benutzer erfolgreich gelöscht.',
'activate_selected' => 'Ausgewählte aktivieren',
'activate_selected_confirm' => 'Sollten die ausgewählten Benutzer aktiviert werden?',
'activate_selected_empty' => 'Es sind keine Benutzer zur Aktivierung ausgewählt.',
'activate_selected_success' => 'Die ausgewählten Benutzer wurden erfolgreich aktiviert.',
'deactivate_selected' => 'Ausgewählte deaktivieren',
'deactivate_selected_confirm' => 'Ausgewählte Benutzer deaktivieren?',
'deactivate_selected_empty' => 'Es wurden keine Benutzer zum Deaktivieren ausgewählt.',
'deactivate_selected_success' => 'Ausgewählte Benutzer erfolgreich deaktiviert.',
'restore_selected' => 'Ausgewählte wiederherstellen',
'restore_selected_confirm' => 'Ausgewählte Benutzer wiederherstellen?',
'restore_selected_empty' => 'Es wurden keine Benutzer zum Wiederherstellen ausgewählt.',
'restore_selected_success' => 'Ausgewählte Benutzer erfolgreich wiederhergestellt.',
'ban_selected' => 'Ausgewählte sperren',
'ban_selected_confirm' => 'Ausgewählte Benutzer sperren?',
'ban_selected_empty' => 'Es wurden keine Benutzer zum Sperren ausgewählt.',
'ban_selected_success' => 'Ausgewählte Benutzer erfolgreich gesperrt.',
'unban_selected' => 'Ausgewählte entsperren',
'unban_selected_confirm' => 'Ausgewählte Benutzer entsperren?',
'unban_selected_empty' => 'Es wurden keine Benutzer zum Entsperren ausgewählt.',
'unban_selected_success' => 'Ausgewählte Benutzer erfolgreich entsperrt.',
'activating' => 'Aktiviere...',
],
'settings' => [
'users' => 'Benutzer',
'menu_label' => 'Benutzer-Einstellungen',
'menu_description' => 'Benutzer-Einstellungen verwalten.',
'activation_tab' => 'Aktivierung',
'signin_tab' => 'Einloggen',
'registration_tab' => 'Registrierungen',
'notifications_tab' => 'Benachrichtigungen',
'allow_registration' => 'Benutzerregistrierung erlauben',
'allow_registration_comment' => 'Falls dies deaktivert ist, können Benutzer nur von Administratoren erstellt werden.',
'activate_mode' => 'Aktivierungsmodus',
'activate_mode_comment' => 'Wählen Sie aus, wie ein Benutzer aktiviert werden soll.',
'activate_mode_auto' => 'Automatisch',
'activate_mode_auto_comment' => 'Automatische Aktivierung bei Registrierung.',
'activate_mode_user' => 'Benutzer',
'activate_mode_user_comment' => 'Der Benutzer aktiviert seinen eigenes Konto per E-Mail.',
'activate_mode_admin' => 'Administrator',
'activate_mode_admin_comment' => 'Nur ein Administrator kann einen Benutzer aktivieren.',
'require_activation' => 'Anmeldung benötigt Aktivierung',
'require_activation_comment' => 'Benutzer müssen zum Einloggen ein aktiviertes Konto besitzen.',
'use_throttle' => 'Anmeldeversuche begrenzen',
'use_throttle_comment' => 'Bei wiederholten Anmelde-Fehlversuchen wird der Benutzer temporär gesperrt.',
'block_persistence' => 'Gleichzeitige Anmeldung unterbinden',
'block_persistence_comment' => 'Wird diese Option aktiviert kann sich ein Benutzer nicht an mehreren Geräten gleichzeitig anmelden.',
'login_attribute' => 'Anmelde-Attribut-Zuordnung',
'login_attribute_comment' => 'Wählen Sie, welches Benutzerattribut zum Anmelden verwendet werden soll.',
'location_tab' => 'Standort',
'default_country' => 'Standort-Voreinstellung',
'default_country_comment' => 'Wenn ein Benutzer keinen Standort angibt, wird dieser Standort als Standard gewählt.',
'default_state' => 'Provinz-Voreinstellung',
'default_state_comment' => 'Wenn ein Benutzer keinen Standort angibt, wird diese Provinz als Standard gewählt.',
],
'state' => [
'label' => 'Provinz',
'name' => 'Name',
'name_comment' => 'Anzeigenamen für diese Provinz eingeben.',
'code' => 'Code',
'code_comment' => 'Eindeutigen Code für diese Provinz eingeben.',
],
'country' => [
'label' => 'Land',
'name' => 'Name',
'code' => 'Code',
'code_comment' => 'Eindeutigen Code für dieses Land eingeben.',
'enabled' => 'Aktiv',
],
'user' => [
'label' => 'Benutzer',
'id' => 'ID',
'username' => 'Benutzername',
'name' => 'Name',
'name_empty' => 'Anonym',
'surname' => 'Nachname',
'email' => 'E-Mail',
'created_at' => 'Registriert am',
'last_seen' => 'Zuletzt gesehen',
'is_guest' => 'Gast',
'joined' => 'Registriert',
'is_online' => 'Jetzt online',
'is_offline' => 'Momentan offline',
'send_invite' => 'Einladung per E-Mail versenden',
'send_invite_comment' => 'Sendet eine E-Mail mit Benutzername und Passwort and den Benutzer',
'create_password' => 'Passwort erstellen',
'create_password_comment' => 'Gib ein neues Passwort ein, das zum Anmelden verwendet wird.',
'reset_password' => 'Passwort setzen',
'reset_password_comment' => 'Geben Sie hier ein Passwort ein, um das aktuelle Benutzerpasswort zu überschreiben.',
'confirm_password' => 'Passwort bestätigen',
'confirm_password_comment' => 'Passwort zur Bestätigung erneut eingeben.',
'groups' => 'Gruppen',
'empty_groups' => 'Es gibt keine Benutzer-Gruppen.',
'avatar' => 'Avatar',
'details' => 'Details',
'account' => 'Benutzerkonto',
'block_mail' => 'Blockiere alle ausgehenden E-Mails an diesen Benutzer.',
'status_guest' => 'Gast',
'status_activated' => 'Aktiviert',
'status_registered' => 'Registriert',
],
'login' => [
'attribute_email' => 'E-Mail',
'attribute_username' => 'Benutzername',
],
'account' => [
'account' => 'Benutzerkonto',
'account_desc' => 'Benutzerkontoverwaltung.',
'banned' => 'Sorry, dieser Benutzer ist momentan nicht aktiviert. Kontaktieren Sie uns für weitere Unterstützung.',
'redirect_to' => 'Weiterleiten nach',
'redirect_to_desc' => 'Seitenname zum Weiterleiten nach Update, Anmeldung oder Registrierung.',
'code_param' => 'Aktivierungscode Parameter',
'code_param_desc' => 'Dieser URL-Parameter wird als Registrierungs-Aktivierungscode verwendet',
'force_secure' => 'Forciere sichere URLs',
'force_secure_desc' => 'Verwende für Weiterleitungen immer das HTTPS-Protokoll.',
'invalid_user' => 'Es wurde kein Benutzer mit diesen Zugangsdaten gefunden.',
'invalid_activation_code' => 'Ungültiger Aktivierungscode übermittelt',
'invalid_deactivation_pass' => 'Das eingegebene Passwort war ungültig.',
'success_activation' => 'Benutzerkonto erfolgreich aktiviert.',
'success_deactivation' => 'Konto erfolgreich deaktiviert. Schade, dass du gehst!',
'success_saved' => 'Einstellungen erfolgreich gespeichert!',
'login_first' => 'Sie müssen sich erst einloggen!',
'already_active' => 'Ihr Benutzerkonto ist bereits aktiviert!',
'activation_email_sent' => 'Eine Aktivierungs-E-Mail wurde an Ihre E-Mail-Adresse versendet.',
'registration_disabled' => 'Registrierungen sind momentan deaktiviert.',
'sign_in' => 'Anmelden',
'register' => 'Registrieren',
'full_name' => 'Name',
'email' => 'E-Mail',
'password' => 'Passwort',
'login' => 'Anmelden',
'new_password' => 'Neues Passwort',
'new_password_confirm' => 'Neues Passwort bestätigen',
],
'reset_password' => [
'reset_password' => 'Passwort zurücksetzen',
'reset_password_desc' => 'Formular zum Zurücksetzen des Passworts.',
'code_param' => 'Reset-Code-Parameter',
'code_param_desc' => 'URL-Parameter, der für den Reset-Code verwendet wird',
],
'session' => [
'session' => 'Session',
'session_desc' => 'Fügt Benutzer-Session zu Seite hinzu und kann Zugriff einschränken.',
'security_title' => 'Erlauben',
'security_desc' => 'Wer hat Zugriff auf die Seite?',
'all' => 'Jeder',
'users' => 'Benutzer',
'guests' => 'Gäste',
'allowed_groups_title' => 'Gruppen zulassen',
'allowed_groups_description' => 'Wählen Sie zugelassene Gruppen aus. Wird keine Gruppe ausgewhält sind alle zugelassen.',
'redirect_title' => 'Weiterleiten nach',
'redirect_desc' => 'Seitenname zum Weiterleiten bei verweigertem Zugriff.',
'logout' => 'Sie haben sich erfolgreich ausgeloggt!',
'stop_impersonate_success' => 'Sie sind nicht mehr als diesen Benutzer angemeldet.',
],
'group' => [
'label' => 'Gruppe',
'id' => 'ID',
'name' => 'Name',
'description_field' => 'Beschreibung',
'code' => 'Code',
'code_comment' => 'Gebe einen eindeutigen Code ein, der die Gruppe identifiziert.',
'created_at' => 'Erstellt am',
'users_count' => 'Benutzer',
],
'groups' => [
'menu_label' => 'Gruppen',
'all_groups' => 'Benutzergruppen',
'new_group' => 'Neue Gruppe',
'delete_selected_confirm' => 'Willst du die ausgewählten Gruppen wirklich löschen?',
'list_title' => 'Gruppen verwalten',
'delete_confirm' => 'Willst du diese Gruppe wirklich löschen?',
'delete_selected_success' => 'Ausgewählte Gruppen erfolgreich gelöscht.',
'delete_selected_empty' => 'Es wurden keine Gruppen zum Löschen ausgewählt.',
'return_to_list' => 'Zurück zur Gruppenliste',
'return_to_users' => 'Zurück zur Benutzerliste',
'create_title' => 'Benutzergruppe erstellen',
'update_title' => 'Benutzergruppe bearbeiten',
'preview_title' => 'Vorschau der Benutzergruppe',
],
];

View File

@ -0,0 +1,228 @@
<?php
return [
'plugin' => [
'name' => 'User',
'description' => 'Front-end user management.',
'tab' => 'Users',
'access_users' => 'Manage Users',
'access_groups' => 'Manage User Groups',
'access_settings' => 'Manage User Settings',
'impersonate_user' => 'Impersonate Users'
],
'users' => [
'menu_label' => 'Users',
'all_users' => 'All Users',
'new_user' => 'New User',
'list_title' => 'Manage Users',
'trashed_hint_title' => 'User has deactivated their account',
'trashed_hint_desc' => 'This user has deactivated their account and no longer wants to appear on the site. They can restore their account at any time by signing back in.',
'banned_hint_title' => 'User has been banned',
'banned_hint_desc' => 'This user has been banned by an administrator and will be unable to sign in.',
'guest_hint_title' => 'This is a guest user',
'guest_hint_desc' => 'This user is stored for reference purposes only and needs to register before signing in.',
'activate_warning_title' => 'User not activated!',
'activate_warning_desc' => 'This user has not been activated and may be unable to sign in.',
'activate_confirm' => 'Do you really want to activate this user?',
'activated_success' => 'User has been activated',
'activate_manually' => 'Activate this user manually',
'convert_guest_confirm' => 'Convert this guest to a user?',
'convert_guest_manually' => 'Convert to registered user',
'convert_guest_success' => 'User has been converted to a registered account',
'impersonate_user' => 'Impersonate user',
'impersonate_confirm' => 'Impersonate this user? You can revert to your original state by logging out.',
'impersonate_success' => 'You are now impersonating this user',
'delete_confirm' => 'Do you really want to delete this user?',
'unban_user' => 'Unban this user',
'unban_confirm' => 'Do you really want to unban this user?',
'unbanned_success' => 'User has been unbanned',
'return_to_list' => 'Return to users list',
'update_details' => 'Update details',
'bulk_actions' => 'Bulk actions',
'delete_selected' => 'Delete selected',
'delete_selected_confirm' => 'Delete the selected users?',
'delete_selected_empty' => 'There are no selected users to delete.',
'delete_selected_success' => 'Successfully deleted the selected users.',
'activate_selected' => 'Activate selected',
'activate_selected_confirm' => 'Activate the selected users?',
'activate_selected_empty' => 'There are no selected users to activate.',
'activate_selected_success' => 'Successfully activated the selected users.',
'deactivate_selected' => 'Deactivate selected',
'deactivate_selected_confirm' => 'Deactivate the selected users?',
'deactivate_selected_empty' => 'There are no selected users to deactivate.',
'deactivate_selected_success' => 'Successfully deactivated the selected users.',
'restore_selected' => 'Restore selected',
'restore_selected_confirm' => 'Restore the selected users?',
'restore_selected_empty' => 'There are no selected users to restore.',
'restore_selected_success' => 'Successfully restored the selected users.',
'ban_selected' => 'Ban selected',
'ban_selected_confirm' => 'Ban the selected users?',
'ban_selected_empty' => 'There are no selected users to ban.',
'ban_selected_success' => 'Successfully banned the selected users.',
'unban_selected' => 'Unban selected',
'unban_selected_confirm' => 'Unban the selected users?',
'unban_selected_empty' => 'There are no selected users to unban.',
'unban_selected_success' => 'Successfully unbanned the selected users.',
'unsuspend' => 'Unsuspend',
'unsuspend_success' => 'User has been unsuspended.',
'unsuspend_confirm' => 'Unsuspend this user?'
],
'settings' => [
'users' => 'Users',
'menu_label' => 'User settings',
'menu_description' => 'Manage user authentication, registration and activation settings.',
'activation_tab' => 'Activation',
'signin_tab' => 'Sign in',
'registration_tab' => 'Registration',
'profile_tab' => 'Profile',
'notifications_tab' => 'Notifications',
'allow_registration' => 'Allow user registration',
'allow_registration_comment' => 'If this is disabled users can only be created by administrators.',
'activate_mode' => 'Activation mode',
'activate_mode_comment' => 'Select how a user account should be activated.',
'activate_mode_auto' => 'Automatic',
'activate_mode_auto_comment' => 'Activated automatically upon registration.',
'activate_mode_user' => 'User',
'activate_mode_user_comment' => 'The user activates their own account using mail.',
'activate_mode_admin' => 'Administrator',
'activate_mode_admin_comment' => 'Only an Administrator can activate a user.',
'require_activation' => 'Sign in requires activation',
'require_activation_comment' => 'Users must have an activated account to sign in.',
'use_throttle' => 'Throttle attempts',
'use_throttle_comment' => 'Repeat failed sign in attempts will temporarily suspend the user.',
'use_register_throttle' => 'Throttle registration',
'use_register_throttle_comment' => 'Prevent multiple registrations from the same IP in short succession.',
'block_persistence' => 'Prevent concurrent sessions',
'block_persistence_comment' => 'When enabled users cannot sign in to multiple devices at the same time.',
'login_attribute' => 'Login attribute',
'login_attribute_comment' => 'Select what primary user detail should be used for signing in.',
'remember_login' => 'Remember login mode',
'remember_login_comment' => 'Select if the user session should be persistent.',
'remember_always' => 'Always',
'remember_never' => 'Never',
'remember_ask' => 'Ask the user on login',
],
'user' => [
'label' => 'User',
'id' => 'ID',
'username' => 'Username',
'name' => 'Name',
'name_empty' => 'Anonymous',
'surname' => 'Surname',
'email' => 'Email',
'created_at' => 'Registered',
'last_seen' => 'Last seen',
'is_guest' => 'Guest',
'joined' => 'Joined',
'is_online' => 'Online now',
'is_offline' => 'Currently offline',
'send_invite' => 'Send invitation by email',
'send_invite_comment' => 'Sends a welcome message containing login and password information.',
'create_password' => 'Create Password',
'create_password_comment' => 'Enter a new password used for signing in.',
'reset_password' => 'Reset Password',
'reset_password_comment' => 'To reset this users password, enter a new password here.',
'confirm_password' => 'Password Confirmation',
'confirm_password_comment' => 'Enter the password again to confirm it.',
'groups' => 'Groups',
'empty_groups' => 'There are no user groups available.',
'avatar' => 'Avatar',
'details' => 'Details',
'account' => 'Account',
'block_mail' => 'Block all outgoing mail sent to this user.',
'status_label' => 'Status',
'status_guest' => 'Guest',
'status_activated' => 'Activated',
'status_registered' => 'Registered',
'created_ip_address' => 'Created IP Address',
'last_ip_address' => 'Last IP Address',
],
'group' => [
'label' => 'Group',
'id' => 'ID',
'name' => 'Name',
'description_field' => 'Description',
'code' => 'Code',
'code_comment' => 'Enter a unique code used to identify this group.',
'created_at' => 'Created',
'users_count' => 'Users'
],
'groups' => [
'menu_label' => 'Groups',
'all_groups' => 'User Groups',
'new_group' => 'New Group',
'delete_selected_confirm' => 'Do you really want to delete selected groups?',
'list_title' => 'Manage Groups',
'delete_confirm' => 'Do you really want to delete this group?',
'delete_selected_success' => 'Successfully deleted the selected groups.',
'delete_selected_empty' => 'There are no selected groups to delete.',
'return_to_list' => 'Back to groups list',
'return_to_users' => 'Back to users list',
'create_title' => 'Create User Group',
'update_title' => 'Edit User Group',
'preview_title' => 'Preview User Group'
],
'login' => [
'attribute_email' => 'Email',
'attribute_username' => 'Username'
],
'account' => [
'account' => 'Account',
'account_desc' => 'User management form.',
'banned' => 'Sorry, this user is currently not activated. Please contact us for further assistance.',
'redirect_to' => 'Redirect to',
'redirect_to_desc' => 'Page name to redirect to after update, sign in or registration.',
'code_param' => 'Activation Code Param',
'code_param_desc' => 'The page URL parameter used for the registration activation code',
'force_secure' => 'Force secure protocol',
'force_secure_desc' => 'Always redirect the URL with the HTTPS schema.',
'invalid_user' => 'A user was not found with the given credentials.',
'invalid_activation_code' => 'Invalid activation code supplied.',
'invalid_deactivation_pass' => 'The password you entered was invalid.',
'invalid_current_pass' => 'The current password you entered was invalid.',
'success_activation' => 'Successfully activated your account.',
'success_deactivation' => 'Successfully deactivated your account. Sorry to see you go!',
'success_saved' => 'Settings successfully saved!',
'login_first' => 'You must be logged in first!',
'already_active' => 'Your account is already activated!',
'activation_email_sent' => 'An activation email has been sent to your email address.',
'activation_by_admin' => 'You have successfully registered. Your account is not yet active and must be approved by an administrator.',
'registration_disabled' => 'Registrations are currently disabled.',
'registration_throttled' => 'Registration is throttled. Please try again later.',
'sign_in' => 'Sign in',
'register' => 'Register',
'full_name' => 'Full Name',
'email' => 'Email',
'password' => 'Password',
'login' => 'Login',
'new_password' => 'New Password',
'new_password_confirm' => 'Confirm New Password',
'update_requires_password' => 'Confirm password on update',
'update_requires_password_comment' => 'Require the current password of the user when changing their profile.',
'activation_page' => 'Activation Page',
'activation_page_comment' => 'Select a page to use for activating the user account',
'reset_page' => 'Reset Page',
'reset_page_comment' => 'Select a page to use for resetting the account password',
],
'reset_password' => [
'reset_password' => 'Reset Password',
'reset_password_desc' => 'Forgotten password form.',
'code_param' => 'Reset Code Param',
'code_param_desc' => 'The page URL parameter used for the reset code'
],
'session' => [
'session' => 'Session',
'session_desc' => 'Adds the user session to a page and can restrict page access.',
'security_title' => 'Allow only',
'security_desc' => 'Who is allowed to access this page.',
'all' => 'All',
'users' => 'Users',
'guests' => 'Guests',
'allowed_groups_title' => 'Allow groups',
'allowed_groups_description' => 'Choose allowed groups or none to allow all groups',
'redirect_title' => 'Redirect to',
'redirect_desc' => 'Page name to redirect if access is denied.',
'logout' => 'You have been successfully logged out!',
'stop_impersonate_success' => 'You are no longer impersonating a user.',
]
];

View File

@ -0,0 +1,168 @@
<?php
return [
'plugin' => [
'name' => 'User',
'description' => 'Front-end user management.',
'tab' => 'Users',
'access_users' => 'Administrar Usuarios',
'access_groups' => 'Administrar Grupos de Usuarios',
'access_settings' => 'Administrar Ajustes de Usuario'
],
'users' => [
'menu_label' => 'Usuarios',
'all_users' => 'Todos los Usuarios',
'new_user' => 'Nuevo Usuario',
'list_title' => 'Administrar Usuarios',
'activating' => 'Activando...',
'trashed_hint_title' => 'El usuario ha desactivado su cuenta',
'trashed_hint_desc' => 'Éste usuario ha desactivado su cuenta y no quiere volver a aparecer en el sitio. Ellos pueden restaurar su cuenta en cualquier momento al re-ingresar.',
'banned_hint_title' => 'El usuario ha sido baneado',
'banned_hint_desc' => 'Éste usuario ha sido baneado por un administrador y estará imposibilitado para ingresar.',
'activate_warning_title' => 'El usuario no esta activado!',
'activate_warning_desc' => 'Éste usuario no esta activado y quizá no pueda ingresar.',
'activate_confirm' => 'Realmente desea activar éste usuario?',
'activate_manually' => 'Activar éste usuario manualmente',
'delete_confirm' => 'Realmente desea eliminar éste usuario?',
'activated_success' => 'El usuario ha sido activado con éxito!',
'return_to_list' => 'Regresar a la lista de usuarios',
'delete_selected' => 'Eliminar seleccionados',
'delete_selected_confirm' => 'Eliminar los usuarios seleccionados?',
'delete_selected_empty' => 'No hay usuarios seleccionados para eliminar.',
'delete_selected_success' => 'Los usuarios seleccionados se eliminaron con éxito.',
'deactivate_selected' => 'Desactivar seleccionados',
'deactivate_selected_confirm' => 'Desactivar los usuarios seleccionados?',
'deactivate_selected_empty' => 'No hay usuarios seleccionados para desactivar.',
'deactivate_selected_success' => 'Los usuarios seleccionados se desactivaron con éxito.',
'restore_selected' => 'Reactivar seleccionados',
'restore_selected_confirm' => 'Reactivar los usuarios seleccionados?',
'restore_selected_empty' => 'No hay usuarios seleccionados para reactivar.',
'restore_selected_success' => 'Los usuarios seleccionados se reactivaron con éxito.',
'ban_selected' => 'Suspender seleccionados (Banear)',
'ban_selected_confirm' => 'Suspender los usuarios seleccionados?',
'ban_selected_empty' => 'No hay usuarios seleccionados para suspender.',
'ban_selected_success' => 'Los usuarios seleccionados se suspendieron con éxito.',
'unban_selected' => 'Reanudar seleccionados (Baneados)',
'unban_selected_confirm' => 'Reanudar los usuarios seleccionados?',
'unban_selected_empty' => 'No hay usuarios seleccionados para reanudar.',
'unban_selected_success' => 'Los usuarios seleccionados se reanudaron con éxito.',
],
'settings' => [
'users' => 'Usuarios',
'menu_label' => 'Ajustes de Usuario',
'menu_description' => 'Administrar los ajustes de usuario.',
'activation_tab' => 'Activación',
'signin_tab' => 'Ingreso',
'registration_tab' => 'Registración',
'notifications_tab' => 'Notificaciones',
'allow_registration' => 'Permitir registro de ususarios',
'allow_registration_comment' => 'Si esta desactivado, los usuarios solo podrán ser creados por administradores.',
'activate_mode' => 'Modo de Activación',
'activate_mode_comment' => 'Seleccione la forma en que una cuenta debe ser activada.',
'activate_mode_auto' => 'Automático',
'activate_mode_auto_comment' => 'Se activa automáticamente en la registración.',
'activate_mode_user' => 'Usuario',
'activate_mode_user_comment' => 'El usuario activa su propia cuenta a través del e-mail.',
'activate_mode_admin' => 'Administrador',
'activate_mode_admin_comment' => 'Solo los administradores pueden activar usuarios.',
'require_activation' => 'El ingreso requiere activación',
'require_activation_comment' => 'Los usuarios necesitarán una cuenta activa para ingresar.',
'use_throttle' => 'Regular intentos fallidos',
'use_throttle_comment' => 'Repetidos intentos fallidos de ingreso suspenderán temporalmente al usuario.',
'login_attribute' => 'Atributo para ingreso',
'login_attribute_comment' => 'Seleccione que atributo sera utilizado para el ingreso.',
],
'user' => [
'label' => 'Usuario',
'id' => 'ID',
'username' => 'Nombre de Usuario',
'name' => 'Nombre',
'surname' => 'Apellido',
'email' => 'Email',
'created_at' => 'Registrado',
'create_password' => 'Crear Contraseña',
'create_password_comment' => 'Ingrese una nueva contraseña.',
'reset_password' => 'Reiniciar contraseña ',
'reset_password_comment' => 'Para reiniciar esta contraseña, ingrese un nueva aquí.',
'confirm_password' => 'Confirmar contraseña',
'confirm_password_comment' => 'Ingrese nuevamente la contraseña para confirmarla.',
'groups' => 'Grupos',
'empty_groups' => 'No hay grupos de usuarios disponibles.',
'avatar' => 'Avatar',
'details' => 'Detalles',
'account' => 'Cuenta'
],
'group' => [
'label' => 'Grupo',
'id' => 'ID',
'name' => 'Nombre',
'description_field' => 'Descripción',
'code' => 'Código',
'code_comment' => 'Ingrese un código único para identificar a este grupo.',
'created_at' => 'Creado',
'users_count' => 'Usuarios'
],
'groups' => [
'menu_label' => 'Grupos',
'all_groups' => 'Grupos de Usuario',
'new_group' => 'Nuevo Grupo',
'delete_selected_confirm' => 'Realmente quiere eliminar los grupos seleccionados?',
'list_title' => 'Administrar Grupos',
'delete_confirm' => 'Realmente quiere eliminar este grupo?',
'delete_selected_success' => 'Los grupos seleccionados se eliminaron con éxito.',
'delete_selected_empty' => 'No hay grupos seleccionados para eliminar.',
'return_to_list' => 'Volver a la lista de grupos',
'return_to_users' => 'Volver a la lista de usuarios',
'create_title' => 'Crear Grupo',
'update_title' => 'Editar Grupo',
'preview_title' => 'Ver Grupo'
],
'login' => [
'attribute_email' => 'Email',
'attribute_username' => 'Nombre de Usuario'
],
'account' => [
'account' => 'Cuenta',
'account_desc' => 'Formulario de administración de usuario.',
'redirect_to' => 'Redirigir a',
'redirect_to_desc' => 'Nombre de la página a redirigir luego de una actualización, ingreso o registro.',
'code_param' => 'Parámetro del Código de Activación',
'code_param_desc' => 'El parámetro de URL utilizado para el código de activación de registro.',
'invalid_user' => 'No se encontraron usuarios con los datos proporcionados.',
'invalid_activation_code' => 'Código de activación inválido.',
'invalid_deactivation_pass' => 'La contraseña ingresada no es válida.',
'success_activation' => 'Su cuenta fue activada con éxito.',
'success_deactivation' => 'Su cuenta fue desactivada con éxito.',
'success_saved' => 'Ajustes guardados con éxito!',
'login_first' => 'Primero debes ingresar con un usuario!',
'already_active' => 'Su cuenta ya se encuentra activada!',
'activation_email_sent' => 'Un mail de activación fue enviado a su cuenta de correo.',
'registration_disabled' => 'Actualmente los registros no están habilitados.',
'sign_in' => 'Ingresar',
'register' => 'Registrarse',
'full_name' => 'Nombre Completo',
'email' => 'Email',
'password' => 'Contraseña',
'login' => 'Iniciar Sesión',
'new_password' => 'Nueva Contraseña',
'new_password_confirm' => 'Confirmar Nueva Contraseña'
],
'reset_password' => [
'reset_password' => 'Reiniciar Contraseña',
'reset_password_desc' => 'Formulario de olvido de contraseña.',
'code_param' => 'Parámetro del Código de Reinicio',
'code_param_desc' => 'El parámetro de URL utilizado para el código de reinicio.'
],
'session' => [
'session' => 'Sesión',
'session_desc' => 'Agrega la sesión de usuario a una pagina y permite restringir el acceso a la misma.',
'security_title' => 'Permitir acceso a',
'security_desc' => 'Quien tiene permiso para acceder a esta página.',
'all' => 'Todos',
'users' => 'Usuarios',
'guests' => 'Invitados',
'redirect_title' => 'Redirigir a',
'redirect_desc' => 'Nombre de la página a redirigir si el acceso es denegado.',
'logout' => 'La sesión se ha cerrado con éxito!'
]
];

View File

@ -0,0 +1,212 @@
<?php
return [
'plugin' => [
'name' => 'Usuarios',
'description' => 'Administración de usuarios en la interfaz del sistema.',
'tab' => 'Usuarios',
'access_users' => 'Administrar usuarios',
'access_groups' => 'Administrar grupos',
'access_settings' => 'Preferencias de usuario',
'impersonate_user' => 'Personificar Usuario'
],
'users' => [
'menu_label' => 'Usuarios',
'all_users' => 'Todos los usuarios',
'new_user' => 'Nuevo usuario',
'list_title' => 'Administrar usuarios',
'trashed_hint_title' => 'El usuario tiene su perfil desactivado',
'trashed_hint_desc' => 'Este usuario tiene desactivado su perfil y no quiere aparecer en el sitio. Los usuarios pueden reactivar su perfil en cualquier momento iniciando sesión nuevamente.',
'banned_hint_title' => 'El Usuario ha sido bloqueado',
'banned_hint_desc' => 'Este usuario ha sido bloqueado por un administrador y no será capaz de iniciar sesión.',
'guest_hint_title' => 'Este usuario es un invitado',
'guest_hint_desc' => 'El usuario es almacenado sólo para efectos de referencia y necesita registrarse antes de iniciar sesión.',
'activate_warning_title' => '¡El usuario no se pudo activar!',
'activate_warning_desc' => 'Este usuario todavía no ha sido activado y no será capaz de iniciar sesión.',
'activate_confirm' => '¿Realmente desea activar este usuario?',
'activated_success' => '¡El usuario ha sido activado exitosamente!',
'activate_manually' => 'Activar usuario manualmente',
'convert_guest_confirm' => '¿Convertir este invitado en usuario?',
'convert_guest_manually' => 'Convertir a usuario registrado',
'convert_guest_success' => 'El usuario ha sido convertido a una cuenta registrada',
'impersonate_user' => 'Iniciar sesión como este usuario',
'impersonate_confirm' => '¿Estás seguro que quieres iniciar sesión como este usuario? Puedes volver a tu estado original cerrando la sesión.',
'impersonate_success' => 'Has iniciado sesión como este usuario correctamente.',
'delete_confirm' => '¿Realmente desea eliminar este usuario?',
'unban_user' => 'Desbloquear este usuario',
'unban_confirm' => '¿Realmente desea desbloquear este usuario?',
'unbanned_success' => 'El usuario ha sido desbloqueado',
'return_to_list' => 'Volver a la lista de usuarios',
'update_details' => 'Actualizar detalles',
'bulk_actions' => 'Acciones en masa',
'delete_selected' => 'Eliminar usuarios seleccionados',
'delete_selected_confirm' => '¿Eliminar los usuarios seleccionados?',
'delete_selected_empty' => 'No hay usuarios seleccionados a eliminar.',
'delete_selected_success' => 'Se eliminaron exitosamente los usuarios seleccionados.',
'activate_selected' => 'Activar usuarios seleccionados',
'activate_selected_confirm' => '¿Activar los usuarios seleccionados?',
'activate_selected_empty' => 'No hay usuarios seleccionados para activar.',
'activate_selected_success' => 'Los usuarios seleccionados han sido activados exitosamente.',
'deactivate_selected' => 'Desactivar usuarios seleccionados',
'deactivate_selected_confirm' => '¿Desactivar los usuarios seleccionados?',
'deactivate_selected_empty' => 'No hay usuarios seleccionados a desactivar.',
'deactivate_selected_success' => 'Se desactivaron exitosamente los usuarios seleccionados.',
'restore_selected' => 'Restablecer los usuarios seleccionados',
'restore_selected_confirm' => '¿Restablecer los usuarios seleccionados?',
'restore_selected_empty' => 'No hay usuarios seleccionados a restablecer.',
'restore_selected_success' => 'Se restablecieron exitosamente los usuarios seleccionados.',
'ban_selected' => 'Bloquear usuarios seleccionados',
'ban_selected_confirm' => '¿Bloquear los usuarios seleccionados?',
'ban_selected_empty' => 'No hay usuarios seleccionados a bloquear.',
'ban_selected_success' => 'Se bloquearon exitosamente los usuarios seleccionados.',
'unban_selected' => 'Desbloquear usuarios seleccionados',
'unban_selected_confirm' => '¿Desbloquear los usuarios seleccionados?',
'unban_selected_empty' => 'No hay usuarios seleccionados a desbloquear.',
'unban_selected_success' => 'Se desbloquearon exitosamente los usuarios seleccionados.',
],
'settings' => [
'users' => 'Usuarios',
'menu_label' => 'Preferencias de usuario',
'menu_description' => 'Administra las preferencias de los usuarios.',
'activation_tab' => 'Activación',
'signin_tab' => 'Iniciar sesión',
'registration_tab' => 'Registro',
'notifications_tab' => 'Notificaciones',
'allow_registration' => 'Permitir registro de usuarios',
'allow_registration_comment' => 'Si está deshabilitado los usuarios sólo pueden ser creados por administradores.',
'min_password_length' => 'Largo mínimo de la contraseña',
'min_password_length_comment' => 'La cantidad mínima de caracteres requerida para contraseñas.',
'activate_mode' => 'Modo de activación',
'activate_mode_comment' => 'Seleccione como debería ser activado un perfil de usuario.',
'activate_mode_auto' => 'Automática',
'activate_mode_auto_comment' => 'Activada automáticamente al registrarse.',
'activate_mode_user' => 'Usuario',
'activate_mode_user_comment' => 'El usuario activa su perfil usando su e-mail.',
'activate_mode_admin' => 'Administrador',
'activate_mode_admin_comment' => 'Sólo un administrador puede activar un usuario.',
'require_activation' => 'Inicio de sesión requiere activación.',
'require_activation_comment' => 'Usuarios deben tener una perfil activado para poder iniciar sesión.',
'use_throttle' => 'Límite de intentos',
'use_throttle_comment' => 'Intentos de inicios de sesión seguidos que provocaran la suspensión temporal del perfil de usuario.',
'block_persistence' => 'Prevenir sesiones concurrentes',
'block_persistence_comment' => 'Prevenir que los usuarios habilitados puedan iniciar sesión desde múltiples dispositivos.',
'login_attribute' => 'Atributo de inicio de sesión',
'login_attribute_comment' => 'Seleccione que dato de usuario debería ser utilizado para el inicio de sesión.',
'remember_login' => 'Modo recordar usuario',
'remember_login_comment' => 'Selecciona si la sesión del usuario debe ser persistente.',
'remember_always' => 'Siempre',
'remember_never' => 'Nunca',
'remember_ask' => 'Preguntar al usuario al iniciar sesión',
],
'user' => [
'label' => 'Usuario',
'id' => 'ID',
'username' => 'Nombre de usuario',
'name' => 'Nombres',
'name_empty' => 'Anónimo',
'surname' => 'Apellidos',
'email' => 'E-mail',
'created_at' => 'Registrado',
'last_seen' => 'Última vez visto',
'is_guest' => 'Invitado',
'joined' => 'Incorporado',
'is_online' => 'En línea ahora',
'is_offline' => 'Actualmente desconectado',
'send_invite' => 'Enviar invitación por email',
'send_invite_comment' => 'Envía un mensaje de bienvenida con información de inicio de sesión y contraseña.',
'create_password' => 'Crear contraseña',
'create_password_comment' => 'Ingrese nueva contraseña para iniciar sesión',
'reset_password' => 'Restablecer contraseña',
'reset_password_comment' => 'Para restablecer la contraseña del usuario, ingrese una nueva contraseña aquí.',
'confirm_password' => 'Confirmación de contraseña',
'confirm_password_comment' => 'Ingrese la contraseña nuevamente para confirmarla.',
'groups' => 'Grupos',
'empty_groups' => 'No hay grupos de usuarios disponibles.',
'avatar' => 'Avatar',
'details' => 'Detalles',
'account' => 'Perfil',
'block_mail' => 'Bloquear todos los envios de e-mail para este usuario.',
'status_guest' => 'Invitado',
'status_activated' => 'Activado',
'status_registered' => 'Registrado',
],
'group' => [
'label' => 'Grupo',
'id' => 'ID',
'name' => 'Nombre',
'description_field' => 'Descripción',
'code' => 'Código',
'code_comment' => 'Ingrese un código único para identificar este grupo.',
'created_at' => 'Creado',
'users_count' => 'Usuarios'
],
'groups' => [
'menu_label' => 'Grupos',
'all_groups' => 'Grupos de usuarios',
'new_group' => 'Nuevo grupo',
'delete_selected_confirm' => '¿Realmente quiere eliminar todos los grupos seleccionados?',
'list_title' => 'Administrar grupos',
'delete_confirm' => '¿Realmente desea eliminar este grupo?',
'delete_selected_success' => 'Los grupos seleccionados fueron eliminados exitosamente.',
'delete_selected_empty' => 'No hay grupos seleccionados para eliminar.',
'return_to_list' => 'Volver a la lista de grupos',
'return_to_users' => 'Volver a la lista de usuarios',
'create_title' => 'Añadir grupo',
'update_title' => 'Editar grupo',
'preview_title' => 'Vista previa de grupo'
],
'login' => [
'attribute_email' => 'Email',
'attribute_username' => 'Nombre de usuario'
],
'account' => [
'account' => 'Perfil',
'account_desc' => 'Formulario para gestionar datos del usuario.',
'banned' => 'Los sentimos, este usuario no se encuentra activado actualmente. Por favor contáctanos para mayor asistencia.',
'redirect_to' => 'redirigir a',
'redirect_to_desc' => 'Página hacia la cual redirigir despues de una actualización, inicio de sesión o registro.',
'code_param' => 'Parámetro para el código de activación',
'code_param_desc' => 'El parámetro de URL en la página usuado para el código de activación del registro.',
'force_secure' => 'Forzar protocolo seguro',
'force_secure_desc' => 'Siempre redirigir la URL utilizando HTTPS.',
'invalid_user' => 'No se encontro un usuario con las credenciales proporcionadas.',
'invalid_activation_code' => 'El código de activación que proporcionó es inválido.',
'invalid_deactivation_pass' => 'La contraseña que ingresó es inválida.',
'success_activation' => 'Su perfil fue activado exitosamente.',
'success_deactivation' => 'Su perfil fue desactivado exitosamente. ¡Nos apena mucho su partida!',
'success_saved' => '¡Preferencias guardadas exitosamente!',
'login_first' => '¡Debe iniciar sesión primero!',
'already_active' => '¡Su perfil ya estaba activado!',
'activation_email_sent' => 'Un e-mail de confirmación ha sido enviado a su dirección de correo electrónico.',
'registration_disabled' => 'El registro de usuarios está temporalmente deshabilitado.',
'sign_in' => 'Iniciar sesión',
'register' => 'Registro',
'full_name' => 'Nombre completo',
'email' => 'E-mail',
'password' => 'Contraseña',
'login' => 'Iniciar sesión',
'new_password' => 'Nueva contraseña',
'new_password_confirm' => 'Confirme su nueva contraseña'
],
'reset_password' => [
'reset_password' => 'Restablecer contraseña',
'reset_password_desc' => 'Formulario de contraseña olvidada.',
'code_param' => 'Parámetro para el código de restablecimiento',
'code_param_desc' => 'El parámetro de URL de la página usado para el código de restablecimiento.e'
],
'session' => [
'session' => 'Sesión',
'session_desc' => 'Agrega la sesión del usuario a una página y puede restringir el acceso a dicha página.',
'security_title' => 'Permitir solamente',
'security_desc' => 'Quién es permitido acceder a esta página.',
'all' => 'Todos',
'users' => 'Usuarios',
'guests' => 'Invitados',
'allowed_groups_title' => 'Permitir grupos',
'allowed_groups_description' => 'Selecciona los grupos permitidos o ninguno para permitir todos los grupos',
'redirect_title' => 'redirigir a',
'redirect_desc' => 'Página a la cual redirigir si el acceso es denegado.',
'logout' => '¡Ha terminado exitosamente su sesión!',
'stop_impersonate_success' => 'Has dejado de personificar al usuario.',
]
];

View File

@ -0,0 +1,191 @@
<?php return [
'plugin' => [
'name' => 'کاربر',
'description' => 'مدیریت کاربران',
'tab' => 'کاربران',
'access_users' => 'مدیریت کاربران',
'access_groups' => 'مدیریت گروه‌های کاربران',
'access_settings' => 'مدیریت تنطیمات کاربران',
'impersonate_user' => 'از دید کاربران'
],
'users' => [
'menu_label' => 'کاربران',
'all_users' => 'همه کاربران',
'new_user' => 'کاربر جدید',
'list_title' => 'مدیریت کاربران',
'trashed_hint_title' => 'کاربر حساب خود را غیر فعال کرده است',
'trashed_hint_desc' => 'این کاربر حساب خود را غیر فعال کرده است و علاقه ای به ادامه فعالیت در سایت را ندارد. کاربران با ورود مجدد به سایت میتوانند حساب خود را فعال کنند.',
'banned_hint_title' => 'حساب کاربری مسدود است',
'banned_hint_desc' => 'حساب این کاربر توسط مدیر مسدود است و نمی تواند به سیستم وارد شود',
'guest_hint_title' => 'این کاربر مهمان است',
'guest_hint_desc' => 'این کاربر برای مرجع دهی ثبت شده است باید ثبت نام و وارد سیستم شود.',
'activate_warning_title' => 'کاربر فعال نمیباشد!',
'activate_warning_desc' => 'این کاربر فعال نشده است و نمیتواند وارد سایت شود.',
'activate_confirm' => 'آیا از فعالسازی این کاربر اطمینان دارید؟',
'activated_success' => 'کاربر با موفقیت فعال شد.',
'activate_manually' => 'فعال سازی دستی این کاربر',
'convert_guest_confirm' => 'تبدیل این کاربر به مهمان؟',
'convert_guest_manually' => 'تبدیل به کاربر ثبت نام شده',
'convert_guest_success' => 'کارب به حالت ثبت نام شده تغییر پیدا کرد',
'delete_confirm' => 'آیا از حذف این کاربر اطمینان دارید؟',
'unban_user' => 'رفع انتسداد حساب کاربری',
'unban_confirm' => 'آیا از رفع انسداد حساب کاربری این شخص اطمینان دارید؟',
'unbanned_success' => 'حساب کاربری رفع انسداد شد',
'return_to_list' => 'بازگشت به لیست کاربران',
'update_details' => 'ویرایش جزئیات',
'bulk_actions' => 'اعمال گروهی',
'delete_selected' => 'حذف انتخاب شده',
'delete_selected_confirm' => 'آیا از حذف کاربران انتخاب شده اطمینان داری؟',
'delete_selected_empty' => 'کاربری جهت حذف انتخاب نشده است.',
'delete_selected_success' => 'کاربران انتخاب شده با موفقیت حذف شدند.',
'deactivate_selected' => 'غیر فعال سازی انتخاب شده',
'deactivate_selected_confirm' => 'کاربران انتخاب شده غیرفعال شوند؟',
'deactivate_selected_empty' => 'کاربری برای غیر فعال سازی انتخاب نشده است',
'deactivate_selected_success' => 'کاربران انتخاب شده با موفقیت غیرفعال شدند',
'restore_selected' => 'بازسازی انتخاب شده ها',
'restore_selected_confirm' => 'کاربرانت انتخاب شده بازسازی شوند؟',
'restore_selected_empty' => 'کاربری برای بازسازی انتخاب نشده',
'restore_selected_success' => 'کاربران انتخاب شده با موفقیت بازسازی شدند',
'ban_selected' => 'مسدود کردن انتخاب شده ها',
'ban_selected_confirm' => 'کاربران انتخاب شده مسدود شوند؟',
'ban_selected_empty' => 'کاربری برای اسنداد حساب انتخاب نشده است',
'ban_selected_success' => 'حساب کاربران انتخاب شده با موفقیت مسدود شد',
'unban_selected' => 'رفع انسداد انتخاب شده ها',
'unban_selected_confirm' => 'کاربران انتخاب شده رفع انسداد شوند؟',
'unban_selected_empty' => 'کاربری برای رفع انسداد انتخاب نشده است',
'unban_selected_success' => 'کاربران انتخاب شده با موفقیت رفع انسداد شدند',
'activating' => 'فعال سازی...',
],
'settings' => [
'users' => 'کاربران',
'menu_label' => 'تنظیمات کاربران',
'menu_description' => 'مدیریت تنظیمات مربوط به کاربر.',
'activation_tab' => 'فعال سازی',
'signin_tab' => 'ورود',
'registration_tab' => 'ایجاد حساب کاربری',
'notifications_tab' => 'هشدار ها',
'allow_registration' => 'به کاربران اجازه ثبت نام داده شود.',
'allow_registration_comment' => 'اگر این گزینه غیر فعال باشد حساب کاربری فقط توسط مدیران میتواند ایجاد شود.',
'activate_mode' => 'روش فعال سازی',
'activate_mode_comment' => 'روشی را که میخواهید حساب های کاربری از آن طریق فعال شوند را انتخاب نمایید.',
'activate_mode_auto' => 'خودکار',
'activate_mode_auto_comment' => 'بهنگام ثبت نام حساب کاربری به صورت خودکار فعال شود.',
'activate_mode_user' => 'کاربر',
'activate_mode_user_comment' => 'کاربران حساب خود را از طریق ایمیل فعال نمایند.',
'activate_mode_admin' => 'مدیریت',
'activate_mode_admin_comment' => 'فقط مدیران حساب کاربری را فعال نمایید.',
'require_activation' => 'ورود نیاز مند فعال سازی حساب کاربری می باشد',
'require_activation_comment' => 'کاربران باید دارای حساب کاربری فعال جهت ورود باشند.',
'use_throttle' => 'جلو گیری از ورود',
'use_throttle_comment' => 'تکرار ورود نا موفق کاربر را به طور موقت غیر فعال میکند.',
'login_attribute' => 'مشخصه ی ورود',
'login_attribute_comment' => 'مشخصه ای را که کاربر برای ورود باید وارد نماید انتخاب نمایید.',
],
'user' => [
'label' => 'کاربر',
'id' => 'مشخصه',
'username' => 'نام کاربری',
'name' => 'نام',
'name_empty' => 'ناشناس',
'surname' => 'نام خانوادگی',
'email' => 'پست الکترونیکی',
'created_at' => 'تاریخ ثبت نام',
'last_seen' => 'آخرین بازدید',
'is_guest' => 'مهمان',
'joined' => 'عضو شده',
'is_online' => 'آنلاین',
'is_offline' => 'هم اکنون آفلاین',
'send_invite' => 'ارسال دعوت نامه با ایمیل',
'send_invite_comment' => 'ارسال ایمیل خوش آمد شامل رمز عبور و نام کاربری',
'create_password' => 'ساخت رمزعبور',
'create_password_comment' => 'رمز جدید برای استفاده کاربر در زمان ورود را وارد کنید',
'reset_password' => 'تنظیم مجدد کلمه عبور',
'reset_password_comment' => 'جهت تنظیم مجدد کلمه عبور کاربر ، کلمه عبور جدید را وارد نمایید.',
'confirm_password' => 'تایید کلمه عبور',
'confirm_password_comment' => 'جهت تایید کلمه عبور را مجددا وارد نمایید.',
'groups' => 'گرو ها',
'empty_groups' => 'گروه کاربری موجود نیست',
'avatar' => 'نمایه',
'details' => 'جزییات',
'account' => 'حساب کاربری',
'block_mail' => 'هیچ ایمیلی به این کاربر ارسال نشود',
'status_guest' => 'مهمان',
'status_activated' => 'فعال',
'status_registered' => 'عضو شده',
'user' => 'user',
],
'group' => [
'label' => 'گروه',
'id' => 'مشخصه',
'name' => 'نام',
'description_field' => 'توضیحات',
'code' => 'کد یکتا',
'code_comment' => 'کد یکتایی را جهت دسترسی به این گروه وارد نمایید',
'created_at' => 'تاریخ ایجاد',
'users_count' => 'کاربران',
],
'groups' => [
'menu_label' => 'گروه ها',
'all_groups' => 'گروه های کاربر',
'new_group' => 'گروه جدید',
'delete_selected_confirm' => 'آیا از حذف گروه های انتخاب شده اطمینان دارید؟',
'list_title' => 'مدیریت گروه ها',
'delete_confirm' => 'آیا از حذف این گروه اطمینان دارید؟',
'delete_selected_success' => 'گروه های انتخاب شده با موفقیت حذف شدند.',
'delete_selected_empty' => 'گروهی جهت حذف انتخاب نشده است.',
'return_to_list' => 'بازگشت به لیست گروه ها',
'return_to_users' => 'بازگشت به لیست کاربران',
'create_title' => 'ایجاد گروه کاربری جدید',
'update_title' => 'ویرایش گروه کاربری',
'preview_title' => 'پیش نمایش گروه کاربری',
],
'login' => [
'attribute_email' => 'پست الکترونیکی',
'attribute_username' => 'نام کاربری',
],
'account' => [
'account' => 'حساب کاربری',
'account_desc' => 'فرم مدیریت کاربران.',
'redirect_to' => 'انتقال به',
'redirect_to_desc' => 'نام صفحه ای که کاربر پس از ورود باید به آن صفحه منتقل شود.',
'code_param' => 'پارامتر کد فعال سازی',
'code_param_desc' => 'پارامتر آدرس صفحه جهت استفاده در کد فعال سازی بهنگام ثبت نام',
'invalid_user' => 'کاربری با اطلاعات وارد شده یافت نشد.',
'invalid_activation_code' => 'مد فعالسازی معتبر نمیباشد',
'invalid_deactivation_pass' => 'کلمه عبور وارد شده صحیح نمی باشد.',
'success_activation' => 'حساب کاربری شما با موفقیت فعال شد.',
'success_deactivation' => 'حساب شما با موفقیت غیر فعال شد. از رفتن شما متاسفیم.',
'success_saved' => 'تنظیمات با موفقیت اعمال شدند.',
'login_first' => 'شما باید وارد حساب کاربری خود شوید!',
'already_active' => 'حساب کاربری شما قبلا فعال شده است!',
'activation_email_sent' => 'یک پست الکترونیکی حاوی آدرس فعال سازی به ایمیل شما ارسال شد.',
'registration_disabled' => 'در حال حاظر سرویس ثبت نام فعال نمی باشد.',
'sign_in' => 'ورود',
'register' => 'ثبت نام',
'full_name' => 'نام کامل',
'email' => 'پست الکترونیکی',
'password' => 'کلمه عبور',
'login' => 'نام کاربری',
'new_password' => 'کلمه عبور جدید',
'new_password_confirm' => 'تایید کلمه عبور',
],
'reset_password' => [
'reset_password' => 'بازنشانی کلمه عبور',
'reset_password_desc' => 'فرم کلمه عبور فراموش شده.',
'code_param' => 'پارامتر کد بازنشانی',
'code_param_desc' => 'پارامتر آدرس صفحه ای که جهت کد بازنشانی استفاده خوهد شد',
],
'session' => [
'session' => 'جلسه',
'session_desc' => 'جلسه کاربری را به صفحه جهت دسترسی کاربران اضافه می کند.',
'security_title' => 'دسترسی برای',
'security_desc' => 'چه کسانی میتوانند به این صفحه دسترسی داشته باشند؟',
'all' => 'همه',
'users' => 'کاربران',
'guests' => 'میهمان ها',
'redirect_title' => 'انتقال به',
'redirect_desc' => 'نام صفحه‌ای که در صورت عدم اجازه دسترسی کاربر به آن انتقال پیدا می‌کند.',
'logout' => 'با موفقیت از سیستم خارج شدید!',
'stop_impersonate_success' => 'دیگر در نقشِ سایر کاربران نیستید.',
],
];

View File

@ -0,0 +1,206 @@
<?php
return [
'plugin' => [
'name' => 'Utilisateur',
'description' => 'Gestion des utilisateurs Front-End.',
'tab' => 'Utilisateur',
'access_users' => 'Gérer les utilisateurs',
'access_groups' => 'Gérer les groupes',
'access_settings' => 'Gérer les paramètres',
'impersonate_user' => 'Usurper l\'identité des utilisateurs'
],
'users' => [
'menu_label' => 'Utilisateurs',
'all_users' => 'Tous les utilisateurs',
'new_user' => 'Nouvel utilisateur',
'list_title' => 'Gestion des utilisateurs',
'trashed_hint_title' => 'Lutilisateur a désactivé son compte',
'trashed_hint_desc' => 'Cet utilisateur a désactivé son compte ou ne souhaite plus apparaître sur le site. Il peut réactiver son compte à tout moment en se réinscrivant.',
'banned_hint_title' => 'Lutilisateur a été banni',
'banned_hint_desc' => 'Cet utilisateur a été banni par ladministrateur et ne pourra plus se réinscrire.',
'guest_hint_title' => 'Ceci est un utilisteur invité',
'guest_hint_desc' => 'Cette utilisateur est enregistré comme référence seulement, il doit s\'inscire avant de se connecter.',
'activate_warning_title' => 'Lutilisateur nest pas activé !',
'activate_warning_desc' => 'Cet utilisateur na pas été activé et sera dans limpossibilité de se connecter.',
'activate_confirm' => 'Confirmez-vous lactivation de cet utilisateur ?',
'activated_success' => 'Lutilisateur a été activé avec succès !',
'activate_manually' => 'Activer cet utilisateur manuellement',
'convert_guest_confirm' => 'Convertir cet invité en utilisateur?',
'convert_guest_manually' => 'Convertir en utilisateur enregistré',
'convert_guest_success' => 'L\'utilisateur à été converti en compte enregistré',
'impersonate_user' => 'Usurper l\'identité d\'un utilisateur',
'impersonate_confirm' => 'Usurper l\'identité de cet utilisateur? Vous pouvez revenir à votre état d\'origine en vous déconnectant.',
'impersonate_success' => 'Vous êtes en train d\'usurper l\'identité de cet utilisateur',
'delete_confirm' => 'Confirmez-vous la suppression de cet utilisateur ?',
'unban_user' => 'Lever le bannissement de cet utilisateur',
'unban_confirm' => 'Confirmez-vous la levée du bannissement de cet utilisateur ?',
'unbanned_success' => 'Lutilisateur nest plus banni',
'return_to_list' => 'Retour à la liste des utilisateurs',
'update_details' => 'Mettre à jour les informations',
'bulk_actions' => 'Actions groupées',
'delete_selected' => 'Supprimer la sélection',
'delete_selected_confirm' => 'Supprimer les utilisateurs sélectionnés ?',
'delete_selected_empty' => 'Aucun utilisateur na été sélectionné pour la suppression.',
'delete_selected_success' => 'Les utilisateurs sélectionnés ont été supprimés correctement.',
'activate_selected' => 'Activer la sélection',
'activate_selected_confirm' => 'Activer les utilisateurs sélectionnés?',
'activate_selected_empty' => 'Aucun utilisateur sélectionné à activer.',
'activate_selected_success' => 'Les utilisateurs sélectionnés ont été activé avec succès.',
'deactivate_selected' => 'Désactiver la sélection',
'deactivate_selected_confirm' => 'Désactiver les utilisateurs sélectionnés ?',
'deactivate_selected_empty' => 'Il ny a aucun utilisateur sélectionné à désactiver.',
'deactivate_selected_success' => 'Les utilisateurs sélectionnés ont été désactivés avec succès.',
'restore_selected' => 'Activer la sélection',
'restore_selected_confirm' => 'Activer les utilisateurs sélectionnés ?',
'restore_selected_empty' => 'Il ny a aucun utilisateur sélectionné à activer.',
'restore_selected_success' => 'Les utilisateurs sélectionnés ont été activés avec succès.',
'ban_selected' => 'Bannir la sélection',
'ban_selected_confirm' => 'Bannir les utilisateurs sélectionnés ?',
'ban_selected_empty' => 'Il ny a aucun utilisateur sélectionné à bannir.',
'ban_selected_success' => 'Les utilisateurs sélectionnés ont été bannis avec succès.',
'unban_selected' => 'Lever le bannissement de la sélection',
'unban_selected_confirm' => 'Lever le bannissement des utilisateurs sélectionnés ?',
'unban_selected_empty' => 'Il ny a aucun utilisateur sélectionné pour lesquels lever le bannissement.',
'unban_selected_success' => 'Le bannissement des utilisateurs sélectionnés a été levé avec succès.',
],
'settings' => [
'users' => 'Utilisateurs',
'menu_label' => 'Paramètres utilisateurs',
'menu_description' => 'Gérer les paramètres liés aux utilisateurs.',
'activation_tab' => 'Activation',
'signin_tab' => 'Connexion',
'registration_tab' => 'Enregistrement',
'notifications_tab' => 'Notifications',
'allow_registration' => 'Autoriser l\'inscription des utilisateurs',
'allow_registration_comment' => 'Si désactivé, les utilisateurs ne peuvent être créés que par des administrateurs.',
'activate_mode' => 'Mode dactivation',
'activate_mode_comment' => 'Choisissez la méthode dactivation des comptes dutilisateurs.',
'activate_mode_auto' => 'Automatique',
'activate_mode_auto_comment' => 'Activation automatique après inscription.',
'activate_mode_user' => 'Utilisateur',
'activate_mode_user_comment' => 'Lutilisateur active son compte par email.',
'activate_mode_admin' => 'Administrateur',
'activate_mode_admin_comment' => 'Seul un administrateur peut activer un utilisateur.',
'require_activation' => 'Vérifier lactivation des comptes utilisateurs lors de la connexion',
'require_activation_comment' => 'Si activé, les utilisateurs doivent avoir leur compte activé pour pouvoir se connecter.',
'use_throttle' => 'Tentatives de connexion ratées',
'use_throttle_comment' => 'En cas de tentatives répétées de connexion, lutilisateur sera suspendu temporairement.',
'block_persistence' => 'Empêcher les sessions simultanées',
'block_persistence_comment' => 'Lorsque activée, les utilisateurs ne peuvent pas se connecter à plusieurs appareils en même temps.',
'login_attribute' => 'Attribut pour lidentifiant',
'login_attribute_comment' => 'Choisissez lattribut utilisateur à utiliser comme identifiant.',
],
'user' => [
'label' => 'Utilisateur',
'id' => 'ID',
'username' => 'Identifiant',
'name' => 'Prénom',
'name_empty' => 'Anonyme',
'surname' => 'Nom',
'email' => 'E-mail',
'created_at' => 'Enregistré le',
'last_seen' => 'Dernière connexion',
'is_guest' => 'Invité',
'joined' => 'Inscrit le',
'is_online' => 'Est actuellement connecté',
'is_offline' => 'Nest pas connecté',
'send_invite' => 'Envoyer une invitation par email',
'send_invite_comment' => 'Envoie un message de bienvenue contenant les informations de connexion et de mot de passe.',
'create_password' => 'Créer un mot de passe',
'create_password_comment' => 'Entrez un nouveau mot de passe de connexion.',
'reset_password' => 'Réinitialiser le mot de passe',
'reset_password_comment' => 'Pour effacer le mot de passe de cet utilisateur, entrez un nouveau mot de passe ici.',
'confirm_password' => 'Confirmation du mot de passe',
'confirm_password_comment' => 'Entrez à nouveau le mot de passe pour le confirmer.',
'groups' => 'Groupes',
'empty_groups' => 'Aucun groupe d\'utilisateurs disponible.',
'avatar' => 'Avatar',
'details' => 'Détails',
'account' => 'Compte',
'block_mail' => 'Bloquer tous les e-mails sortants à destination de cet utilisateur.',
'status_guest' => 'Invité',
'status_activated' => 'Activé',
'status_registered' => 'Enregistré',
],
'group' => [
'label' => 'Groupe dutilisateurs',
'id' => 'ID',
'name' => 'Nom',
'description_field' => 'Description',
'code' => 'Code',
'code_comment' => 'Entrez un code unique pour y accéder via lAPI',
'created_at' => 'Créé le',
'users_count' => 'Nombre dutilisateurs',
],
'groups' => [
'menu_label' => 'Groupes',
'all_groups' => 'Tous les groupes',
'new_group' => 'Nouveau groupe',
'delete_selected_confirm' => 'Confirmez-vous la suppression des groupes sélectionnés ?',
'list_title' => 'Groupes dutilisateurs',
'delete_confirm' => 'Confirmez-vous la suppression de ce groupe dutilisateurs ?',
'delete_selected_success' => 'Les groupes dutilisateurs sélectionnés ont été supprimés avec succès.',
'delete_selected_empty' => 'Il na aucun groupe dutilisateurs sélectionné à supprimer.',
'return_to_list' => 'Retour à la liste des groupes',
'return_to_users' => 'Retour à la liste des utilisateurs',
'create_title' => 'Nouveau groupe dutilisateurs',
'update_title' => 'Modifier un groupe dutilisateurs',
'preview_title' => 'Visualiser le groupe d\'utilisateurs',
],
'login' => [
'attribute_email' => 'Email',
'attribute_username' => 'Pseudo',
],
'account' => [
'account' => 'Compte',
'account_desc' => 'Gestion du compte utilisateur.',
'banned' => 'Désolé, cet utilisateur n\'est actuellement pas activé. S\'il vous plaît contactez-nous pour plus d\'aide.',
'redirect_to' => 'Rediriger vers',
'redirect_to_desc' => 'Nom de la page de redirection après la mise à jour, la connexion ou lenregistrement.',
'code_param' => 'Paramètre code dactivation',
'code_param_desc' => 'URL de la page utilisée pour lenregistrement du code dactivation',
'force_secure' => 'Forer le protocole sécurisé',
'force_secure_desc' => 'Toujours rediriger l\'URL avec le schéma HTTPS.',
'invalid_user' => 'Aucun utilisateur ne correspond aux identifiants fournis.',
'invalid_activation_code' => 'Le code dactivation fourni est invalide.',
'invalid_deactivation_pass' => 'Le mot de passe saisi est invalide.',
'success_activation' => 'Votre compte a été activé avec succès !',
'success_deactivation' => 'Votre compte a été désactivé avec succès. Nous somme navrés de vous voir partir !',
'success_saved' => 'Vos paramètres ont été enregistrés avec succès !',
'login_first' => 'Vous devez dabord vous connecter !',
'already_active' => 'Votre compte a déjà été activé !',
'activation_email_sent' => 'Un e-mail dactivation a été envoyé sur votre adresse e-mail personnelle.',
'registration_disabled' => 'La création de compte est désactivée pour le moment.',
'sign_in' => 'Connexion',
'register' => 'Créer un compte',
'full_name' => 'Nom complet',
'email' => 'E-mail',
'password' => 'Mot de passe',
'login' => 'Identifiant',
'new_password' => 'Nouveau mot de passe',
'new_password_confirm' => 'Confirmez le nouveau mot de passe',
],
'reset_password' => [
'reset_password' => 'Réinitialiser le mot de passe',
'reset_password_desc' => 'Formulaire de récupération du mot de passe.',
'code_param' => 'Code de réinitialisation',
'code_param_desc' => 'URL de la page utilisée pour le code de réinitialisation',
],
'session' => [
'session' => 'Session',
'session_desc' => 'Ajoute la session utilisateur à une page et permet de restreindre laccès à la page.',
'security_title' => 'Autorisations spéciales',
'security_desc' => 'Personne(s) autorisée(s) à accéder à cette page.',
'all' => 'Tous',
'users' => 'Utilisateurs',
'guests' => 'Invités',
'allowed_groups_title' => 'Autoriser les groupes',
'allowed_groups_description' => 'Choisissez les groupes autorisés ou aucun pour autoriser tous les groupes',
'redirect_title' => 'Rediriger vers',
'redirect_desc' => 'Nom de la page de redirection au cas où laccès est refusé.',
'logout' => 'Vous avez été déconnecté avec succès.',
'stop_impersonate_success' => 'Vous n\'êtes plus en train d\'usurper l\'identité d\'un utilisateur',
],
];

Some files were not shown because too many files have changed in this diff Show More