How can I update multi rows using wherein in Laravel? - php

How can I update multi rows by id using whereIn I'm tried this, but doesn't work
if (count($request->ids) > 0) {
$downloaded = PreCreatedUser::whereIn('id', $request->ids)->update(['downloaded' => 1]);
}
return response()->json([
'message' => true,
'data' => $downloaded
], 200);

Finally I found a way to solve this, according to Laravel documentation, if you want to update multi rows by a specific data in this case an array of ids you can use for integer type data "whereIntegerInRaw", and this was my solution, and finally works.
if (count($request->ids) > 0) {
$downloaded = PreCreatedUser::whereIntegerInRaw('id', $request->ids)->update(['downloaded' => "1"]);
}
return response()->json([
'message' => true,
'data' => $downloaded
], 200);

Related

Laravel merge arrays into one

I have 2 tables and I want to make 1 array of both tables data.
Logic
User has bids
Either user is bidder which results come from bids table based on user_id column
Or user is owner and received bids which comes from projects table based on user_id column
I want to merge this 2 arrays into 1 (regardless of user being bidder or receiving bids, I want get all bids at once)
Code
This is what I have currently, but it's not good solution in case user is both bidder and owner, with current code user will only receive data of his/her bids as bidder only.
$bids = Bid::where('user_id', '=', $user->id)->with(['project', 'project.user', 'user'])->get();
if(count($bids) > 0) {
return response()->json([
'data' => BidsResource::collection($bids),
'message' => 'Your data is ready.'
], 200);
} else {
$projects = Project::where('user_id', $user->id)->pluck('id');
$bids = Bid::whereIn('project_id', $projects)->with(['project', 'project.user', 'user'])->get();
return response()->json([
'data' => BidsResource::collection($bids),
'message' => 'Your data is ready.'
], 200);
}
I have already tried array_merge but it return errors (details below).
// as bidder
$bids1 = Bid::where('user_id', '=', $user->id)->with(['project', 'project.user', 'user'])->get();
// as project owner
$projects = Project::where('user_id', $user->id)->pluck('id');
$bids2 = Bid::whereIn('project_id', $projects)->with(['project', 'project.user', 'user'])->get();
// merge results
$bids = array_merge($bids1, $bids2);
return response()->json([
'data' => BidsResource::collection($bids),
'message' => 'Data is ready.'
], 200);
array_merge Errors
Code above return array_merge(): Expected parameter 1 to be an array, object given
If I add ->get()->toArray(); then it would return Trying to get property 'id' of non-object
Any suggestions?
Update
BidsResource file
public function toArray($request)
{
$arrayData = [
'id' => $this->id,
'amount' => $this->amount ? "$ " .number_format($this->amount, 0) : "$0",
'note' => $this->note,
'attachment' => $this->attachment ? url('images', $this->attachment) : null,
'accepted' => $this->accepted,
'results' => $this->results,
'user' => new UserResource($this->whenLoaded('user')),
'project' => new ProjectsResource($this->whenLoaded('project')),
'chats' => BidChatsResource::collection($this->whenLoaded('chats')),
'created_at' => $this->created_at ? $this->created_at->diffForHumans() : null,
'updated_at' => $this->updated_at ? $this->updated_at->diffForHumans() : null,
];
return $arrayData;
}
In your specific case, the proper and efficient way would be using an OR clause to get the records where either of the conditions is satisfied.
The code would be
$projects = Project::where('user_id', $user->id)->pluck('id');
$bids = Bid::where(function($query) use ($projects, $user){
$query->where('user_id', '=', $user->id)->orWhereIn('project_id', $projects);
})->with(['project', 'project.user', 'user'])->get();
As the results of $bids1 and $bids2 are objects of laravel collection, you can use merge() method of collections#method-merge
$bids = $bids1->merge($bids2);

Phabricator, haw to take all tasks from database

I use Conduit API to create gantt chart for phabricator application. I call maniphest.search method but I have an error when I want to take more than 100 tasks.
Maximum page size for Conduit API method calls is 100, but this call specified 101.
Why? Haw Can I take all tasks? (or more than 100)
Thanks for reply.
#UPDATE:
First solution it is possible by maniphest.search method
Second solution is a loop like below - Ugly (bad practice - but you can get all nessesery fields)
for($i=0; $i <= 700; $i=$i+100){
try {
$result = $conduit->searchManiphest(
[
'queryKey' => $this->getParameter('phacility_maniphest_query_key'),
'attachments' => [
'projects' => TRUE,
'subscribers' => TRUE,
'columns' => TRUE,
'constraints' => TRUE,
],
'order' => "newest",
'after' => $i,
'limit' => 100
]
);
} catch (\Exception $e) {
$result = ['data' => []];
}
foreach($result['data'] as $item){
$all_result['data'][] = $item;
}
}

Laravel Fractal Optional fields

I am using fractal for my small project, here is my code:
public function transform(Series $series) {
return [
'id' => $series->id,
'title' => $series->title,
'url' => $series->url,
'description' => $series->description,
'thumbnail_hd' => $series->thumbnail_hd,
'thumbnail_wide' => $series->thumbnail_wide,
'views' => $series->views
];
}
I would like to make views (which is an int) optional and not return the views unless requested - since this field is based on a relationship and will increase the processing time.
I would like to use it as relationships (so i can include particular fields whenever I need to):
// in transformer
public function includeUser(Series $series) {
return $this->item($series->user, new UserTransformer);
}
// in controller
return fractal()
->item($series)
->parseIncludes(['user'])
->transformWith(new SeriesTransformer)
->toArray();
But just for an integer instead of a whole array of data. Is it possible using Fractal?
What you can do is the following
public function transform(Series $series) {
$return = [
'id' => $series->id,
'title' => $series->title,
'url' => $series->url,
'description' => $series->description,
'thumbnail_hd' => $series->thumbnail_hd,
'thumbnail_wide' => $series->thumbnail_wide,
];
if ($series->views > 0) {
$return['views'] = (int) $series->views;
}
return $return;
}
I wouldn't suggest doing this though. I would usually just return views as 0.
If you're worried about your DB performance, your app is going to have to count the views anyway to know if they're greater than 0.
If you worried about client side performance, this is not going to matter with a single key value pair.

Symfony 2 / PHP compare the difference of objects in arrays?

I am using Symfony 2.7 I have built a form with an entity, which when submitted returns an array of objects. I need to be able to compare this array of objects with what I have in the that table?
So this is how I have the form setup
$builder
.......
->add('my_options', 'entity', [
'label' => 'Options:',
'class' => 'xxxxBundle:Details',
'choice_label' => 'Title',
'multiple' => true,
'expanded' => true,
'required' => false,
'mapped' => false,
'data' => $data,
'attr' => ['class' => 'AdminList'],
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('de')
->where('de.active = ?1')
->setParameter(1, 1); }
]);
I then do a basic lookup of what my options table has already got,
$EditPanels = $this->getDoctrine()
->getRepository('xxxBundle:Options')
->findBy(['AccountID' => $AcID]);
This gives me two arrays, one of which the user has just selected (the options they now need on this account) and one with what is already in the database table.
How do I compare these tables to update the rows with the new options, by removing whats not needed and adding in the new options?
Thanks.
$newIds = array_map($formData, function (Details $d) {
return $d->id;
});
$oldIds = array_map($EditPanels, function (Details $d) {
return $d->id;
});
$shouldBeRemoved = array_diff($oldIds, $newIds);
$shouldBeAdded = array_diff($newIds, $oldIds);
Now you have all the IDs for the Options that need to change. Hope this helps.
I think you should not even query for existing records. Instead you can:
Persist all new records and update existing:
foreach ($new as $object) {
if ($object->getId() === null) {
$em->persist($object);
}
}
$em->flush();
Delete all other records from database:
$qb = $em->getRepository('xxxxBundle:Details')->createQueryBuilder();
$qb->delete()->where($qb->expr()->notIn('id', array_column('id', $new)));
P.S. Not sure regarding the syntax, but you got the idea.

Returning paginated eloquent models with custom JSON schema?

I'm working on an API in Laravel 4, and right now when I return paginated info in JSON format it comes back in this specific format:
{
"Photos":{
"total":1,
"per_page":15,
"current_page":1,
"last_page":1,
"from":1,
"to":1,
"data":[
{
"id":3,
"moreInfo":"..."
}
]
}
}
But I want my API to instead return the information in this format:
{
"total":1,
"per_page":15,
"current_page":1,
"last_page":1,
"from":1,
"to":1,
"Photos":[
{
"id":3,
"moreInfo":"..."
}
]
}
The relevant code looks like:
if (Input::has('page')) {
$limit = (Input::get('limit')) ? Input::get('limit') : 15;
return Response::json([
'Photos' => $photos->paginate($limit)->toArray()
]);
}
At first I didn't realize how simple this actually is, I tried getting data via the Pagination->getItems() and Pagination->getCollection().
I realized all I had to do was get the ['data'] section from the pagination. My code now looks like:
if (Input::has('page')) {
$limit = (Input::get('limit')) ? Input::get('limit') : 15;
$pagedPhotos = $photos->paginate($limit);
return Response::json([
'total' => $pagedPhotos->getTotal(),
'per_page' => $pagedPhotos->getPerPage(),
'current_page' => $pagedPhotos->getCurrentPage(),
'last_page' => $pagedPhotos->getLastPage(),
'from' => $pagedPhotos->getFrom(),
'to' => $pagedPhotos->getTo(),
'Photos' => $photos->paginate($limit)->toArray()['data']
]);
}
So strip out the photos component:
return Response::json($photos->paginate($limit)->toArray())

Categories