Skip to content
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

[Release] CRUD 3.4 Upgrade #1251

Merged
merged 73 commits into from
Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
782f2c4
Fixed typo in comment
Aug 16, 2017
7f4dd96
Implemented 1 to 1 relations on create
Aug 16, 2017
a7b31cd
Refactored recursive method
Aug 16, 2017
3037ba1
Added null check for relation when getting nested attributes
Aug 16, 2017
0661280
Formatted form data and added recursive method for creating item rela…
Aug 16, 2017
77e277c
Added form information to create relations methods
Aug 16, 2017
8b5ad1d
Fixed update relations
Aug 16, 2017
d9f50fa
Removed TODO after fix
Aug 16, 2017
bc778e8
Moved condition from second relation data filter into the first one f…
Aug 17, 2017
a778403
Added visibility modifier to function
Aug 17, 2017
63fd071
Removed redundant field access when setting update field values
Aug 17, 2017
47dc235
Added method for getting values in update view for fields with chaine…
Aug 17, 2017
dda342c
Added dissociate to relations when form value is null.
Aug 17, 2017
33fbf0a
Apply fixes from StyleCI (#864)
tabacitu Aug 17, 2017
03aa036
Updated docs. Used isset instead of null check. Removed setValue meth…
Aug 21, 2017
076ea86
Merge branch 'feature-1-to-1-relationships' of https://github.com/Lar…
Aug 21, 2017
9993ddf
Apply fixes from StyleCI (#876)
tabacitu Aug 21, 2017
bcf2103
Removed unnecessary variable assignment.
Aug 21, 2017
2172df6
Merge branch 'feature-1-to-1-relationships' of https://github.com/Lar…
Aug 21, 2017
f2ac05a
Removed collection when generating formatted relations array.
Aug 21, 2017
fbeb442
Added docs to the update trait methods.
Aug 21, 2017
1804e28
Moved else to previous line.
Aug 21, 2017
ad414e1
Extracted relation method into variable.
Aug 21, 2017
b057596
Removed unnecessary condition and fixed pivot entry check when filter…
Aug 21, 2017
75fef00
Apply fixes from StyleCI (#877)
tabacitu Aug 21, 2017
f58949f
Re-added check for related model variable when getting entry value.
Aug 22, 2017
42d34b5
Refactored the formatData method.
Aug 22, 2017
364151c
Apply fixes from StyleCI (#878)
tabacitu Aug 22, 2017
fb25595
Renamed getEntryValue method in update trait.
Aug 23, 2017
875ad51
Merge branch 'feature-1-to-1-relationships' of https://github.com/Lar…
Aug 23, 2017
c25ba67
Merge branch 'dev' into feature-1-to-1-relationships
Aug 23, 2017
1f43c88
Refactored the getAttributeFromNestedRelations method in the CRUD panel.
Aug 24, 2017
e824d95
Apply fixes from StyleCI (#883)
tabacitu Aug 24, 2017
c5cb10d
Simplified getting the entity model in the select2 field view. Added …
Aug 24, 2017
bc46cfb
Renamed method name to plural form to reflect returned result.
Aug 27, 2017
d250a97
Restructured doc and extracted variable in get relation fields method.
Aug 27, 2017
8ccbbcf
Merge branch 'feature-1-to-1-relationships' of https://github.com/Lar…
Aug 27, 2017
aba0914
Added fully qualified model class name in php docs.
Aug 31, 2017
d388578
Merge branch 'upgrade' into feature-1-to-1-relationships
tabacitu Oct 25, 2017
995b031
Merge branch 'upgrade' into feature-1-to-1-relationships
tabacitu Oct 25, 2017
cf07deb
list view datatables uses datatables-responsive plugin
tabacitu Jan 11, 2018
4e49452
removed commented js
tabacitu Jan 11, 2018
ee4e350
list view - hide no of entries picker on mobile
tabacitu Jan 12, 2018
463e114
list view mobile expand button looks like mobile buttons usually do
tabacitu Jan 12, 2018
11ed574
list view extra features logic has been separated - each into its own…
tabacitu Jan 12, 2018
59517c2
list view on mobile and desktop - delete button works on both
tabacitu Jan 14, 2018
f725152
list view - details row are merged into the first column; hidden when…
tabacitu Jan 14, 2018
3178b68
list view style improvements
tabacitu Jan 14, 2018
6e2889e
css improvs
tabacitu Jan 14, 2018
ca1e36c
fixed @lloy0076 's review
tabacitu Jan 14, 2018
98c4306
merged master into mobile-friendly branch; added prefix, suffix and l…
tabacitu Feb 23, 2018
a250087
added CRUD installation command
tabacitu Mar 5, 2018
5f4fcbc
removed dependency loading, since they all use laravel auto-load now
tabacitu Mar 5, 2018
0a38f66
crud installer now asks user if he wants file manager installed
tabacitu Mar 5, 2018
17a5bc1
moved datatables logic from list view file to its own file
tabacitu Mar 8, 2018
db739d6
moved details_row logic to its own blade file
tabacitu Mar 8, 2018
a3ea937
updated field dependency paths to match updated adminlte
tabacitu Mar 8, 2018
a0d9e68
Apply fixes from StyleCI (#1277)
tabacitu Mar 13, 2018
302cf14
Merge branch 'install-command' of https://github.com/Laravel-Backpack…
tabacitu Mar 5, 2018
c0fdbb0
Apply fixes from StyleCI (#1280)
tabacitu Mar 13, 2018
8c4527b
Merge branch 'remove-dependency-loading' of https://github.com/Larave…
tabacitu Mar 21, 2018
4657748
changelog
tabacitu Mar 21, 2018
73d192e
Merge branch 'install-command' of https://github.com/Laravel-Backpack…
tabacitu Mar 21, 2018
a56f4ed
Merge branch 'master' into upgrade
tabacitu Mar 21, 2018
7cda429
Merge branch 'upgrade' into feature-1-to-1-relationships
tabacitu Mar 21, 2018
14baea5
Merge branch 'master' into feature-1-to-1-relationships
tabacitu Mar 21, 2018
32f9b59
Merge branch 'feature-1-to-1-relationships' into upgrade
tabacitu Mar 21, 2018
f2e5229
made fields wide by default on mobile
tabacitu Mar 8, 2018
a47290a
updated datatable plugins
tabacitu Mar 22, 2018
d814984
datatables responsive working with export buttons
tabacitu Mar 22, 2018
e57eee9
changelog
tabacitu Mar 22, 2018
af4c26f
fixed datatables responsive with details_row
tabacitu Mar 22, 2018
cb9130d
Merge pull request #1295 from Laravel-Backpack/adminlte-update
tabacitu Mar 22, 2018
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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ All Notable changes to `Backpack CRUD` will be documented in this file
- Nothing
-----------

## Unreleased

## Added
- one-line installation command ```php artisan backpack:crud:install```;
- 1-1 relatiosnhips; merges #865;

## Fixed
- ```checkbox``` field was using the default value over the DB value on edit; merges #1239;
- no longer registering Base, Elfinder and Image service providers and aliases, since they all now use auto-load; merges #1279;
- datatables responsive working with colvis and export buttons;

### Removed
- elFinder is no longer a dependency; users should require it themselves, if they need it;

-----------

## [3.3.17] - 2018-03-21

## Fixed
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
],
"require": {
"backpack/base": "^0.8.0",
"barryvdh/laravel-elfinder": "^0.3.10",
"doctrine/dbal": "^2.5",
"venturecraft/revisionable": "1.*",
"intervention/image": "^2.3"
Expand Down
86 changes: 81 additions & 5 deletions src/CrudPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Backpack\CRUD\PanelTraits\AutoFocus;
use Backpack\CRUD\PanelTraits\FakeFields;
use Backpack\CRUD\PanelTraits\FakeColumns;
use Illuminate\Database\Eloquent\Collection;
use Backpack\CRUD\PanelTraits\ViewsAndRestoresRevisions;

class CrudPanel
Expand Down Expand Up @@ -255,16 +256,91 @@ public function sort($items)
* App/Models/Address defined by a company() method on the user model and an address() method on the
* company model, the 'App/Models/Address' string will be returned.
*
* @param $relationString String Relation string. A dot notation can be used to chain multiple relations.
* @param string $relationString Relation string. A dot notation can be used to chain multiple relations.
* @param int $length Optionally specify the number of relations to omit from the start of the relation string. If
* the provided length is negative, then that many relations will be omitted from the end of the relation
* string.
* @param \Illuminate\Database\Eloquent\Model $model Optionally specify a different model than the one in the crud object.
*
* @return string relation model name
* @return string Relation model name.
*/
private function getRelationModel($relationString)
public function getRelationModel($relationString, $length = null, $model = null)
{
$result = array_reduce(explode('.', $relationString), function ($obj, $method) {
$relationArray = explode('.', $relationString);

if (! isset($length)) {
$length = count($relationArray);
}

if (! isset($model)) {
$model = $this->model;
}

$result = array_reduce(array_splice($relationArray, 0, $length), function ($obj, $method) {
return $obj->$method()->getRelated();
}, $this->model);
}, $model);

return get_class($result);
}

/**
* Get the given attribute from a model or models resulting from the specified relation string (eg: the list of streets from
* the many addresses of the company of a given user).
*
* @param \Illuminate\Database\Eloquent\Model $model Model (eg: user).
* @param string $relationString Model relation. Can be a string representing the name of a relation method in the given
* Model or one from a different Model through multiple relations. A dot notation can be used to specify
* multiple relations (eg: user.company.address).
* @param string $attribute The attribute from the relation model (eg: the street attribute from the address model).
*
* @return array An array containing a list of attributes from the resulting model.
*/
public function getModelAttributeFromRelation($model, $relationString, $attribute)
{
$endModels = $this->getRelationModelInstances($model, $relationString);
$attributes = [];
foreach ($endModels as $model) {
if ($model->{$attribute}) {
$attributes[] = $model->{$attribute};
}
}

return $attributes;
}

/**
* Traverse the tree of relations for the given model, defined by the given relation string, and return the ending
* associated model instance or instances.
*
* @param \Illuminate\Database\Eloquent\Model $model The CRUD model.
* @param string $relationString Relation string. A dot notation can be used to chain multiple relations.
* @return array An array of the associated model instances defined by the relation string.
*/
private function getRelationModelInstances($model, $relationString)
{
$relationArray = explode('.', $relationString);
$firstRelationName = array_first($relationArray);
$relation = $model->{$firstRelationName};

$results = [];
if (! empty($relation)) {
if ($relation instanceof Collection) {
$currentResults = $relation->toArray();
} else {
$currentResults[] = $relation;
}

array_shift($relationArray);

if (! empty($relationArray)) {
foreach ($currentResults as $currentResult) {
$results = array_merge($results, $this->getRelationModelInstances($currentResult, implode('.', $relationArray)));
}
} else {
$results = $currentResults;
}
}

return $results;
}
}
14 changes: 6 additions & 8 deletions src/CrudServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

class CrudServiceProvider extends ServiceProvider
{
protected $commands = [
\Backpack\CRUD\app\Console\Commands\Install::class,
];

/**
* Indicates if loading of the provider is deferred.
*
Expand Down Expand Up @@ -76,14 +80,8 @@ public function register()
return new CRUD($app);
});

// register its dependencies
$this->app->register(\Backpack\Base\BaseServiceProvider::class);
$this->app->register(\Barryvdh\Elfinder\ElfinderServiceProvider::class);
$this->app->register(\Intervention\Image\ImageServiceProvider::class);

// register their aliases
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('Image', \Intervention\Image\Facades\Image::class);
// register the artisan commands
$this->commands($this->commands);

// map the elfinder prefix
if (! \Config::get('elfinder.route.prefix')) {
Expand Down
119 changes: 117 additions & 2 deletions src/PanelTraits/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Backpack\CRUD\PanelTraits;

use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

trait Create
{
/*
Expand All @@ -22,12 +25,12 @@ public function create($data)
$data = $this->decodeJsonCastedAttributes($data, 'create');
$data = $this->compactFakeFields($data, 'create');

// ommit the n-n relationships when updating the eloquent item
// omit the n-n relationships when updating the eloquent item
$nn_relationships = array_pluck($this->getRelationFieldsWithPivot('create'), 'name');
$item = $this->model->create(array_except($data, $nn_relationships));

// if there are any relationships available, also sync those
$this->syncPivot($item, $data);
$this->createRelations($item, $data);

return $item;
}
Expand Down Expand Up @@ -92,6 +95,26 @@ public function getRelationFieldsWithPivot($form = 'create')
});
}

/**
* Create the relations for the current model.
*
* @param \Illuminate\Database\Eloquent\Model $item The current CRUD model.
* @param array $data The form data.
* @param string $form Optional form type. Can be either 'create', 'update' or 'both'. Default is 'create'.
*/
public function createRelations($item, $data, $form = 'create')
{
$this->syncPivot($item, $data, $form);
$this->createOneToOneRelations($item, $data, $form);
}

/**
* Sync the declared many-to-many associations through the pivot field.
*
* @param \Illuminate\Database\Eloquent\Model $model The current CRUD model.
* @param array $data The form data.
* @param string $form Optional form type. Can be either 'create', 'update' or 'both'. Default is 'create'.
*/
public function syncPivot($model, $data, $form = 'create')
{
$fields_with_relationships = $this->getRelationFields($form);
Expand All @@ -116,4 +139,96 @@ public function syncPivot($model, $data, $form = 'create')
}
}
}

/**
* Create any existing one to one relations for the current model from the form data.
*
* @param \Illuminate\Database\Eloquent\Model $item The current CRUD model.
* @param array $data The form data.
* @param string $form Optional form type. Can be either 'create', 'update' or 'both'. Default is 'create'.
*/
private function createOneToOneRelations($item, $data, $form = 'create')
{
$relationData = $this->getRelationDataFromFormData($data, $form);
$this->createRelationsForItem($item, $relationData);
}

/**
* Create any existing one to one relations for the current model from the relation data.
*
* @param \Illuminate\Database\Eloquent\Model $item The current CRUD model.
* @param array $formattedData The form data.
*/
private function createRelationsForItem($item, $formattedData)
{
foreach ($formattedData['relations'] as $relationMethod => $relationData) {
$model = $relationData['model'];
$relation = $item->{$relationMethod}();

if ($relation instanceof BelongsTo) {
$modelInstance = $model::find($relationData['values'])->first();
if ($modelInstance != null) {
$relation->associate($modelInstance)->save();
} else {
$relation->dissociate()->save();
}
} elseif ($relation instanceof HasOne) {
if ($item->{$relationMethod} != null) {
$item->{$relationMethod}->update($relationData['values']);
$modelInstance = $item->{$relationMethod};
} else {
$relationModel = new $model();
$modelInstance = $relationModel->create($relationData['values']);
$relation->save($modelInstance);
}
} else {
$relationModel = new $model();
$modelInstance = $relationModel->create($relationData['values']);
$relation->save($modelInstance);
}

if (isset($relationData['relations'])) {
$this->createRelationsForItem($modelInstance, ['relations' => $relationData['relations']]);
}
}
}

/**
* Get a relation data array from the form data.
* For each relation defined in the fields through the entity attribute, set the model, the parent model and the
* attribute values. For relations defined with the "dot" notations, this will be used to calculate the depth in the
* final array (@see \Illuminate\Support\Arr::set() for more).
*
* @param array $data The form data.
* @param string $form Optional form type. Can be either 'create', 'update' or 'both'. Default is 'create'.
*
* @return array The formatted relation data.
*/
private function getRelationDataFromFormData($data, $form = 'create')
{
$relationFields = $this->getRelationFields($form);

$relationData = [];
foreach ($relationFields as $relationField) {
$attributeKey = $relationField['name'];
if (array_key_exists($attributeKey, $data) && empty($relationField['pivot'])) {
$key = implode('.relations.', explode('.', $relationField['entity']));
$fieldData = array_get($relationData, 'relations.'.$key, []);

if (! array_key_exists('model', $fieldData)) {
$fieldData['model'] = $relationField['model'];
}

if (! array_key_exists('parent', $fieldData)) {
$fieldData['parent'] = $this->getRelationModel($relationField['entity'], -1);
}

$fieldData['values'][$attributeKey] = $data[$attributeKey];

array_set($relationData, 'relations.'.$key, $fieldData);
}
}

return $relationData;
}
}
7 changes: 4 additions & 3 deletions src/PanelTraits/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,13 @@ public function getRowViews($entry)
->render();
}

// add the details_row buttons as the first column
// add the details_row button to the first column
if ($this->details_row) {
array_unshift($row_items, \View::make('crud::columns.details_row_button')
$details_row_button = \View::make('crud::columns.details_row_button')
->with('crud', $this)
->with('entry', $entry)
->render());
->render();
$row_items[0] = $details_row_button.$row_items[0];
}

return $row_items;
Expand Down
Loading