netdudes /
DataSourceryBundle
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 |
||
| 2 | namespace Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\QueryBuilder; |
||
| 3 | |||
| 4 | use Doctrine\ORM\EntityManager; |
||
| 5 | use Doctrine\ORM\QueryBuilder; |
||
| 6 | use Netdudes\DataSourceryBundle\DataSource\DataSourceInterface; |
||
| 7 | use Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\DoctrineDriver; |
||
| 8 | use Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\Events\GenerateJoinsEvent; |
||
| 9 | use Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\Events\GenerateSelectsEvent; |
||
| 10 | use Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\Events\PostGenerateQueryBuilderEvent; |
||
| 11 | use Netdudes\DataSourceryBundle\Query\Query; |
||
| 12 | use Netdudes\DataSourceryBundle\Query\SearchTextFieldHandler; |
||
| 13 | use Netdudes\DataSourceryBundle\Query\SearchTextFilterConditionTransformer; |
||
| 14 | |||
| 15 | class Builder |
||
| 16 | { |
||
| 17 | /** |
||
| 18 | * @var Filterer |
||
| 19 | */ |
||
| 20 | protected $filterer; |
||
| 21 | |||
| 22 | /** |
||
| 23 | * @var Sorter |
||
| 24 | */ |
||
| 25 | protected $sorter; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * @var Paginator |
||
| 29 | */ |
||
| 30 | protected $paginator; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * @var string |
||
| 34 | */ |
||
| 35 | protected $fromAlias; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * @var array |
||
| 39 | */ |
||
| 40 | protected $joins; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * @var array |
||
| 44 | */ |
||
| 45 | protected $selectFieldsMap = []; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * @var RequiredFieldsExtractor |
||
| 49 | */ |
||
| 50 | protected $requiredFieldsExtractor; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @var JoinGenerator |
||
| 54 | */ |
||
| 55 | protected $joinGenerator; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * @var SelectGenerator |
||
| 59 | */ |
||
| 60 | protected $selectGenerator; |
||
| 61 | |||
| 62 | /** |
||
| 63 | * @var SearchTextFieldHandler |
||
| 64 | */ |
||
| 65 | protected $searchTextFieldHandler; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @var EntityManager |
||
| 69 | */ |
||
| 70 | private $entityManager; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @var DataSourceInterface |
||
| 74 | */ |
||
| 75 | private $dataSource; |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @param DataSourceInterface $dataSource |
||
| 79 | * @param EntityManager $entityManager |
||
| 80 | */ |
||
| 81 | public function __construct(DataSourceInterface $dataSource, EntityManager $entityManager) |
||
|
0 ignored issues
–
show
|
|||
| 82 | { |
||
| 83 | $this->dataSource = $dataSource; |
||
| 84 | $this->entityManager = $entityManager; |
||
| 85 | |||
| 86 | $fields = $dataSource->getFields(); |
||
| 87 | $transformers = $dataSource->getTransformers(); |
||
| 88 | |||
| 89 | $this->requiredFieldsExtractor = new RequiredFieldsExtractor($fields, $transformers); |
||
| 90 | $this->joinGenerator = new JoinGenerator($fields, $this->getFromAlias(), $this->requiredFieldsExtractor); |
||
| 91 | $this->selectGenerator = new SelectGenerator($fields, $this->getFromAlias(), $this->joinGenerator, $this->requiredFieldsExtractor); |
||
| 92 | $this->filterer = new Filterer(); |
||
| 93 | $this->searchTextFieldHandler = new SearchTextFieldHandler(new SearchTextFilterConditionTransformer()); |
||
| 94 | $this->sorter = new Sorter(); |
||
| 95 | $this->paginator = new Paginator(); |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Gets the fully generated query builder. Will autogenerate select and |
||
| 100 | * join statements as needed. |
||
| 101 | * |
||
| 102 | * This function is cached, and will only be generated once per execution. |
||
| 103 | * |
||
| 104 | * @param Query $query |
||
| 105 | * |
||
| 106 | * @return QueryBuilder |
||
| 107 | */ |
||
| 108 | public function buildQueryBuilder(Query $query, $entityClass) |
||
| 109 | { |
||
| 110 | $this->searchTextFieldHandler->handle($query->getFilter(), $this->dataSource->getFields()); |
||
| 111 | |||
| 112 | $queryBuilder = $this->entityManager->createQueryBuilder(); |
||
| 113 | $queryBuilder->from($entityClass, $this->getFromAlias()); |
||
| 114 | |||
| 115 | $select = $this->selectGenerator->generate($query); |
||
| 116 | $event = new GenerateSelectsEvent($select, $this->getFromAlias()); |
||
|
0 ignored issues
–
show
It seems like
$select defined by $this->selectGenerator->generate($query) on line 115 can be null; however, Netdudes\DataSourceryBun...ctsEvent::__construct() does not accept null, maybe add an additional type check?
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: /** @return stdClass|null */
function mayReturnNull() { }
function doesNotAcceptNull(stdClass $x) { }
// With potential error.
function withoutCheck() {
$x = mayReturnNull();
doesNotAcceptNull($x); // Potential error here.
}
// Safe - Alternative 1
function withCheck1() {
$x = mayReturnNull();
if ( ! $x instanceof stdClass) {
throw new \LogicException('$x must be defined.');
}
doesNotAcceptNull($x);
}
// Safe - Alternative 2
function withCheck2() {
$x = mayReturnNull();
if ($x instanceof stdClass) {
doesNotAcceptNull($x);
}
}
Loading history...
|
|||
| 117 | $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_GENERATE_SELECTS, $event); |
||
| 118 | $select = $event->select; |
||
| 119 | $queryBuilder->add('select', $select); |
||
| 120 | |||
| 121 | $joins = $this->joinGenerator->generate($query); |
||
| 122 | $event = new GenerateJoinsEvent($this->getFromAlias(), $joins); |
||
| 123 | $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_GENERATE_JOINS, $event); |
||
| 124 | $joins = $event->joins; |
||
| 125 | foreach ($joins as $join) { |
||
| 126 | $queryBuilder |
||
| 127 | ->leftJoin($join->getJoin(), $join->getAlias(), $join->getConditionType(), $join->getCondition(), $join->getIndexBy()); |
||
| 128 | } |
||
| 129 | |||
| 130 | $this->filterer->filter($queryBuilder, $query->getFilter(), $this->selectGenerator->getUniqueNameToSelectFieldMap($query)); |
||
| 131 | |||
| 132 | $this->sorter->sort($queryBuilder, $query->getSort(), $this->selectGenerator->getUniqueNameToSelectFieldMap($query)); |
||
| 133 | |||
| 134 | $this->paginator->paginate($queryBuilder, $query->getPagination(), $this->dataSource->getFields()); |
||
|
0 ignored issues
–
show
The call to
Paginator::paginate() has too many arguments starting with $this->dataSource->getFields().
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 135 | |||
| 136 | $this->dataSource->getEventDispatcher()->dispatch(DoctrineDriver::EVENT_POST_GENERATE_QUERY_BUILDER, new PostGenerateQueryBuilderEvent($queryBuilder, $this->getFromAlias())); |
||
| 137 | |||
| 138 | return $queryBuilder; |
||
| 139 | } |
||
| 140 | |||
| 141 | /** |
||
| 142 | * Gets the FROM alias, an internal name given to the class in the FROM part of the DQL. |
||
| 143 | * |
||
| 144 | * This name is generated once, and it's unique per execution of the data source. |
||
| 145 | * |
||
| 146 | * @return string |
||
| 147 | */ |
||
| 148 | protected function getFromAlias() |
||
| 149 | { |
||
| 150 | if (is_null($this->fromAlias)) { |
||
| 151 | $this->fromAlias = uniqid('ENTITY_'); |
||
| 152 | } |
||
| 153 | |||
| 154 | return $this->fromAlias; |
||
| 155 | } |
||
| 156 | } |
||
| 157 |
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.