I need a loop inside a model query - php

How can I loop in a model?
I have:
SitemapGenerator::create(config('app.url'))
->configureCrawler(function (Crawler $crawler) {
$crawler->setMaximumDepth(4);
})
->add(Url::create('https://mydomain/mycustompage/'))
->getSitemap()
->writeToFile(public_path('sitemap.xml'));
I need someway to loop this: ->add(Url::create('https://mydomain/mycustompage/'))
I want to get info from my DB like this:
$all_active_products = DB::table('products')->select('slug')->where('is_active',1)->whereNull('deleted_at')->get();
And I want something like this:
$all_active_products = DB::table('products')->select('slug')->where('is_active',1)->whereNull('deleted_at')->get();
SitemapGenerator::create(config('app.url'))
->configureCrawler(function (Crawler $crawler) {
$crawler->setMaximumDepth(4);
})
foreach ($all_active_products as $a){
->add(Url::create('https://mydomain/mycustompage/'.$a->slug))
}
->getSitemap()
->writeToFile(public_path('sitemap.xml'));
I am using this package.

$products = Product::all();
//or
$products = Product::with('categories')->where('status', 1)->whereRaw('quantity is not null AND quantity > 0 ', 1)->whereNotNull('price');
//or
$products = Product::select([
'*',
DB::raw('(CASE
WHEN sale_price is not null AND ( now() = sale_from THEN sale_price
ELSE price
END) product_price')
])->where('status', 1)->whereNotNull('price');
//now for loop
foreach ($products as $key=>$product) {
echo $product->name;
}

Related

Lumen - pagination and result editing

I'm new to Lumen and trying to make a simple REST API app. I want one of the endpoints to be able to display all records from a "storeItems" table but add a field to each record with its' categories and paginate them.
So at the moment I have the usual
$products = DB::table('storeItems as i')
->where('i.B2BAvailable', '=', '1')
->select('i.title','i.EAN','i.vendor','i.productType','i.ID as productID','i.releaseDate',DB::raw('(CASE WHEN (i.releaseDate > NOW()) THEN 1 ELSE 0 END) AS announced'))
->orderBy('i.releaseDate', 'desc')
->paginate(100);
return response()->json($products);
This gives out the expected result, but if I want to iterate over the results and add a field from a different table...like this:
foreach($products as $product) {
$genres = DB::table('sCategoryConnector as ggc')
->join('sCatGenre as gg','gg.ID','=','ggc.ID_sCatGenre')
->where('ggc.EAN', '=', DB::raw("'".$product->EAN."'"))
->select('gg.tag')
->orderBy('gg.ID', 'asc')
->get();
if (count($genres) > 0) {
$i=0;
foreach($genres as $genre) {
//$product['genres'][$i] = $genre['tag'];
$propName = 'genre'.$i;
$product->genres->$propName = $genre->tag;
$i++;
}
}
}
But Lumen is outputting: Creating default object from empty value error and marking this line:
$product->genres->$propName = $genre->tag;
What am I doing wrong? Thanks up front.
So I was rushing a bit...should have replaced assigning genres like this:
if (count($genres) > 0) {
$i=0;
$product->genres = $genres;
/*
foreach($genres as $genre) {
//$product['genres'][$i] = $genre['tag'];
$propName = 'genre'.$i;
$product->genres->$propName = $genre->tag;
$i++;
}
*/
}
So the correct way to assign a new property to a StdClass object....
$product->genres = $genres;

How to extract data from JSON - Laravel & JSON

This is how my json looks like ["Chicken",{"quantity":"1"},"Froggies",{"quantity":"2"},"Fryies",{"quantity":"3"}].
Is there a way that i can get the data out the results like
Chicken : 1, Froggies:2, Fryies:3
I tried to use implode to get this done but i get an error saying array to string conversion,
Below is my code
foreach($request->get('item_id') as $key => $id)
{
$selected_item = Item::all()->where('id',$id);
foreach($selected_food as $select)
{
$food_selected[]= $select->name ;
$food_selected[] = ['quantity' => $request->get('quantity')[$key]];
}
}
$query ="Your items are ".implode(',',$food_selected)."";
Maybe array of objects would be more useful in that situation, which you could get this way:
$arr = [];
foreach ( $request->get('item_id') as $key => $id ) {
$selected_item = Item::all()->where('id', $id);
foreach ( $selected_item as $select ) {// $selected_item or $selected_food here
/*
$obj = new stdClass;
$obj->{$select->name} = $request->get('quantity')[$key];
$arr[] = $obj;*/
$arr[$select->name] = (int) $request->get('quantity')[$key];
}
}
$query = '';
foreach ( $arr as $k => $v ) {
$query .= ' '.$k.': '.$v.',';
}
$query = rtrim($query, ',');
$query = ltrim($query);
$query = "Your items are ".$query;
I assume that the ID is unique key for an Item and your Item::all()->where('id',$id) will return only one record. If this is true, the second loop is unnecessary.
Based on this assumption, I come to this code:
$result = collect($request->get('item_id'))
->map(function($itemId, $itemKey) use ($request) {
$item = Item::find($itemId);
return $item->name . ' : ' . $request->get('quantity')[$itemKey];
})->implode(',');
// $result contains the string: "Chicken : 2, Fries : 1"
For explanation:
Cast the array into a collection
Use map to loop over it
Find the Item by its ID
Return the name and the quantity (this returns a collection)
Implode the collection

PHP function for returning array with unique indexes

I have a simple problem. Lets say I have an array
Array
0
product_id 233
slug "zotac-geforce-gtx-1070-amp-extreme-edition-8gb-zt-p10700b-10p"
1
product_id 227
slug "zotac-geforce-gtx-1060-mini-6gb-gddr5-zt-p10600a-10l"
2
product_id 233
slug "zotac-geforce-gtx-1070-amp-extreme-edition-8gb-zt-p10700b-10p"
Now if you see there are two products having same product_id! I don't want that I am trying to get this array filtered from duplicate products
This is what I tried but it doesn't work
$temp_products = array();
foreach($products as $product)
{
if(count($temp_products) > 0)
{
foreach($temp_products as $temp_product)
{
if($temp_product['product_id'] != $product['product_id'])
{
$temp_products[] = $product;
}
}
}
else
{
$temp_products[] = $product;
}
}
It returns the same array as the original one. and $products is the main array having the data.
Try this! But I would definitely suggest using array_filter or array_unique will post an example later. Try this.
$temp_products = array();
$count = 0;
foreach($products as $product)
{
if(count($temp_products) > 0)
{
//foreach($temp_products as $temp_product)
//{
if($temp_products[$count]['product_id'] != $product['product_id'])
{
$temp_products[] = $product;
}
//}
}
else
{
$temp_products[] = $product;
}
}
Using array_unqiue
foreach($products as $product)
{
$temp_products[] = $product;
}
dd(array_unique($temp_products));
Another way would be to use a helper array to keep track of already present ids.
$temp_products = array();
$already_present = array();
foreach($products as $product)
{
$id = $product['product_id'];
if ( isset($already_present[ $id ] ) ) continue;
$temp_products[] = $product;
$already_present[ $id ] = '';
}
$products = $temp_products;

How to compare values in a single foreach loop php

I am working on opencart.I dont want to allow users to add same product multiple times in cart. for this i have a logic that i want to compare the products in cart. I will get the the product id of each product(how many the user added by clicking add to cart) than i will compare those ids. If they are same i will show them error message else they can carry on. For this logic i have used this code till now.
$products = $this->cart->getProducts();
foreach ($products as $product)
{
$p_id=$product['product_id'];
}
But i dont get that how will i compare 2 product ids in foreach loop. and than add my logic that if product ids are equal show error message.
You can simply check it at the time when user add a product to cart. To do so modify add function in controller->checkout->cart.php
In public function add() {
Add
$products = $this->cart->getProducts();
if($products){
foreach ($products as $product)
{
if($this->request->post['product_id'] == $product['product_id']){
$json['error']['blabla'] = 'Your warning message.';
break;
}
}
}
Before
if (!$json) {
And display that error wherever you want to display. That's it.
you can get the value of new product id and than compare it like this
//get product id to be added
$new_product = "get ID";
$products = $this->cart->getProducts();
foreach ($products as $product)
{
$p_id=$product['product_id'];
//compare with new product_id with existing
if ($_pid == $new_product){
echo " Product already exists!!";
}
}
$products = $this->cart->getProducts();
$exist = false;
foreach ($products as $product)
{
if ($p_id == $product['product_id']) {
$exist = true;
break;
}
}
if (!$exist) {
//add product co cart
}
Try this way
$products = $this->cart->getProducts();
$p_id = '';
foreach ($products as $product)
{
if($p_id != $product['product_id']) {
$p_id=$product['product_id'];
}else{
echo " Product already exists!!";
}
}
This will get you both a unique list of ID's and a list of ID's that needed to be removed to make the list unique.
// get the list of ID's
$products = $this->cart->getProducts();
$all = array();
foreach ($products as $product)
{
$all[] = $product['product_id'];
}
// Flip the array twice to just get the unique ID's
$unique = array_flip(array_flip($all));
// Get a list of ID's that were lost
$difference = array_diff_assoc($all, $unique);

get an array of all categories with details in Magento

I want to be able to call through the API to get an array of all the categories with the details like the URL key. That goal in the end will be an array like this
$massage_cats=array(
array("entity_id"=>78,
"name"=>"Massage Oils and Tools",
"url_key"=>"massage-oils-and-tools",
"url_path"=>"essential-accessories/massage-oils-and-tools.html"),
array("entity_id"=>79,
"name"=>"Massage Oils",
"url_key"=>"massage-oils",
"url_path"=>"essential-accessories/massage-oils-and-tools/massage-oils.html")
);
So I would want to call out something like
$massage_cats= array();
$allcats = Mage::getModel('catalog/cats?')->loadAll();
foreach($allcats $k=>$item){
array_push($massage_cats,$item->loadDetails());
}
I know that is totally made up and not real to the API but that is basically the goal. I do need the output as I showed it. Ideas on the code to achieve the need?
This will get your values. You can build your array however you like from here.
$categories = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('id')
->addAttributeToSelect('name')
->addAttributeToSelect('url_key')
->addAttributeToSelect('url')
->addAttributeToSelect('is_active');
foreach ($categories as $category)
{
if ($category->getIsActive()) { // Only pull Active categories
$entity_id = $category->getId();
$name = $category->getName();
$url_key = $category->getUrlKey();
$url_path = $category->getUrl();
}
}
EDIT
I adapted this from a post on MagentoCommerce.com. You can use this instead:
$category = Mage::getModel('catalog/category');
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
if ($ids){
foreach ($ids as $id){
$cat = Mage::getModel('catalog/category');
$cat->load($id);
$entity_id = $cat->getId();
$name = $cat->getName();
$url_key = $cat->getUrlKey();
$url_path = $cat->getUrlPath();
}
}
HERE I WROTE FUNCTION UPTO THREE LEVELS RETURN IN ARRAY FORMAT
$array=hpCat(2,3); //categoryID,Sublevel upto three level
print_r($array);
<?php
function hpCat($id,$level=0){
if(!empty($id)){
$level=empty($level)?0:$level;
$category = Mage::getModel('catalog/category')->load($id);
$levelOneItems = $category->getChildrenCategories();
if (count($levelOneItems) > 0){
$array=hpCatDetails($category);
if($level>=1):
$i=0;
foreach($levelOneItems as $levelOneItem){
$array['sub'][$i]=hpCatDetails($levelOneItem);
$leveltwoItems=$levelOneItem->getChildrenCategories();
if (count($leveltwoItems) > 0){
if($level>=2):
$j=0;
foreach($leveltwoItems as $leveltwoItem){
$array['sub'][$i]['sub'][$j]=hpCatDetails($leveltwoItem);
$levelthreeItems=$leveltwoItem->getChildrenCategories();
if (count($levelthreeItems) > 0){
if($level>=3):
$k=0;
foreach($levelthreeItems as $levelthreeItem){
$array['sub'][$i]['sub'][$j]['sub'][$k]=hpCatDetails($levelthreeItem);
$k++;
}
endif;
}
$j++;
}
endif;
}
$i++;
}
endif;
}
return $array;
}
return array();
}
function hpCatDetails($cat){
return array('name'=>$cat->getName());
}
$array=hpCat(2,3);//categoryID,Sublevel upto three level
echo '<pre>';print_r($array);die();
?>
For the people looking for MySQL query to fetch all Magento categories.
SELECT
e.entity_id AS id,
e.parent_id,
e.path,
e.`level`,
IF (
at_name.value_id > 0,
at_name.
VALUE
,
at_name_default.
VALUE
) AS `name`
FROM
`catalog_category_entity` AS `e`
INNER JOIN `catalog_category_entity_varchar` AS `at_name_default` ON (
`at_name_default`.`entity_id` = `e`.`entity_id`
)
AND (
`at_name_default`.`attribute_id` = '41'
)
LEFT JOIN `catalog_category_entity_varchar` AS `at_name` ON (
`at_name`.`entity_id` = `e`.`entity_id`
)
AND (
`at_name`.`attribute_id` = '41'
)
A recursive function to make it :
private function __categoriesTree($id = 2) {
$category = Mage::getModel('catalog/category');
$_category = $category->load($id);
$details = new stdClass();
list($details->id, $details->name, $details->urlKey, $details->level, $details->children) = [
$_category->getId(),
$_category->getName(),
$_category->getUrlKey(),
$_category->getLevel(),
[]
];
foreach (array_filter(explode(',', $_category->getChildren())) as $childId) {
$details->children[] = $this->__categoriesTree($childId);
}
if (count($details->children) === 0) {
unset($details->children);
}
return $details;
}
And
$categoriesTree= $this->categoriesTree()
I prefer to use objects than arrays to model a node but you can easily replace.

Categories