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

Deep nested modules #775

Merged
merged 7 commits into from
Apr 26, 2021
5 changes: 5 additions & 0 deletions src/Helpers/routes_helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ function moduleRoute($moduleName, $prefix, $action, $parameters = [], $absolute
// Fix module name case
$moduleName = Str::camel($moduleName);

// Nested module, pass in current parameters for deeply nested modules
if (Str::contains($moduleName, '.')) {
$parameters = array_merge(Route::current()->parameters(), $parameters);
}

// Create base route name
$routeName = 'admin.' . ($prefix ? $prefix . '.' : '');

Expand Down
116 changes: 73 additions & 43 deletions src/Http/Controllers/Admin/ModuleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,31 @@ protected function setMiddlewarePermission()
$this->middleware('can:delete', ['only' => ['destroy', 'bulkDelete', 'restore', 'bulkRestore', 'forceDelete', 'bulkForceDelete', 'restoreRevision']]);
}

/**
* @param Request $request
* @return string|int|null
*/
protected function getParentModuleIdFromRequest(Request $request)
{
$moduleParts = explode('.', $this->moduleName);

if (count($moduleParts) > 1) {
$parentModule = Str::singular($moduleParts[count($moduleParts) - 2]);

return $request->route()->parameters()[$parentModule];
}

return null;
}

/**
* @param int|null $parentModuleId
* @return array|\Illuminate\View\View
*/
public function index($parentModuleId = null)
{
$parentModuleId = $this->getParentModuleIdFromRequest($this->request) ?? $parentModuleId;

$this->submodule = isset($parentModuleId);
$this->submoduleParentId = $parentModuleId;

Expand Down Expand Up @@ -359,6 +378,8 @@ public function browser()
*/
public function store($parentModuleId = null)
{
$parentModuleId = $this->getParentModuleIdFromRequest($this->request) ?? $parentModuleId;

$input = $this->validateFormRequest()->all();
$optionalParent = $parentModuleId ? [$this->getParentModuleForeignKey() => $parentModuleId] : [];

Expand All @@ -382,17 +403,6 @@ public function store($parentModuleId = null)
return $this->respondWithSuccess(twillTrans('twill::lang.publisher.save-success'));
}

if ($parentModuleId) {
$params = [
Str::singular(explode('.', $this->moduleName)[0]) => $parentModuleId,
Str::singular(explode('.', $this->moduleName)[1]) => $item[$this->identifierColumnKey],
];
} else {
$params = [
Str::singular($this->moduleName) => $item[$this->identifierColumnKey],
];
}

if (isset($input['cmsSaveType']) && Str::endsWith($input['cmsSaveType'], '-close')) {
return $this->respondWithRedirect($this->getBackLink());
}
Expand All @@ -409,11 +419,12 @@ public function store($parentModuleId = null)
$this->moduleName,
$this->routePrefix,
'edit',
$params
[Str::singular(last(explode('.', $this->moduleName))) => $item[$this->identifierColumnKey]]
));
}

/**
* @param Request $request
* @param int|$id
* @param int|null $submoduleId
* @return \Illuminate\Http\RedirectResponse
Expand All @@ -424,22 +435,28 @@ public function show($id, $submoduleId = null)
return Redirect::to(moduleRoute($this->moduleName, $this->routePrefix, 'index'));
}

return $this->redirectToForm($submoduleId ?? $id);
return $this->redirectToForm($this->getParentModuleIdFromRequest($this->request) ?? $submoduleId ?? $id);
}

/**
* @param int $id
* @param int|null $submoduleId
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
* @param int $id
* @param int|null $submoduleId
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function edit($id, $submoduleId = null)
{
$this->submodule = isset($submoduleId);
$this->submoduleParentId = $id;
$params = $this->request->route()->parameters();

$this->submodule = count($params) > 1;
$this->submoduleParentId = $this->submodule
? $this->getParentModuleIdFromRequest($this->request) ?? $id
: head($params);

$id = last($params);

if ($this->getIndexOption('editInModal')) {
return $this->request->ajax()
? Response::json($this->modalFormData($submoduleId ?? $id))
? Response::json($this->modalFormData($id))
: Redirect::to(moduleRoute($this->moduleName, $this->routePrefix, 'index'));
}

Expand All @@ -453,12 +470,11 @@ public function edit($id, $submoduleId = null)
return View::exists($view);
});

return View::make($view, $this->form($submoduleId ?? $id));
return View::make($view, $this->form($id));
}

/**
* @param int $id
* @param int|null $submoduleId
* @param int $parentModuleId
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function create($parentModuleId = null)
Expand All @@ -471,6 +487,9 @@ public function create($parentModuleId = null)
['openCreate' => true]
));
}

$parentModuleId = $this->getParentModuleIdFromRequest($this->request) ?? $parentModuleId;

$this->submodule = isset($parentModuleId);
$this->submoduleParentId = $parentModuleId;

Expand All @@ -492,10 +511,15 @@ public function create($parentModuleId = null)
*/
public function update($id, $submoduleId = null)
{
$this->submodule = isset($submoduleId);
$this->submoduleParentId = $id;
$params = $this->request->route()->parameters();

$submoduleParentId = $this->getParentModuleIdFromRequest($this->request) ?? $id;
$this->submodule = isset($submoduleParentId);
$this->submoduleParentId = $submoduleParentId;

$id = last($params);

$item = $this->repository->getById($submoduleId ?? $id);
$item = $this->repository->getById($id);
$input = $this->request->all();

if (isset($input['cmsSaveType']) && $input['cmsSaveType'] === 'cancel') {
Expand All @@ -508,7 +532,7 @@ public function update($id, $submoduleId = null)
} else {
$formRequest = $this->validateFormRequest();

$this->repository->update($submoduleId ?? $id, $formRequest->all());
$this->repository->update($id, $formRequest->all());

activity()->performedOn($item)->log('updated');

Expand Down Expand Up @@ -674,9 +698,12 @@ public function bulkPublish()
*/
public function duplicate($id, $submoduleId = null)
{
$params = $this->request->route()->parameters();

$item = $this->repository->getById($submoduleId ?? $id);
if ($newItem = $this->repository->duplicate($submoduleId ?? $id, $this->titleColumnKey)) {
$id = last($params);

$item = $this->repository->getById($id);
if ($newItem = $this->repository->duplicate($id, $this->titleColumnKey)) {
$this->fireEvent();
activity()->performedOn($item)->log('duplicated');

Expand All @@ -702,8 +729,12 @@ public function duplicate($id, $submoduleId = null)
*/
public function destroy($id, $submoduleId = null)
{
$item = $this->repository->getById($submoduleId ?? $id);
if ($this->repository->delete($submoduleId ?? $id)) {
$params = $this->request->route()->parameters();

$id = last($params);

$item = $this->repository->getById($id);
if ($this->repository->delete($id)) {
$this->fireEvent();
activity()->performedOn($item)->log('deleted');
return $this->respondWithSuccess($this->modelTitle . ' moved to trash!');
Expand Down Expand Up @@ -1025,8 +1056,9 @@ protected function getItemColumnData($item, $column)
if (isset($column['nested']) && $column['nested']) {
$field = $column['nested'];
$nestedCount = $item->{$column['nested']}->count();
$module = Str::singular(last(explode('.', $this->moduleName)));
$value = '<a href="';
$value .= moduleRoute("$this->moduleName.$field", $this->routePrefix, 'index', [$item[$this->identifierColumnKey]]);
$value .= moduleRoute("$this->moduleName.$field", $this->routePrefix, 'index', [$module => $item[$this->identifierColumnKey]]);
$value .= '">' . $nestedCount . " " . (strtolower($nestedCount > 1
? Str::plural($column['title'])
: Str::singular($column['title']))) . '</a>';
Expand Down Expand Up @@ -1200,7 +1232,9 @@ protected function getIndexUrls($moduleName, $routePrefix)
])->mapWithKeys(function ($endpoint) {
return [
$endpoint . 'Url' => $this->getIndexOption($endpoint) ? moduleRoute(
$this->moduleName, $this->routePrefix, $endpoint,
$this->moduleName,
$this->routePrefix,
$endpoint,
$this->submodule ? [$this->submoduleParentId] : []
) : null,
];
Expand Down Expand Up @@ -1414,7 +1448,6 @@ protected function orderScope()
*/
protected function form($id, $item = null)
{

if (!$item && $id) {
$item = $this->repository->getById($id, $this->formWith, $this->formWithCount);
} elseif (!$item && !$id) {
Expand Down Expand Up @@ -1449,10 +1482,10 @@ protected function form($id, $item = null)
'availableRepeaters' => $this->getRepeaterList()->toJson(),
'revisions' => $this->moduleHas('revisions') ? $item->revisionsArray() : null,
] + (Route::has($previewRouteName) && $item[$this->identifierColumnKey] ? [
'previewUrl' => moduleRoute($this->moduleName, $this->routePrefix, 'preview', $item[$this->identifierColumnKey]),
'previewUrl' => moduleRoute($this->moduleName, $this->routePrefix, 'preview', [$item[$this->identifierColumnKey]]),
] : [])
+ (Route::has($restoreRouteName) && $item[$this->identifierColumnKey] ? [
'restoreUrl' => moduleRoute($this->moduleName, $this->routePrefix, 'restoreRevision', $item[$this->identifierColumnKey]),
'restoreUrl' => moduleRoute($this->moduleName, $this->routePrefix, 'restoreRevision', [$item[$this->identifierColumnKey]]),
] : []);

return array_replace_recursive($data, $this->formData($this->request));
Expand Down Expand Up @@ -1583,7 +1616,9 @@ protected function getModelTitle()
*/
protected function getParentModuleForeignKey()
{
return Str::singular(explode('.', $this->moduleName)[0]) . '_id';
$moduleParts = explode('.', $this->moduleName);

return Str::singular($moduleParts[count($moduleParts) - 2]) . '_id';
}

/**
Expand Down Expand Up @@ -1620,12 +1655,7 @@ protected function getPermalinkPrefix($baseUrl)
*/
protected function getModuleRoute($id, $action)
{
return moduleRoute(
$this->moduleName,
$this->routePrefix,
$action,
array_merge($this->submodule ? [$this->submoduleParentId] : [], [$id])
);
return moduleRoute($this->moduleName, $this->routePrefix, $action, [$id]);
}

/**
Expand Down