static function bootTreeTrait() { Static::saving(function ($model) { if (!$model->getNameField()) { throw new Exception('Please set $name_field', 1); } if (!$model->getPathField()) { throw new Exception('Please set $path_field', 1); } else { $model->{$model->getPathField()} = ''; } $new_instance = $model->newInstance(); // RULES $rules['parent_id'] = ['integer', 'min:0']; if ($model->parent_id) { $rules['parent_id'][] = 'exists:' . $model->getTable() . ',id'; } $validator = Validator::make($model->toArray(), $rules); if ($validator->fails()) { $model->setErrors($validator->messages()); return false; } else { if ($model->parent_id) { $parent = $new_instance->findorfail($model->parent_id); $model->{$model->getPathField()} = $parent->{$model->getPathField()}; $model->{$model->getPathField()} = ($model->{$model->getPathField()} ? $model->{$model->getPathField()} . $model->getDelimiter() : '') . str_slug($model->{$model->getNameField()}); } else { $model->{$model->getPathField()} = str_slug($model->{$model->getNameField()}); } // Check Duplicated path $rules['path'] = ['unique:' . $new_instance->getTable() . ',path,' . ($model->id ? $model->id : 'NULL') . ',id']; $validator = Validator::make(['path' => $model->path], $rules, ['unique' => 'Data ' . $model->{$model->getNameField()} . ' already exists']); if ($validator->fails()) { $model->setErrors($validator->messages()); return false; } } }); Static::updated(function ($model) { if (!str_is($model->{$model->getPathField()}, $model->getOriginal($model->getPathField()))) { foreach ($model->children as $x) { $x->save(); } } }); Static::deleting(function ($model) { if ($model->children->count()) { $model->setErrors('Fail to delete ' . $model->{$model->getNameField()} . ' as it has subtrees'); return false; } }); }