MongoDB only works when using fetch via other function - php

I am trying to get a record from my MongoDB. To get the record I use the following code;
public function getEventsForAggregate($identifier)
{
$events = $this->MongoCollection()->findOne([
'_id' => $identifier
], [
'events',
]);
var_dump($events);
}
Unfortunately it dies on the findOne.
Do I change the code so the findOne is in a protected function it does work.
So the following code does work.
public function getEventsForAggregate($identifier)
{
$events = $this->getEvents($identifier);
var_dump($events);
}
protected function getEvents($identifier)
{
return $this->MongoCollection()->findOne([
'_id' => $identifier
], [
'events',
]);
}
Can some one explain how it is possible that the first code breaks, but the second one works?
Extra code;
/** #var MongoCollection */
protected $mongoCollection;
public function __construct(MongoCollection $MongoCollection)
{
$this->mongoCollection = $MongoCollection;
}
/**
* #return MongoCollection
*/
protected function MongoCollection()
{
return $this->mongoCollection;
}

Related

get data after save excel file with `maatwebsite/excel`

Project in Laravel (9), and PHP (8.1).
I want to import an excel file and use maatwebsite/excel (3.1) package.
I can import a file, and save the file into the model, like this:
import class:
class BankTransfersHistoryImport implements ToModel, WithHeadingRow, WithValidation
{
use Importable;
/**
* #param array $row
*
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
return new BankTransfersHistory([
'loanId' => $row['loanId'],
'actionDate' => transformDate($row['actionDate']),
'worth' => $row['worth'],
.
.
]);
}
public function headingRow(): int
{
return 2;
}
public function rules(): array
{
return [
'*.loanId' => ['required', 'numeric'],
... some roles ...
];
}
}
controller:
$import = new BankTransfersHistoryImport;
try {
// date validation
$collection = $import->toCollection($file);
... some validation about the date ...
$import->import($file);
... check and update rows ...
return [
"message" => some message,
"data" => [
some data
],
];
} catch (\Maatwebsite\Excel\Validators\ValidationException$e) {
$failures = $e->failures();
foreach ($failures as $failure) {
$failure->row(); // row that went wrong
$failure->attribute(); // either heading key (if using heading row concern) or column index
$failure->errors(); // Actual error messages from Laravel validator
$failure->values(); // The values of the row that has failed.
}
return $failures;
}
My question is:
If I can get the response of the file after saving the data, and that will give me the data with the id of the row that was saved.
In some cases, I will have to update a row. That's why I would like to get the ID.
Now in the check and update rows section, I update by loanId + actionDate. I want it to be done by ID.
something like this:
code:
$data = $import->import($file);
data will be like:
[
{
"id": 1,
"loanId": 21001,
"actionDate": "2020-01-02T00:00:00.000000Z",
"worth": 2997.09,
"offerId": 1,
},
{
"id": 2,
"loanId": 21002,
"actionDate": "2020-01-02T00:00:00.000000Z",
"worth": 3000,
"offerId": 10,
},
]
You can create a function on import class which will return the imported data, adding a sample for your reference.
UsersImport.php
<?php
namespace App\Imports;
use App\Models\User;
use Maatwebsite\Excel\Concerns\ToModel;
class UsersImport implements ToModel
{
private $rows;
public function __construct() {
$this->rows = collect();
}
/**
* #param array $row
*
* #return User|null
*/
public function model(array $row)
{
$user = new User([
'name' => $row[0],
'email' => $row[1],
'password' => bcrypt(12345678),
]);
$this->rows->push($user);
return $user;
}
/**
* Returns Imported Data
*
* #return \Illuminate\Support\Collection
*/
public function getImportedData(): \Illuminate\Support\Collection
{
return $this->rows;
}
}
Your Import Function in Controller
public function import(UsersImport $usersImport)
{
Excel::import($usersImport, public_path('users.xlsx'));
$usersImport->getImportedData();
}

Laravel excel, update rows after save in DB

Project in Laravel (9), and PHP (8.1).
I want to import an excel file and use maatwebsite/excel (3.1) package.
I can import a file, and save the file into the model, like this:
import class:
class BankTransfersHistoryImport implements ToModel, WithHeadingRow, WithValidation, WithBatchInserts
{
use Importable;
private $rows;
public function __construct()
{
$this->rows = collect();
}
/**
* #param array $row
*
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
$bankTransferHistory = new BankTransfersHistory([
'loanId' => $row['loanId'],
'actionDate' => transformDate($row['actionDate']),
'worth' => $row['worth'],
.
.
]);
$this->rows->push($bankTransferHistory);
return $bankTransferHistory;
}
/**
* Returns Imported Data
*
* #return \Illuminate\Support\Collection
*/
public function getImportedData(): \Illuminate\Support\Collection
{
return $this->rows;
}
public function headingRow(): int
{
return 2;
}
public function rules(): array
{
return [
'*.loanId' => ['required', 'numeric'],
... some roles ...
];
}
}
controller:
public function store(Request $request)
{
$request->validate([
'file' => 'required|mimes:xls,xlsx',
]);
$file = $request->file('file');
$import = new BankTransfersHistoryImport;
try {
// date validation
$collection = $import->toCollection($file);
... some validation about the date ...
$import->import($file);
$getImportedData = import->getImportedData();
... check and update rows ...
return [
"message" => some message,
"data" => [
some data
],
];
} catch (\Maatwebsite\Excel\Validators\ValidationException$e) {
$failures = $e->failures();
foreach ($failures as $failure) {
$failure->row(); // row that went wrong
$failure->attribute(); // either heading key (if using heading row concern) or column index
$failure->errors(); // Actual error messages from Laravel validator
$failure->values(); // The values of the row that has failed.
}
return $failures;
}
My question is:
If I can get the response of the file after saving the data, that will give me the data with the id of the row that was saved.
In some cases, I will have to update a row. That's why I would like to get the ID.
Now, in the check and update rows section, I update row by loanId + actionDate. I want it to be done by only ID.
something like this:
code:
$getImportedData = import->getImportedData();
data will be like:
[
{
"id": 1,
"loanId": 21001,
"actionDate": "2020-01-02T00:00:00.000000Z",
"worth": 2997.09,
"offerId": 1,
},
{
"id": 2,
"loanId": 21002,
"actionDate": "2020-01-02T00:00:00.000000Z",
"worth": 3000,
"offerId": 10,
},
]
The solution to my problem.
To save the information and get the ID of each saved row, I did a few things.
I changed my import class.
First I changed the create from ToModel to ToCollection
I deleted WithBatchInserts because this method does not work with ToCollection.
Next, I called the getImportedData function.
That's how I got all the rows I create in the DB with their ID.
This solved the problem for me to get the information saved with the ID of each line, and perform validation + update if necessary.
The code is below.
A small note:
I changed the word rows to data in the `getImportedData' function.
I save all the files in the system.
import class:
class BankTransfersHistoryImport implements ToCollection, WithHeadingRow, WithValidation
{
use Importable;
private $data;
public function __construct()
{
$this->data = collect();
}
/**
* #param array $row
*
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function collection(Collection $rows)
{
foreach ($rows as $row) {
$bankTransferHistory = BankTransfersHistory::create([
'loanId' => $row['loanId'],
'actionDate' => transformDate($row['actionDate']),
'worth' => $row['worth'],
.
.
]);
$this->data->push($bankTransferHistory);
}
}
/**
* Returns Imported Data
*
* #return \Illuminate\Support\Collection
*/
public function getImportedData(): \Illuminate\Support\Collection
{
return $this->data;
}
public function headingRow(): int
{
return 2;
}
public function rules(): array
{
return [
'*.loanId' => ['required', 'numeric'],
... some roles ...
];
}
}
store controller:
public function store(Request $request)
{
$request->validate([
'file' => 'required|mimes:xls,xlsx',
]);
$file = $request->file('file');
$import = new BankTransfersHistoryImport;
try {
// date validation
$collection = $import->toCollection($file);
... some validation about the date ...
// save the file in the system
$fileName = time() . '-' . $file->getClientOriginalName();
$file->storeAs('import bank transfers history', $fileName);
$import->import($file);
$importedData = $import->getImportedData(); // data after save in DB
... check and update rows ...
return [
"message" => some message,
"data" => [
some data
],
];
} catch (\Maatwebsite\Excel\Validators\ValidationException$e) {
$failures = $e->failures();
foreach ($failures as $failure) {
$failure->row(); // row that went wrong
$failure->attribute(); // either heading key (if using heading row concern) or column index
$failure->errors(); // Actual error messages from Laravel validator
$failure->values(); // The values of the row that has failed.
}
return $failures;
}
}

Laravel get data from db array not working

When I run the code I get no error but the data I am trying to display is not displaying it's just blank.. can someone tell me what I'm doing wrong?
My controller:
public function openingPage($id) {
$this->getGames();
$games = $this->getGames();
return view('caseopener')->with('games',$games);
}
private function getGames() {
$games = array();
foreach ($this->data->items as $item) {
$game = new Game($item);
$games[] = array(
'id' => $game['id'],
'name' => $game['name'],
'price' => $game['price'],
'image' => $game['image'],
);
}
return $games;
}
The 'Game' Model that is used in 'getGames function':
class Game extends Model
{
private $id;
public $data;
public function __construct($id) {
parent::__construct();
$this->id = $id;
$this->data = $this->getData();
}
private function getData() {
$game = DB::table('products')->where('id', 1)->first();
if(empty($game)) return array();
return $game;
}
}
The view:
#foreach ($games as $game)
<div class="gold">$ {{ $game['price'] }}</div>
#endforeach
I think you are over-complicating things. You could simplify your flow like this:
Given your provided code, it seems like you are using a custom table name ('products') in your Game model. So we'll address this first:
Game.php
class Game extends Model
{
protected $table = 'products'; //
}
Now, it seems like you're searching an array of Game ids ($this->data->items). If so, you could make use of Eloquent for your query, specially the whereIn() method:
YourController.php
public function openingPage($id)
{
$games = Game::whereIn('id', $this->data->items)->get();
return view('caseopener')->with('games', $games);
}
Optionally, if you want to make sure of just returning the id, name, price and image of each Game/product, you could format the response with API Resources:
php artisan make:resource GameResource
Then in your newly created class:
app/Http/Resources/GameResource.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class GameResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->price,
'image' => $this->image,
];
}
}
So now just update your controller:
YourController.php
use App\Http\Resources\GameResource;
public function openingPage($id)
{
$games = Game::whereIn('id', $this->data->items)->get();
return view('caseopener')->with('games', GameResource::collection($games));
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Laravel Model, deleted callback not being called

im trying to run some additional code when a row is deleted using my Model. However the callback statis::deleted simply isn't being triggered.
Controller:
/**
* #param Website $website
* #param Request $request
* #return \Illuminate\Http\RedirectResponse
* #throws \Exception
*/
public function delete(Website $website, Request $request)
{
$id = $request->input('id-value');
WebsiteRedirects::query()->where(['website_id' => $website['id'], 'id' => $id])->delete();
Session::flash('message', [ 'is-success' => [ '1 Redirect has been deleted!' ] ]);
return back();
}
Model:
class WebsiteRedirects extends Model
{
protected $table = 'website_redirects';
protected $guarded = [];
public $timestamps = false;
protected static function boot()
{
parent::boot();
static::saved(function ($redirect) {
PlannerStatus::status('redirect', $redirect->website_id, 1);
});
static::deleted(function($redirect) {
dd('deleted');
PlannerStatus::status('redirect', $redirect->website_id, 1);
});
}
...
static::saved works fine, and I insert using query too.
WebsiteRedirects::query()->create(
[
'website_id' => $website->id,
'redirect_from' => $request->input('redirect-from'),
'redirect_to' => $request->input('redirect-to')
]
);
The event is not being called because you are not deleting the row via Eloquent. You are deleting the row directly, without fetching the result - therefor Eloquent can't run the deleted event.
You will have to fetch the model before deleting for the event to be triggered.
WebsiteRedirects::where(['website_id' => $website['id'], 'id' => $id])->first()->delete();
Add first() to retrieve the WebsiteRedirect before you run delete()
In your code
WebsiteRedirects::query()->where(['website_id' => $website['id'], 'id' => $id])
right before the delete() method, the instance of the object is Illuminate\Database\Eloquent\Builder not your model. wich will trigger the Eloquent delete (DB) not your model's one.
Normaly you would do something like:
$user = User::find($id);
$user->delete();

REST api not working

I am new to php development. Just for practicing I am creating a rest API following a video tutorial. I have followed each and every step but still unable to get the desired result. Below is the code
Employee Model
class Employee extends \yii\db\ActiveRecord
{
const SCENARIO_CREATE = 'create';
/**
* #inheritdoc
*/
public static function tableName()
{
return 'employee';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['emp_name', 'emp_email', 'emp_sal'], 'required'],
[['emp_name', 'emp_email', 'emp_sal'], 'string', 'max' => 100],
];
}
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['create'] = ['emp_name','emp_email', 'emp_sal'];
return $scenarios;
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'emp_name' => 'Emp Name',
'emp_email' => 'Emp Email',
'emp_sal' => 'Emp Sal',
];
}
}
Above the ID field is auto-increment
Employee Controller
public function actionCreateEmployee()
{
\Yii::$app->response->format= \yii\web\Response::FORMAT_JSON;
$employee = new Employee();
$employee-> scenario = Employee::SCENARIO_CREATE;
$employee->attributes = \Yii::$app->request->post();
if ($employee->validate())
{
return array('status'=> true, 'data' => 'Employee Created Sussessfully');
}
else
{
return array('status'=> false, 'data'=>$employee->getErrors());
}
//return array('status'=> true);
}
Now when I run the API in Postman. I got the following result.
Though I have entered all the required fields data still it gives me false status
Any help would be highly appreciated
You need to select x-www-form-urlencoded
The documentation says that the $_POST-parameter only gets filled on application/x-www-form-urlencoded or multipart/form-data and yii is probably using this.
An associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request.
from php.net

Categories