How to test Laravel Scout (with Algolia)? - php

I have a piece of code like this:
public function index(Request $request, Runner $runnerParam)
{
$name = $request->input('name');
$fromDate = $request->input('from_date');
$toDate = $request->input('to_date');
$runners = Runner::query();
if ($name) {
$runners = $runnerParam::search($name);
}
if ($fromDate && $toDate) {
$runners->where('created_at', '<=',$toDate )
->where('created_at', '>=', $fromDate);
}
switch ($type) {
case 1:
$runners->where('role', '=', runner::PRO);
break;
case 2:
$runners->where('role', '=', runner::AMATEUR);
break;
}
$runners = $runners->get();
foreach($runners as $runner){
$runner->distance = $runner->stats->sum('distance');
}
return $runners;
}
The question is, how do I write test for this? If I just try to provide 'name' in test, it will return nothing like search() function isn't working at all while testing. Tried really hard to find anything on this, but the info is scarce and I only ended up with something like 'set Algolia driver to null', which I managed to do, but to no effect since I don't know what's the point of doing so and how do you apply it in tests. There are absolutely no examples of successful tests out there, just a few questions with short answer that didn't quite help.
A piece of test:
public function testNameFilter()
{
$this->logIn();
$runners = factory(runner::class, 30)->create();
$name = $runners[0]->name;
$response = $this->json('get', route('api::runners.get'), ['name' => $name]);
$responseContent = $response->getContent();
...
}
So, what I get in the end is empty responseContent, which means this is not the right way to test this. Any thoughts?

Why not just test that you've properly configured your class to use Laravel Scout, vs. testing that Laravel Scout works as expected?
public function class_uses_scout()
{
$this->assertTrue(in_array('Laravel\Scout\Searchable', class_uses('App\FooModel')));
}
public function class_has_searchable_array()
{
// compare the searchable array with a hardcoded array here
}
Be sure to set your disable Laravel Scout in your test environment.

Related

Laravel. Exporting results from database problems

As short as possible. My code runs through multiple databases counts objects and matches name - number of objects
It runs like a script(command in laravel) that exports the results in .csv file.
$formatted_data = array();
$providers = provider::where('del', 'no')->get();
foreach($providers as $provider){
$formatted_data[$provider['id']]['name'] = $provider['name'];
}
$objectMappingsModels = array((new objectMapping1), (new objectMapping2),
(new objectMapping3), (new objectMapping4), (new objectMapping5),
(new objectMapping6), (new objectMapping7), (new objectMapping8));
foreach($objectMappingsModels as $objectMappingsModel){
$totals = $objectMappingsModel::select('providerFK', DB::raw('count(*) as total'),
DB::raw('monthName(ut) as month_name')
)
->where('userFK', '!=', 1)
->where('del', 'no')
->whereMonth('ut', $this->option('month'))
->whereYear('ut', $this->option('year'))
->groupBy('providerFK', 'month_name')
->get()
->toArray();
foreach($totals as $total){
$formatted_data[$total['providerFK']]['count'] = $total['total'];
}
}
$responce = Excel::store(new UsersExport($formatted_data), 'testNameDate.csv',null, \Maatwebsite\Excel\Excel::CSV);
return true;
That's what my code looks like.
class UsersExport implements FromArray
{
protected $invoices;
public function __construct(array $invoices)
{
$this->invoices = $invoices;
}
public function array(): array
{
return $this->invoices;
}
}
And that's what my export class looks like.
Unfortunately, it's not working flawlessly. It gives me wrong results from time to time. Some records a correct and some are not. Also, the last row is always with just a random number(without a name attached to it). Any idea why such problems occur and can you suggest me some code optimizations?
Thanks!
I added this if-else in the last loop
if(isset($formatted_data[$total['providerFK']]['count'])){
$formatted_data[$total['providerFK']]['count'] += $total['total'];
}else{
$formatted_data[$total['providerFK']]['count'] = $total['total'];
}
And it seems to have fixed some issues

How to make autonumber restart every year in Laravel/PHP?

I made code like this in Models Number_npe:
public function nomor_akhir()
{
$query = DB::table('nomor_npe')
->select('*')
->orderBy('id','DESC')
->first();
return $query;
}
Then the Controllers:
public function nomor_npe_store(Request $req)
{
$tanggal_npe = $req->input('tanggal_npe');
$pesan = new Nomor_npe();
$check = $pesan->nomor_akhir();
if($check) {
$nomor_npe = $check->nomor_npe+1;
}else{
$nomor_npe = 1;
}
DB::table('nomor_npe')->insert([
'nomor_npe' => $nomor_npe,
'tanggal_npe' => $tanggal_npe
]);
return redirect('nomor_npe')->with('success','Nomor NPE berhasil ditambahkan');
}
The Add NPE Number display looks like this:
When I click Save, the number_npe has been successfully added automatically.
But I want to make when the year changes, the number_npe restarts automatically from 1 again ... Please help everyone who knows
I have to write this as an answer, but it is not 100% an answer to your code, these are just tips for you to have better code. (So if anyone sees this too, they are aware too)
First of all, avoid 100% writing code in other language than English, as we are following it (we do not speak your language) and we do not understand nearly anything unless we use a Translator...
So, if you are going to use Laravel, try to avoid using DB, when you can just use the Model (hopefully you have created it...).
So your class should look like this:
public function lastNumber()
{
return NomorNpe::orderByDesc('id')->first();
}
Then your controller should be like:
public function store(Request $request, NomorNpe $nomor_npe)
{
NomorNpe::create([
'nomor_npe' => $nomor_npe->lastNumber() ? $nomor_npe->lastNumber()->nomor_npe + 1 : 1,
'tanggal_npe' => $request->input('tanggal_npe')
]);
return redirect('nomor_npe')->with('success', 'Nomor NPE berhasil ditambahkan');
}
See how I reduced everything from 13 lines of code to 5 lines of code and is 100% readable... (Or 9 lines to 2)
Make sure to use what Laravel brings you as "default" for it, use Models not DB::table('xxx'), take advantage of Eloquent.
Use this code for starting the number from 1, when the year changed:
public function nomor_npe_store(Request $req) {
$tanggal_npe = $req->input('tanggal_npe');
//---Current Date
$date = date('Y-m-d', time());
//---NOMOR NPE
$nomor_npe = DB('number_npe')->whereYear('tanggal_npe', $date)->max('normor_npe');
if (!$nomor_npe) {
$nomor_npe = 1;
} else {
$nomor_npe++;
}
DB::table('nomor_npe')->insert([
'nomor_npe' => $nomor_npe,
'tanggal_npe' => $tanggal_npe
]);
return redirect('nomor_npe')->with('success','Nomor NPE berhasil ditambahkan');
}

Using variable in a different function of the same controller laravel

i know this question looks like a easy one and asked many times, but i tried all the possible solution and nothing seems to work. so please don't mark this as duplicate until a solution has been found. So here is the problem,
I have defined a variable $msg_body in tabloader function.
I want to use it in tabloader1 function which is in the same controller.
here is the code and all the solutions that i tried, below is my tabloader function
public function tabloader(Request $request){
$msg_body= Message::where('id', $request->id)->value('body');
$msg_topic= Message::where('id', $request->id)->value('topic');
$this->tabloader1($msg_body);
//$name = $request->$msg_body;
//$a = new RtrController();
//$a->tabloader1();
//Session::put('key', $msg_body);
//$response = Response::make('Hello World');
//return $response->withCookie(Cookie::make('name', 'value', $msg_body));
//DB::table('sendmessages')->insert(array('body1'=>$msg_body, 'phone_nos'=>'1111'));
//foreach($item_nos as $item_no)
//Sendmessage::insert(array('body1'=>$msg_body, 'phone_nos'=>'1234' )); //'phone_nos'=>$item_no
//endforeach
//return view('adminCenter',compact('prod'));
}
and below is my tabloader1 function
public function tabloader1($msg_body){
$prod=Message::get()->all();
$item_nos=DB::table('items')->pluck('phone_no');
//dd($item_nos);
$item_ids=DB::table('items')->pluck('id');
//$name = Session::get('key');
//$value = Cookie::get('name');
//Sendmessage::create(array('body1' => $value,'phone_nos' => '11113'));
DB::table('sendmessages')->insert(array('body1'=>$msg_body, 'phone_nos'=>'1111'));
//foreach($item_nos as $item_no){
//foreach($item_ids as $item_id){
//DB::table('sendmessages')->whereId($item_id)->update(array('phone_nos'=>$item_no ));
//DB::table('sendmessages')->insert(array('body1'=>$msg_body, 'phone_nos'=>'1111'));
return view('adminCenter',compact('prod')); //here i want it to return to .. know the syntax? no
}
i am using that variable to insert it into a table sendmessages
and the error is
"in tabloader1 function, the argument 1 is missing."
I have tried various solutions as you can see the commented lines in code.
Really hoping for a solution, Thanks
try this :
public function tabloader(Request $request){
$msg_body= Message::where('id', $request->id)->select(['body'])->first();
$msg_topic= Message::where('id', $request->id)->select(['topic'])->first();
return $this->tabloader1($msg_body);
}
public function tabloader1($msg_body=''){ // '' if empty
.
.
return view('adminCenter',compact('prod')); //here i want it to return to .. know the syntax? no
}

Laravel ORM select query function load() on null

Here's my function to load submissions created by a user.
public function viewSubs()
{
$user = User::find(Input::get('id'));
$submissions = Submission::find($user)->sortByDesc('created_at');
$submissions->load('user')->load('votes')->load('suggestions.votes');
return view('submissions.index' , compact('submissions'));
}
This returns with an error
Call to a member function load() on null
when there are no records on the submission.
How to handle if there are no submission on the DB?
Just check if its null first using an if statement:
public function viewSubs()
{
$user = User::find(Input::get('id'));
if ($submissions = Submission::find($user)->sortByDesc('created_at')) {
$submissions->load('user')->load('votes')->load('suggestions.votes');
}
return view('submissions.index' , compact('submissions'));
}
Also, depending on your DB structure I'm pretty sure you can cut out a lot of the code by utilising your models' relationships by doing something like this:
$user = User::find(Input::get('id'))
->with(['submissions' => function($query) {
$query->orderBy('created_at', 'asc');
}, 'submissions.votes', 'submissions.suggestions.votes']);
Then pass the $user variable to the view, or:
$submissions = Submission::with('user', 'votes', 'suggestions.votes')
->where('user_id', Input::get('id'))
->sortByDesc('created_at')
->first();
Not entirely sure the code will work perfectly, but I'm sure you can tweak it. The point is your code can be a lot shorter and still/or more readable by using relationships you've already set up.

Create like/unlike functionality with Laravel

I have a list of properties for a real estate application and im trying to implement a like/unlike functionality based on each property detail. The idea is to add a like or remove it matching the current property and user. This is my code so far, but it only remove likes so it doesnt work as expected. If anyone can suggest for a better approach ill be appreciated.
//Controller
public function storeLike($id)
{
$like = Like::firstOrNew(array('property_id' => $id));
$user = Auth::id();
try{
$liked = Like::get_like_user($id);
}catch(Exception $ex){
$liked = null;
}
if($liked){
$liked->total_likes -= 1;
$liked->status = false;
$liked->save();
}else{
$like->user_id = $user;
$like->total_likes += 1;
$like->status = true;
$like->save();
}
return Redirect::to('/detalle/propiedad/' . $id);
}
// Model
public static function get_like_user($id)
{
return static::with('property', 'user')->where('property_id', $id)
->where('user_id', Auth::id())->first();
}
// Route
Route::get('store/like/{id}', array('as' => 'store.like', 'uses' => 'LikeController#storeLike'));
#Andrés Da Viá Looks like you are returning object from model. In case there is no data in database, it will still return an object - so far my guessing. Can you do something like below in the if($liked){ code?
Try this instead:
if(isset($liked -> user_id)){
Also try to print $liked variable after try and catch blocks. Use var_dump.
If this still does not work for you then let me know. I will try to create code based on your question.
Fix it by adding a where clause in my model to make the status equal to True ->where('status', 1)->first();

Categories