Commit a51c4203 authored by Jens Segers's avatar Jens Segers

Add Jenssegers\Mongodb\Eloquent and use dummy class

parent 22063084
...@@ -107,7 +107,7 @@ Eloquent ...@@ -107,7 +107,7 @@ Eloquent
This package includes a MongoDB enabled Eloquent class that you can use to define models for corresponding collections. This package includes a MongoDB enabled Eloquent class that you can use to define models for corresponding collections.
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent {} class User extends Eloquent {}
``` ```
...@@ -115,7 +115,7 @@ class User extends Eloquent {} ...@@ -115,7 +115,7 @@ class User extends Eloquent {}
Note that we did not tell Eloquent which collection to use for the `User` model. Just like the original Eloquent, the lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. You may specify a custom collection (alias for table) by defining a `collection` property on your model: Note that we did not tell Eloquent which collection to use for the `User` model. Just like the original Eloquent, the lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. You may specify a custom collection (alias for table) by defining a `collection` property on your model:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -127,7 +127,7 @@ class User extends Eloquent { ...@@ -127,7 +127,7 @@ class User extends Eloquent {
**NOTE:** Eloquent will also assume that each collection has a primary key column named id. You may define a `primaryKey` property to override this convention. Likewise, you may define a `connection` property to override the name of the database connection that should be used when utilizing the model. **NOTE:** Eloquent will also assume that each collection has a primary key column named id. You may define a `primaryKey` property to override this convention. Likewise, you may define a `connection` property to override the name of the database connection that should be used when utilizing the model.
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class MyModel extends Eloquent { class MyModel extends Eloquent {
...@@ -143,7 +143,7 @@ Everything else works just like the original Eloquent model. Read more about the ...@@ -143,7 +143,7 @@ Everything else works just like the original Eloquent model. Read more about the
You may also register an alias for the MongoDB model by adding the following to the alias array in `app/config/app.php`: You may also register an alias for the MongoDB model by adding the following to the alias array in `app/config/app.php`:
```php ```php
'Moloquent' => 'Jenssegers\Mongodb\Model', 'Moloquent' => 'Jenssegers\Mongodb\Eloquent\Model',
``` ```
This will allow you to use the registered alias like: This will allow you to use the registered alias like:
...@@ -233,10 +233,10 @@ MongoDB Support => enabled ...@@ -233,10 +233,10 @@ MongoDB Support => enabled
#### Argument 2 passed to Illuminate\Database\Query\Builder::__construct() must be an instance of Illuminate\Database\Query\Grammars\Grammar, null given #### Argument 2 passed to Illuminate\Database\Query\Builder::__construct() must be an instance of Illuminate\Database\Query\Grammars\Grammar, null given
To solve this, you will need to check two things. First check if your model is extending the correct class; this class should be `Jenssegers\Mongodb\Model`. Secondly, check if your model is using a MongoDB connection. If you did not change the default database connection in your database configuration file, you need to specify the MongoDB enabled connection. This is what your class should look like if you did not set up an alias and change the default database connection: To solve this, you will need to check two things. First check if your model is extending the correct class; this class should be `Jenssegers\Mongodb\Eloquent\Model`. Secondly, check if your model is using a MongoDB connection. If you did not change the default database connection in your database configuration file, you need to specify the MongoDB enabled connection. This is what your class should look like if you did not set up an alias and change the default database connection:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -531,7 +531,7 @@ Eloquent allows you to work with Carbon/DateTime objects instead of MongoDate ob ...@@ -531,7 +531,7 @@ Eloquent allows you to work with Carbon/DateTime objects instead of MongoDate ob
Example: Example:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -558,7 +558,7 @@ Supported relations are: ...@@ -558,7 +558,7 @@ Supported relations are:
Example: Example:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -573,7 +573,7 @@ class User extends Eloquent { ...@@ -573,7 +573,7 @@ class User extends Eloquent {
And the inverse relation: And the inverse relation:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Item extends Eloquent { class Item extends Eloquent {
...@@ -588,7 +588,7 @@ class Item extends Eloquent { ...@@ -588,7 +588,7 @@ class Item extends Eloquent {
The belongsToMany relation will not use a pivot "table", but will push id's to a __related_ids__ attribute instead. This makes the second parameter for the belongsToMany method useless. If you want to define custom keys for your relation, set it to `null`: The belongsToMany relation will not use a pivot "table", but will push id's to a __related_ids__ attribute instead. This makes the second parameter for the belongsToMany method useless. If you want to define custom keys for your relation, set it to `null`:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -608,7 +608,7 @@ Other relations are not yet supported, but may be added in the future. Read more ...@@ -608,7 +608,7 @@ Other relations are not yet supported, but may be added in the future. Read more
If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation, but embeds the models inside the parent object. If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation, but embeds the models inside the parent object.
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent { class User extends Eloquent {
...@@ -703,7 +703,7 @@ $books = $user->books()->where('rating', '>', 5)->orderBy('title')->get(); ...@@ -703,7 +703,7 @@ $books = $user->books()->where('rating', '>', 5)->orderBy('title')->get();
The embedsOne relation is similar to the EmbedsMany relation, but only embeds a single model. The embedsOne relation is similar to the EmbedsMany relation, but only embeds a single model.
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Book extends Eloquent { class Book extends Eloquent {
...@@ -773,7 +773,7 @@ class User extends Eloquent { ...@@ -773,7 +773,7 @@ class User extends Eloquent {
And the Mongodb-based Message model: And the Mongodb-based Message model:
```php ```php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Message extends Eloquent { class Message extends Eloquent {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Jenssegers\Mongodb\Model; use Jenssegers\Mongodb\Eloquent\Model;
use Jenssegers\Mongodb\Relations\BelongsTo; use Jenssegers\Mongodb\Relations\BelongsTo;
use Jenssegers\Mongodb\Relations\BelongsToMany; use Jenssegers\Mongodb\Relations\BelongsToMany;
use Jenssegers\Mongodb\Relations\HasMany; use Jenssegers\Mongodb\Relations\HasMany;
...@@ -23,7 +23,7 @@ trait HybridRelations ...@@ -23,7 +23,7 @@ trait HybridRelations
public function hasOne($related, $foreignKey = null, $localKey = null) public function hasOne($related, $foreignKey = null, $localKey = null)
{ {
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::hasOne($related, $foreignKey, $localKey); return parent::hasOne($related, $foreignKey, $localKey);
} }
...@@ -49,7 +49,7 @@ trait HybridRelations ...@@ -49,7 +49,7 @@ trait HybridRelations
public function morphOne($related, $name, $type = null, $id = null, $localKey = null) public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
{ {
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::morphOne($related, $name, $type, $id, $localKey); return parent::morphOne($related, $name, $type, $id, $localKey);
} }
...@@ -75,7 +75,7 @@ trait HybridRelations ...@@ -75,7 +75,7 @@ trait HybridRelations
public function hasMany($related, $foreignKey = null, $localKey = null) public function hasMany($related, $foreignKey = null, $localKey = null)
{ {
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::hasMany($related, $foreignKey, $localKey); return parent::hasMany($related, $foreignKey, $localKey);
} }
...@@ -101,7 +101,7 @@ trait HybridRelations ...@@ -101,7 +101,7 @@ trait HybridRelations
public function morphMany($related, $name, $type = null, $id = null, $localKey = null) public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
{ {
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::morphMany($related, $name, $type, $id, $localKey); return parent::morphMany($related, $name, $type, $id, $localKey);
} }
...@@ -140,7 +140,7 @@ trait HybridRelations ...@@ -140,7 +140,7 @@ trait HybridRelations
} }
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::belongsTo($related, $foreignKey, $otherKey, $relation); return parent::belongsTo($related, $foreignKey, $otherKey, $relation);
} }
...@@ -227,7 +227,7 @@ trait HybridRelations ...@@ -227,7 +227,7 @@ trait HybridRelations
} }
// Check if it is a relation with an original model. // Check if it is a relation with an original model.
if (! is_subclass_of($related, 'Jenssegers\Mongodb\Model')) { if (! is_subclass_of($related, 'Jenssegers\Mongodb\Eloquent\Model')) {
return parent::belongsToMany($related, $collection, $foreignKey, $otherKey, $relation); return parent::belongsToMany($related, $collection, $foreignKey, $otherKey, $relation);
} }
......
<?php namespace Jenssegers\Mongodb\Eloquent;
use Carbon\Carbon;
use DateTime;
use Illuminate\Database\Eloquent\Model as BaseModel;
use Illuminate\Database\Eloquent\Relations\Relation;
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
use Jenssegers\Mongodb\Relations\EmbedsMany;
use Jenssegers\Mongodb\Relations\EmbedsOne;
use Jenssegers\Mongodb\Relations\EmbedsOneOrMany;
use MongoDate;
use MongoId;
use ReflectionMethod;
abstract class Model extends BaseModel
{
use HybridRelations;
/**
* The collection associated with the model.
*
* @var string
*/
protected $collection;
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = '_id';
/**
* The parent relation instance.
*
* @var Relation
*/
protected $parentRelation;
/**
* Custom accessor for the model's id.
*
* @param mixed $value
* @return mixed
*/
public function getIdAttribute($value)
{
// If we don't have a value for 'id', we will use the Mongo '_id' value.
// This allows us to work with models in a more sql-like way.
if (! $value and array_key_exists('_id', $this->attributes)) {
$value = $this->attributes['_id'];
}
// Convert MongoId's to string.
if ($value instanceof MongoId) {
return (string) $value;
}
return $value;
}
/**
* Get the table qualified key name.
*
* @return string
*/
public function getQualifiedKeyName()
{
return $this->getKeyName();
}
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $localKey
* @param string $foreignKey
* @param string $relation
* @return \Jenssegers\Mongodb\Relations\EmbedsMany
*/
protected function embedsMany($related, $localKey = null, $foreignKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation)) {
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
if (is_null($localKey)) {
$localKey = $relation;
}
if (is_null($foreignKey)) {
$foreignKey = snake_case(class_basename($this));
}
$query = $this->newQuery();
$instance = new $related;
return new EmbedsMany($query, $this, $instance, $localKey, $foreignKey, $relation);
}
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $localKey
* @param string $foreignKey
* @param string $relation
* @return \Jenssegers\Mongodb\Relations\EmbedsOne
*/
protected function embedsOne($related, $localKey = null, $foreignKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation)) {
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
if (is_null($localKey)) {
$localKey = $relation;
}
if (is_null($foreignKey)) {
$foreignKey = snake_case(class_basename($this));
}
$query = $this->newQuery();
$instance = new $related;
return new EmbedsOne($query, $this, $instance, $localKey, $foreignKey, $relation);
}
/**
* Convert a DateTime to a storable MongoDate object.
*
* @param DateTime|int $value
* @return MongoDate
*/
public function fromDateTime($value)
{
// If the value is already a MongoDate instance, we don't need to parse it.
if ($value instanceof MongoDate) {
return $value;
}
// Let Eloquent convert the value to a DateTime instance.
if (! $value instanceof DateTime) {
$value = parent::asDateTime($value);
}
return new MongoDate($value->getTimestamp());
}
/**
* Return a timestamp as DateTime object.
*
* @param mixed $value
* @return DateTime
*/
protected function asDateTime($value)
{
// Convert MongoDate instances.
if ($value instanceof MongoDate) {
return Carbon::createFromTimestamp($value->sec);
}
return parent::asDateTime($value);
}
/**
* Get the format for database stored dates.
*
* @return string
*/
protected function getDateFormat()
{
return $this->dateFormat ?: 'Y-m-d H:i:s';
}
/**
* Get a fresh timestamp for the model.
*
* @return MongoDate
*/
public function freshTimestamp()
{
return new MongoDate;
}
/**
* Get the table associated with the model.
*
* @return string
*/
public function getTable()
{
return $this->collection ?: parent::getTable();
}
/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
// Check if the key is an array dot notation.
if (str_contains($key, '.') and array_has($this->attributes, $key)) {
return $this->getAttributeValue($key);
}
$camelKey = camel_case($key);
// If the "attribute" exists as a method on the model, it may be an
// embedded model. If so, we need to return the result before it
// is handled by the parent method.
if (method_exists($this, $camelKey)) {
$method = new ReflectionMethod(get_called_class(), $camelKey);
// Ensure the method is not static to avoid conflicting with Eloquent methods.
if (! $method->isStatic()) {
$relations = $this->$camelKey();
// This attribute matches an embedsOne or embedsMany relation so we need
// to return the relation results instead of the interal attributes.
if ($relations instanceof EmbedsOneOrMany) {
// If the key already exists in the relationships array, it just means the
// relationship has already been loaded, so we'll just return it out of
// here because there is no need to query within the relations twice.
if (array_key_exists($key, $this->relations)) {
return $this->relations[$key];
}
// Get the relation results.
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
}
return parent::getAttribute($key);
}
/**
* Get an attribute from the $attributes array.
*
* @param string $key
* @return mixed
*/
protected function getAttributeFromArray($key)
{
// Support keys in dot notation.
if (str_contains($key, '.')) {
$attributes = array_dot($this->attributes);
if (array_key_exists($key, $attributes)) {
return $attributes[$key];
}
}
return parent::getAttributeFromArray($key);
}
/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
*/
public function setAttribute($key, $value)
{
// Convert _id to MongoId.
if ($key == '_id' and is_string($value)) {
$builder = $this->newBaseQueryBuilder();
$value = $builder->convertKey($value);
}
// Support keys in dot notation.
elseif (str_contains($key, '.')) {
if (in_array($key, $this->getDates()) && $value) {
$value = $this->fromDateTime($value);
}
array_set($this->attributes, $key, $value);
return;
}
parent::setAttribute($key, $value);
}
/**
* Get the casts array.
*
* @return array
*/
public function getCasts()
{
return $this->casts;
}
/**
* Convert the model's attributes to an array.
*
* @return array
*/
public function attributesToArray()
{
$attributes = parent::attributesToArray();
// Because the original Eloquent never returns objects, we convert
// MongoDB related objects to a string representation. This kind
// of mimics the SQL behaviour so that dates are formatted
// nicely when your models are converted to JSON.
foreach ($attributes as $key => &$value) {
if ($value instanceof MongoId) {
$value = (string) $value;
}
}
// Convert dot-notation dates.
foreach ($this->getDates() as $key) {
if (str_contains($key, '.') and array_has($attributes, $key)) {
array_set($attributes, $key, (string) $this->asDateTime(array_get($attributes, $key)));
}
}
return $attributes;
}
/**
* Determine if the new and old values for a given key are numerically equivalent.
*
* @param string $key
* @return bool
*/
protected function originalIsNumericallyEquivalent($key)
{
$current = $this->attributes[$key];
$original = $this->original[$key];
// Date comparison.
if (in_array($key, $this->getDates())) {
$current = $current instanceof MongoDate ? $this->asDateTime($current) : $current;
$original = $original instanceof MongoDate ? $this->asDateTime($original) : $original;
return $current == $original;
}
return parent::originalIsNumericallyEquivalent($key);
}
/**
* Remove one or more fields.
*
* @param mixed $columns
* @return int
*/
public function drop($columns)
{
if (! is_array($columns)) {
$columns = [$columns];
}
// Unset attributes
foreach ($columns as $column) {
$this->__unset($column);
}
// Perform unset only on current document
return $this->newQuery()->where($this->getKeyName(), $this->getKey())->unset($columns);
}
/**
* Append one or more values to an array.
*
* @return mixed
*/
public function push()
{
if ($parameters = func_get_args()) {
$unique = false;
if (count($parameters) == 3) {
list($column, $values, $unique) = $parameters;
} else {
list($column, $values) = $parameters;
}
// Do batch push by default.
if (! is_array($values)) {
$values = [$values];
}
$query = $this->setKeysForSaveQuery($this->newQuery());
$this->pushAttributeValues($column, $values, $unique);
return $query->push($column, $values, $unique);
}
return parent::push();
}
/**
* Remove one or more values from an array.
*
* @param string $column
* @param mixed $values
* @return mixed
*/
public function pull($column, $values)
{
// Do batch pull by default.
if (! is_array($values)) {
$values = [$values];
}
$query = $this->setKeysForSaveQuery($this->newQuery());
$this->pullAttributeValues($column, $values);
return $query->pull($column, $values);
}
/**
* Append one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
* @param bool $unique
*/
protected function pushAttributeValues($column, array $values, $unique = false)
{
$current = $this->getAttributeFromArray($column) ?: [];
foreach ($values as $value) {
// Don't add duplicate values when we only want unique values.
if ($unique and in_array($value, $current)) {
continue;
}
array_push($current, $value);
}
$this->attributes[$column] = $current;
$this->syncOriginalAttribute($column);
}
/**
* Remove one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
*/
protected function pullAttributeValues($column, array $values)
{
$current = $this->getAttributeFromArray($column) ?: [];
foreach ($values as $value) {
$keys = array_keys($current, $value);
foreach ($keys as $key) {
unset($current[$key]);
}
}
$this->attributes[$column] = array_values($current);
$this->syncOriginalAttribute($column);
}
/**
* Set the parent relation.
*
* @param \Illuminate\Database\Eloquent\Relations\Relation $relation
*/
public function setParentRelation(Relation $relation)
{
$this->parentRelation = $relation;
}
/**
* Get the parent relation.
*
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function getParentRelation()
{
return $this->parentRelation;
}
/**
* Create a new Eloquent query builder for the model.
*
* @param \Jenssegers\Mongodb\Query\Builder $query
* @return \Jenssegers\Mongodb\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new Builder($query);
}
/**
* Get a new query builder instance for the connection.
*
* @return Builder
*/
protected function newBaseQueryBuilder()
{
$connection = $this->getConnection();
return new QueryBuilder($connection, $connection->getPostProcessor());
}
/**
* Handle dynamic method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
// Unset method
if ($method == 'unset') {
return call_user_func_array([$this, 'drop'], $parameters);
}
return parent::__call($method, $parameters);
}
}
<?php namespace Jenssegers\Mongodb; <?php namespace Jenssegers\Mongodb;
use Carbon\Carbon; use Jenssegers\Mongodb\Eloquent\Model as BaseModel;
use DateTime;
use Illuminate\Database\Eloquent\Model as BaseModel;
use Illuminate\Database\Eloquent\Relations\Relation;
use Jenssegers\Mongodb\Eloquent\Builder;
use Jenssegers\Mongodb\Eloquent\HybridRelations;
use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
use Jenssegers\Mongodb\Relations\EmbedsMany;
use Jenssegers\Mongodb\Relations\EmbedsOne;
use Jenssegers\Mongodb\Relations\EmbedsOneOrMany;
use MongoDate;
use MongoId;
use ReflectionMethod;
abstract class Model extends BaseModel abstract class Model extends BaseModel
{ {
use HybridRelations;
/**
* The collection associated with the model.
*
* @var string
*/
protected $collection;
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = '_id';
/**
* The parent relation instance.
*
* @var Relation
*/
protected $parentRelation;
/**
* Custom accessor for the model's id.
*
* @param mixed $value
* @return mixed
*/
public function getIdAttribute($value)
{
// If we don't have a value for 'id', we will use the Mongo '_id' value.
// This allows us to work with models in a more sql-like way.
if (! $value and array_key_exists('_id', $this->attributes)) {
$value = $this->attributes['_id'];
}
// Convert MongoId's to string.
if ($value instanceof MongoId) {
return (string) $value;
}
return $value;
}
/**
* Get the table qualified key name.
*
* @return string
*/
public function getQualifiedKeyName()
{
return $this->getKeyName();
}
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $localKey
* @param string $foreignKey
* @param string $relation
* @return \Jenssegers\Mongodb\Relations\EmbedsMany
*/
protected function embedsMany($related, $localKey = null, $foreignKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation)) {
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
if (is_null($localKey)) {
$localKey = $relation;
}
if (is_null($foreignKey)) {
$foreignKey = snake_case(class_basename($this));
}
$query = $this->newQuery();
$instance = new $related;
return new EmbedsMany($query, $this, $instance, $localKey, $foreignKey, $relation);
}
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $localKey
* @param string $foreignKey
* @param string $relation
* @return \Jenssegers\Mongodb\Relations\EmbedsOne
*/
protected function embedsOne($related, $localKey = null, $foreignKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation)) {
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
if (is_null($localKey)) {
$localKey = $relation;
}
if (is_null($foreignKey)) {
$foreignKey = snake_case(class_basename($this));
}
$query = $this->newQuery();
$instance = new $related;
return new EmbedsOne($query, $this, $instance, $localKey, $foreignKey, $relation);
}
/**
* Convert a DateTime to a storable MongoDate object.
*
* @param DateTime|int $value
* @return MongoDate
*/
public function fromDateTime($value)
{
// If the value is already a MongoDate instance, we don't need to parse it.
if ($value instanceof MongoDate) {
return $value;
}
// Let Eloquent convert the value to a DateTime instance.
if (! $value instanceof DateTime) {
$value = parent::asDateTime($value);
}
return new MongoDate($value->getTimestamp());
}
/**
* Return a timestamp as DateTime object.
*
* @param mixed $value
* @return DateTime
*/
protected function asDateTime($value)
{
// Convert MongoDate instances.
if ($value instanceof MongoDate) {
return Carbon::createFromTimestamp($value->sec);
}
return parent::asDateTime($value);
}
/**
* Get the format for database stored dates.
*
* @return string
*/
protected function getDateFormat()
{
return $this->dateFormat ?: 'Y-m-d H:i:s';
}
/**
* Get a fresh timestamp for the model.
*
* @return MongoDate
*/
public function freshTimestamp()
{
return new MongoDate;
}
/**
* Get the table associated with the model.
*
* @return string
*/
public function getTable()
{
return $this->collection ?: parent::getTable();
}
/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
// Check if the key is an array dot notation.
if (str_contains($key, '.') and array_has($this->attributes, $key)) {
return $this->getAttributeValue($key);
}
$camelKey = camel_case($key);
// If the "attribute" exists as a method on the model, it may be an
// embedded model. If so, we need to return the result before it
// is handled by the parent method.
if (method_exists($this, $camelKey)) {
$method = new ReflectionMethod(get_called_class(), $camelKey);
// Ensure the method is not static to avoid conflicting with Eloquent methods.
if (! $method->isStatic()) {
$relations = $this->$camelKey();
// This attribute matches an embedsOne or embedsMany relation so we need
// to return the relation results instead of the interal attributes.
if ($relations instanceof EmbedsOneOrMany) {
// If the key already exists in the relationships array, it just means the
// relationship has already been loaded, so we'll just return it out of
// here because there is no need to query within the relations twice.
if (array_key_exists($key, $this->relations)) {
return $this->relations[$key];
}
// Get the relation results.
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
}
return parent::getAttribute($key);
}
/**
* Get an attribute from the $attributes array.
*
* @param string $key
* @return mixed
*/
protected function getAttributeFromArray($key)
{
// Support keys in dot notation.
if (str_contains($key, '.')) {
$attributes = array_dot($this->attributes);
if (array_key_exists($key, $attributes)) {
return $attributes[$key];
}
}
return parent::getAttributeFromArray($key);
}
/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
*/
public function setAttribute($key, $value)
{
// Convert _id to MongoId.
if ($key == '_id' and is_string($value)) {
$builder = $this->newBaseQueryBuilder();
$value = $builder->convertKey($value);
}
// Support keys in dot notation.
elseif (str_contains($key, '.')) {
if (in_array($key, $this->getDates()) && $value) {
$value = $this->fromDateTime($value);
}
array_set($this->attributes, $key, $value);
return;
}
parent::setAttribute($key, $value);
}
/**
* Get the casts array.
*
* @return array
*/
public function getCasts()
{
return $this->casts;
}
/**
* Convert the model's attributes to an array.
*
* @return array
*/
public function attributesToArray()
{
$attributes = parent::attributesToArray();
// Because the original Eloquent never returns objects, we convert
// MongoDB related objects to a string representation. This kind
// of mimics the SQL behaviour so that dates are formatted
// nicely when your models are converted to JSON.
foreach ($attributes as $key => &$value) {
if ($value instanceof MongoId) {
$value = (string) $value;
}
}
// Convert dot-notation dates.
foreach ($this->getDates() as $key) {
if (str_contains($key, '.') and array_has($attributes, $key)) {
array_set($attributes, $key, (string) $this->asDateTime(array_get($attributes, $key)));
}
}
return $attributes;
}
/**
* Determine if the new and old values for a given key are numerically equivalent.
*
* @param string $key
* @return bool
*/
protected function originalIsNumericallyEquivalent($key)
{
$current = $this->attributes[$key];
$original = $this->original[$key];
// Date comparison.
if (in_array($key, $this->getDates())) {
$current = $current instanceof MongoDate ? $this->asDateTime($current) : $current;
$original = $original instanceof MongoDate ? $this->asDateTime($original) : $original;
return $current == $original;
}
return parent::originalIsNumericallyEquivalent($key);
}
/**
* Remove one or more fields.
*
* @param mixed $columns
* @return int
*/
public function drop($columns)
{
if (! is_array($columns)) {
$columns = [$columns];
}
// Unset attributes
foreach ($columns as $column) {
$this->__unset($column);
}
// Perform unset only on current document
return $this->newQuery()->where($this->getKeyName(), $this->getKey())->unset($columns);
}
/**
* Append one or more values to an array.
*
* @return mixed
*/
public function push()
{
if ($parameters = func_get_args()) {
$unique = false;
if (count($parameters) == 3) {
list($column, $values, $unique) = $parameters;
} else {
list($column, $values) = $parameters;
}
// Do batch push by default.
if (! is_array($values)) {
$values = [$values];
}
$query = $this->setKeysForSaveQuery($this->newQuery());
$this->pushAttributeValues($column, $values, $unique);
return $query->push($column, $values, $unique);
}
return parent::push();
}
/**
* Remove one or more values from an array.
*
* @param string $column
* @param mixed $values
* @return mixed
*/
public function pull($column, $values)
{
// Do batch pull by default.
if (! is_array($values)) {
$values = [$values];
}
$query = $this->setKeysForSaveQuery($this->newQuery());
$this->pullAttributeValues($column, $values);
return $query->pull($column, $values);
}
/**
* Append one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
* @param bool $unique
*/
protected function pushAttributeValues($column, array $values, $unique = false)
{
$current = $this->getAttributeFromArray($column) ?: [];
foreach ($values as $value) {
// Don't add duplicate values when we only want unique values.
if ($unique and in_array($value, $current)) {
continue;
}
array_push($current, $value);
}
$this->attributes[$column] = $current;
$this->syncOriginalAttribute($column);
}
/**
* Remove one or more values to the underlying attribute value and sync with original.
*
* @param string $column
* @param array $values
*/
protected function pullAttributeValues($column, array $values)
{
$current = $this->getAttributeFromArray($column) ?: [];
foreach ($values as $value) {
$keys = array_keys($current, $value);
foreach ($keys as $key) {
unset($current[$key]);
}
}
$this->attributes[$column] = array_values($current);
$this->syncOriginalAttribute($column);
}
/**
* Set the parent relation.
*
* @param \Illuminate\Database\Eloquent\Relations\Relation $relation
*/
public function setParentRelation(Relation $relation)
{
$this->parentRelation = $relation;
}
/**
* Get the parent relation.
*
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function getParentRelation()
{
return $this->parentRelation;
}
/**
* Create a new Eloquent query builder for the model.
*
* @param \Jenssegers\Mongodb\Query\Builder $query
* @return \Jenssegers\Mongodb\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new Builder($query);
}
/**
* Get a new query builder instance for the connection.
*
* @return Builder
*/
protected function newBaseQueryBuilder()
{
$connection = $this->getConnection();
return new QueryBuilder($connection, $connection->getPostProcessor());
}
/**
* Handle dynamic method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
// Unset method
if ($method == 'unset') {
return call_user_func_array([$this, 'drop'], $parameters);
}
return parent::__call($method, $parameters);
}
} }
<?php namespace Jenssegers\Mongodb; <?php namespace Jenssegers\Mongodb;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Jenssegers\Eloquent\Model;
class MongodbServiceProvider extends ServiceProvider class MongodbServiceProvider extends ServiceProvider
{ {
......
<?php require 'vendor/autoload.php';
...@@ -14,7 +14,7 @@ class ModelTest extends TestCase ...@@ -14,7 +14,7 @@ class ModelTest extends TestCase
public function testNewModel() public function testNewModel()
{ {
$user = new User; $user = new User;
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $user); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $user);
$this->assertInstanceOf('Jenssegers\Mongodb\Connection', $user->getConnection()); $this->assertInstanceOf('Jenssegers\Mongodb\Connection', $user->getConnection());
$this->assertEquals(false, $user->exists); $this->assertEquals(false, $user->exists);
$this->assertEquals('users', $user->getTable()); $this->assertEquals('users', $user->getTable());
...@@ -171,7 +171,7 @@ class ModelTest extends TestCase ...@@ -171,7 +171,7 @@ class ModelTest extends TestCase
$check = User::find($user->_id); $check = User::find($user->_id);
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $check); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $check);
$this->assertEquals(true, $check->exists); $this->assertEquals(true, $check->exists);
$this->assertEquals($user->_id, $check->_id); $this->assertEquals($user->_id, $check->_id);
...@@ -189,7 +189,7 @@ class ModelTest extends TestCase ...@@ -189,7 +189,7 @@ class ModelTest extends TestCase
$users = User::get(); $users = User::get();
$this->assertEquals(2, count($users)); $this->assertEquals(2, count($users));
$this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users); $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users);
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $users[0]); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $users[0]);
} }
public function testFirst() public function testFirst()
...@@ -200,7 +200,7 @@ class ModelTest extends TestCase ...@@ -200,7 +200,7 @@ class ModelTest extends TestCase
]); ]);
$user = User::first(); $user = User::first();
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $user); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $user);
$this->assertEquals('John Doe', $user->name); $this->assertEquals('John Doe', $user->name);
} }
...@@ -227,7 +227,7 @@ class ModelTest extends TestCase ...@@ -227,7 +227,7 @@ class ModelTest extends TestCase
{ {
$user = User::create(['name' => 'Jane Poe']); $user = User::create(['name' => 'Jane Poe']);
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $user); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $user);
$this->assertEquals(true, $user->exists); $this->assertEquals(true, $user->exists);
$this->assertEquals('Jane Poe', $user->name); $this->assertEquals('Jane Poe', $user->name);
...@@ -455,12 +455,12 @@ class ModelTest extends TestCase ...@@ -455,12 +455,12 @@ class ModelTest extends TestCase
return $collection->find(['age' => 35]); return $collection->find(['age' => 35]);
}); });
$this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users); $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users);
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $users[0]); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $users[0]);
$user = User::raw(function ($collection) { $user = User::raw(function ($collection) {
return $collection->findOne(['age' => 35]); return $collection->findOne(['age' => 35]);
}); });
$this->assertInstanceOf('Jenssegers\Mongodb\Model', $user); $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Model', $user);
$count = User::raw(function ($collection) { $count = User::raw(function ($collection) {
return $collection->count(); return $collection->count();
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Address extends Eloquent class Address extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Book extends Eloquent class Book extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Client extends Eloquent class Client extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Group extends Eloquent class Group extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Item extends Eloquent class Item extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Photo extends Eloquent class Photo extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Role extends Eloquent class Role extends Eloquent
{ {
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
use Jenssegers\Mongodb\Eloquent\SoftDeletes; use Jenssegers\Mongodb\Eloquent\SoftDeletes;
class Soft extends Eloquent class Soft extends Eloquent
......
<?php <?php
use Jenssegers\Mongodb\Model as Eloquent; use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
use Illuminate\Auth\Authenticatable; use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment