Complex classes like query often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use query, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | abstract class query |
||
| 17 | { |
||
| 18 | /** |
||
| 19 | * |
||
| 20 | * @var \Doctrine\ORM\QueryBuilder |
||
| 21 | */ |
||
| 22 | protected $qb; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * |
||
| 26 | * @var boolean |
||
| 27 | */ |
||
| 28 | protected $include_deleted = false; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * |
||
| 32 | * @var int |
||
| 33 | */ |
||
| 34 | protected $parameters = 0; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * |
||
| 38 | * @var string |
||
| 39 | */ |
||
| 40 | protected $classname = null; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * |
||
| 44 | * @var array |
||
| 45 | */ |
||
| 46 | protected $groupstack = array(); |
||
| 47 | |||
| 48 | /** |
||
| 49 | * |
||
| 50 | * @var array |
||
| 51 | */ |
||
| 52 | protected $join_tables = array(); |
||
| 53 | |||
| 54 | 57 | public function __construct($class) |
|
| 60 | |||
| 61 | abstract public function execute(); |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @return \Doctrine\ORM\QueryBuilder |
||
| 65 | */ |
||
| 66 | public function get_doctrine() |
||
| 67 | { |
||
| 68 | return $this->qb; |
||
| 69 | } |
||
| 70 | |||
| 71 | 1 | public function add_constraint_with_property($name, $operator, $property) |
|
| 72 | 1 | { |
|
| 73 | //TODO: INTREE & IN operator functionality ? |
||
| 74 | 1 | $parsed = $this->parse_constraint_name($name); |
|
| 75 | 1 | $parsed_property = $this->parse_constraint_name($property); |
|
| 76 | 1 | $constraint = $parsed['name'] . ' ' . $operator . ' ' . $parsed_property['name']; |
|
| 77 | |||
| 78 | 1 | $this->get_current_group()->add($constraint); |
|
| 79 | |||
| 80 | 1 | return true; |
|
| 81 | } |
||
| 82 | |||
| 83 | 48 | public function add_constraint($name, $operator, $value) |
|
| 84 | { |
||
| 85 | 48 | if ($operator === 'INTREE') { |
|
| 86 | 1 | $operator = 'IN'; |
|
| 87 | 1 | $targetclass = $this->classname; |
|
| 88 | 1 | $fieldname = $name; |
|
| 89 | |||
| 90 | 1 | if (strpos($name, '.') !== false) { |
|
| 91 | 1 | $parsed = $this->parse_constraint_name($name); |
|
| 92 | 1 | $fieldname = $parsed['column']; |
|
| 93 | 1 | $targetclass = $parsed['targetclass']; |
|
| 94 | 1 | } |
|
| 95 | |||
| 96 | 1 | $mapping = connection::get_em()->getClassMetadata($targetclass)->getAssociationMapping($fieldname); |
|
| 97 | 1 | $parentfield = $name; |
|
| 98 | |||
| 99 | 1 | if ($mapping['targetEntity'] !== get_class($this)) { |
|
| 100 | 1 | $cm = connection::get_em()->getClassMetadata($mapping['targetEntity']); |
|
| 101 | 1 | $parentfield = $cm->midgard['upfield']; |
|
|
|
|||
| 102 | 1 | } |
|
| 103 | |||
| 104 | 1 | $value = (array) $value; |
|
| 105 | 1 | $value = array_merge($value, $this->get_child_ids($mapping['targetEntity'], $parentfield, $value)); |
|
| 106 | 1 | } elseif ( $operator === 'IN' |
|
| 107 | 47 | || $operator === 'NOT IN') { |
|
| 108 | 1 | $value = array_values($value); |
|
| 109 | 47 | } elseif (!in_array($operator, array('=', '>', '<', '<>', '<=', '>=', 'LIKE', 'NOT LIKE'))) { |
|
| 110 | 4 | return false; |
|
| 111 | } |
||
| 112 | 47 | $this->parameters++; |
|
| 113 | 47 | $this->get_current_group()->add($this->build_constraint($name, $operator, $value)); |
|
| 114 | 46 | $this->qb->setParameter($this->parameters, $value); |
|
| 115 | |||
| 116 | 46 | return true; |
|
| 117 | } |
||
| 118 | |||
| 119 | 3 | public function add_order($name, $direction = 'ASC') |
|
| 133 | |||
| 134 | 9 | public function count() |
|
| 135 | { |
||
| 136 | 9 | $select = $this->qb->getDQLPart('select'); |
|
| 150 | |||
| 151 | 2 | public function set_limit($limit) |
|
| 155 | |||
| 156 | 1 | public function set_offset($offset) |
|
| 160 | |||
| 161 | 12 | public function include_deleted() |
|
| 165 | |||
| 166 | 50 | public function begin_group($operator = 'OR') |
|
| 178 | |||
| 179 | 46 | public function end_group() |
|
| 194 | |||
| 195 | /** |
||
| 196 | * @return Doctrine\ORM\Query\Expr: |
||
| 197 | */ |
||
| 198 | 48 | public function get_current_group() |
|
| 206 | |||
| 207 | 49 | protected function pre_execution() |
|
| 213 | |||
| 214 | 49 | protected function post_execution() |
|
| 220 | |||
| 221 | 1 | protected function add_collection_join($current_table, $targetclass) |
|
| 230 | |||
| 231 | 6 | protected function add_join($current_table, $mrp, $property) |
|
| 247 | |||
| 248 | 50 | protected function parse_constraint_name($name) |
|
| 295 | |||
| 296 | 47 | protected function build_constraint($name, $operator, $value) |
|
| 340 | |||
| 341 | 49 | protected function check_groups() |
|
| 347 | |||
| 348 | 1 | private function get_child_ids($targetclass, $fieldname, array $parent_values) |
|
| 367 | } |
||
| 368 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.