Jump to content
dfile

How to count products in categories if the product-pages are not in the category tree?

Recommended Posts

Hello, i must count products per category like so:

category 1 (4 products)
--category 1.1 (2 products)
----category 1.1.1 (1 product)

and so on.

category 1
--category 1.1
----category 1.1.1
----category 1.1.2
----category 1.1.3

--category 1.2
----category 1.2.1
----category 1.2.2
----category 1.2.3

produkts have page references for the categories:

product 1
-- page reference->category 1.1.1
-- page reference->category 1.1.3
-- page reference->category 1.2.2
-- page reference->category 1.2.3

what is the best way to do this, i have many categories and many many products.
Thank you.

 

Share this post


Link to post
Share on other sites
1 hour ago, Matzn said:

Hi,

use $pages->count https://processwire.com/api/ref/pages/count/ 

for each category like:


$cnt = $pages->count('parent=yourCategory,id=yourProductId');

 

yes, i know count, so far i have this result, but only for level 3 of the categories:

//categories level3
$kategorienId=getCategoryLevel3($page);

$produktCount=WireArray();

foreach ($kategorienId as $id){
    $count=$pages->count("template=produkt, pro_kategorie=$id");
    $produktCount->add($count);
}
$kategorienId->data('count', $produktCount);

var_dump($kategorienId->data('count'));

and this is the ugly function getCategoryLevel3:

function getCategoryLevel3($page){
    $pages=wire('pages');
    $id=WireArray();
    $p='';
    $data='';
    if ($page->children!=''){
        $children=$page->children;
        //level2
        foreach($children as $children2){    
            if($children2->children!=''){
                //level3
                foreach($children2->children as $children3){
                    if($children3->children!=''){
                        foreach($children3->children as $child3){
                            //level3 add id    
                            $id->add($child3->id);
                        }
                    }
                }
            }
        }
    }
    return $id;
}

there is a better way to do this?
I also need the number of products for level2 and level1.

Share this post


Link to post
Share on other sites

Your function returns only category 3. To get all pages (categories) in you category tree you can

$kategorien = $page->find();

//or

$kategorien = $page->descendants();

After count your products for each category

foreach ($kategorien as $kategorie){

    $count = $pages->count("template=produkt, pro_kategorie={$kategorie->id}");

	echo $count . " Produkte in Kategorie " . $kategorie->title;
}

 

Share this post


Link to post
Share on other sites

The page reference field (pro_kategorie) have only the level 3 category.
Here i can count the products, but then i have to go up to  level 2  and
add all products in all level 3 categories to the count of level 2.

Sorry if that was not clear.

 I have to search the categories from bottom to top like this
$parentId=$pages->find($id)->parent();
this doesn't make things easy in processwire, or did I miss something?

Share this post


Link to post
Share on other sites

if I understood correctly your situation, you can simply use the numReferences of the pro_kategorie field

 

Share this post


Link to post
Share on other sites

Thanks for your feedback.

I ended up doing this:
For each product I store the parend category for each category in the page reference field. This way I can easy count all products in the parent category.

$this->addHookBefore('Pages::saved', function(HookEvent $event) {
$pages = $event->object;
$page = $event->arguments(0);

	if($page->template == 'produkt') {
		//remove parent kategorie
		foreach($page->pro_kategorie_parent as $item) {
			$page->pro_kategorie_parent->remove($item);
		}
		$page->save(pro_kategorie_parent);
		
		foreach($page->pro_raeume_parent as $item) {
			$page->pro_raeume_parent->remove($item);
		}
		$page->save(pro_raeume_parent);
		
		//add parent kategorie
		if ($page->pro_kategorie){
			foreach($page->pro_kategorie as $item) {
			$cat_parent=$item->parent;
			$page->setAndSave(pro_kategorie_parent, $cat_parent);
			}
		}
		if ($page->pro_raeume){
			foreach($page->pro_raeume as $item) {
			$raum_parent=$item->parent;
			$page->setAndSave(pro_raeume_parent, $raum_parent);
			}
		}
	}
});

435213912_Screenshot2020-11-06110029.jpg.f7942dab4bff598b1cbd8557870f462c.jpg

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Rossie
      Hi Everyone,
      I wish to display a gallery of images from multiple pages on the site.  These images have custom fields created through page reference called 'furniture_list_type'.  Each image now has a radio button which has been selected.
      In  the example code below all images appear from the "gallery20", however the selector  "gallery20.furniture_list_type=3390" does not have any effect.  "3390" is the id of the page reference "chair" selected through the page reference.  I wish only images selected as chair to show.
      Hope someone can help with this.
       
      Thanks,
       
      Calum
       
      $imagePages = $pages->find("template=makers-child, gallery20.furniture_list_type=3390") ;                     foreach($imagePages as $p) {     echo "<ul>";     foreach($p->gallery20 as $image) {         echo "<li><img src='{$image->url}'>{$image->furniture_list_type}</li>";     }     echo "</ul>";      }
    • By Robin S
      Page Reference Default Value
      Most ProcessWire core inputfield types that can be used with a Page Reference field support a "Default value" setting. This module extends support for default values to the following core inputfield types:
      Page List Select Page List Select Multiple Page Autocomplete (single and multiple) Seeing as these inputfield types only support the selection of pages a Page List Select / Page List Select Multiple is used for defining the default value instead of the Text / Textarea field used by the core for other inputfield types. This makes defining a default value a bit more user-friendly.
      Note that as per the core "Default value" setting, the Page Reference field must be set to "required" in order for the default value to be used.
      Screenshot

       
      https://github.com/Toutouwai/PageReferenceDefaultValue
      https://modules.processwire.com/modules/page-reference-default-value/
    • By jds43
      Hello, I'm trying to list the categories, on the front through select options, that have been selected by page reference field (multiple pages PageArray) on the child pages.
      Things to Do (would only display three, six, seven, nine in select)
      -thing one (-category three, -category nine)
      -thing two (-category six, -category seven)

      Lodging (would only display one, two, three, four in select)
      -lodging one (-category one, -category two)
      -lodging two (-category three, -category four)

      Dining (would only display five, six, seven, eight in select)
      -dining one (-category five, -category six)
      -dining two (-category seven, -category eight)
      Categories(hidden page)
      -category one
      -category two
      -category there
      -category four
      -category five
      -category six
      -category seven
      -category eight
      -category nine
      -category ten
      $categories = $pages->find(1129)->children('include=hidden'); foreach($categories->references('category') as $ref) { echo $ref->title; } This selector isn't working, but it seems 'references' would be helpful. I've never used it before, so I'm not sure how to employ for this.
      https://processwire.com/blog/posts/processwire-3.0.107-core-updates/#page-gt-references
    • By Pip
      Hi, Everyone! 
      I'm currently working on a page reference field and set it for multiple pages (AsmSelect) for the input. Is there a way for me to add an image field (aka Avatar) and the title of page in the radio button? 
      I used the field name enclosed in the { }. Didn't work. It appeared a text instead. 
      Thanks in advance and hope to hear from you soon!
    • By jonatan
      Hi! 😄
      SITE SETUP / DESCRIPTION:
      What? Online art magazine with an "All featured works" and also an "All featured artists" index page, and also individual "Work" and "Artists" pages, and data relations between the different artists and their artworks.
      So, I have two different page reference fields, connected by @Robin S's awesome Connect Page Fields module (though that has nothing to do with the issue in fact, Robin's plugin works great! and the issue is the same with or without it).
      The two Page Reference type fields are called "works" and "artists". They are meant to simply connect different artists to different artworks.
      Fx:
      Work 1  (page)  –> artists (Page Reference field) : Artist A (page)           --->>> (automatically connected)         Artist A (page)  –> works (Page Reference field) : Work 1 (page)
      Work 2  (page) –> artists (Page Reference field) : Artist B  (page)           --->>> (automatically connected)         Artist B (page)  –> works (Page Reference field) : Work 2 (page)
      ISSUE:
      On both Page Reference fields, both on "artists" and on "works" this option "Allow unpublished pages" is activated:

      As it says in the option description, supposedly, unpublished pages should be selectable in the page reference field, but they should not be visible, they shouldn't appear, on the front-end...
      Frontend:
      To show all works related to the artist on the artist individual page I'm doing this:
      <?php foreach($page->works as $item) { echo "<img src='{$item->image->first->width(200)->url}' class='pr-2'><a class='pr-4' href='$item->url'>$item->title</a>"; } The problem is now, unexpectedly, if some work is set to "Unpublished", it shows up anyways!
      WORKAROUND:
      So to get around this I figured out that I can do this:
      <?php foreach($page->works as $item) { if($item->is(Page::statusUnpublished)) { return; }; echo "<img src='{$item->image->first->width(200)->url}' class='pr-2'><a class='pr-4' href='$item->url'>$item->title</a>"; } But ofc this is a rather inelegant "solution" which shouldn't really be necessary, right? 
      I might be missing something basic here, but really can't figure out what it is... I hope one of you awesome guys can help me out 😊
      Thanks a lot in advance!
      All the best,
      Jonatan
×
×
  • Create New...