Commit ca065823 authored by Taylor Otwell's avatar Taylor Otwell

Add some events to Eloquent models.

parent 1f3d269a
<?php namespace Laravel\Database\Eloquent; <?php namespace Laravel\Database\Eloquent;
use Laravel\Str; use Laravel\Str;
use Laravel\Event;
use Laravel\Database; use Laravel\Database;
use Laravel\Database\Eloquent\Relationships\Has_Many_And_Belongs_To; use Laravel\Database\Eloquent\Relationships\Has_Many_And_Belongs_To;
...@@ -115,14 +116,23 @@ abstract class Model { ...@@ -115,14 +116,23 @@ abstract class Model {
* Hydrate the model with an array of attributes. * Hydrate the model with an array of attributes.
* *
* @param array $attributes * @param array $attributes
* @param bool $raw
* @return Model * @return Model
*/ */
public function fill($attributes) public function fill(array $attributes, $raw = false)
{ {
$attributes = (array) $attributes;
foreach ($attributes as $key => $value) foreach ($attributes as $key => $value)
{ {
// If the "raw" flag is set, it means that we'll just load every value from
// the array directly into the attributes, without any accessibility or
// mutators being accounted for. What you pass in is what you get.
if ($raw)
{
$this->set_attribute($key, $value);
continue;
}
// If the "accessible" property is an array, the developer is limiting the // If the "accessible" property is an array, the developer is limiting the
// attributes that may be mass assigned, and we need to verify that the // attributes that may be mass assigned, and we need to verify that the
// current attribute is included in that list of allowed attributes. // current attribute is included in that list of allowed attributes.
...@@ -154,14 +164,29 @@ abstract class Model { ...@@ -154,14 +164,29 @@ abstract class Model {
return $this; return $this;
} }
/**
* Fill the model with the contents of the array.
*
* No mutators or accessibility checks will be accounted for.
*
* @param array $attributes
* @return Model
*/
public function fill_raw(array $attributes)
{
return $this->fill($attributes, true);
}
/** /**
* Set the accessible attributes for the given model. * Set the accessible attributes for the given model.
* *
* @param array $attributes * @param array $attributes
* @return void * @return void
*/ */
public static function accessible($attributes) public static function accessible($attributes = null)
{ {
if (is_null($attributes)) return static::$accessible;
static::$accessible = $attributes; static::$accessible = $attributes;
} }
...@@ -355,6 +380,8 @@ abstract class Model { ...@@ -355,6 +380,8 @@ abstract class Model {
$this->timestamp(); $this->timestamp();
} }
$this->fire_event('saving');
// If the model exists, we only need to update it in the database, and the update // If the model exists, we only need to update it in the database, and the update
// will be considered successful if there is one affected row returned from the // will be considered successful if there is one affected row returned from the
// fluent query instance. We'll set the where condition automatically. // fluent query instance. We'll set the where condition automatically.
...@@ -382,6 +409,11 @@ abstract class Model { ...@@ -382,6 +409,11 @@ abstract class Model {
// dirty and subsequent calls won't hit the database. // dirty and subsequent calls won't hit the database.
$this->original = $this->attributes; $this->original = $this->attributes;
if ($result)
{
$this->fire_event('saved');
}
return $result; return $result;
} }
...@@ -394,7 +426,13 @@ abstract class Model { ...@@ -394,7 +426,13 @@ abstract class Model {
{ {
if ($this->exists) if ($this->exists)
{ {
return $this->query()->where(static::$key, '=', $this->get_key())->delete(); $this->fire_event('deleting');
$result = $this->query()->where(static::$key, '=', $this->get_key())->delete();
$this->fire_event('deleted');
return $result;
} }
} }
...@@ -585,6 +623,19 @@ abstract class Model { ...@@ -585,6 +623,19 @@ abstract class Model {
return $attributes; return $attributes;
} }
/**
* Fire a given event for the model.
*
* @param string $event
* @return array
*/
protected function fire_event($event)
{
$events = array("eloquent.{$event}", "eloquent.{$event}: ".get_class($this));
Event::fire($events, array($this));
}
/** /**
* Handle the dynamic retrieval of attributes and associations. * Handle the dynamic retrieval of attributes and associations.
* *
......
<?php namespace Laravel\Database\Eloquent; <?php namespace Laravel\Database\Eloquent;
use Laravel\Event;
use Laravel\Database; use Laravel\Database;
use Laravel\Database\Eloquent\Relationships\Has_Many_And_Belongs_To; use Laravel\Database\Eloquent\Relationships\Has_Many_And_Belongs_To;
...@@ -119,12 +120,7 @@ class Query { ...@@ -119,12 +120,7 @@ class Query {
// We need to set the attributes manually in case the accessible property is // We need to set the attributes manually in case the accessible property is
// set on the array which will prevent the mass assignemnt of attributes if // set on the array which will prevent the mass assignemnt of attributes if
// we were to pass them in using the constructor or fill methods. // we were to pass them in using the constructor or fill methods.
foreach ($result as $key => $value) $new->fill_raw($result);
{
$new->set_attribute($key, $value);
}
$new->original = $new->attributes;
$models[] = $new; $models[] = $new;
} }
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
- `Schema::drop` now accepts `$connection` as second parameter. - `Schema::drop` now accepts `$connection` as second parameter.
- Added `Input::merge` method. - Added `Input::merge` method.
- Added `Input::replace` method. - Added `Input::replace` method.
- Added `eloquent.saved`, `eloquent.saving`, `eloquent.deleting`, and `eloquent.deleted` events to Eloquent models.
<a name="upgrade-3.2"></a> <a name="upgrade-3.2"></a>
## Upgrading From 3.1 ## Upgrading From 3.1
......
...@@ -108,14 +108,17 @@ class Event { ...@@ -108,14 +108,17 @@ class Event {
* *
* // Fire the "start" event passing an array of parameters * // Fire the "start" event passing an array of parameters
* $responses = Event::fire('start', array('Laravel', 'Framework')); * $responses = Event::fire('start', array('Laravel', 'Framework'));
*
* // Fire multiple events with the same parameters
* $responses = Event::fire(array('start', 'loading'), $parameters);
* </code> * </code>
* *
* @param string $event * @param string|array $event
* @param array $parameters * @param array $parameters
* @param bool $halt * @param bool $halt
* @return array * @return array
*/ */
public static function fire($event, $parameters = array(), $halt = false) public static function fire($events, $parameters = array(), $halt = false)
{ {
$responses = array(); $responses = array();
...@@ -124,24 +127,27 @@ class Event { ...@@ -124,24 +127,27 @@ class Event {
// If the event has listeners, we will simply iterate through them and call // If the event has listeners, we will simply iterate through them and call
// each listener, passing in the parameters. We will add the responses to // each listener, passing in the parameters. We will add the responses to
// an array of event responses and return the array. // an array of event responses and return the array.
if (static::listeners($event)) foreach ((array) $events as $event)
{ {
foreach (static::$events[$event] as $callback) if (static::listeners($event))
{ {
$response = call_user_func_array($callback, $parameters); foreach (static::$events[$event] as $callback)
// If the event is set to halt, we will return the first response
// that is not null. This allows the developer to easily stack
// events but still get the first valid response.
if ($halt and ! is_null($response))
{ {
return $response; $response = call_user_func_array($callback, $parameters);
// If the event is set to halt, we will return the first response
// that is not null. This allows the developer to easily stack
// events but still get the first valid response.
if ($halt and ! is_null($response))
{
return $response;
}
// After the handler has been called, we'll add the response to
// an array of responses and return the array to the caller so
// all of the responses can be easily examined.
$responses[] = $response;
} }
// After the handler has been called, we'll add the response to
// an array of responses and return the array to the caller so
// all of the responses can be easily examined.
$responses[] = $response;
} }
} }
......
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