mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Hosted Migration Console Command
This commit is contained in:
parent
bdb771e4ca
commit
ff130ae8a2
131
app/Console/HostedMigrations.php
Normal file
131
app/Console/HostedMigrations.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Exceptions\MigrationValidatorFailed;
|
||||
use App\Exceptions\NonExistingMigrationFile;
|
||||
use App\Exceptions\ProcessingMigrationArchiveFailed;
|
||||
use App\Exceptions\ResourceDependencyMissing;
|
||||
use App\Exceptions\ResourceNotAvailableForMigration;
|
||||
use App\Jobs\Util\Import;
|
||||
use App\Jobs\Util\StartMigration;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\MigrationFailed;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use DirectoryIterator;
|
||||
use Faker\Factory;
|
||||
use Faker\Generator;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
use ZipArchive;
|
||||
|
||||
class HostedMigrations extends Command
|
||||
{
|
||||
use MakesHash;
|
||||
use AppSetup;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'migrations:hosted-import {--email=}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Import a v4 migration file';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->buildCache();
|
||||
|
||||
if(!MultiDB::userFindAndSetDb($this->option('email'))){
|
||||
$this->info("Could not find a user with that email address");
|
||||
return;
|
||||
}
|
||||
|
||||
$user = User::where('email', $this->option('email'))->first();
|
||||
|
||||
if(!$user){
|
||||
$this->info("There was a problem getting the user, did you set the right DB?");
|
||||
return;
|
||||
}
|
||||
|
||||
$path = public_path('storage/migrations/import');
|
||||
|
||||
nlog(public_path('storage/migrations/import'));
|
||||
|
||||
$directory = new DirectoryIterator($path);
|
||||
|
||||
foreach ($directory as $file) {
|
||||
if ($file->getExtension() === 'zip') {
|
||||
|
||||
$company = $user->companies()->first();
|
||||
|
||||
$this->info('Started processing: '.$file->getBasename().' at '.now());
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$archive = $zip->open($file->getRealPath());
|
||||
|
||||
try {
|
||||
if (! $archive) {
|
||||
throw new ProcessingMigrationArchiveFailed('Processing migration archive failed. Migration file is possibly corrupted.');
|
||||
}
|
||||
|
||||
$filename = pathinfo($file->getRealPath(), PATHINFO_FILENAME);
|
||||
|
||||
$zip->extractTo(public_path("storage/migrations/{$filename}"));
|
||||
$zip->close();
|
||||
|
||||
$import_file = public_path("storage/migrations/$filename/migration.json");
|
||||
|
||||
Import::dispatch($import_file, $user->companies()->first(), $user);
|
||||
|
||||
unlink(public_path("storage/migrations/$filename/migration.json"));
|
||||
unlink($file->getRealPath());
|
||||
|
||||
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing $e) {
|
||||
\Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
|
||||
|
||||
if (app()->environment() !== 'production') {
|
||||
info($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -36,7 +36,7 @@ class WebhookHandler implements ShouldQueue
|
||||
|
||||
private $company;
|
||||
|
||||
public $tries = 3; //number of retries
|
||||
public $tries = 1; //number of retries
|
||||
|
||||
public $backoff = 10; //seconds to wait until retry
|
||||
|
||||
|
@ -54,7 +54,7 @@ class CompanyPresenter extends EntityPresenter
|
||||
$settings = $this->entity->settings;
|
||||
}
|
||||
|
||||
if(config('ninja.is_docker'))
|
||||
if(config('ninja.is_docker') || config('ninja.local_download'))
|
||||
return $this->logo($settings);
|
||||
|
||||
$context_options =array(
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class ActivityTransformer extends EntityTransformer
|
||||
@ -23,7 +24,9 @@ class ActivityTransformer extends EntityTransformer
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $availableIncludes = [];
|
||||
protected $availableIncludes = [
|
||||
'history'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
@ -55,4 +58,11 @@ class ActivityTransformer extends EntityTransformer
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
public function includeHistory(Activity $activity)
|
||||
{
|
||||
$transformer = new ActivityTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($activity->backup, $transformer, Backup::class);
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,12 @@ class InvoiceHistoryTransformer extends EntityTransformer
|
||||
use MakesHash;
|
||||
|
||||
protected $defaultIncludes = [
|
||||
'activity',
|
||||
// 'activity',
|
||||
];
|
||||
|
||||
protected $availableIncludes = [];
|
||||
protected $availableIncludes = [
|
||||
'activity',
|
||||
];
|
||||
|
||||
public function transform(Backup $backup)
|
||||
{
|
||||
|
@ -132,6 +132,7 @@ class HtmlEngine
|
||||
$data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_invoice').'</a>', 'label' => ctrans('texts.view_invoice')];
|
||||
$data['$viewLink'] = &$data['$view_link'];
|
||||
$data['$viewButton'] = &$data['$view_link'];
|
||||
$data['$paymentButton'] = &$data['$view_link'];
|
||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_invoice')];
|
||||
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->entity->client->date_format(), $this->entity->client->locale()) ?: ' ', 'label' => ctrans('texts.invoice_date')];
|
||||
|
||||
@ -148,6 +149,8 @@ class HtmlEngine
|
||||
$data['$terms'] = &$data['$entity.terms'];
|
||||
$data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_quote').'</a>', 'label' => ctrans('texts.view_quote')];
|
||||
$data['$viewLink'] = &$data['$view_link'];
|
||||
$data['$viewButton'] = &$data['$view_link'];
|
||||
$data['$approveButton'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_quote').'</a>', 'label' => ctrans('texts.approve')];
|
||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_quote')];
|
||||
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->entity->client->date_format(), $this->entity->client->locale()) ?: ' ', 'label' => ctrans('texts.quote_date')];
|
||||
}
|
||||
@ -159,6 +162,7 @@ class HtmlEngine
|
||||
$data['$entity.terms'] = ['value' => $this->entity->terms ?: '', 'label' => ctrans('texts.credit_terms')];
|
||||
$data['$terms'] = &$data['$entity.terms'];
|
||||
$data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_credit').'</a>', 'label' => ctrans('texts.view_credit')];
|
||||
$data['$viewButton'] = &$data['$view_link'];
|
||||
$data['$viewLink'] = &$data['$view_link'];
|
||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')];
|
||||
// $data['$view_link'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')];
|
||||
|
@ -36,6 +36,7 @@ return [
|
||||
'phantomjs_pdf_generation' => env('PHANTOMJS_PDF_GENERATION', true),
|
||||
'trusted_proxies' => env('TRUSTED_PROXIES', false),
|
||||
'is_docker' => env('IS_DOCKER', false),
|
||||
'local_download' => env('LOCAL_DOWNLOAD', false),
|
||||
'sentry_dsn' => env('SENTRY_LARAVEL_DSN', 'https://9b4e15e575214354a7d666489783904a@sentry.invoicing.co/6'),
|
||||
'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller'
|
||||
'preconfigured_install' => env('PRECONFIGURED_INSTALL',false),
|
||||
|
70
config/querydetector.php
Normal file
70
config/querydetector.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
* Enable or disable the query detection.
|
||||
* If this is set to "null", the app.debug config value will be used.
|
||||
*/
|
||||
'enabled' => env('QUERY_DETECTOR_ENABLED', false),
|
||||
|
||||
/*
|
||||
* Threshold level for the N+1 query detection. If a relation query will be
|
||||
* executed more then this amount, the detector will notify you about it.
|
||||
*/
|
||||
'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1),
|
||||
|
||||
/*
|
||||
* Here you can whitelist model relations.
|
||||
*
|
||||
* Right now, you need to define the model relation both as the class name and the attribute name on the model.
|
||||
* So if an "Author" model would have a "posts" relation that points to a "Post" class, you need to add both
|
||||
* the "posts" attribute and the "Post::class", since the relation can get resolved in multiple ways.
|
||||
*/
|
||||
'except' => [
|
||||
//Author::class => [
|
||||
// Post::class,
|
||||
// 'posts',
|
||||
//]
|
||||
],
|
||||
|
||||
/*
|
||||
* Here you can set a specific log channel to write to
|
||||
* in case you are trying to isolate queries or have a lot
|
||||
* going on in the laravel.log. Defaults to laravel.log though.
|
||||
*/
|
||||
'log_channel' => env('QUERY_DETECTOR_LOG_CHANNEL', 'daily'),
|
||||
|
||||
/*
|
||||
* Define the output format that you want to use. Multiple classes are supported.
|
||||
* Available options are:
|
||||
*
|
||||
* Alert:
|
||||
* Displays an alert on the website
|
||||
* \BeyondCode\QueryDetector\Outputs\Alert::class
|
||||
*
|
||||
* Console:
|
||||
* Writes the N+1 queries into your browsers console log
|
||||
* \BeyondCode\QueryDetector\Outputs\Console::class
|
||||
*
|
||||
* Clockwork: (make sure you have the itsgoingd/clockwork package installed)
|
||||
* Writes the N+1 queries warnings to Clockwork log
|
||||
* \BeyondCode\QueryDetector\Outputs\Clockwork::class
|
||||
*
|
||||
* Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed)
|
||||
* Writes the N+1 queries into a custom messages collector of Debugbar
|
||||
* \BeyondCode\QueryDetector\Outputs\Debugbar::class
|
||||
*
|
||||
* JSON:
|
||||
* Writes the N+1 queries into the response body of your JSON responses
|
||||
* \BeyondCode\QueryDetector\Outputs\Json::class
|
||||
*
|
||||
* Log:
|
||||
* Writes the N+1 queries into the Laravel.log file
|
||||
* \BeyondCode\QueryDetector\Outputs\Log::class
|
||||
*/
|
||||
'output' => [
|
||||
//\BeyondCode\QueryDetector\Outputs\Alert::class,
|
||||
\BeyondCode\QueryDetector\Outputs\Log::class,
|
||||
//\BeyondCode\QueryDetector\Outputs\Json::class,
|
||||
]
|
||||
];
|
Loading…
Reference in New Issue
Block a user