diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 4d81705ea3..10036a77bd 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -104,9 +104,9 @@ class ForgotPasswordController extends Controller */ public function sendResetLinkEmail(Request $request) { - //MultiDB::userFindAndSetDb($request->input('email')); + MultiDB::userFindAndSetDb($request->input('email')); - $user = MultiDB::hasUser(['email' => $request->input('email')]); + // $user = MultiDB::hasUser(['email' => $request->input('email')]); $this->validateEmail($request); diff --git a/app/Jobs/Company/CompanyExport.php b/app/Jobs/Company/CompanyExport.php index ed514acee4..f9206969fd 100644 --- a/app/Jobs/Company/CompanyExport.php +++ b/app/Jobs/Company/CompanyExport.php @@ -11,13 +11,19 @@ namespace App\Jobs\Company; +use App\Jobs\Mail\NinjaMailerJob; +use App\Jobs\Mail\NinjaMailerObject; +use App\Jobs\Util\UnlinkFile; use App\Libraries\MultiDB; +use App\Mail\DownloadBackup; +use App\Mail\DownloadInvoices; use App\Models\Company; use App\Models\CreditInvitation; use App\Models\InvoiceInvitation; use App\Models\QuoteInvitation; use App\Models\RecurringInvoice; use App\Models\RecurringInvoiceInvitation; +use App\Models\User; use App\Models\VendorContact; use App\Utils\Traits\MakesHash; use Illuminate\Bus\Queueable; @@ -25,17 +31,22 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Storage; +use ZipStream\Option\Archive; +use ZipStream\ZipStream; class CompanyExport implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash; - protected $company; + public $company; private $export_format; private $export_data = []; + public $user; + /** * Create a new job instance. * @@ -43,9 +54,10 @@ class CompanyExport implements ShouldQueue * @param User $user * @param string $custom_token_name */ - public function __construct(Company $company, $export_format = 'json') + public function __construct(Company $company, User $user, $export_format = 'json') { $this->company = $company; + $this->user = $user; $this->export_format = $export_format; } @@ -87,11 +99,15 @@ class CompanyExport implements ShouldQueue return $activity; - })->toArray(); + })->makeHidden(['id'])->toArray(); $this->export_data['backups'] = $this->company->all_activities()->with('backup')->cursor()->map(function ($activity){ $backup = $activity->backup; + + if(!$backup) + return; + $backup->activity_id = $this->encodePrimaryKey($backup->activity_id); return $backup; @@ -309,7 +325,7 @@ class CompanyExport implements ShouldQueue $this->export_data['subscriptions'] = $this->company->subscriptions->map(function ($subscription){ $subscription = $this->transformBasicEntities($subscription); - $subscription->group_id = $this->encodePrimaryKey($group_id); + $subscription->group_id = $this->encodePrimaryKey($subscription->group_id); return $subscription; @@ -328,7 +344,7 @@ class CompanyExport implements ShouldQueue $this->export_data['tasks'] = $this->company->tasks->map(function ($task){ $task = $this->transformBasicEntities($task); - $task = $this->transformArrayOfKeys(['client_id', 'invoice_id', 'project_id', 'status_id']); + $task = $this->transformArrayOfKeys($task, ['client_id', 'invoice_id', 'project_id', 'status_id']); return $task; @@ -387,7 +403,9 @@ class CompanyExport implements ShouldQueue })->makeHidden(['id'])->toArray(); - var_dump($this->export_data); + //write to tmp and email to owner(); + + $this->zipAndSend(); } private function transformBasicEntities($model) @@ -408,4 +426,46 @@ class CompanyExport implements ShouldQueue } + private function zipAndSend() + { + nlog("zipping"); + + $tempStream = fopen('php://memory', 'w+'); + + $options = new Archive(); + $options->setOutputStream($tempStream); + + $file_name = date('Y-m-d').'_'.str_replace(' ', '_', $this->company->present()->name() . '_' . $this->company->company_key .'.zip'); + + $zip = new ZipStream($file_name, $options); + + $fp = tmpfile(); + fwrite($fp, json_encode($this->export_data)); + rewind($fp); + $zip->addFileFromStream('backup.json', $fp); + + $zip->finish(); + + $path = 'backups/'; + + nlog($path.$file_name); + + Storage::disk(config('filesystems.default'))->put($path.$file_name, $tempStream); + // fclose($fp); + + nlog(Storage::disk(config('filesystems.default'))->url($path.$file_name)); + + fclose($tempStream); + + $nmo = new NinjaMailerObject; + $nmo->mailable = new DownloadBackup(Storage::disk(config('filesystems.default'))->url($path.$file_name), $this->company); + $nmo->to_user = $this->user; + $nmo->settings = $this->company->settings; + $nmo->company = $this->company; + + NinjaMailerJob::dispatch($nmo); + + UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1)); + } + } diff --git a/app/Libraries/MultiDB.php b/app/Libraries/MultiDB.php index 92132a118b..27673891e0 100644 --- a/app/Libraries/MultiDB.php +++ b/app/Libraries/MultiDB.php @@ -129,13 +129,12 @@ class MultiDB } foreach (self::$dbs as $db) { + self::setDB($db); - $user = User::where($data)->withTrashed()->first(); - - if ($user) { + if ($user = User::where($data)->withTrashed()->first()) return $user; - } + } self::setDefaultDatabase(); diff --git a/resources/lang/ca/texts.php b/resources/lang/ca/texts.php index 5302d2431d..efa1181504 100644 --- a/resources/lang/ca/texts.php +++ b/resources/lang/ca/texts.php @@ -2861,6 +2861,7 @@ $LANG = [ 'my_invoices' => 'My Invoices', 'mobile_refresh_warning' => 'If you\'re using the mobile app you may need to do a full refresh.', 'enable_proposals_for_background' => 'To upload a background image :link to enable the proposals module.', + ]; diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 2a46a25013..7f1174d56b 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4248,6 +4248,7 @@ $LANG = array( 'activity_104' => ':user restored recurring invoice :recurring_invoice', 'new_login_detected' => 'New login detected for your account.', 'new_login_description' => 'You recently logged in to your Invoice Ninja account from a new location or device:

IP: :ip
Time: :time
Email: :email', + 'download_backup_subject' => 'Your company backup is ready for download', ); return $LANG; diff --git a/routes/api.php b/routes/api.php index ed9029c41f..b46bd12f0d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -75,6 +75,8 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::put('expenses/{expense}/upload', 'ExpenseController@upload'); Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk'); + Route::post('export', 'ExportController@index')->name('export.index'); + Route::resource('expense_categories', 'ExpenseCategoryController'); // name = (expense_categories. index / create / show / update / destroy / edit Route::post('expense_categories/bulk', 'ExpenseCategoryController@bulk')->name('expense_categories.bulk'); diff --git a/tests/Feature/Export/ExportCompanyTest.php b/tests/Feature/Export/ExportCompanyTest.php index 189b1b47dd..bfdad43e38 100644 --- a/tests/Feature/Export/ExportCompanyTest.php +++ b/tests/Feature/Export/ExportCompanyTest.php @@ -44,6 +44,6 @@ class ExportCompanyTest extends TestCase public function testCompanyExport() { - CompanyExport::dispatchNow($this->company); + CompanyExport::dispatchNow($this->company, $this->company->users->first()); } }