2018-04-29 14:20:06 -05:00
< ? php
/**
* JobStatusController . php
* Copyright ( c ) 2017 thegrumpydictator @ gmail . com
*
* This file is part of Firefly III .
*
* Firefly III is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Firefly III is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Firefly III . If not , see < http :// www . gnu . org / licenses />.
*/
declare ( strict_types = 1 );
namespace FireflyIII\Http\Controllers\Import ;
2018-05-03 10:23:16 -05:00
use Exception ;
2018-04-29 14:20:06 -05:00
use FireflyIII\Exceptions\FireflyException ;
use FireflyIII\Http\Controllers\Controller ;
use FireflyIII\Http\Middleware\IsDemoUser ;
use FireflyIII\Import\Routine\RoutineInterface ;
2018-05-03 10:23:16 -05:00
use FireflyIII\Import\Storage\ImportArrayStorage ;
2018-04-29 14:20:06 -05:00
use FireflyIII\Models\ImportJob ;
2018-04-29 23:37:29 -05:00
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface ;
2018-04-29 14:20:06 -05:00
use Illuminate\Http\JsonResponse ;
use Log ;
/**
* Class JobStatusController
*/
class JobStatusController extends Controller
{
2018-04-29 23:37:29 -05:00
/** @var ImportJobRepositoryInterface */
private $repository ;
2018-04-29 14:20:06 -05:00
/**
*
*/
public function __construct ()
{
parent :: __construct ();
$this -> middleware (
function ( $request , $next ) {
app ( 'view' ) -> share ( 'mainTitleIcon' , 'fa-archive' );
app ( 'view' ) -> share ( 'title' , trans ( 'firefly.import_index_title' ));
2018-04-29 23:37:29 -05:00
$this -> repository = app ( ImportJobRepositoryInterface :: class );
2018-04-29 14:20:06 -05:00
return $next ( $request );
}
);
$this -> middleware ( IsDemoUser :: class );
}
/**
* @ param ImportJob $importJob
*
* @ return \Illuminate\Contracts\View\Factory | \Illuminate\View\View
*/
public function index ( ImportJob $importJob )
{
2018-05-03 23:59:14 -05:00
$subTitleIcon = 'fa-gear' ;
$subTitle = trans ( 'import.job_status_breadcrumb' , [ 'key' => $importJob -> key ]);
return view ( 'import.status' , compact ( 'importJob' , 'subTitle' , 'subTitleIcon' ));
2018-04-29 14:20:06 -05:00
}
/**
2018-05-03 10:23:16 -05:00
* @ param ImportJob $importJob
2018-04-29 14:20:06 -05:00
*
* @ return JsonResponse
*/
2018-05-01 13:47:38 -05:00
public function json ( ImportJob $importJob ) : JsonResponse
2018-04-29 14:20:06 -05:00
{
2018-05-04 13:21:27 -05:00
$count = \count ( $importJob -> transactions );
$json = [
2018-05-03 23:59:14 -05:00
'status' => $importJob -> status ,
'errors' => $importJob -> errors ,
'count' => $count ,
'tag_id' => $importJob -> tag_id ,
'tag_name' => null === $importJob -> tag_id ? null : $importJob -> tag -> tag ,
'report_txt' => trans ( 'import.unknown_import_result' ),
2018-04-29 14:20:06 -05:00
];
2018-05-03 23:59:14 -05:00
// if count is zero:
2018-05-04 13:21:27 -05:00
if ( null !== $importJob -> tag_id ) {
$count = $importJob -> tag -> transactionJournals -> count ();
}
2018-05-03 23:59:14 -05:00
if ( $count === 0 ) {
$json [ 'report_txt' ] = trans ( 'import.result_no_transactions' );
}
2018-05-04 13:21:27 -05:00
if ( $count === 1 ) {
$json [ 'report_txt' ] = trans ( 'import.result_one_transaction' , [ 'route' => route ( 'tags.show' , [ $importJob -> tag_id ]), 'tag' => $importJob -> tag -> tag ]);
2018-05-03 23:59:14 -05:00
}
if ( $count > 1 && null !== $importJob -> tag_id ) {
2018-05-04 13:21:27 -05:00
$json [ 'report_txt' ] = trans (
'import.result_many_transactions' , [ 'count' => $count , 'route' => route ( 'tags.show' , [ $importJob -> tag_id ]), 'tag' => $importJob -> tag -> tag ]
);
2018-05-03 11:17:59 -05:00
}
2018-04-29 14:20:06 -05:00
return response () -> json ( $json );
}
/**
2018-05-04 13:21:27 -05:00
* @ param ImportJob $importJob
2018-04-29 14:20:06 -05:00
*
* @ return JsonResponse
*/
2018-05-01 13:47:38 -05:00
public function start ( ImportJob $importJob ) : JsonResponse
2018-04-29 14:20:06 -05:00
{
2018-05-01 13:47:38 -05:00
// catch impossible status:
2018-05-06 13:42:30 -05:00
$allowed = [ 'ready_to_run' , 'need_job_config' , 'error' , 'running' ];
// todo remove error and running.
2018-05-04 13:21:27 -05:00
if ( null !== $importJob && ! \in_array ( $importJob -> status , $allowed , true )) {
2018-05-01 13:47:38 -05:00
Log :: error ( 'Job is not ready.' );
2018-05-03 10:23:16 -05:00
2018-05-06 13:42:30 -05:00
// kill the job:
$this -> repository -> setStatus ( $importJob , 'error' );
2018-05-06 09:19:29 -05:00
return response () -> json ([ 'status' => 'NOK' , 'message' => 'JobStatusController::start expects status "ready_to_run".' ]);
2018-05-01 13:47:38 -05:00
}
$importProvider = $importJob -> provider ;
2018-04-29 14:20:06 -05:00
$key = sprintf ( 'import.routine.%s' , $importProvider );
$className = config ( $key );
if ( null === $className || ! class_exists ( $className )) {
2018-05-04 13:21:27 -05:00
// @codeCoverageIgnoreStart
return response () -> json (
[ 'status' => 'NOK' , 'message' => sprintf ( 'Cannot find import routine class for job of type "%s".' , $importProvider )]
);
// @codeCoverageIgnoreEnd
2018-05-03 10:23:16 -05:00
}
2018-04-29 23:37:29 -05:00
// set job to be running:
2018-05-01 13:47:38 -05:00
$this -> repository -> setStatus ( $importJob , 'running' );
2018-04-29 14:20:06 -05:00
/** @var RoutineInterface $routine */
$routine = app ( $className );
2018-05-12 08:50:01 -05:00
$routine -> setImportJob ( $importJob );
2018-04-29 14:20:06 -05:00
try {
$routine -> run ();
2018-05-04 13:21:27 -05:00
} catch ( FireflyException | Exception $e ) {
2018-04-29 14:20:06 -05:00
$message = 'The import routine crashed: ' . $e -> getMessage ();
Log :: error ( $message );
Log :: error ( $e -> getTraceAsString ());
2018-04-29 23:37:29 -05:00
// set job errored out:
2018-05-01 13:47:38 -05:00
$this -> repository -> setStatus ( $importJob , 'error' );
2018-04-29 23:37:29 -05:00
2018-04-29 14:20:06 -05:00
return response () -> json ([ 'status' => 'NOK' , 'message' => $message ]);
}
// expect nothing from routine, just return OK to user.
2018-05-01 13:47:38 -05:00
return response () -> json ([ 'status' => 'OK' , 'message' => 'stage_finished' ]);
2018-05-03 10:23:16 -05:00
}
/**
2018-05-04 13:21:27 -05:00
* Store does three things :
*
* - Store the transactions .
* - Add them to a tag .
*
* @ param ImportJob $importJob
2018-05-03 10:23:16 -05:00
*
* @ return JsonResponse
*/
public function store ( ImportJob $importJob ) : JsonResponse
{
// catch impossible status:
2018-05-10 02:10:16 -05:00
$allowed = [ 'provider_finished' , 'storing_data' , 'error' ];
2018-05-04 13:21:27 -05:00
if ( null !== $importJob && ! \in_array ( $importJob -> status , $allowed , true )) {
2018-05-03 10:23:16 -05:00
Log :: error ( 'Job is not ready.' );
2018-05-10 02:10:16 -05:00
return response () -> json ([ 'status' => 'NOK' , 'message' => sprintf ( 'JobStatusController::start expects status "provider_finished" instead of "%s".' , $importJob -> status )]);
2018-05-03 10:23:16 -05:00
}
// set job to be storing data:
$this -> repository -> setStatus ( $importJob , 'storing_data' );
try {
2018-05-04 13:21:27 -05:00
$this -> storeTransactions ( $importJob );
2018-05-03 10:23:16 -05:00
} catch ( FireflyException $e ) {
$message = 'The import storage routine crashed: ' . $e -> getMessage ();
Log :: error ( $message );
Log :: error ( $e -> getTraceAsString ());
// set job errored out:
$this -> repository -> setStatus ( $importJob , 'error' );
return response () -> json ([ 'status' => 'NOK' , 'message' => $message ]);
}
2018-05-04 13:21:27 -05:00
// set storage to be finished:
$this -> repository -> setStatus ( $importJob , 'storage_finished' );
2018-05-03 10:23:16 -05:00
// expect nothing from routine, just return OK to user.
return response () -> json ([ 'status' => 'OK' , 'message' => 'storage_finished' ]);
}
/**
* @ param ImportJob $importJob
*
* @ throws FireflyException
*/
2018-05-04 13:21:27 -05:00
private function storeTransactions ( ImportJob $importJob ) : void
2018-05-03 10:23:16 -05:00
{
2018-05-04 13:21:27 -05:00
/** @var ImportArrayStorage $storage */
$storage = app ( ImportArrayStorage :: class );
2018-05-12 08:50:01 -05:00
$storage -> setImportJob ( $importJob );
2018-05-03 10:23:16 -05:00
try {
2018-05-04 13:21:27 -05:00
$storage -> store ();
} catch ( FireflyException | Exception $e ) {
2018-05-03 10:23:16 -05:00
throw new FireflyException ( $e -> getMessage ());
}
2018-04-29 14:20:06 -05:00
}
}