Bigcommerce Pagination in php - php

i hope all are doing well, I am working on Bigcommerce API integration with PHP, as API fetches 50 records per page, but what i want is it starts fetching all records 50 and then from next page store it in an array and then that data should be dropped to the database, i am confused with how to pass current page id to the api
self::set_config($channel);
$page = 1;
$url=self::$current_channel->api_url."v3/catalog/products?page=$page";
$headers = self::getHeader($channel);
$body = '';
$response=self::make_api_request($url,$body,"GET",$headers);
// echo "<pre>";
// print_r($response->meta->pagination->total);
// echo "</pre>";
// exit;
if(isset($response->data)) {
foreach ($response->data as $item) {
$record = self::get_product_detail($channel,$item->id); // get detail from api
$record = isset($record->data[0]) ? $record->data[0] : NULL;
if ($record)
{
$mappedItems = [
'parent_sku_id' => null,
'sku' => $record->id,
'channel_sku' => $record->sku,
'variation_id' => $record->option_set_id,
'name' => $record->name,
'ean' => $record->upc, //$data->mpn, $data->gtin
'price' => $record->price,
'stock_qty' => isset($record->inventory_level) ? $record->inventory_level : null,
'channel_id' => self::$current_channel->id,
'is_live' => isset($record->is_visible) ? $record->is_visible : "1",
'type1' => 'main_product',
];
$parent_sku_id = self::save_channel_products((object)$mappedItems); // will return product id from products table
$headers = self::getHeader($channel);
$url=self::$current_channel->api_url."v3/catalog/products/$item->id/variants";
$server_output = self::make_api_request($url,$body,"GET",$headers);
if ($parent_sku_id && isset($record->option_set_id)) {
foreach ($server_output->data as $variation) {
$mappedItems = [
'parent_sku_id' => $parent_sku_id,
'sku' => $variation->sku_id,
//'sku' => $variation->product_id,
'channel_sku' => $variation->sku,
// 'variation_id' => $variation->sku_id,
'variation_id' => $variation->id,
'name' => $record->name,
'ean' => $variation->upc, //$variation->mpn, $variation->gtin
'price' => $variation->calculated_price,
'stock_qty' => isset($variation->inventory_level) ? $variation->inventory_level : null,
'channel_id' => self::$current_channel->id,
'is_live' => isset($record->is_visible) ? $record->is_visible : "1",
'type1' => 'variation',
];
//echo '<pre>';print_r($new_item);die;
// self::save_channel_products((object)$mappedItems);
if(isset($response->meta->pagination->total))
{
self:: $products_fetched = self:: $products_fetched + 50; // for offset
if($response->meta->pagination->total > self:: $products_fetched)
{
$lim=($response->meta->pagination->total - self:: $products_fetched);
$lim= $lim > 50 ? 50:$lim;
//self:: channelProducts(null,self:: $products_fetched ,$lim);
}
echo $page = $response->meta->pagination->current_page;
}
}
}
}
}
I am looking forward for help with php? i am little confused how to set per page request in api, every time it fetches same records in api i want to make it as per pagination changes

you can send a key from url with get method ex: p=1
and replace this code : $page = 1; with :
$page = isset($_GET['p']) ? $_GET['p'] : 1;

Related

Laravel Collection only pushing one record

When I try to push an array of records to my Laravel Collection, I end up with only the first record being inserted into the collection. It was working well before I made a few changes (related to $limit and $test) but now produces this bug.
public static function processOldOrders(int $limit = 1, bool $test = true)
{
//Read CSV and turn into a collection
$allOldOrders = Excel::toArray([], 'orders.csv');
$orderCollection = collect();
$count = 0;
foreach ($allOldOrders as $key => $oldOrder) {
$orderCollection->push(
(object) [
'order_id' => ltrim($oldOrder[$key][0], "#"),
'order_created' => $oldOrder[$key][4],
'email' => $test ? 'test#test.com' : trim(strtolower($oldOrder[$key][5])),
'phone' => ltrim($oldOrder[$key][12], "'"),
'first_name' => $oldOrder[$key][7],
'last_name' => $oldOrder[$key][8],
'purchase_status' => 'a_purchase',
'total_price' => $oldOrder[$key][33],
'items' => [],
'gift_cards' => [],
'coupons' => [],
'shipping_data' => [],
]
);
$count++;
if ($count >= $limit) {
break;
}
}
dd($orderCollection);
In your processOldOrders method by default you set limit = 1. And on the bottom,
$count = 0;
foreach ($allOldOrders as $key => $oldOrder) {
...
$count++;
if ($count >= $limit) {
break;
}
...
there you check it with count. At first time $count is equal to 0, and you plus it 1. Then you checking it with $limit. By default limit is 1 . So it works only one time. Yu have to more than one limit where you call processOldOrders method
There's nothing wrong with your code. But you forgot the output of Excel::toArray(), that it has sub-arrays.
array:1 [
0 => array [ // <-- init
0 => array [ // <-- CSV data
...
So, you can change your $allOldOrders to $allOldOrders[0] :
foreach ($allOldOrders[0] as $key => $oldOrder) {
...
}

Rearranging logic that uses multipe foreach conditions

I have some code that takes an rss feed url, expands the rss link and gets the individual links inside that feed xml. After checking if a link exists, i insert it to a table if it does not exist and do nothing if it does. However my code is becoming more unreadable and one more check that requires another foreach it shall be even more unreadable.
This is the code
public function links_cron_job(){
//Get Rss Links
$this->db->select("the_link_itself");
$query = $this->db->get_where("search_engine_links", array("link_type" => "rss"));
foreach ($query->result() as $row){
$url = $row->the_link_itself;
$rss = Feed::loadRss($url);
foreach ($rss->item as $item) {
$this->db->where('the_link_itself',$item->link);
$query3 = $this->db->get('search_engine_links');
if ($query3->num_rows() > 0){
echo 'duplicates are there';
}else{
$data = array(
'link_country' => 'usa',
'the_link_itself' => $item->link,
'link_category' => 'news_website',
'link_added_by' => 'admin',
'link_type' => 'ordinary_link',
'link_local_type' => 'news',
'link_region' => 'countrywide',
'link_city' => 'washington',
'date_added' => $item->timestamp,
'last_updated' => time()
);
$this->db->insert('search_engine_links', $data);
echo 'no duplicates are there';
}
}
}
}
What would be another approach in doing what i am doing?
Normally I would say, just enter a return. But in this case you still might have
work to do in the extra iterations. So in this case at least we know that we are
done with this iteration, so at least we can add a continue statement:
<?php
foreach ($rss->item as $item) {
$this->db->where('the_link_itself',$item->link);
$query3 = $this->db->get('search_engine_links');
if ($query3->num_rows() > 0) {
echo 'duplicates are there';
continue;
}
$data = array(
'link_country' => 'usa',
'the_link_itself' => $item->link,
'link_category' => 'news_website',
'link_added_by' => 'admin',
'link_type' => 'ordinary_link',
'link_local_type' => 'news',
'link_region' => 'countrywide',
'link_city' => 'washington',
'date_added' => $item->timestamp,
'last_updated' => time()
);
$this->db->insert('search_engine_links', $data);
echo 'no duplicates are there';
}

Parsing returns an empty value

I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.

Trying to sort my result of foreach loop on postcount

Trying to get top posters sorted on their post count obtained from an Invision powerboard API (forum software). Can't figure out how to sort this echo of my foreach loop.
$curl = curl_init( $communityUrl . '/core/members/' );
curl_setopt_array( $curl, array(
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => "{$apiKey}:"
) );
$response = curl_exec( $curl );
$data = json_decode($response, true);
$count = 0;
foreach($data as $member) {
if (is_array($member)) {
foreach($member as $name) {
if($count > 4)
return;
echo '<p class="top-member-p">'.ucfirst($name['name']).' has '.$name['posts'] . ' posts</p>';
$count++;
}
}
}
I expect to get the result sorted on their post count like so:
"Swaghetti has 34 posts"<br>
"Josh has 15 posts"<br>
"Test has 3 posts"<br>
"Testuser2 has 0 posts"
But instead it goes like this:
"Swaghetti has 34 posts"<br>
"Testuser2 has 0 posts"<br>
"Test has 3 posts"<br>
"Josh has 15 posts"
If you have no other option to retreive the data sorted, you can do it yourself - using usort() - which is sort by your own function. Compare against the other posts values, and place them accordingly in the array (return 1 if it should be moved up, -1 if it should be moved down).
I also added array_slice() in, since you appear to only want the first 4 elements (that way you only get those, and no need for a counter).
// Test-data, I guessed my way to your format to match the output from what you had in the question
$data = [
[['name' => 'Testuser2', 'posts' => 0, 'profileUrl' => 'swag']],
[['name' => 'Josh', 'posts' => 15, 'profileUrl' => 'swag']],
[['name' => 'Test', 'posts' => 3, 'profileUrl' => 'swag']],
[['name' => 'Swaghetti', 'posts' => 34, 'profileUrl' => 'swag']],
];
// $data = json_decode($response, true);
usort($data, function($a, $b) {
$a = array_column($a[0], 'posts');
$b = array_column($b[0], 'posts');
return ($a < $b) ? -1 : 1;
});
$slieced = array_slice($data, 0, 4);
foreach($slieced as $member) {
if (is_array($member)) {
foreach($member as $name) {
echo '<p class="top-member-p">
'.ucfirst($name['name']).'
has '.$name['posts'] . ' posts
</p>'."\n";
}
}
}
Live demo at https://3v4l.org/i9eDB

cant update data through array in codeigniter

i am not able to update data through array in Codeigniter (PHP),
I want to update or set column premium_id and premium to 0 when column premium_count reduce to 0
Controller Function :-
$premium_count = !empty($logged_user[0]->premium_count) ? $logged_user[0]->premium_count : '0';
if($premium_count == '0') {
$data = array(
'premium_count' => '0',
'premium_id' => '0',
'premium' => '0'
);
} else {
$data = array(
'premium_count' => $premium_count-1
);
}
$this->admin_model->updateData('users', $data, $this->session->userdata('userid'));
Model Function (sql Query) :-
public function updateData($table,$data,$id)
{
$this->db->where('id',$id);
$this->db->update($table,$data);
}
It works when premium_count has value like 1,2,3.. but when it reduce to 0, It wont update or set above column to 0.
Please try and remove the quotes from 0s.
I mean change
if($premium_count == '0') {
$data = array(
'premium_count' => '0',
'premium_id' => '0',
'premium' => '0'
);
to
if($premium_count == 0) {
$data = array(
'premium_count' => 0,
'premium_id' => 0,
'premium' => 0
);
Hope it helps.
replace this part to place zero as integer instead of string
$premium_count = !empty($logged_user[0]->premium_count) ? $logged_user[0]->premium_count : 0; // <- remove '' over zero
and check like this
if($premium_count == 0) { // <- remove '' over zero
$data = array(
'premium_count' => '0',
'premium_id' => '0',
'premium' => '0'
);
} else {
$data = array(
'premium_count' => $premium_count-1
);
}

Categories