Passed
Push — master ( 5379a4...a2888f )
by Joao
04:49
created

src/Database/MongoDBDriver.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace ByJG\AnyDataset\Database;
4
5
use ByJG\AnyDataset\ConnectionManagement;
6
use ByJG\AnyDataset\Repository\ArrayDatasetIterator;
7
use InvalidArgumentException;
8
use MongoClient;
9
use MongoCollection;
10
use MongoDate;
11
use MongoDB;
12
use stdClass;
13
14
class MongoDBDriver implements NoSQLDriverInterface
15
{
16
17
    /**
18
     * @var MongoDB
19
     */
20
    protected $_db = null;
21
22
    /**
23
     *
24
     * @var MongoClient;
25
     */
26
    protected $_client = null;
27
28
    /**
29
     * Enter description here...
30
     *
31
     * @var ConnectionManagement
32
     */
33
    protected $_connectionManagement;
34
35
    /**
36
     *
37
     * @var MongoCollection MongoDB collection
38
     */
39
    protected $_collection;
40
41
    /**
42
     *
43
     * @var string
44
     */
45
    protected $_collectionName;
46
47
    /**
48
     * Creates a new MongoDB connection. This class is managed from NoSqlDataset
49
     *
50
     * @param ConnectionManagement $connMngt
51
     * @param string $collection
52
     */
53
    public function __construct($connMngt, $collection)
54
    {
55
        $this->_connectionManagement = $connMngt;
56
57
        $hosts = $this->_connectionManagement->getServer();
58
        $port = $this->_connectionManagement->getPort() == '' ? 27017 : $this->_connectionManagement->getPort();
59
        $database = $this->_connectionManagement->getDatabase();
60
        $username = $this->_connectionManagement->getUsername();
61
        $password = $this->_connectionManagement->getPassword();
62
63
        if ($username != '' && $password != '') {
64
            $auth = array('username' => $username, 'password' => $password, 'connect' => 'true');
65
        } else {
66
            $auth = array('connect' => 'true');
67
        }
68
69
        $connecting_string = sprintf('mongodb://%s:%d', $hosts, $port);
70
        $this->_client = new MongoClient($connecting_string, $auth);
71
        $this->_db = new MongoDB($this->_client, $database);
72
73
        $this->setCollection($collection);
74
    }
75
76
    /**
77
     * Closes and destruct the MongoDB connection
78
     */
79
    public function __destruct()
80
    {
81
        $this->_client->close();
82
        $this->_db = null;
83
    }
84
85
    /**
86
     *
87
     * @return string
88
     */
89
    public function getCollection()
90
    {
91
        return $this->_collectionName;
92
    }
93
94
    /**
95
     * Gets the instance of MongoDB; You do not need uses this directly. If you have to, probably something is missing in this class
96
     * @return \MongoDB
97
     */
98
    public function getDbConnection()
99
    {
100
        return $this->_db;
101
    }
102
103
    /**
104
     * Return a IteratorInterface
105
     *
106
     * @param array $filter
107
     * @param array $fields
108
     * @return ArrayDatasetIterator
109
     */
110
    public function getIterator($filter = null, $fields = null)
111
    {
112
        if (is_null($filter)) {
113
            $filter = array();
114
        }
115
        if (is_null($fields)) {
116
            $fields = array();
117
        }
118
        $cursor = $this->_collection->find($filter, $fields);
119
        $arrIt = iterator_to_array($cursor);
120
121
        return new ArrayDatasetIterator($arrIt);
122
    }
123
124
    /**
125
     * Insert a document in the MongoDB
126
     * @param mixed $document
127
     * @return bool
128
     */
129
    public function insert($document)
130
    {
131
        if (is_array($document)) {
132
            $document['created_at'] = new MongoDate();
133
        } else if ($document instanceof stdClass) {
134
            $document->created_at = new MongoDate();
135
        }
136
137
        return $this->_collection->insert($document);
138
    }
139
140
    /**
141
     * Defines the new Collection
142
     * @param string $collection
143
     */
144
    public function setCollection($collection)
145
    {
146
        $this->_collection = $this->_db->selectCollection($collection);
147
        $this->_collectionName = $collection;
148
    }
149
150
    /**
151
     * Update a document based on your criteria
152
     *
153
     * Options for MongoDB is an array of:
154
     *
155
     * sort array	Determines which document the operation will modify if the
156
     *              query selects multiple documents. findAndModify will modify
157
     *              the first document in the sort order specified by this argument.
158
     * remove boolean	Optional if update field exists. When TRUE, removes the
159
     *              selected document. The default is FALSE.
160
     * update array	Optional if remove field exists. Performs an update of the
161
     *              selected document.
162
     * new boolean	Optional. When TRUE, returns the modified document rather than the original.
163
     *              The findAndModify method ignores the new option for remove operations.
164
     *              The default is FALSE.
165
     * upsert boolean	Optional. Used in conjunction with the update field. When TRUE,
166
     *              the findAndModify command creates a new document if the query
167
     *              returns no documents. The default is false. In MongoDB 2.2, the findAndModify
168
     *              command returns NULL when upsert is TRUE.
169
     *
170
     * @param mixed $document
171
     * @param array $filter
172
     * @param array $options See:
173
     * @return bool
174
     */
175
    public function update($document, $filter = null, $options = null)
176
    {
177
        if (is_null($filter)) {
178
            throw new InvalidArgumentException('You need to set the filter for update, or pass an empty array for all fields');
179
        }
180
181
        $update = array();
182
        if (is_array($document)) {
183
            $document['updated_at'] = new MongoDate();
184
        }
185
        if ($document instanceof stdClass) {
186
            $document->updated_at = new MongoDate();
187
        }
188
        foreach ($document as $key => $value) {
0 ignored issues
show
The expression $document of type object|integer|double|st...":"object<MongoDate>"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
189
            if ($key[0] == '$') {
190
                $update[$key] = $value;
191
            } else {
192
                $update['$set'][$key] = $value;
193
            }
194
        }
195
196
        if (is_null($options)) {
197
            $options = array('new' => true);
198
        }
199
        return $this->_collection->findAndModify($filter, $update, array(), $options);
200
    }
201
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
202
      public function getAttribute($name)
203
      {
204
      $this->_db->getAttribute($name);
205
      }
206
207
      public function setAttribute($name, $value)
208
      {
209
      $this->_db->setAttribute ( $name, $value );
210
      }
211
     */
212
}
213