PHP code example of lupennat / nova-nested-many

1. Go to this page and download the library: Download lupennat/nova-nested-many library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

lupennat / nova-nested-many example snippets


namespace App\Nova;

use Laravel\Nova\Resource as NovaResource;
use Lupennat\NestedMany\HasNestedResource;

abstract class Resource extends NovaResource
{
    use HasNestedResource;
}

namespace App\Nova;

use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Gravatar;
use Laravel\Nova\Fields\Password;
// Add use statement here.
use Lupennat\NestedMany\Fields\HasManyNested;

class User extends Resource
{

    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),

            Gravatar::make(),

            Text::make('Name')
                ->sortable()
                ->rules('d::make('Posts'),
        ];
    }

}

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Lupennat\NestedMany\Models\Contracts\Nestable;
use Lupennat\NestedMany\Models\HasNested;

class Post extends Model implements Nestable
{
    use HasNested;

}

HasNestedMany::make('Posts', Post::class)
    ->dependsOn('name', function(HasNestedMany $field, NovaRequest $novaRequest, FormData $formData) {
        if ($formData->name === 'xxx') {
            $field->show();
        } else {
            $field->hide();
        }
    })

HasNestedMany::make('Posts', Post::class)->propagate(['name'])

// you can also propagate custom key/value to related resource.
HasNestedMany::make('Posts', Post::class)->propagate(['not_a_field' => 'test'])


namespace App\Nova;

use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;

class Post extends Resource
{

    public function fields(NovaRequest $request)
    {
        return array_filter([
            ID::make(),
            BelongsTo::make(__('User'), 'user', User::class),
            Select::section(__('Section'), 'section')
                ->options(['sport' => 'Sport', 'news' => 'News'])
                ->rules('

HasNestedMany::make('Posts', Post::class)
    ->defaultChildren([
        ['title' => 'first post', 'section' => 'sport'],
        ['title' => 'second post', 'section' => 'news'],
    ])

HasNestedMany::make('Posts', Post::class)
    ->defaultChildren([
        ['title' => 'first post', 'section' => 'sport'],
        ['title' => 'second post', 'section' => 'news'],
    ], true)

namespace App\Nova;

use Illuminate\Http\Request;
use Lupennat\NestedMany\Fields\HasManyNested;
use Laravel\Nova\Http\Requests\NovaRequest;

class User extends Resource
{

    public function fields(Request $request)
    {
        return [
            HasNestedMany::make('Posts', Post::class)
                ->beforeFill(function(\App\Models\User $user, NovaRequest $request) {
                    // do stuff
                })
                ->afterFill(function(\App\Models\User $user, NovaRequest $request) {
                    // do stuff
                })
        ];
    }

}

namespace App\Nova;

class User extends Resource
{

    public function nestedTitle()
    {
        return $this->resource->name;
    }

}

namespace App\Nova;

class User extends Resource
{
    /**
     * Handle any post-validation processing.
     *
     * @param \Illuminate\Validation\Validator $validator
     *
     * @return void
     */
    protected static function afterValidation(NovaRequest $request, $validator)
    {
        // do logic to detect error
        $isDisposableEmail = true;
        if($isDisposableEmail) {
            $validator
                ->errors()
                ->add(
                    $request->getNestedValidationKeyPrefix() . 'email',
                    'Temporary emails are forbidden.'
                );
        }
    }


namespace App\Nova;

class User extends Resource
{

    public static function authorizedToCreateNested(Request $request)
    {
        return true;
    }

    public function authorizedToUpdateNested(Request $request)
    {
        return false;
    }

    public function authorizedToDeleteNested(Request $request)
    {
        return $this->authorizedToDelete($request);
    }

}

namespace App\Nova;

use Lupennat\NestedMany\Actions\Basics\NestedBasicAddAction;
use Lupennat\NestedMany\Actions\Basics\NestedBasicDeleteAction;
use Lupennat\NestedMany\Actions\Basics\NestedBasicRestoreAction;
use Laravel\Nova\Http\Requests\NovaRequest;

class Post extends Resource
{

    /**
     * Get the nested create action on the entity.
     */
    public function nestedAddAction(NovaRequest $request): NestedBasicAddAction
    {
        return new \App\Nova\NestedActions\MyCustomAddActionExtendsBasicAddAction();
    }

    /**
     * Get the nested delete action on the entity.
     */
    public function nestedDeleteAction(NovaRequest $request): NestedBasicDeleteAction
    {
        return parent::nestedDeleteAction($request)->withConfirmation();
    }

    /**
     * Get the nested delete action on the entity.
     */
    public function nestedRestoreAction(NovaRequest $request): NestedBasicRestoreAction
    {
        return parent::nestedRestoreAction($request)->withConfirmation();
    }

}

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Lupennat\NestedMany\Models\Contracts\Nestable;
use Lupennat\NestedMany\Models\HasNested;

class Post extends Model implements Nestable
{
    use HasNested;

    protected $nestedHasSoftDelete = true;

}



namespace App\Nova\NestedActions;

use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
use Lupennat\NestedMany\Models\Nested;
use Lupennat\NestedMany\Actions\NestedAction;

class DuplicatePost extends NestedAction
{

    /**
     * Handle any post-validation processing.
     *
     * @param \Illuminate\Contracts\Validation\Validator $validator
     * @param \Illuminate\Support\Collection<int,\Lupennat\NestedMany\Models\Nested> $resources
     *
     * @return void
     */
    protected function afterValidation(NovaRequest $request, Collection $resources, $validator)
    {
       // do validation stuff
    }


    /**
     * Perform the action on the given models.
     *
     * @param \Laravel\Nova\Fields\ActionFields $actionFields
     * @param \Illuminate\Support\Collection<int,\Lupennat\NestedMany\Models\Nested> $children
     * @param string|null $selectedUid
     *
     * @return \Illuminate\Support\Collection<int,\Lupennat\NestedMany\Models\Nested>
     */
    public function handle(ActionFields $fields, Collection $children, $selectedUid): Collection
    {
        $selectedNested = $children->where(Nested::UIDFIELD, $selectedUid)->first();

        $children->push(tap($this->getNewNested(), function ($newResource) use ($selectedNested, $fields) {
            foreach ($selectedNested->getAttributes() as $key => $value) {
                if($key !== $selectedNested->getKeyName()) {
                    $newResource->{$key} = $value;
                }
            }
            $newResource->active();
        }));

        return $children;
    }

    /**
     * Get the fields available on the action.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @return array
     */
    public function fields(NovaRequest $request)
    {
        return [];
    }
}

namespace App\Nova;

use Lupennat\NestedMany\Actions\Basics\NestedBasicAddAction;

class Post extends Resource
{
    /**
     * Get the actions available on the entity.
     *
     * @return array<\Lupennat\NestedMany\Actions\NestedAction>
     */
    public function nestedActions(NovaRequest $request): array
    {
        return [
            \App\Nova\NestedActions\DuplicatePost::create()
        ];
    }
}

class Parent extends Model {
    protected static function booted(): void
    {
        static::deleted(function (Parent $model) {
            // to propagate event we need to call ->delete() within the model
            foreach ($model->childrenItemA as $childItemA) {
                $childItemA->delete();
            }
        });
    }

    public childrenItemA() {
        return $this->hasMany(ItemA::class);
    }
}

class ItemA extends Model {

    protected static function booted(): void {
        static::deleted(function (ItemA $model) {
            // we can avoid loop we don't need to propagate event
           $model->childrenItemB()->delete()
        });
    }

    public childrenItemB() {
        return $this->hasMany(ItemB::class);
    }
}

class ItemB extends Model {
}
bash
php artisan nested-many:action DuplicatePost