2021-04-19 20:13:21 +08:00
< ? php
namespace App\Repositories ;
2021-04-28 01:22:25 +08:00
use App\Exceptions\NexusException ;
2021-04-19 20:13:21 +08:00
use App\Models\Exam ;
2021-04-25 21:28:58 +08:00
use App\Models\ExamProgress ;
2021-04-25 02:12:14 +08:00
use App\Models\ExamUser ;
2021-04-28 19:44:48 +08:00
use App\Models\Message ;
2021-04-19 20:13:21 +08:00
use App\Models\Setting ;
2021-04-25 21:28:58 +08:00
use App\Models\Torrent ;
2021-04-19 20:13:21 +08:00
use App\Models\User ;
2021-04-20 20:18:02 +08:00
use Carbon\Carbon ;
2021-04-28 19:44:48 +08:00
use Illuminate\Database\Query\JoinClause ;
2021-04-23 20:05:39 +08:00
use Illuminate\Support\Arr ;
2021-04-27 19:13:32 +08:00
use Illuminate\Support\Facades\DB ;
2021-04-19 20:13:21 +08:00
class ExamRepository extends BaseRepository
{
public function getList ( array $params )
{
$query = Exam :: query ();
list ( $sortField , $sortType ) = $this -> getSortFieldAndType ( $params );
$query -> orderBy ( $sortField , $sortType );
return $query -> paginate ();
}
public function store ( array $params )
{
2021-04-25 02:12:14 +08:00
$this -> checkIndexes ( $params );
2021-05-02 17:24:05 +08:00
$valid = $this -> listValid ( null , Exam :: DISCOVERED_YES );
2021-04-29 02:52:22 +08:00
if ( $valid -> isNotEmpty () && $params [ 'status' ] == Exam :: STATUS_ENABLED ) {
2021-05-02 17:24:05 +08:00
throw new NexusException ( " Enabled and discovered exam already exists. " );
2021-04-28 19:44:48 +08:00
}
2021-04-19 20:13:21 +08:00
$exam = Exam :: query () -> create ( $params );
return $exam ;
}
public function update ( array $params , $id )
{
2021-04-25 02:12:14 +08:00
$this -> checkIndexes ( $params );
2021-05-02 17:24:05 +08:00
$valid = $this -> listValid ( $id , Exam :: DISCOVERED_YES );
2021-04-29 02:52:22 +08:00
if ( $valid -> isNotEmpty () && $params [ 'status' ] == Exam :: STATUS_ENABLED ) {
2021-05-02 17:24:05 +08:00
throw new NexusException ( " Enabled and discovered exam already exists. " );
2021-04-28 19:44:48 +08:00
}
2021-04-19 20:13:21 +08:00
$exam = Exam :: query () -> findOrFail ( $id );
$exam -> update ( $params );
return $exam ;
}
2021-04-25 02:12:14 +08:00
private function checkIndexes ( array $params )
{
if ( empty ( $params [ 'indexes' ])) {
throw new \InvalidArgumentException ( " Require index. " );
}
2021-05-02 17:24:05 +08:00
$validIndex = [];
foreach ( $params [ 'indexes' ] as $index ) {
if ( ! isset ( $index [ 'checked' ]) || ! $index [ 'checked' ]) {
continue ;
}
if ( ! isset ( $index [ 'require_value' ]) || ! ctype_digit (( string ) $index [ 'require_value' ])) {
throw new \InvalidArgumentException ( sprintf (
'Invalid require value for index: %s.' , $index [ 'name' ]
));
}
$validIndex [] = $index ;
}
2021-04-25 02:12:14 +08:00
if ( empty ( $validIndex )) {
throw new \InvalidArgumentException ( " Require valid index. " );
}
return true ;
}
2021-04-23 20:05:39 +08:00
public function getDetail ( $id )
{
$exam = Exam :: query () -> findOrFail ( $id );
return $exam ;
}
2021-04-25 02:12:14 +08:00
public function delete ( $id )
2021-04-20 20:18:02 +08:00
{
2021-04-25 02:12:14 +08:00
$exam = Exam :: query () -> findOrFail ( $id );
$result = $exam -> delete ();
return $result ;
2021-04-23 20:05:39 +08:00
}
2021-04-25 02:12:14 +08:00
public function listIndexes ()
2021-04-23 20:05:39 +08:00
{
$out = [];
2021-04-25 02:12:14 +08:00
foreach ( Exam :: $indexes as $key => $value ) {
$value [ 'index' ] = $key ;
2021-04-23 20:05:39 +08:00
$out [] = $value ;
2021-04-20 20:18:02 +08:00
}
return $out ;
}
2021-04-21 01:13:24 +08:00
/**
2021-04-25 02:12:14 +08:00
* list valid exams
2021-04-21 01:13:24 +08:00
*
2021-04-28 19:44:48 +08:00
* @ param null $excludeId
2021-04-25 02:12:14 +08:00
* @ return \Illuminate\Database\Eloquent\Builder [] | \Illuminate\Database\Eloquent\Collection
2021-04-21 01:13:24 +08:00
*/
2021-05-02 17:24:05 +08:00
public function listValid ( $excludeId = null , $isDiscovered = null )
2021-04-20 20:18:02 +08:00
{
$now = Carbon :: now ();
2021-04-28 19:44:48 +08:00
$query = Exam :: query ()
2021-04-20 20:18:02 +08:00
-> where ( 'status' , Exam :: STATUS_ENABLED )
2021-05-06 01:49:05 +08:00
-> whereRaw ( " if(begin is not null and end is not null, begin <= ' $now ' and end >= ' $now ', duration > 0) " )
2021-04-28 19:44:48 +08:00
-> orderBy ( 'id' , 'desc' );
2021-05-02 17:24:05 +08:00
if ( ! is_null ( $excludeId )) {
2021-04-28 19:44:48 +08:00
$query -> whereNotIn ( 'id' , Arr :: wrap ( $excludeId ));
}
2021-05-02 17:24:05 +08:00
if ( ! is_null ( $isDiscovered )) {
$query -> where ( 'is_discovered' , $isDiscovered );
}
2021-04-28 19:44:48 +08:00
return $query -> get ();
2021-04-25 02:12:14 +08:00
}
/**
* list user match exams
*
* @ param $uid
* @ return \Illuminate\Database\Eloquent\Builder [] | \Illuminate\Database\Eloquent\Collection
*/
public function listMatchExam ( $uid )
{
2021-04-20 20:18:02 +08:00
$logPrefix = " uid: $uid " ;
2021-04-25 02:12:14 +08:00
$exams = $this -> listValid ();
if ( $exams -> isEmpty ()) {
2021-04-26 20:37:17 +08:00
do_log ( " $logPrefix , no valid exam. " );
2021-04-25 02:12:14 +08:00
return $exams ;
}
2021-04-28 19:44:48 +08:00
$matched = $exams -> filter ( function ( Exam $exam ) use ( $uid , $logPrefix ) {
return $this -> isExamMatchUser ( $exam , $uid );
});
2021-04-25 02:12:14 +08:00
2021-04-28 19:44:48 +08:00
return $matched ;
}
2021-04-25 02:12:14 +08:00
2021-04-28 19:44:48 +08:00
private function isExamMatchUser ( Exam $exam , $user )
{
if ( ! $user instanceof User ) {
$user = User :: query () -> findOrFail ( intval ( $user ), [ 'id' , 'username' , 'added' , 'class' ]);
}
$logPrefix = sprintf ( 'exam: %s, user: %s' , $exam -> id , $user -> id );
$filters = $exam -> filters ;
if ( empty ( $filters -> classes )) {
do_log ( " $logPrefix , exam: { $exam -> id } no class " );
return false ;
}
if ( ! in_array ( $user -> class , $filters -> classes )) {
do_log ( " $logPrefix , user class: { $user -> class } not in: " . json_encode ( $filters ));
return false ;
}
if ( ! $user -> added ) {
do_log ( " $logPrefix , user no added time " , 'warning' );
return false ;
}
2021-04-25 02:12:14 +08:00
2021-04-28 19:44:48 +08:00
$added = $user -> added -> toDateTimeString ();
2021-04-30 01:27:29 +08:00
$registerTimeBegin = isset ( $filters -> register_time_range [ 0 ]) ? Carbon :: parse ( $filters -> register_time_range [ 0 ]) -> toDateString () : '' ;
$registerTimeEnd = isset ( $filters -> register_time_range [ 1 ]) ? Carbon :: parse ( $filters -> register_time_range [ 1 ]) -> toDateString () : '' ;
2021-04-28 19:44:48 +08:00
if ( empty ( $registerTimeBegin )) {
do_log ( " $logPrefix , exam: { $exam -> id } no register_time_begin " );
return false ;
}
if ( $added < $registerTimeBegin ) {
2021-04-29 19:18:13 +08:00
do_log ( " $logPrefix , user added: $added not after: " . $registerTimeBegin );
2021-04-28 19:44:48 +08:00
return false ;
}
2021-04-25 02:12:14 +08:00
2021-04-28 19:44:48 +08:00
if ( empty ( $registerTimeEnd )) {
do_log ( " $logPrefix , exam: { $exam -> id } no register_time_end " );
return false ;
}
if ( $added > $registerTimeEnd ) {
2021-04-29 19:18:13 +08:00
do_log ( " $logPrefix , user added: $added not before: " . $registerTimeEnd );
2021-04-28 19:44:48 +08:00
return false ;
}
return true ;
2021-04-25 02:12:14 +08:00
}
2021-04-25 21:28:58 +08:00
2021-04-25 02:12:14 +08:00
/**
* assign exam to user
*
2021-04-27 19:13:32 +08:00
* @ param int $uid
2021-05-02 17:24:05 +08:00
* @ param int $examId
2021-04-26 20:37:17 +08:00
* @ param null $begin
* @ param null $end
2021-04-25 02:12:14 +08:00
* @ return mixed
*/
2021-05-02 17:24:05 +08:00
public function assignToUser ( int $uid , int $examId , $begin = null , $end = null )
2021-04-25 02:12:14 +08:00
{
2021-04-26 20:37:17 +08:00
$logPrefix = " uid: $uid , examId: $examId , begin: $begin , end: $end " ;
2021-05-02 17:24:05 +08:00
$exam = Exam :: query () -> find ( $examId );
2021-04-25 02:12:14 +08:00
$user = User :: query () -> findOrFail ( $uid );
2021-04-29 19:18:13 +08:00
if ( ! $this -> isExamMatchUser ( $exam , $user )) {
throw new NexusException ( " Exam: { $exam -> id } no match this user. " );
}
2021-04-29 02:52:22 +08:00
if ( $user -> exams () -> where ( 'status' , ExamUser :: STATUS_NORMAL ) -> exists ()) {
throw new NexusException ( " User: $uid already has exam on the way. " );
}
2021-04-25 02:12:14 +08:00
$exists = $user -> exams () -> where ( 'exam_id' , $exam -> id ) -> exists ();
if ( $exists ) {
2021-04-29 02:52:22 +08:00
throw new NexusException ( " Exam: { $exam -> id } already assign to user: { $user -> id } . " );
2021-04-20 20:18:02 +08:00
}
2021-04-26 20:37:17 +08:00
$data = [
'exam_id' => $exam -> id ,
];
if ( $begin && $end ) {
$logPrefix .= " , specific begin and end " ;
$data [ 'begin' ] = $begin ;
$data [ 'end' ] = $end ;
}
do_log ( " $logPrefix , data: " . nexus_json_encode ( $data ));
$result = $user -> exams () -> create ( $data );
2021-04-20 20:18:02 +08:00
return $result ;
}
2021-04-25 02:12:14 +08:00
public function listUser ( array $params )
{
$query = ExamUser :: query ();
if ( ! empty ( $params [ 'uid' ])) {
$query -> where ( 'uid' , $params [ 'uid' ]);
}
if ( ! empty ( $params [ 'exam_id' ])) {
$query -> where ( 'exam_id' , $params [ 'exam_id' ]);
}
list ( $sortField , $sortType ) = $this -> getSortFieldAndType ( $params );
$query -> orderBy ( $sortField , $sortType );
$result = $query -> with ([ 'user' , 'exam' ]) -> paginate ();
return $result ;
}
2021-04-29 02:52:22 +08:00
public function addProgress ( int $uid , int $torrentId , array $indexAndValue )
2021-04-25 21:28:58 +08:00
{
2021-04-29 02:52:22 +08:00
$logPrefix = " uid: $uid , torrentId: $torrentId , indexAndValue: " . json_encode ( $indexAndValue );
do_log ( $logPrefix );
$user = User :: query () -> findOrFail ( $uid );
$user -> checkIsNormal ();
$now = Carbon :: now () -> toDateTimeString ();
$examUser = $user -> exams () -> where ( 'status' , ExamUser :: STATUS_NORMAL ) -> orderBy ( 'id' , 'desc' ) -> first ();
if ( ! $examUser ) {
do_log ( " no exam is on the way, " . last_query ());
return false ;
2021-04-25 21:28:58 +08:00
}
$exam = $examUser -> exam ;
2021-04-29 02:52:22 +08:00
if ( ! $exam ) {
throw new NexusException ( " exam: { $examUser -> exam_id } not exists. " );
2021-04-25 21:28:58 +08:00
}
2021-05-06 01:49:05 +08:00
$begin = $examUser -> begin ;
$end = $examUser -> end ;
if ( ! $begin || ! $end ) {
do_log ( sprintf ( " no begin or end, examUser: %s " , $examUser -> toJson ()));
return false ;
}
2021-04-29 02:52:22 +08:00
if ( $now < $begin || $now > $end ) {
do_log ( sprintf ( " now: %s, not in exam time range: %s ~ %s " , $now , $begin , $end ));
return false ;
2021-04-25 21:28:58 +08:00
}
2021-04-29 02:52:22 +08:00
$indexes = collect ( $exam -> indexes ) -> keyBy ( 'index' );
do_log ( " examUser: " . $examUser -> toJson () . " , indexes: " . $indexes -> toJson ());
2021-05-05 22:28:19 +08:00
if ( ! isset ( $indexAndValue [ Exam :: INDEX_SEED_BONUS ])) {
//seed bonus is relative to user all torrents, not single one, torrentId = 0
$torrentFields = [ 'id' , 'visible' , 'banned' ];
$torrent = Torrent :: query () -> findOrFail ( $torrentId , $torrentFields );
$torrent -> checkIsNormal ( $torrentFields );
}
2021-04-25 21:28:58 +08:00
2021-04-29 02:52:22 +08:00
$insert = [];
foreach ( $indexAndValue as $indexId => $value ) {
if ( ! $indexes -> has ( $indexId )) {
do_log ( sprintf ( 'Exam: %s does not has index: %s.' , $exam -> id , $indexId ));
continue ;
}
$indexInfo = $indexes -> get ( $indexId );
if ( ! isset ( $indexInfo [ 'checked' ]) || ! $indexInfo [ 'checked' ]) {
do_log ( sprintf ( 'Exam: %s index: %s is not checked.' , $exam -> id , $indexId ));
continue ;
}
$insert [] = [
'exam_user_id' => $examUser -> id ,
'uid' => $user -> id ,
'exam_id' => $exam -> id ,
'torrent_id' => $torrentId ,
'index' => $indexId ,
'value' => $value ,
'created_at' => $now ,
'updated_at' => $now ,
];
}
if ( empty ( $insert )) {
do_log ( " no progress to insert. " );
return false ;
}
ExamProgress :: query () -> insert ( $insert );
do_log ( " [addProgress] " . nexus_json_encode ( $insert ));
2021-04-25 21:28:58 +08:00
2021-04-27 02:44:44 +08:00
$examProgress = $this -> calculateProgress ( $examUser );
2021-04-28 19:44:48 +08:00
$examProgressFormatted = $this -> getProgressFormatted ( $exam , $examProgress );
$examNotPassed = array_filter ( $examProgressFormatted , function ( $item ) {
return ! $item [ 'passed' ];
});
$update = [
'progress' => $examProgress ,
'is_done' => count ( $examNotPassed ) ? ExamUser :: IS_DONE_NO : ExamUser :: IS_DONE_YES ,
];
2021-04-29 02:52:22 +08:00
do_log ( " [updateProgress] " . nexus_json_encode ( $update ));
2021-04-28 19:44:48 +08:00
$examUser -> update ( $update );
2021-04-29 02:52:22 +08:00
return true ;
2021-04-25 21:28:58 +08:00
}
2021-04-27 19:13:32 +08:00
public function getUserExamProgress ( $uid , $status = null , $with = [ 'exam' , 'user' ])
2021-04-25 21:28:58 +08:00
{
$logPrefix = " uid: $uid " ;
2021-04-27 19:13:32 +08:00
$query = ExamUser :: query () -> where ( 'uid' , $uid ) -> orderBy ( 'exam_id' , 'desc' );
2021-04-28 19:44:48 +08:00
if ( ! is_null ( $status )) {
2021-04-25 21:28:58 +08:00
$query -> where ( 'status' , $status );
}
2021-04-27 19:13:32 +08:00
if ( ! empty ( $with )) {
$query -> with ( $with );
}
2021-04-26 20:37:17 +08:00
$examUsers = $query -> get ();
if ( $examUsers -> isEmpty ()) {
return null ;
2021-04-25 21:28:58 +08:00
}
2021-04-26 20:37:17 +08:00
if ( $examUsers -> count () > 1 ) {
do_log ( " $logPrefix , user exam more than 1. " , 'warning' );
2021-04-25 21:28:58 +08:00
}
2021-04-26 20:37:17 +08:00
$examUser = $examUsers -> first ();
2021-04-27 19:13:32 +08:00
$exam = $examUser -> exam ;
2021-04-27 02:44:44 +08:00
$progress = $this -> calculateProgress ( $examUser );
do_log ( " $logPrefix , progress: " . nexus_json_encode ( $progress ));
$examUser -> progress = $progress ;
2021-04-27 19:13:32 +08:00
$examUser -> progress_formatted = $this -> getProgressFormatted ( $exam , $progress );
2021-04-27 02:44:44 +08:00
return $examUser ;
}
private function calculateProgress ( ExamUser $examUser )
{
2021-04-29 02:52:22 +08:00
$logPrefix = " examUser: " . $examUser -> id ;
2021-05-06 01:49:05 +08:00
$begin = $examUser -> begin ;
$end = $examUser -> end ;
if ( ! $begin ) {
2021-04-26 20:37:17 +08:00
do_log ( " $logPrefix , no begin " );
return null ;
}
2021-05-06 01:49:05 +08:00
if ( ! $end ) {
2021-04-26 20:37:17 +08:00
do_log ( " $logPrefix , no end " );
return null ;
}
$progressSum = $examUser -> progresses ()
-> where ( 'created_at' , '>=' , $begin )
-> where ( 'created_at' , '<=' , $end )
-> selectRaw ( " `index`, sum(`value`) as sum " )
-> groupBy ([ 'index' ])
2021-04-29 02:52:22 +08:00
-> get ()
-> pluck ( 'sum' , 'index' )
-> toArray ();
$logPrefix .= " , progressSum raw: " . json_encode ( $progressSum ) . " , query: " . last_query ();
$index = Exam :: INDEX_SEED_TIME_AVERAGE ;
if ( isset ( $progressSum [ $index ])) {
$torrentCount = $examUser -> progresses ()
-> where ( 'index' , $index )
-> selectRaw ( 'count(distinct(torrent_id)) as torrent_count' )
-> first ()
-> torrent_count ;
$progressSum [ $index ] = intval ( $progressSum [ $index ] / $torrentCount );
$logPrefix .= " , get torrent count: $torrentCount , from query: " . last_query ();
}
2021-04-25 21:28:58 +08:00
2021-04-29 02:52:22 +08:00
do_log ( " $logPrefix , final progressSum: " . json_encode ( $progressSum ));
2021-04-27 02:44:44 +08:00
2021-04-29 02:52:22 +08:00
return $progressSum ;
2021-04-27 02:44:44 +08:00
2021-04-25 21:28:58 +08:00
}
2021-04-27 19:13:32 +08:00
private function getProgressFormatted ( Exam $exam , array $progress , $locale = null )
{
$result = [];
foreach ( $exam -> indexes as $key => $index ) {
if ( ! isset ( $index [ 'checked' ]) || ! $index [ 'checked' ]) {
continue ;
}
$currentValue = $progress [ $index [ 'index' ]] ? ? 0 ;
$requireValue = $index [ 'require_value' ];
switch ( $index [ 'index' ]) {
case Exam :: INDEX_UPLOADED :
case Exam :: INDEX_DOWNLOADED :
$currentValueFormatted = mksize ( $currentValue );
$requireValueAtomic = $requireValue * 1024 * 1024 * 1024 ;
break ;
case Exam :: INDEX_SEED_TIME_AVERAGE :
2021-04-29 19:18:13 +08:00
$currentValueFormatted = number_format ( $currentValue / 3600 , 2 ) . " { $index [ 'unit' ] } " ;
2021-04-27 19:13:32 +08:00
$requireValueAtomic = $requireValue * 3600 ;
break ;
default :
$currentValueFormatted = $currentValue ;
$requireValueAtomic = $requireValue ;
}
2021-05-02 17:24:05 +08:00
$index [ 'name' ] = Exam :: $indexes [ $index [ 'index' ]][ 'name' ] ? ? '' ;
2021-04-28 19:44:48 +08:00
$index [ 'index_formatted' ] = nexus_trans ( 'exam.index_text_' . $index [ 'index' ]);
$index [ 'require_value_formatted' ] = " $requireValue " . ( $index [ 'unit' ] ? ? '' );
2021-04-27 19:13:32 +08:00
$index [ 'current_value' ] = $currentValue ;
$index [ 'current_value_formatted' ] = $currentValueFormatted ;
$index [ 'passed' ] = $currentValue >= $requireValueAtomic ;
$result [] = $index ;
}
return $result ;
}
public function removeExamUser ( int $examUserId )
{
$examUser = ExamUser :: query () -> findOrFail ( $examUserId );
$result = DB :: transaction ( function () use ( $examUser ) {
$examUser -> progresses () -> delete ();
return $examUser -> delete ();
});
return $result ;
}
2021-04-28 19:44:48 +08:00
public function cronjonAssign ()
{
2021-05-02 17:24:05 +08:00
$exams = $this -> listValid ( null , Exam :: DISCOVERED_YES );
2021-04-28 19:44:48 +08:00
if ( $exams -> isEmpty ()) {
2021-05-02 17:24:05 +08:00
do_log ( " No valid and discovered exam. " );
2021-04-29 19:18:13 +08:00
return false ;
2021-04-28 19:44:48 +08:00
}
if ( $exams -> count () > 1 ) {
2021-05-02 17:24:05 +08:00
do_log ( " Valid and discovered exam more than 1. " , " warning " );
2021-04-28 19:44:48 +08:00
}
/** @var Exam $exam */
$exam = $exams -> first ();
$userTable = ( new User ()) -> getTable ();
$examUserTable = ( new ExamUser ()) -> getTable ();
2021-04-29 19:18:13 +08:00
$baseQuery = User :: query ()
2021-04-28 19:44:48 +08:00
-> leftJoin ( $examUserTable , function ( JoinClause $join ) use ( $examUserTable , $userTable ) {
$join -> on ( " $userTable .id " , " = " , " $examUserTable .uid " )
-> on ( " $examUserTable .status " , " = " , DB :: raw ( ExamUser :: STATUS_NORMAL ));
})
-> whereRaw ( " $examUserTable .id is null " )
-> selectRaw ( " $userTable .* " )
2021-04-29 19:18:13 +08:00
-> orderBy ( " $userTable .id " , " asc " );
$size = 100 ;
$minId = 0 ;
$result = 0 ;
while ( true ) {
$logPrefix = sprintf ( '[%s], exam: %s, size: %s' , __FUNCTION__ , $exam -> id , $size );
$users = ( clone $baseQuery ) -> where ( " $userTable .id " , " > " , $minId ) -> limit ( $size ) -> get ();
if ( $users -> isEmpty ()) {
do_log ( " $logPrefix , no more data... " . last_query ());
break ;
}
$insert = [];
$now = Carbon :: now () -> toDateTimeString ();
foreach ( $users as $user ) {
$minId = $user -> id ;
$currentLogPrefix = sprintf ( " $logPrefix , user: %s " , $user -> id );
if ( ! $this -> isExamMatchUser ( $exam , $user )) {
do_log ( " $currentLogPrefix , exam not match this user. " );
continue ;
2021-04-28 19:44:48 +08:00
}
2021-04-29 19:18:13 +08:00
$insert [] = [
'uid' => $user -> id ,
'exam_id' => $exam -> id ,
'created_at' => $now ,
'updated_at' => $now ,
];
do_log ( " $currentLogPrefix , exam will be assigned to this user. " );
}
if ( ! empty ( $insert )) {
$result += count ( $insert );
2021-04-28 19:44:48 +08:00
ExamUser :: query () -> insert ( $insert );
2021-04-29 19:18:13 +08:00
}
}
return $result ;
2021-04-28 19:44:48 +08:00
}
2021-04-29 19:18:13 +08:00
public function cronjobCheckout ( $ignoreTimeRange = false )
2021-04-28 19:44:48 +08:00
{
$now = Carbon :: now () -> toDateTimeString ();
$examUserTable = ( new ExamUser ()) -> getTable ();
$examTable = ( new Exam ()) -> getTable ();
2021-04-29 19:18:13 +08:00
$baseQuery = ExamUser :: query ()
2021-04-28 19:44:48 +08:00
-> join ( $examTable , " $examUserTable .exam_id " , " = " , " $examTable .id " )
-> where ( " $examUserTable .status " , ExamUser :: STATUS_NORMAL )
-> selectRaw ( " $examUserTable .* " )
-> with ([ 'exam' , 'user' , 'user.language' ])
-> orderBy ( " $examUserTable .id " , " asc " );
2021-04-29 19:18:13 +08:00
if ( ! $ignoreTimeRange ) {
2021-05-06 01:49:05 +08:00
// $baseQuery->whereRaw("if($examUserTable.end is not null, $examUserTable.end < '$now', $examTable.end < '$now')");
$baseQuery -> whereRaw ( " case when $examUserTable .end is not null then $examUserTable .end < ' $now ' case when $examTable .end is not null then $examTable .end < ' $now ' case when $examTable .duration > 0 then date_add( $examUserTable .created_at, interval $examTable .duration day) < ' $now ' else true end " );
2021-04-29 19:18:13 +08:00
}
2021-04-28 19:44:48 +08:00
2021-04-29 19:18:13 +08:00
$size = 100 ;
$minId = 0 ;
$result = 0 ;
2021-04-28 19:44:48 +08:00
while ( true ) {
2021-04-29 19:18:13 +08:00
$logPrefix = sprintf ( '[%s], size: %s' , __FUNCTION__ , $size );
$examUsers = ( clone $baseQuery ) -> where ( " $examUserTable .id " , " > " , $minId ) -> limit ( $size ) -> get ();
2021-04-28 19:44:48 +08:00
if ( $examUsers -> isEmpty ()) {
do_log ( " $logPrefix , no more data... " . last_query ());
break ;
} else {
2021-04-29 19:18:13 +08:00
do_log ( " $logPrefix , fetch exam users: { $examUsers -> count () } " );
2021-04-28 19:44:48 +08:00
}
2021-04-29 19:18:13 +08:00
$result += $examUsers -> count ();
2021-04-28 19:44:48 +08:00
$now = Carbon :: now () -> toDateTimeString ();
2021-04-29 19:18:13 +08:00
$examUserIdArr = $uidToDisable = $messageToSend = [];
2021-04-28 19:44:48 +08:00
foreach ( $examUsers as $examUser ) {
2021-04-29 19:18:13 +08:00
$minId = $examUser -> id ;
$examUserIdArr [] = $examUser -> id ;
2021-04-28 19:44:48 +08:00
$uid = $examUser -> uid ;
$currentLogPrefix = sprintf ( " $logPrefix , user: %s, exam: %s, examUser: %s " , $uid , $examUser -> exam_id , $examUser -> id );
2021-04-29 19:18:13 +08:00
$locale = $examUser -> user -> locale ;
2021-04-28 19:44:48 +08:00
if ( $examUser -> is_done ) {
do_log ( " $currentLogPrefix , [is_done] " );
2021-04-29 19:18:13 +08:00
$subjectTransKey = 'exam.checkout_pass_message_subject' ;
$msgTransKey = 'exam.checkout_pass_message_content' ;
2021-04-28 19:44:48 +08:00
} else {
do_log ( " $currentLogPrefix , [will be banned] " );
2021-04-29 19:18:13 +08:00
$subjectTransKey = 'exam.checkout_not_pass_message_subject' ;
$msgTransKey = 'exam.checkout_not_pass_message_content' ;
2021-04-28 19:44:48 +08:00
//ban user
$uidToDisable [] = $uid ;
}
2021-04-29 19:18:13 +08:00
$subject = nexus_trans ( $subjectTransKey , [], $locale );
$msg = nexus_trans ( $msgTransKey , [
'exam_name' => $examUser -> exam -> name ,
'begin' => $examUser -> begin ,
'end' => $examUser -> end
], $locale );
$messageToSend [] = [
'receiver' => $uid ,
'added' => $now ,
'subject' => $subject ,
'msg' => $msg
];
2021-04-28 19:44:48 +08:00
}
2021-04-29 19:18:13 +08:00
DB :: transaction ( function () use ( $uidToDisable , $messageToSend , $examUserIdArr ) {
ExamUser :: query () -> whereIn ( 'id' , $examUserIdArr ) -> update ([ 'status' => ExamUser :: STATUS_FINISHED ]);
2021-04-28 19:44:48 +08:00
Message :: query () -> insert ( $messageToSend );
if ( ! empty ( $uidToDisable )) {
User :: query () -> whereIn ( 'id' , $uidToDisable ) -> update ([ 'enabled' => User :: ENABLED_NO ]);
}
});
}
2021-04-29 19:18:13 +08:00
return $result ;
2021-04-28 19:44:48 +08:00
}
2021-04-25 02:12:14 +08:00
2021-04-20 20:18:02 +08:00
2021-04-19 20:13:21 +08:00
}