laravel retrieve json and save into database - laravel

I am getting cinema title + times using API from Cinelist, I then want to save these values into a database.
At the moment, it does save but only 1 record, the last one. However, I want it to save each one.
Also each time it is run I want to update existing records instead of creating new ones unless there are more results.
So usually there are 5 records, each time I run the function I want to update the database with the new 5 records, however, if it's a different day and there are 6 records I want to update 5 records and insert 1 extra one so there is 6.
My code so far:
function odeon(){
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/10565');
$data = json_decode($data);
foreach($data->listings as $listing){
$title = $listing->title;
$time = implode(', ', $listing->times);
$id = + 1;
$films = Film::where('id', $id)->first();
if (!$films) {
$films = new Film();
}
$films->title = $title;
$films->times = $time;
$films->save();
}
}

You may use eloquent's updateOrCreate method to insert non-existent data and update existing data.
function odeon(){
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/10565');
$data = json_decode($data);
foreach($data->listings as $listing){
$title = $listing->title;
$time = implode(', ', $listing->times);
Films::updateOrCreate([
'title' => $title,
'$times' => $time
]);
}
}

Related

Laravel : How can i get old and new value by updateOrCreate

I want update or create in data base
but i want get the old value and updated value because i want to compare between these two value
for example
this item in table user
name = Alex and Order = 10
so now i want update this person by
name = Alex and Order = 8
Now After updating or creating if not exist
just for update i want get
Old order 10 | And new Order 8
I want compare between these order
i have tryin getChange() and getOriginal() but two the function give me just the new value.
Please Help
You can get the old value using getOriginal if you have the object already loaded.
For example :
$user = User::find(1);
$user->first_name = 'newname';
// Dumps `oldname`
dd($user->getOriginal('first_name'));
$user->save();
However in case of updateOrCreate, you just have the data. I am not sure about a way to do it using updateOrCreate but you can do simply do :
$user = User::where('name', 'Alex')->first();
$newOrder = 10;
if($user){
$oldOrder = $user->getOriginal('order');
$user->order = $newOrder;
$user->save();
}
Is the name unique in the table? Because if it is not you will have updates on multiple rows with the same data.
So the best approach is to use the unique column which is probably the ID.
User::updateOrCreate(
[ 'id' => $request->get('id') ], // if the $id is null, it will create new row
[ 'name' => $request->get('name'), 'order' => $request->get('order') ]
);
Solution
$model = Trend::where('name', $trend->name)->first();
if ($model) {
$model->old_order = $model->getOriginal('order');
$model->order = $key + 1;
$model->save();
} else {
Trend::where('order', $key + 1)->delete();
$new = new Trend();
$new->name = $trend->name;
$new->old_order = $key + 1;
$new->order = $key + 1;
$new->tweet_volume = $trend->tweet_volume;
$new->save();
}

laravel change url and id on each loop

I have something like this:
function odeon(){
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/10565');
$data = json_decode($data);
$id = 1;
foreach($data->listings as $listing){
$title = $listing->title;
$time = implode(', ', $listing->times);
$business_id = 1;
$film = Film::where('id', $id)->first();
$id = $id + 1;
// if news is null
if (!$film) {
$film = new Film();
}
$film->title = $title;
$film->times = $time;
$film->business_id = $business_id;
$film->save();
}
return view('odeon')->with(['listings' => $data->listings]);
}
What I want to do is add more cinemas so instead of:
$data=
file_get_contents('https://api.cinelist.co.uk/get/times/cinema/10565');
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/6756');
Be something like:
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/6756-10565');
So to go throught from numbers 6756 to 10565, problem is this as well as each cinema has a different business_id I don't want to replicate function for each cinema so any help will be appreciated ;)
Another issue is what if another day therewill be less films than previous day, of course I don't want to display yesturdays films for today
//edit
Ok I will do my best to explain what I want to achieve.
I want to loop throught a cinema, retrieve films for today, save into database, retrieve data for tomorrow save into database, etc. I want to do it for 7 days, Now for each cinema, cinema id + date changes:
https://api.cinelist.co.uk/get/times/cinema/10565?day=2017-06-14
Would bring me back films for today, but I want to achieve it for 7 days so something like this:
$cinema_id=['10', '20'] (number = cinema_id)
$startdate = strtotime("today");
$enddate = strtotime("+7 Days");
while ($startdate < $enddate) {
echo date("Y-m-d", $startdate) . "<br>";
$startdate = strtotime("+1 Days", $startdate);
}
$data= file_get_contents (https://api.cinelist.co.uk/get/times/cinema/$cinema_id?day=$startdate)
So basically I want to loop throught array of cinema and for each cinema_id, go throught 7 days ahead and save details to database. Of course I don't want to keep old records, so each day they either have to be removed or updated
Your question is vague but probably you mean this...
function odeon(){
$arrayOfCinemaIds = [10565,6756];
foreach($arrayOfCinemaIds as $id){
//append your id
$data= file_get_contents('https://api.cinelist.co.uk/get/times/cinema/'.$id);
$data = json_decode($data);
$id = 1;
foreach($data->listings as $listing){
$title = $listing->title;
$time = implode(', ', $listing->times);
$business_id = 1;
$film = Film::where('id', $id)->first();
$id = $id + 1;
// if news is null
if (!$film) {
$film = new Film();
}
$film->title = $title;
$film->times = $time;
$film->business_id = $business_id;
$film->save();
}
$listings[]=$data->listings;
}
//$listings will have all the listings from all the loops
return view('odeon')->with(['listings' => $listings]);
}
You will just need to add more entries to $arrayOfCimenaIds as you need. Typically you would load them up from a Db or other data store.
EDIT:
If you have a sequence of numbers you dont need the array you can do
for($id=6756;$id<=10565;$id++){..}
instead of the foreach()

Laravel: how to update records values coming as arrow

I am new to Laravel and I need to update records coming as array from a form.
$a = $request->id;
$b = $request->val;
Now I need to update the records
Details::find($b)->update(['detail'=>$a]);
The script above obviously does not work...
You can do it in more than one way, try this :
$details = Details::find($request->input($id));
$details->val = $request->input('val');
$details->save();
Or you can use this if the inputs has the same name as the model fields:
$details = Details::findOrFail($request->input($id));
$details->update($request->all());
You can update in the following ways. Assuming detail is your field name to update.
$id = $request->id;
$val = $request->val;
$detail = Details::findOrFail($id);
$detail->detail = $val;
$detail->save();
For the below to work. You need to set the $fillable propery in the model
// In Detail model
protected $fillable = ['detail'];
// Controller
Details::where('id', $id)->update([
'detail' => $val
]);
$a = $request->id;
$b = $request->val;
$detail = Detail::where('id', $a)->first();
$detail->update(['detail' => $b]);

How to create a paginator?

I've checked out the rather thin docs, but still unsure how to do this.
I have a collection. I wish to manually create a paginator.
I think I have to do something like, in my controller:
new \Illuminate\Pagination\LengthAwarePaginator()
But, what params do I need and do I need to slice the collection? Also how do I then display the 'links' in my view?
Could someone post a simple example how to create a paginator?
Please note, I don't want to paginate eloquent, eg. User::paginate(10);
Take a look at the Illuminate\Eloquent\Builder::paginate method for an example on how to create one.
A simple example of doing one using an eloquent model to pull out the results etc:
$page = 1; // You could get this from the request using request()->page
$perPage = 15;
$total = Product::count();
$items = Product::take($perPage)->offset(($page - 1) * $perPage)->get();
$paginator = new LengthAwarePaginator(
$items, $total, $perPage, $page
);
The first parameter accepts the results to display on the page that you're on
the second is the total number of results (The total number of items you're paginating, not the total number of items you're displaying on that page)
the third is the number per page you want to display
the fourth is the page that you're on.
You can pass in extra options as a fifth parameter if you want to customise things as well.
The links you should just be able to generate using the ->render() or ->links() method on the paginator as you would if you used Model::paginate()
With an existing collection of items you could do this:
$page = 1;
$perPage = 15;
$total = $collection->count();
$items = $collection->slice(($page - 1) * $perPage, $perPage);
$paginator = new LengthAwarePaginator(
$items, $total, $perPage, $page
);
You can create a Paginator like this:
$page = request()->get('page'); // By default LengthAwarePaginator does this automatically.
$collection = collect(...array...);
$total = $collection->count();
$perPage = 10;
$paginatedCollection = new \Illuminate\Pagination\LengthAwarePaginator(
$collection,
$total,
$perPage,
$page
);
According to the source code for LengthAwarePaginator (constructor)
public function __construct($items, $total, $perPage, $currentPage = null, array $options = [])
{
foreach ($options as $key => $value) {
$this->{$key} = $value;
}
$this->total = $total;
$this->perPage = $perPage;
$this->lastPage = (int) ceil($total / $perPage);
$this->path = $this->path != '/' ? rtrim($this->path, '/') : $this->path;
$this->currentPage = $this->setCurrentPage($currentPage, $this->pageName);
$this->items = $items instanceof Collection ? $items : Collection::make($items);
}
See more about LengthAwarePaginator
To display links in the view:
$paginatedCollection->links();
Hope this helps!

How to validate duplicate entries before inserting to database - Codeigniter

I have developed simple application, i have generated checkbox in grid dynamically from database, but my problem is when user select the checkbox and other required field from grid and press submit button, it adds duplicate value, so i want to know how can i check the checkbox value & other field value with database value while submitting data to database.
following code i use to generate all selected items and then save too db
foreach ($this->addattendee->results as $key=>$value)
{
//print_r($value);
$id = $this->Attendee_model->save($value);
}
i am using codeigniter....can any one give the idea with sample code plz
{
$person = $this->Person_model->get_by_id($id)->row();
$this->form_data->id = $person->tab_classid;
$this->form_data->classtitle = $person->tab_classtitle;
$this->form_data->classdate = $person->tab_classtime;
$this->form_data->createddate = $person->tab_crtdate;
$this->form_data->peremail = $person->tab_pemail;
$this->form_data->duration = $person->tab_classduration;
//Show User Grid - Attendee>>>>>>>>>>>>>>>>>>>>>>>>
$uri_segment = 0;
$offset = $this->uri->segment($uri_segment);
$users = $this->User_model->get_paged_list($this->limit, $offset)->result();
// generate pagination
$this->load->library('pagination');
$config['base_url'] = site_url('person/index/');
$config['total_rows'] = $this->User_model->count_all();
$config['per_page'] = $this->limit;
$config['uri_segment'] = $uri_segment;
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
// generate table data
$this->load->library('table');
$this->table->set_empty(" ");
$this->table->set_heading('Check', 'User Id','User Name', 'Email', 'Language');
$i = 0 + $offset;
foreach ($users as $user)
{
$checkarray=array('name'=>'chkclsid[]','id'=>'chkclsid','value'=>$user->user_id);
$this->table->add_row(form_checkbox($checkarray), $user->user_id, $user->user_name, $user->user_email,$user->user_language
/*,anchor('person/view/'.$user->user_id,'view',array('class'=>'view')).' '.
anchor('person/update/'.$user->user_id,'update',array('class'=>'update')).' '.
anchor('person/showattendee/'.$user->user_id,'Attendee',array('class'=>'attendee')).' '.
anchor('person/delete/'.$user->user_id,'delete',array('class'=>'delete','onclick'=>"return confirm('Are you sure want to delete this person?')"))*/ );
}
$data['table'] = $this->table->generate();
//end grid code
// load view
// set common properties
$data['title'] = 'Assign Attendees';
$msg = '';
$data['message'] = $msg;
$data['action'] = site_url('person/CreateAttendees');
//$data['value'] = "sssssssssssssssssss";
$session_data = $this->session->userdata('logged_in');
$data['username'] = "<p>Welcome:"." ".$session_data['username']. " | " . anchor('home/logout', 'Logout')." | ". "Userid :"." ".$session_data['id']; "</p>";
$data['link_back'] = anchor('person/index/','Back to list of Classes',array('class'=>'back'));
$this->load->view('common/header',$data);
$this->load->view('adminmenu');
$this->load->view('addattendee_v', $data);
}
The code is quite messy but I have solved a similar issue in my application I think, I am not sure if its the best way, but it works.
function save_vote($vote,$show_id, $stats){
// Check if new vote
$this->db->from('show_ratings')
->where('user_id', $user_id)
->where('show_id', $show_id);
$rs = $this->db->get();
$user_vote = $rs->row_array();
// Here we are check if that entry exists
if ($rs->num_rows() == '0' ){
// Its a new vote so insert data
$this->db->insert('show_ratings', $rate);
}else{
// Its a not new vote, so we update the DB. I also added a UNIQUE KEY to my database for the user_id and show_id fields in the show_ratings table. So There is that extra protection.
$this->db->query('INSERT INTO `show_ratings` (`user_id`,`show_id`,`score`) VALUES (?,?,?) ON DUPLICATE KEY UPDATE `score`=?;', array($user_id, $show_id, $vote, $vote));
return $update;
}
}
I hope this code snippet gives you some idea of what to do.
maybe i have same trouble with you.
and this is what i did.
<?php
public function set_news(){
$this->load->helper('url');
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$query = $this->db->query("select slug from news where slug like '%$slug%'");
if($query->num_rows()>=1){
$jum = $query->num_rows() + 1;
$slug = $slug.'-'.$jum;
}
$data = array(
'title' => $this->input->post('title'),
'slug' => $slug,
'text' => $this->input->post('text')
);
return $this->db->insert('news', $data);
}
?>
then it works.

Resources