Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like MongoCollection 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 MongoCollection, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class MongoCollection |
||
30 | { |
||
31 | use Helper\ReadPreference; |
||
32 | use Helper\SlaveOkay; |
||
33 | use Helper\WriteConcern; |
||
34 | |||
35 | const ASCENDING = 1; |
||
36 | const DESCENDING = -1; |
||
37 | |||
38 | /** |
||
39 | * @var MongoDB |
||
40 | */ |
||
41 | public $db = null; |
||
42 | |||
43 | /** |
||
44 | * @var string |
||
45 | */ |
||
46 | protected $name; |
||
47 | |||
48 | /** |
||
49 | * @var \MongoDB\Collection |
||
50 | */ |
||
51 | protected $collection; |
||
52 | |||
53 | /** |
||
54 | * Creates a new collection |
||
55 | * |
||
56 | * @link http://www.php.net/manual/en/mongocollection.construct.php |
||
57 | * @param MongoDB $db Parent database. |
||
58 | * @param string $name Name for this collection. |
||
59 | * @throws Exception |
||
60 | */ |
||
61 | public function __construct(MongoDB $db, $name) |
||
72 | |||
73 | /** |
||
74 | * Gets the underlying collection for this object |
||
75 | * |
||
76 | * @internal This part is not of the ext-mongo API and should not be used |
||
77 | * @return \MongoDB\Collection |
||
78 | */ |
||
79 | public function getCollection() |
||
83 | |||
84 | /** |
||
85 | * String representation of this collection |
||
86 | * |
||
87 | * @link http://www.php.net/manual/en/mongocollection.--tostring.php |
||
88 | * @return string Returns the full name of this collection. |
||
89 | */ |
||
90 | public function __toString() |
||
94 | |||
95 | /** |
||
96 | * Gets a collection |
||
97 | * |
||
98 | * @link http://www.php.net/manual/en/mongocollection.get.php |
||
99 | * @param string $name The next string in the collection name. |
||
100 | * @return MongoCollection |
||
101 | */ |
||
102 | public function __get($name) |
||
111 | |||
112 | /** |
||
113 | * @param string $name |
||
114 | * @param mixed $value |
||
115 | */ |
||
116 | public function __set($name, $value) |
||
123 | |||
124 | /** |
||
125 | * Perform an aggregation using the aggregation framework |
||
126 | * |
||
127 | * @link http://www.php.net/manual/en/mongocollection.aggregate.php |
||
128 | * @param array $pipeline |
||
129 | * @param array $op |
||
130 | * @return array |
||
131 | */ |
||
132 | public function aggregate(array $pipeline, array $op = []) |
||
177 | |||
178 | /** |
||
179 | * Execute an aggregation pipeline command and retrieve results through a cursor |
||
180 | * |
||
181 | * @link http://php.net/manual/en/mongocollection.aggregatecursor.php |
||
182 | * @param array $pipeline |
||
183 | * @param array $options |
||
184 | * @return MongoCommandCursor |
||
185 | */ |
||
186 | public function aggregateCursor(array $pipeline, array $options = []) |
||
206 | |||
207 | /** |
||
208 | * Returns this collection's name |
||
209 | * |
||
210 | * @link http://www.php.net/manual/en/mongocollection.getname.php |
||
211 | * @return string |
||
212 | */ |
||
213 | public function getName() |
||
217 | |||
218 | /** |
||
219 | * {@inheritdoc} |
||
220 | */ |
||
221 | public function setReadPreference($readPreference, $tags = null) |
||
228 | |||
229 | /** |
||
230 | * {@inheritdoc} |
||
231 | */ |
||
232 | public function setWriteConcern($wstring, $wtimeout = 0) |
||
239 | |||
240 | /** |
||
241 | * Drops this collection |
||
242 | * |
||
243 | * @link http://www.php.net/manual/en/mongocollection.drop.php |
||
244 | * @return array Returns the database response. |
||
245 | */ |
||
246 | public function drop() |
||
250 | |||
251 | /** |
||
252 | * Validates this collection |
||
253 | * |
||
254 | * @link http://www.php.net/manual/en/mongocollection.validate.php |
||
255 | * @param bool $scan_data Only validate indices, not the base collection. |
||
256 | * @return array Returns the database's evaluation of this object. |
||
257 | */ |
||
258 | public function validate($scan_data = false) |
||
267 | |||
268 | /** |
||
269 | * Inserts an array into the collection |
||
270 | * |
||
271 | * @link http://www.php.net/manual/en/mongocollection.insert.php |
||
272 | * @param array|object $a |
||
273 | * @param array $options |
||
274 | * @throws MongoException if the inserted document is empty or if it contains zero-length keys. Attempting to insert an object with protected and private properties will cause a zero-length key error. |
||
275 | * @throws MongoCursorException if the "w" option is set and the write fails. |
||
276 | * @throws MongoCursorTimeoutException if the "w" option is set to a value greater than one and the operation takes longer than MongoCursor::$timeout milliseconds to complete. This does not kill the operation on the server, it is a client-side timeout. The operation in MongoCollection::$wtimeout is milliseconds. |
||
277 | * @return bool|array Returns an array containing the status of the insertion if the "w" option is set. |
||
278 | */ |
||
279 | public function insert(&$a, array $options = []) |
||
308 | |||
309 | /** |
||
310 | * Inserts multiple documents into this collection |
||
311 | * |
||
312 | * @link http://www.php.net/manual/en/mongocollection.batchinsert.php |
||
313 | * @param array $a An array of arrays. |
||
314 | * @param array $options Options for the inserts. |
||
315 | * @throws MongoCursorException |
||
316 | * @return mixed If "safe" is set, returns an associative array with the status of the inserts ("ok") and any error that may have occured ("err"). Otherwise, returns TRUE if the batch insert was successfully sent, FALSE otherwise. |
||
317 | */ |
||
318 | public function batchInsert(array &$a, array $options = []) |
||
365 | |||
366 | /** |
||
367 | * Update records based on a given criteria |
||
368 | * |
||
369 | * @link http://www.php.net/manual/en/mongocollection.update.php |
||
370 | * @param array|object $criteria Description of the objects to update. |
||
371 | * @param array|object $newobj The object with which to update the matching records. |
||
372 | * @param array $options |
||
373 | * @return bool|array |
||
374 | * @throws MongoException |
||
375 | * @throws MongoWriteConcernException |
||
376 | */ |
||
377 | public function update($criteria, $newobj, array $options = []) |
||
419 | |||
420 | /** |
||
421 | * Remove records from this collection |
||
422 | * |
||
423 | * @link http://www.php.net/manual/en/mongocollection.remove.php |
||
424 | * @param array $criteria Query criteria for the documents to delete. |
||
425 | * @param array $options An array of options for the remove operation. |
||
426 | * @throws MongoCursorException |
||
427 | * @throws MongoCursorTimeoutException |
||
428 | * @return bool|array Returns an array containing the status of the removal |
||
429 | * if the "w" option is set. Otherwise, returns TRUE. |
||
430 | */ |
||
431 | public function remove(array $criteria = [], array $options = []) |
||
457 | |||
458 | /** |
||
459 | * Querys this collection |
||
460 | * |
||
461 | * @link http://www.php.net/manual/en/mongocollection.find.php |
||
462 | * @param array $query The fields for which to search. |
||
463 | * @param array $fields Fields of the results to return. |
||
464 | * @return MongoCursor |
||
465 | */ |
||
466 | View Code Duplication | public function find(array $query = [], array $fields = []) |
|
473 | |||
474 | /** |
||
475 | * Retrieve a list of distinct values for the given key across a collection |
||
476 | * |
||
477 | * @link http://www.php.net/manual/ru/mongocollection.distinct.php |
||
478 | * @param string $key The key to use. |
||
479 | * @param array $query An optional query parameters |
||
480 | * @return array|bool Returns an array of distinct values, or FALSE on failure |
||
481 | */ |
||
482 | public function distinct($key, array $query = []) |
||
490 | |||
491 | /** |
||
492 | * Update a document and return it |
||
493 | * |
||
494 | * @link http://www.php.net/manual/ru/mongocollection.findandmodify.php |
||
495 | * @param array $query The query criteria to search for. |
||
496 | * @param array $update The update criteria. |
||
497 | * @param array $fields Optionally only return these fields. |
||
498 | * @param array $options An array of options to apply, such as remove the match document from the DB and return it. |
||
499 | * @return array Returns the original document, or the modified document when new is set. |
||
500 | */ |
||
501 | public function findAndModify(array $query, array $update = null, array $fields = null, array $options = []) |
||
542 | |||
543 | /** |
||
544 | * Querys this collection, returning a single element |
||
545 | * |
||
546 | * @link http://www.php.net/manual/en/mongocollection.findone.php |
||
547 | * @param array $query The fields for which to search. |
||
548 | * @param array $fields Fields of the results to return. |
||
549 | * @param array $options |
||
550 | * @return array|null |
||
551 | */ |
||
552 | public function findOne($query = [], array $fields = [], array $options = []) |
||
573 | |||
574 | /** |
||
575 | * Creates an index on the given field(s), or does nothing if the index already exists |
||
576 | * |
||
577 | * @link http://www.php.net/manual/en/mongocollection.createindex.php |
||
578 | * @param array $keys Field or fields to use as index. |
||
579 | * @param array $options [optional] This parameter is an associative array of the form array("optionname" => <boolean>, ...). |
||
580 | * @return array Returns the database response. |
||
581 | */ |
||
582 | public function createIndex($keys, array $options = []) |
||
650 | |||
651 | /** |
||
652 | * Creates an index on the given field(s), or does nothing if the index already exists |
||
653 | * |
||
654 | * @link http://www.php.net/manual/en/mongocollection.ensureindex.php |
||
655 | * @param array $keys Field or fields to use as index. |
||
656 | * @param array $options [optional] This parameter is an associative array of the form array("optionname" => <boolean>, ...). |
||
657 | * @return array Returns the database response. |
||
658 | * @deprecated Use MongoCollection::createIndex() instead. |
||
659 | */ |
||
660 | public function ensureIndex(array $keys, array $options = []) |
||
664 | |||
665 | /** |
||
666 | * Deletes an index from this collection |
||
667 | * |
||
668 | * @link http://www.php.net/manual/en/mongocollection.deleteindex.php |
||
669 | * @param string|array $keys Field or fields from which to delete the index. |
||
670 | * @return array Returns the database response. |
||
671 | */ |
||
672 | public function deleteIndex($keys) |
||
691 | |||
692 | /** |
||
693 | * Delete all indexes for this collection |
||
694 | * |
||
695 | * @link http://www.php.net/manual/en/mongocollection.deleteindexes.php |
||
696 | * @return array Returns the database response. |
||
697 | */ |
||
698 | public function deleteIndexes() |
||
706 | |||
707 | /** |
||
708 | * Returns an array of index names for this collection |
||
709 | * |
||
710 | * @link http://www.php.net/manual/en/mongocollection.getindexinfo.php |
||
711 | * @return array Returns a list of index names. |
||
712 | */ |
||
713 | public function getIndexInfo() |
||
751 | |||
752 | /** |
||
753 | * Counts the number of documents in this collection |
||
754 | * |
||
755 | * @link http://www.php.net/manual/en/mongocollection.count.php |
||
756 | * @param array|stdClass $query |
||
757 | * @param array $options |
||
758 | * @return int Returns the number of documents matching the query. |
||
759 | */ |
||
760 | public function count($query = [], $options = []) |
||
782 | |||
783 | /** |
||
784 | * Saves an object to this collection |
||
785 | * |
||
786 | * @link http://www.php.net/manual/en/mongocollection.save.php |
||
787 | * @param array|object $a Array to save. If an object is used, it may not have protected or private properties. |
||
788 | * @param array $options Options for the save. |
||
789 | * @throws MongoException if the inserted document is empty or if it contains zero-length keys. Attempting to insert an object with protected and private properties will cause a zero-length key error. |
||
790 | * @throws MongoCursorException if the "w" option is set and the write fails. |
||
791 | * @throws MongoCursorTimeoutException if the "w" option is set to a value greater than one and the operation takes longer than MongoCursor::$timeout milliseconds to complete. This does not kill the operation on the server, it is a client-side timeout. The operation in MongoCollection::$wtimeout is milliseconds. |
||
792 | * @return array|boolean If w was set, returns an array containing the status of the save. |
||
793 | * Otherwise, returns a boolean representing if the array was not empty (an empty array will not be inserted). |
||
794 | */ |
||
795 | public function save(&$a, array $options = []) |
||
832 | |||
833 | /** |
||
834 | * Creates a database reference |
||
835 | * |
||
836 | * @link http://www.php.net/manual/en/mongocollection.createdbref.php |
||
837 | * @param array|object $document_or_id Object to which to create a reference. |
||
838 | * @return array Returns a database reference array. |
||
839 | */ |
||
840 | public function createDBRef($document_or_id) |
||
862 | |||
863 | /** |
||
864 | * Fetches the document pointed to by a database reference |
||
865 | * |
||
866 | * @link http://www.php.net/manual/en/mongocollection.getdbref.php |
||
867 | * @param array $ref A database reference. |
||
868 | * @return array Returns the database document pointed to by the reference. |
||
869 | */ |
||
870 | public function getDBRef(array $ref) |
||
874 | |||
875 | /** |
||
876 | * Performs an operation similar to SQL's GROUP BY command |
||
877 | * |
||
878 | * @link http://www.php.net/manual/en/mongocollection.group.php |
||
879 | * @param mixed $keys Fields to group by. If an array or non-code object is passed, it will be the key used to group results. |
||
880 | * @param array $initial Initial value of the aggregation counter object. |
||
881 | * @param MongoCode|string $reduce A function that aggregates (reduces) the objects iterated. |
||
882 | * @param array $condition An condition that must be true for a row to be considered. |
||
883 | * @return array |
||
884 | */ |
||
885 | public function group($keys, array $initial, $reduce, array $condition = []) |
||
917 | |||
918 | /** |
||
919 | * Returns an array of cursors to iterator over a full collection in parallel |
||
920 | * |
||
921 | * @link http://www.php.net/manual/en/mongocollection.parallelcollectionscan.php |
||
922 | * @param int $num_cursors The number of cursors to request from the server. Please note, that the server can return less cursors than you requested. |
||
923 | * @return MongoCommandCursor[] |
||
924 | */ |
||
925 | public function parallelCollectionScan($num_cursors) |
||
929 | |||
930 | protected function notImplemented() |
||
934 | |||
935 | /** |
||
936 | * @return \MongoDB\Collection |
||
937 | */ |
||
938 | View Code Duplication | private function createCollectionObject() |
|
951 | |||
952 | /** |
||
953 | * Converts legacy write concern options to a WriteConcern object |
||
954 | * |
||
955 | * @param array $options |
||
956 | * @return array |
||
957 | */ |
||
958 | private function convertWriteConcernOptions(array $options) |
||
985 | |||
986 | private function checkKeys(array $array) |
||
998 | |||
999 | /** |
||
1000 | * @param array|object $document |
||
1001 | * @return MongoId |
||
1002 | */ |
||
1003 | private function ensureDocumentHasMongoId(&$document) |
||
1032 | |||
1033 | private function checkCollectionName($name) |
||
1041 | |||
1042 | /** |
||
1043 | * @return array |
||
1044 | */ |
||
1045 | public function __sleep() |
||
1049 | |||
1050 | private function mustBeArrayOrObject($a) |
||
1056 | } |
||
1057 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: