Skip to content

Documents count #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
[![Slack](https://img.shields.io/badge/join%20the%20conversation-on%20slack-green.svg)](https://mongodb-cakephp3.slack.com/messages/general/)

# what's more
The fork fixes some bugs and adds the ability to be able to count rows in a collection:

```php
$this->Categories->count($filters, $options);
```

---

Mongodb for Cakephp3
========

Expand All @@ -10,15 +19,15 @@ An Mongodb datasource for CakePHP 3.5
Install [composer](http://getcomposer.org) and run:

```bash
composer require giginc/mongodb 1.0.0
composer require Edsol/mongodb 1.0.0
```

## Connecting the Plugin to your application

add the following line in your config/bootstrap.php to tell your application to load the plugin:

```php
Plugin::load('Giginc/Mongodb');
Plugin::load('Edsol/Mongodb');

```

Expand All @@ -28,11 +37,12 @@ Now, you need to set the connection in your config/app.php file:
```php
'Datasources' => [
'default' => [
'className' => 'Giginc\Mongodb\Database\Connection',
'driver' => 'Giginc\Mongodb\Database\Driver\Mongodb',
'className' => 'Edsol\Mongodb\Database\Connection',
'driver' => 'Edsol\Mongodb\Database\Driver\Mongodb',
'persistent' => false,
'host' => 'localhost',
'port' => 27017,
'srv' => false,
'username' => '',
'password' => '',
'database' => 'devmongo',
Expand All @@ -51,12 +61,12 @@ Now, you need to set the connection in your config/app.php file:
If you want to connect to MongoDB using a SSH tunnel, you need to set additional variables in your Datasource. Some variables are unnecessary, depending on how you intend to connect. IF you're connecting using a SSH key file, the ```ssh_pubkey_path``` and ```ssh_privatekey_path``` variables are necessary and the ```ssh_password``` variable is unnecessary. If you're connecting using a text-based password (which is **not** a wise idea), the reverse is true. The function needs, at minimum, ```ssh_host```, ```ssh_user``` and one method of authentication to establish a SSH tunnel.

## Models
After that, you need to load Giginc\Mongodb\ORM\Table in your tables class:
After that, you need to load Edsol\Mongodb\ORM\Table in your tables class:

```php
//src/Model/Table/YourTable.php

use Giginc\Mongodb\ORM\Table;
use Edsol\Mongodb\ORM\Table;

class CategoriesTable extends Table {

Expand Down
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "giginc/mongodb",
"name": "edsol/mongodb-cakephp",
"description": "An Mongodb datasource for CakePHP 3.0",
"type": "cakephp-plugin",
"require": {
Expand All @@ -14,14 +14,14 @@
"license": "MIT",
"authors": [
{
"name": "giginc",
"email": "dev@giginc.co.jp"
"name": "Edsol",
"email": "contact@edsol.dev"
}
],
"autoload": {
"psr-4": {
"Giginc\\Mongodb\\": "src",
"Giginc\\Mongodb\\Test\\": "tests"
"Edsol\\Mongodb\\": "src",
"Edsol\\Mongodb\\Test\\": "tests"
}
}
}
8 changes: 4 additions & 4 deletions src/Database/Connection.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?php

namespace Giginc\Mongodb\Database;
namespace Edsol\Mongodb\Database;

use Cake\Database\Exception\MissingConnectionException;
use Giginc\Mongodb\Database\Driver\Mongodb as Gigincdb;
use Giginc\Mongodb\Database\Schema\MongoSchema;
use Edsol\Mongodb\Database\Driver\Mongodb as Gigincdb;
use Edsol\Mongodb\Database\Schema\MongoSchema;

class Connection extends \Cake\Database\Connection
{
Expand All @@ -19,7 +19,7 @@ class Connection extends \Cake\Database\Connection
/**
* Database Driver object
*
* @var \Giginc\Mongodb\Database\Driver\Mongodb;
* @var \Edsol\Mongodb\Database\Driver\Mongodb;
*/
protected $_driver = null;

Expand Down
7 changes: 6 additions & 1 deletion src/Database/Driver/Mongodb.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Giginc\Mongodb\Database\Driver;
namespace Edsol\Mongodb\Database\Driver;

use Exception;
use MongoDB\Driver\ReadPreference;
Expand Down Expand Up @@ -184,6 +184,11 @@ private function createConnectionName()
}
$hostname = $this->_config['host'] . ':' . $this->_config['port'];

if ($this->_config['srv'] ?? false) {
$host = 'mongodb+srv://';
$hostname = $this->_config['host'];
}

if (!empty($this->_config['login'])) {
$host .= $this->_config['login'] . ':' . $this->_config['password'] . '@' . $hostname . '/' . $this->_config['database'];
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/Database/Schema/MongoSchema.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Giginc\Mongodb\Database\Schema;
namespace Edsol\Mongodb\Database\Schema;

use Giginc\Mongodb\Database\Driver\Mongodb;
use Edsol\Mongodb\Database\Driver\Mongodb;
use Cake\Database\Schema\TableSchema;

class MongoSchema
Expand Down
2 changes: 1 addition & 1 deletion src/ORM/Document.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Giginc\Mongodb\ORM;
namespace Edsol\Mongodb\ORM;

use Cake\ORM\Entity;
use Exception;
Expand Down
103 changes: 69 additions & 34 deletions src/ORM/MongoFinder.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Giginc\Mongodb\ORM;
namespace Edsol\Mongodb\ORM;

use Cake\Utility\Hash;
use MongoDB\Collection;
Expand Down Expand Up @@ -58,31 +58,36 @@ public function __construct($connection, $options = [])
}
}

/**
* Convert ['foo' => 'bar', ['baz' => true]]
* to
* ['$and' => [['foo', 'bar'], ['$and' => ['baz' => true]]]
* @param $conditions
*/
private function __translateNestedArray(&$conditions)
public static function translateNestedArray(&$conditions)
{
$and = isset($conditions['$and']) ? (array)$conditions['$and'] : [];
foreach ($conditions as $key => $value) {
if (is_numeric($key) && is_array($value)) {
unset($conditions[$key]);
$and[] = $value;
} elseif (is_array($value) && !in_array(strtoupper($key), ['OR', '$OR', 'AND', '$AND'])) {
$this->__translateNestedArray($conditions[$key]);
self::translateNestedArray($conditions[$key]);
}
}
if (!empty($and)) {
$conditions['$and'] = $and;
foreach (array_keys($conditions['$and']) as $key) {
$this->__translateNestedArray($conditions['$and'][$key]);
self::translateNestedArray($conditions['$and'][$key]);
}
}
}

/**
* Convert ['foo' => 'bar', ['baz' => true]]
* to
* ['$and' => [['foo', 'bar'], ['$and' => ['baz' => true]]]
* @param $conditions
*/
private function __translateNestedArray(&$conditions)
{
return self::translateNestedArray($conditions);
}

/**
* connection
*
Expand Down Expand Up @@ -116,18 +121,23 @@ public function connection($connection = null)
* @return array
*/
private function __translateConditions(&$conditions)
{
return self::translateConditions($conditions);
}

public static function translateConditions(&$conditions)
{
$operators = '<|>|<=|>=|!=|=|<>|IN|LIKE';
foreach ($conditions as $key => $value) {
if (is_numeric($key) && is_array($value)) {
$this->__translateConditions($conditions[$key]);
self::translateConditions($conditions[$key]);
} elseif (preg_match("/^(.+) ($operators)$/", $key, $matches)) {
list(, $field, $operator) = $matches;
if (substr($field, -3) === 'NOT') {
$field = substr($field, 0, strlen($field) -4);
$operator = 'NOT '.$operator;
$field = substr($field, 0, strlen($field) - 4);
$operator = 'NOT ' . $operator;
}
$operator = $this->__translateOperator(strtoupper($operator));
$operator = self::translateOperator(strtoupper($operator));
unset($conditions[$key]);
if (substr($operator, -4) === 'LIKE') {
$value = str_replace('%', '.*', $value);
Expand All @@ -149,15 +159,17 @@ private function __translateConditions(&$conditions)
} else {
$conditions[$operator][$nestedKey] = $nestedValue;
}
$this->__translateConditions($conditions[$operator][$nestedKey]);
self::translateConditions($conditions[$operator][$nestedKey]);
}
} elseif (preg_match("/^(.+) (<|>|<=|>=|!=|=) (.+)$/", $key, $matches)
} elseif (
preg_match("/^(.+) (<|>|<=|>=|!=|=) (.+)$/", $key, $matches)
|| (is_string($value) && preg_match("/^(.+) (<|>|<=|>=|!=|=) (.+)$/", $value, $matches))
) {
unset($conditions[$key]);
array_splice($matches, 0, 1);
$conditions['$where'] = implode(' ', array_map(function ($v) {
if (preg_match("/^[\w.]+$/", $v)
if (
preg_match("/^[\w.]+$/", $v)
&& substr($v, 0, strlen('this')) !== 'this'
) {
$v = "this.$v";
Expand All @@ -178,18 +190,32 @@ private function __translateConditions(&$conditions)
* @return string
*/
private function __translateOperator($operator)
{
return self::translateOperator($operator);
}

public static function translateOperator($operator)
{
switch ($operator) {
case '<': return '$lt';
case '<=': return '$lte';
case '>': return '$gt';
case '>=': return '$gte';
case '=': return '$eq';
case '<':
return '$lt';
case '<=':
return '$lte';
case '>':
return '$gt';
case '>=':
return '$gte';
case '=':
return '$eq';
case '!=':
case '<>': return '$ne';
case 'NOT IN': return '$nin';
case 'IN': return '$in';
default: return $operator;
case '<>':
return '$ne';
case 'NOT IN':
return '$nin';
case 'IN':
return '$in';
default:
return $operator;
}
}

Expand All @@ -210,7 +236,6 @@ public function find(array $options = [])
} else {
$this->_totalRows = 0;
}

return $cursor;
}

Expand All @@ -236,12 +261,10 @@ public function findList()
$results = [];
$keyField = isset($this->_options['keyField'])
? $this->_options['keyField']
: '_id'
;
: '_id';
$valueField = isset($this->_options['valueField'])
? $this->_options['valueField']
: 'name'
;
: 'name';

$cursor = $this->find(['projection' => [$keyField => 1, $valueField => 1]]);
foreach (iterator_to_array($cursor) as $value) {
Expand Down Expand Up @@ -280,7 +303,7 @@ function ($v) {
return strtolower((string)$v) === 'desc' ? -1 : 1;
},
Hash::get($options, 'sort', [])
+ Hash::normalize((array)$this->_options['order'])
+ Hash::normalize((array)$this->_options['order'])
);
}
}
Expand All @@ -294,11 +317,12 @@ private function __limitOption(array &$options)
if (!empty($this->_options['limit']) && !isset($options['limit'])) {
$options['limit'] = $this->_options['limit'];
}
if (!empty($this->_options['page']) && $this->_options['page'] > 1
if (
!empty($this->_options['page']) && $this->_options['page'] > 1
&& !empty($options['limit'])
&& !isset($options['skip'])
) {
$options['skip'] = $options['limit'] * ($this->_options['page'] -1);
$options['skip'] = $options['limit'] * ($this->_options['page'] - 1);
}
}

Expand Down Expand Up @@ -326,4 +350,15 @@ public function count()
{
return $this->_totalRows;
}

/**
* setTotalRows
*
* @param int $rows
* @return void
*/
public function setTotalRows(int $rows)
{
$this->_totalRows = $rows;
}
}
2 changes: 1 addition & 1 deletion src/ORM/MongoQuery.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Giginc\Mongodb\ORM;
namespace Edsol\Mongodb\ORM;

class MongoQuery
{
Expand Down
2 changes: 1 addition & 1 deletion src/ORM/ResultSet.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Giginc\Mongodb\ORM;
namespace Edsol\Mongodb\ORM;

class ResultSet
{
Expand Down
Loading