middleware( function ($request, $next) { View::share('mainTitleIcon', 'fa-archive'); View::share('title', trans('firefly.import_index_title')); $this->repository = app(ImportJobRepositoryInterface::class); return $next($request); } ); } /** * This is step 3. This repeats until the job is configured. * * @param ImportJob $job * * @return View * @throws FireflyException */ public function configure(ImportJob $job) { // create configuration class: $configurator = $this->makeConfigurator($job); // is the job already configured? if ($configurator->isJobConfigured()) { $this->repository->updateStatus($job, 'configured'); return redirect(route('import.status', [$job->key])); } $view = $configurator->getNextView(); $data = $configurator->getNextData(); $subTitle = trans('firefly.import_config_bread_crumb'); $subTitleIcon = 'fa-wrench'; return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon')); } /** * Generate a JSON file of the job's configuration and send it to the user. * * @param ImportJob $job * * @return LaravelResponse */ public function download(ImportJob $job) { Log::debug('Now in download()', ['job' => $job->key]); $config = $job->configuration; // TODO this is CSV import specific: $config['column-roles-complete'] = false; $config['column-mapping-complete'] = false; $config['initial-config-complete'] = false; $config['delimiter'] = $config['delimiter'] === "\t" ? 'tab' : $config['delimiter']; $result = json_encode($config, JSON_PRETTY_PRINT); $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\')); /** @var LaravelResponse $response */ $response = response($result, 200); $response->header('Content-disposition', 'attachment; filename=' . $name) ->header('Content-Type', 'application/json') ->header('Content-Description', 'File Transfer') ->header('Connection', 'Keep-Alive') ->header('Expires', '0') ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->header('Pragma', 'public') ->header('Content-Length', strlen($result)); return $response; } /** * This is step 1. Upload a file. * * @return View */ public function index() { $subTitle = trans('firefly.import_index_sub_title'); $subTitleIcon = 'fa-home'; $importFileTypes = []; $defaultImportType = config('firefly.default_import_format'); foreach (array_keys(config('firefly.import_formats')) as $type) { $importFileTypes[$type] = trans('firefly.import_file_type_' . $type); } return view('import.index', compact('subTitle', 'subTitleIcon', 'importFileTypes', 'defaultImportType')); } /** * This is step 2. It creates an Import Job. Stores the import. * * @param ImportUploadRequest $request * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function initialize(ImportUploadRequest $request) { Log::debug('Now in initialize()'); // create import job: $type = $request->get('import_file_type'); $job = $this->repository->create($type); Log::debug('Created new job', ['key' => $job->key, 'id' => $job->id]); // process file: $this->repository->processFile($job, $request->files->get('import_file')); // process config, if present: if ($request->files->has('configuration_file')) { $this->repository->processConfiguration($job, $request->files->get('configuration_file')); } $this->repository->updateStatus($job, 'initialized'); return redirect(route('import.configure', [$job->key])); } /** * * Show status of import job in JSON. * * @param ImportJob $job * * @return \Illuminate\Http\JsonResponse */ public function json(ImportJob $job) { $result = [ 'started' => false, 'finished' => false, 'running' => false, 'errors' => array_values($job->extended_status['errors']), 'percentage' => 0, 'show_percentage' => false, 'steps' => $job->extended_status['steps'], 'done' => $job->extended_status['done'], 'statusText' => trans('firefly.import_status_job_' . $job->status), 'status' => $job->status, 'finishedText' => '', ]; if ($job->extended_status['steps'] !== 0) { $result['percentage'] = round(($job->extended_status['done'] / $job->extended_status['steps']) * 100, 0); $result['show_percentage'] = true; } if ($job->status === 'finished') { $tagId = $job->extended_status['tag']; /** @var TagRepositoryInterface $repository */ $repository = app(TagRepositoryInterface::class); $tag = $repository->find($tagId); $result['finished'] = true; $result['finishedText'] = trans('firefly.import_status_finished_job', ['link' => route('tags.show', [$tag->id, 'all']), 'tag' => $tag->tag]); } if ($job->status === 'running') { $result['started'] = true; $result['running'] = true; } return Response::json($result); } /** * Step 4. Save the configuration. * * @param Request $request * @param ImportJob $job * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function postConfigure(Request $request, ImportJob $job) { Log::debug('Now in postConfigure()', ['job' => $job->key]); $configurator = $this->makeConfigurator($job); // is the job already configured? if ($configurator->isJobConfigured()) { return redirect(route('import.status', [$job->key])); } $data = $request->all(); $configurator->configureJob($data); // return to configure return redirect(route('import.configure', [$job->key])); } /** * @param ImportJob $job * * @return \Illuminate\Http\JsonResponse * @throws FireflyException */ public function start(ImportJob $job) { /** @var ImportRoutine $routine */ $routine = app(ImportRoutine::class); $routine->setJob($job); $result = $routine->run(); if ($result) { return Response::json(['run' => 'ok']); } throw new FireflyException('Job did not complete succesfully.'); } /** * @param ImportJob $job * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View */ public function status(ImportJob $job) { $statuses = ['configured', 'running', 'finished']; if (!in_array($job->status, $statuses)) { return redirect(route('import.configure', [$job->key])); } $subTitle = trans('firefly.import_status_sub_title'); $subTitleIcon = 'fa-star'; return view('import.status', compact('job', 'subTitle', 'subTitleIcon')); } /** * @param ImportJob $job * * @return ConfiguratorInterface * @throws FireflyException */ private function makeConfigurator(ImportJob $job): ConfiguratorInterface { $type = $job->file_type; $key = sprintf('firefly.import_configurators.%s', $type); $className = config($key); if (is_null($className)) { throw new FireflyException('Cannot find configurator class for this job.'); // @codeCoverageIgnore } /** @var ConfiguratorInterface $configurator */ $configurator = app($className); $configurator->setJob($job); return $configurator; } }