PageFinder::getQueryHasParent PHP Method

getQueryHasParent() protected method

Make the query specific to all pages below a certain parent (children, grandchildren, great grandchildren, etc.)
protected getQueryHasParent ( DatabaseQuerySelect $query, $selector )
$query DatabaseQuerySelect
    protected function getQueryHasParent(DatabaseQuerySelect $query, $selector)
    {
        static $cnt = 0;
        $wheres = array();
        $parent_ids = $selector->value;
        if (!is_array($parent_ids)) {
            $parent_ids = array($parent_ids);
        }
        foreach ($parent_ids as $parent_id) {
            if (!ctype_digit("{$parent_id}")) {
                // parent_id is a path, convert a path to a parent
                $parent = new NullPage();
                $path = $this->wire('sanitizer')->path($parent_id);
                if ($path) {
                    $parent = $this->wire('pages')->get('/' . trim($path, '/') . '/');
                }
                $parent_id = $parent->id;
                if (!$parent_id) {
                    $query->where("1>2");
                    // force the query to fail
                    return;
                }
            }
            $parent_id = (int) $parent_id;
            $cnt++;
            if ($parent_id == 1) {
                // homepage
                if ($selector->operator == '!=') {
                    // homepage is only page that can match not having a has_parent of 1
                    $query->where("pages.id=1");
                } else {
                    // no different from not having a has_parent, so we ignore it
                }
                return;
            }
            // the subquery performs faster than the old method (further below) on sites with tens of thousands of pages
            $in = $selector->operator == '!=' ? 'NOT IN' : 'IN';
            $wheres[] = "pages.parent_id {$in} (SELECT pages_id FROM pages_parents WHERE parents_id={$parent_id} OR pages_id={$parent_id})";
        }
        $andor = $selector->operator == '!=' ? ' AND ' : ' OR ';
        $query->where(implode($andor, $wheres));
        /*
        // OLD method kept for reference
        $joinType = 'join';
        $table = "pages_has_parent$cnt";
        
        if($selector->operator == '!=') { 
        	$joinType = 'leftjoin';
        	$query->where("$table.pages_id IS NULL"); 
        
        }
        
        $query->$joinType(
        	"pages_parents AS $table ON (" . 
        		"($table.pages_id=pages.id OR $table.pages_id=pages.parent_id) " . 
        		"AND ($table.parents_id=$parent_id OR $table.pages_id=$parent_id) " . 
        	")"
        ); 
        */
    }