Deprecate Utils class and use helper functions instead

This commit is contained in:
printempw 2018-08-07 11:47:12 +08:00
parent adb6aed94a
commit 60a24c03b0
17 changed files with 184 additions and 132 deletions

View File

@ -5,7 +5,6 @@ namespace App\Http\Controllers;
use Log; use Log;
use Mail; use Mail;
use View; use View;
use Utils;
use Cache; use Cache;
use Cookie; use Cookie;
use Option; use Option;
@ -44,7 +43,7 @@ class AuthController extends Controller
$user = $users->get($identification, $authType); $user = $users->get($identification, $authType);
// Require CAPTCHA if user fails to login more than 3 times // Require CAPTCHA if user fails to login more than 3 times
$loginFailsCacheKey = sha1('login_fails_'.Utils::getClientIp()); $loginFailsCacheKey = sha1('login_fails_'.get_client_ip());
$loginFails = (int) Cache::get($loginFailsCacheKey, 0); $loginFails = (int) Cache::get($loginFailsCacheKey, 0);
if ($loginFails > 3) { if ($loginFails > 3) {
@ -135,54 +134,52 @@ class AuthController extends Controller
// If amount of registered accounts of IP is more than allowed amounts, // If amount of registered accounts of IP is more than allowed amounts,
// then reject the register. // then reject the register.
if (User::where('ip', Utils::getClientIp())->count() < option('regs_per_ip')) if (User::where('ip', get_client_ip())->count() >= option('regs_per_ip')) {
{
// Register a new user.
// If the email is already registered,
// it will return a false value.
$user = User::register(
$request->get('email'),
$request->get('password'), function($user) use ($request)
{
$user->ip = Utils::getClientIp();
$user->score = option('user_initial_score');
$user->register_at = Utils::getTimeFormatted();
$user->last_sign_at = Utils::getTimeFormatted(time() - 86400);
$user->permission = User::NORMAL;
$user->nickname = $request->get(
option('register_with_player_name') ? 'player_name' : 'nickname'
);
});
if (! $user) {
return json(trans('auth.register.registered'), 5);
}
event(new Events\UserRegistered($user));
// Add player with chosen name
if (option('register_with_player_name')) {
$player = new Player;
$player->uid = $user->uid;
$player->player_name = $request->get('player_name');
$player->preference = 'default';
$player->last_modified = Utils::getTimeFormatted();
$player->save();
event(new Events\PlayerWasAdded($player));
}
return json([
'errno' => 0,
'msg' => trans('auth.register.success'),
'token' => $user->getToken(),
]) // Set cookies
->withCookie('uid', $user->uid, 60)
->withCookie('token', $user->getToken(), 60);
} else {
return json(trans('auth.register.max', ['regs' => option('regs_per_ip')]), 7); return json(trans('auth.register.max', ['regs' => option('regs_per_ip')]), 7);
} }
// Register a new user.
// If the email is already registered,
// it will return a false value.
$user = User::register(
$request->get('email'),
$request->get('password'), function($user) use ($request)
{
$user->ip = get_client_ip();
$user->score = option('user_initial_score');
$user->register_at = get_datetime_string();
$user->last_sign_at = get_datetime_string(time() - 86400);
$user->permission = User::NORMAL;
$user->nickname = $request->get(
option('register_with_player_name') ? 'player_name' : 'nickname'
);
});
if (! $user) {
return json(trans('auth.register.registered'), 5);
}
event(new Events\UserRegistered($user));
// Add player with chosen name
if (option('register_with_player_name')) {
$player = new Player;
$player->uid = $user->uid;
$player->player_name = $request->get('player_name');
$player->preference = 'default';
$player->last_modified = get_datetime_string();
$player->save();
event(new Events\PlayerWasAdded($player));
}
return json([
'errno' => 0,
'msg' => trans('auth.register.success'),
'token' => $user->getToken(),
]) // Set cookies
->withCookie('uid', $user->uid, 60)
->withCookie('token', $user->getToken(), 60);
} }
public function forgot() public function forgot()
@ -204,7 +201,7 @@ class AuthController extends Controller
} }
$rateLimit = 180; $rateLimit = 180;
$lastMailCacheKey = sha1('last_mail_'.Utils::getClientIp()); $lastMailCacheKey = sha1('last_mail_'.get_client_ip());
$remain = $rateLimit + Cache::get($lastMailCacheKey, 0) - time(); $remain = $rateLimit + Cache::get($lastMailCacheKey, 0) - time();
// Rate limit // Rate limit

View File

@ -4,7 +4,6 @@ namespace App\Http\Controllers;
use View; use View;
use Event; use Event;
use Utils;
use Option; use Option;
use App\Models\User; use App\Models\User;
use App\Models\Player; use App\Models\Player;
@ -79,7 +78,7 @@ class PlayerController extends Controller
$player->uid = $this->user->uid; $player->uid = $this->user->uid;
$player->player_name = $request->input('player_name'); $player->player_name = $request->input('player_name');
$player->preference = "default"; $player->preference = "default";
$player->last_modified = Utils::getTimeFormatted(); $player->last_modified = get_datetime_string();
$player->save(); $player->save();
event(new PlayerWasAdded($player)); event(new PlayerWasAdded($player));

View File

@ -4,7 +4,6 @@ namespace App\Http\Controllers;
use Log; use Log;
use File; use File;
use Utils;
use Schema; use Schema;
use Option; use Option;
use Storage; use Storage;
@ -101,10 +100,10 @@ class SetupController extends Controller
$request->input('email'), $request->input('email'),
$request->input('password'), function ($user) $request->input('password'), function ($user)
{ {
$user->ip = Utils::getClientIp(); $user->ip = get_client_ip();
$user->score = option('user_initial_score'); $user->score = option('user_initial_score');
$user->register_at = Utils::getTimeFormatted(); $user->register_at = get_datetime_string();
$user->last_sign_at = Utils::getTimeFormatted(time() - 86400); $user->last_sign_at = get_datetime_string(time() - 86400);
$user->permission = User::SUPER_ADMIN; $user->permission = User::SUPER_ADMIN;
}); });
Log::info("[SetupWizard] Super Admin registered.", ['user' => $user]); Log::info("[SetupWizard] Super Admin registered.", ['user' => $user]);

View File

@ -3,7 +3,6 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use View; use View;
use Utils;
use Option; use Option;
use Storage; use Storage;
use Session; use Session;
@ -20,6 +19,23 @@ class SkinlibController extends Controller
{ {
protected $user = null; protected $user = null;
/**
* Map error code of file uploading to human-readable text.
*
* @see http://php.net/manual/en/features.file-upload.errors.php
* @var array
*/
public static $phpFileUploadErrors = [
0 => 'There is no error, the file uploaded with success',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
3 => 'The uploaded file was only partially uploaded',
4 => 'No file was uploaded',
6 => 'Missing a temporary folder',
7 => 'Failed to write file to disk.',
8 => 'A PHP extension stopped the file upload.',
];
public function __construct(UserRepository $users) public function __construct(UserRepository $users)
{ {
// Try to load user by uid stored in session. // Try to load user by uid stored in session.
@ -167,7 +183,7 @@ class SkinlibController extends Controller
$t->size = ceil($request->file('file')->getSize() / 1024); $t->size = ceil($request->file('file')->getSize() / 1024);
$t->public = ($request->input('public') == 'true') ? "1" : "0"; $t->public = ($request->input('public') == 'true') ? "1" : "0";
$t->uploader = $this->user->uid; $t->uploader = $this->user->uid;
$t->upload_at = Utils::getTimeFormatted(); $t->upload_at = get_datetime_string();
$cost = $t->size * (($t->public == "1") ? Option::get('score_per_storage') : Option::get('private_score_per_storage')); $cost = $t->size * (($t->public == "1") ? Option::get('score_per_storage') : Option::get('private_score_per_storage'));
$cost += option('score_per_closet_item'); $cost += option('score_per_closet_item');
@ -334,7 +350,7 @@ class SkinlibController extends Controller
{ {
if ($file = $request->files->get('file')) { if ($file = $request->files->get('file')) {
if ($file->getError() !== UPLOAD_ERR_OK) { if ($file->getError() !== UPLOAD_ERR_OK) {
return json(Utils::convertUploadFileError($file->getError()), $file->getError()); return json(static::$phpFileUploadErrors[$file->getError()], $file->getError());
} }
} }

View File

@ -5,7 +5,6 @@ namespace App\Http\Controllers;
use App; use App;
use Mail; use Mail;
use View; use View;
use Utils;
use Session; use Session;
use App\Models\User; use App\Models\User;
use App\Models\Texture; use App\Models\Texture;

View File

@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use Event; use Event;
use Utils;
use Response; use Response;
use App\Models\User; use App\Models\User;
use App\Events\GetPlayerJson; use App\Events\GetPlayerJson;
@ -98,7 +97,7 @@ class Player extends Model
} }
} }
$this->last_modified = Utils::getTimeFormatted(); $this->last_modified = get_datetime_string();
$this->save(); $this->save();
@ -159,7 +158,7 @@ class Player extends Model
{ {
$this->update([ $this->update([
'preference' => $type, 'preference' => $type,
'last_modified' => Utils::getTimeFormatted() 'last_modified' => get_datetime_string()
]); ]);
event(new PlayerProfileUpdated($this)); event(new PlayerProfileUpdated($this));
@ -187,7 +186,7 @@ class Player extends Model
{ {
$this->update([ $this->update([
'player_name' => $newName, 'player_name' => $newName,
'last_modified' => Utils::getTimeFormatted() 'last_modified' => get_datetime_string()
]); ]);
$this->player_name = $newName; $this->player_name = $newName;
@ -272,7 +271,7 @@ class Player extends Model
public function updateLastModified() public function updateLastModified()
{ {
// @see http://stackoverflow.com/questions/2215354/php-date-format-when-inserting-into-datetime-in-mysql // @see http://stackoverflow.com/questions/2215354/php-date-format-when-inserting-into-datetime-in-mysql
$this->update(['last_modified' => Utils::getTimeFormatted()]); $this->update(['last_modified' => get_datetime_string()]);
return event(new PlayerProfileUpdated($this)); return event(new PlayerProfileUpdated($this));
} }
} }

View File

@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use DB; use DB;
use Utils;
use Carbon\Carbon; use Carbon\Carbon;
use App\Events\EncryptUserPassword; use App\Events\EncryptUserPassword;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -301,7 +300,7 @@ class User extends Model
$acquiredScore = rand($scoreLimits[0], $scoreLimits[1]); $acquiredScore = rand($scoreLimits[0], $scoreLimits[1]);
$this->setScore($acquiredScore, 'plus'); $this->setScore($acquiredScore, 'plus');
$this->last_sign_at = Utils::getTimeFormatted(); $this->last_sign_at = get_datetime_string();
$this->save(); $this->save();
return $acquiredScore; return $acquiredScore;

View File

@ -4,7 +4,6 @@ namespace App\Providers;
use View; use View;
use Event; use Event;
use Utils;
use Parsedown; use Parsedown;
use App\Events; use App\Events;
use ReflectionException; use ReflectionException;
@ -62,7 +61,7 @@ class AppServiceProvider extends ServiceProvider
} }
} }
if (option('force_ssl') || Utils::isRequestSecure()) { if (option('force_ssl') || is_request_secure()) {
$this->app['url']->forceSchema('https'); $this->app['url']->forceSchema('https');
} }
} }

View File

@ -3,10 +3,6 @@
namespace App\Services; namespace App\Services;
use Log; use Log;
use Storage;
use Carbon\Carbon;
use Illuminate\Support\Str;
use App\Exceptions\PrettyPageException;
class Utils class Utils
{ {
@ -16,21 +12,12 @@ class Utils
* This method is defined because Symfony's Request::getClientIp() needs "setTrustedProxies()" * This method is defined because Symfony's Request::getClientIp() needs "setTrustedProxies()"
* which sucks when load balancer is enabled. * which sucks when load balancer is enabled.
* *
* @deprecated Use the helper function instead.
* @return string * @return string
*/ */
public static function getClientIp() public static function getClientIp()
{ {
if (option('ip_get_method') == "0") { return get_client_ip();
// Fallback to REMOTE_ADDR
$ip = array_get(
$_SERVER, 'HTTP_X_FORWARDED_FOR',
array_get($_SERVER, 'HTTP_CLIENT_IP', $_SERVER['REMOTE_ADDR'])
);
} else {
$ip = array_get($_SERVER, 'REMOTE_ADDR');
}
return $ip;
} }
/** /**
@ -40,20 +27,12 @@ class Utils
* This method is defined because Symfony's Request::isSecure() needs "setTrustedProxies()" * This method is defined because Symfony's Request::isSecure() needs "setTrustedProxies()"
* which sucks when load balancer is enabled. * which sucks when load balancer is enabled.
* *
* @deprecated Use the helper function instead.
* @return bool * @return bool
*/ */
public static function isRequestSecure() public static function isRequestSecure()
{ {
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') return is_request_secure();
return true;
if (! empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
return true;
if (! empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
return true;
return false;
} }
public static function download($url, $path) public static function download($url, $path)
@ -119,46 +98,29 @@ class Utils
return strlen(stream_get_contents($fp)); return strlen(stream_get_contents($fp));
} }
/**
* Get date time string in "Y-m-d H:i:s" format.
*
* @deprecated Use the helper function instead.
* @param integer $timestamp
* @return string
*/
public static function getTimeFormatted($timestamp = 0) public static function getTimeFormatted($timestamp = 0)
{ {
return ($timestamp == 0) ? Carbon::now()->toDateTimeString() : Carbon::createFromTimestamp($timestamp)->toDateTimeString(); return get_datetime_string($timestamp);
} }
/** /**
* Replace content of string according to given rules. * Replace content of string according to given rules.
* *
* @deprecated Use the helper function instead.
* @param string $str * @param string $str
* @param array $rules * @param array $rules
* @return string * @return string
*/ */
public static function getStringReplaced($str, $rules) public static function getStringReplaced($str, $rules)
{ {
foreach ($rules as $search => $replace) { return get_string_replaced($str, $rules);
$str = str_replace($search, $replace, $str);
}
return $str;
}
/**
* Convert error number of uploading files to human-readable text.
*
* @param int $errno
* @return string
*/
public static function convertUploadFileError($errno = 0)
{
$phpFileUploadErrors = [
0 => 'There is no error, the file uploaded with success',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
3 => 'The uploaded file was only partially uploaded',
4 => 'No file was uploaded',
6 => 'Missing a temporary folder',
7 => 'Failed to write file to disk.',
8 => 'A PHP extension stopped the file upload.',
];
return $phpFileUploadErrors[$errno];
} }
} }

View File

@ -258,7 +258,7 @@ if (! function_exists('bs_custom_copyright')) {
function bs_custom_copyright() function bs_custom_copyright()
{ {
return Utils::getStringReplaced(option_localized('copyright_text'), [ return get_string_replaced(option_localized('copyright_text'), [
'{site_name}' => option_localized('site_name'), '{site_name}' => option_localized('site_name'),
'{site_url}' => option('site_url') '{site_url}' => option('site_url')
]); ]);
@ -546,3 +546,88 @@ if (! function_exists('format_http_date')) {
return Carbon::createFromTimestampUTC($timestamp)->format('D, d M Y H:i:s \G\M\T'); return Carbon::createFromTimestampUTC($timestamp)->format('D, d M Y H:i:s \G\M\T');
} }
} }
if (! function_exists('get_datetime_string')) {
/**
* Get date time string in "Y-m-d H:i:s" format.
*
* @param integer $timestamp
* @return string
*/
function get_datetime_string($timestamp = 0) {
return $timestamp == 0 ? Carbon::now()->toDateTimeString() : Carbon::createFromTimestamp($timestamp)->toDateTimeString();
}
}
if (! function_exists('get_client_ip')) {
/**
* Return the client IP address.
*
* We define this function because Symfony's "Request::getClientIp()" method
* needs "setTrustedProxies()", which sucks when load balancer is enabled.
*
* @return string
*/
function get_client_ip() {
if (option('ip_get_method') == "0") {
// Use `HTTP_X_FORWARDED_FOR` if available first
$ip = array_get(
$_SERVER,
'HTTP_X_FORWARDED_FOR',
// Fallback to `HTTP_CLIENT_IP`
array_get(
$_SERVER,
'HTTP_CLIENT_IP',
// Fallback to `REMOTE_ADDR`
array_get($_SERVER, 'REMOTE_ADDR')
)
);
} else {
$ip = array_get($_SERVER, 'REMOTE_ADDR');
}
return $ip;
}
}
if (! function_exists('get_string_replaced')) {
/**
* Replace content of string according to given rules.
*
* @param string $str
* @param array $rules
* @return string
*/
function get_string_replaced($str, $rules)
{
foreach ($rules as $search => $replace) {
$str = str_replace($search, $replace, $str);
}
return $str;
}
}
if (! function_exists('is_request_secure')) {
/**
* Check whether the request is secure or not.
* True is always returned when "X-Forwarded-Proto" header is set.
*
* We define this function because Symfony's "Request::isSecure()" method
* needs "setTrustedProxies()" which sucks when load balancer is enabled.
*
* @return bool
*/
function is_request_secure()
{
if (array_get($_SERVER, 'HTTPS') == 'on')
return true;
if (array_get($_SERVER, 'HTTP_X_FORWARDED_PROTO') == 'https')
return true;
if (array_get($_SERVER, 'HTTP_X_FORWARDED_SSL') == 'on')
return true;
return false;
}
}

View File

@ -41,7 +41,7 @@
<tr> <tr>
<td class="key">{{ trans('admin.update.info.release-time') }}</td> <td class="key">{{ trans('admin.update.info.release-time') }}</td>
<td class="value"> <td class="value">
{{ Utils::getTimeFormatted($info['release_time']) }} {{ get_datetime_string($info['release_time']) }}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -77,7 +77,7 @@
<td class="key">{{ trans('admin.update.info.release-time') }}</td> <td class="key">{{ trans('admin.update.info.release-time') }}</td>
<td class="value"> <td class="value">
@if ($info['release_time']) @if ($info['release_time'])
{{ Utils::getTimeFormatted($info['release_time']) }} {{ get_datetime_string($info['release_time']) }}
@else @else
{{ trans('admin.update.info.pre-release') }} {{ trans('admin.update.info.pre-release') }}
@endif @endif

View File

@ -42,7 +42,7 @@
<a href="{{ url('auth/login') }}" class="text-center">{{ trans('auth.forgot.login-link') }}</a> <a href="{{ url('auth/login') }}" class="text-center">{{ trans('auth.forgot.login-link') }}</a>
</div> </div>
<!-- /.col --> <!-- /.col -->
<?php $remain = 180 + Cache::get(sha1('last_mail_'.Utils::getClientIp()), 0) - time(); ?> <?php $remain = 180 + Cache::get(sha1('last_mail_'.get_client_ip()), 0) - time(); ?>
<div class="col-xs-4"> <div class="col-xs-4">
<button id="forgot-button" class="btn btn-primary btn-block btn-flat" data-remain="{{ $remain }}"> <button id="forgot-button" class="btn btn-primary btn-block btn-flat" data-remain="{{ $remain }}">
{{ trans('auth.forgot.button') }} {{ trans('auth.forgot.button') }}

View File

@ -26,7 +26,7 @@
<span class="glyphicon glyphicon-lock form-control-feedback"></span> <span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div> </div>
<div class="row" id="captcha-form" style="{{ (Cache::get(sha1('login_fails_'.Utils::getClientIp())) > 3) ? '' : 'display: none;' }}"> <div class="row" id="captcha-form" style="{{ (Cache::get(sha1('login_fails_'.get_client_ip())) > 3) ? '' : 'display: none;' }}">
<div class="col-xs-8"> <div class="col-xs-8">
<div class="form-group has-feedback"> <div class="form-group has-feedback">
<input id="captcha" type="text" class="form-control" placeholder="{{ trans('auth.captcha') }}"> <input id="captcha" type="text" class="form-control" placeholder="{{ trans('auth.captcha') }}">

View File

@ -120,7 +120,7 @@
<div class="box-body"> <div class="box-body">
@if (option('comment_script') != "") @if (option('comment_script') != "")
<!-- Comment Start --> <!-- Comment Start -->
{!! Utils::getStringReplaced(option('comment_script'), ['{tid}' => $texture->tid, '{name}' => $texture->name, '{url}' => get_current_url()]) !!} {!! get_string_replaced(option('comment_script'), ['{tid}' => $texture->tid, '{name}' => $texture->name, '{url}' => get_current_url()]) !!}
<!-- Comment End --> <!-- Comment End -->
@else @else
<p style="text-align: center; margin: 30px 0;">{{ trans('skinlib.show.comment-not-available') }}</p> <p style="text-align: center; margin: 30px 0;">{{ trans('skinlib.show.comment-not-available') }}</p>

View File

@ -76,7 +76,7 @@ class AuthControllerTest extends TestCase
$this->flushSession(); $this->flushSession();
$loginFailsCacheKey = sha1('login_fails_'.Utils::getClientIp()); $loginFailsCacheKey = sha1('login_fails_'.get_client_ip());
// Logging in should be failed if password is wrong // Logging in should be failed if password is wrong
$this->post( $this->post(
@ -477,7 +477,7 @@ class AuthControllerTest extends TestCase
]); ]);
config(['mail.driver' => 'smtp']); config(['mail.driver' => 'smtp']);
$lastMailCacheKey = sha1('last_mail_'.Utils::getClientIp()); $lastMailCacheKey = sha1('last_mail_'.get_client_ip());
// Should be forbidden if sending email frequently // Should be forbidden if sending email frequently
$this->withCache([ $this->withCache([

View File

@ -1,7 +1,6 @@
<?php <?php
use App\Models\User; use App\Models\User;
use App\Services\Utils;
use Illuminate\Foundation\Testing\WithoutMiddleware; use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
@ -13,7 +12,7 @@ class UserTest extends TestCase
public function testSign() public function testSign()
{ {
$user = factory(User::class)->make([ $user = factory(User::class)->make([
'last_sign_at' => Utils::getTimeFormatted(time()) 'last_sign_at' => get_datetime_string(time())
]); ]);
$user->sign(); $user->sign();
$this->assertFalse($user->sign()); $this->assertFalse($user->sign());

View File

@ -4,7 +4,6 @@ use App\Models\User;
use App\Models\Closet; use App\Models\Closet;
use App\Models\Player; use App\Models\Player;
use App\Models\Texture; use App\Models\Texture;
use App\Services\Utils;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
use Illuminate\Foundation\Testing\WithoutMiddleware; use Illuminate\Foundation\Testing\WithoutMiddleware;
@ -418,7 +417,7 @@ class SkinlibControllerTest extends TestCase
->getContent(); ->getContent();
$this->seeJson([ $this->seeJson([
'errno' => UPLOAD_ERR_NO_TMP_DIR, 'errno' => UPLOAD_ERR_NO_TMP_DIR,
'msg' => Utils::convertUploadFileError(UPLOAD_ERR_NO_TMP_DIR) 'msg' => App\Http\Controllers\SkinlibController::$phpFileUploadErrors[UPLOAD_ERR_NO_TMP_DIR]
]); ]);
// Without `name` field // Without `name` field