Last active
July 9, 2019 18:52
-
-
Save andy-berry-dev/be3c45380568fc359cb61e00c4249704 to your computer and use it in GitHub Desktop.
Changes required to Laravel to allow observing attached/detached events (https://github.com/laravel/framework/pull/14988#issuecomment-267717423)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use App\Extensions\Relations\BelongsToMany; | |
abstract class AbstractModel extends Model | |
{ | |
/* | |
* This is copied AS IS from \Illuminate\Database\Eloquent\Model@belongsToMany but instead uses our own BelongsToMany class | |
*/ | |
public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null) | |
{ | |
if (is_null($relation)) { | |
$relation = $this->getBelongsToManyCaller(); | |
} | |
$foreignKey = $foreignKey ?: $this->getForeignKey(); | |
$instance = new $related; | |
$otherKey = $otherKey ?: $instance->getForeignKey(); | |
if (is_null($table)) { | |
$table = $this->joiningTable($related); | |
} | |
$query = $instance->newQuery(); | |
return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation); | |
} | |
/* | |
* Override Model@observe and add replace . with _ for the observer callback | |
*/ | |
public static function observe($class, $priority = 0) | |
{ | |
$instance = new static; | |
$className = is_string($class) ? $class : get_class($class); | |
foreach ($instance->getObservableEvents() as $event) { | |
$methodName = str_replace('.', '_', $event); | |
if (method_exists($class, $methodName)) { | |
static::registerModelEvent($event, $className.'@'.$methodName, $priority); | |
} | |
} | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Extensions\Relations; | |
use Exception; | |
use Illuminate\Support\Collection; | |
use Illuminate\Database\Eloquent\Collection as EloquentCollection; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Relations\BelongsToMany as LaravelBelongsToMany; | |
class BelongsToMany extends LaravelBelongsToMany { | |
public function attach($ids, array $attributes = [], $touch = true) | |
{ | |
$returnVal = parent::attach($ids, $attributes, $touch); | |
if ($ids instanceof EloquentCollection) | |
{ | |
$ids = $ids->modelKeys(); | |
} | |
else | |
{ | |
$ids = [$ids]; | |
} | |
foreach($ids as $id) | |
{ | |
$attached = $id instanceof Model ? $this->find($id = $id->getKey()) : $this->find($id); | |
if ($attached) | |
{ | |
$this->fireParentEvent("attached.{$this->relationName}", $attached, false); | |
} | |
} | |
return $returnVal; | |
} | |
public function detach($ids = [], $touch = true) | |
{ | |
$results = parent::detach($ids, $touch); | |
if ($ids instanceof EloquentCollection) | |
{ | |
$ids = $ids->modelKeys(); | |
} | |
else | |
{ | |
$ids = [$ids]; | |
} | |
foreach($ids as $id) | |
{ | |
$id = $id instanceof Model ? $id->getKey() : $id; | |
$this->fireParentEvent("detached.{$this->relationName}", $id, false); | |
} | |
return $results; | |
} | |
protected function fireParentEvent($event, $records, $halt = true) | |
{ | |
$dispatcher = $this->getParent()->getEventDispatcher(); | |
if (! $dispatcher) | |
{ | |
return true; | |
} | |
$event = "eloquent.{$event}: ".get_class($this->getParent()); | |
$method = $halt ? 'until' : 'fire'; | |
return $dispatcher->$method($event, [$this->getParent(), $records]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class MyModel extends AbstractModel | |
{ | |
protected $observables = [ | |
'attached.someRelationship', | |
'detached.someRelationship', | |
]; | |
public function boot() | |
{ | |
MyModel::attached_some_relationship(function ($model) { | |
// do something | |
}); | |
} | |
// the rest of your model | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
so that is working)