FOF30\Model\TreeModel::findByPath PHP Метод

findByPath() публичный Метод

Notes: - This will only work when you have a "slug" and a "hash" field in your table. - If the path starts with "/" we will use the root with lft=1. Otherwise the first component of the path is supposed to be the slug of the root node. - If the root node is not found you'll get null as the return value - You will also get null if any component of the path is not found
public findByPath ( string $path ) : TreeModel | null
$path string The path to locate
Результат TreeModel | null The found node or null if nothing is found
    public function findByPath($path)
    {
        // No path? No node.
        if (empty($path)) {
            return null;
        }
        // Extract the path parts
        $pathParts = explode('/', $path);
        $firstElement = array_shift($pathParts);
        if (!empty($firstElement)) {
            array_unshift($pathParts, $firstElement);
        }
        // Just a slash? Return the root
        if (empty($pathParts[0])) {
            return $this->getRoot();
        }
        // Get the quoted field names
        $db = $this->getDbo();
        $fldLeft = $db->qn($this->getFieldAlias('lft'));
        $fldRight = $db->qn($this->getFieldAlias('rgt'));
        $fldHash = $db->qn($this->getFieldAlias('hash'));
        // Get the quoted hashes of the slugs
        $pathHashesQuoted = array();
        foreach ($pathParts as $part) {
            $pathHashesQuoted[] = $db->q(sha1($part));
        }
        // Get all nodes with slugs matching our path
        $query = $db->getQuery(true)->select(array($db->qn('node') . '.*', '(COUNT(' . $db->qn('parent') . '.' . $db->qn($this->getFieldAlias('lft')) . ') - 1) AS ' . $db->qn('depth')))->from($db->qn($this->tableName) . ' AS ' . $db->qn('node'))->join('CROSS', $db->qn($this->tableName) . ' AS ' . $db->qn('parent'))->where($db->qn('node') . '.' . $fldLeft . ' >= ' . $db->qn('parent') . '.' . $fldLeft)->where($db->qn('node') . '.' . $fldLeft . ' <= ' . $db->qn('parent') . '.' . $fldRight)->where($db->qn('node') . '.' . $fldHash . ' IN (' . implode(',', $pathHashesQuoted) . ')')->group($db->qn('node') . '.' . $fldLeft)->order(array($db->qn('depth') . ' ASC', $db->qn('node') . '.' . $fldLeft . ' ASC'));
        $queryResults = $db->setQuery($query)->loadAssocList();
        $pathComponents = array();
        // Handle paths with (no root slug provided) and without (root slug provided) a leading slash
        $currentLevel = substr($path, 0, 1) == '/' ? 0 : -1;
        $maxLevel = count($pathParts) + $currentLevel;
        // Initialise the path results array
        $i = $currentLevel;
        foreach ($pathParts as $part) {
            $i++;
            $pathComponents[$i] = array('slug' => $part, 'id' => null, 'lft' => null, 'rgt' => null);
        }
        // Search for the best matching nodes
        $colSlug = $this->getFieldAlias('slug');
        $colLft = $this->getFieldAlias('lft');
        $colRgt = $this->getFieldAlias('rgt');
        $colId = $this->getIdFieldName();
        foreach ($queryResults as $row) {
            if ($row['depth'] == $currentLevel + 1) {
                if ($row[$colSlug] != $pathComponents[$currentLevel + 1]['slug']) {
                    continue;
                }
                if ($currentLevel > 0) {
                    if ($row[$colLft] < $pathComponents[$currentLevel]['lft']) {
                        continue;
                    }
                    if ($row[$colRgt] > $pathComponents[$currentLevel]['rgt']) {
                        continue;
                    }
                }
                $currentLevel++;
                $pathComponents[$currentLevel]['id'] = $row[$colId];
                $pathComponents[$currentLevel]['lft'] = $row[$colLft];
                $pathComponents[$currentLevel]['rgt'] = $row[$colRgt];
            }
            if ($currentLevel == $maxLevel) {
                break;
            }
        }
        // Get the last found node
        $lastNode = array_pop($pathComponents);
        // If the node exists, return it...
        if (!empty($lastNode['lft'])) {
            return $this->getClone()->reset()->where($colLft, '=', $lastNode['lft'])->firstOrFail();
        }
        // ...otherwise return null
        return null;
    }