ARCANEDEV /
LaravelNestedSet
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php namespace Arcanedev\LaravelNestedSet\Eloquent; |
||
| 2 | |||
| 3 | use Arcanedev\LaravelNestedSet\Utilities\NestedSet; |
||
| 4 | use Illuminate\Database\Eloquent\Builder as EloquentBuilder; |
||
| 5 | use Illuminate\Database\Eloquent\Collection as EloquentCollection; |
||
| 6 | use Illuminate\Database\Eloquent\Model; |
||
| 7 | use Illuminate\Database\Eloquent\Relations\Relation; |
||
| 8 | use Illuminate\Database\Query\Builder; |
||
| 9 | use InvalidArgumentException; |
||
| 10 | use RuntimeException; |
||
| 11 | |||
| 12 | /** |
||
| 13 | * Class AncestorsRelation |
||
| 14 | * |
||
| 15 | * @package Arcanedev\LaravelNestedSet\Eloquent |
||
| 16 | * @author ARCANEDEV <[email protected]> |
||
| 17 | */ |
||
| 18 | class AncestorsRelation extends Relation |
||
| 19 | { |
||
| 20 | /* ----------------------------------------------------------------- |
||
| 21 | | Properties |
||
| 22 | | ----------------------------------------------------------------- |
||
| 23 | */ |
||
| 24 | /** |
||
| 25 | * @var \Arcanedev\LaravelNestedSet\NodeTrait|\Illuminate\Database\Eloquent\Model |
||
| 26 | */ |
||
| 27 | protected $parent; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @var QueryBuilder |
||
| 31 | */ |
||
| 32 | protected $query; |
||
| 33 | |||
| 34 | /* ----------------------------------------------------------------- |
||
| 35 | | Constructor |
||
| 36 | | ----------------------------------------------------------------- |
||
| 37 | */ |
||
| 38 | /** |
||
| 39 | * AncestorsRelation constructor. |
||
| 40 | * |
||
| 41 | * @param \Arcanedev\LaravelNestedSet\Eloquent\QueryBuilder $builder |
||
| 42 | * @param \Illuminate\Database\Eloquent\Model|mixed $model |
||
| 43 | */ |
||
| 44 | 3 | public function __construct(QueryBuilder $builder, Model $model) |
|
| 45 | { |
||
| 46 | 3 | if ( ! NestedSet::isNode($model)) |
|
| 47 | 1 | throw new InvalidArgumentException('Model must be node.'); |
|
| 48 | |||
| 49 | 3 | parent::__construct($builder, $model); |
|
| 50 | 3 | } |
|
| 51 | |||
| 52 | /** |
||
| 53 | * Add the constraints for a relationship count query. |
||
| 54 | * |
||
| 55 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
| 56 | * @param \Illuminate\Database\Eloquent\Builder $parentQuery |
||
| 57 | * |
||
| 58 | * @return \Illuminate\Database\Eloquent\Builder |
||
| 59 | */ |
||
| 60 | public function getRelationExistenceCountQuery(EloquentBuilder $query, EloquentBuilder $parentQuery) |
||
| 61 | { |
||
| 62 | throw new RuntimeException('Cannot count ancestors, use depth functionality instead'); |
||
| 63 | } |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Add the constraints for an internal relationship existence query. |
||
| 67 | * |
||
| 68 | * Essentially, these queries compare on column names like whereColumn. |
||
| 69 | * |
||
| 70 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
| 71 | * @param \Illuminate\Database\Eloquent\Builder $parentQuery |
||
| 72 | * @param array|mixed $columns |
||
| 73 | * |
||
| 74 | * @return \Illuminate\Database\Eloquent\Builder |
||
| 75 | */ |
||
| 76 | public function getRelationExistenceQuery(EloquentBuilder $query, EloquentBuilder $parentQuery, $columns = [ '*' ]) |
||
| 77 | { |
||
| 78 | $query->select($columns); |
||
|
0 ignored issues
–
show
|
|||
| 79 | |||
| 80 | $table = $query->getModel()->getTable(); |
||
| 81 | |||
| 82 | $query->from($table.' as '.$hash = $this->getRelationSubSelectHash()); |
||
| 83 | |||
| 84 | $grammar = $query->getQuery()->getGrammar(); |
||
| 85 | $table = $grammar->wrapTable($table); |
||
| 86 | $hash = $grammar->wrapTable($hash); |
||
| 87 | |||
| 88 | $parentIdName = $grammar->wrap($this->parent->getParentIdName()); |
||
|
0 ignored issues
–
show
The method
getParentIdName does only exist in Arcanedev\LaravelNestedSet\NodeTrait, but not in Illuminate\Database\Eloquent\Model.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 89 | |||
| 90 | return $query->whereRaw("{$hash}.{$parentIdName} = {$table}.{$parentIdName}"); |
||
| 91 | } |
||
| 92 | |||
| 93 | /** |
||
| 94 | * @param \Illuminate\Database\Eloquent\Builder $query |
||
| 95 | * @param \Illuminate\Database\Eloquent\Builder $parentQuery |
||
| 96 | * @param array|mixed $columns |
||
| 97 | * |
||
| 98 | * @return mixed |
||
| 99 | */ |
||
| 100 | public function getRelationQuery(EloquentBuilder $query, EloquentBuilder $parentQuery, $columns = [ '*' ]) |
||
| 101 | { |
||
| 102 | return $this->getRelationExistenceQuery($query, $parentQuery, $columns); |
||
| 103 | } |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Get a relationship join table hash. |
||
| 107 | * |
||
| 108 | * @return string |
||
| 109 | */ |
||
| 110 | public function getRelationSubSelectHash() |
||
| 111 | { |
||
| 112 | return 'self_'.md5(microtime(true)); |
||
| 113 | } |
||
| 114 | |||
| 115 | /** |
||
| 116 | * Set the base constraints on the relation query. |
||
| 117 | */ |
||
| 118 | 3 | public function addConstraints() |
|
| 119 | { |
||
| 120 | 3 | if ( ! static::$constraints) return; |
|
| 121 | |||
| 122 | 3 | $this->query->whereAncestorOf($this->parent)->defaultOrder(); |
|
| 123 | 3 | } |
|
| 124 | |||
| 125 | /** |
||
| 126 | * Set the constraints for an eager load of the relation. |
||
| 127 | * |
||
| 128 | * @param array $models |
||
| 129 | */ |
||
| 130 | public function addEagerConstraints(array $models) |
||
| 131 | { |
||
| 132 | $model = $this->query->getModel(); |
||
| 133 | $table = $model->getTable(); |
||
| 134 | $key = $model->getKeyName(); |
||
| 135 | |||
| 136 | $grammar = $this->query->getQuery()->getGrammar(); |
||
| 137 | $table = $grammar->wrapTable($table); |
||
| 138 | $hash = $grammar->wrap($this->getRelationSubSelectHash()); |
||
| 139 | $key = $grammar->wrap($key); |
||
| 140 | $lft = $grammar->wrap($this->parent->getLftName()); |
||
|
0 ignored issues
–
show
The method
getLftName does only exist in Arcanedev\LaravelNestedSet\NodeTrait, but not in Illuminate\Database\Eloquent\Model.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 141 | $rgt = $grammar->wrap($this->parent->getRgtName()); |
||
|
0 ignored issues
–
show
The method
getRgtName does only exist in Arcanedev\LaravelNestedSet\NodeTrait, but not in Illuminate\Database\Eloquent\Model.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 142 | |||
| 143 | $sql = "$key IN (SELECT DISTINCT($key) FROM {$table} INNER JOIN " |
||
| 144 | . "(SELECT {$lft}, {$rgt} FROM {$table} WHERE {$key} IN (" . implode(',', $this->getKeys($models)) |
||
| 145 | . ")) AS $hash ON {$table}.{$lft} <= {$hash}.{$lft} AND {$table}.{$rgt} >= {$hash}.{$rgt})"; |
||
| 146 | |||
| 147 | $this->query |
||
|
0 ignored issues
–
show
The method
whereNested does not exist on object<Arcanedev\Laravel...\Eloquent\QueryBuilder>? Since you implemented __call, maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
Loading history...
|
|||
| 148 | ->whereNested(function (Builder $inner) use ($sql) { |
||
| 149 | $inner->whereRaw($sql); |
||
| 150 | }) |
||
| 151 | ->orderBy('lft', 'ASC'); |
||
| 152 | } |
||
| 153 | |||
| 154 | /** |
||
| 155 | * Initialize the relation on a set of models. |
||
| 156 | * |
||
| 157 | * @param array $models |
||
| 158 | * @param string $relation |
||
| 159 | * |
||
| 160 | * @return array |
||
| 161 | */ |
||
| 162 | public function initRelation(array $models, $relation) |
||
| 163 | { |
||
| 164 | return $models; |
||
| 165 | } |
||
| 166 | |||
| 167 | /** |
||
| 168 | * Match the eagerly loaded results to their parents. |
||
| 169 | * |
||
| 170 | * @param array $models |
||
| 171 | * @param \Illuminate\Database\Eloquent\Collection $results |
||
| 172 | * @param string $relation |
||
| 173 | * |
||
| 174 | * @return array |
||
| 175 | */ |
||
| 176 | public function match(array $models, EloquentCollection $results, $relation) |
||
| 177 | { |
||
| 178 | foreach ($models as $model) { |
||
| 179 | $model->setRelation($relation, $this->getAncestorsForModel($model, $results)); |
||
| 180 | } |
||
| 181 | |||
| 182 | return $models; |
||
| 183 | } |
||
| 184 | |||
| 185 | /** |
||
| 186 | * Get the results of the relationship. |
||
| 187 | * |
||
| 188 | * @return mixed |
||
| 189 | */ |
||
| 190 | public function getResults() |
||
| 191 | { |
||
| 192 | return $this->query->get(); |
||
| 193 | } |
||
| 194 | |||
| 195 | /** |
||
| 196 | * Get ancestors for the given model. |
||
| 197 | * |
||
| 198 | * @param \Illuminate\Database\Eloquent\Model $model |
||
| 199 | * @param \Illuminate\Database\Eloquent\Collection $results |
||
| 200 | * |
||
| 201 | * @return \Illuminate\Database\Eloquent\Collection |
||
| 202 | */ |
||
| 203 | protected function getAncestorsForModel(Model $model, EloquentCollection $results) |
||
| 204 | { |
||
| 205 | $result = $this->related->newCollection(); |
||
| 206 | |||
| 207 | foreach ($results as $ancestor) { |
||
| 208 | if ($ancestor->isAncestorOf($model)) |
||
| 209 | $result->push($ancestor); |
||
| 210 | } |
||
| 211 | |||
| 212 | return $result; |
||
| 213 | } |
||
| 214 | } |
||
| 215 |
This check marks calls to methods that do not seem to exist on an object.
This is most likely the result of a method being renamed without all references to it being renamed likewise.